summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--config.tests/arch/arch.pro1
-rw-r--r--config.tests/common/avx/avx.pro1
-rw-r--r--config.tests/common/avx2/avx2.pro1
-rw-r--r--config.tests/common/c++11/c++11.pro2
-rw-r--r--config.tests/common/sse2/sse2.pro1
-rw-r--r--config.tests/common/sse3/sse3.pro1
-rw-r--r--config.tests/common/sse4_1/sse4_1.pro1
-rw-r--r--config.tests/common/sse4_2/sse4_2.pro1
-rw-r--r--config.tests/common/ssse3/ssse3.pro1
-rw-r--r--config.tests/mac/coreservices/coreservices.pro2
-rw-r--r--config.tests/mac/corewlan/corewlan.pro2
-rw-r--r--config.tests/qpa/directfb/directfb.pro1
-rw-r--r--config.tests/unix/alsa/alsa.pro1
-rwxr-xr-xconfig.tests/unix/arch.test2
-rw-r--r--config.tests/unix/clock-gettime/clock-gettime.pro1
-rw-r--r--config.tests/unix/clock-monotonic/clock-monotonic.pro1
-rwxr-xr-xconfig.tests/unix/compile.test2
-rw-r--r--config.tests/unix/cups/cups.pro1
-rw-r--r--config.tests/unix/db2/db2.pro1
-rw-r--r--config.tests/unix/dbus/dbus.pro1
-rw-r--r--config.tests/unix/eventfd/eventfd.pro1
-rw-r--r--config.tests/unix/fontconfig/fontconfig.pro2
-rw-r--r--config.tests/unix/getaddrinfo/getaddrinfo.pro1
-rw-r--r--config.tests/unix/getifaddrs/getifaddrs.pro1
-rw-r--r--config.tests/unix/glib/glib.pro2
-rw-r--r--config.tests/unix/gnu-libiconv/gnu-libiconv.pro1
-rw-r--r--config.tests/unix/ibase/ibase.pro1
-rw-r--r--config.tests/unix/iconv/iconv.pro2
-rw-r--r--config.tests/unix/icu/icu.pro2
-rw-r--r--config.tests/unix/inotify/inotify.pro1
-rw-r--r--config.tests/unix/iodbc/iodbc.pro1
-rw-r--r--config.tests/unix/ipv6ifname/ipv6ifname.pro1
-rw-r--r--config.tests/unix/libjpeg/libjpeg.pro1
-rw-r--r--config.tests/unix/libpng/libpng.pro1
-rw-r--r--config.tests/unix/mremap/mremap.pro1
-rw-r--r--config.tests/unix/mysql/mysql.pro1
-rw-r--r--config.tests/unix/mysql_r/mysql_r.pro1
-rw-r--r--config.tests/unix/nis/nis.pro1
-rw-r--r--config.tests/unix/oci/oci.pro1
-rw-r--r--config.tests/unix/odbc/odbc.pro1
-rw-r--r--config.tests/unix/opengldesktop/opengldesktop.pro1
-rw-r--r--config.tests/unix/opengles1/opengles1.pro1
-rw-r--r--config.tests/unix/opengles2/opengles2.pro1
-rw-r--r--config.tests/unix/openssl/openssl.pro1
-rw-r--r--config.tests/unix/pcre/pcre.pro2
-rw-r--r--config.tests/unix/psql/psql.pro1
-rwxr-xr-xconfig.tests/unix/ptrsize.test2
-rw-r--r--config.tests/unix/ptrsize/ptrsizetest.pro1
-rw-r--r--config.tests/unix/slog2/slog2.pro1
-rw-r--r--config.tests/unix/sqlite/sqlite.pro1
-rw-r--r--config.tests/unix/sqlite2/sqlite2.pro1
-rw-r--r--config.tests/unix/stdint/stdint.pro1
-rw-r--r--config.tests/unix/stl/stl.pro1
-rw-r--r--config.tests/unix/sun-libiconv/sun-libiconv.pro2
-rw-r--r--config.tests/unix/tds/tds.pro1
-rw-r--r--config.tests/unix/zlib/zlib.pro1
-rwxr-xr-xconfigure136
-rw-r--r--dist/changes-5.2.045
-rw-r--r--doc/global/config.qdocconf12
-rw-r--r--doc/global/externalsites/rfc.qdoc15
-rw-r--r--doc/global/fileextensions.qdocconf12
-rw-r--r--doc/global/html-config.qdocconf29
-rw-r--r--doc/global/html-footer.qdocconf30
-rw-r--r--doc/global/html-header-offline.qdocconf31
-rw-r--r--doc/global/html-header-online.qdocconf64
-rw-r--r--doc/global/qt-cpp-defines.qdocconf (renamed from doc/global/qt-cpp-ignore.qdocconf)32
-rw-r--r--doc/global/qt-defines.qdocconf17
-rw-r--r--doc/global/qt-html-templates-offline.qdocconf45
-rw-r--r--doc/global/qt-html-templates-online.qdocconf79
-rw-r--r--doc/global/qt-module-defaults-offline.qdocconf13
-rw-r--r--doc/global/qt-module-defaults-online.qdocconf40
-rw-r--r--doc/global/qt-module-defaults.qdocconf35
-rw-r--r--doc/global/template/images/Qt-dark_gradient.pngbin0 -> 1032 bytes
-rw-r--r--doc/global/template/images/Qt-footer-bg.jpgbin0 -> 3843 bytes
-rw-r--r--doc/global/template/images/Qt-footer_shadow.pngbin0 -> 3181 bytes
-rw-r--r--doc/global/template/images/Qt-gradient.pngbin0 -> 956 bytes
-rw-r--r--doc/global/template/images/Qt-header-bg.jpgbin0 -> 11264 bytes
-rw-r--r--doc/global/template/images/Qt-logo.pngbin0 -> 4344 bytes
-rw-r--r--doc/global/template/images/arrow_bc.pngbin0 -> 1071 bytes
-rw-r--r--doc/global/template/images/logo.pngbin0 -> 2205 bytes
-rw-r--r--doc/global/template/style/offline.css980
-rw-r--r--doc/global/template/style/online.css1472
-rw-r--r--examples/widgets/dialogs/standarddialogs/dialog.cpp20
-rw-r--r--examples/widgets/dialogs/standarddialogs/dialog.h2
-rw-r--r--examples/widgets/doc/src/addressbook-fr.qdoc14
-rw-r--r--examples/widgets/doc/src/addressbook-tutorial.qdoc14
-rw-r--r--examples/widgets/itemviews/spreadsheet/main.cpp3
-rw-r--r--examples/widgets/itemviews/spreadsheet/spreadsheet.cpp1
-rw-r--r--examples/widgets/widgets/spinboxes/window.cpp10
-rw-r--r--mkspecs/blackberry-armv7le-qcc/qmake.conf1
-rw-r--r--mkspecs/common/clang.conf10
-rw-r--r--mkspecs/common/ios/qmake.conf3
-rw-r--r--mkspecs/common/mac.conf2
-rw-r--r--mkspecs/common/macx.conf2
-rw-r--r--mkspecs/darwin-g++/qmake.conf2
-rw-r--r--mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp6
-rw-r--r--mkspecs/features/configure.prf3
-rw-r--r--mkspecs/features/create_cmake.prf6
-rw-r--r--mkspecs/features/gcov.prf31
-rw-r--r--mkspecs/features/ios/default_post.prf95
-rw-r--r--mkspecs/features/ios/default_pre.prf2
-rw-r--r--mkspecs/features/ios/qt.prf24
-rw-r--r--mkspecs/features/qt_docs.prf2
-rw-r--r--mkspecs/features/simd.prf3
-rw-r--r--mkspecs/features/spec_post.prf10
-rw-r--r--mkspecs/macx-clang-libc++-32/qmake.conf23
-rw-r--r--mkspecs/macx-clang-libc++/qmake.conf22
-rwxr-xr-xmkspecs/macx-xcode/Info.plist.app22
-rw-r--r--mkspecs/macx-xcode/Info.plist.lib18
-rw-r--r--mkspecs/macx-xcode/features/default_post.prf7
-rw-r--r--qmake/Makefile.unix7
-rw-r--r--qmake/Makefile.win324
-rw-r--r--qmake/doc/images/qmake-precompile-ui.png (renamed from qmake/doc/src/images/qmake-precompile-ui.png)bin89070 -> 89070 bytes
-rw-r--r--qmake/doc/qmake.qdocconf6
-rw-r--r--qmake/doc/snippets/code/doc_src_qmake-manual.cpp (renamed from qmake/doc/src/snippets/code/doc_src_qmake-manual.cpp)0
-rw-r--r--qmake/doc/snippets/code/doc_src_qmake-manual.pro (renamed from qmake/doc/src/snippets/code/doc_src_qmake-manual.pro)0
-rw-r--r--qmake/doc/snippets/qmake/comments.pro (renamed from qmake/doc/src/snippets/qmake/comments.pro)0
-rw-r--r--qmake/doc/snippets/qmake/configscopes.pro (renamed from qmake/doc/src/snippets/qmake/configscopes.pro)0
-rw-r--r--qmake/doc/snippets/qmake/debug_and_release.pro (renamed from qmake/doc/src/snippets/qmake/debug_and_release.pro)0
-rw-r--r--qmake/doc/snippets/qmake/delegate.h (renamed from qmake/doc/src/snippets/qmake/delegate.h)0
-rw-r--r--qmake/doc/snippets/qmake/dereferencing.pro (renamed from qmake/doc/src/snippets/qmake/dereferencing.pro)0
-rw-r--r--qmake/doc/snippets/qmake/destdir.pro (renamed from qmake/doc/src/snippets/qmake/destdir.pro)0
-rw-r--r--qmake/doc/snippets/qmake/dirname.pro (renamed from qmake/doc/src/snippets/qmake/dirname.pro)0
-rw-r--r--qmake/doc/snippets/qmake/environment.pro (renamed from qmake/doc/src/snippets/qmake/environment.pro)0
-rw-r--r--qmake/doc/snippets/qmake/functions.pro (renamed from qmake/doc/src/snippets/qmake/functions.pro)0
-rw-r--r--qmake/doc/snippets/qmake/include.pro (renamed from qmake/doc/src/snippets/qmake/include.pro)0
-rw-r--r--qmake/doc/snippets/qmake/main.cpp (renamed from qmake/doc/src/snippets/qmake/main.cpp)0
-rw-r--r--qmake/doc/snippets/qmake/model.cpp (renamed from qmake/doc/src/snippets/qmake/model.cpp)0
-rw-r--r--qmake/doc/snippets/qmake/model.h (renamed from qmake/doc/src/snippets/qmake/model.h)0
-rw-r--r--qmake/doc/snippets/qmake/other.pro (renamed from qmake/doc/src/snippets/qmake/other.pro)0
-rw-r--r--qmake/doc/snippets/qmake/paintwidget_mac.cpp (renamed from qmake/doc/src/snippets/qmake/paintwidget_mac.cpp)0
-rw-r--r--qmake/doc/snippets/qmake/paintwidget_unix.cpp (renamed from qmake/doc/src/snippets/qmake/paintwidget_unix.cpp)0
-rw-r--r--qmake/doc/snippets/qmake/paintwidget_win.cpp (renamed from qmake/doc/src/snippets/qmake/paintwidget_win.cpp)0
-rw-r--r--qmake/doc/snippets/qmake/precompile-stable.h (renamed from qmake/doc/src/snippets/qmake/precompile-stable.h)0
-rw-r--r--qmake/doc/snippets/qmake/project_location.pro (renamed from qmake/doc/src/snippets/qmake/project_location.pro)0
-rw-r--r--qmake/doc/snippets/qmake/qtconfiguration.pro (renamed from qmake/doc/src/snippets/qmake/qtconfiguration.pro)0
-rw-r--r--qmake/doc/snippets/qmake/quoting.pro (renamed from qmake/doc/src/snippets/qmake/quoting.pro)0
-rw-r--r--qmake/doc/snippets/qmake/replace.pro (renamed from qmake/doc/src/snippets/qmake/replace.pro)0
-rw-r--r--qmake/doc/snippets/qmake/replacefunction.pro (renamed from qmake/doc/src/snippets/qmake/replacefunction.pro)0
-rw-r--r--qmake/doc/snippets/qmake/scopes.pro (renamed from qmake/doc/src/snippets/qmake/scopes.pro)0
-rw-r--r--qmake/doc/snippets/qmake/shared_or_static.pro (renamed from qmake/doc/src/snippets/qmake/shared_or_static.pro)0
-rw-r--r--qmake/doc/snippets/qmake/spaces.pro (renamed from qmake/doc/src/snippets/qmake/spaces.pro)0
-rw-r--r--qmake/doc/snippets/qmake/specifications.pro (renamed from qmake/doc/src/snippets/qmake/specifications.pro)0
-rw-r--r--qmake/doc/snippets/qmake/testfunction.pro (renamed from qmake/doc/src/snippets/qmake/testfunction.pro)0
-rw-r--r--qmake/doc/snippets/qmake/variables.pro (renamed from qmake/doc/src/snippets/qmake/variables.pro)0
-rw-r--r--qmake/doc/snippets/qmake/view.h (renamed from qmake/doc/src/snippets/qmake/view.h)0
-rw-r--r--qmake/doc/src/qmake-manual.qdoc364
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp98
-rw-r--r--qmake/generators/mac/pbuilder_pbx.h1
-rw-r--r--qmake/generators/makefile.cpp3
-rw-r--r--qmake/library/ioutils.cpp5
-rw-r--r--qmake/library/ioutils.h1
-rw-r--r--qmake/library/qmake_global.h4
-rw-r--r--qmake/library/qmakebuiltins.cpp59
-rw-r--r--qmake/library/qmakeevaluator.cpp104
-rw-r--r--qmake/library/qmakeevaluator.h23
-rw-r--r--qmake/library/qmakeglobals.cpp52
-rw-r--r--qmake/library/qmakeparser.cpp24
-rw-r--r--qmake/library/qmakeparser.h4
-rw-r--r--qmake/library/qmakevfs.cpp192
-rw-r--r--qmake/library/qmakevfs.h (renamed from src/plugins/platforms/kms/qkmsudevlistener.h)55
-rw-r--r--qmake/main.cpp4
-rw-r--r--qmake/option.cpp1
-rw-r--r--qmake/option.h2
-rw-r--r--qmake/project.cpp4
-rw-r--r--qmake/property.cpp4
-rw-r--r--qmake/qmake.pri4
-rw-r--r--qmake/qmake.pro2
-rw-r--r--qtbase.pro2
-rw-r--r--src/concurrent/doc/qtconcurrent.qdocconf3
-rw-r--r--src/concurrent/doc/src/qtconcurrent-module.qdoc1
-rw-r--r--src/corelib/Qt5CoreConfigExtras.cmake.in7
-rw-r--r--src/corelib/Qt5CoreConfigExtrasMkspecDir.cmake.in6
-rw-r--r--src/corelib/Qt5CoreConfigExtrasMkspecDirForInstall.cmake.in6
-rw-r--r--src/corelib/corelib.pro24
-rw-r--r--src/corelib/doc/qtcore.qdocconf5
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp6
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp58
-rw-r--r--src/corelib/doc/src/qtcore.qdoc1
-rw-r--r--src/corelib/global/qcompilerdetection.h22
-rw-r--r--src/corelib/global/qglobal.cpp10
-rw-r--r--src/corelib/global/qglobal.h9
-rw-r--r--src/corelib/global/qlibraryinfo.cpp23
-rw-r--r--src/corelib/global/qlibraryinfo.h2
-rw-r--r--src/corelib/global/qnamespace.h11
-rw-r--r--src/corelib/global/qnamespace.qdoc10
-rw-r--r--src/corelib/global/qsystemdetection.h11
-rw-r--r--src/corelib/io/qdatastream.cpp5
-rw-r--r--src/corelib/io/qdatastream.h5
-rw-r--r--src/corelib/io/qdir.cpp57
-rw-r--r--src/corelib/io/qipaddress.cpp60
-rw-r--r--src/corelib/io/qipaddress_p.h2
-rw-r--r--src/corelib/io/qprocess_unix.cpp55
-rw-r--r--src/corelib/io/qstandardpaths.cpp11
-rw-r--r--src/corelib/io/qstandardpaths.h5
-rw-r--r--src/corelib/io/qurl.cpp863
-rw-r--r--src/corelib/io/qurl.h8
-rw-r--r--src/corelib/io/qurl_p.h3
-rw-r--r--src/corelib/io/qurlidna.cpp5
-rw-r--r--src/corelib/io/qurlquery.cpp57
-rw-r--r--src/corelib/io/qurlrecode.cpp114
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp170
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.h5
-rw-r--r--src/corelib/json/qjson_p.h2
-rw-r--r--src/corelib/json/qjsonvalue.cpp12
-rw-r--r--src/corelib/json/qjsonvalue.h1
-rw-r--r--src/corelib/json/qjsonwriter.cpp9
-rw-r--r--src/corelib/kernel/qcore_mac_p.h6
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp57
-rw-r--r--src/corelib/kernel/qeventdispatcher_blackberry.cpp82
-rw-r--r--src/corelib/kernel/qmetatype.cpp283
-rw-r--r--src/corelib/kernel/qmetatype.h1058
-rw-r--r--src/corelib/kernel/qobject.cpp60
-rw-r--r--src/corelib/kernel/qobject_p.h7
-rw-r--r--src/corelib/kernel/qobjectdefs.h1
-rw-r--r--src/corelib/kernel/qsocketnotifier.cpp9
-rw-r--r--src/corelib/kernel/qvariant.cpp589
-rw-r--r--src/corelib/kernel/qvariant.h295
-rw-r--r--src/corelib/plugin/plugin.pri6
-rw-r--r--src/corelib/plugin/qlibrary.cpp141
-rw-r--r--src/corelib/plugin/qmachparser.cpp218
-rw-r--r--src/corelib/plugin/qmachparser_p.h79
-rw-r--r--src/corelib/tools/qalgorithms.h67
-rw-r--r--src/corelib/tools/qalgorithms.qdoc31
-rw-r--r--src/corelib/tools/qbitarray.cpp11
-rw-r--r--src/corelib/tools/qbitarray.h1
-rw-r--r--src/corelib/tools/qbytearray.cpp1
-rw-r--r--src/corelib/tools/qdatetime.cpp190
-rw-r--r--src/corelib/tools/qdatetime.h3
-rw-r--r--src/corelib/tools/qeasingcurve.cpp10
-rw-r--r--src/corelib/tools/qharfbuzz_p.h14
-rw-r--r--src/corelib/tools/qhash.h21
-rw-r--r--src/corelib/tools/qlist.h17
-rw-r--r--src/corelib/tools/qlocale.h3
-rw-r--r--src/corelib/tools/qlocale.qdoc3
-rw-r--r--src/corelib/tools/qlocale_data_p.h2521
-rw-r--r--src/corelib/tools/qlocale_p.h2
-rw-r--r--src/corelib/tools/qmap.h18
-rw-r--r--src/corelib/tools/qpair.h13
-rw-r--r--src/corelib/tools/qpair.qdoc20
-rw-r--r--src/corelib/tools/qscopedpointer.cpp30
-rw-r--r--src/corelib/tools/qscopedpointer.h24
-rw-r--r--src/corelib/tools/qset.h22
-rw-r--r--src/corelib/tools/qstring.cpp32
-rw-r--r--src/corelib/tools/qstring.h4
-rw-r--r--src/corelib/tools/qvarlengtharray.h10
-rw-r--r--src/corelib/tools/qvector.h10
-rw-r--r--src/dbus/doc/qtdbus.qdocconf5
-rw-r--r--src/dbus/doc/src/qtdbus-module.qdoc1
-rw-r--r--src/dbus/qdbusabstractadaptor.cpp11
-rw-r--r--src/dbus/qdbusconnection_p.h4
-rw-r--r--src/dbus/qdbusintegrator.cpp6
-rw-r--r--src/dbus/qdbusmisc.cpp22
-rw-r--r--src/dbus/qdbusxmlgenerator.cpp16
-rw-r--r--src/gui/doc/qtgui.qdocconf3
-rw-r--r--src/gui/doc/src/qtgui.qdoc9
-rw-r--r--src/gui/image/qbmphandler.cpp3
-rw-r--r--src/gui/image/qicon.cpp1
-rw-r--r--src/gui/image/qicon.h4
-rw-r--r--src/gui/image/qiconloader.cpp12
-rw-r--r--src/gui/image/qimage.cpp689
-rw-r--r--src/gui/image/qimage.h8
-rw-r--r--src/gui/image/qimage_p.h3
-rw-r--r--src/gui/image/qppmhandler.cpp3
-rw-r--r--src/gui/image/qxpmhandler.cpp2
-rw-r--r--src/gui/kernel/qevent.cpp56
-rw-r--r--src/gui/kernel/qevent.h11
-rw-r--r--src/gui/kernel/qguiapplication.cpp120
-rw-r--r--src/gui/kernel/qguiapplication_p.h2
-rw-r--r--src/gui/kernel/qkeysequence.cpp8
-rw-r--r--src/gui/kernel/qkeysequence.h4
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp19
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h48
-rw-r--r--src/gui/kernel/qplatformintegration.cpp4
-rw-r--r--src/gui/kernel/qplatformintegration.h6
-rw-r--r--src/gui/kernel/qplatformintegrationfactory.cpp20
-rw-r--r--src/gui/kernel/qplatformintegrationfactory_p.h2
-rw-r--r--src/gui/kernel/qplatformintegrationplugin.cpp14
-rw-r--r--src/gui/kernel/qplatformintegrationplugin.h5
-rw-r--r--src/gui/kernel/qplatformservices.cpp5
-rw-r--r--src/gui/kernel/qplatformtheme.cpp4
-rw-r--r--src/gui/kernel/qplatformtheme.h9
-rw-r--r--src/gui/kernel/qshortcutmap.cpp3
-rw-r--r--src/gui/kernel/qstylehints.cpp11
-rw-r--r--src/gui/kernel/qstylehints.h1
-rw-r--r--src/gui/kernel/qtouchdevice.cpp19
-rw-r--r--src/gui/kernel/qtouchdevice.h2
-rw-r--r--src/gui/kernel/qtouchdevice_p.h4
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp27
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h8
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h6
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp21
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp12
-rw-r--r--src/gui/opengl/qopenglfunctions.h3
-rw-r--r--src/gui/painting/painting.pri9
-rw-r--r--src/gui/painting/qblendfunctions.cpp465
-rw-r--r--src/gui/painting/qcolor.cpp43
-rw-r--r--src/gui/painting/qcolor.h3
-rw-r--r--src/gui/painting/qcolor_p.cpp12
-rw-r--r--src/gui/painting/qdrawhelper.cpp206
-rw-r--r--src/gui/painting/qdrawhelper_p.h24
-rw-r--r--src/gui/painting/qimagescale.cpp2
-rw-r--r--src/gui/painting/qmemrotate.cpp5
-rw-r--r--src/gui/painting/qpaintbuffer.cpp6
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp4
-rw-r--r--src/gui/text/qfontdatabase.cpp49
-rw-r--r--src/gui/text/qfontdatabase.h10
-rw-r--r--src/gui/text/qfontdatabase_qpa.cpp2
-rw-r--r--src/gui/text/qplatformfontdatabase.cpp13
-rw-r--r--src/gui/text/qplatformfontdatabase.h2
-rw-r--r--src/gui/text/qtextengine.cpp233
-rw-r--r--src/gui/text/qtextengine_p.h16
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp36
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h4
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp14
-rw-r--r--src/network/access/qhttpnetworkreply.cpp5
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp22
-rw-r--r--src/network/access/qhttpnetworkrequest_p.h4
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp8
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp17
-rw-r--r--src/network/access/qnetworkaccessbackend_p.h2
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend.cpp6
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessfilebackend.cpp11
-rw-r--r--src/network/access/qnetworkaccessfilebackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessftpbackend.cpp6
-rw-r--r--src/network/access/qnetworkaccessftpbackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp171
-rw-r--r--src/network/access/qnetworkaccessmanager.h16
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h16
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp7
-rw-r--r--src/network/bearer/qnetworkconfiguration.cpp183
-rw-r--r--src/network/bearer/qnetworkconfiguration.h7
-rw-r--r--src/network/doc/qtnetwork.qdocconf3
-rw-r--r--src/network/doc/src/qtnetwork.qdoc1
-rw-r--r--src/network/kernel/qhostaddress.cpp2
-rw-r--r--src/network/ssl/qssl.cpp10
-rw-r--r--src/network/ssl/qssl.h4
-rw-r--r--src/network/ssl/qsslconfiguration.cpp65
-rw-r--r--src/network/ssl/qsslconfiguration.h4
-rw-r--r--src/network/ssl/qsslconfiguration_p.h6
-rw-r--r--src/network/ssl/qsslcontext.cpp41
-rw-r--r--src/network/ssl/qsslcontext_p.h5
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp38
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp6
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h2
-rw-r--r--src/network/ssl/qsslsocket_p.h4
-rw-r--r--src/opengl/doc/qtopengl.qdocconf5
-rw-r--r--src/opengl/doc/src/qtopengl-module.qdoc1
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_p.h3
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp12
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp8
-rw-r--r--src/platformsupport/eglconvenience/qxlibeglintegration.cpp17
-rw-r--r--src/platformsupport/eventdispatchers/eventdispatchers.pri8
-rw-r--r--src/platformsupport/eventdispatchers/qioseventdispatcher.mm (renamed from src/plugins/platforms/ios/qioseventdispatcher.mm)49
-rw-r--r--src/platformsupport/eventdispatchers/qioseventdispatcher_p.h (renamed from src/plugins/platforms/ios/qioseventdispatcher.h)0
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp4
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm173
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h20
-rw-r--r--src/platformsupport/services/genericunix/qgenericunixservices.cpp26
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes.cpp52
-rw-r--r--src/plugins/bearer/blackberry/qbbengine.cpp7
-rw-r--r--src/plugins/platforms/android/src/androidjniinput.cpp18
-rw-r--r--src/plugins/platforms/android/src/androidplatformplugin.cpp2
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.cpp5
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.h2
-rw-r--r--src/plugins/platforms/android/src/qandroidsystemlocale.cpp179
-rw-r--r--src/plugins/platforms/android/src/qandroidsystemlocale.h (renamed from src/plugins/platforms/kms/qkmsudevdrmhandler.h)25
-rw-r--r--src/plugins/platforms/android/src/src.pri6
-rw-r--r--src/plugins/platforms/cocoa/main.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm12
-rw-r--r--src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.h8
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm128
-rw-r--r--src/plugins/platforms/cocoa/qcocoafontdialoghelper.h11
-rw-r--r--src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm265
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm26
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaservices.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm4
-rwxr-xr-xsrc/plugins/platforms/cocoa/qcocoasystemtrayicon.mm18
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm3
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm25
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac.mm10
-rw-r--r--src/plugins/platforms/directfb/main.cpp2
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.cpp8
-rw-r--r--src/plugins/platforms/eglfs/main.cpp2
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp36
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.h3
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp6
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h7
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp31
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h4
-rw-r--r--src/plugins/platforms/ios/ios.pro40
-rw-r--r--src/plugins/platforms/ios/plugin.mm6
-rw-r--r--src/plugins/platforms/ios/plugin.pro36
-rw-r--r--src/plugins/platforms/ios/qiosapplicationdelegate.h4
-rw-r--r--src/plugins/platforms/ios/qiosapplicationdelegate.mm59
-rw-r--r--src/plugins/platforms/ios/qiosapplicationstate.h (renamed from src/plugins/platforms/kms/qkmsudevhandler.cpp)19
-rw-r--r--src/plugins/platforms/ios/qiosapplicationstate.mm162
-rw-r--r--src/plugins/platforms/ios/qioscontext.mm2
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.h1
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm11
-rw-r--r--src/plugins/platforms/ios/qiosintegration.h3
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm10
-rw-r--r--src/plugins/platforms/ios/qiosmain_dummy.mm (renamed from src/plugins/platforms/kms/qkmsudevhandler.h)32
-rw-r--r--src/plugins/platforms/ios/qiosmain_wrapper.mm (renamed from src/plugins/platforms/kms/qkmsudevdrmhandler.cpp)34
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm18
-rw-r--r--src/plugins/platforms/ios/qtmain.mm94
-rw-r--r--src/plugins/platforms/ios/qtmain.pro8
-rw-r--r--src/plugins/platforms/kms/kms.pro6
-rw-r--r--src/plugins/platforms/kms/main.cpp2
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.cpp43
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.h14
-rw-r--r--src/plugins/platforms/linuxfb/main.cpp2
-rw-r--r--src/plugins/platforms/minimal/main.cpp2
-rw-r--r--src/plugins/platforms/minimalegl/main.cpp2
-rw-r--r--src/plugins/platforms/offscreen/main.cpp2
-rw-r--r--src/plugins/platforms/openwfd/main.cpp2
-rw-r--r--src/plugins/platforms/qnx/main.cpp3
-rw-r--r--src/plugins/platforms/qnx/main.h2
-rw-r--r--src/plugins/platforms/qnx/qnx.pro31
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.cpp12
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper.h28
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp217
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp (renamed from src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp)36
-rw-r--r--src/plugins/platforms/qnx/qqnxfilepicker.cpp289
-rw-r--r--src/plugins/platforms/qnx/qqnxfilepicker.h (renamed from src/plugins/platforms/kms/qkmsudevlistener.cpp)113
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp154
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.h15
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp34
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h15
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp27
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp27
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.h1
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxtheme.cpp4
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp148
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h19
-rw-r--r--src/plugins/platforms/windows/main.cpp6
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h7
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp40
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp211
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp141
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h2
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp473
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.h142
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp26
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h3
-rw-r--r--src/plugins/platforms/windows/windows.pro6
-rw-r--r--src/plugins/platforms/xcb/main.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp33
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h15
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp288
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp30
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp47
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h13
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp180
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.h87
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp6
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro6
-rw-r--r--src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp28
-rw-r--r--src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h12
-rw-r--r--src/printsupport/doc/qtprintsupport.qdocconf3
-rw-r--r--src/printsupport/doc/src/qtprintsupport-module.qdoc1
-rw-r--r--src/sql/doc/qtsql.qdocconf3
-rw-r--r--src/sql/doc/src/qtsql.qdoc1
-rw-r--r--src/src.pro6
-rw-r--r--src/testlib/doc/qttestlib.qdocconf3
-rw-r--r--src/testlib/doc/src/qttest.qdoc1
-rw-r--r--src/testlib/doc/src/qttestlib-manual.qdoc3
-rw-r--r--src/testlib/qabstracttestlogger.cpp10
-rw-r--r--src/testlib/qtestcase.cpp35
-rw-r--r--src/testlib/qtestresult.cpp8
-rw-r--r--src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp12
-rw-r--r--src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp4
-rw-r--r--src/tools/qdoc/codemarker.cpp2
-rw-r--r--src/tools/qdoc/codeparser.cpp57
-rw-r--r--src/tools/qdoc/codeparser.h2
-rw-r--r--src/tools/qdoc/config.cpp13
-rw-r--r--src/tools/qdoc/config.h7
-rw-r--r--src/tools/qdoc/cppcodemarker.cpp59
-rw-r--r--src/tools/qdoc/cppcodeparser.cpp381
-rw-r--r--src/tools/qdoc/cppcodeparser.h14
-rw-r--r--src/tools/qdoc/ditaxmlgenerator.cpp68
-rw-r--r--src/tools/qdoc/doc.cpp52
-rw-r--r--src/tools/qdoc/doc.h9
-rw-r--r--src/tools/qdoc/doc/config/qdoc.qdocconf2
-rw-r--r--src/tools/qdoc/generator.cpp73
-rw-r--r--src/tools/qdoc/generator.h27
-rw-r--r--src/tools/qdoc/helpprojectwriter.cpp67
-rw-r--r--src/tools/qdoc/htmlgenerator.cpp588
-rw-r--r--src/tools/qdoc/htmlgenerator.h20
-rw-r--r--src/tools/qdoc/main.cpp24
-rw-r--r--src/tools/qdoc/node.cpp160
-rw-r--r--src/tools/qdoc/node.h63
-rw-r--r--src/tools/qdoc/puredocparser.cpp81
-rw-r--r--src/tools/qdoc/qdocdatabase.cpp2
-rw-r--r--src/tools/qdoc/qdocindexfiles.cpp56
-rw-r--r--src/tools/qdoc/qdoctagfiles.cpp10
-rw-r--r--src/tools/qdoc/qmlcodeparser.cpp67
-rw-r--r--src/tools/qdoc/qmlcodeparser.h4
-rw-r--r--src/tools/qdoc/qmlvisitor.cpp219
-rw-r--r--src/tools/qdoc/qmlvisitor.h11
-rw-r--r--src/tools/qdoc/tree.cpp2
-rw-r--r--src/tools/uic/main.cpp7
-rw-r--r--src/tools/uic/option.h1
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp240
-rw-r--r--src/widgets/dialogs/qcolordialog.h4
-rw-r--r--src/widgets/dialogs/qcolordialog_p.h8
-rw-r--r--src/widgets/dialogs/qdialog_p.h2
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp417
-rw-r--r--src/widgets/dialogs/qfiledialog.h64
-rw-r--r--src/widgets/dialogs/qfiledialog_p.h40
-rw-r--r--src/widgets/dialogs/qfileinfogatherer.cpp2
-rw-r--r--src/widgets/dialogs/qfileinfogatherer_p.h8
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp2
-rw-r--r--src/widgets/dialogs/qfilesystemmodel_p.h2
-rw-r--r--src/widgets/dialogs/qfontdialog.cpp28
-rw-r--r--src/widgets/dialogs/qfontdialog.h6
-rw-r--r--src/widgets/dialogs/qinputdialog.cpp112
-rw-r--r--src/widgets/dialogs/qinputdialog.h9
-rw-r--r--src/widgets/doc/qtwidgets.qdocconf3
-rw-r--r--src/widgets/doc/src/qtwidgets.qdoc1
-rw-r--r--src/widgets/graphicsview/qgridlayoutengine.cpp9
-rw-r--r--src/widgets/itemviews/itemviews.pri1
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp20
-rw-r--r--src/widgets/itemviews/qabstractitemview_p.h2
-rw-r--r--src/widgets/itemviews/qcolumnview.cpp11
-rw-r--r--src/widgets/itemviews/qfileiconprovider.cpp93
-rw-r--r--src/widgets/itemviews/qfileiconprovider.h14
-rw-r--r--src/widgets/itemviews/qfileiconprovider_p.h87
-rw-r--r--src/widgets/itemviews/qheaderview.cpp96
-rw-r--r--src/widgets/itemviews/qheaderview.h5
-rw-r--r--src/widgets/itemviews/qheaderview_p.h5
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp4
-rw-r--r--src/widgets/itemviews/qtableview.cpp219
-rw-r--r--src/widgets/itemviews/qtableview.h2
-rw-r--r--src/widgets/itemviews/qtableview_p.h2
-rw-r--r--src/widgets/itemviews/qtreeview.cpp195
-rw-r--r--src/widgets/itemviews/qtreeview.h5
-rw-r--r--src/widgets/itemviews/qtreeview_p.h14
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp6
-rw-r--r--src/widgets/kernel/qapplication.cpp73
-rw-r--r--src/widgets/kernel/qapplication_p.h4
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp1
-rw-r--r--src/widgets/kernel/qlayout.cpp4
-rw-r--r--src/widgets/kernel/qlayoutitem.cpp2
-rw-r--r--src/widgets/kernel/qsizepolicy.h5
-rw-r--r--src/widgets/kernel/qsizepolicy.qdoc17
-rw-r--r--src/widgets/kernel/qtooltip.cpp36
-rw-r--r--src/widgets/kernel/qtooltip.h2
-rw-r--r--src/widgets/kernel/qwidget.cpp63
-rw-r--r--src/widgets/kernel/qwidget.h3
-rw-r--r--src/widgets/kernel/qwidget_p.h2
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp2
-rw-r--r--src/widgets/styles/images/cleartext-16.pngbin0 -> 760 bytes
-rw-r--r--src/widgets/styles/qcommonstyle.cpp32
-rw-r--r--src/widgets/styles/qgtkstyle_p.cpp3
-rw-r--r--src/widgets/styles/qstyle.cpp11
-rw-r--r--src/widgets/styles/qstyle.h4
-rw-r--r--src/widgets/styles/qstyle.qrc1
-rw-r--r--src/widgets/util/qsystemtrayicon_x11.cpp150
-rw-r--r--src/widgets/util/util.pri1
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp96
-rw-r--r--src/widgets/widgets/qabstractscrollarea.h12
-rw-r--r--src/widgets/widgets/qabstractscrollarea_p.h4
-rw-r--r--src/widgets/widgets/qcombobox.cpp14
-rw-r--r--src/widgets/widgets/qcombobox.h3
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp15
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.h3
-rw-r--r--src/widgets/widgets/qfontcombobox.cpp99
-rw-r--r--src/widgets/widgets/qlineedit.cpp124
-rw-r--r--src/widgets/widgets/qlineedit.h25
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp171
-rw-r--r--src/widgets/widgets/qlineedit_p.h82
-rw-r--r--src/widgets/widgets/qscrollarea.cpp12
-rw-r--r--src/widgets/widgets/qscrollarea.h2
-rw-r--r--src/widgets/widgets/qscrollbar.cpp5
-rw-r--r--src/widgets/widgets/qspinbox.cpp64
-rw-r--r--src/widgets/widgets/qspinbox.h3
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp16
-rw-r--r--src/widgets/widgets/qsplashscreen.h1
-rw-r--r--src/widgets/widgets/qtabbar.cpp46
-rw-r--r--src/widgets/widgets/qtabbar.h3
-rw-r--r--src/widgets/widgets/qtabbar_p.h5
-rw-r--r--src/widgets/widgets/qtabwidget.cpp24
-rw-r--r--src/widgets/widgets/qtabwidget.h2
-rw-r--r--src/widgets/widgets/qtextedit.cpp36
-rw-r--r--src/widgets/widgets/qtextedit.h4
-rw-r--r--src/widgets/widgets/qtextedit_p.h2
-rw-r--r--src/widgets/widgets/qwidgetanimator.cpp28
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp4
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp13
-rw-r--r--src/xml/doc/qtxml.qdocconf3
-rw-r--r--src/xml/doc/src/qtxml.qdoc1
-rwxr-xr-xtests/auto/android/runtests.pl11
-rw-r--r--tests/auto/android/src/org/qtproject/qt5/android/QtActivity.java10
-rw-r--r--tests/auto/android/src/org/qtproject/qt5/android/QtNative.java13
-rw-r--r--tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp4
-rw-r--r--tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp4
-rw-r--r--tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp8
-rw-r--r--tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp11
-rw-r--r--tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp3
-rw-r--r--tests/auto/corelib/io/qurl/tst_qurl.cpp399
-rw-r--r--tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp23
-rw-r--r--tests/auto/corelib/json/tst_qtjson.cpp86
-rw-r--r--tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp30
-rw-r--r--tests/auto/corelib/kernel/qmetatype/qmetatype.pro1
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp450
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp51
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp314
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/fakeplugin.cpp (renamed from mkspecs/macx-clang-libc++-32/qplatformdefs.h)12
-rwxr-xr-xtests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl209
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro56
-rwxr-xr-xtests/auto/corelib/plugin/qpluginloader/machtest/ppcconverter.pl112
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro1
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst/tst.pro5
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp78
-rw-r--r--tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp32
-rw-r--r--tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp80
-rw-r--r--tests/auto/corelib/tools/qdate/tst_qdate.cpp56
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp128
-rw-r--r--tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp14
-rw-r--r--tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro1
-rw-r--r--tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp155
-rw-r--r--tests/auto/corelib/tools/qtime/tst_qtime.cpp84
-rw-r--r--tests/auto/dbus/qdbusabstractinterface/interface.h3
-rw-r--r--tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml4
-rw-r--r--tests/auto/dbus/qdbusabstractinterface/pinger.h152
-rw-r--r--tests/auto/dbus/qdbusabstractinterface/test/test.pro8
-rw-r--r--tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp34
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp49
-rw-r--r--tests/auto/gui/kernel/qbackingstore/qbackingstore.pro1
-rw-r--r--tests/auto/gui/kernel/qinputmethod/qinputmethod.pro1
-rw-r--r--tests/auto/gui/painting/qcolor/tst_qcolor.cpp81
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp81
-rw-r--r--tests/auto/gui/text/qcssparser/tst_qcssparser.cpp5
-rw-r--r--tests/auto/gui/text/qfontdatabase/qfontdatabase.pro3
-rw-r--r--tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp13
-rw-r--r--tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp35
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp61
-rw-r--r--tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp4
-rw-r--r--tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp2
-rw-r--r--tests/auto/other/exceptionsafety/.gitignore1
-rw-r--r--tests/auto/other/exceptionsafety/exceptionsafety.pro6
-rw-r--r--tests/auto/other/exceptionsafety/tst_exceptionsafety.cpp846
-rw-r--r--tests/auto/other/exceptionsafety_objects/3rdparty/memcheck.h319
-rw-r--r--tests/auto/other/exceptionsafety_objects/3rdparty/valgrind.h3924
-rw-r--r--tests/auto/other/exceptionsafety_objects/exceptionsafety_objects.pro6
-rw-r--r--tests/auto/other/exceptionsafety_objects/oomsimulator.h293
-rw-r--r--tests/auto/other/exceptionsafety_objects/tst_exceptionsafety_objects.cpp803
-rw-r--r--tests/auto/other/other.pro3
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.lightxml8
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.txt8
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.xml8
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.xunitxml8
-rw-r--r--tests/auto/testlib/selftests/expected_datetime.lightxml2
-rw-r--r--tests/auto/testlib/selftests/expected_datetime.txt2
-rw-r--r--tests/auto/testlib/selftests/expected_datetime.xml2
-rw-r--r--tests/auto/testlib/selftests/expected_datetime.xunitxml2
-rw-r--r--tests/auto/testlib/selftests/expected_float.txt6
-rw-r--r--tests/auto/testlib/selftests/expected_strcmp.lightxml4
-rw-r--r--tests/auto/testlib/selftests/expected_strcmp.txt4
-rw-r--r--tests/auto/testlib/selftests/expected_strcmp.xml4
-rw-r--r--tests/auto/testlib/selftests/expected_strcmp.xunitxml4
-rw-r--r--tests/auto/testlib/selftests/expected_subtest.lightxml4
-rw-r--r--tests/auto/testlib/selftests/expected_subtest.txt4
-rw-r--r--tests/auto/testlib/selftests/expected_subtest.xml4
-rw-r--r--tests/auto/testlib/selftests/expected_subtest.xunitxml4
-rw-r--r--tests/auto/tools/moc/interface-from-include.h (renamed from mkspecs/macx-clang-libc++/qplatformdefs.h)16
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp41
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp48
-rw-r--r--tests/auto/widgets/graphicsview/graphicsview.pro4
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicseffectsource/qgraphicseffectsource.pro1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsgridlayout/qgraphicsgridlayout.pro1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp38
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicssceneindex/qgraphicssceneindex.pro1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp3
-rw-r--r--tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp32
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp2
-rw-r--r--tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp43
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp146
-rw-r--r--tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp37
-rw-r--r--tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp91
-rw-r--r--tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp58
-rw-r--r--tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp42
-rw-r--r--tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp42
-rw-r--r--tests/benchmarks/corelib/io/qfile/main.cpp4
-rw-r--r--tests/benchmarks/corelib/tools/qset/main.cpp141
-rw-r--r--tests/benchmarks/corelib/tools/qset/qset.pro4
-rw-r--r--tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp21
-rw-r--r--tests/benchmarks/network/access/qnetworkreply/qnetworkreply.pro2
-rw-r--r--tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp127
-rw-r--r--tests/manual/corelib/tools/qhash/main.cpp85
-rw-r--r--tests/manual/corelib/tools/qhash/main.pro1
-rw-r--r--tests/manual/corelib/tools/qlist/main.cpp71
-rw-r--r--tests/manual/corelib/tools/qlist/main.pro1
-rw-r--r--tests/manual/corelib/tools/qmap/main.cpp (renamed from tests/auto/dbus/qdbusabstractinterface/pinger.cpp)82
-rw-r--r--tests/manual/corelib/tools/qmap/qmaptest.pro2
-rw-r--r--tests/manual/corelib/tools/qset/main.cpp63
-rw-r--r--tests/manual/corelib/tools/qset/main.pro1
-rw-r--r--tests/manual/corelib/tools/qvarlengtharray/main.cpp76
-rw-r--r--tests/manual/corelib/tools/qvarlengtharray/main.pro1
-rw-r--r--tests/manual/corelib/tools/qvector/main.cpp76
-rw-r--r--tests/manual/corelib/tools/qvector/main.pro1
-rw-r--r--tests/manual/dialogs/colordialogpanel.h2
-rw-r--r--tests/manual/dialogs/dialogs.pro4
-rw-r--r--tests/manual/dialogs/filedialogpanel.cpp75
-rw-r--r--tests/manual/dialogs/filedialogpanel.h9
-rw-r--r--tests/manual/dialogs/fontdialogpanel.cpp12
-rw-r--r--tests/manual/dialogs/fontdialogpanel.h6
-rw-r--r--tests/manual/dialogs/main.cpp2
-rw-r--r--tests/manual/dialogs/messageboxpanel.cpp181
-rw-r--r--tests/manual/dialogs/messageboxpanel.h84
-rw-r--r--tests/manual/dialogs/wizardpanel.h2
-rw-r--r--tests/manual/manual.pro1
-rw-r--r--tests/manual/qdesktopservices/tst_qdesktopservices.cpp7
-rw-r--r--tests/manual/qnetworkconfiguration/main.cpp139
-rw-r--r--tests/manual/qnetworkconfiguration/qnetworkconfiguration.pro7
-rw-r--r--tests/manual/qpainfo/main.cpp14
-rw-r--r--tests/manual/qtabletevent/regular_widgets/main.cpp83
-rw-r--r--tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.cpp115
-rw-r--r--tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.pro2
-rw-r--r--tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.cpp125
-rw-r--r--tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.pro2
-rw-r--r--tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.cpp132
-rw-r--r--tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.pro2
-rw-r--r--tests/manual/widgets/itemviews/itemviews.pro2
-rw-r--r--tests/manual/widgets/itemviews/qtreeview/main.cpp35
-rw-r--r--tests/manual/widgets/itemviews/qtreewidget/main.cpp152
-rw-r--r--tests/manual/widgets/itemviews/qtreewidget/qtreewidgettest.pro4
-rw-r--r--tests/manual/widgets/kernel/kernel.pro2
-rw-r--r--tests/manual/widgets/kernel/qtooltip/main.cpp161
-rw-r--r--tests/manual/widgets/kernel/qtooltip/main.pro2
-rw-r--r--tests/manual/widgets/kernel/sizeonhide/main.cpp134
-rw-r--r--tests/manual/widgets/kernel/sizeonhide/sizeonhide.pro3
-rw-r--r--tests/manual/widgets/qgraphicsview/rubberband/rubberbandtest.cpp4
-rw-r--r--tests/manual/widgets/widgets.pro3
-rw-r--r--tools/configure/configureapp.cpp39
-rw-r--r--util/local_database/enumdata.py3
-rw-r--r--util/unicode/main.cpp51
765 files changed, 23845 insertions, 13948 deletions
diff --git a/.gitignore b/.gitignore
index 5f9854a674..14aa3a77a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,6 +61,8 @@ Makefile*
*.pro.user*
*.qmlproject.user*
*.gcov
+*.gcda
+*.gcno
bin/Qt*.dll
bin/assistant*
bin/designer*
@@ -118,6 +120,8 @@ qmake/qmake_pch.pch
src/corelib/global/qconfig.cpp
src/corelib/global/qconfig.h
src/corelib/global/qconfig.h.qmake
+src/platformsupport/*_interface.*
+src/platformsupport/*_adaptor.*
ui_*.h
tests/auto/qprocess/test*/*.exe
tests/auto/qtcpsocket/stressTest/*.exe
@@ -310,6 +314,7 @@ tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness
tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper
tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver
tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger
+tests/auto/dbus/qdbusabstractinterface/test/pinger_interface.*
tests/auto/dbus/qdbusinterface/qmyserver/qmyserver
tests/auto/gui/kernel/qfileopenevent/qfileopeneventexternal/qfileopeneventexternal
tests/auto/network/bearer/qnetworksession/lackey/lackey
diff --git a/config.tests/arch/arch.pro b/config.tests/arch/arch.pro
index fda4acc601..d89d70b1ee 100644
--- a/config.tests/arch/arch.pro
+++ b/config.tests/arch/arch.pro
@@ -2,4 +2,3 @@ TARGET = arch
SOURCES = arch.cpp
CONFIG -= qt dylib release debug_and_release
CONFIG += debug console
-mac:CONFIG -= app_bundle
diff --git a/config.tests/common/avx/avx.pro b/config.tests/common/avx/avx.pro
index ba7fd96e43..8d1b9702bc 100644
--- a/config.tests/common/avx/avx.pro
+++ b/config.tests/common/avx/avx.pro
@@ -1,6 +1,5 @@
SOURCES = avx.cpp
CONFIG -= qt dylib release debug_and_release
CONFIG += debug console
-mac:CONFIG -= app_bundle
isEmpty(QMAKE_CFLAGS_AVX):error("This compiler does not support AVX")
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_AVX
diff --git a/config.tests/common/avx2/avx2.pro b/config.tests/common/avx2/avx2.pro
index 5aa9429d68..927f64efc8 100644
--- a/config.tests/common/avx2/avx2.pro
+++ b/config.tests/common/avx2/avx2.pro
@@ -1,6 +1,5 @@
SOURCES = avx2.cpp
CONFIG -= qt dylib release debug_and_release
CONFIG += debug console
-mac:CONFIG -= app_bundle
isEmpty(QMAKE_CFLAGS_AVX2):error("This compiler does not support AVX2")
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_AVX2
diff --git a/config.tests/common/c++11/c++11.pro b/config.tests/common/c++11/c++11.pro
index dd4042b8d6..dbe764ba84 100644
--- a/config.tests/common/c++11/c++11.pro
+++ b/config.tests/common/c++11/c++11.pro
@@ -1,3 +1,3 @@
SOURCES = c++11.cpp
CONFIG += c++11
-CONFIG -= qt app_bundle
+CONFIG -= qt
diff --git a/config.tests/common/sse2/sse2.pro b/config.tests/common/sse2/sse2.pro
index c8d0861170..b4031f13fa 100644
--- a/config.tests/common/sse2/sse2.pro
+++ b/config.tests/common/sse2/sse2.pro
@@ -1,6 +1,5 @@
SOURCES = sse2.cpp
CONFIG -= qt dylib release debug_and_release
CONFIG += debug console
-mac:CONFIG -= app_bundle
isEmpty(QMAKE_CFLAGS_SSE2):error("This compiler does not support SSE2")
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2
diff --git a/config.tests/common/sse3/sse3.pro b/config.tests/common/sse3/sse3.pro
index 90f61d2065..f704c40c75 100644
--- a/config.tests/common/sse3/sse3.pro
+++ b/config.tests/common/sse3/sse3.pro
@@ -1,6 +1,5 @@
SOURCES = sse3.cpp
CONFIG -= qt dylib release debug_and_release
CONFIG += debug console
-mac:CONFIG -= app_bundle
isEmpty(QMAKE_CFLAGS_SSE3):error("This compiler does not support SSE3")
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE3
diff --git a/config.tests/common/sse4_1/sse4_1.pro b/config.tests/common/sse4_1/sse4_1.pro
index d92be9dc43..5cc04e7c5c 100644
--- a/config.tests/common/sse4_1/sse4_1.pro
+++ b/config.tests/common/sse4_1/sse4_1.pro
@@ -1,6 +1,5 @@
SOURCES = sse4_1.cpp
CONFIG -= qt dylib release debug_and_release
CONFIG += debug console
-mac:CONFIG -= app_bundle
isEmpty(QMAKE_CFLAGS_SSE4_1):error("This compiler does not support SSE4.1")
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE4_1
diff --git a/config.tests/common/sse4_2/sse4_2.pro b/config.tests/common/sse4_2/sse4_2.pro
index 744098dce8..6a04b1f9a5 100644
--- a/config.tests/common/sse4_2/sse4_2.pro
+++ b/config.tests/common/sse4_2/sse4_2.pro
@@ -1,6 +1,5 @@
SOURCES = sse4_2.cpp
CONFIG -= qt dylib release debug_and_release
CONFIG += debug console
-mac:CONFIG -= app_bundle
isEmpty(QMAKE_CFLAGS_SSE4_2):error("This compiler does not support SSE4.2")
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE4_2
diff --git a/config.tests/common/ssse3/ssse3.pro b/config.tests/common/ssse3/ssse3.pro
index e3984bd1cd..5b207e78ce 100644
--- a/config.tests/common/ssse3/ssse3.pro
+++ b/config.tests/common/ssse3/ssse3.pro
@@ -1,6 +1,5 @@
SOURCES = ssse3.cpp
CONFIG -= qt dylib release debug_and_release
CONFIG += debug console
-mac:CONFIG -= app_bundle
isEmpty(QMAKE_CFLAGS_SSSE3):error("This compiler does not support SSSE3")
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSSE3
diff --git a/config.tests/mac/coreservices/coreservices.pro b/config.tests/mac/coreservices/coreservices.pro
index 6f7c07a487..64936eb974 100644
--- a/config.tests/mac/coreservices/coreservices.pro
+++ b/config.tests/mac/coreservices/coreservices.pro
@@ -1,3 +1,3 @@
OBJECTIVE_SOURCES = coreservices.mm
LIBS += -framework CoreServices
-CONFIG -= app_bundle qt
+CONFIG -= qt
diff --git a/config.tests/mac/corewlan/corewlan.pro b/config.tests/mac/corewlan/corewlan.pro
index a9c256043c..8db0c8c1e7 100644
--- a/config.tests/mac/corewlan/corewlan.pro
+++ b/config.tests/mac/corewlan/corewlan.pro
@@ -1,3 +1,3 @@
OBJECTIVE_SOURCES = corewlantest.mm
LIBS += -framework CoreWLAN -framework Foundation
-CONFIG -= app_bundle qt
+CONFIG -= qt
diff --git a/config.tests/qpa/directfb/directfb.pro b/config.tests/qpa/directfb/directfb.pro
index 958ced7bea..b138fd0109 100644
--- a/config.tests/qpa/directfb/directfb.pro
+++ b/config.tests/qpa/directfb/directfb.pro
@@ -1,3 +1,2 @@
SOURCES = directfb.cpp
CONFIG -= qt
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/alsa/alsa.pro b/config.tests/unix/alsa/alsa.pro
index 4931d38ea8..6d5d55bcfd 100644
--- a/config.tests/unix/alsa/alsa.pro
+++ b/config.tests/unix/alsa/alsa.pro
@@ -1,4 +1,3 @@
SOURCES = alsatest.cpp
LIBS+=-lasound
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/arch.test b/config.tests/unix/arch.test
index 3efd6f4f25..529ed5e547 100755
--- a/config.tests/unix/arch.test
+++ b/config.tests/unix/arch.test
@@ -26,7 +26,7 @@ CXXFLAGS="$SYSROOT_FLAG"
test -d "$OUTDIR/config.tests/arch" || mkdir -p "$OUTDIR/config.tests/arch"
cd "$OUTDIR/config.tests/arch"
[ -f Makefile ] && $MAKE distclean >/dev/null 2>&1
-OUTDIR=$OUTDIR "$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "QT_BUILD_TREE=$OUTDIR" "LIBS+=$LFLAGS" "QMAKE_CXXFLAGS+=$CXXFLAGS" "$SRCDIR/config.tests/arch/arch$PROSUFFIX.pro" >/dev/null 2>&1 || echo "qmake is broken" >&2
+OUTDIR=$OUTDIR "$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "QT_BUILD_TREE=$OUTDIR" "LIBS+=$LFLAGS" "QMAKE_CXXFLAGS+=$CXXFLAGS" "CONFIG-=app_bundle" "$SRCDIR/config.tests/arch/arch$PROSUFFIX.pro" >/dev/null 2>&1 || echo "qmake is broken" >&2
ARCH=""
diff --git a/config.tests/unix/clock-gettime/clock-gettime.pro b/config.tests/unix/clock-gettime/clock-gettime.pro
index c527535183..bdbb1c2a82 100644
--- a/config.tests/unix/clock-gettime/clock-gettime.pro
+++ b/config.tests/unix/clock-gettime/clock-gettime.pro
@@ -1,4 +1,3 @@
SOURCES = clock-gettime.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
include(clock-gettime.pri)
diff --git a/config.tests/unix/clock-monotonic/clock-monotonic.pro b/config.tests/unix/clock-monotonic/clock-monotonic.pro
index 961e3a848d..253a9f7346 100644
--- a/config.tests/unix/clock-monotonic/clock-monotonic.pro
+++ b/config.tests/unix/clock-monotonic/clock-monotonic.pro
@@ -1,4 +1,3 @@
SOURCES = clock-monotonic.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
include(../clock-gettime/clock-gettime.pri)
diff --git a/config.tests/unix/compile.test b/config.tests/unix/compile.test
index 6b90044009..22064b85e9 100755
--- a/config.tests/unix/compile.test
+++ b/config.tests/unix/compile.test
@@ -67,7 +67,7 @@ test -r Makefile && $MAKE distclean >/dev/null 2>&1
# Make sure output from possible previous tests is gone
rm -f "$EXE" "${EXE}.exe"
-set -- "$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "CONFIG+=android_app" "CONFIG-=debug_and_release" "LIBS*=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" "QT_BUILD_TREE=$OUTDIR" "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile"
+set -- "$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "CONFIG+=android_app" "CONFIG-=debug_and_release app_bundle lib_bundle" "LIBS*=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" "QT_BUILD_TREE=$OUTDIR" "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile"
if [ "$VERBOSE" = "yes" ]; then
OUTDIR=$OUTDIR "$@"
$MAKE
diff --git a/config.tests/unix/cups/cups.pro b/config.tests/unix/cups/cups.pro
index d7b78c877f..3f8ca99d0f 100644
--- a/config.tests/unix/cups/cups.pro
+++ b/config.tests/unix/cups/cups.pro
@@ -1,4 +1,3 @@
SOURCES = cups.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -lcups
diff --git a/config.tests/unix/db2/db2.pro b/config.tests/unix/db2/db2.pro
index 0fa39a8242..b7316051f9 100644
--- a/config.tests/unix/db2/db2.pro
+++ b/config.tests/unix/db2/db2.pro
@@ -1,4 +1,3 @@
SOURCES = db2.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -ldb2
diff --git a/config.tests/unix/dbus/dbus.pro b/config.tests/unix/dbus/dbus.pro
index 1e4aea73e4..c2a01ea269 100644
--- a/config.tests/unix/dbus/dbus.pro
+++ b/config.tests/unix/dbus/dbus.pro
@@ -1,3 +1,2 @@
SOURCES = dbus.cpp
CONFIG -= qt
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/eventfd/eventfd.pro b/config.tests/unix/eventfd/eventfd.pro
index c41204f49f..de99717750 100644
--- a/config.tests/unix/eventfd/eventfd.pro
+++ b/config.tests/unix/eventfd/eventfd.pro
@@ -1,3 +1,2 @@
SOURCES = main.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/fontconfig/fontconfig.pro b/config.tests/unix/fontconfig/fontconfig.pro
index 5989586751..8360774035 100644
--- a/config.tests/unix/fontconfig/fontconfig.pro
+++ b/config.tests/unix/fontconfig/fontconfig.pro
@@ -1,4 +1,4 @@
SOURCES = fontconfig.cpp
-CONFIG -= qt app_bundle
+CONFIG -= qt
LIBS += -lfreetype -lfontconfig
include(../../unix/freetype/freetype.pri)
diff --git a/config.tests/unix/getaddrinfo/getaddrinfo.pro b/config.tests/unix/getaddrinfo/getaddrinfo.pro
index c9121db9b4..cc739118fa 100644
--- a/config.tests/unix/getaddrinfo/getaddrinfo.pro
+++ b/config.tests/unix/getaddrinfo/getaddrinfo.pro
@@ -1,4 +1,3 @@
SOURCES = getaddrinfotest.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += $$QMAKE_LIBS_NETWORK
diff --git a/config.tests/unix/getifaddrs/getifaddrs.pro b/config.tests/unix/getifaddrs/getifaddrs.pro
index c3fead6354..14a89f87b8 100644
--- a/config.tests/unix/getifaddrs/getifaddrs.pro
+++ b/config.tests/unix/getifaddrs/getifaddrs.pro
@@ -1,5 +1,4 @@
SOURCES = getifaddrs.cpp
CONFIG -= qt
-mac:CONFIG -= app_bundle
QT =
LIBS += $$QMAKE_LIBS_NETWORK
diff --git a/config.tests/unix/glib/glib.pro b/config.tests/unix/glib/glib.pro
index c7cd53d116..15d059df77 100644
--- a/config.tests/unix/glib/glib.pro
+++ b/config.tests/unix/glib/glib.pro
@@ -1,2 +1,2 @@
SOURCES = glib.cpp
-CONFIG -= qt app_bundle
+CONFIG -= qt
diff --git a/config.tests/unix/gnu-libiconv/gnu-libiconv.pro b/config.tests/unix/gnu-libiconv/gnu-libiconv.pro
index d879b205f1..1ecf94390a 100644
--- a/config.tests/unix/gnu-libiconv/gnu-libiconv.pro
+++ b/config.tests/unix/gnu-libiconv/gnu-libiconv.pro
@@ -1,4 +1,3 @@
SOURCES = gnu-libiconv.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -liconv
diff --git a/config.tests/unix/ibase/ibase.pro b/config.tests/unix/ibase/ibase.pro
index 01e7429733..58787851e1 100644
--- a/config.tests/unix/ibase/ibase.pro
+++ b/config.tests/unix/ibase/ibase.pro
@@ -1,4 +1,3 @@
SOURCES = ibase.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -lgds
diff --git a/config.tests/unix/iconv/iconv.pro b/config.tests/unix/iconv/iconv.pro
index 39375a5714..1ef6aa7207 100644
--- a/config.tests/unix/iconv/iconv.pro
+++ b/config.tests/unix/iconv/iconv.pro
@@ -1,3 +1,3 @@
SOURCES = iconv.cpp
-CONFIG -= qt dylib app_bundle
+CONFIG -= qt dylib
mac|win32-g++*|qnx:LIBS += -liconv
diff --git a/config.tests/unix/icu/icu.pro b/config.tests/unix/icu/icu.pro
index 8e583348bb..002c4840d5 100644
--- a/config.tests/unix/icu/icu.pro
+++ b/config.tests/unix/icu/icu.pro
@@ -1,4 +1,4 @@
SOURCES = icu.cpp
-CONFIG -= qt dylib app_bundle
+CONFIG -= qt dylib
unix:LIBS += -licuuc -licui18n
win32:LIBS += -licuin
diff --git a/config.tests/unix/inotify/inotify.pro b/config.tests/unix/inotify/inotify.pro
index e2e1560a47..35880de3c0 100644
--- a/config.tests/unix/inotify/inotify.pro
+++ b/config.tests/unix/inotify/inotify.pro
@@ -1,3 +1,2 @@
SOURCES = inotifytest.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/iodbc/iodbc.pro b/config.tests/unix/iodbc/iodbc.pro
index 465a9a7a1b..68a0bd0ef4 100644
--- a/config.tests/unix/iodbc/iodbc.pro
+++ b/config.tests/unix/iodbc/iodbc.pro
@@ -1,4 +1,3 @@
SOURCES = iodbc.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -liodbc
diff --git a/config.tests/unix/ipv6ifname/ipv6ifname.pro b/config.tests/unix/ipv6ifname/ipv6ifname.pro
index ed62869cb9..88203a782c 100644
--- a/config.tests/unix/ipv6ifname/ipv6ifname.pro
+++ b/config.tests/unix/ipv6ifname/ipv6ifname.pro
@@ -1,5 +1,4 @@
SOURCES = ipv6ifname.cpp
CONFIG -= qt
-mac:CONFIG -= app_bundle
QT =
LIBS += $$QMAKE_LIBS_NETWORK
diff --git a/config.tests/unix/libjpeg/libjpeg.pro b/config.tests/unix/libjpeg/libjpeg.pro
index d06888c57d..01329a11fe 100644
--- a/config.tests/unix/libjpeg/libjpeg.pro
+++ b/config.tests/unix/libjpeg/libjpeg.pro
@@ -1,4 +1,3 @@
SOURCES = libjpeg.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -ljpeg
diff --git a/config.tests/unix/libpng/libpng.pro b/config.tests/unix/libpng/libpng.pro
index f03838663e..4e50fe26e5 100644
--- a/config.tests/unix/libpng/libpng.pro
+++ b/config.tests/unix/libpng/libpng.pro
@@ -1,4 +1,3 @@
SOURCES = libpng.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -lpng
diff --git a/config.tests/unix/mremap/mremap.pro b/config.tests/unix/mremap/mremap.pro
index a36d756db3..1dbd3b7a7e 100644
--- a/config.tests/unix/mremap/mremap.pro
+++ b/config.tests/unix/mremap/mremap.pro
@@ -1,3 +1,2 @@
SOURCES = mremap.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/mysql/mysql.pro b/config.tests/unix/mysql/mysql.pro
index a22579e1bd..06d1880f08 100644
--- a/config.tests/unix/mysql/mysql.pro
+++ b/config.tests/unix/mysql/mysql.pro
@@ -1,4 +1,3 @@
SOURCES = mysql.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -lmysqlclient
diff --git a/config.tests/unix/mysql_r/mysql_r.pro b/config.tests/unix/mysql_r/mysql_r.pro
index 8c06067305..096da69487 100644
--- a/config.tests/unix/mysql_r/mysql_r.pro
+++ b/config.tests/unix/mysql_r/mysql_r.pro
@@ -1,4 +1,3 @@
SOURCES = ../mysql/mysql.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -lmysqlclient_r
diff --git a/config.tests/unix/nis/nis.pro b/config.tests/unix/nis/nis.pro
index 1f985b2049..b7f5693b60 100644
--- a/config.tests/unix/nis/nis.pro
+++ b/config.tests/unix/nis/nis.pro
@@ -1,5 +1,4 @@
SOURCES = nis.cpp
CONFIG -= qt dylib
-mac: CONFIG -= app_bundle
solaris-*:LIBS += -lnsl
else:LIBS += $$QMAKE_LIBS_NIS
diff --git a/config.tests/unix/oci/oci.pro b/config.tests/unix/oci/oci.pro
index 4add225f5d..3ffda1ddd7 100644
--- a/config.tests/unix/oci/oci.pro
+++ b/config.tests/unix/oci/oci.pro
@@ -1,4 +1,3 @@
SOURCES = oci.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -lclntsh
diff --git a/config.tests/unix/odbc/odbc.pro b/config.tests/unix/odbc/odbc.pro
index 06a548fd71..418a0e0d54 100644
--- a/config.tests/unix/odbc/odbc.pro
+++ b/config.tests/unix/odbc/odbc.pro
@@ -1,5 +1,4 @@
SOURCES = odbc.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
win32-g++*:LIBS += -lodbc32
else:LIBS += -lodbc
diff --git a/config.tests/unix/opengldesktop/opengldesktop.pro b/config.tests/unix/opengldesktop/opengldesktop.pro
index fbf36a0c67..c3e700c50a 100644
--- a/config.tests/unix/opengldesktop/opengldesktop.pro
+++ b/config.tests/unix/opengldesktop/opengldesktop.pro
@@ -9,4 +9,3 @@ CONFIG -= qt
LIBS += $$QMAKE_LIBS_OPENGL
mac:DEFINES += Q_OS_MAC
-CONFIG -= app_bundle
diff --git a/config.tests/unix/opengles1/opengles1.pro b/config.tests/unix/opengles1/opengles1.pro
index 9e6012474d..58817e6a6e 100644
--- a/config.tests/unix/opengles1/opengles1.pro
+++ b/config.tests/unix/opengles1/opengles1.pro
@@ -9,5 +9,4 @@ CONFIG -= qt
LIBS += $$QMAKE_LIBS_OPENGL_ES1
mac {
DEFINES += BUILD_ON_MAC
- CONFIG -= app_bundle
}
diff --git a/config.tests/unix/opengles2/opengles2.pro b/config.tests/unix/opengles2/opengles2.pro
index 34d77371b4..c4d76895a8 100644
--- a/config.tests/unix/opengles2/opengles2.pro
+++ b/config.tests/unix/opengles2/opengles2.pro
@@ -9,5 +9,4 @@ CONFIG -= qt
LIBS += $$QMAKE_LIBS_OPENGL_ES2
mac {
DEFINES += BUILD_ON_MAC
- CONFIG -= app_bundle
}
diff --git a/config.tests/unix/openssl/openssl.pro b/config.tests/unix/openssl/openssl.pro
index 1c537cb2b1..a023aee4aa 100644
--- a/config.tests/unix/openssl/openssl.pro
+++ b/config.tests/unix/openssl/openssl.pro
@@ -1,3 +1,2 @@
SOURCES = openssl.cpp
CONFIG -= x11 qt
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/pcre/pcre.pro b/config.tests/unix/pcre/pcre.pro
index b29c55da47..7b8bfc6545 100644
--- a/config.tests/unix/pcre/pcre.pro
+++ b/config.tests/unix/pcre/pcre.pro
@@ -1,3 +1,3 @@
SOURCES = pcre.cpp
-CONFIG -= qt dylib app_bundle
+CONFIG -= qt dylib
LIBS += -lpcre16
diff --git a/config.tests/unix/psql/psql.pro b/config.tests/unix/psql/psql.pro
index 38bfb3ed70..d0f3761bfb 100644
--- a/config.tests/unix/psql/psql.pro
+++ b/config.tests/unix/psql/psql.pro
@@ -1,4 +1,3 @@
SOURCES = psql.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS *= -lpq
diff --git a/config.tests/unix/ptrsize.test b/config.tests/unix/ptrsize.test
index c78c73f7a2..3ad15dbd2b 100755
--- a/config.tests/unix/ptrsize.test
+++ b/config.tests/unix/ptrsize.test
@@ -10,7 +10,7 @@ OUTDIR=$4
# build and run a test program
test -d "$OUTDIR/config.tests/unix/ptrsize" || mkdir -p "$OUTDIR/config.tests/unix/ptrsize"
-"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "QT_BUILD_TREE=$OUTDIR" "$SRCDIR/config.tests/unix/ptrsize/ptrsizetest.pro" -o "$OUTDIR/config.tests/unix/ptrsize/Makefile" >/dev/null 2>&1
+"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "QT_BUILD_TREE=$OUTDIR" "CONFIG-=app_bundle" "$SRCDIR/config.tests/unix/ptrsize/ptrsizetest.pro" -o "$OUTDIR/config.tests/unix/ptrsize/Makefile" >/dev/null 2>&1
cd "$OUTDIR/config.tests/unix/ptrsize"
if [ "$VERBOSE" = "yes" ]; then
diff --git a/config.tests/unix/ptrsize/ptrsizetest.pro b/config.tests/unix/ptrsize/ptrsizetest.pro
index 41aba86dd9..045a759ec9 100644
--- a/config.tests/unix/ptrsize/ptrsizetest.pro
+++ b/config.tests/unix/ptrsize/ptrsizetest.pro
@@ -1,3 +1,2 @@
SOURCES = ptrsizetest.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/slog2/slog2.pro b/config.tests/unix/slog2/slog2.pro
index 9f5b34d664..e65460bb94 100644
--- a/config.tests/unix/slog2/slog2.pro
+++ b/config.tests/unix/slog2/slog2.pro
@@ -1,4 +1,3 @@
SOURCES = slog2.cpp
CONFIG -= qt
-mac:CONFIG -= app_bundle
LIBS += -lslog2
diff --git a/config.tests/unix/sqlite/sqlite.pro b/config.tests/unix/sqlite/sqlite.pro
index ba2cac1465..4b24e014ba 100644
--- a/config.tests/unix/sqlite/sqlite.pro
+++ b/config.tests/unix/sqlite/sqlite.pro
@@ -1,3 +1,2 @@
SOURCES = sqlite.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/sqlite2/sqlite2.pro b/config.tests/unix/sqlite2/sqlite2.pro
index 14a64d5db9..7e69fdf2f3 100644
--- a/config.tests/unix/sqlite2/sqlite2.pro
+++ b/config.tests/unix/sqlite2/sqlite2.pro
@@ -1,4 +1,3 @@
SOURCES = sqlite2.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -lsqlite
diff --git a/config.tests/unix/stdint/stdint.pro b/config.tests/unix/stdint/stdint.pro
index 79a0d9cd3a..9975484889 100644
--- a/config.tests/unix/stdint/stdint.pro
+++ b/config.tests/unix/stdint/stdint.pro
@@ -1,4 +1,3 @@
SOURCES = main.cpp
CONFIG -= x11 qt
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/stl/stl.pro b/config.tests/unix/stl/stl.pro
index a2feab431c..7303e8d31c 100644
--- a/config.tests/unix/stl/stl.pro
+++ b/config.tests/unix/stl/stl.pro
@@ -1,3 +1,2 @@
SOURCES = stltest.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/sun-libiconv/sun-libiconv.pro b/config.tests/unix/sun-libiconv/sun-libiconv.pro
index 00df8653c8..923afc7dd2 100644
--- a/config.tests/unix/sun-libiconv/sun-libiconv.pro
+++ b/config.tests/unix/sun-libiconv/sun-libiconv.pro
@@ -1,2 +1,2 @@
SOURCES = ../gnu-libiconv/gnu-libiconv.cpp
-CONFIG -= qt dylib app_bundle
+CONFIG -= qt dylib
diff --git a/config.tests/unix/tds/tds.pro b/config.tests/unix/tds/tds.pro
index 5516a14c8f..6712779d58 100644
--- a/config.tests/unix/tds/tds.pro
+++ b/config.tests/unix/tds/tds.pro
@@ -1,4 +1,3 @@
SOURCES = tds.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -lsybdb
diff --git a/config.tests/unix/zlib/zlib.pro b/config.tests/unix/zlib/zlib.pro
index 67cc870516..d9bd03e5df 100644
--- a/config.tests/unix/zlib/zlib.pro
+++ b/config.tests/unix/zlib/zlib.pro
@@ -1,4 +1,3 @@
SOURCES = zlib.cpp
CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
LIBS += -lz
diff --git a/configure b/configure
index ba6248eba8..b4ba4a6934 100755
--- a/configure
+++ b/configure
@@ -1518,6 +1518,11 @@ while [ "$#" -gt 0 ]; do
QTCONFIG_CONFIG="$QTCONFIG_CONFIG testcocoon"
fi
;;
+ gcov)
+ if [ "$VAL" = "yes" ]; then
+ QTCONFIG_CONFIG="$QTCONFIG_CONFIG gcov"
+ fi
+ ;;
platform)
PLATFORM="$VAL"
# keep compatibility with old platform names
@@ -2457,47 +2462,7 @@ if [ "$OPT_SHADOW" = "yes" ]; then
[ -d "$outpath/bin" ] || mkdir -p "$outpath/bin"
- # save a pre-existing mkspecs/modules dir
- test -d "$outpath/mkspecs/modules" && \
- mv "$outpath/mkspecs/modules" "$outpath/mkspecs-modules"
- # ditto for mkspecs/modules-inst
- test -d "$outpath/mkspecs/modules-inst" && \
- mv "$outpath/mkspecs/modules-inst" "$outpath/mkspecs-modules-inst"
-
- # symlink the mkspecs directory
mkdir -p "$outpath/mkspecs"
- rm -rf "$outpath"/mkspecs/*
- ln -s "$relpath"/mkspecs/* "$outpath/mkspecs"
-
- ShadowMkspecs()
- {
- rm -rf "$outpath/mkspecs/$1"
- find "$relpath/mkspecs/$1" -type d | sed "s,^$relpath,$outpath," | xargs mkdir -p
- find "$relpath/mkspecs/$1" -type f | sed "s,^$relpath/,," | while read f; do ln -s "$relpath/$f" "$outpath/$f"; done
- }
-
- # Special case for mkspecs/features directory.
- # To be able to place .prf files into a shadow build directory,
- # we're creating links for files only. The directory structure is reproduced.
- ShadowMkspecs features
-
- # The modules dir is special, too.
- if test -d "$outpath/mkspecs-modules"; then
- rm -rf "$outpath/mkspecs/modules"
- mv "$outpath/mkspecs-modules" "$outpath/mkspecs/modules"
- else
- ShadowMkspecs modules
- fi
-
- # The modules-inst dir is not quite as special, but still.
- if test -d "$outpath/mkspecs-modules-inst"; then
- rm -rf "$outpath/mkspecs/modules-inst"
- mv "$outpath/mkspecs-modules-inst" "$outpath/mkspecs/modules-inst"
- fi
-
- # Prepare doc directory
- mkdir -p "$outpath/doc"
- ln -f -s "$relpath"/doc/global "$outpath/doc"
fi
# symlink fonts to be able to run application from build directory
@@ -2801,9 +2766,9 @@ if [ "$BUILD_ON_MAC" = "yes" ]; then
if [ `basename $QMAKESPEC` = "macx-xcode" ] || [ `basename $XQMAKESPEC` = "macx-xcode" ]; then
echo >&2
echo " Platform 'macx-xcode' should not be used when building Qt/Mac." >&2
- echo " Please build Qt/Mac with 'macx-g++', then if you would like to" >&2
- echo " use mac-xcode on your application code it can link to a Qt/Mac" >&2
- echo " built with 'macx-g++'" >&2
+ echo " Please build Qt/Mac with 'macx-clang' or 'macx-g++', then use" >&2
+ echo " the 'macx-xcode' spec for your application, and it will link to" >&2
+ echo " the Qt/Mac build using the settings of the original mkspec." >&2
echo >&2
exit 2
fi
@@ -2894,7 +2859,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then
CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples tests"
CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store
CFG_CXX11="no" # C++11 support disabled for now
- CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtdeclarative qtquickcontrols qtwebkit qtgraphicaleffects qtdoc qtmultimedia qtwebkit-examples qttools"
+ CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtquickcontrols qtwebkit qtgraphicaleffects qtdoc qtmultimedia qtwebkit-examples qttools"
fi
# disable GTK style support auto-detection on Mac
@@ -3039,21 +3004,44 @@ else
fi
# auto-detect default include and library search paths
-gccout=`LC_ALL=C $TEST_COMPILER $SYSROOT_FLAG $TEST_COMPILER_CXXFLAGS -xc++ -E -v - < /dev/null 2>&1 > /dev/null`
-# extract from one line like 'LIBRARY_PATH=/one/path:/another/path:...'
-libdirs=`echo "$gccout" | sed -n -e 's/^LIBRARY_PATH=\(.*\)/\1/p'`
-DEFAULT_LIBDIRS=`IFS=${HOST_DIRLIST_SEP}; for i in $libdirs; do test -d "$i" && cd "$i" && pwd; done`
-# extract from indented lines between '#include <...> search starts here:' and 'End of search list.'
-DEFAULT_INCDIRS=`echo "$gccout" | $AWK '
-/^End of search/ { yup=0 }
+unset tty
+[ "$OPT_VERBOSE" = "yes" ] && tty=/dev/stderr
+
+eval `LC_ALL=C $TEST_COMPILER $SYSROOT_FLAG $TEST_COMPILER_CXXFLAGS -xc++ -E -v - < /dev/null 2>&1 > /dev/null | $AWK '
+BEGIN { ORS = ""; FS = "="; incs = 0; libs = 0; }
+function quote(s)
+{
+ # We only handle spaces
+ if (match(s, " ") != 0)
+ return "\\\\\"" s "\\\\\"";
+ return s;
+}
+
+# extract include paths from indented lines between
+# #include <...> search starts here:
+# and
+# End of search list.
+/^\#include </ { yup=1; print "DEFAULT_INCDIRS=\""; next }
+/^End of search/ { yup=0; print "\"\n" }
/ \(framework directory\)$/ { next }
-yup { print substr($0, 2) }
-/^\#include </ { yup=1 }
-'`
-test -z "$DEFAULT_LIBDIRS" && DEFAULT_LIBDIRS="/lib
-/usr/lib"
-test -z "$DEFAULT_INCDIRS" && DEFAULT_INCDIRS="/usr/include
-/usr/local/include"
+yup { print quote(substr($0, 2)) " "; ++incs }
+
+# extract from one line like LIBRARY_PATH=/one/path:/another/path:...
+$1 == "LIBRARY_PATH" {
+ libs = split($2, library_paths, ":");
+ print "DEFAULT_LIBDIRS=\"";
+ for (lib in library_paths)
+ print quote(library_paths[lib]) " ";
+ print "\"\n"
+}
+
+END {
+ if (incs == 0)
+ print "DEFAULT_INCDIRS=\"/usr/include /usr/local/include\"\n";
+ if (libs == 0)
+ print "DEFAULT_LIBDIRS=\"/lib /usr/lib\"\n";
+}' | tee $tty`
+unset tty
#setup the build parts
if [ -z "$CFG_BUILD_PARTS" ]; then
@@ -3463,6 +3451,7 @@ Configure options:
-qtlibinfix <infix> Renames all libQt*.so to libQt*<infix>.so.
-testcocoon ........ Instrument Qt with the TestCocoon code coverage tool.
+ -gcov .............. Instrument Qt with the GCov code coverage tool.
-D <string> ........ Add an explicit define to the preprocessor.
-I <string> ........ Add an explicit include path.
@@ -4124,6 +4113,12 @@ cat > "$QTCONFFILE" <<EOF
[EffectivePaths]
Prefix=..
EOF
+if [ x"$relpath" != x"$outpath" ]; then
+ cat >> "$QTCONFFILE" <<EOF
+[EffectiveSourcePaths]
+Prefix=$relpath
+EOF
+fi
#-------------------------------------------------------------------------------
# write out device config before we run the test.
@@ -4398,8 +4393,7 @@ fi
# detect neon support
if [ "$CFG_ARCH" = "arm" ] && [ "${CFG_NEON}" = "auto" ]; then
- # The iOS toolchain has trouble building the pixman NEON draw-helpers
- if [ "$XPLATFORM_IOS" != "yes" ] && compileTest unix/neon "neon"; then
+ if compileTest unix/neon "neon"; then
CFG_NEON=yes
else
CFG_NEON=no
@@ -6534,12 +6528,14 @@ fi
cat >>"$QTCONFIG.tmp" <<EOF
#configuration
CONFIG += $QTCONFIG_CONFIG
-QT_ARCH = $CFG_ARCH
-QT_HOST_ARCH = $CFG_HOST_ARCH
-QT_CPU_FEATURES = $CFG_CPUFEATURES
-QT_HOST_CPU_FEATURES = $CFG_HOST_CPUFEATURES
-QMAKE_DEFAULT_LIBDIRS = `echo "$DEFAULT_LIBDIRS" | sed 's,^,",;s,$,",' | tr '\n' ' '`
-QMAKE_DEFAULT_INCDIRS = `echo "$DEFAULT_INCDIRS" | sed 's,^,",;s,$,",' | tr '\n' ' '`
+host_build {
+ QT_ARCH = $CFG_HOST_ARCH
+ QT_TARGET_ARCH = $CFG_ARCH
+} else {
+ QT_ARCH = $CFG_ARCH
+ QMAKE_DEFAULT_LIBDIRS = $DEFAULT_LIBDIRS
+ QMAKE_DEFAULT_INCDIRS = $DEFAULT_INCDIRS
+}
QT_EDITION = $Edition
QT_CONFIG += $QT_CONFIG
@@ -6621,6 +6617,14 @@ if [ -n "$CFG_SKIP_MODULES" ]; then
echo "QT_SKIP_MODULES += $CFG_SKIP_MODULES" >> "$QTMODULE.tmp"
fi
+cat >>"$QTMODULE.tmp" <<EOF
+host_build {
+ QT_CPU_FEATURES.$CFG_HOST_ARCH = $CFG_HOST_CPUFEATURES
+} else {
+ QT_CPU_FEATURES.$CFG_ARCH = $CFG_CPUFEATURES
+}
+EOF
+
if [ -n "$QT_CFLAGS_PSQL" ]; then
echo "QT_CFLAGS_PSQL = $QT_CFLAGS_PSQL" >> "$QTMODULE.tmp"
fi
diff --git a/dist/changes-5.2.0 b/dist/changes-5.2.0
new file mode 100644
index 0000000000..89d1a2d8c7
--- /dev/null
+++ b/dist/changes-5.2.0
@@ -0,0 +1,45 @@
+Qt 5.2 introduces many new features and improvements as well as bugfixes
+over the 5.1.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+ http://qt-project.org/doc/qt-5.2
+
+The Qt version 5.2 series is binary compatible with the 5.1.x series.
+Applications compiled for 5.1 will continue to run with 5.2.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ http://bugreports.qt-project.org/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Library *
+****************************************************************************
+
+QtWidgets
+---------
+
+- QAbstractScrollArea now has a SizeAdjustPolicy. If it is set to AdjustToContents
+ it will make use of the new protected viewportSizeHint() (binary compatible since it
+ was reserved in Qt5). This function returns a suggested size based on contents.
+
+- QTreeView now has setTreePosition to allow the treestructure to show data from other
+ columns than logicalindex zero.
+
+- [QTBUG-4206] QTableView resizeToContents will now adjust to actual contents
+ and not just visible area. QHeaderView::setAutoResizePrecision() has been
+ introduced to control how precise the autoResize should be.
+
+- QFileDialog::setDefaultSuffix() removes leading dot characters.
+
+- QSizePolicy got a retainSizeWhenHidden attribute.
+
+QtCore
+------
+- [QTBUG-30250] QTime, QDateTime:
+ When calling QTime::toString(Qt::TextDate) and QTime::toString(Qt::ISODate),
+ milliseconds are now included in the returned string. This also applies to
+ QDateTime::toString(Qt::TextDate) and QDateTime::toString(ISODate).
diff --git a/doc/global/config.qdocconf b/doc/global/config.qdocconf
new file mode 100644
index 0000000000..2b3ca1d6ba
--- /dev/null
+++ b/doc/global/config.qdocconf
@@ -0,0 +1,12 @@
+#Include this file to inherit configuration related to Qt Project based modules.
+
+dita.metadata.default.author = Qt Project
+dita.metadata.default.permissions = all
+dita.metadata.default.publisher = Qt Project
+dita.metadata.default.copyryear = 2013
+dita.metadata.default.copyrholder = Digia Plc
+dita.metadata.default.audience = programmer
+
+#Set the main Qt index.html
+navigation.homepage = "Qt $QT_VER"
+buildversion = "Qt $QT_VERSION Reference Documentation"
diff --git a/doc/global/externalsites/rfc.qdoc b/doc/global/externalsites/rfc.qdoc
index bc6a1d66a2..37c71ab73e 100644
--- a/doc/global/externalsites/rfc.qdoc
+++ b/doc/global/externalsites/rfc.qdoc
@@ -77,3 +77,18 @@
\externalpage http://www.rfc-editor.org/rfc/rfc3986.txt
\title RFC 3986
*/
+
+/*!
+ \externalpage http://www.rfc-editor.org/rfc/rfc2822.txt
+ \title RFC 2822
+*/
+
+/*!
+ \externalpage http://www.rfc-editor.org/rfc/rfc1036.txt
+ \title RFC 1036
+*/
+
+/*!
+ \externalpage http://www.rfc-editor.org/rfc/rfc850.txt
+ \title RFC 850
+*/
diff --git a/doc/global/fileextensions.qdocconf b/doc/global/fileextensions.qdocconf
new file mode 100644
index 0000000000..ec47dc9c7f
--- /dev/null
+++ b/doc/global/fileextensions.qdocconf
@@ -0,0 +1,12 @@
+naturallanguage = en_US
+outputencoding = UTF-8
+sourceencoding = UTF-8
+
+examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml *.css"
+examples.imageextensions = "*.png *.jpg *.gif"
+
+headers.fileextensions = "*.ch *.h *.h++ *.hh *.hpp *.hxx"
+sources.fileextensions = "*.c++ *.cc *.cpp *.cxx *.mm *.qml *.qdoc"
+
+#include the external websites
+sourcedirs += externalsites
diff --git a/doc/global/html-config.qdocconf b/doc/global/html-config.qdocconf
new file mode 100644
index 0000000000..1560db8d98
--- /dev/null
+++ b/doc/global/html-config.qdocconf
@@ -0,0 +1,29 @@
+#Additional HTML settings
+
+HTML.nonavigationbar = "false"
+
+HTML.extraimages += template/images/arrow_bc.png \
+ template/images/home.png \
+ template/images/ico_out.png \
+ template/images/ico_note.png \
+ template/images/ico_note_attention.png \
+ template/images/btn_prev.png \
+ template/images/btn_next.png \
+ template/images/bullet_dn.png \
+ template/images/bullet_sq.png \
+ template/images/bgrContent.png \
+ template/images/logo.png
+
+#specify which files in the output directory should be packed into the qch file.
+#these files are assumed to be in each module's output directory."qtquick/images/ico_out.png" for example.
+qhp.extraFiles += images/arrow_bc.png \
+ images/home.png \
+ images/ico_out.png \
+ images/ico_note.png \
+ images/ico_note_attention.png \
+ images/btn_prev.png \
+ images/btn_next.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bgrContent.png \
+ images/logo.png
diff --git a/doc/global/html-footer.qdocconf b/doc/global/html-footer.qdocconf
new file mode 100644
index 0000000000..6c26dc7c29
--- /dev/null
+++ b/doc/global/html-footer.qdocconf
@@ -0,0 +1,30 @@
+#Default HTML footer for QDoc builds.
+
+HTML.footer = \
+ " </div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ "</div>\n" \
+ "<div class=\"footer\">\n" \
+ " <div class=\"qt13a-copyright\" id=\"copyright\">\n" \
+ " <div class=\"qt13a-container\">\n" \
+ " <p>\n" \
+ " <acronym title=\"Copyright\">&copy;</acronym> 2013 Digia Plc and/or its\n" \
+ " subsidiaries. Documentation contributions included herein are the copyrights of\n" \
+ " their respective owners.</p>\n" \
+ " <p>\n" \
+ " The documentation provided herein is licensed under the terms of the\n" \
+ " <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU Free Documentation\n" \
+ " License version 1.3</a> as published by the Free Software Foundation.</p>\n" \
+ " <p>\n" \
+ " Documentation sources may be obtained from <a href=\"http://www.qt-project.org\">\n" \
+ " www.qt-project.org</a>.</p>\n" \
+ " <p>\n" \
+ " Digia, Qt and their respective logos are trademarks of Digia Plc \n" \
+ " in Finland and/or other countries worldwide. All other trademarks are property\n" \
+ " of their respective owners. <a title=\"Privacy Policy\"\n" \
+ " href=\"http://en.gitorious.org/privacy_policy/\">Privacy Policy</a></p>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ "</div>\n" \
diff --git a/doc/global/html-header-offline.qdocconf b/doc/global/html-header-offline.qdocconf
new file mode 100644
index 0000000000..d84f38fef8
--- /dev/null
+++ b/doc/global/html-header-offline.qdocconf
@@ -0,0 +1,31 @@
+#Default HTML header for QDoc builds.
+
+#specify the CSS file used by this template
+HTML.stylesheets = template/style/offline.css
+
+#for including files into the qch file
+qhp.extraFiles += style/offline.css
+
+HTML.headerstyles = \
+ " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/offline.css\" />\n"
+
+HTML.endheader = \
+ "</head>\n"
+
+HTML.postheader = \
+ "<body>\n" \
+ "<div class=\"header\" id=\"qtdocheader\">\n"\
+ " <div class=\"main\">\n" \
+ " <div class=\"main-rounded\">\n" \
+ " <div class=\"navigationbar\">\n"\
+ " <ul>\n"\
+
+
+
+HTML.postpostheader = \
+ " </ul>\n"\
+ " </div>\n" \
+ "</div>\n" \
+ "<div class=\"content\">\n" \
+ "<div class=\"line\">\n" \
+ "<div class=\"content mainContent\">\n" \
diff --git a/doc/global/html-header-online.qdocconf b/doc/global/html-header-online.qdocconf
new file mode 100644
index 0000000000..5c21644a39
--- /dev/null
+++ b/doc/global/html-header-online.qdocconf
@@ -0,0 +1,64 @@
+#HTML Header with Qt Project branding and online links
+
+HTML.stylesheets = template/style/online.css
+
+#for including files into the qch file. Relative to the outputdir of a QDoc build.
+# $QT_INSTALL_DOCS/qtquick/style/online.css for example
+qhp.extraFiles += style/online.css
+
+HTML.headerstyles = \
+ " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/online.css\" />\n"
+
+HTML.endheader = \
+ "</head>\n"
+
+HTML.postheader = \
+ "<body>\n" \
+ "<div class=\"header\" id=\"qtdocheader\"></div>\n" \
+ " <div class=\"nav\" id=\"qt13a-header\">\n" \
+ " <div class=\"qt13a-gradient\">\n" \
+ " <div class=\"qt13a-container qt13a-dynamicREMOVE\" >\n" \
+ " <div id=\"qt13a-register\">\n" \
+ " <a href=\"http://qt-project.org/\">Qt Home</a>\n" \
+ " <a href=\"https://bugreports.qt-project.org/\">Bug Tracker</a>\n" \
+ " <a href=\"https://codereview.qt-project.org/\">Code Review</a>\n" \
+ " </div>\n" \
+ " <div class=\"qt13a-sixCol\">\n" \
+ " <div id=\"qt13a-logo\">\n" \
+ " <a href=\"http://qt-project.org/\" class=\"qt13a-site-logo\">\n" \
+ " <img src=\"images/Qt-logo.png\" alt=\"Qt\"></img>\n" \
+ " </a>\n" \
+ " </div>\n" \
+ " <div id=\"qt13a-title_nav\">\n" \
+ " <div id=\"qt13a-title\">\n" \
+ " <p class=\"qt13a-title\">Qt Documentation Snapshots</p>\n" \
+ " </div>\n" \
+ " <div class=\"qt13a-nav\">\n" \
+ " <ul>\n" \
+ " <li>\n" \
+ " <a href=\"http://doc-snapshot.qt-project.org\">Snapshots</a>\n" \
+ " </li>\n" \
+ " <li>\n" \
+ " <a href=\"http://qt-project.org/doc\">Released</a>\n" \
+ " </li>\n" \
+ " <li>\n" \
+ " <a href=\"http://doc.qt.digia.com\">Archives</a>\n" \
+ " </li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"main\">\n" \
+ " <div class=\"main-rounded\">\n" \
+ " <div class=\"navigationbar\">\n" \
+ " <ul>\n" \
+
+HTML.postpostheader = \
+ " </ul>\n" \
+ " </div>\n" \
+ "<div class=\"content\">\n" \
+ " <div class=\"line\">\n" \
+ " <div class=\"content mainContent\">\n" \
diff --git a/doc/global/qt-cpp-ignore.qdocconf b/doc/global/qt-cpp-defines.qdocconf
index 1f34f366cb..2e795e1439 100644
--- a/doc/global/qt-cpp-ignore.qdocconf
+++ b/doc/global/qt-cpp-defines.qdocconf
@@ -1,3 +1,21 @@
+versionsym = QT_VERSION_STR
+
+defines += Q_QDOC \
+ QT_.*_SUPPORT \
+ QT_.*_LIB \
+ QT_COMPAT \
+ QT_KEYPAD_NAVIGATION \
+ QT_NO_EGL \
+ QT3_SUPPORT \
+ Q_WS_.* \
+ Q_OS_.* \
+ Q_BYTE_ORDER \
+ QT_DEPRECATED \
+ QT_DEPRECATED_* \
+ Q_NO_USING_KEYWORD \
+ __cplusplus \
+ Q_COMPILER_INITIALIZER_LISTS
+
Cpp.ignoretokens += \
PHONON_EXPORT \
Q_AUTOTEST_EXPORT \
@@ -37,11 +55,13 @@ Cpp.ignoretokens += \
Q_LOCATION_EXPORT \
Q_MULTIMEDIA_EXPORT \
Q_NETWORK_EXPORT \
+ Q_NORETURN \
Q_OPENGL_EXPORT \
Q_OPENVG_EXPORT \
Q_OUTOFLINE_TEMPLATE \
Q_PRINTSUPPORT_EXPORT \
Q_QML_EXPORT \
+ Q_REQUIRED_RESULT \
Q_SCRIPT_EXPORT \
Q_SCRIPTTOOLS_EXPORT \
Q_SQL_EXPORT \
@@ -84,13 +104,15 @@ Cpp.ignoretokens += \
QT_END_NAMESPACE \
QT_FASTCALL \
QT_WIDGET_PLUGIN_EXPORT \
- QTBLUETOOTH_BEGIN_NAMESPACE \
- QTBLUETOOTH_END_NAMESAPCE \
- QTNFC_BEGIN_NAMESPACE \
- QTNFC_END_NAMESPACE \
+ QT_BEGIN_NAMESPACE_NFC \
+ QT_END_NAMESPACE_NFC \
+ QT_USE_NAMESPACE_NFC \
+ QT_BEGIN_NAMESPACE_BLUETOOTH \
+ QT_END_NAMESPACE_BLUETOOTH \
+ QT_USE_NAMESPACE_BLUETOOTH \
QWEBKIT_EXPORT
-Cpp.ignoredirectives = \
+Cpp.ignoredirectives += \
__attribute__ \
K_DECLARE_PRIVATE \
PHONON_HEIR \
diff --git a/doc/global/qt-defines.qdocconf b/doc/global/qt-defines.qdocconf
deleted file mode 100644
index 79b13eee92..0000000000
--- a/doc/global/qt-defines.qdocconf
+++ /dev/null
@@ -1,17 +0,0 @@
-versionsym = QT_VERSION_STR
-
-defines += Q_QDOC \
- QT_.*_SUPPORT \
- QT_.*_LIB \
- QT_COMPAT \
- QT_KEYPAD_NAVIGATION \
- QT_NO_EGL \
- QT3_SUPPORT \
- Q_WS_.* \
- Q_OS_.* \
- Q_BYTE_ORDER \
- QT_DEPRECATED \
- QT_DEPRECATED_* \
- Q_NO_USING_KEYWORD \
- __cplusplus \
- Q_COMPILER_INITIALIZER_LISTS
diff --git a/doc/global/qt-html-templates-offline.qdocconf b/doc/global/qt-html-templates-offline.qdocconf
index e9b2c6a7a8..cd8315aa9a 100644
--- a/doc/global/qt-html-templates-offline.qdocconf
+++ b/doc/global/qt-html-templates-offline.qdocconf
@@ -1,4 +1,10 @@
-HTML.nobreadcrumbs = "true"
+#include standard set of HTML header and footer.
+include(html-config.qdocconf)
+include(html-header-offline.qdocconf)
+include(html-footer.qdocconf)
+
+#uncomment if navigation bar is not wanted
+#HTML.nonavigationbar = "true"
HTML.stylesheets = template/style/offline.css
HTML.extraimages += template/images/ico_out.png \
@@ -20,40 +26,3 @@ qhp.extraFiles += style/offline.css \
images/bullet_dn.png \
images/bullet_sq.png \
images/bgrContent.png
-
-
-HTML.headerstyles = \
- " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/offline.css\" />\n"
-
-HTML.endheader = \
- "</head>\n" \
- "<body>\n" \
- "<div class=\"header\" id=\"qtdocheader\"></div>\n"\
- "<div class=\"content\">\n" \
- "<div class=\"line\">\n" \
- "<div class=\"content mainContent\">\n" \
-
-HTML.footer = \
- "</div>\n" \
- "</div>\n" \
- "</div>\n" \
- "<div class=\"footer\">\n" \
- " <p>\n" \
- " <acronym title=\"Copyright\">&copy;</acronym> 2013 Digia Plc and/or its\n" \
- " subsidiaries. Documentation contributions included herein are the copyrights of\n" \
- " their respective owners.</p>\n" \
- " <br />\n" \
- " <p>\n" \
- " The documentation provided herein is licensed under the terms of the\n" \
- " <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU Free Documentation\n" \
- " License version 1.3</a> as published by the Free Software Foundation.</p>\n" \
- " <p>\n" \
- " Documentation sources may be obtained from <a href=\"http://www.qt-project.org\">\n" \
- " www.qt-project.org</a>.</p>\n" \
- " <br />\n" \
- " <p>\n" \
- " Digia, Qt and their respective logos are trademarks of Digia Plc \n" \
- " in Finland and/or other countries worldwide. All other trademarks are property\n" \
- " of their respective owners. <a title=\"Privacy Policy\"\n" \
- " href=\"http://en.gitorious.org/privacy_policy/\">Privacy Policy</a></p>\n" \
- "</div>\n" \
diff --git a/doc/global/qt-html-templates-online.qdocconf b/doc/global/qt-html-templates-online.qdocconf
index c794c47679..88abc3429b 100644
--- a/doc/global/qt-html-templates-online.qdocconf
+++ b/doc/global/qt-html-templates-online.qdocconf
@@ -1,4 +1,10 @@
-HTML.nobreadcrumbs = "true"
+#include standard set of HTML header and footer.
+include(html-config.qdocconf)
+include(html-header-online.qdocconf)
+include(html-footer.qdocconf)
+
+#uncomment if navigation bar is not wanted
+#HTML.nonavigationbar = "true"
HTML.stylesheets = template/style/online.css
HTML.extraimages += template/images/ico_out.png \
@@ -8,67 +14,10 @@ HTML.extraimages += template/images/ico_out.png \
template/images/btn_next.png \
template/images/bullet_dn.png \
template/images/bullet_sq.png \
- template/images/bgrContent.png
-
-HTML.headerstyles = \
- " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/online.css\" />\n"
-
-HTML.endheader = \
- "</head>\n" \
- "<body>\n" \
- "<div class=\"header\" id=\"qtdocheader\"></div>\n" \
- " <header>\n" \
- " <div class=\"nav\">\n" \
- " <a href=\"http://qt-project.org/\">Qt Home</a>\n" \
- " <a href=\"https://bugreports.qt-project.org/\">Bug Tracker</a>\n" \
- " <a href=\"https://codereview.qt-project.org/\">Code Review</a>\n" \
- " </div>\n" \
- " <a href=\"http://qt-project.org/\">\n" \
- " <img src=\"http://doc-snapshot.qt-project.org/images/logo.png\" alt=\"Qt\"></img>\n" \
- " </a>\n" \
- " <div class=\"nav-title\">\n" \
- " <h1 >Qt Documentation Snapshots</h1>\n" \
- " <div class=\"nav-subtitle\">\n" \
- " --snapshots of unreleased Qt documentation\n" \
- " </div>\n" \
- " </div>\n" \
- " <div class=\"nav-main\">\n" \
- " <div class=\"nav-main-content\">\n" \
- " <a href=\"http://doc-snapshot.qt-project.org\">All Modules</a>\n" \
- " </div>\n" \
- " <div class=\"nav-main-content\">\n" \
- " <a href=\"http://qt-project.org/doc\">Qt Releases</a>\n" \
- " </div>\n" \
- " <div class=\"nav-main-content\">\n" \
- " <a href=\"http://doc.qt.digia.com\">Archives</a>\n" \
- " </div>\n" \
- " </div>\n" \
- "</header>\n" \
- "<div class=\"content\">\n" \
- " <div class=\"line\">\n" \
- " <div class=\"content mainContent\">\n" \
-
-HTML.footer = \
- " </div>\n" \
- " </div>\n" \
- "</div>\n" \
- "<div class=\"footer\">\n" \
- " <p>\n" \
- " <acronym title=\"Copyright\">&copy;</acronym> 2013 Digia Plc and/or its\n" \
- " subsidiaries. Documentation contributions included herein are the copyrights of\n" \
- " their respective owners.</p>\n" \
- " <br />\n" \
- " <p>\n" \
- " The documentation provided herein is licensed under the terms of the\n" \
- " <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU Free Documentation\n" \
- " License version 1.3</a> as published by the Free Software Foundation.</p>\n" \
- " <p>\n" \
- " Documentation sources may be obtained from <a href=\"http://www.qt-project.org\">\n" \
- " www.qt-project.org</a>.</p>\n" \
- " <br />\n" \
- " <p>\n" \
- " Digia, Qt and their respective logos are trademarks of Digia Plc \n" \
- " in Finland and/or other countries worldwide. All other trademarks are property\n" \
- " of their respective owners. <a title=\"Privacy Policy\"\n" \
- " href=\"http://en.gitorious.org/privacy_policy/\">Privacy Policy</a></p>\n" \
- "</div>\n" \
+ template/images/bgrContent.png \
+ template/images/Qt-logo.png \
+ template/images/Qt-dark_gradient.png \
+ template/images/Qt-footer-bg.jpg \
+ template/images/Qt-footer_shadow.png \
+ template/images/Qt-gradient.png \
+ template/images/Qt-header-bg.jpg
diff --git a/doc/global/qt-module-defaults-offline.qdocconf b/doc/global/qt-module-defaults-offline.qdocconf
new file mode 100644
index 0000000000..bdca212960
--- /dev/null
+++ b/doc/global/qt-module-defaults-offline.qdocconf
@@ -0,0 +1,13 @@
+#The default configuration for a Qt 5 module, including Add-Ons and Tools.
+#Include this file for a standard Qt 5 module; builds with the offline style.
+
+#include standard set of macros and C++ defines and ignores
+include(macros.qdocconf)
+include(qt-cpp-defines.qdocconf)
+include(compat.qdocconf)
+include(manifest-meta.qdocconf)
+include(fileextensions.qdocconf)
+include(qt-html-templates-offline.qdocconf)
+
+#extra configuration data such as file extensions
+include(config.qdocconf)
diff --git a/doc/global/qt-module-defaults-online.qdocconf b/doc/global/qt-module-defaults-online.qdocconf
index 93ecae16fa..258295b4f9 100644
--- a/doc/global/qt-module-defaults-online.qdocconf
+++ b/doc/global/qt-module-defaults-online.qdocconf
@@ -1,32 +1,14 @@
+#The online onfiguration for a Qt 5 module, including Add-Ons and Tools.
+#Online version contains a different header.
+#Include this file for a standard Qt 5 module; builds with the online style.
+
+#include standard set of macros and C++ defines and ignores
include(macros.qdocconf)
-include(qt-cpp-ignore.qdocconf)
-include(qt-defines.qdocconf)
-include(qt-html-templates-online.qdocconf)
+include(qt-cpp-defines.qdocconf)
include(compat.qdocconf)
+include(manifest-meta.qdocconf)
+include(fileextensions.qdocconf)
+include(qt-html-templates-online.qdocconf)
-dita.metadata.default.author = Qt Project
-dita.metadata.default.permissions = all
-dita.metadata.default.publisher = Qt Project
-dita.metadata.default.copyryear = 2013
-dita.metadata.default.copyrholder = Digia Plc
-dita.metadata.default.audience = programmer
-
-naturallanguage = en_US
-outputencoding = UTF-8
-sourceencoding = UTF-8
-
-examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml *.css"
-examples.imageextensions = "*.png *.jpg *.gif"
-
-headers.fileextensions = "*.ch *.h *.h++ *.hh *.hpp *.hxx"
-sources.fileextensions = "*.c++ *.cc *.cpp *.cxx *.mm *.qml *.qdoc"
-
-versionsym = QT_VERSION_STR
-
-macro.raisedaster.HTML = "<sup>*</sup>"
-
-#for including files into the qch file
-qhp.extraFiles += template/style/online.css
-
-#include the external websites
-sourcedirs += externalsites
+#extra configuration data DITA information
+include(config.qdocconf)
diff --git a/doc/global/qt-module-defaults.qdocconf b/doc/global/qt-module-defaults.qdocconf
index 0365d5a6cd..8d0665ef41 100644
--- a/doc/global/qt-module-defaults.qdocconf
+++ b/doc/global/qt-module-defaults.qdocconf
@@ -1,30 +1,7 @@
-include(macros.qdocconf)
-include(qt-cpp-ignore.qdocconf)
-include(qt-defines.qdocconf)
-include(qt-html-templates-offline.qdocconf)
-include(compat.qdocconf)
-include(manifest-meta.qdocconf)
+#The default configuration for a Qt 5 module, including Add-Ons and Tools.
+#Include this file for a standard Qt 5 module. This file is provided for
+#compatibility reasons.
-dita.metadata.default.author = Qt Project
-dita.metadata.default.permissions = all
-dita.metadata.default.publisher = Qt Project
-dita.metadata.default.copyryear = 2013
-dita.metadata.default.copyrholder = Digia Plc
-dita.metadata.default.audience = programmer
-
-naturallanguage = en_US
-outputencoding = UTF-8
-sourceencoding = UTF-8
-
-examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml *.css"
-examples.imageextensions = "*.png *.jpg *.gif"
-
-headers.fileextensions = "*.ch *.h *.h++ *.hh *.hpp *.hxx"
-sources.fileextensions = "*.c++ *.cc *.cpp *.cxx *.mm *.qml *.qdoc"
-
-versionsym = QT_VERSION_STR
-
-macro.raisedaster.HTML = "<sup>*</sup>"
-
-#include the external websites
-sourcedirs += externalsites
+#The default is the offline style. The alternate style is in
+#qt-module-defaults-online.qdocconf
+include(qt-module-defaults-offline.qdocconf)
diff --git a/doc/global/template/images/Qt-dark_gradient.png b/doc/global/template/images/Qt-dark_gradient.png
new file mode 100644
index 0000000000..6ae10f37bf
--- /dev/null
+++ b/doc/global/template/images/Qt-dark_gradient.png
Binary files differ
diff --git a/doc/global/template/images/Qt-footer-bg.jpg b/doc/global/template/images/Qt-footer-bg.jpg
new file mode 100644
index 0000000000..c0ff209b7e
--- /dev/null
+++ b/doc/global/template/images/Qt-footer-bg.jpg
Binary files differ
diff --git a/doc/global/template/images/Qt-footer_shadow.png b/doc/global/template/images/Qt-footer_shadow.png
new file mode 100644
index 0000000000..5a7063dfee
--- /dev/null
+++ b/doc/global/template/images/Qt-footer_shadow.png
Binary files differ
diff --git a/doc/global/template/images/Qt-gradient.png b/doc/global/template/images/Qt-gradient.png
new file mode 100644
index 0000000000..aa38227cbb
--- /dev/null
+++ b/doc/global/template/images/Qt-gradient.png
Binary files differ
diff --git a/doc/global/template/images/Qt-header-bg.jpg b/doc/global/template/images/Qt-header-bg.jpg
new file mode 100644
index 0000000000..c9a6d96db4
--- /dev/null
+++ b/doc/global/template/images/Qt-header-bg.jpg
Binary files differ
diff --git a/doc/global/template/images/Qt-logo.png b/doc/global/template/images/Qt-logo.png
new file mode 100644
index 0000000000..64c1c4aaa3
--- /dev/null
+++ b/doc/global/template/images/Qt-logo.png
Binary files differ
diff --git a/doc/global/template/images/arrow_bc.png b/doc/global/template/images/arrow_bc.png
new file mode 100644
index 0000000000..f2a83a5740
--- /dev/null
+++ b/doc/global/template/images/arrow_bc.png
Binary files differ
diff --git a/doc/global/template/images/logo.png b/doc/global/template/images/logo.png
new file mode 100644
index 0000000000..1e7ed4cf21
--- /dev/null
+++ b/doc/global/template/images/logo.png
Binary files differ
diff --git a/doc/global/template/style/offline.css b/doc/global/template/style/offline.css
index 0e4dd5e9a4..f573633331 100644
--- a/doc/global/template/style/offline.css
+++ b/doc/global/template/style/offline.css
@@ -1,43 +1,55 @@
-body{
-font: normal 400 14px/1.2 Arial;
-margin-top:85px;
-font-family: Arial, Helvetica;
-color:#313131;
-text-align:justify;
-margin-left:5px;
-margin-right:5px;
+body {
+ font: normal 400 14px/1.2 Arial;
+ margin-top: 85px;
+ font-family: Arial, Helvetica;
+ color: #313131;
+ text-align: justify;
+ margin-left: 5px;
+ margin-right: 5px;
}
p {
-line-height: 20px;
+ line-height: 20px
}
-img{
--moz-box-shadow: 3px 3px 3px #ccc;
--webkit-box-shadow: 3px 3px 3px #ccc;
-box-shadow: 3px 3px 3px #ccc;
-border:#8E8D8D 2px solid;
-margin-left:0px;
-max-width: 800px;
-height: auto
+
+img {
+ -moz-box-shadow: 3px 3px 3px #ccc;
+ -webkit-box-shadow: 3px 3px 3px #ccc;
+ box-shadow: 3px 3px 3px #ccc;
+ border: #8E8D8D 2px solid;
+ margin-left: 0px;
+ max-width: 800px;
+ height: auto;
}
-.content{}
+.content {
-.descr{
-margin-top:35px;
-/*max-width: 75%;*/
-margin-left:5px;
-text-align:justify;
-vertical-align:top;
}
-.name{
-max-width: 75%;
-font-weight:100;
+.content .indexboxcont li {
+ font: normal bold 13px/1 Verdana
+ }
+
+.content .normallist li {
+ font: normal 13px/1 Verdana
+ }
+
+.descr {
+ margin-top: 35px;
+ /*max-width: 75%;*/
+ margin-left: 5px;
+ text-align: justify;
+ vertical-align: top;
}
-tt{
-text-align:left;}
+.name {
+ max-width: 75%;
+ font-weight: 100;
+}
+
+tt {
+ text-align: left
+}
/*
-----------
@@ -45,25 +57,25 @@ links
-----------
*/
-a:link{
-color: #007330;
-text-decoration: none;
-text-align:left;
+a:link {
+ color: #007330;
+ text-decoration: none;
+ text-align: left;
}
-a:hover{
-color: #44a51c;
-text-align:left;
+a:hover {
+ color: #44a51c;
+ text-align: left;
}
-a:visited{
-color: #007330;
-text-align:left;
+a:visited {
+ color: #007330;
+ text-align: left;
}
-a:visited:hover{
-color: #44a51c;
-text-align:left;
+a:visited:hover {
+ color: #44a51c;
+ text-align: left;
}
/*
@@ -71,19 +83,19 @@ text-align:left;
offline viewing: HTML links display an icon
-----------
*/
-a[href*="http://"], a[href*="ftp://"],a[href*="https://"]
-{
-text-decoration: none;
-background-image:url(../images/ico_out.png);
-background-repeat:no-repeat;
-background-position:left;
-padding-left:20px;
-text-align:left;
+
+a[href*="http://"], a[href*="ftp://"], a[href*="https://"] {
+ text-decoration: none;
+ background-image: url(../images/ico_out.png);
+ background-repeat: no-repeat;
+ background-position: left;
+ padding-left: 20px;
+ text-align: left;
}
-.flags{
-text-decoration:none;
-text-height:24px;
+.flags {
+ text-decoration: none;
+ text-height: 24px;
}
/*
@@ -91,36 +103,37 @@ text-height:24px;
NOTE styles
-------------------------------
*/
-.notetitle, .tiptitle, .fastpathtitle{
-font-weight:bold;
+
+.notetitle, .tiptitle, .fastpathtitle {
+ font-weight: bold
}
-.attentiontitle,.cautiontitle,.dangertitle,.importanttitle,.remembertitle,.restrictiontitle{
-font-weight:bold;
+.attentiontitle, .cautiontitle, .dangertitle, .importanttitle, .remembertitle, .restrictiontitle {
+ font-weight: bold
}
-.note,.tip,.fastpath{
-background: #F2F2F2 url(../images/ico_note.png);
-background-repeat: no-repeat;
-background-position: top left;
-padding:5px;
-padding-left:40px;
-padding-bottom:10px;
-border:#999 1px dotted;
-color:#666666;
-margin:5px;
+.note, .tip, .fastpath {
+ background: #F2F2F2 url(../images/ico_note.png);
+ background-repeat: no-repeat;
+ background-position: top left;
+ padding: 5px;
+ padding-left: 40px;
+ padding-bottom: 10px;
+ border: #999 1px dotted;
+ color: #666666;
+ margin: 5px;
}
-.attention,.caution,.danger,.important,.remember,.restriction{
-background: #F2F2F2 url(../images/ico_note_attention.png);
-background-repeat:no-repeat;
-background-position:top left;
-padding:5px;
-padding-left:40px;
-padding-bottom:10px;
-border:#999 1px dotted;
-color:#666666;
-margin:5px;
+.attention, .caution, .danger, .important, .remember, .restriction {
+ background: #F2F2F2 url(../images/ico_note_attention.png);
+ background-repeat: no-repeat;
+ background-position: top left;
+ padding: 5px;
+ padding-left: 40px;
+ padding-bottom: 10px;
+ border: #999 1px dotted;
+ color: #666666;
+ margin: 5px;
}
/*
@@ -129,58 +142,127 @@ Top navigation
-------------------------------
*/
-.qtref{
-display: block;
-position: relative;
-height:15px;
-z-index: 1;
-font-size:11px;
-padding-right:10px;
-float:right;
-}
-
-.naviNextPrevious{
-clear: both;
-display: block;
-position: relative;
-text-align: right;
-top: -47px;
-float:right;
-height:20px;
-z-index:1;
-padding-right:10px;
-padding-top:2px;
-vertical-align:top;
-margin:0px;
-}
-
-
-.naviNextPrevious > a:first-child{
-background-image:url(../images/btn_prev.png);
-background-repeat:no-repeat;
-background-position:left;
-padding-left:20px;
-height:20px;
-padding-left:20px;
-}
-
-.naviNextPrevious > a:last-child{
-background-image:url(../images/btn_next.png);
-background-repeat:no-repeat;
-background-position:right;
-padding-right:20px;
-height:20px;
-margin-left:30px;
-}
+.qtref {
+ display: block;
+ position: relative;
+ height: 15px;
+ z-index: 1;
+ font-size: 11px;
+ padding-right: 10px;
+ float: right;
+}
+
+.naviNextPrevious {
+ clear: both;
+ display: block;
+ position: relative;
+ text-align: right;
+ top: -47px;
+ float: right;
+ height: 20px;
+ z-index: 1;
+ padding-right: 10px;
+ padding-top: 2px;
+ vertical-align: top;
+ margin: 0px;
+}
+
+.naviNextPrevious > a:first-child {
+ background-image: url(../images/btn_prev.png);
+ background-repeat: no-repeat;
+ background-position: left;
+ padding-left: 20px;
+ height: 20px;
+ padding-left: 20px;
+ }
+
+.naviNextPrevious > a:last-child {
+ background-image: url(../images/btn_next.png);
+ background-repeat: no-repeat;
+ background-position: right;
+ padding-right: 20px;
+ height: 20px;
+ margin-left: 30px;
+ }
+
/*
-----------
footer and license
-----------
*/
-.footer{
-text-align:center
+
+.footer {
+ text-align: center
+}
+
+.navigationbar {
+ display: block;
+ position: relative;
+ top: -20px;
+ /*border-top: 2px solid #ffffff;*/
+ border-bottom: 1px solid #cecece;
+ background-color: #F2F2F2;
+ z-index: 1;
+ height: 20px;
+ padding-left: 7px;
+ margin: 0px;
+ padding-top: 2px;
+ margin-left: -5px;
+ margin-right: -5px;
+}
+
+.navigationbar .first {
+ background: url(../images/home.png);
+ background-position: left;
+ background-repeat: no-repeat;
+ padding-left: 20px;
+ }
+
+.navigationbar ul {
+ margin: 0px;
+ padding: 0px;
+ }
+
+ .navigationbar ul li {
+ list-style-type: none;
+ padding-top: 2px;
+ padding-left: 4px;
+ margin: 0;
+ height: 20px;
+ }
+
+.navigationbar li {
+ float: left
+ }
+
+ .navigationbar li a {
+ display: block;
+ text-decoration: none;
+ background: url(../images/arrow_bc.png);
+ background-repeat: no-repeat;
+ background-position: right;
+ padding-right: 17px;
+ }
+
+/*
+-----------
+footer and license
+-----------
+*/
+
+.footer {
+ text-align: center
+}
+
+#buildversion {
+ font-style: italic;
+ font-size: small;
+ float: right;
+ margin-right: 5px;
}
+/*
+
/* table of content
no display
*/
@@ -191,181 +273,177 @@ headers
-----------
*/
-
-@media screen{
-.title{
-color:#313131;
-font-size: 18px;
-font-weight: normal;
-left: 0;
-padding-bottom: 20px;
-padding-left: 10px;
-padding-top: 20px;
-position: absolute;
-right: 0;
-top: 0;
-background-color:#E6E6E6;
-border-bottom: 1px #CCC solid;
-border-top: 2px #CCC solid;
-font-weight:bold;
-margin-left:0px;
-margin-right:0px;
-}
+@media screen {
+ .title {
+ color: #313131;
+ font-size: 18px;
+ font-weight: normal;
+ left: 0;
+ padding-bottom: 20px;
+ padding-left: 10px;
+ padding-top: 20px;
+ position: absolute;
+ right: 0;
+ top: 0;
+ background-color: #E6E6E6;
+ border-bottom: 1px #CCC solid;
+ border-top: 2px #CCC solid;
+ font-weight: bold;
+ margin-left: 0px;
+ margin-right: 0px;
+ }
}
h1 {
-margin: 0;
+ margin: 0
}
h2, p.h2 {
-font: 500 16px/1.2 Arial;
-font-weight:100;
-background-color:#F2F3F4;
-padding:4px;
-margin-bottom:30px;
-margin-top:30px;
-border-top:#E0E0DE 1px solid;
-border-bottom: #E0E0DE 1px solid;
-max-width: 99%;
-overflow: hidden;
-}
-
-h3{
-
-font: 500 14px/1.2 Arial;
-font-weight:100;
-text-decoration:underline;
-margin-bottom:30px;
-margin-top:30px;
-}
-
-h3.fn,span.fn{
-border-width: 1px;
-border-style: solid;
-border-color: #E6E6E6;
--moz-border-radius: 7px 7px 7px 7px;
--webkit-border-radius: 7px 7px 7px 7px;
-border-radius: 7px 7px 7px 7px;
-background-color: #F6F6F6;
-word-spacing: 3px;
-padding: 5px 5px;
-text-decoration:none;
-font-weight:bold;
-max-width:75%;
-font-size:14px;
-margin:0px;
-margin-top:45px;
-
-}
-
-.name{
-color:#1A1A1A;
-}
-.type{
-color:#808080;
+ font: 500 16px/1.2 Arial;
+ font-weight: 100;
+ background-color: #F2F3F4;
+ padding: 4px;
+ margin-bottom: 30px;
+ margin-top: 30px;
+ border-top: #E0E0DE 1px solid;
+ border-bottom: #E0E0DE 1px solid;
+ max-width: 99%;
+ overflow: hidden;
+}
+
+h3 {
+ font: 500 14px/1.2 Arial;
+ font-weight: 100;
+ text-decoration: underline;
+ margin-bottom: 30px;
+ margin-top: 30px;
+}
+
+h3.fn, span.fn {
+ border-width: 1px;
+ border-style: solid;
+ border-color: #E6E6E6;
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ background-color: #F6F6F6;
+ word-spacing: 3px;
+ padding: 5px 5px;
+ text-decoration: none;
+ font-weight: bold;
+ max-width: 75%;
+ font-size: 14px;
+ margin: 0px;
+ margin-top: 45px;
+}
+
+.name {
+ color: #1A1A1A
+}
+
+.type {
+ color: #808080
}
-
-
@media print {
-.title {
-color:#0066CB;
-font-family:Arial, Helvetica;
-font-size: 32px;
-font-weight: normal;
-left: 0;
-position: absolute;
-right: 0;
-top: 0;
-}
+ .title {
+ color: #0066CB;
+ font-family: Arial, Helvetica;
+ font-size: 32px;
+ font-weight: normal;
+ left: 0;
+ position: absolute;
+ right: 0;
+ top: 0;
+ }
}
-
/*
-----------------
table styles
-----------------
*/
+
.table img {
-border:none;
-margin-left:0px;
--moz-box-shadow:0px 0px 0px #fff;
--webkit-box-shadow: 0px 0px 0px #fff;
-box-shadow: 0px 0px 0px #fff;
+ border: none;
+ margin-left: 0px;
+ -moz-box-shadow: 0px 0px 0px #fff;
+ -webkit-box-shadow: 0px 0px 0px #fff;
+ box-shadow: 0px 0px 0px #fff;
}
/* table with border alternative colours*/
- table,pre{
--moz-border-radius: 7px 7px 7px 7px;
--webkit-border-radius: 7px 7px 7px 7px;
- border-radius: 7px 7px 7px 7px;
-background-color: #F6F6F6;
-border: 1px solid #E6E6E6;
-border-collapse: separate;
-margin-bottom: 25px;
-margin-left: 15px;
-font-size: 12px;
-line-height: 1.2;
-}
-
-
-table th{
-text-align:left;
-padding-left:20px;
-}
-
-table td {
-padding: 3px 15px 3px 20px;
-border-bottom:#CCC dotted 1px;
-}
-table p { margin:0px;}
-
-table tr.even {
-background-color: white;
-color: #66666E;
-}
-
-table tr.odd {
-background-color: #F6F6F6;
-color: #66666E;
-}
-
-
-table thead {
-text-align:left;
-padding-left:20px;
-background-color:#e1e0e0;
-border-left:none;
-border-right:none;
-}
-
-table thead th {
-padding-top:5px;
-padding-left:10px;
-padding-bottom:5px;
-border-bottom: 2px solid #D1D1D1;
-padding-right:10px;
-}
-
+table, pre {
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ background-color: #F6F6F6;
+ border: 1px solid #E6E6E6;
+ border-collapse: separate;
+ margin-bottom: 25px;
+ margin-left: 15px;
+ font-size: 12px;
+ line-height: 1.2;
+}
+
+ table tr.even {
+ background-color: white;
+ color: #66666E;
+ }
+
+ table tr.odd {
+ background-color: #F6F6F6;
+ color: #66666E;
+ }
+
+ table thead {
+ text-align: left;
+ padding-left: 20px;
+ background-color: #e1e0e0;
+ border-left: none;
+ border-right: none;
+ }
+
+ table thead th {
+ padding-top: 5px;
+ padding-left: 10px;
+ padding-bottom: 5px;
+ border-bottom: 2px solid #D1D1D1;
+ padding-right: 10px;
+ }
+
+ table th {
+ text-align: left;
+ padding-left: 20px;
+ }
+
+ table td {
+ padding: 3px 15px 3px 20px;
+ border-bottom: #CCC dotted 1px;
+ }
+
+ table p {
+ margin: 0px
+ }
/* table bodless & white*/
.borderless {
-border-radius: 0px 0px 0px 0px;
-background-color: #fff;
-border: 1px solid #fff;
+ border-radius: 0px 0px 0px 0px;
+ background-color: #fff;
+ border: 1px solid #fff;
}
.borderless tr {
-background-color: #FFF;
-color: #66666E;
-}
+ background-color: #FFF;
+ color: #66666E;
+ }
.borderless td {
-border:none;
-border-bottom:#fff dotted 1px;
-}
+ border: none;
+ border-bottom: #fff dotted 1px;
+ }
/*
-----------
@@ -373,264 +451,249 @@ List
-----------
*/
-ul{
-padding-bottom:2px;
+ul {
+ padding-bottom: 2px
}
li {
-margin-bottom: 10px;
-padding-left: 8px;
-list-style:outside;
-list-style-type:square;
-text-align:left;
+ margin-bottom: 10px;
+ padding-left: 8px;
+ list-style: outside;
+ list-style-type: square;
+ text-align: left;
}
-
-ol{
-margin:10px;
-padding:0;
+ol {
+ margin: 10px;
+ padding: 0;
}
-ol > li{
-margin-left: 30px;
-padding-left:8px;
-list-style:decimal;
-}
+ ol > li {
+ margin-left: 30px;
+ padding-left: 8px;
+ list-style: decimal;
+ }
-.centerAlign{
-text-align: left;
+.centerAlign {
+ text-align: left
}
-.cpp{
-display: block;
-margin: 10px;
-overflow: auto;
-padding: 20px 20px 20px 20px;
+.cpp {
+ display: block;
+ margin: 10px;
+ overflow: auto;
+ padding: 20px 20px 20px 20px;
}
-.js{
-display: block;
-margin: 10px;
-overflow: auto;
-padding: 20px 20px 20px 20px;
+.js {
+ display: block;
+ margin: 10px;
+ overflow: auto;
+ padding: 20px 20px 20px 20px;
}
-.footer{
-margin-top: 50px;
-padding-left:5px;
-margin-bottom: 10px;
-font-size:10px;
-border-top: 1px solid #999;
-padding-top:11px;
+.footer {
+ margin-top: 50px;
+ padding-left: 5px;
+ margin-bottom: 10px;
+ font-size: 10px;
+ border-top: 1px solid #999;
+ padding-top: 11px;
}
-.footerNavi{
-width:auto;
-text-align:right;
-margin-top:50px;
-z-index:1;
+.footerNavi {
+ width: auto;
+ text-align: right;
+ margin-top: 50px;
+ z-index: 1;
}
-.memItemLeft{
-padding-right: 3px;
+.memItemLeft {
+ padding-right: 3px
}
-.memItemRight{
-padding: 3px 15px 3px 0;
+.memItemRight {
+ padding: 3px 15px 3px 0
}
-.qml{
-display: block;
-margin: 10;
-overflow: auto;
-padding: 20px 20px 20px 20px;
+.qml {
+ display: block;
+ margin: 10px;
+ overflow: auto;
+ padding: 20px 20px 20px 20px;
}
-.qmldefault{
-padding-left: 5px;
-float: right;
-color: red;
+.qmldefault {
+ padding-left: 5px;
+ float: right;
+ color: red;
}
-.qmlreadonly{
-padding-left: 5px;
-float: right;
-color: #254117;
+.qmlreadonly {
+ padding-left: 5px;
+ float: right;
+ color: #254117;
}
-.rightAlign{
-padding: 3px 5px 3px 10px;
-text-align: right;
+.rightAlign {
+ padding: 3px 5px 3px 10px;
+ text-align: right;
}
.qmldoc {
-margin-left: 15px;
+ margin-left: 15px
}
+
/*
-----------
Content table
-----------
*/
-@media print{
-.toc {
-float: right;
-clear: right;
-padding-bottom: 10px;
-padding-top: 50px;
-width: 100%;
-background-image:url(../images/bgrContent.png);
-background-position:top;
-background-repeat:no-repeat;
-}
+@media print {
+ .toc {
+ float: right;
+ clear: right;
+ padding-bottom: 10px;
+ padding-top: 50px;
+ width: 100%;
+ background-image: url(../images/bgrContent.png);
+ background-position: top;
+ background-repeat: no-repeat;
+ }
}
-@media screen{
-.toc{
-float:right;
-clear: right;
-vertical-align:top;
--moz-border-radius: 7px 7px 7px 7px;
--webkit-border-radius: 7px 7px 7px 7px;
-border-radius: 7px 7px 7px 7px;
- background:#FFF url(../images/bgrContent.png);
-background-position:top;
-background-repeat:repeat-x;
-border: 1px solid #E6E6E6;
-padding-left:5px;
-padding-bottom:10px;
-height: auto;
-width: 200px;
-text-align:left;
-margin-left:20px;
-}
+@media screen {
+ .toc {
+ float: right;
+ clear: right;
+ vertical-align: top;
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ background: #FFF url('../images/bgrContent.png');
+ background-position: top;
+ background-repeat: repeat-x;
+ border: 1px solid #E6E6E6;
+ padding-left: 5px;
+ padding-bottom: 10px;
+ height: auto;
+ width: 200px;
+ text-align: left;
+ margin-left: 20px;
+ }
}
-.toc h3{
-text-decoration:none;
-}
-.toc h3{font: 500 14px/1.2 Arial;
-font-weight:100;
-padding:0px;
-margin:0px;
-padding-top:5px;
-padding-left:5px;
+.toc h3 {
+ text-decoration: none
}
-
-.toc ul{
-padding-left:10px;
-padding-right:5px;
+.toc h3 {
+ font: 500 14px/1.2 Arial;
+ font-weight: 100;
+ padding: 0px;
+ margin: 0px;
+ padding-top: 5px;
+ padding-left: 5px;
}
-.toc ul li{
-margin-left:15px;
-list-style-image:url(../images/bullet_dn.png);
-marker-offset: 0px;
-margin-bottom:8px;
-padding-left:0px;
+.toc ul {
+ padding-left: 10px;
+ padding-right: 5px;
}
-.toc .level1{
-border:none;}
+.toc ul li {
+ margin-left: 15px;
+ list-style-image: url(../images/bullet_dn.png);
+ marker-offset: 0px;
+ margin-bottom: 8px;
+ padding-left: 0px;
+ }
-.toc .level2{
-border:none;
-margin-left: 25px;
+.toc .level1 {
+ border: none
}
-.level3{
-border:none;
-margin-left: 30px;
+.toc .level2 {
+ border: none;
+ margin-left: 25px;
}
-.clearfix{
-clear:both;}
+.level3 {
+ border: none;
+ margin-left: 30px;
+}
-/* start index box */
-.indexbox
-{
-width: 100%;
-display:inline-block;
+.clearfix {
+ clear: both
}
-.indexboxcont
-{
-display: block;
+/* start index box */
+.indexbox {
+ width: 100%;
+ display: inline-block;
}
-.indexboxcont .section
-{
-display: inline-block;
-width: 49%;
-*width:42%;
-_width:42%;
-padding:0 2% 0 1%;
-vertical-align:top;
-}
+.indexbox .indexIcon {
+ width: 11%
+ }
-.indexboxcont .indexIcon
-{
-width: 11%;
-*width:18%;
-_width:18%;
-overflow:hidden;
-}
+ .indexbox .indexIcon span {
+ display: block
+ }
-.indexboxcont .section {
- float: left;
+.indexboxcont {
+ display: block
}
-.indexboxcont .section p
-{
-padding-top: 20px;
-padding-bottom: 20px;
-}
-.indexboxcont .sectionlist
-{
-display: inline-block;
-vertical-align:top;
-width: 32.5%;
-padding: 0;
-}
-.indexboxcont .sectionlist ul
-{
-margin-bottom: 20px;
-}
+.indexboxcont .sectionlist {
+ display: inline-block;
+ vertical-align: top;
+ width: 32.5%;
+ padding: 0;
+ }
-.indexboxcont .sectionlist ul li
-{
-line-height: 1.5;
-}
+ .indexboxcont .sectionlist ul {
+ margin-bottom: 20px
+ }
-.content .indexboxcont li
-{
-font: normal bold 13px/1 Verdana;
-}
+ .indexboxcont .sectionlist ul li {
+ line-height: 1.5
+ }
-.content .normallist li
-{
-font: normal 13px/1 Verdana;
-}
+.indexboxcont .indexIcon {
+ width: 11%;
+ *width: 18%;
+ _width: 18%;
+ overflow: hidden;
+ }
-.indexbox .indexIcon {
-width: 11%;
-}
+.indexboxcont .section {
+ display: inline-block;
+ width: 49%;
+ *width: 42%;
+ _width: 42%;
+ padding: 0 2% 0 1%;
+ vertical-align: top;
+ }
+
+ .indexboxcont .section p {
+ padding-top: 20px;
+ padding-bottom: 20px;
+ }
-.indexbox .indexIcon span
-{
-display: block;
-}
+.indexboxcont .section {
+ float: left
+ }
-.indexboxcont:after
-{
-content: ".";
-display: block;
-height: 0;
-clear: both;
-visibility: hidden;
+.indexboxcont:after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
}
/*
@@ -638,6 +701,7 @@ visibility: hidden;
Landing page
-----------
*/
+
.col-group {
white-space: nowrap;
vertical-align: top;
@@ -652,8 +716,8 @@ Landing page
}
.col-1 h1 {
- margin: 20px 0 0 0;
-}
+ margin: 20px 0 0 0
+ }
.col-2 {
display: inline-block;
@@ -663,5 +727,5 @@ Landing page
}
.sectionlist {
- width: 100% !important;
+ width: 100% !important
}
diff --git a/doc/global/template/style/online.css b/doc/global/template/style/online.css
index 7809783fa7..cf73455877 100644
--- a/doc/global/template/style/online.css
+++ b/doc/global/template/style/online.css
@@ -1,43 +1,41 @@
-body{
-font: normal 400 14px/1.2 Arial;
-font-family: Arial, Helvetica;
-color:#313131;
-text-align:justify;
-margin-left:5px;
-margin-right:5px;
-background: none repeat scroll 0% 0% rgb(230,231,232);
+img {
+ -moz-box-shadow: 3px 3px 3px #ccc;
+ -webkit-box-shadow: 3px 3px 3px #ccc;
+ box-shadow: 3px 3px 3px #ccc;
+ border: #8E8D8D 2px solid;
+ margin-left: 0px;
+ max-width: 800px;
+ height: auto;
}
-p {
-line-height: 20px;
-}
-img{
--moz-box-shadow: 3px 3px 3px #ccc;
--webkit-box-shadow: 3px 3px 3px #ccc;
-box-shadow: 3px 3px 3px #ccc;
-border:#8E8D8D 2px solid;
-margin-left:0px;
-max-width: 800px;
-height: auto
+.content {
+ margin: 15px
}
-.content{}
+.content .indexboxcont li {
+ font: normal bold 13px/1 Verdana
+ }
+
+.content .normallist li {
+ font: normal 13px/1 Verdana
+ }
-.descr{
-margin-top:35px;
-/*max-width: 75%;*/
-margin-left:5px;
-text-align:justify;
-vertical-align:top;
+.descr {
+ margin-top: 35px;
+ /*max-width: 75%;*/
+ margin-left: 5px;
+ text-align: justify;
+ vertical-align: top;
}
-.name{
-max-width: 75%;
-font-weight:100;
+.name {
+ max-width: 75%;
+ font-weight: 100;
}
-tt{
-text-align:left;}
+tt {
+ text-align: left
+}
/*
-----------
@@ -45,30 +43,9 @@ links
-----------
*/
-a:link{
-color: #007330;
-text-decoration: none;
-text-align:left;
-}
-
-a:hover{
-color: #44a51c;
-text-align:left;
-}
-
-a:visited{
-color: #007330;
-text-align:left;
-}
-
-a:visited:hover{
-color: #44a51c;
-text-align:left;
-}
-
-.flags{
-text-decoration:none;
-text-height:24px;
+.flags {
+ text-decoration: none;
+ text-height: 24px;
}
/*
@@ -76,692 +53,1005 @@ text-height:24px;
NOTE styles
-------------------------------
*/
-.notetitle, .tiptitle, .fastpathtitle{
-font-weight:bold;
-}
-
-.attentiontitle,.cautiontitle,.dangertitle,.importanttitle,.remembertitle,.restrictiontitle{
-font-weight:bold;
-}
-.note,.tip,.fastpath{
-background: #F2F2F2 url(../images/ico_note.png);
-background-repeat: no-repeat;
-background-position: top left;
-padding:5px;
-padding-left:40px;
-padding-bottom:10px;
-border:#999 1px dotted;
-color:#666666;
-margin:5px;
+.notetitle, .tiptitle, .fastpathtitle {
+ font-weight: bold
}
-.attention,.caution,.danger,.important,.remember,.restriction{
-background: #F2F2F2 url(../images/ico_note_attention.png);
-background-repeat:no-repeat;
-background-position:top left;
-padding:5px;
-padding-left:40px;
-padding-bottom:10px;
-border:#999 1px dotted;
-color:#666666;
-margin:5px;
-}
-
-/*
--------------------------------
-Top navigation
--------------------------------
-*/
-
-.nav{
-text-align:right;
-margin-right:9px;
-}
-.nav img{
- box-shadow: none;
-}
-.nav-main{
-margin-top:22px;
-margin-left: 20px;
-text-align:left
-}
-.nav-main-content{
-margin-right: 20px;
-display:inline-block;
-}
-.nav-subtitle{
-margin-left: 220px;
+.attentiontitle, .cautiontitle, .dangertitle, .importanttitle, .remembertitle, .restrictiontitle {
+ font-weight: bold
}
-header{
-background: none repeat scroll 0% 0% rgb(255,255,255);
-border-radius: 10px 10px 10px 10px;
-padding: 10px;
-box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
+.note, .tip, .fastpath {
+ background: #F2F2F2 url('../images/ico_note.png');
+ background-repeat: no-repeat;
+ background-position: top left;
+ padding: 5px;
+ padding-left: 40px;
+ padding-bottom: 10px;
+ border: #999 1px dotted;
+ color: #666666;
+ margin: 5px;
}
-header h1{
-display:block;
-line-height: 70px;
-font-size: 30px;
-margin-left: 223px;
-}
-header img{
-box-shadow: none;
-border: 0;
-position: absolute;
-left: 30px;
-}
-.qtref{
-display: block;
-top: -76px;
-z-index: 1;
-font-size:11px;
-padding-right:10px;
-float:right;
+.attention, .caution, .danger, .important, .remember, .restriction {
+ background: #F2F2F2 url('../images/ico_note_attention.png');
+ background-repeat: no-repeat;
+ background-position: top left;
+ padding: 5px;
+ padding-left: 40px;
+ padding-bottom: 10px;
+ border: #999 1px dotted;
+ color: #666666;
+ margin: 5px;
}
-.naviNextPrevious{
-display: block;
-text-align: right;
-float:right;
-z-index:1;
-padding-right:10px;
-padding-top:4px;
+.qtref {
+ display: block;
+ top: -76px;
+ z-index: 1;
+ font-size: 11px;
+ padding-right: 10px;
+ float: right;
}
-
-.naviNextPrevious > a.prevPage {
-background-image:url(../images/btn_prev.png);
-background-repeat:no-repeat;
-background-position:left;
-padding-left:20px;
-height:20px;
-padding-left:20px;
+.naviNextPrevious {
+ display: block;
+ text-align: right;
+ float: right;
+ z-index: 1;
+ padding-right: 10px;
+ padding-top: 4px;
}
.naviNextPrevious > a.nextPage {
-background-image:url(../images/btn_next.png);
-background-repeat:no-repeat;
-background-position:right;
-padding-right:20px;
-height:20px;
-margin-left:30px;
-}
-
-.breadcrumb{
-display: block;
-position: relative;
-z-index:1;
-height:20px;
-padding:0px;
-margin:0px;
-padding-left:10px;
-padding-top:12px;
-margin-left:-5px;
-margin-right:-5px;
-}
-
-.breadcrumb ul{
- margin:0px;
- padding:0px;
-}
-
-.breadcrumb ul li{
-list-style-type:none;
-padding:0;
-margin:0;
-height:20px;
-}
-
-.breadcrumb li{
-float:left;
-}
-
-.breadcrumb .first {
-background:url(../images/home.png);
-background-position:left;
-background-repeat:no-repeat;
-padding-left:20px;
-}
-
-
-.breadcrumb li a{
-display:block;
-text-decoration:none;
-background:url(../images/arrow.png);
-background-repeat:no-repeat;
-background-position:right;
-padding-right:25px;
-padding-left:10px;
-}
-
-.breadcrumb li a:hover{
-color:#909090;
-display:block;
-text-decoration:none;
-background:url(../images/arrow.png);
-background-repeat:no-repeat;
-background-position:right;
-padding-right:20px;
-padding-left:10px;
-}
+ background-image: url('../images/btn_next.png');
+ background-repeat: no-repeat;
+ background-position: right;
+ padding-right: 20px;
+ height: 20px;
+ margin-left: 30px;
+ }
-/*
------------
-footer and license
------------
-*/
-.footer{
-text-align:center
-}
-/*
------------
-main content
------------
-*/
-.line{
-text-align: left;
-background: none repeat scroll 0% 0% rgb(255,255,255);
-border-radius: 10px 10px 10px 10px;
-padding-left: 14px;
-padding-right: 14px;
-box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
-margin-top: 10px;
-padding-bottom: 35px;
+.naviNextPrevious > a.prevPage {
+ background-image: url('../images/btn_prev.png');
+ background-repeat: no-repeat;
+ background-position: left;
+ padding-left: 20px;
+ height: 20px;
+ padding-left: 20px;
+ }
+
+.navigationbar {
+ background-repeat: no-repeat;
+ height: 33px;
+ margin: 0px !important;
+ padding: 0px !important;
+ border-bottom: 1px solid rgb(209, 209, 209);
+ background-image: -moz-linear-gradient(center top , rgb(246, 245, 245), rgb(239, 239, 239));
+ background-image: -webkit-gradient( linear, left bottom, left top, color-stop(0.0, #efefef), color-stop(0.5, #f6f5f5) );
+ border-radius: 10px 10px 0px 0px;
+}
+
+.navigationbar ul {
+ margin: 0px;
+ padding: 8px 0px 15px 15px;
+ height: 20px;
+ }
+
+.navigationbar li {
+ list-style-type: none;
+ float: left;
+ font-size: 15px;
+ }
+
+ .navigationbar li a {
+ display: block;
+ text-decoration: none;
+ background: url('../images/arrow_bc.png');
+ background-repeat: no-repeat;
+ background-position: right;
+ padding-right: 25px;
+ font-size: inherit;
+ }
+
+#buildversion {
+ font-style: italic;
+ font-size: small;
+ float: right;
+ margin-right: 5px;
}
-
-/* table of content
-no display
-*/
-
/*
-----------
headers
-----------
*/
-
-@media screen{
-.title{
-color:#313131;
-font-size: 18px;
-font-weight: normal;
-left: 0;
-padding-bottom: 20px;
-padding-left: 10px;
-padding-top: 20px;
-border-bottom: 1px #CCC solid ;
-font-weight:bold;
-margin-left:0px;
-margin-right:0px;
-}
+@media screen {
+ .title {
+ color: #313131;
+ font-size: 18px;
+ font-weight: normal;
+ left: 0;
+ padding-bottom: 20px;
+ padding-left: 10px;
+ padding-top: 20px;
+ border-bottom: 1px #CCC solid;
+ font-weight: bold;
+ margin-left: 0px;
+ margin-right: 0px;
+ }
}
h1 {
-margin: 0;
+ margin: 0
}
h2, p.h2 {
-font: 500 16px/1.2 Arial;
-font-weight:100;
-background-color:#F2F3F4;
-padding:4px;
-padding-left:14px;
-margin-bottom:30px;
-margin-top:30px;
-margin-left:-10px;
-margin-right:-5px;
-border-top:#E0E0DE 1px solid;
-border-bottom: #E0E0DE 1px solid;
-max-width: 99%;
-overflow: hidden;
+ font: 500 16px/1.2 Arial;
+ font-weight: 100;
+ background-color: #F2F3F4;
+ padding: 4px;
+ padding-left: 14px;
+ margin-bottom: 30px;
+ margin-top: 30px;
+ margin-left: -10px;
+ margin-right: -5px;
+ border-top: #E0E0DE 1px solid;
+ border-bottom: #E0E0DE 1px solid;
+ max-width: 99%;
+ overflow: hidden;
+}
+
+h3 {
+ font: 500 14px/1.2 Arial;
+ font-weight: 100;
+ text-decoration: underline;
+ margin-bottom: 30px;
+ margin-top: 30px;
+}
+
+h3.fn, span.fn {
+ border-width: 1px;
+ border-style: solid;
+ border-color: #E6E6E6;
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ background-color: #F6F6F6;
+ word-spacing: 3px;
+ padding: 5px 5px;
+ text-decoration: none;
+ font-weight: bold;
+ max-width: 75%;
+ font-size: 14px;
+ margin: 0px;
+ margin-top: 45px;
+}
+
+.name {
+ color: #1A1A1A
+}
+
+.type {
+ color: #808080
}
-h3{
-
-font: 500 14px/1.2 Arial;
-font-weight:100;
-text-decoration:underline;
-margin-bottom:30px;
-margin-top:30px;
+@media print {
+ .title {
+ color: #0066CB;
+ font-size: 32px;
+ font-weight: normal;
+ left: 0;
+ position: absolute;
+ right: 0;
+ top: 0;
+ }
}
-h3.fn,span.fn{
-border-width: 1px;
-border-style: solid;
-border-color: #E6E6E6;
--moz-border-radius: 7px 7px 7px 7px;
--webkit-border-radius: 7px 7px 7px 7px;
-border-radius: 7px 7px 7px 7px;
-background-color: #F6F6F6;
-word-spacing: 3px;
-padding: 5px 5px;
-text-decoration:none;
-font-weight:bold;
-max-width:75%;
-font-size:14px;
-margin:0px;
-margin-top:45px;
+/*
+-----------------
+table styles
+-----------------
+*/
+.table img {
+ border: none;
+ margin-left: 0px;
+ -moz-box-shadow: 0px 0px 0px #fff;
+ -webkit-box-shadow: 0px 0px 0px #fff;
+ box-shadow: 0px 0px 0px #fff;
}
-.name{
-color:#1A1A1A;
-}
-.type{
-color:#808080;
-}
+/* table with border alternative colours*/
+table, pre {
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ background-color: #F6F6F6;
+ border: 1px solid #E6E6E6;
+ border-collapse: separate;
+ font-size: 12px;
+ line-height: 1.2;
+ margin-bottom: 25px;
+ margin-left: 15px;
+ font-size: 12px;
+ line-height: 1.2;
+ margin-bottom: 25px;
+ margin-left: 15px;
+}
+
+ table tr.even {
+ background-color: white;
+ color: #66666E;
+ }
+
+ table tr.odd {
+ background-color: #F6F6F6;
+ color: #66666E;
+ }
+
+ table thead {
+ text-align: left;
+ padding-left: 20px;
+ background-color: #e1e0e0;
+ border-left: none;
+ border-right: none;
+ }
+
+ table thead th {
+ padding-top: 5px;
+ padding-left: 10px;
+ padding-bottom: 5px;
+ border-bottom: 2px solid #D1D1D1;
+ padding-right: 10px;
+ }
+
+ table td {
+ padding: 3px 15px 3px 20px;
+ border-bottom: #CCC dotted 1px;
+ }
+
+ table th {
+ text-align: left;
+ padding-left: 20px;
+ }
+
+ table p {
+ margin: 0px
+ }
+/* table bodless & white*/
-@media print {
-.title {
-color:#0066CB;
-font-family:Arial, Helvetica;
-font-size: 32px;
-font-weight: normal;
-left: 0;
-position: absolute;
-right: 0;
-top: 0;
-}
+.borderless {
+ border-radius: 0px 0px 0px 0px;
+ background-color: #fff;
+ border: 1px solid #fff;
}
+.borderless td {
+ border: none;
+ border-bottom: #fff dotted 1px;
+ }
+
+.borderless tr {
+ background-color: #FFF;
+ color: #66666E;
+ }
/*
------------------
-table styles
------------------
+-----------
+List
+-----------
*/
-.table img {
-border:none;
-margin-left:0px;
--moz-box-shadow:0px 0px 0px #fff;
--webkit-box-shadow: 0px 0px 0px #fff;
-box-shadow: 0px 0px 0px #fff;
+
+ul {
+ padding-bottom: 2px
}
-/* table with border alternative colours*/
+li {
+ margin-bottom: 10px;
+ padding-left: 8px;
+ list-style: outside;
+ list-style-type: square;
+ text-align: left;
+}
- table,pre{
--moz-border-radius: 7px 7px 7px 7px;
--webkit-border-radius: 7px 7px 7px 7px;
- border-radius: 7px 7px 7px 7px;
-background-color: #F6F6F6;
-border: 1px solid #E6E6E6;
-border-collapse: separate;
-font-size: 12px;
-line-height: 1.2;
-margin-bottom: 25px;
-margin-left: 15px;
-font-size: 12px;
-line-height: 1.2;
-margin-bottom: 25px;
-margin-left: 15px;
+ol {
+ margin: 10px;
+ padding: 0;
}
+ ol > li {
+ margin-left: 30px;
+ padding-left: 8px;
+ list-style: decimal;
+ }
-table th{
-text-align:left;
-padding-left:20px;
+.centerAlign {
+ text-align: left
}
-table td {
-padding: 3px 15px 3px 20px;
-border-bottom:#CCC dotted 1px;
+.cpp {
+ display: block;
+ margin: 10px;
+ overflow: auto;
+ padding: 20px 20px 20px 20px;
}
-table p { margin:0px;}
-table tr.even {
-background-color: white;
-color: #66666E;
+.js {
+ display: block;
+ margin: 10px;
+ overflow: auto;
+ padding: 20px 20px 20px 20px;
}
-table tr.odd {
-background-color: #F6F6F6;
-color: #66666E;
+.footerNavi {
+ width: auto;
+ text-align: right;
+ margin-top: 50px;
+ z-index: 1;
}
-
-table thead {
-text-align:left;
-padding-left:20px;
-background-color:#e1e0e0;
-border-left:none;
-border-right:none;
+.memItemLeft {
+ padding-right: 3px
}
-table thead th {
-padding-top:5px;
-padding-left:10px;
-padding-bottom:5px;
-border-bottom: 2px solid #D1D1D1;
-padding-right:10px;
+.memItemRight {
+ padding: 3px 15px 3px 0
}
+.qml {
+ display: block;
+ margin: 10px;
+ overflow: auto;
+ padding: 20px 20px 20px 20px;
+}
-/* table bodless & white*/
+.qmldefault {
+ padding-left: 5px;
+ float: right;
+ color: red;
+}
-.borderless {
-border-radius: 0px 0px 0px 0px;
-background-color: #fff;
-border: 1px solid #fff;
+.qmlreadonly {
+ padding-left: 5px;
+ float: right;
+ color: #254117;
}
-.borderless tr {
-background-color: #FFF;
-color: #66666E;
+.rightAlign {
+ padding: 3px 5px 3px 10px;
+ text-align: right;
}
-.borderless td {
-border:none;
-border-bottom:#fff dotted 1px;
+.qmldoc {
+ margin-left: 15px
}
/*
-----------
-List
+Content table
-----------
*/
-ul{
-padding-bottom:2px;
+@media print {
+ .toc {
+ float: right;
+ clear: right;
+ padding-bottom: 10px;
+ padding-top: 50px;
+ width: 100%;
+ background-image: url('../images/bgrContent.png');
+ background-position: top;
+ background-repeat: no-repeat;
+ }
+}
+
+@media screen {
+ .toc {
+ clear: both;
+ clear: right;
+ position: relative;
+ top: 83px;
+ float: right;
+ vertical-align: top;
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ background: #FFF url('../images/bgrContent.png');
+ background-position: top;
+ background-repeat: repeat-x;
+ border: 1px solid #E6E6E6;
+ padding-left: 5px;
+ padding-bottom: 10px;
+ height: auto;
+ width: 200px;
+ text-align: left;
+ margin-left: 20px;
+ }
+}
+
+.toc h3 {
+ text-decoration: none
+}
+
+.toc h3 {
+ font: 500 14px/1.2 Arial;
+ font-weight: 100;
+ padding: 0px;
+ margin: 0px;
+ padding-top: 5px;
+ padding-left: 5px;
+}
+
+.toc ul {
+ padding-left: 10px;
+ padding-right: 5px;
+ padding-top: 10px;
+}
+
+.toc ul li {
+ margin-left: 15px;
+ list-style-image: url('../images/blu_dot.png');
+ list-style: outside;
+ marker-offset: 0px;
+ margin-bottom: 8px;
+ padding-left: 0px;
+ }
+
+.toc .level1 {
+ border: none
+}
+
+.toc .level2 {
+ border: none;
+ margin-left: 25px;
+}
+
+.level3 {
+ border: none;
+ margin-left: 30px;
+}
+
+.clearfix {
+ clear: both
}
-li {
-margin-bottom: 10px;
-padding-left: 8px;
-list-style:outside;
-list-style-type:square;
-text-align:left;
+/* start index box */
+
+.indexbox {
+ width: 100%;
+ display: inline-block;
}
+.indexbox .indexIcon {
+ width: 11%
+ }
-ol{
-margin:10px;
-padding:0;
-}
+ .indexbox .indexIcon span {
+ display: block
+ }
-ol > li{
-margin-left: 30px;
-padding-left:8px;
-list-style:decimal;
+.indexboxcont {
+ display: block
}
-.centerAlign{
-text-align: left;
-}
+.indexboxcont .sectionlist {
+ display: inline-block;
+ vertical-align: top;
+ width: 32.5%;
+ padding: 0;
+ }
-.cpp{
-display: block;
-margin: 10px;
-overflow: auto;
-padding: 20px 20px 20px 20px;
-}
+ .indexboxcont .sectionlist ul {
+ margin-bottom: 20px
+ }
-.js{
-display: block;
-margin: 10px;
-overflow: auto;
-padding: 20px 20px 20px 20px;
-}
+ .indexboxcont .sectionlist ul li {
+ line-height: 1.5
+ }
-.footer{
-margin-top: 50px;
-padding-left:5px;
-margin-bottom: 10px;
-font-size:10px;
-border-top: 1px solid #999;
-padding-top:11px;
-}
+.indexboxcont .indexIcon {
+ width: 11%;
+ *width: 18%;
+ _width: 18%;
+ overflow: hidden;
+ }
-.footerNavi{
-width:auto;
-text-align:right;
-margin-top:50px;
-z-index:1;
-}
+.indexboxcont .section {
+ float: left
+ }
-.memItemLeft{
-padding-right: 3px;
+.indexboxcont .section {
+ display: inline-block;
+ width: 49%;
+ *width: 42%;
+ _width: 42%;
+ padding: 0 2% 0 1%;
+ vertical-align: top;
+ }
+
+ .indexboxcont .section p {
+ padding-top: 20px;
+ padding-bottom: 20px;
+ }
+
+.indexboxcont:after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
}
-.memItemRight{
-padding: 3px 15px 3px 0;
-}
+/*
+-----------
+Landing page
+-----------
+*/
-.qml{
-display: block;
-margin: 10px;
-overflow: auto;
-padding: 20px 20px 20px 20px;
+.col-group {
+ white-space: nowrap;
+ vertical-align: top;
}
-.qmldefault{
-padding-left: 5px;
-float: right;
-color: red;
+.col-1 {
+ display: inline-block;
+ white-space: normal;
+ width: 70%;
+ height: 100%;
+ float: left;
}
-.qmlreadonly{
-padding-left: 5px;
-float: right;
-color: #254117;
-}
+.col-1 h1 {
+ margin: 20px 0 0 0
+ }
-.rightAlign{
-padding: 3px 5px 3px 10px;
-text-align: right;
+.col-2 {
+ display: inline-block;
+ white-space: normal;
+ width: 25%;
+ margin: 0 0 0 50px;
}
-.qmldoc {
-margin-left: 15px;
+.sectionlist {
+ width: 100% !important
}
/*
------------
-Content table
------------
+Additions from Qt Project
*/
-@media print{
-.toc {
-float: right;
-clear: right;
-padding-bottom: 10px;
-padding-top: 50px;
-width: 100%;
-background-image:url(../images/bgrContent.png);
-background-position:top;
-background-repeat:no-repeat;
-}
+body {
+ background: #E8E8E8;
+ margin: 0px;
+ font-family: "Open Sans",sans-serif !important;
}
-@media screen{
-.toc{
-clear: both;
-clear: right;
-position: relative;
-top: 83px;
-float:right;
-vertical-align:top;
--moz-border-radius: 7px 7px 7px 7px;
--webkit-border-radius: 7px 7px 7px 7px;
-border-radius: 7px 7px 7px 7px;
- background:#FFF url(../images/bgrContent.png);
-background-position:top;
-background-repeat:repeat-x;
-border: 1px solid #E6E6E6;
-padding-left:5px;
-padding-bottom:10px;
-height: auto;
-width: 200px;
-text-align:left;
-margin-left:20px;
+.qt13a-twoCol {
+ width: 23.46939%;
+ float: left;
+ margin-right: 2.04082%;
+ display: inline;
}
+
+.qt13a-fourCol {
+ width: 48.97959%;
+ float: left;
+ margin-right: 2.04082%;
+ display: inline;
}
-.toc h3{
-text-decoration:none;
+.qt13a-sixCol {
+ width: 70.4898%;
+ float: left;
+ margin-right: 2.04082%;
+ display: inline;
}
-.toc h3{font: 500 14px/1.2 Arial;
-font-weight:100;
-padding:0px;
-margin:0px;
-padding-top:5px;
-padding-left:5px;
+.qt13a-eightCol {
+ width: 100%;
+ float: left;
+ margin-right: 2.04082%;
+ display: inline;
}
+.qt13a-fiveCol {
+ width: 17.35537%;
+ float: left;
+ margin-right: 3.30579%;
+ display: inline;
+}
-.toc ul{
-padding-left:10px;
-padding-right:5px;
-padding-top:10px;
+.qt13a-fiveCol:nth-child(2n) {
+ float: left;
+ margin-right: 3.30579%;
}
-.toc ul li{
-margin-left:15px;
-list-style-image:url(../images/blu_dot.png);
-list-style:outside;
-marker-offset: 0px;
-margin-bottom:8px;
-padding-left:0px;
+.qt13a-omega {
+ float: right;
+ margin-right: 0;
+ *margin-left: -20px;
+ display: inline;
}
-.toc .level1{
-border:none;}
+.qt13a-last {
+ float: right;
+ margin-right: 0;
+ *margin-left: -20px;
+ display: inline;
+}
+
+.qt13a-container {
+ *zoom: 1;
+ padding-left: 20px;
+ padding-right: 20px;
+ margin-left: auto;
+ margin-right: auto;
+ max-width: 1045px;
+}
+
+.qt13a-container:after {
+ content: "";
+ display: table;
+ clear: both;
+}
+
+.qt13a-container.qt13a-dynamic {
+ max-width: 1295px
+}
+
+.qt13a-no-bg-img {
+ background-image: none !important
+}
+
+.qt13a-wrapper {
+ overflow: hidden
+}
+
+.content-view {
+ position: relative;
+ overflow: hidden;
+}
+
+#qt13a-header {
+ background: url('../images/Qt-header-bg.jpg') repeat;
+ min-height: 126px;
+ padding: 0;
+ margin: 0;
+ min-width: 1045px;
+ margin-bottom: 18px;
+}
+
+ #qt13a-header .qt13a-nav-divider-left {
+ border-left: 1px solid #35322f;
+ padding-left: 10px;
+ margin-left: 5px;
+ font-size: 13px;
+ }
+
+ #qt13a-header #qt13a-title_nav {
+ padding-top: 34px;
+ width: 87.37374%;
+ float: left;
+ margin-right: 1.0101%;
+ display: inline;
+ float: right;
+ margin-right: 0;
+ *margin-left: -20px;
+ display: inline;
+ }
+
+ #qt13a-header .qt13a-gradient {
+ background: url('../images/Qt-gradient.png') repeat-x;
+ background-position: bottom;
+ margin: 0;
+ min-height: 126px;
+ padding: 0;
+ }
+
+ #qt13a-header p.qt13a-title {
+ font-size: 24px;
+ margin: 0 0 0 0px;
+ letter-spacing: -1px;
+ color: #35322f;
+ font-weight: 600;
+ }
+
+ #qt13a-header p.qt13a-title a {
+ font-weight: 600;
+ color: #35322f;
+ }
+
+ #qt13a-header p.qt13a-title a:hover {
+ color: #35322f;
+ text-decoration: none;
+ }
+
+ #qt13a-header #qt13a-title {
+ padding: 0px 0 0 0px;
+ padding-bottom: 0px;
+ }
+
+ #qt13a-header #qt13a-logo {
+ float: left;
+ width: 11.61616%;
+ float: left;
+ margin-right: 1.0101%;
+ display: inline;
+ margin: 20px 0px 10px 0;
+ min-width: 50px;
+ }
+
+ #qt13a-header #qt13a-logo .qt13a-site-logo {
+ background: url('../images/Qt-logo.png') no-repeat;
+ text-indent: -100em;
+ overflow: hidden;
+ display: block;
+ height: 90px;
+ -moz-box-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+
+ #qt13a-header #qt13a-logo img {
+ float: left;
+ border: 0;
+ -moz-box-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+
+ #qt13a-header .qt13a-nav {
+ background: none
+ }
+
+ #qt13a-header .qt13a-nav .qt13a-nav-divider-left {
+ border-left: 1px solid #35322f;
+ padding-left: 20px;
+ }
+
+ #qt13a-header .qt13a-nav .qt13a-nav-small a {
+ font-size: 13px
+ }
+
+ #qt13a-header .qt13a-nav ul {
+ margin: 0 0 0 0px;
+ padding: 11px 0 0;
+ background: none;
+ }
+
+ #qt13a-header .qt13a-nav ul li.devnet-active a {
+ color: #fff
+ }
+
+ #qt13a-header .qt13a-nav ul li {
+ display: inline-block;
+ width: auto;
+ padding: 0 2.88% 0 0;
+ margin: 0;
+ border: 0;
+ *display: inline;
+ zoom: 1;
+ }
+
+ #qt13a-header .qt13a-nav ul li a {
+ color: #35322f;
+ margin: 0;
+ padding: 0;
+ line-height: 18px;
+ font-size: 18px;
+ }
+
+ #qt13a-header .qt13a-nav ul li a:hover, #qt13a-header .qt13a-nav ul li a:active, #qt13a-header .qt13a-nav ul li a.active {
+ color: #fff;
+ text-decoration: none;
+ }
+
+#qt13a-register_search {
+ display: block;
+ font-variant: 400;
+ float: right;
+}
+
+#qt13a-register {
+ padding: 34px 0px 0;
+ float: right;
+ text-align: right;
+ color: #1e1b18;
+}
+
+ #qt13a-register .qt13a-link-divider {
+ padding: 0 5px
+ }
+
+ #qt13a-register a {
+ color: #1e1b18;
+ font-weight: 400;
+ font-size: 13px;
+ padding-left: 13px;
+ }
+
+ #qt13a-register a:visited {
+ color: #1e1b18
+ }
+
+ #qt13a-register a:hover {
+ color: #fff;
+ text-decoration: none;
+ }
+
+#search {
+ margin-top: 23px
+}
+
+#qt13a-footer {
+ background: url('../images/Qt-header-bg.jpg') repeat;
+ margin: 0;
+}
+
+ #qt13a-footer .qt13a-container {
+ padding: 36px 0
+ }
+
+ #qt13a-footer .qt13a-gradient {
+ background: url('../images/Qt-dark_gradient.png') repeat-x;
+ background-position: bottom;
+ margin: 0;
+ min-height: 126px;
+ padding: 0;
+ }
+
+ #qt13a-footer .qt13a-shadow {
+ background: transparent url('../images/Qt-footer_shadow.png') repeat-x top center
+ }
+
+ #qt13a-footer .qt13a-last {
+ float: right;
+ margin-right: 0;
+ *margin-left: -20px;
+ display: inline;
+ }
+
+ #qt13a-footer ul {
+ width: 17.35537%;
+ float: left;
+ margin-right: 3.30579%;
+ display: inline;
+ padding-left: 0;
+ list-style-type: none;
+ }
+
+ #qt13a-footer ul li a.qt13a-some-icon {
+ width: 32px;
+ height: 32px;
+ background-repeat: none;
+ text-indent: -300em;
+ overflow: hidden;
+ display: -moz-inline-stack;
+ display: inline-block;
+ vertical-align: middle;
+ *vertical-align: auto;
+ zoom: 1;
+ *display: inline;
+ }
-.toc .level2{
-border:none;
-margin-left: 25px;
-}
+ #qt13a-footer ul li a {
+ font-family: "Open Sans",sans-serif;
+ font-size: 13px;
+ color: #35322f;
+ padding: 0;
+ font-weight: 400;
+ }
-.level3{
-border:none;
-margin-left: 30px;
-}
+ #qt13a-footer ul li a:hover, #qt13a-footer ul li a:active {
+ color: #35322f;
+ text-decoration: underline;
+ }
-.clearfix{
-clear:both;}
+ #qt13a-footer .qt13a-title a, #qt13a-footer .qt13a-title {
+ padding: 18px 0 18px;
+ font-weight: 400;
+ letter-spacing: -0.5pt;
+ color: #35322f;
+ font-size: 18px;
+ margin: 0;
+ }
-/* start index box */
-.indexbox
-{
-width: 100%;
-display:inline-block;
+.qt13a-copyright {
+ border-top: 1px solid #000;
+ background: url('../images/Qt-footer-bg.jpg') repeat;
+ margin: 0;
+ padding: 36px 0;
+ font-weight: 400;
+ font-size: 0.84615em;
+ line-height: 1.63636em;
}
-.indexboxcont
-{
-display: block;
+.qt13a-copyright p {
+ padding: 0;
+ color: #aeadac;
+ font-size: 11px;
+ }
-}
+.qt13a-copyright a {
+ color: #328930
+ }
-.indexboxcont .section
-{
-display: inline-block;
-width: 49%;
-*width:42%;
-_width:42%;
-padding:0 2% 0 1%;
-vertical-align:top;
-}
+.qt13a-copyright a:visited {
+ color: #328930
+ }
-.indexboxcont .indexIcon
-{
-width: 11%;
-*width:18%;
-_width:18%;
-overflow:hidden;
+.searchbox {
+ display: block;
+ overflow: hidden;
+ padding: 0px 35px 0 5px;
}
-.indexboxcont .section {
- float: left;
+.content-view {
+ position: relative;
+ overflow: hidden;
}
-.indexboxcont .section p
-{
-padding-top: 20px;
-padding-bottom: 20px;
-}
-.indexboxcont .sectionlist
-{
-display: inline-block;
-vertical-align:top;
-width: 32.5%;
-padding: 0;
-}
-.indexboxcont .sectionlist ul
-{
-margin-bottom: 20px;
+p, li, p.forum-overview-title, p.forum-description, p.desc, p.forum-lastpost, div.navigationbars li, div.block-profile div {
+ font-size: 13px
}
-.indexboxcont .sectionlist ul li
-{
-line-height: 1.5;
+p.forum-description.desc {
+ font-size: 13px !important
}
-.content .indexboxcont li
-{
-font: normal bold 13px/1 Verdana;
+.steps li {
+ font-size: 16px
}
-.content .normallist li
-{
-font: normal 13px/1 Verdana;
+div.license p, div.notes p {
+ font-size: 12px !important
}
-.indexbox .indexIcon {
-width: 11%;
+a {
+ color: #44a51c;
+ text-decoration: none;
}
-.indexbox .indexIcon span
-{
-display: block;
+.wrap {
+ padding-left: 30px
}
-.indexboxcont:after
-{
-content: ".";
-display: block;
-height: 0;
-clear: both;
-visibility: hidden;
+a:visited {
+ color: #007330;
+ text-align: left;
}
-/*
------------
-Landing page
------------
-*/
-.col-group {
- white-space: nowrap;
- vertical-align: top;
+a:hover {
+ color: #44a51c;
+ text-align: left;
}
-.col-1 {
- display: inline-block;
- white-space: normal;
- width: 70%;
- height: 100%;
- float: left;
+a:visited:hover {
+ color: #44a51c;
+ text-align: left;
}
-.col-1 h1 {
- margin: 20px 0 0 0;
+a:link {
+ color: #007330;
+ text-decoration: none;
+ text-align: left;
}
-.col-2 {
- display: inline-block;
- white-space: normal;
- width: 25%;
- margin: 0 0 0 50px;
+.main {
+ padding: 0px 30px 30px 30px
}
-.sectionlist {
- width: 100% !important;
+.main-rounded {
+ display: inline-block;
+ background: none repeat scroll 0% 0% rgb(255,255,255);
+ width: 100%;
+ border: 1px solid #DADADA;
+ border-radius: 10px 10px 10px 10px;
+ box-shadow: 0 0 3px #C4C4C4;
+ padding-bottom: 30px;
}
diff --git a/examples/widgets/dialogs/standarddialogs/dialog.cpp b/examples/widgets/dialogs/standarddialogs/dialog.cpp
index c626b63b7d..fdd3633950 100644
--- a/examples/widgets/dialogs/standarddialogs/dialog.cpp
+++ b/examples/widgets/dialogs/standarddialogs/dialog.cpp
@@ -121,6 +121,10 @@ Dialog::Dialog(QWidget *parent)
textLabel->setFrameStyle(frameStyle);
QPushButton *textButton = new QPushButton(tr("QInputDialog::get&Text()"));
+ multiLineTextLabel = new QLabel;
+ multiLineTextLabel->setFrameStyle(frameStyle);
+ QPushButton *multiLineTextButton = new QPushButton(tr("QInputDialog::get&MultiLineText()"));
+
colorLabel = new QLabel;
colorLabel->setFrameStyle(frameStyle);
QPushButton *colorButton = new QPushButton(tr("QColorDialog::get&Color()"));
@@ -177,6 +181,7 @@ Dialog::Dialog(QWidget *parent)
connect(doubleButton, SIGNAL(clicked()), this, SLOT(setDouble()));
connect(itemButton, SIGNAL(clicked()), this, SLOT(setItem()));
connect(textButton, SIGNAL(clicked()), this, SLOT(setText()));
+ connect(multiLineTextButton, SIGNAL(clicked()), this, SLOT(setMultiLineText()));
connect(colorButton, SIGNAL(clicked()), this, SLOT(setColor()));
connect(fontButton, SIGNAL(clicked()), this, SLOT(setFont()));
connect(directoryButton, SIGNAL(clicked()),
@@ -206,7 +211,9 @@ Dialog::Dialog(QWidget *parent)
layout->addWidget(itemLabel, 2, 1);
layout->addWidget(textButton, 3, 0);
layout->addWidget(textLabel, 3, 1);
- layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding), 4, 0);
+ layout->addWidget(multiLineTextButton, 4, 0);
+ layout->addWidget(multiLineTextLabel, 4, 1);
+ layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding), 5, 0);
toolbox->addItem(page, tr("Input Dialogs"));
const QString doNotUseNativeDialog = tr("Do not use native dialog");
@@ -327,6 +334,17 @@ void Dialog::setText()
//! [3]
}
+void Dialog::setMultiLineText()
+{
+//! [4]
+ bool ok;
+ QString text = QInputDialog::getMultiLineText(this, tr("QInputDialog::getMultiLineText()"),
+ tr("Address:"), "John Doe\nFreedom Street", &ok);
+ if (ok && !text.isEmpty())
+ multiLineTextLabel->setText(text);
+//! [4]
+}
+
void Dialog::setColor()
{
const QColorDialog::ColorDialogOptions options = QFlag(colorDialogOptionsWidget->value());
diff --git a/examples/widgets/dialogs/standarddialogs/dialog.h b/examples/widgets/dialogs/standarddialogs/dialog.h
index 27b1de98cb..d6272c440e 100644
--- a/examples/widgets/dialogs/standarddialogs/dialog.h
+++ b/examples/widgets/dialogs/standarddialogs/dialog.h
@@ -63,6 +63,7 @@ private slots:
void setDouble();
void setItem();
void setText();
+ void setMultiLineText();
void setColor();
void setFont();
void setExistingDirectory();
@@ -80,6 +81,7 @@ private:
QLabel *doubleLabel;
QLabel *itemLabel;
QLabel *textLabel;
+ QLabel *multiLineTextLabel;
QLabel *colorLabel;
QLabel *fontLabel;
QLabel *directoryLabel;
diff --git a/examples/widgets/doc/src/addressbook-fr.qdoc b/examples/widgets/doc/src/addressbook-fr.qdoc
index 9a7bc3a6b7..7d15d99597 100644
--- a/examples/widgets/doc/src/addressbook-fr.qdoc
+++ b/examples/widgets/doc/src/addressbook-fr.qdoc
@@ -71,8 +71,6 @@
*/
/*!
- \page tutorials-addressbook-fr-part1.html
-
\example tutorials/addressbook-fr/part1
\title Carnet d'adresses 1 - Conception de l'interface utilisateur
@@ -229,8 +227,6 @@
*/
/*!
- \page tutorials-addressbook-fr-part2.html
-
\example tutorials/addressbook-fr/part2
\title Carnet d'adresses 2 - Ajouter des adresses
@@ -389,8 +385,6 @@
*/
/*!
- \page tutorials-addressbook-fr-part3.html
-
\example tutorials/addressbook-fr/part3
\title Carnet d'adresses 3 - Navigation entre les éléments
@@ -509,8 +503,6 @@
/*!
- \page tutorials-addressbook-fr-part4.html
-
\example tutorials/addressbook-fr/part4
\title Carnet d'Adresses 4 - éditer et supprimer des adresses
@@ -659,8 +651,6 @@
*/
/*!
- \page tutorials-addressbook-fr-part5.html
-
\example tutorials/addressbook-fr/part5
\title Carnet d'adresse 5 - Ajout d'une fonction de recherche
@@ -808,8 +798,6 @@
*/
/*!
- \page tutorials-addressbook-part6.html
-
\example tutorials/addressbook-fr/part6
\title Carnet d'Adresses 6 - Sauvegarde et chargement
@@ -945,8 +933,6 @@
*/
/*!
- \page tutorials-addressbook-fr-part7.html
-
\example tutorials/addressbook-fr/part7
\title Carnet d'adresse 7 - Fonctionnalités avancées
diff --git a/examples/widgets/doc/src/addressbook-tutorial.qdoc b/examples/widgets/doc/src/addressbook-tutorial.qdoc
index 089ab2319d..78517f80d7 100644
--- a/examples/widgets/doc/src/addressbook-tutorial.qdoc
+++ b/examples/widgets/doc/src/addressbook-tutorial.qdoc
@@ -77,8 +77,6 @@
*/
/*!
- \page tutorials-addressbook-part1.html
-
\example tutorials/addressbook/part1
\title Part 1 - Designing the User Interface
@@ -231,8 +229,6 @@
*/
/*!
- \page tutorials-addressbook-part2.html
-
\example tutorials/addressbook/part2
\title Part 2 - Adding Addresses
@@ -382,8 +378,6 @@
*/
/*!
- \page tutorials-addressbook-part3.html
-
\example tutorials/addressbook/part3
\title Part 3 - Navigating between Entries
@@ -499,8 +493,6 @@
*/
/*!
- \page tutorials-addressbook-part4.html
-
\example tutorials/addressbook/part4
\title Part 4 - Editing and Removing Addresses
@@ -633,8 +625,6 @@
*/
/*!
- \page tutorials-addressbook-part5.html
-
\example tutorials/addressbook/part5
\title Part 5 - Adding a Find Function
@@ -777,8 +767,6 @@
*/
/*!
- \page tutorials-addressbook-part6.html
-
\example tutorials/addressbook/part6
\title Part 6 - Loading and Saving
@@ -899,8 +887,6 @@
*/
/*!
- \page tutorials-addressbook-part7.html
-
\example tutorials/addressbook/part7
\title Part 7 - Additional Features
diff --git a/examples/widgets/itemviews/spreadsheet/main.cpp b/examples/widgets/itemviews/spreadsheet/main.cpp
index 1cc9205d7e..f518986bc5 100644
--- a/examples/widgets/itemviews/spreadsheet/main.cpp
+++ b/examples/widgets/itemviews/spreadsheet/main.cpp
@@ -42,14 +42,15 @@
#include "spreadsheet.h"
#include <QApplication>
+#include <QLayout>
int main(int argc, char** argv) {
Q_INIT_RESOURCE(spreadsheet);
QApplication app(argc, argv);
SpreadSheet sheet(10, 6);
sheet.setWindowIcon(QPixmap(":/images/interview.png"));
- sheet.resize(640, 420);
sheet.show();
+ sheet.layout()->setSizeConstraint(QLayout::SetFixedSize);
return app.exec();
}
diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp
index 59d29f0e61..6fab0c2aae 100644
--- a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp
+++ b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp
@@ -64,6 +64,7 @@ SpreadSheet::SpreadSheet(int rows, int cols, QWidget *parent)
toolBar->addWidget(formulaInput);
table = new QTableWidget(rows, cols, this);
+ table->setSizeAdjustPolicy(QTableWidget::AdjustToContents);
for (int c = 0; c < cols; ++c) {
QString character(QChar('A' + c));
table->setHorizontalHeaderItem(c, new QTableWidgetItem(character));
diff --git a/examples/widgets/widgets/spinboxes/window.cpp b/examples/widgets/widgets/spinboxes/window.cpp
index 8c35f93c56..acce642ec6 100644
--- a/examples/widgets/widgets/spinboxes/window.cpp
+++ b/examples/widgets/widgets/spinboxes/window.cpp
@@ -94,6 +94,14 @@ void Window::createSpinBoxes()
priceSpinBox->setValue(99);
//! [4] //! [5]
+ QLabel *hexLabel = new QLabel(tr("Enter a value between "
+ "%1 and %2:").arg('-' + QString::number(31, 16)).arg(QString::number(31, 16)));
+ QSpinBox *hexSpinBox = new QSpinBox;
+ hexSpinBox->setRange(-31, 31);
+ hexSpinBox->setSingleStep(1);
+ hexSpinBox->setValue(0);
+ hexSpinBox->setDisplayIntegerBase(16);
+
QVBoxLayout *spinBoxLayout = new QVBoxLayout;
spinBoxLayout->addWidget(integerLabel);
spinBoxLayout->addWidget(integerSpinBox);
@@ -101,6 +109,8 @@ void Window::createSpinBoxes()
spinBoxLayout->addWidget(zoomSpinBox);
spinBoxLayout->addWidget(priceLabel);
spinBoxLayout->addWidget(priceSpinBox);
+ spinBoxLayout->addWidget(hexLabel);
+ spinBoxLayout->addWidget(hexSpinBox);
spinBoxesGroup->setLayout(spinBoxLayout);
}
//! [5]
diff --git a/mkspecs/blackberry-armv7le-qcc/qmake.conf b/mkspecs/blackberry-armv7le-qcc/qmake.conf
index 2e24e4e0d3..cfcd2aecf0 100644
--- a/mkspecs/blackberry-armv7le-qcc/qmake.conf
+++ b/mkspecs/blackberry-armv7le-qcc/qmake.conf
@@ -16,6 +16,7 @@ contains(QT_CONFIG, stack-protector-strong) {
}
QMAKE_CFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mthumb -D_FORTIFY_SOURCE=2
+QMAKE_CXXFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mthumb -D_FORTIFY_SOURCE=2
QMAKE_LFLAGS_SHLIB += -Wl,-z,relro -Wl,-z,now
diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf
index 4f141351c1..ace2496f10 100644
--- a/mkspecs/common/clang.conf
+++ b/mkspecs/common/clang.conf
@@ -20,13 +20,3 @@ QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
QMAKE_CXXFLAGS_CXX11 = -std=c++11
QMAKE_LFLAGS_CXX11 =
-
-QMAKE_CFLAGS_SSE2 += -msse2
-QMAKE_CFLAGS_SSE3 += -msse3
-QMAKE_CFLAGS_SSSE3 += -mssse3
-QMAKE_CFLAGS_SSE4_1 += -msse4.1
-QMAKE_CFLAGS_SSE4_2 += -msse4.2
-QMAKE_CFLAGS_AVX += -mavx
-QMAKE_CFLAGS_AVX2 += -mavx2
-QMAKE_CFLAGS_IWMMXT += -mcpu=iwmmxt
-QMAKE_CFLAGS_NEON += -mfpu=neon
diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf
index 39465aa765..3c477438a3 100644
--- a/mkspecs/common/ios/qmake.conf
+++ b/mkspecs/common/ios/qmake.conf
@@ -15,9 +15,6 @@ QMAKE_RANLIB = ranlib -s
QMAKE_LINK = $$QMAKE_CXX
QMAKE_LINK_SHLIB = $$QMAKE_CXX
-# Basic iOS frameworks needed for any GUI app
-QMAKE_LFLAGS += -framework Foundation -framework UIKit -framework QuartzCore -lz
-
# No OpenGL ES1
QMAKE_INCDIR_OPENGL_ES1 =
QMAKE_LIBDIR_OPENGL_ES1 =
diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf
index 1b480aa267..4421665370 100644
--- a/mkspecs/common/mac.conf
+++ b/mkspecs/common/mac.conf
@@ -4,7 +4,7 @@
!load(device_config): error(Could not successfully load device configuration)
-QMAKE_PLATFORM += mac
+QMAKE_PLATFORM += mac darwin
QMAKE_RESOURCE = /Developer/Tools/Rez
QMAKE_EXTENSION_SHLIB = dylib
diff --git a/mkspecs/common/macx.conf b/mkspecs/common/macx.conf
index 48efae5d1e..ad54612f22 100644
--- a/mkspecs/common/macx.conf
+++ b/mkspecs/common/macx.conf
@@ -2,7 +2,7 @@
# qmake configuration for common OS X
#
-QMAKE_PLATFORM += macx
+QMAKE_PLATFORM += osx macx
QMAKE_MAC_SDK = macosx
include(mac.conf)
diff --git a/mkspecs/darwin-g++/qmake.conf b/mkspecs/darwin-g++/qmake.conf
index 24a6224b7c..ab333b1684 100644
--- a/mkspecs/darwin-g++/qmake.conf
+++ b/mkspecs/darwin-g++/qmake.conf
@@ -5,7 +5,7 @@
#
MAKEFILE_GENERATOR = UNIX
-QMAKE_PLATFORM = mac macx
+QMAKE_PLATFORM = osx macx mac darwin
CONFIG += native_precompiled_headers
DEFINES += __USE_WS_X11__
diff --git a/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp b/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp
index a1fd633c28..6f59b73921 100644
--- a/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp
+++ b/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp
@@ -51,6 +51,7 @@ public:
virtual QSize screenSize() const;
virtual EGLNativeWindowType createNativeWindow(const QSize &size, const QSurfaceFormat &format);
virtual void destroyNativeWindow(EGLNativeWindowType window);
+ virtual EGLNativeDisplayType platformDisplay() const;
private:
QSize mScreenSize;
@@ -72,6 +73,11 @@ QSize QEglFSImx6Hooks::screenSize() const
return mScreenSize;
}
+EGLNativeDisplayType QEglFSImx6Hooks::platformDisplay() const
+{
+ return mNativeDisplay;
+}
+
EGLNativeWindowType QEglFSImx6Hooks::createNativeWindow(const QSize &size, const QSurfaceFormat &format)
{
Q_UNUSED(format);
diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf
index b4569df6d5..39144e7216 100644
--- a/mkspecs/features/configure.prf
+++ b/mkspecs/features/configure.prf
@@ -7,9 +7,6 @@ equals(MAKEFILE_GENERATOR, UNIX) {
QMAKE_MAKE = mingw32-make
} else:if(equals(MAKEFILE_GENERATOR, MSVC.NET)|equals(MAKEFILE_GENERATOR, MSBUILD)) {
QMAKE_MAKE = nmake
-} else:ios {
- # iOS unsets MAKEFILE_GENERATOR in its default_pre.prf
- QMAKE_MAKE = make
} else {
error("Configure tests are not supported with the $$MAKEFILE_GENERATOR Makefile generator.")
}
diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf
index 58a0620e01..2dcb8da063 100644
--- a/mkspecs/features/create_cmake.prf
+++ b/mkspecs/features/create_cmake.prf
@@ -66,12 +66,6 @@ contains(CMAKE_BIN_DIR, "^\\.\\./.*") {
CMAKE_DLL_DIR_IS_ABSOLUTE = $$CMAKE_LIB_DIR_IS_ABSOLUTE
}
-CMAKE_HOST_DATA_DIR = $$cmakeRelativePath($$[QT_HOST_DATA], $$[QT_INSTALL_PREFIX])
-contains(CMAKE_HOST_DATA_DIR, "^\\.\\./.*") {
- CMAKE_HOST_DATA_DIR = $$[QT_HOST_DATA]/
- CMAKE_HOST_DATA_DIR_IS_ABSOLUTE = True
-}
-
static|staticlib:CMAKE_STATIC_TYPE = true
unix:contains(QT_CONFIG, reduce_relocations):CMAKE_ADD_FPIE_FLAGS = "true"
diff --git a/mkspecs/features/gcov.prf b/mkspecs/features/gcov.prf
new file mode 100644
index 0000000000..330831fc0e
--- /dev/null
+++ b/mkspecs/features/gcov.prf
@@ -0,0 +1,31 @@
+#
+# Tested with gcov 4.8.1
+# http://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/Gcov.html
+
+# To instrument a Qt application or library with the gcov coverage
+# tool, do `CONFIG+=gcov' in the application .pro file.
+#
+# To instrument Qt itself with gcov, use the `-gcov' configure
+# option.
+
+# The .gcno file is generated when the source file is compiled.
+# The .gcda file is generated when a program is executed.
+
+# Example how to generate the html output after you've run the program or test
+#
+# lcov --capture --directory . --output-file coverage-gcov.info --no-external
+# lcov --output-file coverage-gcov.info --remove coverage-gcov.info '*.moc*' '.*rcc*' '*3rdparty*'
+# genhtml coverage-gcov.info --output-directory doc/coverage
+
+# If you want to use gcov directly, you most likely need to manually move the .gcda and .gcno files
+# along with the program.
+#
+# mv .obj/debug-shared/tst_example.gc* .
+# gcov -b -c tst_example.cpp
+
+QMAKE_CFLAGS += -fprofile-arcs -ftest-coverage
+QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage
+QMAKE_OBJECTIVE_CFLAGS += -fprofile-arcs -ftest-coverage
+QMAKE_LFLAGS += -fprofile-arcs -ftest-coverage
+
+QMAKE_CLEAN += $(OBJECTS_DIR)*.gcno and $(OBJECTS_DIR)*.gcda
diff --git a/mkspecs/features/ios/default_post.prf b/mkspecs/features/ios/default_post.prf
index e9d2149351..654255eb1f 100644
--- a/mkspecs/features/ios/default_post.prf
+++ b/mkspecs/features/ios/default_post.prf
@@ -1,40 +1,44 @@
-CONFIG(qt):contains(QT, gui):equals(TEMPLATE, app): CONFIG += gui_app
+equals(TEMPLATE, app) {
+ qt:app_bundle:!macx-xcode {
+ # For Qt applications we want Xcode project files as the generated output,
+ # but since qmake doesn't handle the transition between makefiles and Xcode
+ # project files (which happens when using subdirs), we create a wrapper
+ # makefile that takes care of generating the Xcode project, and allows
+ # building by calling out to xcodebuild.
+ TEMPLATE = aux
-isEmpty(MAKEFILE_GENERATOR) {
- gui_app:app_bundle: \
- # For applications we want Xcode project files
- MAKEFILE_GENERATOR = XCODE
- else: \
- # For libs, etc we still want regular Makefiles
- MAKEFILE_GENERATOR = UNIX
-}
+ CONFIG -= have_target qt staticlib dll
+ SOURCES =
+ RESOURCES =
+ INSTALLS =
+
+ TARGET_XCODE_PROJECT_DIR = $${TARGET}.xcodeproj
+
+ system("cd $$system_quote($$OUT_PWD) && $${QMAKE_QMAKE} $$system_quote($$_PRO_FILE_) -spec macx-xcode")
-gui_app {
- # We have to do the link and dependency resolution for the platform plugin
- # manually, since QTPLUGIN and the prl lookup logic does not support
- # the -force_load link style. The -force_load option ensures that all
- # symbols from the static library are included, not just the ones the
- # linker have seen a use for so far. We need this because we load the platform
- # plugin from the platform plugin itself, using Q_IMPORT_PLUGIN.
- lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/libqios$$qtPlatformTargetSuffix()
- LIBS += "-force_load $${lib_path_and_base}.$${QMAKE_EXTENSION_STATICLIB}"
- LIBS += $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS)
+ # We use xcodebuild to do the actual build, but filter out the verbose
+ # output that shows all environment variables for each build step.
+ xcodebuild_build.commands = "@xcodebuild build | grep -v setenv"
+ QMAKE_EXTRA_TARGETS += xcodebuild_build
+ all.depends = xcodebuild_build
+ QMAKE_EXTRA_TARGETS += all
- # Which means we don't want the auto-generated import for the platform plugin
- CONFIG -= import_qpa_plugin
+ # We do the same for the clean action
+ xcodebuild_clean.commands = "@xcodebuild clean"
+ QMAKE_EXTRA_TARGETS += xcodebuild_clean
+ clean.depends = xcodebuild_clean
+ QMAKE_EXTRA_TARGETS += clean
- !no_main_wrapper {
- # We link the iosmain library manually as well, since it's not really a plugin
- lib_name = qiosmain
- lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix()
- LIBS += -L$$[QT_INSTALL_PLUGINS/get]/platforms -l$${lib_name}$$qtPlatformTargetSuffix()
- LIBS += $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS)
- DEFINES += main=qt_main
+ # And distclean
+ xcodebuild_distclean.commands = "$(DEL_FILE) -R $$TARGET_XCODE_PROJECT_DIR"
+ QMAKE_EXTRA_TARGETS += xcodebuild_distclean
+ distclean.depends = xcodebuild_distclean
+ QMAKE_EXTRA_TARGETS += distclean
}
}
-contains(MAKEFILE_GENERATOR, XCODE) {
+macx-xcode {
ios_device_family.name = TARGETED_DEVICE_FAMILY
ios_device_family.value = $$QMAKE_IOS_TARGETED_DEVICE_FAMILY
QMAKE_MAC_XCODE_SETTINGS += ios_device_family
@@ -46,24 +50,27 @@ isEmpty(QT_ARCH) {
# but we fail to pick up the architecture since we're not passing -arch
# yet. Xcode does not seem to have a way to run the shared toolchain
# in a way that will automatically do this (for example xcrun -sdk).
- contains(QMAKE_MAC_SDK, iphoneos.*): QT_ARCH = armv7
+ contains(QMAKE_MAC_SDK, iphoneos.*): QT_ARCH = arm
else: QT_ARCH = i386 # Simulator
-} else {
- # Fix up the QT_ARCH to be more specific
- equals(QT_ARCH, arm) {
- # Samsung S5PC100, Apple A4, A5, A5X
- QT_ARCH = armv7
-
- # FIXME: How do we support armv7s when Qt can't do universal builds?
- }
}
-!equals(MAKEFILE_GENERATOR, XCODE) {
- arch_flag = -arch $$QT_ARCH
- QMAKE_CFLAGS += $$arch_flag
- QMAKE_CXXFLAGS += $$arch_flag
- QMAKE_OBJECTIVE_CFLAGS += $$arch_flag
- QMAKE_LFLAGS += $$arch_flag
+# Be more specific about which architecture we're targeting
+equals(QT_ARCH, arm): \
+ actual_archs = armv7
+else: \
+ actual_archs = $$QT_ARCH
+
+macx-xcode {
+ QMAKE_XCODE_ARCHS = $$actual_archs
+} else {
+ for(arch, actual_archs): \
+ arch_flags += -arch $$arch
+
+ QMAKE_CFLAGS += $$arch_flags
+ QMAKE_CXXFLAGS += $$arch_flags
+ QMAKE_OBJECTIVE_CFLAGS += $$arch_flags
+ QMAKE_LFLAGS += $$arch_flags
}
+unset(actual_archs)
load(default_post)
diff --git a/mkspecs/features/ios/default_pre.prf b/mkspecs/features/ios/default_pre.prf
index 7cfbc03eb5..5db8d98d6c 100644
--- a/mkspecs/features/ios/default_pre.prf
+++ b/mkspecs/features/ios/default_pre.prf
@@ -1,5 +1,3 @@
-# Unset makefile generator, so we can auto-detect value in default_post
-!macx-xcode: unset(MAKEFILE_GENERATOR)
load(default_pre)
diff --git a/mkspecs/features/ios/qt.prf b/mkspecs/features/ios/qt.prf
new file mode 100644
index 0000000000..80d4907acd
--- /dev/null
+++ b/mkspecs/features/ios/qt.prf
@@ -0,0 +1,24 @@
+
+equals(TEMPLATE, app):contains(QT, gui(-private)?) {
+ LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms
+
+ lib_name = qios
+ lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix()
+ LIBS += -l$${lib_name}$$qtPlatformTargetSuffix() $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS)
+
+ # By marking qt_registerPlatformPlugin as undefined, we ensure that
+ # the plugin.o translation unit is considered for inclusion in
+ # the final binary, which in turn ensures that the plugin's
+ # static initializer is included and run.
+ QMAKE_LFLAGS += -u _qt_registerPlatformPlugin
+
+ # We do link and dependency resolution for the platform plugin
+ # manually, since we know we always need the plugin, so we don't
+ # need to generate an import for it.
+ CONFIG -= import_qpa_plugin
+
+ # FIXME: Solve using 'ld -r -alias -unexported_symbol' instead
+ !no_main_wrapper: DEFINES += main=qt_user_main
+}
+
+load(qt)
diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf
index 85e2db25bc..be3cd5273c 100644
--- a/mkspecs/features/qt_docs.prf
+++ b/mkspecs/features/qt_docs.prf
@@ -34,7 +34,7 @@ qtmver.value = $$replace(qtver.value, ^(\\d+\\.\\d+).*$, \\1)
qtvertag.name = QT_VERSION_TAG
qtvertag.value = $$replace(qtver.value, \.,)
qtdocs.name = QT_INSTALL_DOCS
-qtdocs.value = $$[QT_INSTALL_DOCS/get]
+qtdocs.value = $$[QT_INSTALL_DOCS/src]
qtAddToolEnv(QDOC, qtver qtmver qtvertag qtdocs)
doc_command = $$QDOC $$QMAKE_DOCS
prepare_docs {
diff --git a/mkspecs/features/simd.prf b/mkspecs/features/simd.prf
index 14da926dc3..e0cd5a3a58 100644
--- a/mkspecs/features/simd.prf
+++ b/mkspecs/features/simd.prf
@@ -12,6 +12,9 @@
# Get the SIMD flags
load(qt_build_config)
+# Set QT_CPU_FEATURES for convenience
+QT_CPU_FEATURES = $$eval(QT_CPU_FEATURES.$$QT_ARCH)
+
#
# Set up compilers for SIMD (SSE/AVX, NEON etc)
#
diff --git a/mkspecs/features/spec_post.prf b/mkspecs/features/spec_post.prf
index c9e9f8b2f6..ad03c9c428 100644
--- a/mkspecs/features/spec_post.prf
+++ b/mkspecs/features/spec_post.prf
@@ -9,7 +9,7 @@ isEmpty(QMAKE_PLATFORM) {
isEmpty(TARGET_PLATFORM) {
equals(MAKEFILE_GENERATOR, UNIX) {
equals(QMAKE_HOST.os, Darwin): \
- TARGET_PLATFORM = macx
+ TARGET_PLATFORM = macx # backwards compatibility; cannot change
else: \
TARGET_PLATFORM = unix
} else:if(equals(MAKEFILE_GENERATOR, MSVC.NET) \
@@ -28,12 +28,18 @@ isEmpty(QMAKE_PLATFORM) {
equals(TARGET_PLATFORM, unix): \
QMAKE_PLATFORM = unix
else:equals(TARGET_PLATFORM, macx): \
- QMAKE_PLATFORM = mac macx unix
+ QMAKE_PLATFORM = osx macx mac darwin unix
else:equals(TARGET_PLATFORM, win32): \
QMAKE_PLATFORM = win32
else: \
error("Qmake spec sets an invalid TARGET_PLATFORM.")
}
+
+contains(QMAKE_PLATFORM, macx):!contains(QMAKE_PLATFORM, osx) {
+ warning("qmake spec specifies platform macx, but not osx.")
+ QMAKE_PLATFORM = osx $$QMAKE_PLATFORM
+}
+
CONFIG += $$QMAKE_PLATFORM
isEmpty(QMAKE_COMPILER) {
diff --git a/mkspecs/macx-clang-libc++-32/qmake.conf b/mkspecs/macx-clang-libc++-32/qmake.conf
deleted file mode 100644
index 3f7342da0b..0000000000
--- a/mkspecs/macx-clang-libc++-32/qmake.conf
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# qmake configuration for 32-bit Clang on OS X
-#
-
-warning("QMakespec macx-clang-libc++-32 is deprecated. Use macx-clang-32 instead.")
-
-MAKEFILE_GENERATOR = UNIX
-CONFIG += app_bundle incremental global_init_link_order lib_version_first plugin_no_soname
-QMAKE_INCREMENTAL_STYLE = sublib
-
-include(../common/macx.conf)
-include(../common/gcc-base-mac.conf)
-include(../common/clang.conf)
-include(../common/clang-mac.conf)
-
-QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
-
-QMAKE_CFLAGS += -arch i386
-QMAKE_OBJECTIVE_CFLAGS += -arch i386 -stdlib=libc++
-QMAKE_CXXFLAGS += -arch i386 -stdlib=libc++
-QMAKE_LFLAGS += -arch i386 -stdlib=libc++
-
-load(qt_config)
diff --git a/mkspecs/macx-clang-libc++/qmake.conf b/mkspecs/macx-clang-libc++/qmake.conf
deleted file mode 100644
index 7f4151e81b..0000000000
--- a/mkspecs/macx-clang-libc++/qmake.conf
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# qmake configuration for Clang on OS X
-#
-
-warning("QMakespec macx-clang-libc++ is deprecated. Use macx-clang instead.")
-
-MAKEFILE_GENERATOR = UNIX
-CONFIG += app_bundle incremental global_init_link_order lib_version_first plugin_no_soname
-QMAKE_INCREMENTAL_STYLE = sublib
-
-include(../common/macx.conf)
-include(../common/gcc-base-mac.conf)
-include(../common/clang.conf)
-include(../common/clang-mac.conf)
-
-QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
-
-QMAKE_OBJECTIVE_CFLAGS += -stdlib=libc++
-QMAKE_CXXFLAGS += -stdlib=libc++
-QMAKE_LFLAGS += -stdlib=libc++
-
-load(qt_config)
diff --git a/mkspecs/macx-xcode/Info.plist.app b/mkspecs/macx-xcode/Info.plist.app
deleted file mode 100755
index 187a8e0aa4..0000000000
--- a/mkspecs/macx-xcode/Info.plist.app
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>NSPrincipalClass</key>
- <string>NSApplication</string>
- <key>CFBundleIconFile</key>
- <string>@ICON@</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleGetInfoString</key>
- <string>Created by Qt/QMake</string>
- <key>CFBundleSignature</key>
- <string>@TYPEINFO@</string>
- <key>CFBundleExecutable</key>
- <string>@EXECUTABLE@</string>
- <key>CFBundleIdentifier</key>
- <string>com.yourcompany.@EXECUTABLE@</string>
- <key>NOTE</key>
- <string>This file was generated by Qt/QMake.</string>
-</dict>
-</plist>
diff --git a/mkspecs/macx-xcode/Info.plist.lib b/mkspecs/macx-xcode/Info.plist.lib
deleted file mode 100644
index 63f1a945c2..0000000000
--- a/mkspecs/macx-xcode/Info.plist.lib
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundlePackageType</key>
- <string>FMWK</string>
- <key>CFBundleShortVersionString</key>
- <string>@SHORT_VERSION@</string>
- <key>CFBundleGetInfoString</key>
- <string>Created by Qt/QMake</string>
- <key>CFBundleSignature</key>
- <string>@TYPEINFO@</string>
- <key>CFBundleExecutable</key>
- <string>@LIBRARY@</string>
- <key>NOTE</key>
- <string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
-</dict>
-</plist>
diff --git a/mkspecs/macx-xcode/features/default_post.prf b/mkspecs/macx-xcode/features/default_post.prf
new file mode 100644
index 0000000000..4c4746bb2b
--- /dev/null
+++ b/mkspecs/macx-xcode/features/default_post.prf
@@ -0,0 +1,7 @@
+
+isEmpty(QMAKE_INFO_PLIST) {
+ plist_template = $$absolute_path(../../$$[QMAKE_XSPEC]/Info.plist.$${TEMPLATE})
+ exists($$plist_template): QMAKE_INFO_PLIST = $$plist_template
+}
+
+load(default_post)
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix
index 9b7bfa6f8b..2f8f07eb2d 100644
--- a/qmake/Makefile.unix
+++ b/qmake/Makefile.unix
@@ -4,7 +4,7 @@ QMKGENSRC = $(QMKSRC)/generators
#qmake code
OBJS=project.o option.o property.o main.o ioutils.o proitems.o \
- qmakeglobals.o qmakeparser.o qmakeevaluator.o qmakebuiltins.o \
+ qmakevfs.o qmakeglobals.o qmakeparser.o qmakeevaluator.o qmakebuiltins.o \
makefile.o unixmake2.o unixmake.o \
mingw_make.o winmakefile.o projectgenerator.o \
meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \
@@ -90,7 +90,7 @@ CPPFLAGS = -g $(EXTRA_CPPFLAGS) \
-I$(BUILD_PATH)/src/corelib/global -DHAVE_QCONFIG_CPP \
-I$(QMAKESPEC) \
-I$(SOURCE_PATH)/tools/shared \
- -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL -DPROEVALUATOR_DEBUG \
+ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \
-DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM
@@ -125,6 +125,9 @@ proitems.o: $(QMKLIBSRC)/proitems.cpp
qmakeglobals.o: $(QMKLIBSRC)/qmakeglobals.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
+qmakevfs.o: $(QMKLIBSRC)/qmakevfs.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $<
+
qmakeparser.o: $(QMKLIBSRC)/qmakeparser.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 85b5405b41..979155678e 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -38,7 +38,7 @@ CFLAGS_BARE = -c -Fo./ \
-I$(BUILD_PATH)\src\corelib\global -DHAVE_QCONFIG_CPP \
-I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \
-I$(SOURCE_PATH)\tools\shared \
- -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL -DPROEVALUATOR_DEBUG \
+ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \
-DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
-DUNICODE
@@ -57,7 +57,7 @@ ADDCLEAN = vc60.pdb vc70.pdb qmake.pdb qmake.ilk
!ENDIF
#qmake code
-OBJS = project.obj main.obj ioutils.obj proitems.obj \
+OBJS = project.obj main.obj ioutils.obj proitems.obj qmakevfs.obj \
qmakeglobals.obj qmakeparser.obj qmakeevaluator.obj qmakebuiltins.obj \
makefile.obj unixmake.obj unixmake2.obj mingw_make.obj \
option.obj winmakefile.obj projectgenerator.obj property.obj meta.obj \
diff --git a/qmake/doc/src/images/qmake-precompile-ui.png b/qmake/doc/images/qmake-precompile-ui.png
index 8c7b936fee..8c7b936fee 100644
--- a/qmake/doc/src/images/qmake-precompile-ui.png
+++ b/qmake/doc/images/qmake-precompile-ui.png
Binary files differ
diff --git a/qmake/doc/qmake.qdocconf b/qmake/doc/qmake.qdocconf
index cd8ac4d0ab..6b52ccc585 100644
--- a/qmake/doc/qmake.qdocconf
+++ b/qmake/doc/qmake.qdocconf
@@ -22,6 +22,9 @@ language = Cpp
sources = src/qmake-manual.qdoc
+imagedirs = images
+exampledirs = snippets
+
depends += \
activeqt \
qt3d \
@@ -67,9 +70,8 @@ depends += \
qtwebkit \
qtwebkitexamples \
qtwidgets \
+ qtwinextras \
qtx11extras \
qtxml \
qtxmlpatterns
-imagedirs = src/images
-exampledirs = src
diff --git a/qmake/doc/src/snippets/code/doc_src_qmake-manual.cpp b/qmake/doc/snippets/code/doc_src_qmake-manual.cpp
index bd63e600cd..bd63e600cd 100644
--- a/qmake/doc/src/snippets/code/doc_src_qmake-manual.cpp
+++ b/qmake/doc/snippets/code/doc_src_qmake-manual.cpp
diff --git a/qmake/doc/src/snippets/code/doc_src_qmake-manual.pro b/qmake/doc/snippets/code/doc_src_qmake-manual.pro
index 0ee4785887..0ee4785887 100644
--- a/qmake/doc/src/snippets/code/doc_src_qmake-manual.pro
+++ b/qmake/doc/snippets/code/doc_src_qmake-manual.pro
diff --git a/qmake/doc/src/snippets/qmake/comments.pro b/qmake/doc/snippets/qmake/comments.pro
index 957052c81d..957052c81d 100644
--- a/qmake/doc/src/snippets/qmake/comments.pro
+++ b/qmake/doc/snippets/qmake/comments.pro
diff --git a/qmake/doc/src/snippets/qmake/configscopes.pro b/qmake/doc/snippets/qmake/configscopes.pro
index 6ab7f7c428..6ab7f7c428 100644
--- a/qmake/doc/src/snippets/qmake/configscopes.pro
+++ b/qmake/doc/snippets/qmake/configscopes.pro
diff --git a/qmake/doc/src/snippets/qmake/debug_and_release.pro b/qmake/doc/snippets/qmake/debug_and_release.pro
index 92e8dbf76a..92e8dbf76a 100644
--- a/qmake/doc/src/snippets/qmake/debug_and_release.pro
+++ b/qmake/doc/snippets/qmake/debug_and_release.pro
diff --git a/qmake/doc/src/snippets/qmake/delegate.h b/qmake/doc/snippets/qmake/delegate.h
index 92c7eb6a48..92c7eb6a48 100644
--- a/qmake/doc/src/snippets/qmake/delegate.h
+++ b/qmake/doc/snippets/qmake/delegate.h
diff --git a/qmake/doc/src/snippets/qmake/dereferencing.pro b/qmake/doc/snippets/qmake/dereferencing.pro
index ff0c97995c..ff0c97995c 100644
--- a/qmake/doc/src/snippets/qmake/dereferencing.pro
+++ b/qmake/doc/snippets/qmake/dereferencing.pro
diff --git a/qmake/doc/src/snippets/qmake/destdir.pro b/qmake/doc/snippets/qmake/destdir.pro
index b2f943904a..b2f943904a 100644
--- a/qmake/doc/src/snippets/qmake/destdir.pro
+++ b/qmake/doc/snippets/qmake/destdir.pro
diff --git a/qmake/doc/src/snippets/qmake/dirname.pro b/qmake/doc/snippets/qmake/dirname.pro
index 59e1f20b3f..59e1f20b3f 100644
--- a/qmake/doc/src/snippets/qmake/dirname.pro
+++ b/qmake/doc/snippets/qmake/dirname.pro
diff --git a/qmake/doc/src/snippets/qmake/environment.pro b/qmake/doc/snippets/qmake/environment.pro
index 808bdeba47..808bdeba47 100644
--- a/qmake/doc/src/snippets/qmake/environment.pro
+++ b/qmake/doc/snippets/qmake/environment.pro
diff --git a/qmake/doc/src/snippets/qmake/functions.pro b/qmake/doc/snippets/qmake/functions.pro
index 2766120719..2766120719 100644
--- a/qmake/doc/src/snippets/qmake/functions.pro
+++ b/qmake/doc/snippets/qmake/functions.pro
diff --git a/qmake/doc/src/snippets/qmake/include.pro b/qmake/doc/snippets/qmake/include.pro
index 37e7156957..37e7156957 100644
--- a/qmake/doc/src/snippets/qmake/include.pro
+++ b/qmake/doc/snippets/qmake/include.pro
diff --git a/qmake/doc/src/snippets/qmake/main.cpp b/qmake/doc/snippets/qmake/main.cpp
index 92c7eb6a48..92c7eb6a48 100644
--- a/qmake/doc/src/snippets/qmake/main.cpp
+++ b/qmake/doc/snippets/qmake/main.cpp
diff --git a/qmake/doc/src/snippets/qmake/model.cpp b/qmake/doc/snippets/qmake/model.cpp
index 92c7eb6a48..92c7eb6a48 100644
--- a/qmake/doc/src/snippets/qmake/model.cpp
+++ b/qmake/doc/snippets/qmake/model.cpp
diff --git a/qmake/doc/src/snippets/qmake/model.h b/qmake/doc/snippets/qmake/model.h
index 92c7eb6a48..92c7eb6a48 100644
--- a/qmake/doc/src/snippets/qmake/model.h
+++ b/qmake/doc/snippets/qmake/model.h
diff --git a/qmake/doc/src/snippets/qmake/other.pro b/qmake/doc/snippets/qmake/other.pro
index e69de29bb2..e69de29bb2 100644
--- a/qmake/doc/src/snippets/qmake/other.pro
+++ b/qmake/doc/snippets/qmake/other.pro
diff --git a/qmake/doc/src/snippets/qmake/paintwidget_mac.cpp b/qmake/doc/snippets/qmake/paintwidget_mac.cpp
index 92c7eb6a48..92c7eb6a48 100644
--- a/qmake/doc/src/snippets/qmake/paintwidget_mac.cpp
+++ b/qmake/doc/snippets/qmake/paintwidget_mac.cpp
diff --git a/qmake/doc/src/snippets/qmake/paintwidget_unix.cpp b/qmake/doc/snippets/qmake/paintwidget_unix.cpp
index c39fc2cbf6..c39fc2cbf6 100644
--- a/qmake/doc/src/snippets/qmake/paintwidget_unix.cpp
+++ b/qmake/doc/snippets/qmake/paintwidget_unix.cpp
diff --git a/qmake/doc/src/snippets/qmake/paintwidget_win.cpp b/qmake/doc/snippets/qmake/paintwidget_win.cpp
index 92c7eb6a48..92c7eb6a48 100644
--- a/qmake/doc/src/snippets/qmake/paintwidget_win.cpp
+++ b/qmake/doc/snippets/qmake/paintwidget_win.cpp
diff --git a/qmake/doc/src/snippets/qmake/precompile-stable.h b/qmake/doc/snippets/qmake/precompile-stable.h
index eef8cef728..eef8cef728 100644
--- a/qmake/doc/src/snippets/qmake/precompile-stable.h
+++ b/qmake/doc/snippets/qmake/precompile-stable.h
diff --git a/qmake/doc/src/snippets/qmake/project_location.pro b/qmake/doc/snippets/qmake/project_location.pro
index 09d9b3d9d0..09d9b3d9d0 100644
--- a/qmake/doc/src/snippets/qmake/project_location.pro
+++ b/qmake/doc/snippets/qmake/project_location.pro
diff --git a/qmake/doc/src/snippets/qmake/qtconfiguration.pro b/qmake/doc/snippets/qmake/qtconfiguration.pro
index 55e13be352..55e13be352 100644
--- a/qmake/doc/src/snippets/qmake/qtconfiguration.pro
+++ b/qmake/doc/snippets/qmake/qtconfiguration.pro
diff --git a/qmake/doc/src/snippets/qmake/quoting.pro b/qmake/doc/snippets/qmake/quoting.pro
index 62efb2042e..62efb2042e 100644
--- a/qmake/doc/src/snippets/qmake/quoting.pro
+++ b/qmake/doc/snippets/qmake/quoting.pro
diff --git a/qmake/doc/src/snippets/qmake/replace.pro b/qmake/doc/snippets/qmake/replace.pro
index 504e01a018..504e01a018 100644
--- a/qmake/doc/src/snippets/qmake/replace.pro
+++ b/qmake/doc/snippets/qmake/replace.pro
diff --git a/qmake/doc/src/snippets/qmake/replacefunction.pro b/qmake/doc/snippets/qmake/replacefunction.pro
index 98013ba42d..98013ba42d 100644
--- a/qmake/doc/src/snippets/qmake/replacefunction.pro
+++ b/qmake/doc/snippets/qmake/replacefunction.pro
diff --git a/qmake/doc/src/snippets/qmake/scopes.pro b/qmake/doc/snippets/qmake/scopes.pro
index 63b9b3aa55..63b9b3aa55 100644
--- a/qmake/doc/src/snippets/qmake/scopes.pro
+++ b/qmake/doc/snippets/qmake/scopes.pro
diff --git a/qmake/doc/src/snippets/qmake/shared_or_static.pro b/qmake/doc/snippets/qmake/shared_or_static.pro
index 31c25ea44b..31c25ea44b 100644
--- a/qmake/doc/src/snippets/qmake/shared_or_static.pro
+++ b/qmake/doc/snippets/qmake/shared_or_static.pro
diff --git a/qmake/doc/src/snippets/qmake/spaces.pro b/qmake/doc/snippets/qmake/spaces.pro
index 614d4c553d..614d4c553d 100644
--- a/qmake/doc/src/snippets/qmake/spaces.pro
+++ b/qmake/doc/snippets/qmake/spaces.pro
diff --git a/qmake/doc/src/snippets/qmake/specifications.pro b/qmake/doc/snippets/qmake/specifications.pro
index f9a0d0a1cb..f9a0d0a1cb 100644
--- a/qmake/doc/src/snippets/qmake/specifications.pro
+++ b/qmake/doc/snippets/qmake/specifications.pro
diff --git a/qmake/doc/src/snippets/qmake/testfunction.pro b/qmake/doc/snippets/qmake/testfunction.pro
index 785ffed6be..785ffed6be 100644
--- a/qmake/doc/src/snippets/qmake/testfunction.pro
+++ b/qmake/doc/snippets/qmake/testfunction.pro
diff --git a/qmake/doc/src/snippets/qmake/variables.pro b/qmake/doc/snippets/qmake/variables.pro
index c1439ba68b..c1439ba68b 100644
--- a/qmake/doc/src/snippets/qmake/variables.pro
+++ b/qmake/doc/snippets/qmake/variables.pro
diff --git a/qmake/doc/src/snippets/qmake/view.h b/qmake/doc/snippets/qmake/view.h
index 92c7eb6a48..92c7eb6a48 100644
--- a/qmake/doc/src/snippets/qmake/view.h
+++ b/qmake/doc/snippets/qmake/view.h
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index 5f8672c163..a00d00d8c1 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -201,11 +201,11 @@
The following snippet illustrates how lists of values are assigned to
variables:
- \snippet snippets/qmake/variables.pro 0
+ \snippet qmake/variables.pro 0
The list of values in a variable is extended in the following way:
- \snippet snippets/qmake/variables.pro 1
+ \snippet qmake/variables.pro 1
\note The first assignment only includes values that are specified on
the same line as the \c HEADERS variable. The second assignment splits
@@ -244,7 +244,7 @@
The contents of a variable can be read by prepending the variable name with
\c $$. This can be used to assign the contents of one variable to another:
- \snippet snippets/qmake/dereferencing.pro 0
+ \snippet qmake/dereferencing.pro 0
The \c $$ operator is used extensively with built-in functions that operate
on strings and lists of values. For more information, see
@@ -255,21 +255,21 @@
Usually, whitespace separates values in variable assignments. To specify
values that contain spaces, you must enclose the values in double quotes:
- \snippet snippets/qmake/quoting.pro 0
+ \snippet qmake/quoting.pro 0
The quoted text is treated as a single item in the list of values held by
the variable. A similar approach is used to deal with paths that contain
spaces, particularly when defining the
\l{INCLUDEPATH} and \l{LIBS} variables for the Windows platform:
- \snippet snippets/qmake/spaces.pro quoting include paths with spaces
+ \snippet qmake/spaces.pro quoting include paths with spaces
\section2 Comments
You can add comments to project files. Comments begin with the \c
# character and continue to the end of the same line. For example:
- \snippet snippets/qmake/comments.pro 0
+ \snippet qmake/comments.pro 0
To include the \c # character in variable assignments, it is necessary
to use the contents of the built-in \l{LITERAL_HASH} variable.
@@ -285,12 +285,12 @@
The \c include function is most commonly used to include other project
files:
- \snippet snippets/qmake/include.pro 0
+ \snippet qmake/include.pro 0
Support for conditional structures is made available via
\l{Scopes}{scopes} that behave like \c if statements in programming languages:
- \snippet snippets/qmake/scopes.pro 0
+ \snippet qmake/scopes.pro 0
The assignments inside the braces are only made if the condition is
true. In this case, the \c win32 \l{CONFIG} option must be set. This
@@ -353,7 +353,7 @@
versions of a project, the Makefile that qmake generates includes a rule
that builds both versions. This can be invoked in the following way:
- \snippet snippets/code/doc_src_qmake-manual.pro 0
+ \snippet code/doc_src_qmake-manual.pro 0
Adding the \c build_all option to the \c CONFIG variable makes this rule
the default when building the project.
@@ -365,8 +365,8 @@
For example, the following lines show the function as the condition in a scope
to test whether only the \c opengl option is in use:
- \snippet snippets/qmake/configscopes.pro 4
- \snippet snippets/qmake/configscopes.pro 5
+ \snippet qmake/configscopes.pro 4
+ \snippet qmake/configscopes.pro 5
This enables different configurations to be defined for \c release and
\c debug builds. For more information, see \l{Scopes}{Using Scopes}.
@@ -394,7 +394,7 @@
For example, if your application uses the Qt library and you want to
build it in \c debug mode, your project file will contain the following line:
- \snippet snippets/code/doc_src_qmake-manual.pro 1
+ \snippet code/doc_src_qmake-manual.pro 1
\note You must use "+=", not "=", or qmake
will not be able to use Qt's configuration to determine the settings
@@ -409,21 +409,21 @@
extension modules.
For example, we can enable the XML and network modules in the following way:
- \snippet snippets/code/doc_src_qmake-manual.pro 2
+ \snippet code/doc_src_qmake-manual.pro 2
\note \c QT includes the \c core and \c gui modules by default, so the
above declaration \e adds the network and XML modules to this default list.
The following assignment \e omits the default modules, and will lead to
errors when the application's source code is being compiled:
- \snippet snippets/code/doc_src_qmake-manual.pro 3
+ \snippet code/doc_src_qmake-manual.pro 3
If you want to build a project \e without the \c gui module, you need to
exclude it with the "-=" operator. By default, \c QT contains both
\c core and \c gui, so the following line will result in a minimal
Qt project being built:
- \snippet snippets/code/doc_src_qmake-manual.pro 4
+ \snippet code/doc_src_qmake-manual.pro 4
For a list of Qt modules that you can add to the \c QT variable, see
\l{Variables#QT}{QT}.
@@ -441,7 +441,7 @@
\l{http://www.freedesktop.org/wiki/Software/pkg-config}{pkg-config},
such as the D-Bus and ogg libraries, with the following lines:
- \snippet snippets/code/doc_src_qmake-manual.pro 5
+ \snippet code/doc_src_qmake-manual.pro 5
For more information about adding features, see
\l{Adding New Configuration Features}.
@@ -458,14 +458,14 @@
For example, the following lines show how a library can be specified:
- \snippet snippets/code/doc_src_qmake-manual.pro 6
+ \snippet code/doc_src_qmake-manual.pro 6
The paths containing header files can also be specified in a similar way
using the \l{INCLUDEPATH} variable.
For example, to add several paths to be searched for header files:
- \snippet snippets/code/doc_src_qmake-manual.pro 7
+ \snippet code/doc_src_qmake-manual.pro 7
*/
/*!
@@ -485,7 +485,7 @@
The syntax used to run qmake takes the following simple form:
- \snippet snippets/code/doc_src_qmake-manual.pro 8
+ \snippet code/doc_src_qmake-manual.pro 8
\section1 Operating Modes
@@ -572,7 +572,7 @@
\target MakefileMode
\section1 Makefile Mode Options
- \snippet snippets/code/doc_src_qmake-manual.pro 9
+ \snippet code/doc_src_qmake-manual.pro 9
In Makefile mode, qmake will generate a Makefile
that is used to build the project. Additionally, the following options may
@@ -599,12 +599,12 @@
before all of the files specified. For example, the following command
generates a Makefile from test.pro:
- \snippet snippets/code/doc_src_qmake-manual.pro 10
+ \snippet code/doc_src_qmake-manual.pro 10
However, some of the specified options can be omitted as they are default
values:
- \snippet snippets/code/doc_src_qmake-manual.pro 11
+ \snippet code/doc_src_qmake-manual.pro 11
If you are certain you want your variables processed after the
files specified, then you may pass the \c -after option. When this
@@ -614,7 +614,7 @@
\target ProjectMode
\section1 Project Mode Options
- \snippet snippets/code/doc_src_qmake-manual.pro 12
+ \snippet code/doc_src_qmake-manual.pro 12
In project mode, qmake will generate a project
file. Additionally, you may supply the following options in this mode:
@@ -669,7 +669,7 @@
For example, to use qmake from a binary package to create a Makefile in a
project directory, invoke the following command:
- \snippet snippets/code/doc_src_qmake-manual.pro 13
+ \snippet code/doc_src_qmake-manual.pro 13
\section2 Using Frameworks
@@ -681,12 +681,12 @@
to the build system, and this is achieved by appending linker options to the
\l{QMAKE_LFLAGS} variable, as shown in the following example:
- \snippet snippets/code/doc_src_qmake-manual.pro 14
+ \snippet code/doc_src_qmake-manual.pro 14
The framework itself is linked in by appending the \c{-framework} options and
the name of the framework to the \l{LIBS} variable:
- \snippet snippets/code/doc_src_qmake-manual.pro 15
+ \snippet code/doc_src_qmake-manual.pro 15
\section2 Creating Frameworks
@@ -697,7 +697,7 @@
\l{TEMPLATE}{\c lib template} and add the \c lib_bundle option to the
\l{CONFIG} variable:
- \snippet snippets/code/doc_src_qmake-manual.pro 16
+ \snippet code/doc_src_qmake-manual.pro 16
The data associated with the library is specified using the
\l{QMAKE_BUNDLE_DATA}
@@ -705,7 +705,7 @@
bundle, and is often used to specify a collection of header files,
as in the following example:
- \snippet snippets/code/doc_src_qmake-manual.pro 17
+ \snippet code/doc_src_qmake-manual.pro 17
You use the \c FRAMEWORK_HEADERS variable to specify the headers required by
a particular framework.
@@ -727,7 +727,7 @@
by running qmake to generate an Xcode project from an existing qmake project
file. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 19
+ \snippet code/doc_src_qmake-manual.pro 19
\note If a project is later moved on the disk, qmake must be run again to
process the project file and create a new Xcode project file.
@@ -778,12 +778,12 @@
This can also be set using a command line option, for example:
- \snippet snippets/code/doc_src_qmake-manual.pro 20
+ \snippet code/doc_src_qmake-manual.pro 20
It is possible to recursively generate \c{.vcproj} files in subdirectories
and a \c{.sln} file in the main directory, by typing:
- \snippet snippets/code/doc_src_qmake-manual.pro 21
+ \snippet code/doc_src_qmake-manual.pro 21
Each time you update the project file, you need to run
qmake to generate an updated Visual Studio
@@ -802,12 +802,12 @@
Removing manifest embedding for application executables can be done with
the following assignment to the \l{CONFIG} variable:
- \snippet snippets/code/doc_src_qmake-manual.pro 22
+ \snippet code/doc_src_qmake-manual.pro 22
Also, the manifest embedding for DLLs can be removed with the following
assignment to the \c CONFIG variable:
- \snippet snippets/code/doc_src_qmake-manual.pro 23
+ \snippet code/doc_src_qmake-manual.pro 23
This is discussed in more detail in the
\l{Deploying an Application on Windows#Manifest files}
@@ -917,7 +917,7 @@
qmake generates includes a rule that builds both
versions, and this can be invoked in the following way:
- \snippet snippets/code/doc_src_qmake-manual.pro 24
+ \snippet code/doc_src_qmake-manual.pro 24
When linking a library, qmake relies on the
underlying platform to know what other libraries this library links
@@ -954,7 +954,7 @@
will be set for each of these modes, and you can test for this to perform
build-specific tasks. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 25
+ \snippet code/doc_src_qmake-manual.pro 25
As a result, it may be useful to define mode-specific variables, such as
\l{#QMAKE_LFLAGS_RELEASE}{QMAKE_LFLAGS_RELEASE}, instead of general
@@ -1050,7 +1050,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 26
+ \snippet code/doc_src_qmake-manual.pro 26
\target DEFINES
\section1 DEFINES
@@ -1060,7 +1060,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 27
+ \snippet code/doc_src_qmake-manual.pro 27
\target DEF_FILE
\section1 DEF_FILE
@@ -1090,7 +1090,7 @@
For example, the following definition uploads all PNG images in \c path to
the directory where the build target is deployed:
- \snippet snippets/code/doc_src_qmake-manual.pro 28
+ \snippet code/doc_src_qmake-manual.pro 28
The default deployment target path for Windows CE is
\c{%CSIDL_PROGRAM_FILES%\target}, which usually gets expanded to
@@ -1102,7 +1102,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 29
+ \snippet code/doc_src_qmake-manual.pro 29
\note In Windows CE all linked Qt libraries will be deployed to the path
specified by \c{myFiles.path}.
@@ -1123,7 +1123,7 @@
For example, the following definition uploads the jpeg imageformat plugin to
the plugins directory on the Windows CE device:
- \snippet snippets/code/doc_src_qmake-manual.pro 142
+ \snippet code/doc_src_qmake-manual.pro 142
\target DESTDIR
\section1 DESTDIR
@@ -1132,7 +1132,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 30
+ \snippet code/doc_src_qmake-manual.pro 30
\target DISTFILES
\section1 DISTFILES
@@ -1142,7 +1142,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 31
+ \snippet code/doc_src_qmake-manual.pro 31
\target DLLDESTDIR
\section1 DLLDESTDIR
@@ -1160,7 +1160,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 32
+ \snippet code/doc_src_qmake-manual.pro 32
\target GUID
\section1 GUID
@@ -1183,7 +1183,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 34
+ \snippet code/doc_src_qmake-manual.pro 34
See also \l{#SOURCES}{SOURCES}.
@@ -1202,12 +1202,12 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 35
+ \snippet code/doc_src_qmake-manual.pro 35
To specify a path containing spaces, quote the path using the technique
described in \l{Whitespace}.
- \snippet snippets/qmake/spaces.pro quoting include paths with spaces
+ \snippet qmake/spaces.pro quoting include paths with spaces
\target INSTALLS
\section1 INSTALLS
@@ -1221,7 +1221,7 @@
build target will be installed, and the \c INSTALLS assignment adds the
build target to the list of existing resources to be installed:
- \snippet snippets/code/doc_src_qmake-manual.pro 36
+ \snippet code/doc_src_qmake-manual.pro 36
For more information, see \l{Installing Files}.
@@ -1248,7 +1248,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 37
+ \snippet code/doc_src_qmake-manual.pro 37
\target LIBS
\section1 LIBS
@@ -1261,18 +1261,18 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 38
+ \snippet code/doc_src_qmake-manual.pro 38
To specify a path containing spaces, quote the path using the technique
described in \l{Whitespace}.
- \snippet snippets/qmake/spaces.pro quoting library paths with spaces
+ \snippet qmake/spaces.pro quoting library paths with spaces
By default, the list of libraries stored in \c LIBS is reduced to a list of
unique names before it is used. To change this behavior, add the
\c no_lflags_merge option to the \l{CONFIG} variable:
- \snippet snippets/code/doc_src_qmake-manual.pro 39
+ \snippet code/doc_src_qmake-manual.pro 39
\target LITERAL_HASH
\section1 LITERAL_HASH
@@ -1283,7 +1283,7 @@
For example:
- \snippet snippets/qmake/comments.pro 1
+ \snippet qmake/comments.pro 1
By using \c LITERAL_HASH in this way, the \c # character can be used
to construct a URL for the \c message() function to print to the console.
@@ -1311,7 +1311,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 40
+ \snippet code/doc_src_qmake-manual.pro 40
\target OBJECTS
\section1 OBJECTS
@@ -1328,7 +1328,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 41
+ \snippet code/doc_src_qmake-manual.pro 41
\target POST_TARGETDEPS
\section1 POST_TARGETDEPS
@@ -1417,7 +1417,7 @@
and \c path/to/header_two.h to a group containing information about the
headers supplied with the framework:
- \snippet snippets/code/doc_src_qmake-manual.pro 43
+ \snippet code/doc_src_qmake-manual.pro 43
The last line adds the information about the headers to the collection of
resources that will be installed with the library bundle.
@@ -1439,7 +1439,7 @@
For example, the following definition will result in a framework with the
\c{.myframework} extension:
- \snippet snippets/code/doc_src_qmake-manual.pro 44
+ \snippet code/doc_src_qmake-manual.pro 44
\section1 QMAKE_CC
@@ -2027,7 +2027,7 @@
\c{-compress} options are used with particular values each time that
\c rcc is invoked:
- \snippet snippets/code/doc_src_qmake-manual.pro 45
+ \snippet code/doc_src_qmake-manual.pro 45
\section1 QMAKE_RPATHDIR
@@ -2120,6 +2120,7 @@
\row \li webkit \li \l{Qt WebKit}
\row \li webkitwidgets \li \l{Qt WebKit Widgets}
\row \li widgets \li \l{Qt Widgets}
+ \row \li winextras \li \l{Qt Windows Extras}
\row \li xml \li \l{Qt XML} (deprecated)
\row \li xmlpatterns \li \l{Qt XML Patterns}
\endtable
@@ -2131,7 +2132,7 @@
exclude the \c gui value with the "-=" operator. The following line will
result in a minimal Qt project being built:
- \snippet snippets/code/doc_src_qmake-manual.pro 47
+ \snippet code/doc_src_qmake-manual.pro 47
\section1 QTPLUGIN
@@ -2177,7 +2178,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 48
+ \snippet code/doc_src_qmake-manual.pro 48
\target REQUIRES
\section1 REQUIRES
@@ -2219,7 +2220,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 49
+ \snippet code/doc_src_qmake-manual.pro 49
See also \l{#HEADERS}{HEADERS}.
@@ -2233,7 +2234,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 50
+ \snippet code/doc_src_qmake-manual.pro 50
It is essential that the project file in each subdirectory has the same
name as the subdirectory itself, so that qmake
@@ -2244,7 +2245,7 @@
which they are specified, update the \l{#CONFIG}{CONFIG} variable to
include the \c ordered option:
- \snippet snippets/code/doc_src_qmake-manual.pro 51
+ \snippet code/doc_src_qmake-manual.pro 51
It is possible to modify this default behavior of \c SUBDIRS by giving
additional modifiers to \c SUBDIRS elements. Supported modifiers are:
@@ -2266,7 +2267,7 @@
For example, define two subdirectories, both of which reside in a different directory
than the \c SUBDIRS value, and one of the subdirectories must be built before the other:
- \snippet snippets/code/doc_src_qmake-manual.pro 149
+ \snippet code/doc_src_qmake-manual.pro 149
\target TARGET
\section1 TARGET
@@ -2276,7 +2277,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 52
+ \snippet code/doc_src_qmake-manual.pro 52
The project file above would produce an executable named \c myapp on
unix and \c{myapp.exe} on Windows.
@@ -2324,7 +2325,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 53
+ \snippet code/doc_src_qmake-manual.pro 53
The template can be overridden by specifying a new template type with the
\c -t command line option. This overrides the template type \e after the .pro
@@ -2348,7 +2349,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 54
+ \snippet code/doc_src_qmake-manual.pro 54
\target VERSION
\section1 VERSION
@@ -2358,7 +2359,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 57
+ \snippet code/doc_src_qmake-manual.pro 57
\section1 VER_MAJ
@@ -2392,7 +2393,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 58
+ \snippet code/doc_src_qmake-manual.pro 58
\section1 _PRO_FILE_
@@ -2401,7 +2402,7 @@
For example, the following line causes the location of the project
file to be written to the console:
- \snippet snippets/qmake/project_location.pro project file
+ \snippet qmake/project_location.pro project file
\note Do not attempt to overwrite the value of this variable.
@@ -2412,7 +2413,7 @@
For example, the following line causes the location of the directory
containing the project file to be written to the console:
- \snippet snippets/qmake/project_location.pro project file directory
+ \snippet qmake/project_location.pro project file directory
\note Do not attempt to overwrite the value of this variable.
*/
@@ -2448,7 +2449,7 @@
For example, the following call returns the string
\c {"/home/johndoe/myproject/readme.txt"}:
- \snippet snippets/code/doc_src_qmake-manual.pro 159
+ \snippet code/doc_src_qmake-manual.pro 159
See also \l{clean_path(path)}{clean_path()},
\l{relative_path(filePath[, base])}{relative_path()}.
@@ -2459,7 +2460,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 59
+ \snippet code/doc_src_qmake-manual.pro 59
\section2 cat(filename[, mode])
@@ -2491,7 +2492,7 @@
Returns the directory name part of the specified file. For example:
- \snippet snippets/qmake/dirname.pro 0
+ \snippet qmake/dirname.pro 0
\section2 enumerate_vars
@@ -2506,7 +2507,7 @@
\note If you specify the string to expand literally, you need to escape the
backslashes, as illustrated by the following code snippet:
- \snippet snippets/code/doc_src_qmake-manual.pro 173
+ \snippet code/doc_src_qmake-manual.pro 173
\target findfunction
\section2 find(variablename, substr)
@@ -2514,7 +2515,7 @@
Returns all the values in \c variablename that match the regular expression
\c substr.
- \snippet snippets/code/doc_src_qmake-manual.pro 64
+ \snippet code/doc_src_qmake-manual.pro 64
MY_VAR2 will contain '-Lone -Ltwo -Lthree -Lfour -Lfive', and MY_VAR3 will
contain 'three two three'.
@@ -2525,7 +2526,7 @@
For example, the following call returns \c firstname:
- \snippet snippets/code/doc_src_qmake-manual.pro 161
+ \snippet code/doc_src_qmake-manual.pro 161
See also \l{last(variablename)}{last()}.
@@ -2551,7 +2552,7 @@
For example, the following call converts the hexadecimal number \c BAD to
\c 002989:
- \snippet snippets/code/doc_src_qmake-manual.pro 163
+ \snippet code/doc_src_qmake-manual.pro 163
\section2 fromfile(filename, variablename)
@@ -2574,7 +2575,7 @@
For example, the following call returns \c phone:
- \snippet snippets/code/doc_src_qmake-manual.pro 162
+ \snippet code/doc_src_qmake-manual.pro 162
See also \l{first(variablename)}{first()}.
@@ -2585,11 +2586,11 @@
of that variable. You can use the variable to write a loop as illustrated by
the following code snippet
- \snippet snippets/code/doc_src_qmake-manual.pro 170
+ \snippet code/doc_src_qmake-manual.pro 170
instead of:
- \snippet snippets/code/doc_src_qmake-manual.pro 171
+ \snippet code/doc_src_qmake-manual.pro 171
\section2 lower(arg1 [, arg2 ..., argn])
@@ -2635,11 +2636,11 @@
contents of the variable supplied as \c string. For example, the
code
- \snippet snippets/qmake/replace.pro 0
+ \snippet qmake/replace.pro 0
prints the message:
- \snippet snippets/code/doc_src_qmake-manual.pro 70
+ \snippet code/doc_src_qmake-manual.pro 70
\section2 sprintf(string, arguments...)
@@ -2661,7 +2662,7 @@
For example, the following call outputs \c surname:
- \snippet snippets/code/doc_src_qmake-manual.pro 167
+ \snippet code/doc_src_qmake-manual.pro 167
\section2 shadowed(path)
@@ -2699,7 +2700,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 168
+ \snippet code/doc_src_qmake-manual.pro 168
\section2 system(command[, mode])
@@ -2708,7 +2709,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 72
+ \snippet code/doc_src_qmake-manual.pro 72
See also the test variant of \l{system(command)}{system()}.
@@ -2734,7 +2735,7 @@
Returns the list of values in \c variablename with duplicate entries removed.
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 73
+ \snippet code/doc_src_qmake-manual.pro 73
\section2 upper(arg1 [, arg2 ..., argn])
@@ -2779,7 +2780,7 @@
mutually exclusive values) a second parameter can be used to specify a set
of values to consider. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 60
+ \snippet code/doc_src_qmake-manual.pro 60
Because release is considered the active setting (for feature parsing)
it will be the CONFIG used to generate the build file. In the common
@@ -2796,7 +2797,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 61
+ \snippet code/doc_src_qmake-manual.pro 61
The contents of the scope are only processed if the \c drivers
variable contains the value \c network. If this is the case, the
@@ -2813,7 +2814,7 @@
only processed if the variable contains the correct number of values.
For example:
- \snippet snippets/qmake/functions.pro 2
+ \snippet qmake/functions.pro 2
\section2 debug(level, message)
@@ -2838,7 +2839,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 160
+ \snippet code/doc_src_qmake-manual.pro 160
\section2 error(string)
@@ -2848,7 +2849,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 62
+ \snippet code/doc_src_qmake-manual.pro 62
\section2 eval(string)
@@ -2858,7 +2859,7 @@
values of existing variables or create new definitions.
For example:
- \snippet snippets/qmake/functions.pro 4
+ \snippet qmake/functions.pro 4
\note Quotation marks can be used to delimit the string, and
the return value can be discarded if it is not needed.
@@ -2871,7 +2872,7 @@
succeeds if any file matches the regular expression specified.
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 63
+ \snippet code/doc_src_qmake-manual.pro 63
\note "/" should be used as a directory separator, regardless of the
platform in use.
@@ -2895,7 +2896,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 65
+ \snippet code/doc_src_qmake-manual.pro 65
\section2 greaterThan(variablename, value)
@@ -2905,7 +2906,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 164
+ \snippet code/doc_src_qmake-manual.pro 164
It is impossible to compare two numbers as strings directly. As a
workaround, construct temporary values with a non-numeric prefix and compare
@@ -2913,7 +2914,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 172
+ \snippet code/doc_src_qmake-manual.pro 172
See also \l{lessThan(variablename, value)}{lessThan()}.
@@ -2923,7 +2924,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 166
+ \snippet code/doc_src_qmake-manual.pro 166
\section2 include(filename)
@@ -2935,7 +2936,7 @@
You can check whether the file was included by using this function as
the condition for a scope. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 66
+ \snippet code/doc_src_qmake-manual.pro 66
\section2 infile(filename, var, val)
@@ -2955,7 +2956,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 67
+ \snippet code/doc_src_qmake-manual.pro 67
\section2 isEqual
@@ -2968,7 +2969,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 165
+ \snippet code/doc_src_qmake-manual.pro 165
\section2 load(feature)
@@ -2987,7 +2988,7 @@
Always succeeds, and displays \c string as a general message to the user.
Unlike the \c error() function, this function allows processing to continue.
- \snippet snippets/code/doc_src_qmake-manual.pro 68
+ \snippet code/doc_src_qmake-manual.pro 68
The above line causes "This is a message" to be written to the console.
The use of quotation marks is optional, but recommended.
@@ -2998,7 +2999,7 @@
\l{Scopes}{in conjunction with a scope} to filter out
messages during builds. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 69
+ \snippet code/doc_src_qmake-manual.pro 69
\section2 mkpath(dirPath)
@@ -3021,7 +3022,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 71
+ \snippet code/doc_src_qmake-manual.pro 71
See also the replace variant of \l{system(command[, mode])}{system()}.
@@ -3037,7 +3038,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 169
+ \snippet code/doc_src_qmake-manual.pro 169
\section2 warning(string)
@@ -3061,11 +3062,11 @@
This can be useful to optionally enable or disable features. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 157
+ \snippet code/doc_src_qmake-manual.pro 157
And then, in the code:
- \snippet snippets/code/doc_src_qmake-manual.pro 158
+ \snippet code/doc_src_qmake-manual.pro 158
*/
/*!
@@ -3082,14 +3083,14 @@
property in qmake once, and query it each time qmake is invoked. You can set
a property in qmake as follows:
- \snippet snippets/code/doc_src_qmake-manual.pro 74
+ \snippet code/doc_src_qmake-manual.pro 74
The appropriate property and value should be substituted for
\c PROPERTY and \c VALUE.
You can retrieve this information back from qmake as follows:
- \snippet snippets/code/doc_src_qmake-manual.pro 75
+ \snippet code/doc_src_qmake-manual.pro 75
\note \c{qmake -query} lists built-in properties in addition to the
properties that you set with \c{qmake -set PROPERTY VALUE}.
@@ -3135,11 +3136,11 @@
For example, you can query the installation of Qt for this version of qmake with the
\c QT_INSTALL_PREFIX property:
- \snippet snippets/code/doc_src_qmake-manual.pro 77
+ \snippet code/doc_src_qmake-manual.pro 77
You can query the values of properties in a project file as follows:
- \snippet snippets/code/doc_src_qmake-manual.pro 78
+ \snippet code/doc_src_qmake-manual.pro 78
\target QMAKESPEC
\section1 QMAKESPEC
@@ -3189,7 +3190,7 @@
example, the extension used for \l moc files can be redefined with the
following assignment in a project file:
- \snippet snippets/code/doc_src_qmake-manual.pro 85
+ \snippet code/doc_src_qmake-manual.pro 85
The following variables can be used to redefine common file extensions recognized
by qmake:
@@ -3249,7 +3250,7 @@
The \c = operator assigns a value to a variable:
- \snippet snippets/code/doc_src_qmake-manual.pro 89
+ \snippet code/doc_src_qmake-manual.pro 89
The above line sets the \l{TARGET} variable to \c myapp. This will overwrite any
values previously set for \c TARGET with \c myapp.
@@ -3258,7 +3259,7 @@
The \c += operator appends a new value to the list of values in a variable:
- \snippet snippets/code/doc_src_qmake-manual.pro 90
+ \snippet code/doc_src_qmake-manual.pro 90
The above line appends \c USE_MY_STUFF to the list of pre-processor defines to be put
in the generated Makefile.
@@ -3267,7 +3268,7 @@
The \c -= operator removes a value from the list of values in a variable:
- \snippet snippets/code/doc_src_qmake-manual.pro 91
+ \snippet code/doc_src_qmake-manual.pro 91
The above line removes \c USE_MY_STUFF from the list of pre-processor defines to be
put in the generated Makefile.
@@ -3278,7 +3279,7 @@
if it is not already present. This prevents values from being included many
times in a variable. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 92
+ \snippet code/doc_src_qmake-manual.pro 92
In the above line, \c USE_MY_STUFF will only be added to the list of pre-processor
defines if it is not already defined. Note that the \l{unique}{unique()}
@@ -3290,7 +3291,7 @@
The \c ~= operator replaces any values that match a regular expression with
the specified value:
- \snippet snippets/code/doc_src_qmake-manual.pro 93
+ \snippet code/doc_src_qmake-manual.pro 93
In the above line, any values in the list that start with \c QT_D or \c QT_T are
replaced with \c QT.
@@ -3300,7 +3301,7 @@
The \c $$ operator is used to extract the contents of a variable, and can be
used to pass values between variables or supply them to functions:
- \snippet snippets/code/doc_src_qmake-manual.pro 94
+ \snippet code/doc_src_qmake-manual.pro 94
Variables can be used to store the contents of environment variables.
These can be evaluated at the time when qmake
@@ -3310,7 +3311,7 @@
To obtain the contents of an environment value when
qmake is run, use the \c $$(...) operator:
- \snippet snippets/qmake/environment.pro 0
+ \snippet qmake/environment.pro 0
In the above assignment, the value of the \c PWD environment variable
is read when the project file is processed.
@@ -3318,7 +3319,7 @@
To obtain the contents of an environment value at the time when the
generated Makefile is processed, use the \c $(...) operator:
- \snippet snippets/qmake/environment.pro 1
+ \snippet qmake/environment.pro 1
In the above assignment, the value of \c PWD is read immediately
when the project file is processed, but \c $(PWD) is assigned to
@@ -3330,7 +3331,7 @@
The special \c $$[...] operator can be used to access qmake properties:
- \snippet snippets/qmake/qtconfiguration.pro 0
+ \snippet qmake/qtconfiguration.pro 0
For more information, see \l{Configuring qmake}.
@@ -3339,7 +3340,7 @@
For example, a \QD plugin can be installed alongside \QD's built-in
plugins if the following declaration is made in its project file:
- \snippet snippets/code/doc_src_qmake-manual.pro 101
+ \snippet code/doc_src_qmake-manual.pro 101
\target Scopes
\section1 Scopes
@@ -3352,7 +3353,7 @@
Scopes consist of a condition followed by an opening brace on the same line,
a sequence of commands and definitions, and a closing brace on a new line:
- \snippet snippets/qmake/scopes.pro syntax
+ \snippet qmake/scopes.pro syntax
The opening brace \e{must be written on the same line as the condition}.
Scopes may be concatenated to include more than one condition, as described
@@ -3363,7 +3364,7 @@
A scope is written as a condition followed by a series of declarations
contained within a pair of braces. For example:
- \snippet snippets/qmake/scopes.pro 0
+ \snippet qmake/scopes.pro 0
The above code will add the \c paintwidget_win.cpp file to the sources listed
in the generated Makefile when building for a Windows platform. When
@@ -3374,24 +3375,24 @@
original condition is false. For example, to process something when building
for all platforms \e except Windows, negate the scope like this:
- \snippet snippets/qmake/scopes.pro 1
+ \snippet qmake/scopes.pro 1
Scopes can be nested to combine more than one condition. For instance, to
include a particular file for a certain platform only if
debugging is enabled, write the following:
- \snippet snippets/qmake/scopes.pro 2
+ \snippet qmake/scopes.pro 2
To save writing many nested scopes, you can nest scopes using the \c :
operator. The nested scopes in the above example can be rewritten in
the following way:
- \snippet snippets/qmake/scopes.pro 3
+ \snippet qmake/scopes.pro 3
You may also use the \c : operator to perform single line conditional
assignments. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 95
+ \snippet code/doc_src_qmake-manual.pro 95
The above line adds \c USE_MY_STUFF to the \l{DEFINES} variable only when
building for the Windows platform.
@@ -3401,7 +3402,7 @@
There is also the \c | operator to act like a logical OR operator, joining
together a number of conditions, and requiring only one of them to be true.
- \snippet snippets/qmake/scopes.pro 4
+ \snippet qmake/scopes.pro 4
You can also provide alternative declarations to those within a scope by
using an \c else scope. Each \c else scope is processed if the conditions
@@ -3409,7 +3410,7 @@
This allows you to write complex tests when combined with other scopes
(separated by the \c : operator as above). For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 96
+ \snippet code/doc_src_qmake-manual.pro 96
\section2 Configuration and Scopes
@@ -3418,15 +3419,15 @@
values can be used as the condition for a scope. For example, the list of
values held by \c CONFIG can be extended with the \c opengl value:
- \snippet snippets/qmake/configscopes.pro 0
+ \snippet qmake/configscopes.pro 0
As a result of this operation, any scopes that test for \c opengl will
be processed. We can use this feature to give the final executable an
appropriate name:
- \snippet snippets/qmake/configscopes.pro 1
- \snippet snippets/qmake/configscopes.pro 2
- \snippet snippets/qmake/configscopes.pro 3
+ \snippet qmake/configscopes.pro 1
+ \snippet qmake/configscopes.pro 2
+ \snippet qmake/configscopes.pro 3
This feature makes it easy to change the configuration for a project
without losing all the custom settings that might be needed for a specific
@@ -3449,7 +3450,7 @@
following lines from a project file show the current specification in
use and test for the \c linux-g++ specification:
- \snippet snippets/qmake/specifications.pro 0
+ \snippet qmake/specifications.pro 0
You can test for any other platform-compiler combination as long as a
specification exists for it in the \c mkspecs directory.
@@ -3464,7 +3465,7 @@
variables with a given name when it encounters an assignment to that name.
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 97
+ \snippet code/doc_src_qmake-manual.pro 97
There are no restricitions on what you do to your own variables, as
qmake will ignore them unless it needs to evaluate them when processing
@@ -3473,19 +3474,19 @@
You can also assign the value of a current variable to another
variable by prefixing $$ to the variable name. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 98
+ \snippet code/doc_src_qmake-manual.pro 98
Now the MY_DEFINES variable contains what is in the DEFINES variable at
this point in the project file. This is also equivalent to:
- \snippet snippets/code/doc_src_qmake-manual.pro 99
+ \snippet code/doc_src_qmake-manual.pro 99
The second notation allows you to append the contents of the variable to
another value without separating the two with a space. For example, the
following will ensure that the final executable will be given a name
that includes the project template being used:
- \snippet snippets/code/doc_src_qmake-manual.pro 100
+ \snippet code/doc_src_qmake-manual.pro 100
\target UsingReplaceFunctions
\section1 Replace Functions
@@ -3497,7 +3498,7 @@
operator with this type of function as you would to assign contents of one
variable to another:
- \snippet snippets/qmake/functions.pro 1
+ \snippet qmake/functions.pro 1
This type of function should be used on the right-hand side of
assignments (that is, as an operand).
@@ -3505,13 +3506,13 @@
You can define your own functions for processing the contents of variables
as follows:
- \snippet snippets/code/doc_src_qmake-manual.pro 102
+ \snippet code/doc_src_qmake-manual.pro 102
The following example function takes a variable name as its only
argument, extracts a list of values from the variable with the
\l{eval(string)}{eval()} built-in function, and compiles a list of files:
- \snippet snippets/qmake/replacefunction.pro 0
+ \snippet qmake/replacefunction.pro 0
\target UsingTestFunctions
\section1 Test Functions
@@ -3520,7 +3521,7 @@
used as conditions when writing scopes. These functions do not return a
value, but instead indicate \e success or \e failure:
- \snippet snippets/qmake/functions.pro 3
+ \snippet qmake/functions.pro 3
This type of function should be used in conditional expressions
only.
@@ -3529,7 +3530,7 @@
for scopes. The following example tests whether each file in a list
exists and returns true if they all exist, or false if not:
- \snippet snippets/qmake/testfunction.pro 0
+ \snippet qmake/testfunction.pro 0
*/
/*!
@@ -3586,7 +3587,7 @@
For example, consider the following assignment in a project file:
- \snippet snippets/code/doc_src_qmake-manual.pro 103
+ \snippet code/doc_src_qmake-manual.pro 103
With this addition to the \c CONFIG variable,
qmake will search the locations listed above for
@@ -3621,7 +3622,7 @@
be installed. For example, a collection of documentation files can be
described in the following way:
- \snippet snippets/code/doc_src_qmake-manual.pro 79
+ \snippet code/doc_src_qmake-manual.pro 79
The \c path member informs qmake that the files
should be installed in \c /usr/local/program/doc (the path member), and the
@@ -3632,7 +3633,7 @@
Once an install set has been fully described, you can append it to the
install list with a line like this:
- \snippet snippets/code/doc_src_qmake-manual.pro 80
+ \snippet code/doc_src_qmake-manual.pro 80
qmake will ensure that the specified files are
copied to the installation directory. If you require more control over
@@ -3641,7 +3642,7 @@
qmake to execute a series of commands for this
install set:
- \snippet snippets/code/doc_src_qmake-manual.pro 81
+ \snippet code/doc_src_qmake-manual.pro 81
The \c unix \l{Scopes and Conditions}{scope}
ensures that these particular commands are only executed on Unix platforms.
@@ -3656,7 +3657,7 @@
will decide what needs to be copied for you. Currently, the \c target and \c dlltarget
install sets are supported. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 82
+ \snippet code/doc_src_qmake-manual.pro 82
In the above lines, qmake knows what needs to
be copied, and will handle the installation process automatically.
@@ -3672,7 +3673,7 @@
API as found in other places in qmake. Objects are defined automatically by
specifying their \e members. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 86
+ \snippet code/doc_src_qmake-manual.pro 86
The definitions above define a qmake target called \c mytarget, containing a
Makefile target called \c{.buildfile} which in turn is generated with the
@@ -3684,7 +3685,7 @@
The final step is to use the \c QMAKE_EXTRA_TARGETS variable to instruct
qmake that this object is a target to be built:
- \snippet snippets/code/doc_src_qmake-manual.pro 87
+ \snippet code/doc_src_qmake-manual.pro 87
This is all you need to do to actually build custom targets. Of course,
you may want to tie one of these targets to the
@@ -3733,7 +3734,7 @@
It is possible to customize qmake to support new compilers and
preprocessors:
- \snippet snippets/code/doc_src_qmake-manual.pro 88
+ \snippet code/doc_src_qmake-manual.pro 88
With the above definitions, you can use a drop-in replacement for moc if one
is available. The command is executed on all arguments given to the
@@ -3835,7 +3836,7 @@
The first step is to enable dependency tracking in the library itself.
To do this you must tell qmake to save information about the library:
- \snippet snippets/code/doc_src_qmake-manual.pro 83
+ \snippet code/doc_src_qmake-manual.pro 83
This is only relevant to the \c lib template, and will be ignored for all
others. When this option is enabled, qmake will create a file ending in .prl
@@ -3848,7 +3849,7 @@
The second step in this process is to enable reading of this meta
information in the applications that use the static library:
- \snippet snippets/code/doc_src_qmake-manual.pro 84
+ \snippet code/doc_src_qmake-manual.pro 84
When this is enabled, qmake will process all
libraries linked to by the application and find their meta-information.
@@ -3908,7 +3909,7 @@
and \e static throughout your project. A typical precompiled header might
look like this:
- \snippet snippets/code/doc_src_qmake-manual.cpp 104
+ \snippet code/doc_src_qmake-manual.cpp 104
\note A precompiled header file needs to separate C includes from
C++ includes, since the precompiled header file for C files may not
@@ -3920,7 +3921,7 @@
To make your project use precompiled headers, you only need to define the
\l{PRECOMPILED_HEADER} variable in your project file:
- \snippet snippets/code/doc_src_qmake-manual.pro 105
+ \snippet code/doc_src_qmake-manual.pro 105
qmake will handle the rest, to ensure the
creation and use of the precompiled header file. You do not need to
@@ -3933,7 +3934,7 @@
precompiled headers.
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 106
+ \snippet code/doc_src_qmake-manual.pro 106
\section1 Notes on Possible Issues
@@ -3942,7 +3943,7 @@
declarations may cause two different object files with the same name to
be generated:
- \snippet snippets/code/doc_src_qmake-manual.pro 107
+ \snippet code/doc_src_qmake-manual.pro 107
To avoid potential conflicts like these, give distinctive names to header
files that will be precompiled.
@@ -3962,7 +3963,7 @@
\section2 \c stable.h
- \snippet snippets/qmake/precompile-stable.h 0
+ \snippet qmake/precompile-stable.h 0
\omit
##Keeping the snippet in qtdoc is a workaround, because it contains code
@@ -4110,17 +4111,17 @@
Just start a new line with \c {SOURCES +=} and put hello.cpp after it.
You should have something like this:
- \snippet snippets/code/doc_src_qmake-manual.pro 108
+ \snippet code/doc_src_qmake-manual.pro 108
We repeat this for each source file in the project, until we end up
with the following:
- \snippet snippets/code/doc_src_qmake-manual.pro 109
+ \snippet code/doc_src_qmake-manual.pro 109
If you prefer to use a Make-like syntax, with all the files listed in
one go you can use the newline escaping like this:
- \snippet snippets/code/doc_src_qmake-manual.pro 110
+ \snippet code/doc_src_qmake-manual.pro 110
Now that the source files are listed in the project file, the header
files must be added. These are added in exactly the same way as source
@@ -4129,7 +4130,7 @@
Once you have done this, your project file should look something like
this:
- \snippet snippets/code/doc_src_qmake-manual.pro 111
+ \snippet code/doc_src_qmake-manual.pro 111
The target name is set automatically. It is the same as the project
filename, but with the suffix appropriate for the platform. For example, if
@@ -4137,24 +4138,24 @@
on Windows and \c hello on Unix. If you want to use a different name
you can set it in the project file:
- \snippet snippets/code/doc_src_qmake-manual.pro 112
+ \snippet code/doc_src_qmake-manual.pro 112
The finished project file should look like this:
- \snippet snippets/code/doc_src_qmake-manual.pro 113
+ \snippet code/doc_src_qmake-manual.pro 113
You can now use qmake to generate a Makefile
for your application. On the command line, in your project directory,
type the following:
- \snippet snippets/code/doc_src_qmake-manual.pro 114
+ \snippet code/doc_src_qmake-manual.pro 114
Then type \c make or \c nmake depending on the compiler you use.
For Visual Studio users, qmake can also generate Visual Studio project
files. For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 115
+ \snippet code/doc_src_qmake-manual.pro 115
\section1 Making an Application Debuggable
@@ -4166,7 +4167,7 @@
For example:
- \snippet snippets/code/doc_src_qmake-manual.pro 116
+ \snippet code/doc_src_qmake-manual.pro 116
Use qmake as before to generate a Makefile. You will now obtain useful
information about your application when running it in a debugging
@@ -4186,7 +4187,7 @@
A simple scope that adds the platform-dependent file for
Windows looks like this:
- \snippet snippets/code/doc_src_qmake-manual.pro 117
+ \snippet code/doc_src_qmake-manual.pro 117
When building for Windows, qmake adds \c hellowin.cpp to the list of source
files. When building for any other platform, qmake simply ignores it. Now
@@ -4195,7 +4196,7 @@
When you have done that, your project file should look
something like this:
- \snippet snippets/code/doc_src_qmake-manual.pro 118
+ \snippet code/doc_src_qmake-manual.pro 118
Use qmake as before to generate a Makefile.
@@ -4208,13 +4209,13 @@
the scope condition with the function. A check for a file called main.cpp looks
like this:
- \snippet snippets/code/doc_src_qmake-manual.pro 119
+ \snippet code/doc_src_qmake-manual.pro 119
The \c{!} symbol is used to negate the test. That is, \c{exists( main.cpp )}
is true if the file exists, and \c{!exists( main.cpp )} is true if the
file does not exist.
- \snippet snippets/code/doc_src_qmake-manual.pro 120
+ \snippet code/doc_src_qmake-manual.pro 120
Use qmake as before to generate a makefile.
If you rename \c main.cpp temporarily, you will see the message and
@@ -4233,12 +4234,12 @@
the other inside it. Put the settings to be processed inside the second
scope, like this:
- \snippet snippets/code/doc_src_qmake-manual.pro 121
+ \snippet code/doc_src_qmake-manual.pro 121
Nested scopes can be joined together using colons, so the final
project file looks like this:
- \snippet snippets/code/doc_src_qmake-manual.pro 122
+ \snippet code/doc_src_qmake-manual.pro 122
That's it! You have now completed the tutorial for
qmake, and are ready to write project files for
@@ -4311,7 +4312,7 @@
to specify any. qmake will add the necessary default values.
An example project file might look like this:
- \snippet snippets/code/doc_src_qmake-manual.pro 123
+ \snippet code/doc_src_qmake-manual.pro 123
For items that are single valued, such as the template or the destination
directory, we use "="; but for multi-valued items we use "+=" to \e
@@ -4449,8 +4450,8 @@
To enable a project to be built in both modes, you must add the
\c debug_and_release option to the \c CONFIG variable:
- \snippet snippets/qmake/debug_and_release.pro 0
- \snippet snippets/qmake/debug_and_release.pro 1
+ \snippet qmake/debug_and_release.pro 0
+ \snippet qmake/debug_and_release.pro 1
The scope in the above snippet modifies the build target in each mode to
ensure that the resulting targets have different names. Providing different
@@ -4460,23 +4461,23 @@
generate a Makefile rule to allow the project to be built in both modes.
This can be invoked in the following way:
- \snippet snippets/code/doc_src_qmake-manual.pro 124
+ \snippet code/doc_src_qmake-manual.pro 124
The \c build_all option can be added to the \c CONFIG variable in the
project file to ensure that the project is built in both modes by default:
- \snippet snippets/qmake/debug_and_release.pro 2
+ \snippet qmake/debug_and_release.pro 2
This allows the Makefile to be processed using the default rule:
- \snippet snippets/code/doc_src_qmake-manual.pro 125
+ \snippet code/doc_src_qmake-manual.pro 125
\section2 Installing in Both Modes
The \c build_all option also ensures that both versions of the target
will be installed when the installation rule is invoked:
- \snippet snippets/code/doc_src_qmake-manual.pro 126
+ \snippet code/doc_src_qmake-manual.pro 126
It is possible to customize the names of the build targets depending on
the target platform. For example, a library or plugin may be named using a
@@ -4486,11 +4487,10 @@
Note: This was originally used in the customwidgetplugin.pro file, but is
no longer needed there.
\endomit
- \snippet snippets/code/doc_src_qmake-manual.pro 127
+ \snippet code/doc_src_qmake-manual.pro 127
The default behavior in the above snippet is to modify the name used for
the build target when building in debug mode. An \c else clause could be
added to the scope to do the same for release mode. Left as it is, the
target name remains unmodified.
*/
-
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index 41e5754251..d1c70900fb 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -1381,24 +1381,24 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
!project->values("QMAKE_FRAMEWORKPATH").isEmpty() ? SettingsAsList : 0, 5) << ";\n";
{
- ProStringList cflags = fixListForOutput("QMAKE_CFLAGS");
+ ProStringList cflags = project->values("QMAKE_CFLAGS");
const ProStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
for (int i = 0; i < prl_defines.size(); ++i)
cflags += "-D" + prl_defines.at(i);
const ProStringList &defines = project->values("DEFINES");
for (int i = 0; i < defines.size(); ++i)
cflags += "-D" + defines.at(i);
- t << "\t\t\t\t" << writeSettings("OTHER_CFLAGS", cflags, SettingsAsList, 5) << ";\n";
+ t << "\t\t\t\t" << writeSettings("OTHER_CFLAGS", fixListForOutput(cflags), SettingsAsList, 5) << ";\n";
}
{
- ProStringList cxxflags = fixListForOutput("QMAKE_CXXFLAGS");
+ ProStringList cxxflags = project->values("QMAKE_CXXFLAGS");
const ProStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
for (int i = 0; i < prl_defines.size(); ++i)
cxxflags += "-D" + prl_defines.at(i);
const ProStringList &defines = project->values("DEFINES");
for (int i = 0; i < defines.size(); ++i)
cxxflags += "-D" + defines.at(i);
- t << "\t\t\t\t" << writeSettings("OTHER_CPLUSPLUSFLAGS", cxxflags, SettingsAsList, 5) << ";\n";
+ t << "\t\t\t\t" << writeSettings("OTHER_CPLUSPLUSFLAGS", fixListForOutput(cxxflags), SettingsAsList, 5) << ";\n";
}
if (!project->isActiveConfig("staticlib")) {
t << "\t\t\t\t" << writeSettings("OTHER_LDFLAGS",
@@ -1408,7 +1408,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
+ fixListForOutput("QMAKE_LIBS_PRIVATE"),
SettingsAsList, 6) << ";\n";
}
- const ProStringList &archs = project->values("QT_ARCH");
+ const ProStringList &archs = !project->values("QMAKE_XCODE_ARCHS").isEmpty() ?
+ project->values("QMAKE_XCODE_ARCHS") : project->values("QT_ARCH");
if (!archs.isEmpty())
t << "\t\t\t\t" << writeSettings("ARCHS", archs) << ";\n";
if (!project->isEmpty("OBJECTS_DIR"))
@@ -1518,19 +1519,20 @@ ProjectBuilderMakefileGenerator::fixForOutput(const QString &values)
project->values("QMAKE_PBX_VARS").append(reg_var.cap(1));
rep += reg_var.matchedLength();
}
- QString ret = values;
- ret = ret.replace(QRegExp("\\\\ "), " "); //unescape spaces
- ret = ret.replace(QRegExp("('|\\\\|\")"), "\\\\1"); //fix quotes
- ret = ret.replace("\t", " "); //fix tabs
- ret = ret.replace(QRegExp(" "), "\\ "); //escape spaces
- return ret;
+
+ return values;
}
ProStringList
ProjectBuilderMakefileGenerator::fixListForOutput(const char *where)
{
+ return fixListForOutput(project->values(where));
+}
+
+ProStringList
+ProjectBuilderMakefileGenerator::fixListForOutput(const ProStringList &l)
+{
ProStringList ret;
- const ProStringList &l = project->values(where);
for(int i = 0; i < l.count(); i++)
ret += fixForOutput(l[i].toQString());
return ret;
@@ -1747,37 +1749,81 @@ ProjectBuilderMakefileGenerator::escapeFilePath(const QString &path) const
#endif
}
+static QString quotedStringLiteral(const QString &value)
+{
+ QString result;
+ const int len = value.length();
+ result.reserve(int(len * 1.1) + 2);
+
+ result += QLatin1Char('"');
+
+ // Escape
+ for (int i = 0; i < len; ++i) {
+ QChar character = value.at(i);;
+ ushort code = character.unicode();
+ switch (code) {
+ case '\\':
+ result += QLatin1String("\\\\");
+ break;
+ case '"':
+ result += QLatin1String("\\\"");
+ break;
+ case '\b':
+ result += QLatin1String("\\b");
+ break;
+ case '\n':
+ result += QLatin1String("\\n");
+ break;
+ case '\r':
+ result += QLatin1String("\\r");
+ break;
+ case '\t':
+ result += QLatin1String("\\t");
+ break;
+ default:
+ if (code >= 32 && code <= 127)
+ result += character;
+ else
+ result += QLatin1String("\\u") + QString::number(code, 16).rightJustified(4, '0');
+ }
+ }
+
+ result += QLatin1Char('"');
+
+ result.squeeze();
+ return result;
+}
+
QString
ProjectBuilderMakefileGenerator::writeSettings(const QString &var, const ProStringList &vals, int flags, int indent_level)
{
QString ret;
- const QString quote = (flags & SettingsNoQuote) ? "" : "\"";
- const QString escape_quote = quote.isEmpty() ? "" : QString("\\" + quote);
+ bool shouldQuote = !((flags & SettingsNoQuote));
+
QString newline = "\n";
for(int i = 0; i < indent_level; ++i)
newline += "\t";
+
+ ret += var + " = ";
+
if(flags & SettingsAsList) {
- ret += var + " = (" + newline;
+ ret += "(" + newline;
for(int i = 0, count = 0; i < vals.size(); ++i) {
QString val = vals.at(i).toQString();
if(!val.isEmpty()) {
if(count++ > 0)
ret += "," + newline;
- ret += quote + val.replace(quote, escape_quote) + quote;
+ if (shouldQuote)
+ val = quotedStringLiteral(val);
+ ret += val;
}
}
ret += ")";
} else {
- ret += var + " = " + quote;
- for(int i = 0; i < vals.size(); ++i) {
- QString val = vals.at(i).toQString();
-// if(val.isEmpty())
-// val = quote + quote;
- if(i)
- ret += " ";
- ret += val;
- }
- ret += quote;
+ QString val = vals.join(QLatin1Char(' '));
+ if (shouldQuote)
+ val = quotedStringLiteral(val);
+ ret += val;
}
return ret;
}
diff --git a/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h
index 255dd43348..a08dc7c2bd 100644
--- a/qmake/generators/mac/pbuilder_pbx.h
+++ b/qmake/generators/mac/pbuilder_pbx.h
@@ -61,6 +61,7 @@ class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator
QString findProgram(const ProString &prog);
QString fixForOutput(const QString &file);
ProStringList fixListForOutput(const char *where);
+ ProStringList fixListForOutput(const ProStringList &list);
int reftypeForFile(const QString &where);
QString sourceTreeForFile(const QString &where);
QString projectSuffix() const;
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index 98b5a328e4..a8ae84a4e2 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -2272,8 +2272,7 @@ MakefileGenerator::writeHeader(QTextStream &t)
{
t << "#############################################################################\n";
t << "# Makefile for building: " << escapeFilePath(var("TARGET")) << endl;
- t << "# Generated by qmake (" QMAKE_VERSION_STR ") (Qt " QT_VERSION_STR ") on: ";
- t << QDateTime::currentDateTime().toString() << endl;
+ t << "# Generated by qmake (" QMAKE_VERSION_STR ") (Qt " QT_VERSION_STR ")\n";
t << "# Project: " << fileFixify(project->projectFile()) << endl;
t << "# Template: " << var("TEMPLATE") << endl;
if(!project->isActiveConfig("build_pass"))
diff --git a/qmake/library/ioutils.cpp b/qmake/library/ioutils.cpp
index 3c2801594a..cc19aa5c42 100644
--- a/qmake/library/ioutils.cpp
+++ b/qmake/library/ioutils.cpp
@@ -88,6 +88,11 @@ bool IoUtils::isRelativePath(const QString &path)
return true;
}
+QStringRef IoUtils::pathName(const QString &fileName)
+{
+ return fileName.leftRef(fileName.lastIndexOf(QLatin1Char('/')) + 1);
+}
+
QStringRef IoUtils::fileName(const QString &fileName)
{
return fileName.midRef(fileName.lastIndexOf(QLatin1Char('/')) + 1);
diff --git a/qmake/library/ioutils.h b/qmake/library/ioutils.h
index 160e879fce..d69725fa27 100644
--- a/qmake/library/ioutils.h
+++ b/qmake/library/ioutils.h
@@ -64,6 +64,7 @@ public:
static bool exists(const QString &fileName) { return fileType(fileName) != FileNotFound; }
static bool isRelativePath(const QString &fileName);
static bool isAbsolutePath(const QString &fileName) { return !isRelativePath(fileName); }
+ static QStringRef pathName(const QString &fileName); // Requires normalized path
static QStringRef fileName(const QString &fileName); // Requires normalized path
static QString resolvePath(const QString &baseDir, const QString &fileName);
static QString shellQuoteUnix(const QString &arg);
diff --git a/qmake/library/qmake_global.h b/qmake/library/qmake_global.h
index 7e2247e8c6..acb95e7ab3 100644
--- a/qmake/library/qmake_global.h
+++ b/qmake/library/qmake_global.h
@@ -64,4 +64,8 @@
# define ALWAYS_INLINE inline
#endif
+#ifdef PROEVALUATOR_FULL
+# define PROEVALUATOR_DEBUG
+#endif
+
#endif
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index be0d8ea172..c0f1724563 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -44,6 +44,7 @@
#include "qmakeevaluator_p.h"
#include "qmakeglobals.h"
#include "qmakeparser.h"
+#include "qmakevfs.h"
#include "ioutils.h"
#include <qbytearray.h>
@@ -281,46 +282,17 @@ quoteValue(const ProString &val)
return ret;
}
-static bool
-doWriteFile(const QString &name, QIODevice::OpenMode mode, const QString &contents, QString *errStr)
-{
- QByteArray bytes = contents.toLocal8Bit();
- QFile cfile(name);
- if (!(mode & QIODevice::Append) && cfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
- if (cfile.readAll() == bytes)
- return true;
- cfile.close();
- }
- if (!cfile.open(mode | QIODevice::WriteOnly | QIODevice::Text)) {
- *errStr = cfile.errorString();
- return false;
- }
- cfile.write(bytes);
- cfile.close();
- if (cfile.error() != QFile::NoError) {
- *errStr = cfile.errorString();
- return false;
- }
- return true;
-}
-
QMakeEvaluator::VisitReturn
QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
const QString &contents)
{
- QFileInfo qfi(fn);
- if (!QDir::current().mkpath(qfi.path())) {
- evalError(fL1S("Cannot create %1directory %2.")
- .arg(ctx, QDir::toNativeSeparators(qfi.path())));
- return ReturnFalse;
- }
QString errStr;
- if (!doWriteFile(qfi.filePath(), mode, contents, &errStr)) {
+ if (!m_vfs->writeFile(fn, mode, contents, &errStr)) {
evalError(fL1S("Cannot write %1file %2: %3.")
- .arg(ctx, QDir::toNativeSeparators(qfi.filePath()), errStr));
+ .arg(ctx, QDir::toNativeSeparators(fn), errStr));
return ReturnFalse;
}
- m_parser->discardFileFromCache(qfi.filePath());
+ m_parser->discardFileFromCache(fn);
return ReturnTrue;
}
@@ -1118,11 +1090,11 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
}
return ReturnFalse;
-#ifdef PROEVALUATOR_FULL
case T_REQUIRES:
+#ifdef PROEVALUATOR_FULL
checkRequirements(args);
- return ReturnFalse; // Another qmake breakage
#endif
+ return ReturnFalse; // Another qmake breakage
case T_EVAL: {
VisitReturn ret = ReturnFalse;
ProFile *pro = m_parser->parsedProBlock(args.join(statics.field_sep),
@@ -1389,14 +1361,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
return (func_t == T_ERROR && !m_cumulative) ? ReturnError : ReturnTrue;
}
-#ifdef PROEVALUATOR_FULL
case T_SYSTEM: {
- if (m_cumulative) // Anything else would be insanity
- return ReturnFalse;
if (args.count() != 1) {
evalError(fL1S("system(exec) requires one argument."));
return ReturnFalse;
}
+#ifdef PROEVALUATOR_FULL
+ if (m_cumulative) // Anything else would be insanity
+ return ReturnFalse;
#ifndef QT_BOOTSTRAPPED
QProcess proc;
proc.setProcessChannelMode(QProcess::ForwardedChannels);
@@ -1407,8 +1379,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
+ IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory()))
+ QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData()) == 0);
#endif
- }
+#else
+ return ReturnTrue;
#endif
+ }
case T_ISEMPTY: {
if (args.count() != 1) {
evalError(fL1S("isEmpty(var) requires one argument."));
@@ -1423,6 +1397,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
const QString &file = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
+ // Don't use VFS here:
+ // - it supports neither listing nor even directories
+ // - it's unlikely that somebody would test for files they created themselves
if (IoUtils::exists(file))
return ReturnTrue;
int slsh = file.lastIndexOf(QLatin1Char('/'));
@@ -1435,17 +1412,18 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnFalse;
}
-#ifdef PROEVALUATOR_FULL
case T_MKPATH: {
if (args.count() != 1) {
evalError(fL1S("mkpath(file) requires one argument."));
return ReturnFalse;
}
+#ifdef PROEVALUATOR_FULL
const QString &fn = resolvePath(args.at(0).toQString(m_tmp1));
if (!QDir::current().mkpath(fn)) {
evalError(fL1S("Cannot create directory %1.").arg(QDir::toNativeSeparators(fn)));
return ReturnFalse;
}
+#endif
return ReturnTrue;
}
case T_WRITE_FILE: {
@@ -1470,6 +1448,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
evalError(fL1S("touch(file, reffile) requires two arguments."));
return ReturnFalse;
}
+#ifdef PROEVALUATOR_FULL
const QString &tfn = resolvePath(args.at(0).toQString(m_tmp1));
const QString &rfn = resolvePath(args.at(1).toQString(m_tmp2));
#ifdef Q_OS_UNIX
@@ -1506,6 +1485,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
SetFileTime(wHand, 0, 0, &ft);
CloseHandle(wHand);
#endif
+#endif
return ReturnTrue;
}
case T_CACHE: {
@@ -1639,7 +1619,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
return writeFile(fL1S("cache "), fn, QIODevice::Append, varstr);
}
-#endif
default:
evalError(fL1S("Function '%1' is not implemented.").arg(function.toQString(m_tmp1)));
return ReturnFalse;
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index 09ea231684..7c20bb8492 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -44,6 +44,7 @@
#include "qmakeglobals.h"
#include "qmakeparser.h"
+#include "qmakevfs.h"
#include "ioutils.h"
#include <qbytearray.h>
@@ -174,13 +175,13 @@ const ProKey &QMakeEvaluator::map(const ProKey &var)
}
-QMakeEvaluator::QMakeEvaluator(QMakeGlobals *option,
- QMakeParser *parser, QMakeHandler *handler)
+QMakeEvaluator::QMakeEvaluator(QMakeGlobals *option, QMakeParser *parser, QMakeVfs *vfs,
+ QMakeHandler *handler)
:
#ifdef PROEVALUATOR_DEBUG
m_debugLevel(option->debugLevel),
#endif
- m_option(option), m_parser(parser), m_handler(handler)
+ m_option(option), m_parser(parser), m_handler(handler), m_vfs(vfs)
{
// So that single-threaded apps don't have to call initialize() for now.
initStatics();
@@ -936,7 +937,7 @@ void QMakeEvaluator::visitProVariable(
if (varName == statics.strTEMPLATE)
setTemplate();
else if (varName == statics.strQMAKE_PLATFORM)
- updateFeaturePaths();
+ m_featureRoots = 0;
#ifdef PROEVALUATOR_FULL
else if (varName == statics.strREQUIRES)
checkRequirements(values(varName));
@@ -1064,7 +1065,7 @@ bool QMakeEvaluator::prepareProject(const QString &inDir)
superdir = m_outputDir;
forever {
QString superfile = superdir + QLatin1String("/.qmake.super");
- if (IoUtils::exists(superfile)) {
+ if (m_vfs->exists(superfile)) {
m_superfile = QDir::cleanPath(superfile);
break;
}
@@ -1079,10 +1080,10 @@ bool QMakeEvaluator::prepareProject(const QString &inDir)
QString dir = m_outputDir;
forever {
conffile = sdir + QLatin1String("/.qmake.conf");
- if (!IoUtils::exists(conffile))
+ if (!m_vfs->exists(conffile))
conffile.clear();
cachefile = dir + QLatin1String("/.qmake.cache");
- if (!IoUtils::exists(cachefile))
+ if (!m_vfs->exists(cachefile))
cachefile.clear();
if (!conffile.isEmpty() || !cachefile.isEmpty()) {
if (dir != sdir)
@@ -1160,6 +1161,7 @@ bool QMakeEvaluator::loadSpecInternal()
#endif
valuesRef(ProKey("QMAKESPEC")) << ProString(m_qmakespec);
m_qmakespecName = IoUtils::fileName(m_qmakespec).toString();
+ // This also ensures that m_featureRoots is valid.
if (evaluateFeatureFile(QLatin1String("spec_post.prf")) != ReturnTrue)
return false;
// The MinGW and x-build specs may change the separator; $$shell_{path,quote}() need it
@@ -1173,7 +1175,9 @@ bool QMakeEvaluator::loadSpec()
m_hostBuild ? m_option->qmakespec : m_option->xqmakespec);
{
- QMakeEvaluator evaluator(m_option, m_parser, m_handler);
+ QMakeEvaluator evaluator(m_option, m_parser, m_vfs, m_handler);
+ evaluator.m_sourceRoot = m_sourceRoot;
+ evaluator.m_buildRoot = m_buildRoot;
if (!m_superfile.isEmpty()) {
valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
if (evaluator.evaluateFile(
@@ -1330,7 +1334,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
locker.unlock();
#endif
- QMakeEvaluator *baseEval = new QMakeEvaluator(m_option, m_parser, m_handler);
+ QMakeEvaluator *baseEval = new QMakeEvaluator(m_option, m_parser, m_vfs, m_handler);
baseEnv->evaluator = baseEval;
baseEval->m_superfile = m_superfile;
baseEval->m_conffile = m_conffile;
@@ -1429,6 +1433,7 @@ void QMakeEvaluator::updateMkspecPaths()
ret << m_sourceRoot + concat;
ret << m_option->propertyValue(ProKey("QT_HOST_DATA/get")) + concat;
+ ret << m_option->propertyValue(ProKey("QT_HOST_DATA/src")) + concat;
ret.removeDuplicates();
m_mkspecPaths = ret;
@@ -1450,10 +1455,14 @@ void QMakeEvaluator::updateFeaturePaths()
m_option->dirlist_sep, QString::SkipEmptyParts);
QStringList feature_bases;
- if (!m_buildRoot.isEmpty())
+ if (!m_buildRoot.isEmpty()) {
+ feature_bases << m_buildRoot + mkspecs_concat;
feature_bases << m_buildRoot;
- if (!m_sourceRoot.isEmpty())
+ }
+ if (!m_sourceRoot.isEmpty()) {
+ feature_bases << m_sourceRoot + mkspecs_concat;
feature_bases << m_sourceRoot;
+ }
foreach (const QString &item, m_option->getPathListEnv(QLatin1String("QMAKEPATH")))
feature_bases << (item + mkspecs_concat);
@@ -1477,8 +1486,8 @@ void QMakeEvaluator::updateFeaturePaths()
}
}
- feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/get")).toQString(m_mtmp)
- + mkspecs_concat);
+ feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/get")) + mkspecs_concat);
+ feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/src")) + mkspecs_concat);
foreach (const QString &fb, feature_bases) {
foreach (const ProString &sfx, values(ProKey("QMAKE_PLATFORM")))
@@ -1496,7 +1505,7 @@ void QMakeEvaluator::updateFeaturePaths()
foreach (const QString &root, feature_roots)
if (IoUtils::exists(root))
ret << root;
- m_featureRoots = ret;
+ m_featureRoots = new QMakeFeatureRoots(ret);
}
ProString QMakeEvaluator::propertyValue(const ProKey &name) const
@@ -1825,7 +1834,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFile(
#endif
return ok;
} else {
- if (!(flags & LoadSilent) && !IoUtils::exists(fileName))
+ if (!(flags & LoadSilent) && !m_vfs->exists(fileName))
evalError(fL1S("WARNING: Include file %1 not found").arg(fileName));
return ReturnFalse;
}
@@ -1854,34 +1863,55 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
if (!fn.endsWith(QLatin1String(".prf")))
fn += QLatin1String(".prf");
- if (m_featureRoots.isEmpty())
+ if (!m_featureRoots)
updateFeaturePaths();
- int start_root = 0;
+#ifdef PROEVALUATOR_THREAD_SAFE
+ m_featureRoots->mutex.lock();
+#endif
QString currFn = currentFileName();
- if (IoUtils::fileName(currFn) == IoUtils::fileName(fn)) {
- for (int root = 0; root < m_featureRoots.size(); ++root)
- if (currFn == m_featureRoots.at(root) + fn) {
- start_root = root + 1;
- break;
+ if (IoUtils::fileName(currFn) != IoUtils::fileName(fn))
+ currFn.clear();
+ // Null values cannot regularly exist in the hash, so they indicate that the value still
+ // needs to be determined. Failed lookups are represented via non-null empty strings.
+ QString *fnp = &m_featureRoots->cache[qMakePair(fn, currFn)];
+ if (fnp->isNull()) {
+ int start_root = 0;
+ const QStringList &paths = m_featureRoots->paths;
+ if (!currFn.isEmpty()) {
+ QStringRef currPath = IoUtils::pathName(currFn);
+ for (int root = 0; root < paths.size(); ++root)
+ if (currPath == paths.at(root)) {
+ start_root = root + 1;
+ break;
+ }
+ }
+ for (int root = start_root; root < paths.size(); ++root) {
+ QString fname = paths.at(root) + fn;
+ if (IoUtils::exists(fname)) {
+ fn = fname;
+ goto cool;
}
- }
- for (int root = start_root; root < m_featureRoots.size(); ++root) {
- QString fname = m_featureRoots.at(root) + fn;
- if (IoUtils::exists(fname)) {
- fn = fname;
- goto cool;
}
- }
#ifdef QMAKE_BUILTIN_PRFS
- fn.prepend(QLatin1String(":/qmake/features/"));
- if (QFileInfo(fn).exists())
- goto cool;
+ fn.prepend(QLatin1String(":/qmake/features/"));
+ if (QFileInfo(fn).exists())
+ goto cool;
#endif
- if (!silent)
- evalError(fL1S("Cannot find feature %1").arg(fileName));
- return ReturnFalse;
+ fn = QLatin1String(""); // Indicate failed lookup. See comment above.
- cool:
+ cool:
+ *fnp = fn;
+ } else {
+ fn = *fnp;
+ }
+#ifdef PROEVALUATOR_THREAD_SAFE
+ m_featureRoots->mutex.unlock();
+#endif
+ if (fn.isEmpty()) {
+ if (!silent)
+ evalError(fL1S("Cannot find feature %1").arg(fileName));
+ return ReturnFalse;
+ }
ProStringList &already = valuesRef(ProKey("QMAKE_INTERNAL_INCLUDED_FEATURES"));
ProString afn(fn);
if (already.contains(afn)) {
@@ -1908,7 +1938,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFileInto(
const QString &fileName, ProValueMap *values, LoadFlags flags)
{
- QMakeEvaluator visitor(m_option, m_parser, m_handler);
+ QMakeEvaluator visitor(m_option, m_parser, m_vfs, m_handler);
visitor.m_caller = this;
visitor.m_outputDir = m_outputDir;
visitor.m_featureRoots = m_featureRoots;
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
index 09617ba019..8ca2b182c7 100644
--- a/qmake/library/qmakeevaluator.h
+++ b/qmake/library/qmakeevaluator.h
@@ -55,9 +55,13 @@
#include <qstack.h>
#include <qstring.h>
#include <qstringlist.h>
+#include <qshareddata.h>
#ifndef QT_BOOTSTRAPPED
# include <qprocess.h>
#endif
+#ifdef PROEVALUATOR_THREAD_SAFE
+# include <qmutex.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -83,6 +87,20 @@ public:
virtual void doneWithEval(ProFile *parent) = 0;
};
+typedef QPair<QString, QString> QMakeFeatureKey; // key, parent
+typedef QHash<QMakeFeatureKey, QString> QMakeFeatureHash;
+
+class QMAKE_EXPORT QMakeFeatureRoots : public QSharedData
+{
+public:
+ QMakeFeatureRoots(const QStringList &_paths) : paths(_paths) {}
+ const QStringList paths;
+ mutable QMakeFeatureHash cache;
+#ifdef PROEVALUATOR_THREAD_SAFE
+ mutable QMutex mutex;
+#endif
+};
+
// We use a QLinkedList based stack instead of a QVector based one (QStack), so that
// the addresses of value maps stay constant. The qmake generators rely on that.
class QMAKE_EXPORT ProValueMapStack : public QLinkedList<ProValueMap>
@@ -109,7 +127,7 @@ public:
static void initStatics();
static void initFunctionStatics();
- QMakeEvaluator(QMakeGlobals *option, QMakeParser *parser,
+ QMakeEvaluator(QMakeGlobals *option, QMakeParser *parser, QMakeVfs *vfs,
QMakeHandler *handler);
~QMakeEvaluator();
@@ -284,7 +302,7 @@ public:
QStringList m_qmakepath;
QStringList m_qmakefeatures;
QStringList m_mkspecPaths;
- QStringList m_featureRoots;
+ QExplicitlySharedDataPointer<QMakeFeatureRoots> m_featureRoots;
ProString m_dirSep;
ProFunctionDefs m_functionDefs;
ProStringList m_returnValue;
@@ -295,6 +313,7 @@ public:
QMakeGlobals *m_option;
QMakeParser *m_parser;
QMakeHandler *m_handler;
+ QMakeVfs *m_vfs;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeEvaluator::LoadFlags)
diff --git a/qmake/library/qmakeglobals.cpp b/qmake/library/qmakeglobals.cpp
index 3570aa70b7..bf37d51c40 100644
--- a/qmake/library/qmakeglobals.cpp
+++ b/qmake/library/qmakeglobals.cpp
@@ -324,34 +324,46 @@ bool QMakeGlobals::initProperties()
QT_PCLOSE(proc);
}
#endif
- foreach (QByteArray line, data.split('\n'))
- if (!line.startsWith("QMAKE_")) {
- int off = line.indexOf(':');
- if (off < 0) // huh?
- continue;
- if (line.endsWith('\r'))
- line.chop(1);
- QString name = QString::fromLatin1(line.left(off));
- ProString value = ProString(QDir::fromNativeSeparators(
- QString::fromLocal8Bit(line.mid(off + 1))));
- properties.insert(ProKey(name), value);
- if (name.startsWith(QLatin1String("QT_")) && !name.contains(QLatin1Char('/'))) {
- if (name.startsWith(QLatin1String("QT_INSTALL_"))) {
+ foreach (QByteArray line, data.split('\n')) {
+ int off = line.indexOf(':');
+ if (off < 0) // huh?
+ continue;
+ if (line.endsWith('\r'))
+ line.chop(1);
+ QString name = QString::fromLatin1(line.left(off));
+ ProString value = ProString(QDir::fromNativeSeparators(
+ QString::fromLocal8Bit(line.mid(off + 1))));
+ properties.insert(ProKey(name), value);
+ if (name.startsWith(QLatin1String("QT_"))) {
+ bool plain = !name.contains(QLatin1Char('/'));
+ if (!plain) {
+ if (!name.endsWith(QLatin1String("/get")))
+ continue;
+ name.chop(4);
+ }
+ if (name.startsWith(QLatin1String("QT_INSTALL_"))) {
+ if (plain) {
properties.insert(ProKey(name + QLatin1String("/raw")), value);
properties.insert(ProKey(name + QLatin1String("/get")), value);
- if (name == QLatin1String("QT_INSTALL_PREFIX")
- || name == QLatin1String("QT_INSTALL_DATA")
- || name == QLatin1String("QT_INSTALL_BINS")) {
- name.replace(3, 7, QLatin1String("HOST"));
+ }
+ properties.insert(ProKey(name + QLatin1String("/src")), value);
+ if (name == QLatin1String("QT_INSTALL_PREFIX")
+ || name == QLatin1String("QT_INSTALL_DATA")
+ || name == QLatin1String("QT_INSTALL_BINS")) {
+ name.replace(3, 7, QLatin1String("HOST"));
+ if (plain) {
properties.insert(ProKey(name), value);
properties.insert(ProKey(name + QLatin1String("/get")), value);
}
- } else if (name.startsWith(QLatin1String("QT_HOST_"))) {
- properties.insert(ProKey(name + QLatin1String("/get")), value);
+ properties.insert(ProKey(name + QLatin1String("/src")), value);
}
+ } else if (name.startsWith(QLatin1String("QT_HOST_"))) {
+ if (plain)
+ properties.insert(ProKey(name + QLatin1String("/get")), value);
+ properties.insert(ProKey(name + QLatin1String("/src")), value);
}
}
- properties.insert(ProKey("QMAKE_VERSION"), ProString("2.01a"));
+ }
return true;
}
#else
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp
index 49b5429130..35533864eb 100644
--- a/qmake/library/qmakeparser.cpp
+++ b/qmake/library/qmakeparser.cpp
@@ -41,6 +41,7 @@
#include "qmakeparser.h"
+#include "qmakevfs.h"
#include "ioutils.h"
using namespace QMakeInternal;
@@ -142,9 +143,10 @@ void QMakeParser::initialize()
statics.strLITERAL_WHITESPACE = QLatin1String("LITERAL_WHITESPACE");
}
-QMakeParser::QMakeParser(ProFileCache *cache, QMakeParserHandler *handler)
+QMakeParser::QMakeParser(ProFileCache *cache, QMakeVfs *vfs, QMakeParserHandler *handler)
: m_cache(cache)
, m_handler(handler)
+ , m_vfs(vfs)
{
// So that single-threaded apps don't have to call initialize() for now.
initialize();
@@ -230,24 +232,14 @@ void QMakeParser::discardFileFromCache(const QString &fileName)
bool QMakeParser::read(ProFile *pro)
{
- QFile file(pro->fileName());
- if (!file.open(QIODevice::ReadOnly)) {
- if (m_handler && IoUtils::exists(pro->fileName()))
+ QString content;
+ QString errStr;
+ if (!m_vfs->readFile(pro->fileName(), &content, &errStr)) {
+ if (m_handler && m_vfs->exists(pro->fileName()))
m_handler->message(QMakeParserHandler::ParserIoError,
- fL1S("Cannot read %1: %2").arg(pro->fileName(), file.errorString()));
+ fL1S("Cannot read %1: %2").arg(pro->fileName(), errStr));
return false;
}
-
- QByteArray bcont = file.readAll();
- if (bcont.startsWith("\xef\xbb\xbf")) {
- // UTF-8 BOM will cause subtle errors
- m_handler->message(QMakeParserHandler::ParserIoError,
- fL1S("Unexpected UTF-8 BOM in %1").arg(pro->fileName()));
- return false;
- }
- QString content(QString::fromLocal8Bit(bcont));
- bcont.clear();
- file.close();
return read(pro, content, 1, FullGrammar);
}
diff --git a/qmake/library/qmakeparser.h b/qmake/library/qmakeparser.h
index 732e6a05e6..e3da05cc9e 100644
--- a/qmake/library/qmakeparser.h
+++ b/qmake/library/qmakeparser.h
@@ -79,6 +79,7 @@ public:
};
class ProFileCache;
+class QMakeVfs;
class QMAKE_EXPORT QMakeParser
{
@@ -86,7 +87,7 @@ public:
// Call this from a concurrency-free context
static void initialize();
- QMakeParser(ProFileCache *cache, QMakeParserHandler *handler);
+ QMakeParser(ProFileCache *cache, QMakeVfs *vfs, QMakeParserHandler *handler);
enum SubGrammar { FullGrammar, TestGrammar, ValueGrammar };
// fileName is expected to be absolute and cleanPath()ed.
@@ -175,6 +176,7 @@ private:
ProFileCache *m_cache;
QMakeParserHandler *m_handler;
+ QMakeVfs *m_vfs;
// This doesn't help gcc 3.3 ...
template<typename T> friend class QTypeInfo;
diff --git a/qmake/library/qmakevfs.cpp b/qmake/library/qmakevfs.cpp
new file mode 100644
index 0000000000..2039387a0f
--- /dev/null
+++ b/qmake/library/qmakevfs.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the qmake application of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmakevfs.h"
+
+#include "ioutils.h"
+using namespace QMakeInternal;
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+
+#define fL1S(s) QString::fromLatin1(s)
+
+QT_BEGIN_NAMESPACE
+
+QMakeVfs::QMakeVfs()
+#ifndef PROEVALUATOR_FULL
+ : m_magicMissing(fL1S("missing"))
+ , m_magicExisting(fL1S("existing"))
+#endif
+{
+}
+
+bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, const QString &contents,
+ QString *errStr)
+{
+#ifndef PROEVALUATOR_FULL
+# ifdef PROEVALUATOR_THREAD_SAFE
+ QMutexLocker locker(&m_mutex);
+# endif
+ QString *cont = &m_files[fn];
+ if (mode & QIODevice::Append)
+ *cont += contents;
+ else
+ *cont = contents;
+ Q_UNUSED(errStr)
+ return true;
+#else
+ QFileInfo qfi(fn);
+ if (!QDir::current().mkpath(qfi.path())) {
+ *errStr = fL1S("Cannot create parent directory");
+ return false;
+ }
+ QByteArray bytes = contents.toLocal8Bit();
+ QFile cfile(fn);
+ if (!(mode & QIODevice::Append) && cfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ if (cfile.readAll() == bytes)
+ return true;
+ cfile.close();
+ }
+ if (!cfile.open(mode | QIODevice::WriteOnly | QIODevice::Text)) {
+ *errStr = cfile.errorString();
+ return false;
+ }
+ cfile.write(bytes);
+ cfile.close();
+ if (cfile.error() != QFile::NoError) {
+ *errStr = cfile.errorString();
+ return false;
+ }
+ return true;
+#endif
+}
+
+bool QMakeVfs::readFile(const QString &fn, QString *contents, QString *errStr)
+{
+#ifndef PROEVALUATOR_FULL
+# ifdef PROEVALUATOR_THREAD_SAFE
+ QMutexLocker locker(&m_mutex);
+# endif
+ QHash<QString, QString>::ConstIterator it = m_files.constFind(fn);
+ if (it != m_files.constEnd()) {
+ if (it->constData() == m_magicMissing.constData()) {
+ *errStr = fL1S("No such file or directory");
+ return false;
+ }
+ if (it->constData() != m_magicExisting.constData()) {
+ *contents = *it;
+ return true;
+ }
+ }
+#endif
+
+ QFile file(fn);
+ if (!file.open(QIODevice::ReadOnly)) {
+#ifndef PROEVALUATOR_FULL
+ if (!IoUtils::exists(fn)) {
+ m_files[fn] = m_magicMissing;
+ *errStr = fL1S("No such file or directory");
+ } else
+#endif
+ *errStr = file.errorString();
+ return false;
+ }
+#ifndef PROEVALUATOR_FULL
+ m_files[fn] = m_magicExisting;
+#endif
+
+ QByteArray bcont = file.readAll();
+ if (bcont.startsWith("\xef\xbb\xbf")) {
+ // UTF-8 BOM will cause subtle errors
+ *errStr = fL1S("Unexpected UTF-8 BOM");
+ return false;
+ }
+ *contents = QString::fromLocal8Bit(bcont);
+ return true;
+}
+
+bool QMakeVfs::exists(const QString &fn)
+{
+#ifndef PROEVALUATOR_FULL
+# ifdef PROEVALUATOR_THREAD_SAFE
+ QMutexLocker locker(&m_mutex);
+# endif
+ QHash<QString, QString>::ConstIterator it = m_files.constFind(fn);
+ if (it != m_files.constEnd())
+ return it->constData() != m_magicMissing.constData();
+#endif
+ bool ex = IoUtils::exists(fn);
+#ifndef PROEVALUATOR_FULL
+ m_files[fn] = ex ? m_magicExisting : m_magicMissing;
+#endif
+ return ex;
+}
+
+#ifndef PROEVALUATOR_FULL
+// This should be called when the sources may have changed (e.g., VCS update).
+void QMakeVfs::invalidateCache()
+{
+# ifdef PROEVALUATOR_THREAD_SAFE
+ QMutexLocker locker(&m_mutex);
+# endif
+ QHash<QString, QString>::Iterator it = m_files.begin(), eit = m_files.end();
+ while (it != eit) {
+ if (it->constData() == m_magicMissing.constData()
+ ||it->constData() == m_magicExisting.constData())
+ it = m_files.erase(it);
+ else
+ ++it;
+ }
+}
+
+// This should be called when generated files may have changed (e.g., actual build).
+void QMakeVfs::invalidateContents()
+{
+# ifdef PROEVALUATOR_THREAD_SAFE
+ QMutexLocker locker(&m_mutex);
+# endif
+ m_files.clear();
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsudevlistener.h b/qmake/library/qmakevfs.h
index 7534f0bcd3..13204ece9d 100644
--- a/src/plugins/platforms/kms/qkmsudevlistener.h
+++ b/qmake/library/qmakevfs.h
@@ -3,7 +3,7 @@
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the qmake application of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,40 +39,47 @@
**
****************************************************************************/
-#ifndef QKMSUDEVLISTENER_H
-#define QKMSUDEVLISTENER_H
+#ifndef QMAKEVFS_H
+#define QMAKEVFS_H
-#include <QObject>
-#include <QMap>
-#include <QList>
-#include <QPointer>
-#include <QString>
+#include "qmake_global.h"
-#include <qkmsudevhandler.h>
-
-#include <libudev.h>
+# include <qiodevice.h>
+#ifndef PROEVALUATOR_FULL
+# include <qhash.h>
+# include <qstring.h>
+# ifdef PROEVALUATOR_THREAD_SAFE
+# include <qmutex.h>
+# endif
+#endif
QT_BEGIN_NAMESPACE
-class QKmsUdevListener : public QObject
+class QMAKE_EXPORT QMakeVfs
{
- Q_OBJECT
-
public:
- QKmsUdevListener(QObject *parent = 0);
- ~QKmsUdevListener();
+ QMakeVfs();
- void addHandler(QKmsUdevHandler *);
+ bool writeFile(const QString &fn, QIODevice::OpenMode mode, const QString &contents, QString *errStr);
+ bool readFile(const QString &fn, QString *contents, QString *errStr);
+ bool exists(const QString &fn);
-private:
- QList<QPointer<QKmsUdevHandler> > m_handlers;
- QMap<QString, QPointer<QObject> > m_devices;
- struct udev *m_udev;
+#ifndef PROEVALUATOR_FULL
+ void invalidateCache();
+ void invalidateContents();
+#endif
- void scan();
- bool create(struct udev_device *);
+private:
+#ifndef PROEVALUATOR_FULL
+# ifdef PROEVALUATOR_THREAD_SAFE
+ QMutex m_mutex;
+# endif
+ QHash<QString, QString> m_files;
+ QString m_magicMissing;
+ QString m_magicExisting;
+#endif
};
QT_END_NAMESPACE
-#endif // QKMSUDEVLISTENER_H
+#endif // QMAKEVFS_H
diff --git a/qmake/main.cpp b/qmake/main.cpp
index 55f915b52f..66364b83a7 100644
--- a/qmake/main.cpp
+++ b/qmake/main.cpp
@@ -85,6 +85,8 @@ int runQMake(int argc, char **argv)
// This is particularly important for things like QtCreator and scripted builds.
setvbuf(stdout, (char *)NULL, _IONBF, 0);
+ QMakeVfs vfs;
+ Option::vfs = &vfs;
QMakeGlobals globals;
Option::globals = &globals;
@@ -130,7 +132,7 @@ int runQMake(int argc, char **argv)
ProFileCache proFileCache;
Option::proFileCache = &proFileCache;
- QMakeParser parser(&proFileCache, &Option::evalHandler);
+ QMakeParser parser(&proFileCache, &vfs, &Option::evalHandler);
Option::parser = &parser;
QMakeProject project;
diff --git a/qmake/option.cpp b/qmake/option.cpp
index 4f7cdb34a2..387d8ce375 100644
--- a/qmake/option.cpp
+++ b/qmake/option.cpp
@@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE
EvalHandler Option::evalHandler;
QMakeGlobals *Option::globals;
ProFileCache *Option::proFileCache;
+QMakeVfs *Option::vfs;
QMakeParser *Option::parser;
//convenience
diff --git a/qmake/option.h b/qmake/option.h
index 6225f6b4d2..af8e3b7ab8 100644
--- a/qmake/option.h
+++ b/qmake/option.h
@@ -43,6 +43,7 @@
#define OPTION_H
#include <qmakeglobals.h>
+#include <qmakevfs.h>
#include <qmakeparser.h>
#include <qmakeevaluator.h>
@@ -87,6 +88,7 @@ struct Option
static QMakeGlobals *globals;
static ProFileCache *proFileCache;
+ static QMakeVfs *vfs;
static QMakeParser *parser;
//simply global convenience
diff --git a/qmake/project.cpp b/qmake/project.cpp
index 64e8e3c3b2..9f75d1da27 100644
--- a/qmake/project.cpp
+++ b/qmake/project.cpp
@@ -53,12 +53,12 @@ using namespace QMakeInternal;
QT_BEGIN_NAMESPACE
QMakeProject::QMakeProject()
- : QMakeEvaluator(Option::globals, Option::parser, &Option::evalHandler)
+ : QMakeEvaluator(Option::globals, Option::parser, Option::vfs, &Option::evalHandler)
{
}
QMakeProject::QMakeProject(QMakeProject *p)
- : QMakeEvaluator(Option::globals, Option::parser, &Option::evalHandler)
+ : QMakeEvaluator(Option::globals, Option::parser, Option::vfs, &Option::evalHandler)
{
initFrom(*p);
}
diff --git a/qmake/property.cpp b/qmake/property.cpp
index 4685440b48..38d454cb5d 100644
--- a/qmake/property.cpp
+++ b/qmake/property.cpp
@@ -83,6 +83,7 @@ QMakeProperty::QMakeProperty() : settings(0)
{
for (int i = 0; i < sizeof(propList)/sizeof(propList[0]); i++) {
QString name = QString::fromLatin1(propList[i].name);
+ m_values[ProKey(name + "/src")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectiveSourcePaths);
m_values[ProKey(name + "/get")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectivePaths);
QString val = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::FinalPaths);
if (!propList[i].raw) {
@@ -164,11 +165,14 @@ QMakeProperty::exec()
ProString val = value(ProKey(prop));
ProString pval = value(ProKey(prop + "/raw"));
ProString gval = value(ProKey(prop + "/get"));
+ ProString sval = value(ProKey(prop + "/src"));
fprintf(stdout, "%s:%s\n", prop.toLatin1().constData(), val.toLatin1().constData());
if (!pval.isEmpty() && pval != val)
fprintf(stdout, "%s/raw:%s\n", prop.toLatin1().constData(), pval.toLatin1().constData());
if (!gval.isEmpty() && gval != (pval.isEmpty() ? val : pval))
fprintf(stdout, "%s/get:%s\n", prop.toLatin1().constData(), gval.toLatin1().constData());
+ if (!sval.isEmpty() && sval != gval)
+ fprintf(stdout, "%s/src:%s\n", prop.toLatin1().constData(), sval.toLatin1().constData());
}
return true;
}
diff --git a/qmake/qmake.pri b/qmake/qmake.pri
index 66f7964c5f..4cc401bc13 100644
--- a/qmake/qmake.pri
+++ b/qmake/qmake.pri
@@ -4,7 +4,7 @@ DEFINES += QT_NO_TEXTCODEC QT_NO_LIBRARY QT_NO_COMPRESS QT_NO_UNICODETABLES \
#qmake code
SOURCES += project.cpp property.cpp main.cpp \
- library/ioutils.cpp library/proitems.cpp library/qmakeglobals.cpp \
+ library/ioutils.cpp library/proitems.cpp library/qmakevfs.cpp library/qmakeglobals.cpp \
library/qmakeparser.cpp library/qmakeevaluator.cpp library/qmakebuiltins.cpp \
generators/makefile.cpp \
generators/unix/unixmake2.cpp generators/unix/unixmake.cpp meta.cpp \
@@ -19,7 +19,7 @@ SOURCES += project.cpp property.cpp main.cpp \
generators/win32/cesdkhandler.cpp
HEADERS += project.h property.h \
- library/qmake_global.h library/ioutils.h library/proitems.h library/qmakeglobals.h \
+ library/qmake_global.h library/ioutils.h library/proitems.h library/qmakevfs.h library/qmakeglobals.h \
library/qmakeparser.h library/qmakeevaluator.h library/qmakeevaluator_p.h \
generators/makefile.h \
generators/unix/unixmake.h meta.h option.h cachekeys.h \
diff --git a/qmake/qmake.pro b/qmake/qmake.pro
index a81d0cdf77..568ad41ce1 100644
--- a/qmake/qmake.pro
+++ b/qmake/qmake.pro
@@ -6,7 +6,7 @@ option(host_build)
CONFIG += console bootstrap
CONFIG -= qt shared app_bundle uic
DEFINES += QT_BUILD_QMAKE QT_BOOTSTRAPPED \
- PROEVALUATOR_FULL PROEVALUATOR_DEBUG
+ PROEVALUATOR_FULL
DESTDIR = ../bin/
OBJECTS_DIR = .
diff --git a/qtbase.pro b/qtbase.pro
index d6726b5e93..d3b03d1fba 100644
--- a/qtbase.pro
+++ b/qtbase.pro
@@ -107,7 +107,7 @@ prefix_build|!equals(PWD, $$OUT_PWD) {
mkspecs.path = $$[QT_HOST_DATA]/mkspecs
mkspecs.files = \
$$OUT_PWD/mkspecs/qconfig.pri $$OUT_PWD/mkspecs/qmodule.pri $$OUT_PWD/mkspecs/qdevice.pri \
- $$files($$PWD/mkspecs/*) # $$OUT_PWD contains only symlinks under Unix
+ $$files($$PWD/mkspecs/*)
mkspecs.files -= $$PWD/mkspecs/modules
INSTALLS += mkspecs
diff --git a/src/concurrent/doc/qtconcurrent.qdocconf b/src/concurrent/doc/qtconcurrent.qdocconf
index 3d5e9de5e0..7fa437c17f 100644
--- a/src/concurrent/doc/qtconcurrent.qdocconf
+++ b/src/concurrent/doc/qtconcurrent.qdocconf
@@ -40,3 +40,6 @@ exampledirs += ../../../examples/qtconcurrent \
excludedirs += ../../../examples/widgets/doc
imagedirs += images
+
+navigation.landingpage = "Qt Concurrent"
+navigation.cppclassespage = "Qt Concurrent C++ Classes"
diff --git a/src/concurrent/doc/src/qtconcurrent-module.qdoc b/src/concurrent/doc/src/qtconcurrent-module.qdoc
index b8d89cbde3..37298017c7 100644
--- a/src/concurrent/doc/src/qtconcurrent-module.qdoc
+++ b/src/concurrent/doc/src/qtconcurrent-module.qdoc
@@ -31,6 +31,7 @@
\brief The Qt Concurrent module contains functionality to support concurrent execution of program code
\ingroup modules
+ \qtvariable concurrent
The Qt Concurrent module extends the basic threading support found in \l{Qt Core} module and
simplifies the development of code that can be executed in parallel on all available CPU cores.
diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in
index e01b448351..36a54787b3 100644
--- a/src/corelib/Qt5CoreConfigExtras.cmake.in
+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in
@@ -55,11 +55,8 @@ set_property(TARGET Qt5::Core APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING QT_MAJOR_VERSION
)
-!!IF isEmpty(CMAKE_HOST_DATA_DIR_IS_ABSOLUTE)
-set(_qt5_corelib_extra_includes \"${_qt5Core_install_prefix}/$${CMAKE_HOST_DATA_DIR}/mkspecs/$${CMAKE_MKSPEC}\")
-!!ELSE
-set(_qt5_corelib_extra_includes \"$${CMAKE_HOST_DATA_DIR}mkspecs/$${CMAKE_MKSPEC}\")
-!!ENDIF
+include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5CoreConfigExtrasMkspecDir.cmake\")
+
foreach(_dir ${_qt5_corelib_extra_includes})
_qt5_Core_check_file_exists(${_dir})
endforeach()
diff --git a/src/corelib/Qt5CoreConfigExtrasMkspecDir.cmake.in b/src/corelib/Qt5CoreConfigExtrasMkspecDir.cmake.in
new file mode 100644
index 0000000000..c357237d0e
--- /dev/null
+++ b/src/corelib/Qt5CoreConfigExtrasMkspecDir.cmake.in
@@ -0,0 +1,6 @@
+
+!!IF isEmpty(CMAKE_HOST_DATA_DIR_IS_ABSOLUTE)
+set(_qt5_corelib_extra_includes \"${_qt5Core_install_prefix}/$${CMAKE_HOST_DATA_DIR}/mkspecs/$${CMAKE_MKSPEC}\")
+!!ELSE
+set(_qt5_corelib_extra_includes \"$${CMAKE_HOST_DATA_DIR}mkspecs/$${CMAKE_MKSPEC}\")
+!!ENDIF
diff --git a/src/corelib/Qt5CoreConfigExtrasMkspecDirForInstall.cmake.in b/src/corelib/Qt5CoreConfigExtrasMkspecDirForInstall.cmake.in
new file mode 100644
index 0000000000..706304cf34
--- /dev/null
+++ b/src/corelib/Qt5CoreConfigExtrasMkspecDirForInstall.cmake.in
@@ -0,0 +1,6 @@
+
+!!IF isEmpty(CMAKE_INSTALL_DATA_DIR_IS_ABSOLUTE)
+set(_qt5_corelib_extra_includes \"${_qt5Core_install_prefix}/$${CMAKE_INSTALL_DATA_DIR}/mkspecs/$${CMAKE_MKSPEC}\")
+!!ELSE
+set(_qt5_corelib_extra_includes \"$${CMAKE_INSTALL_DATA_DIR}mkspecs/$${CMAKE_MKSPEC}\")
+!!ENDIF
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 44a3f06f50..766529c587 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -77,12 +77,32 @@ cmake_umbrella_config_file.output = $$DESTDIR/cmake/Qt5/Qt5Config.cmake
cmake_umbrella_config_version_file.input = $$PWD/../../mkspecs/features/data/cmake/Qt5ConfigVersion.cmake.in
cmake_umbrella_config_version_file.output = $$DESTDIR/cmake/Qt5/Qt5ConfigVersion.cmake
+load(cmake_functions)
+
+CMAKE_HOST_DATA_DIR = $$cmakeRelativePath($$[QT_HOST_DATA/src], $$[QT_INSTALL_PREFIX])
+contains(CMAKE_HOST_DATA_DIR, "^\\.\\./.*"):!isEmpty(CMAKE_HOST_DATA_DIR) {
+ CMAKE_HOST_DATA_DIR = $$[QT_HOST_DATA/src]/
+ CMAKE_HOST_DATA_DIR_IS_ABSOLUTE = True
+}
+
+cmake_extras_mkspec_dir.input = $$PWD/Qt5CoreConfigExtrasMkspecDir.cmake.in
+cmake_extras_mkspec_dir.output = $$DESTDIR/cmake/Qt5Core/Qt5CoreConfigExtrasMkspecDir.cmake
+
+CMAKE_INSTALL_DATA_DIR = $$cmakeRelativePath($$[QT_HOST_DATA], $$[QT_INSTALL_PREFIX])
+contains(CMAKE_INSTALL_DATA_DIR, "^\\.\\./.*"):!isEmpty(CMAKE_INSTALL_DATA_DIR) {
+ CMAKE_INSTALL_DATA_DIR = $$[QT_HOST_DATA]/
+ CMAKE_INSTALL_DATA_DIR_IS_ABSOLUTE = True
+}
+
+cmake_extras_mkspec_dir_for_install.input = $$PWD/Qt5CoreConfigExtrasMkspecDirForInstall.cmake.in
+cmake_extras_mkspec_dir_for_install.output = $$DESTDIR/cmake/install/Qt5Core/Qt5CoreConfigExtrasMkspecDir.cmake
+
cmake_qt5_umbrella_module_files.files = $$cmake_umbrella_config_file.output $$cmake_umbrella_config_version_file.output
cmake_qt5_umbrella_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5
-QMAKE_SUBSTITUTES += ctest_macros_file cmake_umbrella_config_file cmake_umbrella_config_version_file
+QMAKE_SUBSTITUTES += ctest_macros_file cmake_umbrella_config_file cmake_umbrella_config_version_file cmake_extras_mkspec_dir cmake_extras_mkspec_dir_for_install
-ctest_qt5_module_files.files += $$ctest_macros_file.output
+ctest_qt5_module_files.files += $$ctest_macros_file.output $$cmake_extras_mkspec_dir_for_install.output
ctest_qt5_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5Core
diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf
index 0e275ee8d4..7a3e20aa89 100644
--- a/src/corelib/doc/qtcore.qdocconf
+++ b/src/corelib/doc/qtcore.qdocconf
@@ -39,3 +39,8 @@ exampledirs += \
../../../examples/tools/
imagedirs += images
+
+excludedirs += snippets
+
+navigation.landingpage = "Qt Core"
+navigation.cppclassespage = "Qt Core C++ Classes"
diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp
index 532a0e1f59..91eaf298e1 100644
--- a/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp
@@ -85,3 +85,9 @@ QByteArray ba = QUrl::toPercentEncoding("{a fishy string?}", "{}", "s");
qDebug(ba.constData());
// prints "{a fi%73hy %73tring%3F}"
//! [6]
+
+//! [7]
+QUrl url("http://qt-project.org/support/file.html");
+// url.adjusted(RemoveFilename) == "http://qt-project.org/support/"
+// url.fileName() == "file.html"
+//! [7]
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp
index 25d24185ee..ab909e5065 100644
--- a/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp
@@ -134,3 +134,61 @@ return QVariant::fromValue(s);
QObject *object = getObjectFromSomewhere();
QVariant data = QVariant::fromValue(object);
//! [8]
+
+//! [9]
+
+QList<int> intList;
+intList.push_back(7);
+intList.push_back(11);
+intList.push_back(42);
+
+QVariant variant = QVariant::fromValue(intList);
+if (variant.canConvert<QVariantList>()) {
+ QSequentialIterable iterable = variant.value<QSequentialIterable>();
+ // Can use foreach:
+ foreach (const QVariant &v, iterable) {
+ qDebug() << v;
+ }
+ // Can use C++11 range-for:
+ for (const QVariant &v : iterable) {
+ qDebug() << v;
+ }
+ // Can use iterators:
+ QSequentialIterable::const_iterator it = iterable.begin();
+ const QSequentialIterable::const_iterator end = iterable.end();
+ for ( ; it != end; ++it) {
+ qDebug() << *it;
+ }
+}
+
+//! [9]
+
+//! [10]
+
+QHash<int, QString> mapping;
+mapping.insert(7, "Seven");
+mapping.insert(11, "Eleven");
+mapping.insert(42, "Forty-two");
+
+QVariant variant = QVariant::fromValue(mapping);
+if (variant.canConvert<QVariantHash>()) {
+ QAssociativeIterable iterable = variant.value<QAssociativeIterable>();
+ // Can use foreach over the values:
+ foreach (const QVariant &v, iterable) {
+ qDebug() << v;
+ }
+ // Can use C++11 range-for over the values:
+ for (const QVariant &v : iterable) {
+ qDebug() << v;
+ }
+ // Can use iterators:
+ QAssociativeIterable::const_iterator it = iterable.begin();
+ const QAssociativeIterable::const_iterator end = iterable.end();
+ for ( ; it != end; ++it) {
+ qDebug() << *it; // The current value
+ qDebug() << it.key();
+ qDebug() << it.value();
+ }
+}
+
+//! [10]
diff --git a/src/corelib/doc/src/qtcore.qdoc b/src/corelib/doc/src/qtcore.qdoc
index 155a6cd8c0..88afad75c5 100644
--- a/src/corelib/doc/src/qtcore.qdoc
+++ b/src/corelib/doc/src/qtcore.qdoc
@@ -29,6 +29,7 @@
\module QtCore
\title Qt Core C++ Classes
\ingroup modules
+ \qtvariable core
\brief Provides core non-GUI functionality.
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index f899d63a4d..41e11ea652 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -881,4 +881,26 @@
Q_UNUSED(valueOfExpression); /* the value may not be used if Q_ASSERT_X and Q_ASSUME_IMPL are noop */\
} while (0)
+
+/*
+ Sanitize compiler feature availability
+*/
+#if !defined(Q_PROCESSOR_X86)
+# undef QT_COMPILER_SUPPORTS_SSE2
+# undef QT_COMPILER_SUPPORTS_SSE3
+# undef QT_COMPILER_SUPPORTS_SSSE3
+# undef QT_COMPILER_SUPPORTS_SSE4_1
+# undef QT_COMPILER_SUPPORTS_SSE4_2
+# undef QT_COMPILER_SUPPORTS_AVX
+# undef QT_COMPILER_SUPPORTS_AVX2
+#endif
+#if !defined(Q_PROCESSOR_ARM)
+# undef QT_COMPILER_SUPPORTS_IWMMXT
+# undef QT_COMPILER_SUPPORTS_NEON
+#endif
+#if !defined(Q_PROCESSOR_MIPS)
+# undef QT_COMPILER_SUPPORTS_MIPS_DSP
+# undef QT_COMPILER_SUPPORTS_MIPS_DSPR2
+#endif
+
#endif // QCOMPILERDETECTION_H
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 85cb698afc..4ee4235278 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -934,7 +934,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
\endlist
Some constants are defined only on certain platforms. You can use
- the preprocessor symbols Q_OS_WIN and Q_OS_MACX to test that
+ the preprocessor symbols Q_OS_WIN and Q_OS_OSX to test that
the application is compiled under Windows or OS X.
\sa QLibraryInfo
@@ -1077,18 +1077,20 @@ bool qSharedBuild() Q_DECL_NOTHROW
\macro Q_OS_DARWIN
\relates <QtGlobal>
- Defined on Darwin OS (synonym for Q_OS_MAC).
+ Defined on Darwin-based operating systems such as OS X and iOS,
+ including any open source version(s) of Darwin.
*/
/*!
\macro Q_OS_MAC
\relates <QtGlobal>
- Defined on OS X and iOS (synonym for Q_OS_DARWIN).
+ Defined on Darwin-based operating systems distributed by Apple, which
+ currently includes OS X and iOS, but not the open source version.
*/
/*!
- \macro Q_OS_MACX
+ \macro Q_OS_OSX
\relates <QtGlobal>
Defined on OS X.
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index cde3e96ed1..f9629ff430 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -45,11 +45,11 @@
#include <stddef.h>
-#define QT_VERSION_STR "5.1.2"
+#define QT_VERSION_STR "5.2.0"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x050102
+#define QT_VERSION 0x050200
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
@@ -68,12 +68,15 @@
#define QT_STRINGIFY(x) QT_STRINGIFY2(x)
#include <QtCore/qsystemdetection.h>
-#include <QtCore/qcompilerdetection.h>
#include <QtCore/qprocessordetection.h>
+#include <QtCore/qcompilerdetection.h>
#if defined (__ELF__)
# define Q_OF_ELF
#endif
+#if defined (__MACH__) && defined (__APPLE__)
+# define Q_OF_MACH_O
+#endif
#ifdef __cplusplus
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 53a3ebbc10..18f293bba5 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -78,6 +78,7 @@ struct QLibrarySettings
QLibrarySettings();
QScopedPointer<QSettings> settings;
#ifdef QT_BOOTSTRAPPED
+ bool haveEffectiveSourcePaths;
bool haveEffectivePaths;
bool havePaths;
#endif
@@ -99,8 +100,10 @@ public:
static bool haveGroup(QLibraryInfo::PathGroup group)
{
QLibrarySettings *ls = qt_library_settings();
- return ls ? (group == QLibraryInfo::EffectivePaths
- ? ls->haveEffectivePaths : ls->havePaths) : false;
+ return ls ? (group == QLibraryInfo::EffectiveSourcePaths
+ ? ls->haveEffectiveSourcePaths
+ : group == QLibraryInfo::EffectivePaths
+ ? ls->haveEffectivePaths : ls->havePaths) : false;
}
#endif
static QSettings *configuration()
@@ -122,7 +125,12 @@ QLibrarySettings::QLibrarySettings()
// This code needs to be in the regular library, as otherwise a qt.conf that
// works for qmake would break things for dynamically built Qt tools.
QStringList children = settings->childGroups();
+#ifdef QT_BOOTSTRAPPED
+ haveEffectiveSourcePaths = children.contains(QLatin1String("EffectiveSourcePaths"));
+ haveEffectivePaths = haveEffectiveSourcePaths || children.contains(QLatin1String("EffectivePaths"));
+#else
haveEffectivePaths = children.contains(QLatin1String("EffectivePaths"));
+#endif
// Backwards compat: an existing but empty file is claimed to contain the Paths section.
havePaths = !haveEffectivePaths || children.contains(QLatin1String("Paths"));
#ifndef QT_BOOTSTRAPPED
@@ -130,6 +138,9 @@ QLibrarySettings::QLibrarySettings()
settings.reset(0);
#else
} else {
+#ifdef QT_BOOTSTRAPPED
+ haveEffectiveSourcePaths = false;
+#endif
haveEffectivePaths = false;
havePaths = false;
#endif
@@ -334,9 +345,12 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
// and qt.conf with that section is present, use it, otherwise fall back to
// FinalPaths. For FinalPaths, use qt.conf if present and contains not only
// [EffectivePaths], otherwise fall back to builtins.
+ // EffectiveSourcePaths falls back to EffectivePaths.
if (!QLibraryInfoPrivate::haveGroup(group)
- && (group == FinalPaths
- || !(group = FinalPaths, QLibraryInfoPrivate::haveGroup(FinalPaths))))
+ && !(group == EffectiveSourcePaths
+ && (group = EffectivePaths, QLibraryInfoPrivate::haveGroup(group)))
+ && !(group == EffectivePaths
+ && (group = FinalPaths, QLibraryInfoPrivate::haveGroup(group))))
#elif !defined(QT_NO_SETTINGS)
if (!QLibraryInfoPrivate::configuration())
#endif
@@ -368,6 +382,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
QSettings *config = QLibraryInfoPrivate::configuration();
config->beginGroup(QLatin1String(
#ifdef QT_BOOTSTRAPPED
+ group == EffectiveSourcePaths ? "EffectiveSourcePaths" :
group == EffectivePaths ? "EffectivePaths" :
#endif
"Paths"));
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index b275e018a0..17864b555b 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -92,7 +92,7 @@ public:
};
static QString location(LibraryLocation); // ### Qt 6: consider renaming it to path()
#ifdef QT_BOOTSTRAPPED
- enum PathGroup { FinalPaths, EffectivePaths };
+ enum PathGroup { FinalPaths, EffectivePaths, EffectiveSourcePaths };
static QString rawLocation(LibraryLocation, PathGroup);
#endif
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 25c47d5d34..e714839f26 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -982,6 +982,14 @@ public:
Key_MicMute = 0x01000113,
+ Key_Red = 0x01000114,
+ Key_Green = 0x01000115,
+ Key_Yellow = 0x01000116,
+ Key_Blue = 0x01000117,
+
+ Key_ChannelUp = 0x01000118,
+ Key_ChannelDown = 0x01000119,
+
Key_MediaLast = 0x0100ffff,
// Keypad navigation keys
@@ -1173,7 +1181,8 @@ public:
SystemLocaleShortDate,
SystemLocaleLongDate,
DefaultLocaleShortDate,
- DefaultLocaleLongDate
+ DefaultLocaleLongDate,
+ RFC2822Date // RFC 2822 (+ 850 and 1036 during parsing)
};
enum TimeSpec {
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 677cddc87e..d8d7b9cbcd 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -585,6 +585,10 @@
\value LocalDate \e{This enum value is deprecated.} Use Qt::SystemLocaleShortDate
instead (or Qt::SystemLocaleLongDate if you want long dates).
+ \value RFC2822Date \l{RFC 2822}, \l{RFC 850} and \l{RFC 1036} format: either
+ \c{[ddd,] dd MMM yyyy hh:mm[:ss] +/-TZ} or \c{ddd MMM dd yyyy hh:mm[:ss] +/-TZ}
+ for combined dates and times.
+
\note For \c ISODate formats, each \c Y, \c M and \c D represents a single digit
of the year, month and day used to specify the date. Each \c H, \c M and \c S
represents a single digit of the hour, minute and second used to specify the time.
@@ -1618,6 +1622,12 @@
\value Key_TouchpadOn
\value Key_TouchpadOff
\value Key_MicMute
+ \value Key_Red
+ \value Key_Green
+ \value Key_Yellow
+ \value Key_Blue
+ \value Key_ChannelUp
+ \value Key_ChannelDown
\value Key_MediaLast
\value Key_unknown
diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h
index b638b4d509..dc9fa7383a 100644
--- a/src/corelib/global/qsystemdetection.h
+++ b/src/corelib/global/qsystemdetection.h
@@ -49,9 +49,9 @@
/*
The operating system, must be one of: (Q_OS_x)
- DARWIN - Darwin OS (synonym for Q_OS_MAC)
- MAC - OS X or iOS (synonym for Q_OS_DARWIN)
- MACX - OS X
+ DARWIN - Any Darwin system
+ MAC - OS X and iOS
+ OSX - OS X
IOS - iOS
MSDOS - MS-DOS and Windows
OS2 - OS/2
@@ -186,8 +186,9 @@
# include <TargetConditionals.h>
# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
# define Q_OS_IOS
-# else
-# define Q_OS_MACX
+# elif defined(TARGET_OS_MAC) && TARGET_OS_MAC
+# define Q_OS_OSX
+# define Q_OS_MACX // compatibility synonym
# endif
#endif
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index b6926bc544..52b80badb8 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -251,7 +251,7 @@ QT_BEGIN_NAMESPACE
return retVal;
enum {
- DefaultStreamVersion = QDataStream::Qt_5_1
+ DefaultStreamVersion = QDataStream::Qt_5_2
};
/*!
@@ -539,7 +539,8 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_4_8 Same as Qt_4_6.
\value Qt_4_9 Same as Qt_4_6.
\value Qt_5_0 Version 13 (Qt 5.0)
- \value Qt_5_1 Version 14 (Qt 5.1)
+ \value Qt_5_1 Version 14 (Qt 5.1, Qt 5.2)
+ \value Qt_5_2 Same as Qt_5_1.
\sa setVersion(), version()
*/
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index 969cdf4517..eb064b3fe2 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -86,8 +86,9 @@ public:
Qt_4_8 = Qt_4_7,
Qt_4_9 = Qt_4_8,
Qt_5_0 = 13,
- Qt_5_1 = 14
-#if QT_VERSION >= 0x050200
+ Qt_5_1 = 14,
+ Qt_5_2 = Qt_5_1
+#if QT_VERSION >= 0x050300
#error Add the datastream version for this Qt version
#endif
};
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 9ca512e84f..9b3ea2fe2c 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -2005,25 +2005,14 @@ bool QDir::match(const QString &filter, const QString &fileName)
#endif // QT_NO_REGEXP
/*!
- Returns \a path with directory separators normalized (converted to "/") and
- redundant ones removed, and "."s and ".."s resolved (as far as possible).
-
- Symbolic links are kept. This function does not return the
- canonical path, but rather the simplest version of the input.
- For example, "./local" becomes "local", "local/../bin" becomes
- "bin" and "/local/usr/../bin" becomes "/local/bin".
+ Returns \a path with redundant directory separators removed,
+ and "."s and ".."s resolved (as far as possible).
- \sa absolutePath(), canonicalPath()
+ This method is shared with QUrl, so it doesn't deal with QDir::separator(),
+ nor does it remove the trailing slash, if any.
*/
-QString QDir::cleanPath(const QString &path)
+QString qt_normalizePathSegments(const QString &name, bool allowUncPaths)
{
- if (path.isEmpty())
- return path;
- QString name = path;
- QChar dir_separator = separator();
- if (dir_separator != QLatin1Char('/'))
- name.replace(dir_separator, QLatin1Char('/'));
-
int used = 0, levels = 0;
const int len = name.length();
QVarLengthArray<QChar> outVector(len);
@@ -2033,10 +2022,8 @@ QString QDir::cleanPath(const QString &path)
for (int i = 0, last = -1, iwrite = 0; i < len; ++i) {
if (p[i] == QLatin1Char('/')) {
while (i+1 < len && p[i+1] == QLatin1Char('/')) {
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) //allow unc paths
- if (!i)
+ if (allowUncPaths && i == 0)
break;
-#endif
i++;
}
bool eaten = false;
@@ -2099,8 +2086,6 @@ QString QDir::cleanPath(const QString &path)
eaten = true;
#endif
last = -1;
- } else if (last != -1 && i == len-1) {
- eaten = true;
} else {
levels++;
}
@@ -2126,6 +2111,36 @@ QString QDir::cleanPath(const QString &path)
}
QString ret = (used == len ? name : QString(out, used));
+ return ret;
+}
+
+/*!
+ Returns \a path with directory separators normalized (converted to "/") and
+ redundant ones removed, and "."s and ".."s resolved (as far as possible).
+
+ Symbolic links are kept. This function does not return the
+ canonical path, but rather the simplest version of the input.
+ For example, "./local" becomes "local", "local/../bin" becomes
+ "bin" and "/local/usr/../bin" becomes "/local/bin".
+
+ \sa absolutePath(), canonicalPath()
+*/
+QString QDir::cleanPath(const QString &path)
+{
+ if (path.isEmpty())
+ return path;
+ QString name = path;
+ QChar dir_separator = separator();
+ if (dir_separator != QLatin1Char('/'))
+ name.replace(dir_separator, QLatin1Char('/'));
+
+ bool allowUncPaths = false;
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) //allow unc paths
+ allowUncPaths = true;
+#endif
+
+ QString ret = qt_normalizePathSegments(name, allowUncPaths);
+
// Strip away last slash except for root directories
if (ret.length() > 1 && ret.endsWith(QLatin1Char('/'))) {
#if defined (Q_OS_WIN)
diff --git a/src/corelib/io/qipaddress.cpp b/src/corelib/io/qipaddress.cpp
index bd36d36ac1..334c239c91 100644
--- a/src/corelib/io/qipaddress.cpp
+++ b/src/corelib/io/qipaddress.cpp
@@ -53,7 +53,7 @@ static QString number(quint8 val, int base = 10)
}
typedef QVarLengthArray<char, 64> Buffer;
-static bool checkedToAscii(Buffer &buffer, const QChar *begin, const QChar *end)
+static const QChar *checkedToAscii(Buffer &buffer, const QChar *begin, const QChar *end)
{
const ushort *const ubegin = reinterpret_cast<const ushort *>(begin);
const ushort *const uend = reinterpret_cast<const ushort *>(end);
@@ -64,11 +64,11 @@ static bool checkedToAscii(Buffer &buffer, const QChar *begin, const QChar *end)
while (src != uend) {
if (*src >= 0x7f)
- return false;
+ return reinterpret_cast<const QChar *>(src);
*dst++ = *src++;
}
*dst = '\0';
- return true;
+ return 0;
}
static bool parseIp4Internal(IPv4Address &address, const char *ptr, bool acceptLeadingZero);
@@ -76,7 +76,7 @@ bool parseIp4(IPv4Address &address, const QChar *begin, const QChar *end)
{
Q_ASSERT(begin != end);
Buffer buffer;
- if (!checkedToAscii(buffer, begin, end))
+ if (checkedToAscii(buffer, begin, end))
return false;
const char *ptr = buffer.data();
@@ -137,12 +137,23 @@ void toString(QString &appendTo, IPv4Address address)
% number(address);
}
-bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
+/*!
+ \internal
+ \since 5.0
+
+ Parses one IPv6 address from \a begin to \a end and stores the
+ representation in \a address. Returns null if everything was parsed
+ correctly, or the pointer to the first bad character where parsing failed.
+ If the parsing failed for a reason not related to a particular character,
+ returns \a end.
+*/
+const QChar *parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
{
Q_ASSERT(begin != end);
Buffer buffer;
- if (!checkedToAscii(buffer, begin, end))
- return false;
+ const QChar *ret = checkedToAscii(buffer, begin, end);
+ if (ret)
+ return ret;
const char *ptr = buffer.data();
@@ -158,11 +169,11 @@ bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
}
// IPv4-in-IPv6 addresses are stricter in what they accept
if (dotCount != 0 && dotCount != 3)
- return false;
+ return end;
memset(address, 0, sizeof address);
if (colonCount == 2 && end - begin == 2) // "::"
- return true;
+ return 0;
// if there's a double colon ("::"), this is how many zeroes it means
int zeroWordsToFill;
@@ -174,7 +185,7 @@ bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
(ptr[end - begin - 2] == ':' && ptr[end - begin - 1] == ':')) {
zeroWordsToFill = 9 - colonCount;
} else if (colonCount < 2 || colonCount > 7) {
- return false;
+ return end;
} else {
zeroWordsToFill = 8 - colonCount;
}
@@ -183,18 +194,13 @@ bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
int pos = 0;
while (pos < 15) {
- const char *endptr;
- bool ok;
- quint64 ll = qstrtoull(ptr, &endptr, 16, &ok);
- quint16 x = ll;
-
- if (ptr == endptr) {
+ if (*ptr == ':') {
// empty field, we hope it's "::"
if (zeroWordsToFill < 1)
- return false;
+ return begin + (ptr - buffer.data());
if (pos == 0 || pos == colonCount * 2) {
if (ptr[0] == '\0' || ptr[1] != ':')
- return false;
+ return begin + (ptr - buffer.data());
++ptr;
}
pos += zeroWordsToFill * 2;
@@ -202,24 +208,30 @@ bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
++ptr;
continue;
}
+
+ const char *endptr;
+ bool ok;
+ quint64 ll = qstrtoull(ptr, &endptr, 16, &ok);
+ quint16 x = ll;
+
if (!ok || ll != x)
- return false;
+ return begin + (ptr - buffer.data());
if (*endptr == '.') {
// this could be an IPv4 address
// it's only valid in the last element
if (pos != 12)
- return false;
+ return begin + (ptr - buffer.data());
IPv4Address ip4;
if (!parseIp4Internal(ip4, ptr, false))
- return false;
+ return begin + (ptr - buffer.data());
address[12] = ip4 >> 24;
address[13] = ip4 >> 16;
address[14] = ip4 >> 8;
address[15] = ip4;
- return true;
+ return 0;
}
address[pos++] = x >> 8;
@@ -228,10 +240,10 @@ bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end)
if (*endptr == '\0')
break;
if (*endptr != ':')
- return false;
+ return begin + (endptr - buffer.data());
ptr = endptr + 1;
}
- return pos == 16;
+ return pos == 16 ? 0 : end;
}
static inline QChar toHex(uchar c)
diff --git a/src/corelib/io/qipaddress_p.h b/src/corelib/io/qipaddress_p.h
index d5c158d4d1..3059a1c205 100644
--- a/src/corelib/io/qipaddress_p.h
+++ b/src/corelib/io/qipaddress_p.h
@@ -63,7 +63,7 @@ typedef quint32 IPv4Address;
typedef quint8 IPv6Address[16];
Q_CORE_EXPORT bool parseIp4(IPv4Address &address, const QChar *begin, const QChar *end);
-Q_CORE_EXPORT bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end);
+Q_CORE_EXPORT const QChar *parseIp6(IPv6Address &address, const QChar *begin, const QChar *end);
Q_CORE_EXPORT void toString(QString &appendTo, IPv4Address address);
Q_CORE_EXPORT void toString(QString &appendTo, IPv6Address address);
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index e9957d2384..bc0ae5a382 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -1031,6 +1031,41 @@ static int qt_timeout_value(int msecs, int elapsed)
return timeout < 0 ? 0 : timeout;
}
+#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.
+static int bb_select(QProcessPrivate *process, int nfds, fd_set *fdread, fd_set *fdwrite, int timeout)
+{
+ bool stdoutEnabled = false;
+ bool stderrEnabled = false;
+ bool stdinEnabled = false;
+
+ if (process->stdoutChannel.notifier && process->stdoutChannel.notifier->isEnabled()) {
+ stdoutEnabled = true;
+ process->stdoutChannel.notifier->setEnabled(false);
+ }
+ if (process->stderrChannel.notifier && process->stderrChannel.notifier->isEnabled()) {
+ stderrEnabled = true;
+ process->stderrChannel.notifier->setEnabled(false);
+ }
+ if (process->stdinChannel.notifier && process->stdinChannel.notifier->isEnabled()) {
+ stdinEnabled = true;
+ process->stdinChannel.notifier->setEnabled(false);
+ }
+
+ const int ret = select_msecs(nfds, fdread, fdwrite, timeout);
+
+ if (stdoutEnabled)
+ process->stdoutChannel.notifier->setEnabled(true);
+ if (stderrEnabled)
+ process->stderrChannel.notifier->setEnabled(true);
+ if (stdinEnabled)
+ process->stdinChannel.notifier->setEnabled(true);
+
+ return ret;
+}
+#endif // Q_OS_BLACKBERRY
+
bool QProcessPrivate::waitForStarted(int msecs)
{
Q_Q(QProcess);
@@ -1091,7 +1126,11 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
+#ifdef Q_OS_BLACKBERRY
+ int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+#else
int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+#endif
if (ret < 0) {
break;
}
@@ -1163,8 +1202,12 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
- int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
- int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+ int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
+#ifdef Q_OS_BLACKBERRY
+ int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+#else
+ int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+#endif
if (ret < 0) {
break;
}
@@ -1230,8 +1273,12 @@ bool QProcessPrivate::waitForFinished(int msecs)
if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
- int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
- int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+ int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
+#ifdef Q_OS_BLACKBERRY
+ int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+#else
+ int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+#endif
if (ret < 0) {
break;
}
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index bd399f511e..ea917c90d9 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -347,6 +347,10 @@ QString QStandardPaths::displayName(StandardLocation type)
/*!
\fn void QStandardPaths::enableTestMode(bool testMode)
+ \obsolete Use QStandardPaths::setTestModeEnabled
+ */
+/*!
+ \fn void QStandardPaths::setTestModeEnabled(bool testMode)
If \a testMode is true, this enables a special "test mode" in
QStandardPaths, which changes writable locations
@@ -369,10 +373,17 @@ QString QStandardPaths::displayName(StandardLocation type)
static bool qsp_testMode = false;
+#if QT_DEPRECATED_SINCE(5, 2)
void QStandardPaths::enableTestMode(bool testMode)
{
qsp_testMode = testMode;
}
+#endif
+
+void QStandardPaths::setTestModeEnabled(bool testMode)
+{
+ qsp_testMode = testMode;
+}
/*!
\fn void QStandardPaths::isTestModeEnabled()
diff --git a/src/corelib/io/qstandardpaths.h b/src/corelib/io/qstandardpaths.h
index d8b6d24f57..df9089ace7 100644
--- a/src/corelib/io/qstandardpaths.h
+++ b/src/corelib/io/qstandardpaths.h
@@ -89,7 +89,10 @@ public:
static QString findExecutable(const QString &executableName, const QStringList &paths = QStringList());
- static void enableTestMode(bool testMode);
+#if QT_DEPRECATED_SINCE(5, 2)
+ static QT_DEPRECATED void enableTestMode(bool testMode);
+#endif
+ static void setTestModeEnabled(bool testMode);
static bool isTestModeEnabled();
private:
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index f2e1f9bbc7..9607f14853 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -65,7 +65,8 @@
unencoded representation is suitable for showing to users, but
the encoded representation is typically what you would send to
a web server. For example, the unencoded URL
- "http://b\\uuml\c{}hler.example.com" would be sent to the server as
+ "http://bühler.example.com/List of applicants.xml"
+ would be sent to the server as
"http://xn--bhler-kva.example.com/List%20of%20applicants.xml".
A URL can also be constructed piece by piece by calling
@@ -75,8 +76,10 @@
password, host and port. setUserInfo() sets the user name and
password at once.
- Call isValid() to check if the URL is valid. This can be done at
- any point during the constructing of a URL.
+ Call isValid() to check if the URL is valid. This can be done at any point
+ during the constructing of a URL. If isValid() returns false, you should
+ clear() the URL before proceeding, or start over by parsing a new URL with
+ setUrl().
Constructing a query is particularly convenient through the use of the \l
QUrlQuery class and its methods QUrlQuery::setQueryItems(),
@@ -101,13 +104,19 @@
toString(). This representation is appropriate for displaying a
URL to a user in unencoded form. The encoded form however, as
returned by toEncoded(), is for internal use, passing to web
- servers, mail clients and so on.
+ servers, mail clients and so on. Both forms are technically correct
+ and represent the same URL unambiguously -- in fact, passing either
+ form to QUrl's constructor or to setUrl() will yield the same QUrl
+ object.
QUrl conforms to the URI specification from
\l{RFC 3986} (Uniform Resource Identifier: Generic Syntax), and includes
scheme extensions from \l{RFC 1738} (Uniform Resource Locators). Case
folding rules in QUrl conform to \l{RFC 3491} (Nameprep: A Stringprep
- Profile for Internationalized Domain Names (IDN)).
+ Profile for Internationalized Domain Names (IDN)). It is also compatible with the
+ \l{http://freedesktop.org/wiki/Specifications/file-uri-spec/}{file URI specification}
+ from freedesktop.org, provided that the locale encodes file names using
+ UTF-8 (required by IDN).
\section2 Error checking
@@ -170,6 +179,8 @@
of a percent-encoded sequence. This mode is only valid for the
setters setting components of a URL; it is not permitted in
the QUrl constructor, in fromEncoded() or in setUrl().
+ For more information on this mode, see the documentation for
+ QUrl::FullyDecoded.
In TolerantMode, the parser has the following behaviour:
@@ -186,11 +197,12 @@
\li Reserved and unreserved characters: An encoded URL should only
contain a few characters as literals; all other characters should
be percent-encoded. In TolerantMode, these characters will be
- automatically percent-encoded where they are not allowed:
+ accepted if they are found in the URL:
space / double-quote / "<" / ">" / "\" /
"^" / "`" / "{" / "|" / "}"
Those same characters can be decoded again by passing QUrl::DecodeReserved
- to toString() or toEncoded().
+ to toString() or toEncoded(). In the getters of individual components,
+ those characters are often returned in decoded form.
\endlist
@@ -225,9 +237,14 @@
\value RemoveQuery The query part of the URL (following a '?' character)
is removed.
\value RemoveFragment
+ \value RemoveFilename The filename (i.e. everything after the last '/' in the path) is removed.
+ The trailing '/' is kept, unless StripTrailingSlash is set.
+ Only valid if RemovePath is not set.
\value PreferLocalFile If the URL is a local file according to isLocalFile()
and contains no query or fragment, a local file path is returned.
\value StripTrailingSlash The trailing slash is removed if one is present.
+ \value NormalizePathSegments Modifies the path to remove redundant directory separators,
+ and to resolve "."s and ".."s (as far as possible).
Note that the case folding rules in \l{RFC 3491}{Nameprep}, which QUrl
conforms to, require host names to always be converted to lower case,
@@ -263,11 +280,15 @@
would appear in the URL when the full URL is
represented as text. The delimiters are affected
by this option change from component to component.
+ This flag has no effect in toString() or toEncoded().
- \value EncodeReserved Leave the US-ASCII reserved characters in their encoded
- forms.
+ \value EncodeReserved Leave US-ASCII characters not permitted in the URL by
+ the specification in their encoded form. This is the
+ default on toString() and toEncoded().
- \value DecodeReserved Decode the US-ASCII reserved characters.
+ \value DecodeReserved Decode the US-ASCII characters that the URL specification
+ does not allow to appear in the URL. This is the
+ default on the getters of individual components.
\value FullyEncoded Leave all characters in their properly-encoded form,
as this component would appear as part of a URL. When
@@ -279,28 +300,65 @@
components of the URL, this decodes every percent
encoding sequence, including control characters (U+0000
to U+001F) and UTF-8 sequences found in percent-encoded form.
- Note: if the component contains non-US-ASCII sequences
- that aren't valid UTF-8 sequences, the behaviour is
- undefined since QString cannot represent those values
- (data will be lost!)
- This mode is should not be used in functions where more
- than one URL component is returned (userInfo() and authority())
- and it is not allowed in url() and toString().
+ Use of this mode may cause data loss, see below for more information.
The values of EncodeReserved and DecodeReserved should not be used together
- in one call. The behaviour is undefined if that happens. They are provided
- as separate values because the behaviour of the "pretty mode" with regards
+ in one call. The behavior is undefined if that happens. They are provided
+ as separate values because the behavior of the "pretty mode" with regards
to reserved characters is different on certain components and specially on
the full URL.
- The FullyDecoded mode is similar to the behaviour of the functions
- returning QString in Qt 4.x, including the fact that they will most likely
- cause data loss if the component in question contains a non-UTF-8
- percent-encoded sequence. Fortunately, those cases aren't common, so this
- mode should be used when the component in question is used in a non-URL
- context. For example, in an FTP client application, the path to the remote
- file could be stored in a QUrl object, and the string to be transmitted to
- the FTP server should be obtained using this flag.
+ \section2 Full decoding
+
+ The FullyDecoded mode is similar to the behavior of the functions returning
+ QString in Qt 4.x, in that every character represents itself and never has
+ any special meaning. This is true even for the percent character ('%'),
+ which should be interpreted to mean a literal percent, not the beginning of
+ a percent-encoded sequence. The same actual character, in all other
+ decoding modes, is represented by the sequence "%25".
+
+ Whenever re-applying data obtained with QUrl::FullyDecoded into a QUrl,
+ care must be taken to use the QUrl::DecodedMode parameter to the setters
+ (like setPath() and setUserName()). Failure to do so may cause
+ re-interpretation of the percent character ('%') as the beginning of a
+ percent-encoded sequence.
+
+ This mode is quite useful when portions of a URL are used in a non-URL
+ context. For example, to extract the username, password or file paths in an
+ FTP client application, the FullyDecoded mode should be used.
+
+ This mode should be used with care, since there are two conditions that
+ cannot be reliably represented in the returned QString. They are:
+
+ \list
+ \li \b{Non-UTF-8 sequences:} URLs may contain sequences of
+ percent-encoded characters that do not form valid UTF-8 sequences. Since
+ URLs need to be decoded using UTF-8, any decoder failure will result in
+ the QString containing one or more replacement characters where the
+ sequence existed.
+
+ \li \b{Encoded delimiters:} URLs are also allowed to make a distinction
+ between a delimiter found in its literal form and its equivalent in
+ percent-encoded form. This is most commonly found in the query, but is
+ permitted in most parts of the URL.
+ \endlist
+
+ The following example illustrates the problem:
+
+ \code
+ QUrl original("http://example.com/?q=a%2B%3Db%26c");
+ QUrl copy(original);
+ copy.setQuery(copy.query(QUrl::FullyDecoded), QUrl::DecodedMode);
+
+ qDebug() << original.toString(); // prints: http://example.com/?q=a%2B%3Db%26c
+ qDebug() << copy.toString(); // prints: http://example.com/?q=a+=b&c
+ \endcode
+
+ If the two URLs were used via HTTP GET, the interpretation by the web
+ server would probably be different. In the first case, it would interpret
+ as one parameter, with a key of "q" and value "a+=b&c". In the second
+ case, it would probably interpret as two parameters, one with a key of "q"
+ and value "a =b", and the second with a key "c" and no value.
\sa QUrl::FormattingOptions
*/
@@ -321,6 +379,7 @@
#endif
QT_BEGIN_NAMESPACE
+extern QString qt_normalizePathSegments(const QString &name, bool allowUncPaths); // qdir.cpp
inline static bool isHex(char c)
{
@@ -368,6 +427,7 @@ public:
InvalidRegNameError = Host << 8,
InvalidIPv4AddressError,
InvalidIPv6AddressError,
+ InvalidCharacterInIPv6Error,
InvalidIPvFutureError,
HostMissingEndBracket,
@@ -418,7 +478,7 @@ public:
void appendHost(QString &appendTo, QUrl::FormattingOptions options) const;
void appendPath(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const;
void appendQuery(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const;
- void appendFragment(QString &appendTo, QUrl::FormattingOptions options) const;
+ void appendFragment(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const;
// the "end" parameters are like STL iterators: they point to one past the last valid element
bool setScheme(const QString &value, int len, bool doSetError);
@@ -513,7 +573,7 @@ inline void QUrlPrivate::setError(ErrorCode errorCode, const QString &source, in
error->position = supplement;
}
-// From RFC 3896, Appendix A Collected ABNF for URI
+// From RFC 3986, Appendix A Collected ABNF for URI
// URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
//[...]
// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
@@ -541,46 +601,62 @@ inline void QUrlPrivate::setError(ErrorCode errorCode, const QString &source, in
// the path component has a complex ABNF that basically boils down to
// slash-separated segments of "pchar"
-// The above is the strict definition of the URL components and it is what we
-// return encoded as FullyEncoded. However, we store the equivalent to
-// PrettyDecoded internally, as that is the default formatting mode and most
-// likely to be used. PrettyDecoded decodes spaces, unicode sequences and
-// unambiguous delimiters.
+// The above is the strict definition of the URL components and we mostly
+// adhere to it, with few exceptions. QUrl obeys the following behavior:
+// - percent-encoding sequences always use uppercase HEXDIG;
+// - unreserved characters are *always* decoded, no exceptions;
+// - the space character and bytes with the high bit set are controlled by
+// the EncodeSpaces and EncodeUnicode bits;
+// - control characters, the percent sign itself, and bytes with the high
+// bit set that don't form valid UTF-8 sequences are always encoded,
+// except in FullyDecoded mode;
+// - sub-delims are always left alone, except in FullyDecoded mode;
+// - gen-delim change behavior depending on which section of the URL (or
+// the entire URL) we're looking at; see below;
+// - characters not mentioned above, like "<", and ">", are usually
+// decoded in individual sections of the URL, but encoded when the full
+// URL is put together (we can change on subjective definition of
+// "pretty").
//
-// An ambiguous delimiter is a delimiter that, if appeared decoded, would be
-// interpreted as the beginning of a new component. The exact delimiters that
-// match that definition change according to the use. When each field is
-// considered in isolation from the rest, there are no ambiguities. In other
-// words, we always store the most decoded form (except for the query, see
-// below).
+// The behavior for the delimiters bears some explanation. The spec says in
+// section 2.2:
+// URIs that differ in the replacement of a reserved character with its
+// corresponding percent-encoded octet are not equivalent.
+// (note: QUrl API mistakenly uses the "reserved" term, so we will refer to
+// them here as "delimiters").
//
-// The ambiguities arise when components are put together. From last to first
-// component of a full URL, the ambiguities are:
-// - fragment: none, since it's the last.
-// - query: the "#" character is ambiguous, as it starts the fragment. In
-// addition, the "+" character is treated specially, as should be both
-// intra-query delimiters. Since we don't know which ones they are, we
-// keep all reserved characters untouched.
-// - path: the "#" and "?" characters are ambigous. In addition to them,
-// the slash itself is considered special.
+// For that reason, we cannot encode delimiters found in decoded form and we
+// cannot decode the ones found in encoded form if that would change the
+// interpretation. Conversely, we *can* perform the transformation if it would
+// not change the interpretation. From the last component of a URL to the first,
+// here are the gen-delims we can unambiguously transform when the field is
+// taken in isolation:
+// - fragment: none, since it's the last
+// - query: "#" is unambiguous
+// - path: "#" and "?" are unambiguous
// - host: completely special but never ambiguous, see setHost() below.
-// - password: the "#", "?", "/", "[", "]" and "@" characters are ambiguous
-// - username: the "#", "?", "/", "[", "]", "@", and ":" characters are ambiguous
+// - password: the "#", "?", "/", "[", "]" and "@" characters are unambiguous
+// - username: the "#", "?", "/", "[", "]", "@", and ":" characters are unambiguous
// - scheme: doesn't accept any delimiter, see setScheme() below.
//
-// When the authority component is considered in isolation, the ambiguities of
-// its components are:
-// - host: special, never ambiguous
-// - password: "[", "]", "@" are ambiguous
-// - username: "[", "]", "@", ":" are ambiguous
+// Internally, QUrl stores each component in the format that corresponds to the
+// default mode (PrettyDecoded). It deviates from the "strict" FullyEncoded
+// mode in the following way:
+// - spaces are decoded
+// - valid UTF-8 sequences are decoded
+// - gen-delims that can be unambiguously transformed are decoded
+// - characters controlled by DecodeReserved are often decoded, though this behavior
+// can change depending on the subjective definition of "pretty"
//
-// Finally, when the userinfo is considered in isolation, the ambiguities of its
-// components are:
-// - password: none, since it's the last
-// - username: ":" is ambiguous
+// Note that the list of gen-delims that we can transform is different for the
+// user info (user name + password) and the authority (user info + host +
+// port).
+
// list the recoding table modifications to be used with the recodeFromUser and
-// appendToUser functions, according to the rules above.
+// appendToUser functions, according to the rules above. Spaces and UTF-8
+// sequences are handled outside the tables.
+
// the encodedXXX tables are run with the delimiters set to "leave" by default;
// the decodedXXX tables are run with the delimiters set to "decode" by default
// (except for the query, which doesn't use these functions)
@@ -589,103 +665,88 @@ inline void QUrlPrivate::setError(ErrorCode errorCode, const QString &source, in
#define leave(x) ushort(0x100 | (x))
#define encode(x) ushort(0x200 | (x))
-static const ushort encodedUserNameActions[] = {
- // first field, everything must be encoded, including the ":"
- // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
- encode('/'), // 0
- encode('?'), // 1
- encode('#'), // 2
- encode('['), // 3
- encode(']'), // 4
- encode('@'), // 5
- encode(':'), // 6
- 0
-};
-static const ushort * const decodedUserNameInAuthorityActions = encodedUserNameActions + 3;
-static const ushort * const decodedUserNameInUserInfoActions = encodedUserNameActions + 6;
-static const ushort * const decodedUserNameInUrlActions = encodedUserNameActions;
-static const ushort * const decodedUserNameInIsolationActions = 0;
-
-static const ushort encodedPasswordActions[] = {
- // same as encodedUserNameActions, but decode ":"
- // userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
- encode('/'), // 0
- encode('?'), // 1
- encode('#'), // 2
- encode('['), // 3
- encode(']'), // 4
- encode('@'), // 5
- 0
-};
-static const ushort * const decodedPasswordInAuthorityActions = encodedPasswordActions + 3;
-static const ushort * const decodedPasswordInUserInfoActions = 0;
-static const ushort * const decodedPasswordInUrlActions = encodedPasswordActions;
-static const ushort * const decodedPasswordInIsolationActions = 0;
-
-static const ushort encodedPathActions[] = {
- // pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
- encode('['), // 0
- encode(']'), // 1
- encode('?'), // 2
- encode('#'), // 3
- leave('/'), // 4
- 0
-};
-static const ushort decodedPathInUrlActions[] = {
- decode('{'), // 0
- decode('}'), // 1
- encode('?'), // 2
- encode('#'), // 3
- leave('/'), // 4
+static const ushort userNameInIsolation[] = {
+ decode(':'), // 0
+ decode('@'), // 1
+ decode(']'), // 2
+ decode('['), // 3
+ decode('/'), // 4
+ decode('?'), // 5
+ decode('#'), // 6
+
+ decode('"'), // 7
+ decode('<'),
+ decode('>'),
+ decode('^'),
+ decode('\\'),
+ decode('|'),
+ decode('{'),
+ decode('}'),
0
};
-static const ushort * const decodedPathInIsolationActions = encodedPathActions + 4; // leave('/')
-
-static const ushort encodedFragmentActions[] = {
- // fragment = *( pchar / "/" / "?" )
- // gen-delims permitted: ":" / "@" / "/" / "?"
- // -> must encode: "[" / "]" / "#"
- // HOWEVER: we allow "#" to remain decoded
- decode('#'), // 0
- decode(':'), // 1
- decode('@'), // 2
- decode('/'), // 3
- decode('?'), // 4
- encode('['), // 5
- encode(']'), // 6
+static const ushort * const passwordInIsolation = userNameInIsolation + 1;
+static const ushort * const pathInIsolation = userNameInIsolation + 5;
+static const ushort * const queryInIsolation = userNameInIsolation + 6;
+static const ushort * const fragmentInIsolation = userNameInIsolation + 7;
+
+static const ushort userNameInUserInfo[] = {
+ encode(':'), // 0
+ decode('@'), // 1
+ decode(']'), // 2
+ decode('['), // 3
+ decode('/'), // 4
+ decode('?'), // 5
+ decode('#'), // 6
+
+ decode('"'), // 7
+ decode('<'),
+ decode('>'),
+ decode('^'),
+ decode('\\'),
+ decode('|'),
+ decode('{'),
+ decode('}'),
0
};
-//static const ushort * const decodedFragmentInUrlActions = 0;
-static const ushort * const decodedFragmentInIsolationActions = 0;
-
-// the query is handled specially: the decodedQueryXXX tables are run with
-// the delimiters set to "leave" by default and the others set to "encode"
-static const ushort encodedQueryActions[] = {
- // query = *( pchar / "/" / "?" )
- // gen-delims permitted: ":" / "@" / "/" / "?"
- // HOWEVER: we leave alone them alone, plus "[" and "]"
- // -> must encode: "#"
- encode('#'), // 0
- 0
-};
-static const ushort decodedQueryInIsolationActions[] = {
- decode('"'), // 0
- decode('<'), // 1
- decode('>'), // 2
- decode('^'), // 3
- decode('\\'),// 4
- decode('|'), // 5
- decode('{'), // 6
- decode('}'), // 7
- decode('#'), // 8
+static const ushort * const passwordInUserInfo = userNameInUserInfo + 1;
+
+static const ushort userNameInAuthority[] = {
+ encode(':'), // 0
+ encode('@'), // 1
+ encode(']'), // 2
+ encode('['), // 3
+ decode('/'), // 4
+ decode('?'), // 5
+ decode('#'), // 6
+
+ decode('"'), // 7
+ decode('<'),
+ decode('>'),
+ decode('^'),
+ decode('\\'),
+ decode('|'),
+ decode('{'),
+ decode('}'),
0
};
-static const ushort decodedQueryInUrlActions[] = {
- decode('{'), // 6
- decode('}'), // 7
- encode('#'), // 8
+static const ushort * const passwordInAuthority = userNameInAuthority + 1;
+
+static const ushort userNameInUrl[] = {
+ encode(':'), // 0
+ encode('@'), // 1
+ encode(']'), // 2
+ encode('['), // 3
+ encode('/'), // 4
+ encode('?'), // 5
+ encode('#'), // 6
+
+ // no need to list encode(x) for the other characters
0
};
+static const ushort * const passwordInUrl = userNameInUrl + 1;
+static const ushort * const pathInUrl = userNameInUrl + 5;
+static const ushort * const queryInUrl = userNameInUrl + 6;
+static const ushort * const fragmentInUrl = userNameInUrl + 6;
static inline void parseDecodedComponent(QString &data)
{
@@ -698,33 +759,22 @@ recodeFromUser(const QString &input, const ushort *actions, int from, int to)
QString output;
const QChar *begin = input.constData() + from;
const QChar *end = input.constData() + to;
- if (qt_urlRecode(output, begin, end,
- QUrl::DecodeReserved, actions))
+ if (qt_urlRecode(output, begin, end, 0, actions))
return output;
return input.mid(from, to - from);
}
-// appendXXXX functions:
-// the internal value is stored in its most decoded form, so that case is easy.
-// DecodeUnicode and DecodeSpaces are handled by qt_urlRecode.
-// That leaves these functions to handle two cases related to delimiters:
-// 1) encoded encodedXXXX tables
-// 2) decoded decodedXXXX tables
+// appendXXXX functions: copy from the internal form to the external, user form.
+// the internal value is stored in its PrettyDecoded form, so that case is easy.
static inline void appendToUser(QString &appendTo, const QString &value, QUrl::FormattingOptions options,
- const ushort *encodedActions, const ushort *decodedActions)
+ const ushort *actions)
{
if (options == QUrl::PrettyDecoded) {
appendTo += value;
return;
}
- const ushort *actions = 0;
- if (options & QUrl::EncodeDelimiters)
- actions = encodedActions;
- else
- actions = decodedActions;
-
if (!qt_urlRecode(appendTo, value.constData(), value.constEnd(), options, actions))
appendTo += value;
}
@@ -751,31 +801,32 @@ inline void QUrlPrivate::appendUserInfo(QString &appendTo, QUrl::FormattingOptio
const ushort *userNameActions;
const ushort *passwordActions;
if (options & QUrl::EncodeDelimiters) {
- userNameActions = encodedUserNameActions;
- passwordActions = encodedPasswordActions;
+ userNameActions = userNameInUrl;
+ passwordActions = passwordInUrl;
} else {
switch (appendingTo) {
case UserInfo:
- userNameActions = decodedUserNameInUserInfoActions;
- passwordActions = decodedPasswordInUserInfoActions;
+ userNameActions = userNameInUserInfo;
+ passwordActions = passwordInUserInfo;
break;
case Authority:
- userNameActions = decodedUserNameInAuthorityActions;
- passwordActions = decodedPasswordInAuthorityActions;
+ userNameActions = userNameInAuthority;
+ passwordActions = passwordInAuthority;
break;
case FullUrl:
+ userNameActions = userNameInUrl;
+ passwordActions = passwordInUrl;
+ break;
+
default:
- userNameActions = decodedUserNameInUrlActions;
- passwordActions = decodedPasswordInUrlActions;
+ // can't happen
+ Q_UNREACHABLE();
break;
}
}
- if ((options & QUrl::EncodeReserved) == 0)
- options |= QUrl::DecodeReserved;
-
if (!qt_urlRecode(appendTo, userName.constData(), userName.constEnd(), options, userNameActions))
appendTo += userName;
if (options & QUrl::RemovePassword || !hasPassword()) {
@@ -789,51 +840,52 @@ inline void QUrlPrivate::appendUserInfo(QString &appendTo, QUrl::FormattingOptio
inline void QUrlPrivate::appendUserName(QString &appendTo, QUrl::FormattingOptions options) const
{
- appendToUser(appendTo, userName, options, encodedUserNameActions, decodedUserNameInIsolationActions);
+ // only called from QUrl::userName()
+ appendToUser(appendTo, userName, options,
+ options & QUrl::EncodeDelimiters ? userNameInUrl : userNameInIsolation);
}
inline void QUrlPrivate::appendPassword(QString &appendTo, QUrl::FormattingOptions options) const
{
- appendToUser(appendTo, password, options, encodedPasswordActions, decodedPasswordInIsolationActions);
+ // only called from QUrl::password()
+ appendToUser(appendTo, password, options,
+ options & QUrl::EncodeDelimiters ? passwordInUrl : passwordInIsolation);
}
inline void QUrlPrivate::appendPath(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const
{
- if (appendingTo != Path && !(options & QUrl::EncodeDelimiters)) {
- if (!qt_urlRecode(appendTo, path.constData(), path.constEnd(), options, decodedPathInUrlActions))
- appendTo += path;
-
- } else {
- appendToUser(appendTo, path, options, encodedPathActions, decodedPathInIsolationActions);
+ QString thePath = path;
+ if (options & QUrl::NormalizePathSegments) {
+ thePath = qt_normalizePathSegments(path, false);
+ }
+ if (options & QUrl::RemoveFilename) {
+ const int slash = path.lastIndexOf(QLatin1Char('/'));
+ if (slash == -1)
+ return;
+ thePath = path.left(slash+1);
+ }
+ // check if we need to remove trailing slashes
+ if (options & QUrl::StripTrailingSlash) {
+ while (thePath.length() > 1 && thePath.endsWith(QLatin1Char('/')))
+ thePath.chop(1);
}
+
+ appendToUser(appendTo, thePath, options,
+ appendingTo == FullUrl || options & QUrl::EncodeDelimiters ? pathInUrl : pathInIsolation);
+
}
-inline void QUrlPrivate::appendFragment(QString &appendTo, QUrl::FormattingOptions options) const
+inline void QUrlPrivate::appendFragment(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const
{
- appendToUser(appendTo, fragment, options, encodedFragmentActions, decodedFragmentInIsolationActions);
+ appendToUser(appendTo, fragment, options,
+ options & QUrl::EncodeDelimiters ? fragmentInUrl :
+ appendingTo == FullUrl ? 0 : fragmentInIsolation);
}
inline void QUrlPrivate::appendQuery(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const
{
- // almost the same code as the previous functions
- // except we prefer not to touch the delimiters
- if (options == QUrl::PrettyDecoded && appendingTo == Query) {
- appendTo += query;
- return;
- }
-
- const ushort *actions = 0;
- if (options & QUrl::EncodeDelimiters) {
- actions = encodedQueryActions;
- } else {
- // reset to default qt_urlRecode behaviour (leave delimiters alone)
- options |= QUrl::EncodeDelimiters;
- actions = appendingTo == Query ? decodedQueryInIsolationActions : decodedQueryInUrlActions;
- }
-
- if (!qt_urlRecode(appendTo, query.constData(), query.constData() + query.length(),
- options, actions))
- appendTo += query;
+ appendToUser(appendTo, query, options,
+ appendingTo == FullUrl || options & QUrl::EncodeDelimiters ? queryInUrl : queryInIsolation);
}
// setXXX functions
@@ -978,42 +1030,31 @@ inline void QUrlPrivate::setUserInfo(const QString &userInfo, int from, int end)
inline void QUrlPrivate::setUserName(const QString &value, int from, int end)
{
sectionIsPresent |= UserName;
- userName = recodeFromUser(value, decodedUserNameInIsolationActions, from, end);
+ userName = recodeFromUser(value, userNameInIsolation, from, end);
}
inline void QUrlPrivate::setPassword(const QString &value, int from, int end)
{
sectionIsPresent |= Password;
- password = recodeFromUser(value, decodedPasswordInIsolationActions, from, end);
+ password = recodeFromUser(value, passwordInIsolation, from, end);
}
inline void QUrlPrivate::setPath(const QString &value, int from, int end)
{
// sectionIsPresent |= Path; // not used, save some cycles
- path = recodeFromUser(value, decodedPathInIsolationActions, from, end);
+ path = recodeFromUser(value, pathInIsolation, from, end);
}
inline void QUrlPrivate::setFragment(const QString &value, int from, int end)
{
sectionIsPresent |= Fragment;
- fragment = recodeFromUser(value, decodedFragmentInIsolationActions, from, end);
+ fragment = recodeFromUser(value, fragmentInIsolation, from, end);
}
inline void QUrlPrivate::setQuery(const QString &value, int from, int iend)
{
sectionIsPresent |= Query;
-
- // use the default actions for the query (don't set QUrl::DecodeAllDelimiters)
- QString output;
- const QChar *begin = value.constData() + from;
- const QChar *end = value.constData() + iend;
-
- // leave delimiters alone but decode the rest
- if (qt_urlRecode(output, begin, end, QUrl::EncodeDelimiters,
- decodedQueryInIsolationActions))
- query = output;
- else
- query = value.mid(from, iend - from);
+ query = recodeFromUser(value, queryInIsolation, from, iend);
}
// Host handling
@@ -1059,7 +1100,7 @@ inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions o
// this is either an IPv4Address or a reg-name
// if it is a reg-name, it is already stored in Unicode form
if (options == QUrl::EncodeUnicode)
- appendTo += qt_ACE_do(host, ToAceOnly);
+ appendTo += qt_ACE_do(host, ToAceOnly, AllowLeadingDot);
else
appendTo += host;
}
@@ -1067,7 +1108,7 @@ inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions o
// the whole IPvFuture is passed and parsed here, including brackets;
// returns null if the parsing was successful, or the QChar of the first failure
-static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar *end)
+static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar *end, QUrl::ParsingMode mode)
{
// IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
static const char acceptable[] =
@@ -1076,19 +1117,25 @@ static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar
"-._~"; // unreserved
// the brackets and the "v" have been checked
+ const QChar *const origBegin = begin;
if (begin[3].unicode() != '.')
return &begin[3];
- if ((begin[2].unicode() >= 'A' && begin[2].unicode() >= 'F') ||
+ if ((begin[2].unicode() >= 'A' && begin[2].unicode() <= 'F') ||
(begin[2].unicode() >= 'a' && begin[2].unicode() <= 'f') ||
(begin[2].unicode() >= '0' && begin[2].unicode() <= '9')) {
// this is so unlikely that we'll just go down the slow path
// decode the whole string, skipping the "[vH." and "]" which we already know to be there
host += QString::fromRawData(begin, 4);
+
+ // uppercase the version, if necessary
+ if (begin[2].unicode() >= 'a')
+ host[host.length() - 2] = begin[2].unicode() - 0x20;
+
begin += 4;
--end;
QString decoded;
- if (qt_urlRecode(decoded, begin, end, QUrl::FullyEncoded, 0)) {
+ if (mode == QUrl::TolerantMode && qt_urlRecode(decoded, begin, end, QUrl::FullyDecoded, 0)) {
begin = decoded.constBegin();
end = decoded.constEnd();
}
@@ -1103,37 +1150,44 @@ static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar
else if (begin->unicode() < 0x80 && strchr(acceptable, begin->unicode()) != 0)
host += *begin;
else
- return begin;
+ return decoded.isEmpty() ? begin : &origBegin[2];
}
host += QLatin1Char(']');
return 0;
}
- return &begin[2];
+ return &origBegin[2];
}
// ONLY the IPv6 address is parsed here, WITHOUT the brackets
-static bool parseIp6(QString &host, const QChar *begin, const QChar *end)
+static const QChar *parseIp6(QString &host, const QChar *begin, const QChar *end, QUrl::ParsingMode mode)
{
QIPAddressUtils::IPv6Address address;
- if (!QIPAddressUtils::parseIp6(address, begin, end)) {
+ const QChar *ret = QIPAddressUtils::parseIp6(address, begin, end);
+ if (ret) {
+ // this struct is kept in automatic storage because it's only 4 bytes
+ const ushort decodeColon[] = { decode(':'), 0 };
+
// IPv6 failed parsing, check if it was a percent-encoded character in
// the middle and try again
QString decoded;
- if (!qt_urlRecode(decoded, begin, end, QUrl::FullyEncoded, 0)) {
- // no transformation, nothing to re-parse
- return false;
+ if (mode == QUrl::TolerantMode && qt_urlRecode(decoded, begin, end, 0, decodeColon)) {
+ // recurse
+ // if the parsing fails again, the qt_urlRecode above will return 0
+ ret = parseIp6(host, decoded.constBegin(), decoded.constEnd(), mode);
+
+ // we can't return ret, otherwise it would be dangling
+ return ret ? end : 0;
}
- // recurse
- // if the parsing fails again, the qt_urlRecode above will return 0
- return parseIp6(host, decoded.constBegin(), decoded.constEnd());
+ // no transformation, nothing to re-parse
+ return ret;
}
host.reserve(host.size() + (end - begin));
host += QLatin1Char('[');
QIPAddressUtils::toString(host, address);
host += QLatin1Char(']');
- return true;
+ return 0;
}
inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl::ParsingMode mode)
@@ -1157,17 +1211,22 @@ inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl:
}
if (len > 5 && begin[1].unicode() == 'v') {
- const QChar *c = parseIpFuture(host, begin, end);
+ const QChar *c = parseIpFuture(host, begin, end, mode);
if (c)
setError(InvalidIPvFutureError, value, c - value.constData());
return !c;
+ } else if (begin[1].unicode() == 'v') {
+ setError(InvalidIPvFutureError, value, from);
}
- if (parseIp6(host, begin + 1, end - 1))
+ const QChar *c = parseIp6(host, begin + 1, end - 1, mode);
+ if (!c)
return true;
- setError(begin[1].unicode() == 'v' ? InvalidIPvFutureError : InvalidIPv6AddressError,
- value, from);
+ if (c == end - 1)
+ setError(InvalidIPv6AddressError, value, from);
+ else
+ setError(InvalidCharacterInIPv6Error, value, c - value.constData());
return false;
}
@@ -1194,7 +1253,7 @@ inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl:
// check for percent-encoding first
QString s;
- if (mode == QUrl::TolerantMode && qt_urlRecode(s, begin, end, QUrl::DecodeReserved, 0)) {
+ if (mode == QUrl::TolerantMode && qt_urlRecode(s, begin, end, 0, 0)) {
// something was decoded
// anything encoded left?
int pos = s.indexOf(QChar(0x25)); // '%'
@@ -1207,7 +1266,7 @@ inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl:
return setHost(s, 0, s.length(), QUrl::StrictMode);
}
- s = qt_ACE_do(QString::fromRawData(begin, len), NormalizeAce);
+ s = qt_ACE_do(QString::fromRawData(begin, len), NormalizeAce, ForbidLeadingDot);
if (s.isEmpty()) {
setError(InvalidRegNameError, value);
return false;
@@ -1583,87 +1642,6 @@ inline void QUrlPrivate::validate() const
}
}
}
-
-inline const QByteArray &QUrlPrivate::normalized() const
-{
- if (QURL_HASFLAG(stateFlags, QUrlPrivate::Normalized))
- return encodedNormalized;
-
- QUrlPrivate *that = const_cast<QUrlPrivate *>(this);
- QURL_SETFLAG(that->stateFlags, QUrlPrivate::Normalized);
-
- QUrlPrivate tmp = *this;
- tmp.scheme = tmp.scheme.toLower();
- tmp.host = tmp.canonicalHost();
-
- // ensure the encoded and normalized parts of the URL
- tmp.ensureEncodedParts();
- if (tmp.encodedUserName.contains('%'))
- q_normalizePercentEncoding(&tmp.encodedUserName, userNameExcludeChars);
- if (tmp.encodedPassword.contains('%'))
- q_normalizePercentEncoding(&tmp.encodedPassword, passwordExcludeChars);
- if (tmp.encodedFragment.contains('%'))
- q_normalizePercentEncoding(&tmp.encodedFragment, fragmentExcludeChars);
-
- if (tmp.encodedPath.contains('%')) {
- // the path is a bit special:
- // the slashes shouldn't be encoded or decoded.
- // They should remain exactly like they are right now
- //
- // treat the path as a slash-separated sequence of pchar
- QByteArray result;
- result.reserve(tmp.encodedPath.length());
- if (tmp.encodedPath.startsWith('/'))
- result.append('/');
-
- const char *data = tmp.encodedPath.constData();
- int lastSlash = 0;
- int nextSlash;
- do {
- ++lastSlash;
- nextSlash = tmp.encodedPath.indexOf('/', lastSlash);
- int len;
- if (nextSlash == -1)
- len = tmp.encodedPath.length() - lastSlash;
- else
- len = nextSlash - lastSlash;
-
- if (memchr(data + lastSlash, '%', len)) {
- // there's at least one percent before the next slash
- QByteArray block = QByteArray(data + lastSlash, len);
- q_normalizePercentEncoding(&block, pathExcludeChars);
- result.append(block);
- } else {
- // no percents in this path segment, append wholesale
- result.append(data + lastSlash, len);
- }
-
- // append the slash too, if it's there
- if (nextSlash != -1)
- result.append('/');
-
- lastSlash = nextSlash;
- } while (lastSlash != -1);
-
- tmp.encodedPath = result;
- }
-
- if (!tmp.scheme.isEmpty()) // relative test
- removeDotsFromPath(&tmp.encodedPath);
-
- int qLen = tmp.query.length();
- for (int i = 0; i < qLen; i++) {
- if (qLen - i > 2 && tmp.query.at(i) == '%') {
- ++i;
- tmp.query[i] = qToLower(tmp.query.at(i));
- ++i;
- tmp.query[i] = qToLower(tmp.query.at(i));
- }
- }
- encodedNormalized = tmp.toEncoded();
-
- return encodedNormalized;
-}
#endif
/*!
@@ -1692,7 +1670,9 @@ inline const QByteArray &QUrlPrivate::normalized() const
/*!
Constructs a URL by parsing \a url. QUrl will automatically percent encode
all characters that are not allowed in a URL and decode the percent-encoded
- sequences that represent a character that is allowed in a URL.
+ sequences that represent an unreserved character (letters, digits, hyphens,
+ undercores, dots and tildes). All other characters are left in their
+ original forms.
Parses the \a url using the parser mode \a parsingMode. In TolerantMode
(the default), QUrl will correct certain mistakes, notably the presence of
@@ -1794,8 +1774,9 @@ void QUrl::clear()
/*!
Parses \a url and sets this object to that value. QUrl will automatically
percent encode all characters that are not allowed in a URL and decode the
- percent-encoded sequences that represent a character that is allowed in a
- URL.
+ percent-encoded sequences that represent an unreserved character (letters,
+ digits, hyphens, undercores, dots and tildes). All other characters are
+ left in their original forms.
Parses the \a url using the parser mode \a parsingMode. In TolerantMode
(the default), QUrl will correct certain mistakes, notably the presence of
@@ -1869,6 +1850,7 @@ void QUrl::setScheme(const QString &scheme)
The scheme can only contain US-ASCII letters or digits, which means it
cannot contain any character that would otherwise require encoding.
+ Additionally, schemes are always returned in lowercase form.
\sa setScheme(), isRelative()
*/
@@ -1900,10 +1882,11 @@ QString QUrl::scheme() const
and some characters (including space) are not allowed in undecoded form. In
TolerantMode (the default), all characters are accepted in undecoded form
and the tolerant parser will correct stray '%' not followed by two hex
- characters. In DecodedMode, '%' stand for themselves and encoded characters
- are not possible. Because of that, in DecodedMode, it is not possible to
- use the delimiter characters as non-delimiters (e.g., a password containing
- a '@').
+ characters.
+
+ This function does not allow \a mode to be QUrl::DecodedMode. To set fully
+ decoded data, call setUserName(), setPassword(), setHost() and setPort()
+ individually.
\sa setUserInfo(), setHost(), setPort()
*/
@@ -1911,13 +1894,13 @@ void QUrl::setAuthority(const QString &authority, ParsingMode mode)
{
detach();
d->clearError();
- QString data = authority;
+
if (mode == DecodedMode) {
- parseDecodedComponent(data);
- mode = TolerantMode;
+ qWarning("QUrl::setAuthority(): QUrl::DecodedMode is not permitted in this function");
+ return;
}
- d->setAuthority(data, 0, data.length(), mode);
+ d->setAuthority(authority, 0, authority.length(), mode);
if (authority.isNull()) {
// QUrlPrivate::setAuthority cleared almost everything
// but it leaves the Host bit set
@@ -1929,13 +1912,14 @@ void QUrl::setAuthority(const QString &authority, ParsingMode mode)
Returns the authority of the URL if it is defined; otherwise
an empty string is returned.
- The \a options argument controls how to format the authority portion of the
- URL. The value of QUrl::FullyDecoded should be avoided, since it may
- produce an ambiguous return value (for example, if the username contains a
- colon ':' or either the username or password contain an at-sign '@'). In
- all other cases, this function returns an unambiguous value, which may
- contain those characters still percent-encoded, plus some control
- sequences not representable in decoded form in QString.
+ This function returns an unambiguous value, which may contain that
+ characters still percent-encoded, plus some control sequences not
+ representable in decoded form in QString.
+
+ The \a options argument controls how to format the user info component. The
+ value of QUrl::FullyDecoded is not permitted in this function. If you need
+ to obtain fully decoded data, call userName(), password(), host() and
+ port() individually.
\sa setAuthority(), userInfo(), userName(), password(), host(), port()
*/
@@ -1943,6 +1927,11 @@ QString QUrl::authority(ComponentFormattingOptions options) const
{
if (!d) return QString();
+ if (options == QUrl::FullyDecoded) {
+ qWarning("QUrl::authority(): QUrl::FullyDecoded is not permitted in this function");
+ return QString();
+ }
+
QString result;
d->appendAuthority(result, options, QUrlPrivate::Authority);
return result;
@@ -1964,9 +1953,10 @@ QString QUrl::authority(ComponentFormattingOptions options) const
and some characters (including space) are not allowed in undecoded form. In
TolerantMode (the default), all characters are accepted in undecoded form
and the tolerant parser will correct stray '%' not followed by two hex
- characters. In DecodedMode, '%' stand for themselves and encoded characters
- are not possible. Because of that, in DecodedMode, it is not possible to
- use the ':' delimiter characters as non-delimiter in the user name.
+ characters.
+
+ This function does not allow \a mode to be QUrl::DecodedMode. To set fully
+ decoded data, call setUserName() and setPassword() individually.
\sa userInfo(), setUserName(), setPassword(), setAuthority()
*/
@@ -1976,8 +1966,8 @@ void QUrl::setUserInfo(const QString &userInfo, ParsingMode mode)
d->clearError();
QString trimmed = userInfo.trimmed();
if (mode == DecodedMode) {
- parseDecodedComponent(trimmed);
- mode = TolerantMode;
+ qWarning("QUrl::setUserInfo(): QUrl::DecodedMode is not permitted in this function");
+ return;
}
d->setUserInfo(trimmed, 0, trimmed.length());
@@ -1996,12 +1986,13 @@ void QUrl::setUserInfo(const QString &userInfo, ParsingMode mode)
Returns the user info of the URL, or an empty string if the user
info is undefined.
+ This function returns an unambiguous value, which may contain that
+ characters still percent-encoded, plus some control sequences not
+ representable in decoded form in QString.
+
The \a options argument controls how to format the user info component. The
- value of QUrl::FullyDecoded should be avoided, since it may produce an
- ambiguous return value (for example, if the username contains a colon ':').
- In all other cases, this function returns an unambiguous value, which may
- contain that characters still percent-encoded, plus some control sequences
- not representable in decoded form in QString.
+ value of QUrl::FullyDecoded is not permitted in this function. If you need
+ to obtain fully decoded data, call userName() and password() individually.
\sa setUserInfo(), userName(), password(), authority()
*/
@@ -2009,6 +2000,11 @@ QString QUrl::userInfo(ComponentFormattingOptions options) const
{
if (!d) return QString();
+ if (options == QUrl::FullyDecoded) {
+ qWarning("QUrl::userInfo(): QUrl::FullyDecoded is not permitted in this function");
+ return QString();
+ }
+
QString result;
d->appendUserInfo(result, options, QUrlPrivate::UserInfo);
return result;
@@ -2458,6 +2454,36 @@ QString QUrl::path(ComponentFormattingOptions options) const
*/
/*!
+ \since 5.2
+
+ Returns the name of the file, excluding the directory path.
+
+ Note that, if this QUrl object is given a path ending in a slash, the name of the file is considered empty.
+
+ If the path doesn't contain any slash, it is fully returned as the fileName.
+
+ Example:
+
+ \snippet code/src_corelib_io_qurl.cpp 7
+
+ The \a options argument controls how to format the file name component. All
+ values produce an unambiguous result. With QUrl::FullyDecoded, all
+ percent-encoded sequences are decoded; otherwise, the returned value may
+ contain some percent-encoded sequences for some control sequences not
+ representable in decoded form in QString.
+
+ \sa path()
+*/
+QString QUrl::fileName(ComponentFormattingOptions options) const
+{
+ const QString ourPath = path(options);
+ const int slash = ourPath.lastIndexOf(QLatin1Char('/'));
+ if (slash == -1)
+ return ourPath;
+ return ourPath.mid(slash + 1);
+}
+
+/*!
\since 4.2
Returns true if this URL contains a Query (i.e., if ? was seen on it).
@@ -2903,7 +2929,7 @@ QString QUrl::fragment(ComponentFormattingOptions options) const
if (!d) return QString();
QString result;
- d->appendFragment(result, options);
+ d->appendFragment(result, options, QUrlPrivate::Fragment);
if (d->hasFragment() && result.isNull())
result.detach();
return result;
@@ -2976,7 +3002,7 @@ QString QUrl::topLevelDomain(ComponentFormattingOptions options) const
{
QString tld = qTopLevelDomain(host());
if (options & EncodeUnicode) {
- return qt_ACE_do(tld, ToAceOnly);
+ return qt_ACE_do(tld, ToAceOnly, AllowLeadingDot);
}
return tld;
}
@@ -3148,12 +3174,8 @@ QString QUrl::toString(FormattingOptions options) const
url += QLatin1String("//");
}
- if (!(options & QUrl::RemovePath)) {
+ if (!(options & QUrl::RemovePath))
d->appendPath(url, options, QUrlPrivate::FullUrl);
- // check if we need to remove trailing slashes
- if ((options & StripTrailingSlash) && !d->path.isEmpty() && d->path != QLatin1String("/") && url.endsWith(QLatin1Char('/')))
- url.chop(1);
- }
if (!(options & QUrl::RemoveQuery) && d->hasQuery()) {
url += QLatin1Char('?');
@@ -3161,7 +3183,7 @@ QString QUrl::toString(FormattingOptions options) const
}
if (!(options & QUrl::RemoveFragment) && d->hasFragment()) {
url += QLatin1Char('#');
- d->appendFragment(url, options);
+ d->appendFragment(url, options, QUrlPrivate::FullUrl);
}
return url;
@@ -3188,6 +3210,52 @@ QString QUrl::toDisplayString(FormattingOptions options) const
}
/*!
+ \since 5.2
+
+ Returns an adjusted version of the URL.
+ The output can be customized by passing flags with \a options.
+
+ The encoding options from QUrl::ComponentFormattingOption don't make
+ much sense for this method, nor does QUrl::PreferLocalFile.
+
+ This is always equivalent to QUrl(url.toString(options)).
+
+ \sa FormattingOptions, toEncoded(), toString()
+*/
+QUrl QUrl::adjusted(QUrl::FormattingOptions options) const
+{
+ if (!isValid()) {
+ // also catches isEmpty()
+ return QUrl();
+ }
+ QUrl that = *this;
+ if (options & RemoveScheme)
+ that.setScheme(QString());
+ if ((options & RemoveAuthority) == RemoveAuthority) {
+ that.setAuthority(QString());
+ } else {
+ if ((options & RemoveUserInfo) == RemoveUserInfo)
+ that.setUserInfo(QString());
+ else if (options & RemovePassword)
+ that.setPassword(QString());
+ if (options & RemovePort)
+ that.setPort(-1);
+ }
+ if (options & RemoveQuery)
+ that.setQuery(QString());
+ if (options & RemoveFragment)
+ that.setFragment(QString());
+ if (options & RemovePath) {
+ that.setPath(QString());
+ } else if (options & (StripTrailingSlash | RemoveFilename | NormalizePathSegments)) {
+ QString path;
+ d->appendPath(path, options, QUrlPrivate::Path);
+ that.setPath(path);
+ }
+ return that;
+}
+
+/*!
Returns the encoded representation of the URL if it's valid;
otherwise an empty QByteArray is returned. The output can be
customized by passing flags with \a options.
@@ -3296,7 +3364,7 @@ QString QUrl::fromEncodedComponent_helper(const QByteArray &ba)
*/
QString QUrl::fromAce(const QByteArray &domain)
{
- return qt_ACE_do(QString::fromLatin1(domain), NormalizeAce);
+ return qt_ACE_do(QString::fromLatin1(domain), NormalizeAce, ForbidLeadingDot /*FIXME: make configurable*/);
}
/*!
@@ -3317,7 +3385,7 @@ QString QUrl::fromAce(const QByteArray &domain)
*/
QByteArray QUrl::toAce(const QString &domain)
{
- QString result = qt_ACE_do(domain, ToAceOnly);
+ QString result = qt_ACE_do(domain, ToAceOnly, ForbidLeadingDot /*FIXME: make configurable*/);
return result.toLatin1();
}
@@ -3403,6 +3471,75 @@ bool QUrl::operator ==(const QUrl &url) const
}
/*!
+ \since 5.2
+
+ Returns true if this URL and the given \a url are equal after
+ applying \a options to both; otherwise returns false.
+
+ This is equivalent to calling adjusted(options) on both URLs
+ and comparing the resulting urls, but faster.
+
+*/
+bool QUrl::matches(const QUrl &url, FormattingOptions options) const
+{
+ if (!d && !url.d)
+ return true;
+ if (!d)
+ return url.d->isEmpty();
+ if (!url.d)
+ return d->isEmpty();
+
+ // Compare which sections are present, but ignore Host
+ // which is set by parsing but not by construction, when empty.
+ int mask = QUrlPrivate::FullUrl & ~QUrlPrivate::Host;
+
+ if (options & QUrl::RemoveScheme)
+ mask &= ~QUrlPrivate::Scheme;
+ else if (d->scheme != url.d->scheme)
+ return false;
+
+ if (options & QUrl::RemovePassword)
+ mask &= ~QUrlPrivate::Password;
+ else if (d->password != url.d->password)
+ return false;
+
+ if (options & QUrl::RemoveUserInfo)
+ mask &= ~QUrlPrivate::UserName;
+ else if (d->userName != url.d->userName)
+ return false;
+
+ if (options & QUrl::RemovePort)
+ mask &= ~QUrlPrivate::Port;
+ else if (d->port != url.d->port)
+ return false;
+
+ if (options & QUrl::RemoveAuthority)
+ mask &= ~QUrlPrivate::Host;
+ else if (d->host != url.d->host)
+ return false;
+
+ if (options & QUrl::RemoveQuery)
+ mask &= ~QUrlPrivate::Query;
+ else if (d->query != url.d->query)
+ return false;
+
+ if (options & QUrl::RemoveFragment)
+ mask &= ~QUrlPrivate::Fragment;
+ else if (d->fragment != url.d->fragment)
+ return false;
+
+ if (!(d->sectionIsPresent & mask) == (url.d->sectionIsPresent & mask))
+ return false;
+
+ // Compare paths, after applying path-related options
+ QString path1;
+ d->appendPath(path1, options, QUrlPrivate::Path);
+ QString path2;
+ url.d->appendPath(path2, options, QUrlPrivate::Path);
+ return path1 == path2;
+}
+
+/*!
Returns true if this URL and the given \a url are not equal;
otherwise returns false.
*/
@@ -3668,8 +3805,10 @@ static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &err
return QString(); // doesn't happen yet
case QUrlPrivate::InvalidIPv6AddressError:
return QStringLiteral("Invalid IPv6 address");
+ case QUrlPrivate::InvalidCharacterInIPv6Error:
+ return QStringLiteral("Invalid IPv6 address (character '%1' not permitted)").arg(c);
case QUrlPrivate::InvalidIPvFutureError:
- return QStringLiteral("Invalid IPvFuture address");
+ return QStringLiteral("Invalid IPvFuture address (character '%1' not permitted)").arg(c);
case QUrlPrivate::HostMissingEndBracket:
return QStringLiteral("Expected ']' to match '[' in hostname");
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index cf208bf71e..457440bb89 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -140,7 +140,9 @@ public:
RemoveFragment = 0x80,
// 0x100 was a private code in Qt 4, keep unused for a while
PreferLocalFile = 0x200,
- StripTrailingSlash = 0x400
+ StripTrailingSlash = 0x400,
+ RemoveFilename = 0x800,
+ NormalizePathSegments = 0x1000
};
enum ComponentFormattingOption {
@@ -185,6 +187,7 @@ public:
QString url(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
QString toString(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
QString toDisplayString(FormattingOptions options = FormattingOptions(PrettyDecoded)) const;
+ QUrl adjusted(FormattingOptions options) const;
QByteArray toEncoded(FormattingOptions options = FullyEncoded) const;
static QUrl fromEncoded(const QByteArray &url, ParsingMode mode = TolerantMode);
@@ -221,6 +224,7 @@ public:
void setPath(const QString &path, ParsingMode mode = TolerantMode);
QString path(ComponentFormattingOptions options = PrettyDecoded) const;
+ QString fileName(ComponentFormattingOptions options = PrettyDecoded) const;
bool hasQuery() const;
void setQuery(const QString &query, ParsingMode mode = TolerantMode);
@@ -247,6 +251,8 @@ public:
bool operator ==(const QUrl &url) const;
bool operator !=(const QUrl &url) const;
+ bool matches(const QUrl &url, FormattingOptions options) const;
+
static QString fromPercentEncoding(const QByteArray &);
static QByteArray toPercentEncoding(const QString &,
const QByteArray &exclude = QByteArray(),
diff --git a/src/corelib/io/qurl_p.h b/src/corelib/io/qurl_p.h
index a0c1882162..9c8fe1cfc6 100644
--- a/src/corelib/io/qurl_p.h
+++ b/src/corelib/io/qurl_p.h
@@ -63,8 +63,9 @@ extern Q_AUTOTEST_EXPORT int qt_urlRecode(QString &appendTo, const QChar *begin,
QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications = 0);
// in qurlidna.cpp
+enum AceLeadingDot { AllowLeadingDot, ForbidLeadingDot };
enum AceOperation { ToAceOnly, NormalizeAce };
-extern QString qt_ACE_do(const QString &domain, AceOperation op);
+extern QString qt_ACE_do(const QString &domain, AceOperation op, AceLeadingDot dot);
extern Q_AUTOTEST_EXPORT void qt_nameprep(QString *source, int from);
extern Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QChar *uc, int len);
extern Q_AUTOTEST_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString *output);
diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp
index 70db9e09eb..e959faccd2 100644
--- a/src/corelib/io/qurlidna.cpp
+++ b/src/corelib/io/qurlidna.cpp
@@ -2461,7 +2461,7 @@ static int nextDotDelimiter(const QString &domain, int from = 0)
return ch - b;
}
-QString qt_ACE_do(const QString &domain, AceOperation op)
+QString qt_ACE_do(const QString &domain, AceOperation op, AceLeadingDot dot)
{
if (domain.isEmpty())
return domain;
@@ -2479,7 +2479,8 @@ QString qt_ACE_do(const QString &domain, AceOperation op)
if (labelLength == 0) {
if (idx == domain.length())
break;
- return QString(); // two delimiters in a row -- empty label not allowed
+ if (dot == ForbidLeadingDot || idx > 0)
+ return QString(); // two delimiters in a row -- empty label not allowed
}
// RFC 3490 says, about the ToASCII operation:
diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp
index 547084840f..f6b5cd44bd 100644
--- a/src/corelib/io/qurlquery.cpp
+++ b/src/corelib/io/qurlquery.cpp
@@ -82,7 +82,7 @@ QT_BEGIN_NAMESPACE
All of the getter methods in QUrlQuery support an optional parameter of type
QUrl::ComponentFormattingOptions, including query(), which dictate how to
- encode the data in question. Regardless of the mode, the returned value must
+ encode the data in question. Except for QUrl::FullyDecoded, the returned value must
still be considered a percent-encoded string, as there are certain values
which cannot be expressed in decoded form (like control characters, byte
sequences not decodable to UTF-8). For that reason, the percent character is
@@ -104,6 +104,20 @@ QT_BEGIN_NAMESPACE
"+" sequences found in the keys, values, or query string are left exactly
like written (except for the uppercasing of "%2b" to "%2B").
+ \section2 Full decoding
+
+ With QUrl::FullyDecoded formatting, all percent-encoded sequences will be
+ decoded fully and the '%' character is used to represent itself.
+ QUrl::FullyDecoded should be used with care, since it may cause data loss.
+ See the documentation of QUrl::FullyDecoded for information on what data may
+ be lost.
+
+ This formatting mode should be used only when dealing with text presented to
+ the user in contexts where percent-encoding is not desired. Note that
+ QUrlQuery setters and query methods do not support the counterpart
+ QUrl::DecodedMode parsing, so using QUrl::FullyDecoded to obtain a listing of
+ keys may result in keys not found in the object.
+
\section1 Non-standard delimiters
By default, QUrlQuery uses an equal sign ("=") to separate a key from its
@@ -191,12 +205,9 @@ template<> void QSharedDataPointer<QUrlQueryPrivate>::detach()
// the getter methods, when called with the default encoding value, will not
// have to recode anything (except for toString()).
//
-// The "+" sub-delimiter is always left untouched. We never encode "+" to "%2B"
-// nor do we decode "%2B" to "+", no matter what the user asks.
-//
-// The rest of the delimiters are kept in their decoded forms and that's
-// considered non-ambiguous. That includes the pair and value delimiters
-// themselves.
+// QUrlQuery handling of delimiters is quite simple: we never touch any of
+// them, except for the "#" character and the pair and value delimiters. Those
+// are always kept in their decoded forms.
//
// But when recreating the query string, in toString(), we must take care of
// the special delimiters: the pair and value delimiters, as well as the "#"
@@ -205,12 +216,17 @@ template<> void QSharedDataPointer<QUrlQueryPrivate>::detach()
#define decode(x) ushort(x)
#define leave(x) ushort(0x100 | (x))
#define encode(x) ushort(0x200 | (x))
-static const ushort prettyDecodedActions[] = { leave('+'), 0 };
inline QString QUrlQueryPrivate::recodeFromUser(const QString &input) const
{
// note: duplicated in setQuery()
QString output;
+ ushort prettyDecodedActions[] = {
+ decode(pairDelimiter.unicode()),
+ decode(valueDelimiter.unicode()),
+ decode('#'),
+ 0
+ };
if (qt_urlRecode(output, input.constData(), input.constData() + input.length(),
QUrl::DecodeReserved,
prettyDecodedActions))
@@ -233,7 +249,7 @@ inline QString QUrlQueryPrivate::recodeToUser(const QString &input, QUrl::Compon
if (!(encoding & QUrl::EncodeDelimiters)) {
QString output;
if (qt_urlRecode(output, input.constData(), input.constData() + input.length(),
- encoding, prettyDecodedActions))
+ encoding, 0))
return output;
return input;
}
@@ -249,6 +265,13 @@ inline QString QUrlQueryPrivate::recodeToUser(const QString &input, QUrl::Compon
void QUrlQueryPrivate::setQuery(const QString &query)
{
+ ushort prettyDecodedActions[] = {
+ decode(pairDelimiter.unicode()),
+ decode(valueDelimiter.unicode()),
+ decode('#'),
+ 0
+ };
+
itemList.clear();
const QChar *pos = query.constData();
const QChar *const end = pos + query.size();
@@ -461,24 +484,18 @@ QString QUrlQuery::query(QUrl::ComponentFormattingOptions encoding) const
return QString();
// unlike the component encoding, for the whole query we need to modify a little:
- // - the "#" character is ambiguous, so we decode it only in DecodeAllDelimiters mode
+ // - the "#" character is unambiguous, so we encode it in EncodeDelimiters mode
// - the query delimiter pair must always be encoded
- // - the non-delimiters vary on DecodeUnambiguousDelimiters
- // so:
- // - full encoding: encode the non-delimiters, the pair, "#", "[" and "]"
- // - pretty decode: decode the non-delimiters, "[" and "]"; encode the pair and "#"
- // - decode all: decode the non-delimiters, "[", "]", "#"; encode the pair
// start with what's always encoded
ushort tableActions[] = {
- leave('+'), // 0
- encode(d->pairDelimiter.unicode()), // 1
- encode(d->valueDelimiter.unicode()), // 2
- decode('#'), // 3
+ encode(d->pairDelimiter.unicode()), // 0
+ encode(d->valueDelimiter.unicode()), // 1
+ 0, // 2
0
};
if (encoding & QUrl::EncodeDelimiters) {
- tableActions[3] = encode('#');
+ tableActions[2] = encode('#');
}
QString result;
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index 5ff0c40a4f..7e77b9c251 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -113,59 +113,6 @@ static const uchar defaultActionTable[96] = {
// 0x00 if it belongs to this category
// 0xff if it doesn't
-static const uchar delimsMask[96] = {
- 0xff, // space
- 0x00, // '!' (sub-delim)
- 0xff, // '"'
- 0x00, // '#' (gen-delim)
- 0x00, // '$' (gen-delim)
- 0xff, // '%' (percent)
- 0x00, // '&' (gen-delim)
- 0x00, // "'" (sub-delim)
- 0x00, // '(' (sub-delim)
- 0x00, // ')' (sub-delim)
- 0x00, // '*' (sub-delim)
- 0x00, // '+' (sub-delim)
- 0x00, // ',' (sub-delim)
- 0xff, // '-' (unreserved)
- 0xff, // '.' (unreserved)
- 0x00, // '/' (gen-delim)
-
- 0xff, 0xff, 0xff, 0xff, 0xff, // '0' to '4' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // '5' to '9' (unreserved)
- 0x00, // ':' (gen-delim)
- 0x00, // ';' (sub-delim)
- 0xff, // '<'
- 0x00, // '=' (sub-delim)
- 0xff, // '>'
- 0x00, // '?' (gen-delim)
-
- 0x00, // '@' (gen-delim)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'A' to 'E' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'F' to 'J' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'K' to 'O' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'P' to 'T' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'U' to 'Z' (unreserved)
- 0x00, // '[' (gen-delim)
- 0xff, // '\'
- 0x00, // ']' (gen-delim)
- 0xff, // '^'
- 0xff, // '_' (unreserved)
-
- 0xff, // '`'
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'a' to 'e' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'f' to 'j' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'k' to 'o' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, // 'p' to 't' (unreserved)
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'u' to 'z' (unreserved)
- 0xff, // '{'
- 0xff, // '|'
- 0xff, // '}'
- 0xff, // '~' (unreserved)
-
- 0xff // BSKP
-};
-
static const uchar reservedMask[96] = {
0xff, // space
0xff, // '!' (sub-delim)
@@ -560,6 +507,27 @@ non_trivial:
return 0;
}
+/*!
+ \since 5.0
+ \internal
+
+ This function decodes a percent-encoded string located from \a begin to \a
+ end, by appending each character to \a appendTo. It returns the number of
+ characters appended. Each percent-encoded sequence is decoded as follows:
+
+ \list
+ \li from %00 to %7F: the exact decoded value is appended;
+ \li from %80 to %FF: QChar::ReplacementCharacter is appended;
+ \li bad encoding: original input is copied to the output, undecoded.
+ \endlist
+
+ Given the above, it's important for the input to already have all UTF-8
+ percent sequences decoded by qt_urlRecode (that is, the input should not
+ have been processed with QUrl::EncodeUnicode).
+
+ The input should also be a valid percent-encoded sequence (the output of
+ qt_urlRecode is always valid).
+*/
static int decode(QString &appendTo, const ushort *begin, const ushort *end)
{
const int origSize = appendTo.size();
@@ -573,6 +541,13 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end)
continue;
}
+ if (Q_UNLIKELY(end - input < 3 || !isHex(input[1]) || !isHex(input[2]))) {
+ // badly-encoded data
+ appendTo.resize(origSize + (end - begin));
+ memcpy(appendTo.begin() + origSize, begin, (end - begin) * sizeof(ushort));
+ return end - begin;
+ }
+
if (Q_UNLIKELY(!output)) {
// detach
appendTo.resize(origSize + (end - begin));
@@ -582,10 +557,9 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end)
}
++input;
- Q_ASSERT(input <= end - 2); // we need two characters
- Q_ASSERT(isHex(input[0]));
- Q_ASSERT(isHex(input[1]));
*output++ = decodeNibble(input[0]) << 4 | decodeNibble(input[1]);
+ if (output[-1] >= 0x80)
+ output[-1] = QChar::ReplacementCharacter;
input += 2;
}
@@ -613,8 +587,6 @@ static void maskTable(uchar (&table)[N], const uchar (&mask)[N])
The \a encoding option modifies the default behaviour:
\list
- \li QUrl::EncodeDelimiters: if set, delimiters will be left untransformed (note: not encoded!);
- if unset, delimiters will be decoded
\li QUrl::DecodeReserved: if set, reserved characters will be decoded;
if unset, reserved characters will be encoded
\li QUrl::EncodeSpaces: if set, spaces will be encoded to "%20"; if unset, they will be " "
@@ -635,6 +607,9 @@ static void maskTable(uchar (&table)[N], const uchar (&mask)[N])
handled. It consists of a sequence of 16-bit values, where the low 8 bits
indicate the character in question and the high 8 bits are either \c
EncodeCharacter, \c LeaveCharacter or \c DecodeCharacter.
+
+ This function corrects percent-encoded errors by interpreting every '%' as
+ meaning "%25" (all percents in the same content).
*/
Q_AUTOTEST_EXPORT int
@@ -646,24 +621,11 @@ qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end,
return decode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end));
}
- if (!(encoding & QUrl::EncodeDelimiters) && encoding & QUrl::DecodeReserved) {
- // reset the table
- memset(actionTable, DecodeCharacter, sizeof actionTable);
- if (encoding & QUrl::EncodeSpaces)
- actionTable[0] = EncodeCharacter;
-
- // these are always encoded
- actionTable['%' - ' '] = EncodeCharacter;
- actionTable[0x7F - ' '] = EncodeCharacter;
- } else {
- memcpy(actionTable, defaultActionTable, sizeof actionTable);
- if (!(encoding & QUrl::EncodeDelimiters))
- maskTable(actionTable, delimsMask);
- if (encoding & QUrl::DecodeReserved)
- maskTable(actionTable, reservedMask);
- if (!(encoding & QUrl::EncodeSpaces))
- actionTable[0] = DecodeCharacter; // decode
- }
+ memcpy(actionTable, defaultActionTable, sizeof actionTable);
+ if (encoding & QUrl::DecodeReserved)
+ maskTable(actionTable, reservedMask);
+ if (!(encoding & QUrl::EncodeSpaces))
+ actionTable[0] = DecodeCharacter; // decode
if (tableModifications) {
for (const ushort *p = tableModifications; *p; ++p)
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index 4162e843a7..9791a02723 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -160,8 +160,8 @@ QPersistentModelIndex::~QPersistentModelIndex()
}
/*!
- Returns true if this persistent model index is equal to the \a other
- persistent model index; otherwise returns false.
+ Returns \c{true} if this persistent model index is equal to the \a other
+ persistent model index; otherwise returns \c{false}.
All values in the persistent model index are used when comparing
with another persistent model index.
@@ -177,8 +177,8 @@ bool QPersistentModelIndex::operator==(const QPersistentModelIndex &other) const
/*!
\since 4.1
- Returns true if this persistent model index is smaller than the \a other
- persistent model index; otherwise returns false.
+ Returns \c{true} if this persistent model index is smaller than the \a other
+ persistent model index; otherwise returns \c{false}.
All values in the persistent model index are used when comparing
with another persistent model index.
@@ -196,8 +196,8 @@ bool QPersistentModelIndex::operator<(const QPersistentModelIndex &other) const
\fn bool QPersistentModelIndex::operator!=(const QPersistentModelIndex &other) const
\since 4.2
- Returns true if this persistent model index is not equal to the \a
- other persistent model index; otherwise returns false.
+ Returns \c{true} if this persistent model index is not equal to the \a
+ other persistent model index; otherwise returns \c{false}.
*/
/*!
@@ -258,8 +258,8 @@ QPersistentModelIndex::operator const QModelIndex&() const
/*!
\fn bool QPersistentModelIndex::operator==(const QModelIndex &other) const
- Returns true if this persistent model index refers to the same location as
- the \a other model index; otherwise returns false.
+ Returns \c{true} if this persistent model index refers to the same location as
+ the \a other model index; otherwise returns \c{false}.
All values in the persistent model index are used when comparing with
another model index.
@@ -275,8 +275,8 @@ bool QPersistentModelIndex::operator==(const QModelIndex &other) const
/*!
\fn bool QPersistentModelIndex::operator!=(const QModelIndex &other) const
- Returns true if this persistent model index does not refer to the same
- location as the \a other model index; otherwise returns false.
+ Returns \c{true} if this persistent model index does not refer to the same
+ location as the \a other model index; otherwise returns \c{false}.
*/
bool QPersistentModelIndex::operator!=(const QModelIndex &other) const
@@ -423,8 +423,8 @@ const QAbstractItemModel *QPersistentModelIndex::model() const
/*!
\fn bool QPersistentModelIndex::isValid() const
- Returns true if this persistent model index is valid; otherwise returns
- false.
+ Returns \c{true} if this persistent model index is valid; otherwise returns
+ \c{false}.
A valid index belongs to a model, and has non-negative row and column
numbers.
@@ -522,7 +522,7 @@ static uint typeOfVariant(const QVariant &value)
/*!
\internal
- return true if \a value contains a numerical type
+ Return \c{true} if \a value contains a numerical type.
This function is used by our Q{Tree,Widget,Table}WidgetModel classes to sort.
*/
@@ -984,7 +984,7 @@ void QAbstractItemModel::resetInternalData()
/*!
\fn bool QModelIndex::isValid() const
- Returns true if this model index is valid; otherwise returns false.
+ Returns \c{true} if this model index is valid; otherwise returns \c{false}.
A valid index belongs to a model, and has non-negative row and column
numbers.
@@ -1041,8 +1041,8 @@ void QAbstractItemModel::resetInternalData()
/*!
\fn bool QModelIndex::operator==(const QModelIndex &other) const
- Returns true if this model index refers to the same location as the
- \a other model index; otherwise returns false.
+ Returns \c{true} if this model index refers to the same location as the
+ \a other model index; otherwise returns \c{false}.
All values in the model index are used when comparing with another model
index.
@@ -1052,8 +1052,8 @@ void QAbstractItemModel::resetInternalData()
/*!
\fn bool QModelIndex::operator!=(const QModelIndex &other) const
- Returns true if this model index does not refer to the same location as
- the \a other model index; otherwise returns false.
+ Returns \c{true} if this model index does not refer to the same location as
+ the \a other model index; otherwise returns \c{false}.
*/
@@ -1113,7 +1113,7 @@ void QAbstractItemModel::resetInternalData()
Items can be queried with flags() (see \l Qt::ItemFlag) to see if they can
be selected, dragged, or manipulated in other ways.
- If an item has child objects, hasChildren() returns true for the
+ If an item has child objects, hasChildren() returns \c{true} for the
corresponding index.
The model has a rowCount() and a columnCount() for each level of the
@@ -1236,7 +1236,7 @@ void QAbstractItemModel::resetInternalData()
Inserts a single column before the given \a column in the child items of
the \a parent specified.
- Returns true if the column is inserted; otherwise returns false.
+ Returns \c{true} if the column is inserted; otherwise returns \c{false}.
\sa insertColumns(), insertRow(), removeColumn()
*/
@@ -1249,7 +1249,7 @@ void QAbstractItemModel::resetInternalData()
\note This function calls the virtual method insertRows.
- Returns true if the row is inserted; otherwise returns false.
+ Returns \c{true} if the row is inserted; otherwise returns \c{false}.
\sa insertRows(), insertColumn(), removeRow()
*/
@@ -1284,7 +1284,7 @@ void QAbstractItemModel::resetInternalData()
Removes the given \a column from the child items of the \a parent
specified.
- Returns true if the column is removed; otherwise returns false.
+ Returns \c{true} if the column is removed; otherwise returns \c{false}.
\sa removeColumns(), removeRow(), insertColumn()
*/
@@ -1294,7 +1294,7 @@ void QAbstractItemModel::resetInternalData()
Removes the given \a row from the child items of the \a parent specified.
- Returns true if the row is removed; otherwise returns false.
+ Returns \c{true} if the row is removed; otherwise returns \c{false}.
This is a convenience function that calls removeRows(). The
QAbstractItemModel implementation of removeRows() does nothing.
@@ -1308,8 +1308,8 @@ void QAbstractItemModel::resetInternalData()
On models that support this, moves \a sourceColumn from \a sourceParent to \a destinationChild under
\a destinationParent.
- Returns true if the columns were successfully moved; otherwise returns
- false.
+ Returns \c{true} if the columns were successfully moved; otherwise returns
+ \c{false}.
\sa moveRows(), moveColumn()
*/
@@ -1320,8 +1320,8 @@ void QAbstractItemModel::resetInternalData()
On models that support this, moves \a sourceColumn from \a sourceParent to \a destinationChild under
\a destinationParent.
- Returns true if the columns were successfully moved; otherwise returns
- false.
+ Returns \c{true} if the columns were successfully moved; otherwise returns
+ \c{false}.
\sa moveColumns(), moveRow()
*/
@@ -1663,8 +1663,8 @@ QAbstractItemModel::~QAbstractItemModel()
*/
/*!
- Returns true if the model returns a valid QModelIndex for \a row and
- \a column with \a parent, otherwise returns false.
+ Returns \c{true} if the model returns a valid QModelIndex for \a row and
+ \a column with \a parent, otherwise returns \c{false}.
*/
bool QAbstractItemModel::hasIndex(int row, int column, const QModelIndex &parent) const
{
@@ -1675,7 +1675,7 @@ bool QAbstractItemModel::hasIndex(int row, int column, const QModelIndex &parent
/*!
- Returns true if \a parent has any children; otherwise returns false.
+ Returns \c{true} if \a parent has any children; otherwise returns \c{false}.
Use rowCount() on the parent to find out the number of children.
@@ -1732,12 +1732,12 @@ QMap<int, QVariant> QAbstractItemModel::itemData(const QModelIndex &index) const
/*!
Sets the \a role data for the item at \a index to \a value.
- Returns true if successful; otherwise returns false.
+ Returns \c{true} if successful; otherwise returns \c{false}.
The dataChanged() signal should be emitted if the data was successfully
set.
- The base class implementation returns false. This function and data() must
+ The base class implementation returns \c{false}. This function and data() must
be reimplemented for editable models.
\sa Qt::ItemDataRole, data(), itemData()
@@ -1766,7 +1766,7 @@ bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value
Sets the role data for the item at \a index to the associated value in
\a roles, for every Qt::ItemDataRole.
- Returns true if successful; otherwise returns false.
+ Returns \c{true} if successful; otherwise returns \c{false}.
Roles that are not in \a roles will not be modified.
@@ -1781,10 +1781,19 @@ bool QAbstractItemModel::setItemData(const QModelIndex &index, const QMap<int, Q
}
/*!
- Returns a list of MIME types that can be used to describe a list of model
- indexes.
+ Returns the list of allowed MIME types. By default, the built-in
+ models and views use an internal MIME type:
+ \c{application/x-qabstractitemmodeldatalist}.
- \sa mimeData()
+ When implementing drag and drop support in a custom model, if you
+ will return data in formats other than the default internal MIME
+ type, reimplement this function to return your list of MIME types.
+
+ If you reimplement this function in your custom model, you must
+ also reimplement the member functions that call it: mimeData() and
+ dropMimeData().
+
+ \sa mimeData(), dropMimeData()
*/
QStringList QAbstractItemModel::mimeTypes() const
{
@@ -1795,11 +1804,14 @@ QStringList QAbstractItemModel::mimeTypes() const
/*!
Returns an object that contains serialized items of data corresponding to
- the list of \a indexes specified. The formats used to describe the encoded
- data is obtained from the mimeTypes() function.
+ the list of \a indexes specified. The format used to describe the encoded
+ data is obtained from the mimeTypes() function. This default implementation
+ uses the default MIME type returned by the default implementation of
+ mimeTypes(). If you reimplement mimeTypes() in your custom model to return
+ more MIME types, reimplement this function to make use of them.
- If the list of indexes is empty, or there are no supported MIME types, 0 is
- returned rather than a serialized empty list.
+ If the list of \a indexes is empty, or there are no supported MIME types, 0
+ is returned rather than a serialized empty list.
\sa mimeTypes(), dropMimeData()
*/
@@ -1820,13 +1832,13 @@ QMimeData *QAbstractItemModel::mimeData(const QModelIndexList &indexes) const
}
/*!
- Returns whether a model can accept a drop of data.
+ Returns \c{true} if a model can accept a drop of the \a data. This
+ default implementation always returns \c{true}.
- This can be used to indicate whether a drop of certain data is allowed, for example
- by using a 'forbidden' emblem on a mouse cursor during a drag operation.
-
- This method returns true by default. Reimplementations can return whether the
- \a data can be dropped at \a row, \a column, \a parent with \a action.
+ Reimplement this function in your custom model, if you want to
+ test whether the \a data can be dropped at \a row, \a column,
+ \a parent with \a action. If you don't need that test, it is not
+ necessary to reimplement this function.
\sa dropMimeData(), {Using drag and drop with item views}
*/
@@ -1846,8 +1858,8 @@ bool QAbstractItemModel::canDropMimeData(const QMimeData *data, Qt::DropAction a
Handles the \a data supplied by a drag and drop operation that ended with
the given \a action.
- Returns true if the data and action can be handled by the model; otherwise
- returns false.
+ Returns \c{true} if the data and action were handled by the model; otherwise
+ returns \c{false}.
The specified \a row, \a column and \a parent indicate the location of an
item in the model where the operation ended. It is the responsibility of
@@ -1859,10 +1871,16 @@ bool QAbstractItemModel::canDropMimeData(const QMimeData *data, Qt::DropAction a
When \a row and \a column are -1 it means that the dropped data should be
considered as dropped directly on \a parent. Usually this will mean
- appending the data as child items of \a parent. If \a row and column are
+ appending the data as child items of \a parent. If \a row and \a column are
greater than or equal zero, it means that the drop occurred just before the
specified \a row and \a column in the specified \a parent.
+ The mimeTypes() member is called to get the list of acceptable MIME types.
+ This default implementation assumes the default implementation of mimeTypes(),
+ which returns a single default MIME type. If you reimplement mimeTypes() in
+ your custom model to return multiple MIME types, you must reimplement this
+ function to make use of them.
+
\sa supportedDropActions(), canDropMimeData(), {Using drag and drop with item views}
*/
bool QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
@@ -1950,7 +1968,7 @@ void QAbstractItemModel::doSetSupportedDragActions(Qt::DropActions actions)
/*!
\note The base class implementation of this function does nothing and
- returns false.
+ returns \c{false}.
On models that support this, inserts \a count rows into the model before
the given \a row. Items in the new row will be children of the item
@@ -1964,8 +1982,8 @@ void QAbstractItemModel::doSetSupportedDragActions(Qt::DropActions actions)
If \a parent has no children, a single column with \a count rows is
inserted.
- Returns true if the rows were successfully inserted; otherwise returns
- false.
+ Returns \c{true} if the rows were successfully inserted; otherwise returns
+ \c{false}.
If you implement your own model, you can reimplement this function if you
want to support insertions. Alternatively, you can provide your own API for
@@ -1993,10 +2011,10 @@ bool QAbstractItemModel::insertRows(int, int, const QModelIndex &)
If \a parent has no children, a single row with \a count columns is
inserted.
- Returns true if the columns were successfully inserted; otherwise returns
- false.
+ Returns \c{true} if the columns were successfully inserted; otherwise returns
+ \c{false}.
- The base class implementation does nothing and returns false.
+ The base class implementation does nothing and returns \c{false}.
If you implement your own model, you can reimplement this function if you
want to support insertions. Alternatively, you can provide your own API for
@@ -2013,10 +2031,10 @@ bool QAbstractItemModel::insertColumns(int, int, const QModelIndex &)
On models that support this, removes \a count rows starting with the given
\a row under parent \a parent from the model.
- Returns true if the rows were successfully removed; otherwise returns
- false.
+ Returns \c{true} if the rows were successfully removed; otherwise returns
+ \c{false}.
- The base class implementation does nothing and returns false.
+ The base class implementation does nothing and returns \c{false}.
If you implement your own model, you can reimplement this function if you
want to support removing. Alternatively, you can provide your own API for
@@ -2034,10 +2052,10 @@ bool QAbstractItemModel::removeRows(int, int, const QModelIndex &)
On models that support this, removes \a count columns starting with the
given \a column under parent \a parent from the model.
- Returns true if the columns were successfully removed; otherwise returns
- false.
+ Returns \c{true} if the columns were successfully removed; otherwise returns
+ \c{false}.
- The base class implementation does nothing and returns false.
+ The base class implementation does nothing and returns \c{false}.
If you implement your own model, you can reimplement this function if you
want to support removing. Alternatively, you can provide your own API for
@@ -2056,10 +2074,10 @@ bool QAbstractItemModel::removeColumns(int, int, const QModelIndex &)
\a sourceRow under parent \a sourceParent to row \a destinationChild under
parent \a destinationParent.
- Returns true if the rows were successfully moved; otherwise returns
- false.
+ Returns \c{true} if the rows were successfully moved; otherwise returns
+ \c{false}.
- The base class implementation does nothing and returns false.
+ The base class implementation does nothing and returns \c{false}.
If you implement your own model, you can reimplement this function if you
want to support moving. Alternatively, you can provide your own API for
@@ -2077,10 +2095,10 @@ bool QAbstractItemModel::moveRows(const QModelIndex &, int , int , const QModelI
\a sourceColumn under parent \a sourceParent to column \a destinationChild under
parent \a destinationParent.
- Returns true if the columns were successfully moved; otherwise returns
- false.
+ Returns \c{true} if the columns were successfully moved; otherwise returns
+ \c{false}.
- The base class implementation does nothing and returns false.
+ The base class implementation does nothing and returns \c{false}.
If you implement your own model, you can reimplement this function if you
want to support moving. Alternatively, you can provide your own API for
@@ -2109,10 +2127,10 @@ void QAbstractItemModel::fetchMore(const QModelIndex &)
}
/*!
- Returns true if there is more data available for \a parent; otherwise
- returns false.
+ Returns \c{true} if there is more data available for \a parent; otherwise
+ returns \c{false}.
- The default implementation always returns false.
+ The default implementation always returns \c{false}.
If canFetchMore() returns true, the fetchMore() function should
be called. This is the behavior of QAbstractItemView, for example.
@@ -2310,7 +2328,7 @@ QHash<int,QByteArray> QAbstractItemModel::roleNames() const
Lets the model know that it should submit cached information to permanent
storage. This function is typically used for row editing.
- Returns true if there is no error; otherwise returns false.
+ Returns \c{true} if there is no error; otherwise returns \c{false}.
\sa revert()
*/
@@ -2355,7 +2373,7 @@ QVariant QAbstractItemModel::headerData(int section, Qt::Orientation orientation
Sets the data for the given \a role and \a section in the header with the
specified \a orientation to the \a value supplied.
- Returns true if the header's data was updated; otherwise returns false.
+ Returns \c{true} if the header's data was updated; otherwise returns \c{false}.
When reimplementing this function, the headerDataChanged() signal must be
emitted explicitly.
@@ -2682,7 +2700,7 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
you must ensure that the \a destinationChild is not within the range
of \a sourceFirst and \a sourceLast + 1. You must also ensure that you
do not attempt to move a row to one of its own children or ancestors.
- This method returns false if either condition is true, in which case you
+ This method returns \c{false} if either condition is true, in which case you
should abort your move operation.
\table 80%
@@ -2949,7 +2967,7 @@ void QAbstractItemModel::endRemoveColumns()
you must ensure that the \a destinationChild is not within the range
of \a sourceFirst and \a sourceLast + 1. You must also ensure that you
do not attempt to move a column to one of its own children or ancestors.
- This method returns false if either condition is true, in which case you
+ This method returns \c{false} if either condition is true, in which case you
should abort your move operation.
\sa endMoveColumns()
@@ -3596,8 +3614,8 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti
\fn bool QModelIndex::operator<(const QModelIndex &other) const
\since 4.1
- Returns true if this model index is smaller than the \a other
- model index; otherwise returns false.
+ Returns \c{true} if this model index is smaller than the \a other
+ model index; otherwise returns \c{false}.
The less than calculation is not directly useful to developers - the way that indexes
with different parents compare is not defined. This operator only exists so that the
diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h
index f3bf2c1019..ac98476492 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.h
+++ b/src/corelib/itemmodels/qabstractitemmodel.h
@@ -113,6 +113,11 @@ public:
inline bool operator!=(const QPersistentModelIndex &other) const
{ return !operator==(other); }
QPersistentModelIndex &operator=(const QPersistentModelIndex &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QPersistentModelIndex(QPersistentModelIndex &&other) : d(other.d) { other.d = 0; }
+ inline QPersistentModelIndex &operator=(QPersistentModelIndex &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
inline void swap(QPersistentModelIndex &other) { qSwap(d, other.d); }
bool operator==(const QModelIndex &other) const;
bool operator!=(const QModelIndex &other) const;
diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h
index 06885ad972..7d0162938d 100644
--- a/src/corelib/json/qjson_p.h
+++ b/src/corelib/json/qjson_p.h
@@ -60,8 +60,10 @@
#include <qatomic.h>
#include <qstring.h>
#include <qendian.h>
+#include <qnumeric.h>
#include <limits.h>
+#include <limits>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp
index 3fbc811948..3aba6124b8 100644
--- a/src/corelib/json/qjsonvalue.cpp
+++ b/src/corelib/json/qjsonvalue.cpp
@@ -156,6 +156,18 @@ QJsonValue::QJsonValue(int n)
}
/*!
+ \overload
+ Creates a value of type Double, with value \a n.
+ NOTE: the integer limits for IEEE 754 double precision data is 2^53 (-9007199254740992 to +9007199254740992).
+ If you pass in values outside this range expect a loss of precision to occur.
+ */
+QJsonValue::QJsonValue(qint64 n)
+ : d(0), t(Double)
+{
+ this->dbl = n;
+}
+
+/*!
Creates a value of type String, with value \a s.
*/
QJsonValue::QJsonValue(const QString &s)
diff --git a/src/corelib/json/qjsonvalue.h b/src/corelib/json/qjsonvalue.h
index b8bdf55aa3..c8efab5d5f 100644
--- a/src/corelib/json/qjsonvalue.h
+++ b/src/corelib/json/qjsonvalue.h
@@ -79,6 +79,7 @@ public:
QJsonValue(bool b);
QJsonValue(double n);
QJsonValue(int n);
+ QJsonValue(qint64 n);
QJsonValue(const QString &s);
QJsonValue(QLatin1String s);
QJsonValue(const QJsonArray &a);
diff --git a/src/corelib/json/qjsonwriter.cpp b/src/corelib/json/qjsonwriter.cpp
index 3ac16c6fd1..8426b351f6 100644
--- a/src/corelib/json/qjsonwriter.cpp
+++ b/src/corelib/json/qjsonwriter.cpp
@@ -169,9 +169,14 @@ static void valueToJson(const QJsonPrivate::Base *b, const QJsonPrivate::Value &
case QJsonValue::Bool:
json += v.toBoolean() ? "true" : "false";
break;
- case QJsonValue::Double:
- json += QByteArray::number(v.toDouble(b), 'g', 17);
+ 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
+ else
+ json += "null"; // +INF || -INF || NaN (see RFC4627#section2.4)
break;
+ }
case QJsonValue::String:
json += '"';
json += escapedString(v.toString(b));
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index f0899c6dee..fa911fb967 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -75,6 +75,12 @@
#include "qstring.h"
+#if defined( __OBJC__) && defined(QT_NAMESPACE)
+#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__) @compatibility_alias __KLASS__ QT_MANGLE_NAMESPACE(__KLASS__)
+#else
+#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__)
+#endif
+
QT_BEGIN_NAMESPACE
/*
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index a7b14b22b5..3460b9e228 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -1950,7 +1950,6 @@ QString QCoreApplication::applicationFilePath()
char buff[maximum_path+1];
if (_cmdname(buff)) {
d->cachedApplicationFilePath = QDir::cleanPath(QString::fromLocal8Bit(buff));
- return d->cachedApplicationFilePath;
} else {
qWarning("QCoreApplication::applicationFilePath: _cmdname() failed");
// _cmdname() won't fail, but just in case, fallback to the old method
@@ -1959,11 +1958,11 @@ QString QCoreApplication::applicationFilePath()
if (!executables.empty()) {
//We assume that there is only one executable in the folder
d->cachedApplicationFilePath = dir.absoluteFilePath(executables.first());
- return d->cachedApplicationFilePath;
} else {
- return QString();
+ d->cachedApplicationFilePath = QString();
}
}
+ return d->cachedApplicationFilePath;
#elif defined(Q_OS_MAC)
QString qAppFileName_str = qAppFileName();
if(!qAppFileName_str.isEmpty()) {
@@ -1982,34 +1981,38 @@ QString QCoreApplication::applicationFilePath()
return d->cachedApplicationFilePath;
}
# endif
+ if (!arguments().isEmpty()) {
+ QString argv0 = QFile::decodeName(arguments().at(0).toLocal8Bit());
+ QString absPath;
+
+ if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
+ /*
+ If argv0 starts with a slash, it is already an absolute
+ file path.
+ */
+ absPath = argv0;
+ } else if (argv0.contains(QLatin1Char('/'))) {
+ /*
+ If argv0 contains one or more slashes, it is a file path
+ relative to the current directory.
+ */
+ absPath = QDir::current().absoluteFilePath(argv0);
+ } else {
+ /*
+ Otherwise, the file path has to be determined using the
+ PATH environment variable.
+ */
+ absPath = QStandardPaths::findExecutable(argv0);
+ }
+
+ absPath = QDir::cleanPath(absPath);
- QString argv0 = QFile::decodeName(arguments().at(0).toLocal8Bit());
- QString absPath;
-
- if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
- /*
- If argv0 starts with a slash, it is already an absolute
- file path.
- */
- absPath = argv0;
- } else if (argv0.contains(QLatin1Char('/'))) {
- /*
- If argv0 contains one or more slashes, it is a file path
- relative to the current directory.
- */
- absPath = QDir::current().absoluteFilePath(argv0);
+ QFileInfo fi(absPath);
+ d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
} else {
- /*
- Otherwise, the file path has to be determined using the
- PATH environment variable.
- */
- absPath = QStandardPaths::findExecutable(argv0);
+ d->cachedApplicationFilePath = QString();
}
- absPath = QDir::cleanPath(absPath);
-
- QFileInfo fi(absPath);
- d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
return d->cachedApplicationFilePath;
#endif
}
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry.cpp b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
index f90f2e3268..d9e38b68b2 100644
--- a/src/corelib/kernel/qeventdispatcher_blackberry.cpp
+++ b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
@@ -128,16 +128,16 @@ static int bpsIOHandler(int fd, int io_events, void *data)
// create unblock event
bps_event_t *event;
int result = bps_event_create(&event, bpsUnblockDomain, 0, NULL, NULL);
- if (result != BPS_SUCCESS) {
- qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_event_create() failed");
+ 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 (result != BPS_SUCCESS) {
- qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_push_event() failed");
+ if (Q_UNLIKELY(result != BPS_SUCCESS)) {
+ qWarning("QEventDispatcherBlackberry: bps_push_event failed");
bps_event_destroy(event);
return BPS_FAILURE;
}
@@ -151,16 +151,16 @@ QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate()
{
// prepare to use BPS
int result = bps_initialize();
- if (result != BPS_SUCCESS)
- qFatal("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_initialize() failed");
+ if (Q_UNLIKELY(result != BPS_SUCCESS))
+ qFatal("QEventDispatcherBlackberry: bps_initialize failed");
bps_channel = bps_channel_get_active();
// get domain for IO ready and wake up events - ignoring race condition here for now
if (bpsUnblockDomain == -1) {
bpsUnblockDomain = bps_register_domain();
- if (bpsUnblockDomain == -1)
- qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_register_domain() failed");
+ if (Q_UNLIKELY(bpsUnblockDomain == -1))
+ qWarning("QEventDispatcherBlackberry: bps_register_domain failed");
}
}
@@ -202,21 +202,26 @@ void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifie
Q_ASSERT(notifier);
Q_D(QEventDispatcherBlackberry);
- BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
-
- // Register the fd with bps
int sockfd = notifier->socket();
int type = notifier->type();
- qEventDispatcherDebug << Q_FUNC_INFO << "fd =" << sockfd;
- int io_events = ioEvents(sockfd);
+ qEventDispatcherDebug << Q_FUNC_INFO << "fd =" << sockfd;
- if (io_events)
- bps_remove_fd(sockfd);
+ if (Q_UNLIKELY(sockfd >= FD_SETSIZE)) {
+ qWarning() << "QEventDispatcherBlackberry: cannot register QSocketNotifier (fd too high)"
+ << sockfd;
+ return;
+ }
// Call the base Unix implementation. Needed to allow select() to be called correctly
QEventDispatcherUNIX::registerSocketNotifier(notifier);
+ // 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";
@@ -233,44 +238,41 @@ void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifie
break;
}
- errno = 0;
- int result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data());
-
- if (result != BPS_SUCCESS)
- qWarning() << Q_FUNC_INFO << "bps_add_fd() failed" << strerror(errno) << "code:" << errno;
+ 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";
}
void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier *notifier)
{
Q_D(QEventDispatcherBlackberry);
- BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
+ int sockfd = notifier->socket();
+
+ qEventDispatcherDebug << Q_FUNC_INFO << "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
QEventDispatcherUNIX::unregisterSocketNotifier(notifier);
// Unregister the fd with bps
- int sockfd = notifier->socket();
- qEventDispatcherDebug << Q_FUNC_INFO << "fd =" << sockfd;
-
+ BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
const int io_events = ioEvents(sockfd);
-
int result = bps_remove_fd(sockfd);
- if (result != BPS_SUCCESS)
- qWarning() << Q_FUNC_INFO << "bps_remove_fd() failed" << sockfd;
-
+ if (Q_UNLIKELY(result != BPS_SUCCESS))
+ qWarning() << "QEventDispatcherBlackberry: bps_remove_fd failed" << sockfd;
- /* if no other socket notifier is
- * watching sockfd, our job ends here
- */
+ // if no other socket notifier is watching sockfd, our job ends here
if (!io_events)
return;
- errno = 0;
result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data());
- if (result != BPS_SUCCESS) {
- qWarning() << Q_FUNC_INFO << "bps_add_fd() failed" << strerror(errno) << "code:" << errno;
- }
+ if (Q_UNLIKELY(result != BPS_SUCCESS))
+ qWarning("QEventDispatcherBlackberry: bps_add_fd error");
}
static inline int timespecToMillisecs(const timespec &tv)
@@ -358,8 +360,8 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef
// Wait for event or file to be ready
const int result = bps_get_event(&event, timeoutLeft);
- if (result != BPS_SUCCESS)
- qWarning("QEventDispatcherBlackberry::select: bps_get_event() failed");
+ 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
@@ -392,13 +394,13 @@ void QEventDispatcherBlackberry::wakeUp()
Q_D(QEventDispatcherBlackberry);
if (d->wakeUps.testAndSetAcquire(0, 1)) {
bps_event_t *event;
- if (bps_event_create(&event, bpsUnblockDomain, 0, 0, 0) == BPS_SUCCESS) {
- if (bps_channel_push_event(d->bps_channel, event) == BPS_SUCCESS)
+ 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("QEventDispatcherBlackberryPrivate::wakeUp failed");
+ qWarning("QEventDispatcherBlackberry: wakeUp failed");
}
}
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 50f3a1814b..586d6cf29f 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -421,6 +421,56 @@ public:
int alias;
};
+template<typename T, typename Key>
+class QMetaTypeFunctionRegistry
+{
+public:
+ ~QMetaTypeFunctionRegistry()
+ {
+ const QWriteLocker locker(&lock);
+ map.clear();
+ }
+
+ bool contains(Key k) const
+ {
+ const QReadLocker locker(&lock);
+ return map.contains(k);
+ }
+
+ bool insertIfNotContains(Key k, const T *f)
+ {
+ const QWriteLocker locker(&lock);
+ const T* &fun = map[k];
+ if (fun != 0)
+ return false;
+ fun = f;
+ return true;
+ }
+
+ const T *function(Key k) const
+ {
+ const QReadLocker locker(&lock);
+ return map.value(k, 0);
+ }
+
+ void remove(int from, int to)
+ {
+ const Key k(from, to);
+ const QWriteLocker locker(&lock);
+ map.remove(k);
+ }
+private:
+ mutable QReadWriteLock lock;
+ QHash<Key, const T *> map;
+};
+
+typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractConverterFunction,QPair<int,int> >
+QMetaTypeConverterRegistry;
+typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractComparatorFunction,int>
+QMetaTypeComparatorRegistry;
+typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractDebugStreamFunction,int>
+QMetaTypeDebugStreamRegistry;
+
namespace
{
union CheckThatItIsPod
@@ -432,6 +482,198 @@ union CheckThatItIsPod
Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
+Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
+Q_GLOBAL_STATIC(QMetaTypeComparatorRegistry, customTypesComparatorRegistry)
+Q_GLOBAL_STATIC(QMetaTypeDebugStreamRegistry, customTypesDebugStreamRegistry)
+
+/*!
+ \fn bool QMetaType::registerConverter()
+ \since 5.2
+ Registers the possibility of an implicit conversion from type From to type To in the meta
+ type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ \fn bool QMetaType::registerConverter(MemberFunction function)
+ \since 5.2
+ \overload
+ Registers a method \a function like To From::function() const as converter from type From
+ to type To in the meta type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ \fn bool QMetaType::registerConverter(MemberFunctionOk function)
+ \since 5.2
+ \overload
+ Registers a method \a function like To From::function(bool *ok) const as converter from type From
+ to type To in the meta type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ \fn bool QMetaType::registerConverter(UnaryFunction function)
+ \since 5.2
+ \overload
+ Registers a unary function object \a function as converter from type From
+ to type To in the meta type system. Returns true if the registration succeeded, otherwise false.
+*/
+
+/*!
+ \fn bool QMetaType::registerComparators()
+ \since 5.2
+ Registers comparison operetarors for the user-registered type T. This requires T to have
+ both an operator== and an operator<.
+ Returns true if the registration succeeded, otherwise false.
+*/
+
+#ifndef QT_NO_DEBUG_STREAM
+/*!
+ \fn bool QMetaType::registerDebugStreamOperator()
+ Registers the debug stream operator for the user-registered type T. This requires T to have
+ an operator<<(QDebug dbg, T).
+ Returns true if the registration succeeded, otherwise false.
+*/
+#endif
+
+/*!
+ Registers function \a f as converter function from type id \a from to \a to.
+ If there's already a conversion registered, this does nothing but deleting \a f.
+ Returns true if the registration succeeded, otherwise false.
+ \since 5.2
+ \internal
+*/
+bool QMetaType::registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to)
+{
+ if (!customTypesConversionRegistry()->insertIfNotContains(qMakePair(from, to), f)) {
+ qWarning("Type conversion already registered from type %s to type %s",
+ QMetaType::typeName(from), QMetaType::typeName(to));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \internal
+
+ Invoked automatically when a converter function object is destroyed.
+ */
+void QMetaType::unregisterConverterFunction(int from, int to)
+{
+ customTypesConversionRegistry()->remove(from, to);
+}
+
+bool QMetaType::registerComparatorFunction(const QtPrivate::AbstractComparatorFunction *f, int type)
+{
+ if (!customTypesComparatorRegistry()->insertIfNotContains(type, f)) {
+ qWarning("Comparators already registered for type %s", QMetaType::typeName(type));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \fn bool QMetaType::hasRegisteredComparators()
+ Returns true, if the meta type system has registered comparators for type T.
+ \since 5.2
+ */
+
+/*!
+ Returns true, if the meta type system has registered comparators for type id \a typeId.
+ \since 5.2
+ */
+bool QMetaType::hasRegisteredComparators(int typeId)
+{
+ return customTypesComparatorRegistry()->contains(typeId);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+bool QMetaType::registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f,
+ int type)
+{
+ if (!customTypesDebugStreamRegistry()->insertIfNotContains(type, f)) {
+ qWarning("Debug stream operator already registered for type %s", QMetaType::typeName(type));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \fn bool QMetaType::hasRegisteredDebugStreamOperator()
+ Returns true, if the meta type system has a registered debug stream operator for type T.
+ \since 5.2
+ */
+
+/*!
+ Returns true, if the meta type system has a registered debug stream operator for type
+ id \a typeId.
+ \since 5.2
+*/
+bool QMetaType::hasRegisteredDebugStreamOperator(int typeId)
+{
+ return customTypesDebugStreamRegistry()->contains(typeId);
+}
+#endif
+
+/*!
+ Converts the object at \a from from \a fromTypeId to the preallocated space at \a to
+ typed \a toTypeId. Returns true, if the conversion succeeded, otherwise false.
+ \since 5.2
+*/
+bool QMetaType::convert(const void *from, int fromTypeId, void *to, int toTypeId)
+{
+ const QtPrivate::AbstractConverterFunction * const f =
+ customTypesConversionRegistry()->function(qMakePair(fromTypeId, toTypeId));
+ return f && f->convert(f, from, to);
+}
+
+/*!
+ Compares the objects at \a lhs and \a rhs. Both objects need to be of type \a typeId.
+ \a result is set to less than, equal to or greater than zero, if \a lhs is less than, equal to
+ or greater than \a rhs. Returns true, if the comparison succeeded, otherwiess false.
+ \since 5.2
+*/
+bool QMetaType::compare(const void *lhs, const void *rhs, int typeId, int* result)
+{
+ const QtPrivate::AbstractComparatorFunction * const f =
+ customTypesComparatorRegistry()->function(typeId);
+ if (!f)
+ return false;
+ if (f->equals(f, lhs, rhs))
+ *result = 0;
+ else
+ *result = f->lessThan(f, lhs, rhs) ? -1 : 1;
+ return true;
+}
+
+/*!
+ Streams the object at \a rhs of type \a typeId to the debug stream \a dbg. Returns true
+ on success, otherwise false.
+ \since 5.2
+*/
+bool QMetaType::debugStream(QDebug& dbg, const void *rhs, int typeId)
+{
+ const QtPrivate::AbstractDebugStreamFunction * const f = customTypesDebugStreamRegistry()->function(typeId);
+ if (!f)
+ return false;
+ f->stream(f, dbg, rhs);
+ return true;
+}
+
+/*!
+ \fn bool QMetaType::hasRegisteredConverterFunction()
+ Returns true, if the meta type system has a registered conversion from type From to type To.
+ \since 5.2
+ \overload
+ */
+
+/*!
+ Returns true, if the meta type system has a registered conversion from meta type id \a fromTypeId
+ to \a toTypeId
+ \since 5.2
+*/
+bool QMetaType::hasRegisteredConverterFunction(int fromTypeId, int toTypeId)
+{
+ return customTypesConversionRegistry()->contains(qMakePair(fromTypeId, toTypeId));
+}
#ifndef QT_NO_DATASTREAM
/*!
@@ -723,11 +965,11 @@ int QMetaType::registerNormalizedTypedef(const NS(QByteArray) &normalizedTypeNam
}
if (idx != aliasId) {
- qFatal("QMetaType::registerTypedef: Binary compatibility break "
- "-- Type name '%s' previously registered as typedef of '%s' [%i], "
- "now registering as typedef of '%s' [%i].",
- normalizedTypeName.constData(), QMetaType::typeName(idx), idx,
- QMetaType::typeName(aliasId), aliasId);
+ qWarning("QMetaType::registerTypedef: "
+ "-- Type name '%s' previously registered as typedef of '%s' [%i], "
+ "now registering as typedef of '%s' [%i].",
+ normalizedTypeName.constData(), QMetaType::typeName(idx), idx,
+ QMetaType::typeName(aliasId), aliasId);
}
return idx;
}
@@ -1841,6 +2083,37 @@ const QMetaObject *QMetaType::metaObjectForType(int type)
\sa Q_DECLARE_METATYPE(), QMetaType::type()
*/
+/*!
+ \fn bool qRegisterSequentialConverter()
+ \relates QMetaType
+ \since 5.2
+
+ Registers a sequential container so that it can be converted to
+ a QVariantList. If compilation fails, then you probably forgot to
+ Q_DECLARE_METATYPE the value type.
+
+ Note that it is not necessary to call this method for Qt containers (QList,
+ QVector etc) or for std::vector or std::list. Such containers are automatically
+ registered by Qt.
+
+ \sa QVariant::canConvert()
+*/
+
+/*!
+ \fn bool qRegisterAssociativeConverter()
+ \relates QMetaType
+ \since 5.2
+
+ Registers an associative container so that it can be converted to
+ a QVariantHash or QVariantMap. If the key_type and mapped_type of the container
+ was not declared with Q_DECLARE_METATYPE(), compilation will fail.
+
+ Note that it is not necessary to call this method for Qt containers (QHash,
+ QMap etc) or for std::map. Such containers are automatically registered by Qt.
+
+ \sa QVariant::canConvert()
+*/
+
namespace {
class TypeInfo {
template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 5763bcc07b..005199080d 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -47,17 +47,27 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qisenum.h>
+#include <QtCore/qtypetraits.h>
#ifndef QT_NO_QOBJECT
#include <QtCore/qobjectdefs.h>
#endif
#include <new>
+#include <vector>
+#include <list>
+#include <map>
+
#ifdef Bool
#error qmetatype.h must be included before any header file that defines Bool
#endif
QT_BEGIN_NAMESPACE
+template <typename T>
+struct QMetaTypeId2;
+
+template <typename T>
+inline Q_DECL_CONSTEXPR int qMetaTypeId();
// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
#define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
@@ -183,10 +193,183 @@ QT_BEGIN_NAMESPACE
#define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \
TypeName = Id,
+#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \
+ F(QList) \
+ F(QVector) \
+ F(QQueue) \
+ F(QStack) \
+ F(QSet) \
+ F(QLinkedList)
+
+#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \
+ F(QHash, class) \
+ F(QMap, class) \
+ F(QPair, struct)
+
class QDataStream;
class QMetaTypeInterface;
struct QMetaObject;
+namespace QtPrivate
+{
+/*!
+ This template is used for implicit conversion from type From to type To.
+ \internal
+*/
+template<typename From, typename To>
+To convertImplicit(const From& from)
+{
+ return from;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+struct AbstractDebugStreamFunction
+{
+ typedef void (*Stream)(const AbstractDebugStreamFunction *, QDebug&, const void *);
+ typedef void (*Destroy)(AbstractDebugStreamFunction *);
+ explicit AbstractDebugStreamFunction(Stream s = 0, Destroy d = 0)
+ : stream(s), destroy(d) {}
+ Q_DISABLE_COPY(AbstractDebugStreamFunction)
+ Stream stream;
+ Destroy destroy;
+};
+
+template<typename T>
+struct BuiltInDebugStreamFunction : public AbstractDebugStreamFunction
+{
+ BuiltInDebugStreamFunction()
+ : AbstractDebugStreamFunction(stream, destroy) {}
+ static void stream(const AbstractDebugStreamFunction *, QDebug& dbg, const void *r)
+ {
+ const T *rhs = static_cast<const T *>(r);
+ operator<<(dbg, *rhs);
+ }
+
+ static void destroy(AbstractDebugStreamFunction *_this)
+ {
+ delete static_cast<BuiltInDebugStreamFunction *>(_this);
+ }
+};
+#endif
+
+struct AbstractComparatorFunction
+{
+ typedef bool (*LessThan)(const AbstractComparatorFunction *, const void *, const void *);
+ typedef bool (*Equals)(const AbstractComparatorFunction *, const void *, const void *);
+ typedef void (*Destroy)(AbstractComparatorFunction *);
+ explicit AbstractComparatorFunction(LessThan lt = 0, Equals e = 0, Destroy d = 0)
+ : lessThan(lt), equals(e), destroy(d) {}
+ Q_DISABLE_COPY(AbstractComparatorFunction)
+ LessThan lessThan;
+ Equals equals;
+ Destroy destroy;
+};
+
+template<typename T>
+struct BuiltInComparatorFunction : public AbstractComparatorFunction
+{
+ BuiltInComparatorFunction()
+ : AbstractComparatorFunction(lessThan, equals, destroy) {}
+ static bool lessThan(const AbstractComparatorFunction *, const void *l, const void *r)
+ {
+ const T *lhs = static_cast<const T *>(l);
+ const T *rhs = static_cast<const T *>(r);
+ return *lhs < *rhs;
+ }
+
+ static bool equals(const AbstractComparatorFunction *, const void *l, const void *r)
+ {
+ const T *lhs = static_cast<const T *>(l);
+ const T *rhs = static_cast<const T *>(r);
+ return *lhs == *rhs;
+ }
+
+ static void destroy(AbstractComparatorFunction *_this)
+ {
+ delete static_cast<BuiltInComparatorFunction *>(_this);
+ }
+};
+
+struct AbstractConverterFunction
+{
+ typedef bool (*Converter)(const AbstractConverterFunction *, const void *, void*);
+ explicit AbstractConverterFunction(Converter c = 0)
+ : convert(c) {}
+ Q_DISABLE_COPY(AbstractConverterFunction)
+ Converter convert;
+};
+
+template<typename From, typename To>
+struct ConverterMemberFunction : public AbstractConverterFunction
+{
+ explicit ConverterMemberFunction(To(From::*function)() const)
+ : AbstractConverterFunction(convert),
+ m_function(function) {}
+ ~ConverterMemberFunction();
+ static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
+ {
+ const From *f = static_cast<const From *>(in);
+ To *t = static_cast<To *>(out);
+ const ConverterMemberFunction *_typedThis =
+ static_cast<const ConverterMemberFunction *>(_this);
+ *t = (f->*_typedThis->m_function)();
+ return true;
+ }
+
+ To(From::* const m_function)() const;
+};
+
+template<typename From, typename To>
+struct ConverterMemberFunctionOk : public AbstractConverterFunction
+{
+ explicit ConverterMemberFunctionOk(To(From::*function)(bool *) const)
+ : AbstractConverterFunction(convert),
+ m_function(function) {}
+ ~ConverterMemberFunctionOk();
+ static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
+ {
+ const From *f = static_cast<const From *>(in);
+ To *t = static_cast<To *>(out);
+ bool ok = false;
+ const ConverterMemberFunctionOk *_typedThis =
+ static_cast<const ConverterMemberFunctionOk *>(_this);
+ *t = (f->*_typedThis->m_function)(&ok);
+ if (!ok)
+ *t = To();
+ return ok;
+ }
+
+ To(From::* const m_function)(bool*) const;
+};
+
+template<typename From, typename To, typename UnaryFunction>
+struct ConverterFunctor : public AbstractConverterFunction
+{
+ explicit ConverterFunctor(UnaryFunction function)
+ : AbstractConverterFunction(convert),
+ m_function(function) {}
+ ~ConverterFunctor();
+ static bool convert(const AbstractConverterFunction *_this, const void *in, void *out)
+ {
+ const From *f = static_cast<const From *>(in);
+ To *t = static_cast<To *>(out);
+ const ConverterFunctor *_typedThis =
+ static_cast<const ConverterFunctor *>(_this);
+ *t = _typedThis->m_function(*f);
+ return true;
+ }
+
+ UnaryFunction m_function;
+};
+
+ template<typename T, bool>
+ struct ValueTypeIsMetaType;
+ template<typename T, bool>
+ struct AssociativeValueTypeIsMetaType;
+ template<typename T, bool>
+ struct IsMetaTypePair;
+}
+
class Q_CORE_EXPORT QMetaType {
enum ExtensionFlag { NoExtensionFlags,
CreateEx = 0x1, DestroyEx = 0x2,
@@ -320,6 +503,109 @@ public:
inline void destroy(void *data) const;
inline void *construct(void *where, const void *copy = 0) const;
inline void destruct(void *data) const;
+
+public:
+ template<typename T>
+ static bool registerComparators()
+ {
+ Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn),
+ "QMetaType::registerComparators: The type must be a custom type.");
+
+ const int typeId = qMetaTypeId<T>();
+ static const QtPrivate::BuiltInComparatorFunction<T> f;
+ return registerComparatorFunction( &f, typeId);
+ }
+ template<typename T>
+ static bool hasRegisteredComparators()
+ {
+ return hasRegisteredComparators(qMetaTypeId<T>());
+ }
+ static bool hasRegisteredComparators(int typeId);
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ template<typename T>
+ static bool registerDebugStreamOperator()
+ {
+ Q_STATIC_ASSERT_X((!QMetaTypeId2<T>::IsBuiltIn),
+ "QMetaType::registerDebugStreamOperator: The type must be a custom type.");
+
+ const int typeId = qMetaTypeId<T>();
+ static const QtPrivate::BuiltInDebugStreamFunction<T> f;
+ return registerDebugStreamOperatorFunction(&f, typeId);
+ }
+ template<typename T>
+ static bool hasRegisteredDebugStreamOperator()
+ {
+ return hasRegisteredDebugStreamOperator(qMetaTypeId<T>());
+ }
+ static bool hasRegisteredDebugStreamOperator(int typeId);
+#endif
+
+ // implicit conversion supported like double -> float
+ template<typename From, typename To>
+ static bool registerConverter()
+ {
+ return registerConverter<From, To>(QtPrivate::convertImplicit<From, To>);
+ }
+
+#ifdef Q_QDOC
+ static bool registerConverter(MemberFunction function);
+ static bool registerConverter(MemberFunctionOk function);
+ static bool registerConverter(UnaryFunction function);
+#else
+ // member function as in "QString QFont::toString() const"
+ template<typename From, typename To>
+ static bool registerConverter(To(From::*function)() const)
+ {
+ Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
+ "QMetaType::registerConverter: At least one of the types must be a custom type.");
+
+ const int fromTypeId = qMetaTypeId<From>();
+ const int toTypeId = qMetaTypeId<To>();
+ static const QtPrivate::ConverterMemberFunction<From, To> f(function);
+ return registerConverterFunction(&f, fromTypeId, toTypeId);
+ }
+
+ // member function as in "double QString::toDouble(bool *ok = 0) const"
+ template<typename From, typename To>
+ static bool registerConverter(To(From::*function)(bool*) const)
+ {
+ Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
+ "QMetaType::registerConverter: At least one of the types must be a custom type.");
+
+ const int fromTypeId = qMetaTypeId<From>();
+ const int toTypeId = qMetaTypeId<To>();
+ static const QtPrivate::ConverterMemberFunctionOk<From, To> f(function);
+ return registerConverterFunction(&f, fromTypeId, toTypeId);
+ }
+
+ // functor or function pointer
+ template<typename From, typename To, typename UnaryFunction>
+ static bool registerConverter(UnaryFunction function)
+ {
+ Q_STATIC_ASSERT_X((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
+ "QMetaType::registerConverter: At least one of the types must be a custom type.");
+
+ const int fromTypeId = qMetaTypeId<From>();
+ const int toTypeId = qMetaTypeId<To>();
+ static const QtPrivate::ConverterFunctor<From, To, UnaryFunction> f(function);
+ return registerConverterFunction(&f, fromTypeId, toTypeId);
+ }
+#endif
+
+ static bool convert(const void *from, int fromTypeId, void *to, int toTypeId);
+ static bool compare(const void *lhs, const void *rhs, int typeId, int* result);
+ static bool debugStream(QDebug& dbg, const void *rhs, int typeId);
+
+ template<typename From, typename To>
+ static bool hasRegisteredConverterFunction()
+ {
+ return hasRegisteredConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
+ }
+
+ static bool hasRegisteredConverterFunction(int fromTypeId, int toTypeId);
+
private:
static QMetaType typeInfo(const int type);
inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
@@ -348,6 +634,31 @@ private:
void *constructExtended(void *where, const void *copy = 0) const;
void destructExtended(void *data) const;
+ static bool registerComparatorFunction(const QtPrivate::AbstractComparatorFunction *f, int type);
+#ifndef QT_NO_DEBUG_STREAM
+ static bool registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f, int type);
+#endif
+
+#ifndef Q_NO_TEMPLATE_FRIENDS
+#ifndef Q_QDOC
+ template<typename T>
+ friend bool qRegisterSequentialConverter();
+ template<typename, bool> friend struct QtPrivate::ValueTypeIsMetaType;
+ template<typename, typename> friend struct QtPrivate::ConverterMemberFunction;
+ template<typename, typename> friend struct QtPrivate::ConverterMemberFunctionOk;
+ template<typename, typename, typename> friend struct QtPrivate::ConverterFunctor;
+ template<typename T>
+ friend bool qRegisterAssociativeConverter();
+ template<typename, bool> friend struct QtPrivate::AssociativeValueTypeIsMetaType;
+ template<typename, bool> friend struct QtPrivate::IsMetaTypePair;
+#endif
+#else
+public:
+#endif
+ static bool registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to);
+ static void unregisterConverterFunction(int from, int to);
+private:
+
Creator m_creator;
Deleter m_deleter;
SaveOperator m_saveOp;
@@ -366,6 +677,26 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
+namespace QtPrivate {
+
+template<typename From, typename To>
+ConverterMemberFunction<From, To>::~ConverterMemberFunction()
+{
+ QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
+}
+template<typename From, typename To>
+ConverterMemberFunctionOk<From, To>::~ConverterMemberFunctionOk()
+{
+ QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
+}
+template<typename From, typename To, typename UnaryFunction>
+ConverterFunctor<From, To, UnaryFunction>::~ConverterFunctor()
+{
+ QMetaType::unregisterConverterFunction(qMetaTypeId<From>(), qMetaTypeId<To>());
+}
+
+}
+
namespace QtMetaTypePrivate {
template <typename T, bool Accepted = true>
struct QMetaTypeFunctionHelper {
@@ -421,6 +752,484 @@ template <>
struct QMetaTypeFunctionHelper<void, /* Accepted */ true>
: public QMetaTypeFunctionHelper<void, /* Accepted */ false>
{};
+
+struct VariantData
+{
+ VariantData(const int metaTypeId_,
+ const void *data_,
+ const uint flags_)
+ : metaTypeId(metaTypeId_)
+ , data(data_)
+ , flags(flags_)
+ {
+ }
+ const int metaTypeId;
+ const void *data;
+ const uint flags;
+};
+
+template<typename const_iterator>
+struct IteratorOwner
+{
+ static void assign(void **ptr, const_iterator iterator)
+ {
+ *ptr = new const_iterator(iterator);
+ }
+
+ static void advance(void **iterator, int step)
+ {
+ const_iterator &it = *static_cast<const_iterator*>(*iterator);
+ std::advance(it, step);
+ }
+
+ static void destroy(void **ptr)
+ {
+ delete static_cast<const_iterator*>(*ptr);
+ }
+
+ static const void *getData(void * const *iterator)
+ {
+ return &**static_cast<const_iterator*>(*iterator);
+ }
+
+ static const void *getData(const_iterator it)
+ {
+ return &*it;
+ }
+};
+template<typename const_iterator>
+struct IteratorOwner<const const_iterator*>
+{
+ static void assign(void **ptr, const const_iterator *iterator )
+ {
+ *ptr = const_cast<const_iterator*>(iterator);
+ }
+
+ static void advance(void **iterator, int step)
+ {
+ const_iterator *it = static_cast<const_iterator*>(*iterator);
+ std::advance(it, step);
+ *iterator = it;
+ }
+
+ static void destroy(void **)
+ {
+ }
+
+ static const void *getData(void * const *iterator)
+ {
+ return *iterator;
+ }
+
+ static const void *getData(const const_iterator *it)
+ {
+ return it;
+ }
+};
+
+enum IteratorCapability
+{
+ ForwardCapability = 1,
+ BiDirectionalCapability = 2,
+ RandomAccessCapability = 4
+};
+
+template<typename T, typename Category = typename std::iterator_traits<typename T::const_iterator>::iterator_category>
+struct CapabilitiesImpl;
+
+template<typename T>
+struct CapabilitiesImpl<T, std::forward_iterator_tag>
+{ enum { IteratorCapabilities = ForwardCapability }; };
+template<typename T>
+struct CapabilitiesImpl<T, std::bidirectional_iterator_tag>
+{ enum { IteratorCapabilities = BiDirectionalCapability | ForwardCapability }; };
+template<typename T>
+struct CapabilitiesImpl<T, std::random_access_iterator_tag>
+{ enum { IteratorCapabilities = RandomAccessCapability | BiDirectionalCapability | ForwardCapability }; };
+
+template<typename T>
+struct ContainerAPI : CapabilitiesImpl<T>
+{
+ static int size(const T *t) { return std::distance(t->begin(), t->end()); }
+};
+
+template<typename T>
+struct ContainerAPI<QList<T> > : CapabilitiesImpl<QList<T> >
+{ static int size(const QList<T> *t) { return t->size(); } };
+
+template<typename T>
+struct ContainerAPI<QVector<T> > : CapabilitiesImpl<QVector<T> >
+{ static int size(const QVector<T> *t) { return t->size(); } };
+
+template<typename T>
+struct ContainerAPI<std::vector<T> > : CapabilitiesImpl<std::vector<T> >
+{ static int size(const std::vector<T> *t) { return t->size(); } };
+
+template<typename T>
+struct ContainerAPI<std::list<T> > : CapabilitiesImpl<std::list<T> >
+{ static int size(const std::list<T> *t) { return t->size(); } };
+
+class QSequentialIterableImpl
+{
+public:
+ const void * _iterable;
+ void *_iterator;
+ int _metaType_id;
+ uint _metaType_flags;
+ uint _iteratorCapabilities;
+ typedef int(*sizeFunc)(const void *p);
+ typedef const void * (*atFunc)(const void *p, int);
+ typedef void (*moveIteratorFunc)(const void *p, void **);
+ typedef void (*advanceFunc)(void **p, int);
+ typedef VariantData (*getFunc)( void * const *p, int metaTypeId, uint flags);
+ typedef void (*destroyIterFunc)(void **p);
+ typedef bool (*equalIterFunc)(void * const *p, void * const *other);
+
+ sizeFunc _size;
+ atFunc _at;
+ moveIteratorFunc _moveToBegin;
+ moveIteratorFunc _moveToEnd;
+ advanceFunc _advance;
+ getFunc _get;
+ destroyIterFunc _destroyIter;
+ equalIterFunc _equalIter;
+
+ template<class T>
+ static int sizeImpl(const void *p)
+ { return ContainerAPI<T>::size(static_cast<const T*>(p)); }
+
+ template<class T>
+ static const void* atImpl(const void *p, int idx)
+ {
+ typename T::const_iterator i = static_cast<const T*>(p)->begin();
+ std::advance(i, idx);
+ return IteratorOwner<typename T::const_iterator>::getData(i);
+ }
+
+ template<class T>
+ static void advanceImpl(void **p, int step)
+ { IteratorOwner<typename T::const_iterator>::advance(p, step); }
+
+ template<class T>
+ static void moveToBeginImpl(const void *container, void **iterator)
+ { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); }
+
+ template<class T>
+ static void moveToEndImpl(const void *container, void **iterator)
+ { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
+
+ template<class T>
+ static void destroyIterImpl(void **iterator)
+ { IteratorOwner<typename T::const_iterator>::destroy(iterator); }
+
+ template<class T>
+ static bool equalIterImpl(void * const *iterator, void * const *other)
+ { return *static_cast<typename T::const_iterator*>(*iterator) == *static_cast<typename T::const_iterator*>(*other); }
+
+ template<class T>
+ static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags)
+ { return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); }
+
+public:
+ template<class T> QSequentialIterableImpl(const T*p)
+ : _iterable(p)
+ , _iterator(0)
+ , _metaType_id(qMetaTypeId<typename T::value_type>())
+ , _metaType_flags(QTypeInfo<typename T::value_type>::isPointer)
+ , _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities)
+ , _size(sizeImpl<T>)
+ , _at(atImpl<T>)
+ , _moveToBegin(moveToBeginImpl<T>)
+ , _moveToEnd(moveToEndImpl<T>)
+ , _advance(advanceImpl<T>)
+ , _get(getImpl<T>)
+ , _destroyIter(destroyIterImpl<T>)
+ , _equalIter(equalIterImpl<T>)
+ {
+ }
+
+ QSequentialIterableImpl()
+ : _iterable(0)
+ , _iterator(0)
+ , _metaType_id(QMetaType::UnknownType)
+ , _metaType_flags(0)
+ , _iteratorCapabilities(0)
+ , _size(0)
+ , _at(0)
+ , _moveToBegin(0)
+ , _moveToEnd(0)
+ , _advance(0)
+ , _get(0)
+ , _destroyIter(0)
+ , _equalIter(0)
+ {
+ }
+
+ inline void moveToBegin() { _moveToBegin(_iterable, &_iterator); }
+ inline void moveToEnd() { _moveToEnd(_iterable, &_iterator); }
+ inline bool equal(const QSequentialIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); }
+ inline QSequentialIterableImpl &advance(int i) {
+ Q_ASSERT(i > 0 || _iteratorCapabilities & BiDirectionalCapability);
+ _advance(&_iterator, i);
+ return *this;
+ }
+
+ inline VariantData getCurrent() const { return _get(&_iterator, _metaType_id, _metaType_flags); }
+
+ VariantData at(int idx) const
+ { return VariantData(_metaType_id, _at(_iterable, idx), _metaType_flags); }
+
+ int size() const { Q_ASSERT(_iterable); return _size(_iterable); }
+
+ inline void destroyIter() { _destroyIter(&_iterator); }
+};
+
+template<typename From>
+struct QSequentialIterableConvertFunctor
+{
+ QSequentialIterableConvertFunctor() {}
+
+ QSequentialIterableImpl operator()(const From &f) const
+ {
+ return QSequentialIterableImpl(&f);
+ }
+};
+}
+
+namespace QtMetaTypePrivate {
+template<typename T, bool = QtPrivate::is_same<typename T::const_iterator::value_type, typename T::mapped_type>::value>
+struct AssociativeContainerAccessor
+{
+ static const typename T::key_type& getKey(const typename T::const_iterator &it)
+ {
+ return it.key();
+ }
+
+ static const typename T::mapped_type& getValue(const typename T::const_iterator &it)
+ {
+ return it.value();
+ }
+};
+
+template<typename T, bool = QtPrivate::is_same<typename T::const_iterator::value_type, std::pair<const typename T::key_type, typename T::mapped_type> >::value>
+struct StlStyleAssociativeContainerAccessor;
+
+template<typename T>
+struct StlStyleAssociativeContainerAccessor<T, true>
+{
+ static const typename T::key_type& getKey(const typename T::const_iterator &it)
+ {
+ return it->first;
+ }
+
+ static const typename T::mapped_type& getValue(const typename T::const_iterator &it)
+ {
+ return it->second;
+ }
+};
+
+template<typename T>
+struct AssociativeContainerAccessor<T, false> : public StlStyleAssociativeContainerAccessor<T>
+{
+};
+
+class QAssociativeIterableImpl
+{
+public:
+ const void *_iterable;
+ void *_iterator;
+ int _metaType_id_key;
+ uint _metaType_flags_key;
+ int _metaType_id_value;
+ uint _metaType_flags_value;
+ typedef int(*sizeFunc)(const void *p);
+ typedef void (*findFunc)(const void *container, const void *p, void **iterator);
+ typedef void (*beginFunc)(const void *p, void **);
+ typedef void (*advanceFunc)(void **p, int);
+ typedef VariantData (*getFunc)(void * const *p, int metaTypeId, uint flags);
+ typedef void (*destroyIterFunc)(void **p);
+ typedef bool (*equalIterFunc)(void * const *p, void * const *other);
+
+ sizeFunc _size;
+ findFunc _find;
+ beginFunc _begin;
+ beginFunc _end;
+ advanceFunc _advance;
+ getFunc _getKey;
+ getFunc _getValue;
+ destroyIterFunc _destroyIter;
+ equalIterFunc _equalIter;
+
+ template<class T>
+ static int sizeImpl(const void *p)
+ { return std::distance(static_cast<const T*>(p)->begin(),
+ static_cast<const T*>(p)->end()); }
+
+ template<class T>
+ static void findImpl(const void *container, const void *p, void **iterator)
+ { IteratorOwner<typename T::const_iterator>::assign(iterator,
+ static_cast<const T*>(container)->find(*static_cast<const typename T::key_type*>(p))); }
+
+ template<class T>
+ static void advanceImpl(void **p, int step)
+ { std::advance(*static_cast<typename T::const_iterator*>(*p), step); }
+
+ template<class T>
+ static void beginImpl(const void *container, void **iterator)
+ { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); }
+
+ template<class T>
+ static void endImpl(const void *container, void **iterator)
+ { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
+
+ template<class T>
+ static VariantData getKeyImpl(void * const *iterator, int metaTypeId, uint flags)
+ { return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getKey(*static_cast<typename T::const_iterator*>(*iterator)), flags); }
+
+ template<class T>
+ static VariantData getValueImpl(void * const *iterator, int metaTypeId, uint flags)
+ { return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getValue(*static_cast<typename T::const_iterator*>(*iterator)), flags); }
+
+ template<class T>
+ static void destroyIterImpl(void **iterator)
+ { IteratorOwner<typename T::const_iterator>::destroy(iterator); }
+
+ template<class T>
+ static bool equalIterImpl(void * const *iterator, void * const *other)
+ { return *static_cast<typename T::const_iterator*>(*iterator) == *static_cast<typename T::const_iterator*>(*other); }
+
+public:
+ template<class T> QAssociativeIterableImpl(const T*p)
+ : _iterable(p)
+ , _metaType_id_key(qMetaTypeId<typename T::key_type>())
+ , _metaType_flags_key(QTypeInfo<typename T::key_type>::isPointer)
+ , _metaType_id_value(qMetaTypeId<typename T::mapped_type>())
+ , _metaType_flags_value(QTypeInfo<typename T::mapped_type>::isPointer)
+ , _size(sizeImpl<T>)
+ , _find(findImpl<T>)
+ , _begin(beginImpl<T>)
+ , _end(endImpl<T>)
+ , _advance(advanceImpl<T>)
+ , _getKey(getKeyImpl<T>)
+ , _getValue(getValueImpl<T>)
+ , _destroyIter(destroyIterImpl<T>)
+ , _equalIter(equalIterImpl<T>)
+ {
+ }
+
+ QAssociativeIterableImpl()
+ : _iterable(0)
+ , _metaType_id_key(QMetaType::UnknownType)
+ , _metaType_flags_key(0)
+ , _metaType_id_value(QMetaType::UnknownType)
+ , _metaType_flags_value(0)
+ , _size(0)
+ , _find(0)
+ , _begin(0)
+ , _end(0)
+ , _advance(0)
+ , _getKey(0)
+ , _getValue(0)
+ , _destroyIter(0)
+ , _equalIter(0)
+ {
+ }
+
+ inline void begin() { _begin(_iterable, &_iterator); }
+ inline void end() { _end(_iterable, &_iterator); }
+ inline bool equal(const QAssociativeIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); }
+ inline QAssociativeIterableImpl &advance(int i) { _advance(&_iterator, i); return *this; }
+
+ inline void destroyIter() { _destroyIter(&_iterator); }
+
+ inline VariantData getCurrentKey() const { return _getKey(&_iterator, _metaType_id_key, _metaType_flags_value); }
+ inline VariantData getCurrentValue() const { return _getValue(&_iterator, _metaType_id_value, _metaType_flags_value); }
+
+ inline void find(const VariantData &key)
+ { _find(_iterable, key.data, &_iterator); }
+
+ int size() const { Q_ASSERT(_iterable); return _size(_iterable); }
+};
+
+template<typename From>
+struct QAssociativeIterableConvertFunctor
+{
+ QAssociativeIterableConvertFunctor() {}
+
+ QAssociativeIterableImpl operator()(const From& f) const
+ {
+ return QAssociativeIterableImpl(&f);
+ }
+};
+
+class QPairVariantInterfaceImpl
+{
+ const void *_pair;
+ int _metaType_id_first;
+ uint _metaType_flags_first;
+ int _metaType_id_second;
+ uint _metaType_flags_second;
+
+ typedef VariantData (*getFunc)(const void * const *p, int metaTypeId, uint flags);
+
+ getFunc _getFirst;
+ getFunc _getSecond;
+
+ template<class T>
+ static VariantData getFirstImpl(const void * const *pair, int metaTypeId, uint flags)
+ { return VariantData(metaTypeId, &static_cast<const T*>(*pair)->first, flags); }
+ template<class T>
+ static VariantData getSecondImpl(const void * const *pair, int metaTypeId, uint flags)
+ { return VariantData(metaTypeId, &static_cast<const T*>(*pair)->second, flags); }
+
+public:
+ template<class T> QPairVariantInterfaceImpl(const T*p)
+ : _pair(p)
+ , _metaType_id_first(qMetaTypeId<typename T::first_type>())
+ , _metaType_flags_first(QTypeInfo<typename T::first_type>::isPointer)
+ , _metaType_id_second(qMetaTypeId<typename T::second_type>())
+ , _metaType_flags_second(QTypeInfo<typename T::second_type>::isPointer)
+ , _getFirst(getFirstImpl<T>)
+ , _getSecond(getSecondImpl<T>)
+ {
+ }
+
+ QPairVariantInterfaceImpl()
+ : _pair(0)
+ , _getFirst(0)
+ , _getSecond(0)
+ {
+ }
+
+ inline VariantData first() const { return _getFirst(&_pair, _metaType_id_first, _metaType_flags_first); }
+ inline VariantData second() const { return _getSecond(&_pair, _metaType_id_second, _metaType_flags_second); }
+};
+
+template<typename From>
+struct QPairVariantInterfaceConvertFunctor;
+
+template<typename T, typename U>
+struct QPairVariantInterfaceConvertFunctor<QPair<T, U> >
+{
+ QPairVariantInterfaceConvertFunctor() {}
+
+ QPairVariantInterfaceImpl operator()(const QPair<T, U>& f) const
+ {
+ return QPairVariantInterfaceImpl(&f);
+ }
+};
+
+template<typename T, typename U>
+struct QPairVariantInterfaceConvertFunctor<std::pair<T, U> >
+{
+ QPairVariantInterfaceConvertFunctor() {}
+
+ QPairVariantInterfaceImpl operator()(const std::pair<T, U>& f) const
+ {
+ return QPairVariantInterfaceImpl(&f);
+ }
+};
+
}
class QObject;
@@ -509,6 +1318,176 @@ namespace QtPrivate
enum { Value = true };
};
+ template<typename T>
+ struct IsSequentialContainer
+ {
+ enum { Value = false };
+ };
+
+#define QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE(CONTAINER) \
+ template<typename T> \
+ struct IsSequentialContainer<CONTAINER<T> > \
+ { \
+ enum { Value = true }; \
+ };
+ QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE)
+ QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE(std::vector)
+ QT_DEFINE_SEQUENTIAL_CONTAINER_TYPE(std::list)
+
+ template<typename T>
+ struct IsAssociativeContainer
+ {
+ enum { Value = false };
+ };
+
+#define QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(CONTAINER) \
+ template<typename T, typename U> \
+ struct IsAssociativeContainer<CONTAINER<T, U> > \
+ { \
+ enum { Value = true }; \
+ };
+ QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(QHash)
+ QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(QMap)
+ QT_DEFINE_ASSOCIATIVE_CONTAINER_TYPE(std::map)
+
+
+ template<typename T, bool = QtPrivate::IsSequentialContainer<T>::Value>
+ struct SequentialContainerConverterHelper
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::value_type>::Defined>
+ struct ValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct ValueTypeIsMetaType<T, true>
+ {
+ static bool registerConverter(int id)
+ {
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ static const QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QSequentialIterableImpl,
+ QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+ }
+ };
+
+ template<typename T>
+ struct SequentialContainerConverterHelper<T, true> : ValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T, bool = QtPrivate::IsAssociativeContainer<T>::Value>
+ struct AssociativeContainerConverterHelper
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::mapped_type>::Defined>
+ struct AssociativeValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct AssociativeValueTypeIsMetaType<T, true>
+ {
+ static bool registerConverter(int id)
+ {
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ static const QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QAssociativeIterableImpl,
+ QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+ }
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::key_type>::Defined>
+ struct KeyAndValueTypeIsMetaType
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct KeyAndValueTypeIsMetaType<T, true> : AssociativeValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T>
+ struct AssociativeContainerConverterHelper<T, true> : KeyAndValueTypeIsMetaType<T>
+ {
+ };
+
+ template<typename T, bool = QMetaTypeId2<typename T::first_type>::Defined
+ && QMetaTypeId2<typename T::second_type>::Defined>
+ struct IsMetaTypePair
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+
+ template<typename T>
+ struct IsMetaTypePair<T, true>
+ {
+ static bool registerConverter(int id)
+ {
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
+ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) {
+ static const QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QPairVariantInterfaceImpl,
+ QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+ }
+ return true;
+ }
+ };
+
+ template<typename T>
+ struct IsPair
+ {
+ static bool registerConverter(int)
+ {
+ return false;
+ }
+ };
+ template<typename T, typename U>
+ struct IsPair<QPair<T, U> > : IsMetaTypePair<QPair<T, U> > {};
+ template<typename T, typename U>
+ struct IsPair<std::pair<T, U> > : IsMetaTypePair<std::pair<T, U> > {};
+
+ template<typename T>
+ struct MetaTypePairHelper : IsPair<T> {};
+
Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
} // namespace QtPrivate
@@ -546,11 +1525,16 @@ namespace QtPrivate {
{ return -1; }
};
+#ifndef Q_COMPILER_VARIADIC_TEMPLATES
// Function pointers don't derive from QObject
template <class Result> struct IsPointerToTypeDerivedFromQObject<Result(*)()> { enum { Value = false }; };
template <class Result, class Arg0> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1, class Arg2> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1, Arg2)> { enum { Value = false }; };
+#else
+ template <typename Result, typename... Args>
+ struct IsPointerToTypeDerivedFromQObject<Result(*)(Args...)> { enum { Value = false }; };
+#endif
template<typename T>
struct QMetaTypeTypeFlags
@@ -593,7 +1577,7 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
if (defined)
flags |= QMetaType::WasDeclaredAsMetaType;
- return QMetaType::registerNormalizedType(normalizedTypeName,
+ const int id = QMetaType::registerNormalizedType(normalizedTypeName,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Delete,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Create,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct,
@@ -601,6 +1585,14 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
int(sizeof(T)),
flags,
QtPrivate::MetaObjectForType<T>::value());
+
+ if (id > 0) {
+ QtPrivate::SequentialContainerConverterHelper<T>::registerConverter(id);
+ QtPrivate::AssociativeContainerConverterHelper<T>::registerConverter(id);
+ QtPrivate::MetaTypePairHelper<T>::registerConverter(id);
+ }
+
+ return id;
}
template <typename T>
@@ -846,19 +1838,6 @@ struct QMetaTypeId< SMART_POINTER<T> > : public QMetaTypeId_ ## SMART_POINTER ##
{ \
};
-#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \
- F(QList) \
- F(QVector) \
- F(QQueue) \
- F(QStack) \
- F(QSet) \
- F(QLinkedList)
-
-#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \
- F(QHash, class) \
- F(QMap, class) \
- F(QPair, struct)
-
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \
F(QSharedPointer) \
F(QWeakPointer) \
@@ -872,6 +1851,9 @@ QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER)
#undef Q_DECLARE_METATYPE_TEMPLATE_1ARG_ITER
+Q_DECLARE_METATYPE_TEMPLATE_1ARG(std::vector)
+Q_DECLARE_METATYPE_TEMPLATE_1ARG(std::list)
+
#define Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER(TEMPLATENAME, CPPTYPE) \
template <class T1, class T2> CPPTYPE TEMPLATENAME; \
Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
@@ -880,6 +1862,9 @@ QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER)
#undef Q_DECLARE_METATYPE_TEMPLATE_2ARG_ITER
+Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::pair)
+Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::map)
+
#define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \
Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME)
@@ -987,5 +1972,50 @@ QT_END_NAMESPACE
QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QSequentialIterableImpl)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QAssociativeIterableImpl)
+Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl)
+
+QT_BEGIN_NAMESPACE
+
+#ifndef Q_QDOC
+template<typename T>
+#endif
+bool qRegisterSequentialConverter()
+{
+ Q_STATIC_ASSERT_X(QMetaTypeId2<typename T::value_type>::Defined,
+ "The value_type of a sequential container must itself be a metatype.");
+ const int id = qMetaTypeId<T>();
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>();
+ if (QMetaType::hasRegisteredConverterFunction(id, toId))
+ return true;
+
+ static const QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QSequentialIterableImpl,
+ QtMetaTypePrivate::QSequentialIterableConvertFunctor<T> > f(o);
+ return QMetaType::registerConverterFunction(&f, id, toId);
+}
+
+template<typename T>
+bool qRegisterAssociativeConverter()
+{
+ Q_STATIC_ASSERT_X(QMetaTypeId2<typename T::key_type>::Defined
+ && QMetaTypeId2<typename T::mapped_type>::Defined,
+ "The key_type and mapped_type of an associative container must themselves be metatypes.");
+
+ const int id = qMetaTypeId<T>();
+ const int toId = qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>();
+ if (QMetaType::hasRegisteredConverterFunction(id, toId))
+ return true;
+ static const QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> o;
+ static const QtPrivate::ConverterFunctor<T,
+ QtMetaTypePrivate::QAssociativeIterableImpl,
+ QtMetaTypePrivate::QAssociativeIterableConvertFunctor<T> > f(o);
+
+ return QMetaType::registerConverterFunction(&f, id, toId);
+}
+
+QT_END_NAMESPACE
#endif // QMETATYPE_H
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 33e2adf5ba..f99bcf1532 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4270,7 +4270,7 @@ void qDeleteInEventHandler(QObject *o)
must not have an overloaded or templated operator().
*/
-/**
+/*!
\internal
Implementation of the template version of connect
@@ -4295,12 +4295,13 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
const int *types, const QMetaObject *senderMetaObject)
{
- if (!sender || !signal || !slotObj || !senderMetaObject) {
+ if (!signal) {
qWarning("QObject::connect: invalid null parameter");
if (slotObj)
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
}
+
int signal_index = -1;
void *args[] = { &signal_index, signal };
for (; senderMetaObject && signal_index < 0; senderMetaObject = senderMetaObject->superClass()) {
@@ -4314,6 +4315,27 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
return QMetaObject::Connection(0);
}
signal_index += QMetaObjectPrivate::signalOffset(senderMetaObject);
+ return QObjectPrivate::connectImpl(sender, signal_index, receiver, slot, slotObj, type, types, senderMetaObject);
+}
+
+/*!
+ \internal
+
+ Internal version of connect used by the template version of QObject::connect (called via connectImpl) and
+ also used by the QObjectPrivate::connect version used by QML. The signal_index is expected to be relative
+ to the number of signals.
+ */
+QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int signal_index,
+ const QObject *receiver, void **slot,
+ QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
+ const int *types, const QMetaObject *senderMetaObject)
+{
+ if (!sender || !slotObj || !senderMetaObject) {
+ qWarning("QObject::connect: invalid null parameter");
+ if (slotObj)
+ slotObj->destroyIfLastRef();
+ return QMetaObject::Connection();
+ }
QObject *s = const_cast<QObject *>(sender);
QObject *r = const_cast<QObject *>(receiver);
@@ -4487,6 +4509,40 @@ bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject
return QMetaObjectPrivate::disconnect(sender, signal_index, senderMetaObject, receiver, -1, slot);
}
+/*!
+ \internal
+ Used by QML to connect a signal by index to a slot implemented in JavaScript (wrapped in a custom QSlotOBjectBase subclass).
+
+ The signal_index is an index relative to the number of methods.
+ */
+QMetaObject::Connection QObjectPrivate::connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type)
+{
+ if (!sender) {
+ qWarning("QObject::connect: invalid null parameter");
+ if (slotObj)
+ slotObj->destroyIfLastRef();
+ return QMetaObject::Connection();
+ }
+ const QMetaObject *senderMetaObject = sender->metaObject();
+ signal_index = methodIndexToSignalIndex(&senderMetaObject, signal_index);
+
+ return QObjectPrivate::connectImpl(sender, signal_index, sender, /*slot*/0, slotObj, type, /*types*/0, senderMetaObject);
+}
+
+/*!
+ \internal
+ Used by QML to disconnect a signal by index that's connected to a slot implemented in JavaScript (wrapped in a custom QSlotObjectBase subclass)
+ In the QML case the slot is not a pointer to a pointer to the function to disconnect, but instead it is a pointer to an array of internal values
+ required for the disconnect.
+ */
+bool QObjectPrivate::disconnect(const QObject *sender, int signal_index, void **slot)
+{
+ const QMetaObject *senderMetaObject = sender->metaObject();
+ signal_index = methodIndexToSignalIndex(&senderMetaObject, signal_index);
+
+ return QMetaObjectPrivate::disconnect(sender, signal_index, senderMetaObject, sender, -1, slot);
+}
+
/*! \class QMetaObject::Connection
\inmodule QtCore
Represents a handle to a signal-slot connection.
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index e849ec1599..3c43972ac9 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -207,6 +207,13 @@ public:
template <typename Func1, typename Func2>
static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot);
+
+ static QMetaObject::Connection connectImpl(const QObject *sender, int signal_index,
+ const QObject *receiver, void **slot,
+ QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
+ const int *types, const QMetaObject *senderMetaObject);
+ static QMetaObject::Connection connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type);
+ static bool disconnect(const QObject *sender, int signal_index, void **slot);
public:
ExtraData *extraData; // extra data set by the user
QThreadData *threadData; // id of the thread that owns the object
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index afbe1a5ece..c489344b10 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -456,6 +456,7 @@ class Q_CORE_EXPORT QMetaObject::Connection {
void *d_ptr; //QObjectPrivate::Connection*
explicit Connection(void *data) : d_ptr(data) { }
friend class QObject;
+ friend class QObjectPrivate;
friend struct QMetaObject;
public:
~Connection();
diff --git a/src/corelib/kernel/qsocketnotifier.cpp b/src/corelib/kernel/qsocketnotifier.cpp
index e0c7f171c3..6c88ed4531 100644
--- a/src/corelib/kernel/qsocketnotifier.cpp
+++ b/src/corelib/kernel/qsocketnotifier.cpp
@@ -181,17 +181,16 @@ QSocketNotifier::QSocketNotifier(qintptr socket, Type type, QObject *parent)
: QObject(*new QSocketNotifierPrivate, parent)
{
Q_D(QSocketNotifier);
- if (socket < 0)
- qWarning("QSocketNotifier: Invalid socket specified");
d->sockfd = socket;
d->sntype = type;
d->snenabled = true;
- if (!d->threadData->eventDispatcher.load()) {
+ if (socket < 0)
+ qWarning("QSocketNotifier: Invalid socket specified");
+ else if (!d->threadData->eventDispatcher.load())
qWarning("QSocketNotifier: Can only be used with threads started with QThread");
- } else {
+ else
d->threadData->eventDispatcher.load()->registerSocketNotifier(this);
- }
}
/*!
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 276257ddcf..24bf25baea 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -269,6 +269,16 @@ inline bool qt_convertToBool(const QVariant::Private *const d)
/*!
\internal
+ Returns the internal data pointer from \a d.
+ */
+
+static const void *constData(const QVariant::Private &d)
+{
+ return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.c);
+}
+
+/*!
+ \internal
Converts \a d to type \a t, which is placed in \a result.
*/
@@ -277,6 +287,14 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
Q_ASSERT(d->type != uint(t));
Q_ASSERT(result);
+ if (d->type >= QMetaType::User || t >= QMetaType::User) {
+ const bool isOk = QMetaType::convert(constData(*d), d->type, result, t);
+ if (ok)
+ *ok = isOk;
+ if (isOk)
+ return true;
+ }
+
bool dummy;
if (!ok)
ok = &dummy;
@@ -867,8 +885,15 @@ static bool customCompare(const QVariant::Private *a, const QVariant::Private *b
return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
}
-static bool customConvert(const QVariant::Private *, int, void *, bool *ok)
+static bool customConvert(const QVariant::Private *d, int t, void *result, bool *ok)
{
+ if (d->type >= QMetaType::User || t >= QMetaType::User) {
+ const bool isOk = QMetaType::convert(constData(*d), d->type, result, t);
+ if (ok)
+ *ok = isOk;
+ return isOk;
+ }
+
if (ok)
*ok = false;
return false;
@@ -1958,6 +1983,12 @@ inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &han
return *v_cast<T>(&d);
T ret;
+ if (d.type >= QMetaType::User || targetType >= QMetaType::User) {
+ const void * const from = constData(d);
+ if (QMetaType::convert(from, d.type, &ret, targetType))
+ return ret;
+ }
+
handlerManager[d.type]->convert(&d, targetType, &ret, 0);
return ret;
}
@@ -2374,13 +2405,19 @@ template <typename T>
inline T qNumVariantToHelper(const QVariant::Private &d,
const HandlersManager &handlerManager, bool *ok, const T& val)
{
- uint t = qMetaTypeId<T>();
+ const uint t = qMetaTypeId<T>();
if (ok)
*ok = true;
+
if (d.type == t)
return val;
T ret = 0;
+ if ((d.type >= QMetaType::User || t >= QMetaType::User)
+ && QMetaType::convert(&val, d.type, &ret, t)) {
+ return ret;
+ }
+
if (!handlerManager[d.type]->convert(&d, t, &ret, ok) && ok)
*ok = false;
return ret;
@@ -2735,10 +2772,52 @@ static bool canConvertMetaObject(int fromId, int toId, QObject *fromObject)
function if a qobject_cast to the type described by \a targetTypeId would succeed. Note that
this only works for QObject subclasses which use the Q_OBJECT macro.
- \sa convert()
+ A QVariant containing a sequential container will also return true for this
+ function if the \a targetTypeId is QVariantList. It is possible to iterate over
+ the contents of the container without extracting it as a (copied) QVariantList:
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 9
+
+ This requires that the value_type of the container is itself a metatype.
+
+ Similarly, a QVariant containing a sequential container will also return true for this
+ function the \a targetTypeId is QVariantHash or QVariantMap. It is possible to iterate over
+ the contents of the container without extracting it as a (copied) QVariantHash or QVariantMap:
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 10
+
+ \sa convert(), QSequentialIterable, qRegisterSequentialConverter(), QAssociativeIterable,
+ qRegisterAssociativeConverter()
*/
bool QVariant::canConvert(int targetTypeId) const
{
+ if (targetTypeId == QMetaType::QVariantList
+ && (d.type == QMetaType::QVariantList
+ || d.type == QMetaType::QStringList
+ || QMetaType::hasRegisteredConverterFunction(d.type,
+ qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>()))) {
+ return true;
+ }
+
+ if ((targetTypeId == QMetaType::QVariantHash || targetTypeId == QMetaType::QVariantMap)
+ && (d.type == QMetaType::QVariantMap
+ || d.type == QMetaType::QVariantHash
+ || QMetaType::hasRegisteredConverterFunction(d.type,
+ qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()))) {
+ return true;
+ }
+
+ if (targetTypeId == qMetaTypeId<QPair<QVariant, QVariant> >() &&
+ QMetaType::hasRegisteredConverterFunction(d.type,
+ qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
+ return true;
+ }
+
+ if ((d.type >= QMetaType::User || targetTypeId >= QMetaType::User)
+ && QMetaType::hasRegisteredConverterFunction(d.type, targetTypeId)) {
+ return true;
+ }
+
// TODO Reimplement this function, currently it works but it is a historical mess.
uint currentType = ((d.type == QMetaType::Float) ? QVariant::Double : d.type);
if (currentType == QMetaType::SChar || currentType == QMetaType::Char)
@@ -2886,7 +2965,6 @@ bool QVariant::convert(int targetTypeId)
*/
bool QVariant::convert(const int type, void *ptr) const
{
- Q_ASSERT(type < int(QMetaType::User));
return handlerManager[type]->convert(&d, type, ptr, 0);
}
@@ -2908,8 +2986,9 @@ bool QVariant::convert(const int type, void *ptr) const
which means that two values can be equal even if one of them is null and
another is not.
- \warning This function doesn't support custom types registered
- with qRegisterMetaType().
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
*/
/*!
\fn bool operator!=(const QVariant &v1, const QVariant &v2)
@@ -2918,8 +2997,9 @@ bool QVariant::convert(const int type, void *ptr) const
Returns false if \a v1 and \a v2 are equal; otherwise returns true.
- \warning This function doesn't support custom types registered
- with qRegisterMetaType().
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
*/
/*! \fn bool QVariant::operator==(const QVariant &v) const
@@ -2932,8 +3012,9 @@ bool QVariant::convert(const int type, void *ptr) const
type is not the same as this variant's type. See canConvert() for
a list of possible conversions.
- \warning This function doesn't support custom types registered
- with qRegisterMetaType().
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
*/
/*!
@@ -2942,8 +3023,61 @@ bool QVariant::convert(const int type, void *ptr) const
Compares this QVariant with \a v and returns true if they are not
equal; otherwise returns false.
- \warning This function doesn't support custom types registered
- with qRegisterMetaType().
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
+*/
+
+/*!
+ \fn bool QVariant::operator<(const QVariant &v) const
+
+ Compares this QVariant with \a v and returns true if this is less than \a v.
+
+ \note Comparability might not be availabe for the type stored in this QVariant
+ or in \a v.
+
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
+*/
+
+/*!
+ \fn bool QVariant::operator<=(const QVariant &v) const
+
+ Compares this QVariant with \a v and returns true if this is less or equal than \a v.
+
+ \note Comparability might not be available for the type stored in this QVariant
+ or in \a v.
+
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
+*/
+
+/*!
+ \fn bool QVariant::operator>(const QVariant &v) const
+
+ Compares this QVariant with \a v and returns true if this is larger than \a v.
+
+ \note Comparability might not be available for the type stored in this QVariant
+ or in \a v.
+
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
+*/
+
+/*!
+ \fn bool QVariant::operator>=(const QVariant &v) const
+
+ Compares this QVariant with \a v and returns true if this is larger or equal than \a v.
+
+ \note Comparability might not be available for the type stored in this QVariant
+ or in \a v.
+
+ \warning To make this function work with a custom type registered with
+ qRegisterMetaType(), its comparison operator must be registered using
+ QMetaType::registerComparators().
*/
static bool qIsNumericType(uint tp)
@@ -2962,6 +3096,7 @@ static bool qIsFloatingPoint(uint tp)
*/
bool QVariant::cmp(const QVariant &v) const
{
+ QVariant v1 = *this;
QVariant v2 = v;
if (d.type != v2.d.type) {
if (qIsNumericType(d.type) && qIsNumericType(v.d.type)) {
@@ -2970,10 +3105,63 @@ bool QVariant::cmp(const QVariant &v) const
else
return toLongLong() == v.toLongLong();
}
- if (!v2.canConvert(d.type) || !v2.convert(d.type))
+ if (!v2.canConvert(v1.d.type) || !v2.convert(v1.d.type))
return false;
}
- return handlerManager[d.type]->compare(&d, &v2.d);
+ if (v1.d.type >= QMetaType::User) {
+ int result;
+ if (QMetaType::compare(QT_PREPEND_NAMESPACE(constData(v1.d)), QT_PREPEND_NAMESPACE(constData(v2.d)), v1.d.type, &result))
+ return result == 0;
+ }
+ return handlerManager[v1.d.type]->compare(&v1.d, &v2.d);
+}
+
+/*!
+ \internal
+ */
+int QVariant::compare(const QVariant &v) const
+{
+ if (cmp(v))
+ return 0;
+ QVariant v1 = *this;
+ QVariant v2 = v;
+ if (v1.d.type != v2.d.type) {
+ // if both types differ, try to convert
+ if (v2.canConvert(v1.d.type)) {
+ QVariant temp = v2;
+ if (temp.convert(v1.d.type))
+ v2 = temp;
+ }
+ if (v1.d.type != v2.d.type && v1.canConvert(v2.d.type)) {
+ QVariant temp = v1;
+ if (temp.convert(v2.d.type))
+ v1 = temp;
+ }
+ if (v1.d.type != v2.d.type) {
+ // if conversion fails, default to toString
+ return v1.toString().compare(v2.toString(), Qt::CaseInsensitive);
+ }
+ }
+ if (v1.d.type >= QMetaType::User) {
+ int result;
+ if (QMetaType::compare(QT_PREPEND_NAMESPACE(constData(d)), QT_PREPEND_NAMESPACE(constData(v2.d)), d.type, &result))
+ return result;
+ }
+ if (qIsNumericType(v1.d.type)) {
+ if (qIsFloatingPoint(v1.d.type))
+ return v1.toReal() < v2.toReal() ? -1 : 1;
+ else
+ return v1.toLongLong() < v2.toLongLong() ? -1 : 1;
+ }
+ switch (v1.d.type) {
+ case QVariant::Date:
+ return v1.toDate() < v2.toDate() ? -1 : 1;
+ case QVariant::Time:
+ return v1.toTime() < v2.toTime() ? -1 : 1;
+ case QVariant::DateTime:
+ return v1.toDateTime() < v2.toDateTime() ? -1 : 1;
+ }
+ return v1.toString().compare(v2.toString(), Qt::CaseInsensitive);
}
/*!
@@ -3022,7 +3210,16 @@ QDebug operator<<(QDebug dbg, const QVariant &v)
dbg.nospace() << "QVariant(";
if (typeId != QMetaType::UnknownType) {
dbg.nospace() << QMetaType::typeName(typeId) << ", ";
- handlerManager[typeId]->debugStream(dbg, v);
+ bool userStream = false;
+ bool canConvertToString = false;
+ if (typeId >= QMetaType::User) {
+ userStream = QMetaType::debugStream(dbg, constData(v.d), typeId);
+ canConvertToString = v.canConvert<QString>();
+ }
+ if (!userStream && canConvertToString)
+ dbg << v.toString();
+ else if (!userStream)
+ handlerManager[typeId]->debugStream(dbg, v);
} else {
dbg.nospace() << "Invalid";
}
@@ -3074,7 +3271,12 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
returned. Note that this only works for QObject subclasses which use the
Q_OBJECT macro.
- \sa setValue(), fromValue(), canConvert()
+ If the QVariant contains a sequential container and \c{T} is QVariantList, the
+ elements of the container will be converted into QVariants and returned as a QVariantList.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 9
+
+ \sa setValue(), fromValue(), canConvert(), qRegisterSequentialConverter()
*/
/*! \fn bool QVariant::canConvert() const
@@ -3226,4 +3428,359 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
\internal
*/
+/*!
+ \class QSequentialIterable
+
+ \inmodule QtCore
+ \brief The QSequentialIterable class is an iterable interface for a container in a QVariant.
+
+ This class allows several methods of accessing the elements of a container held within
+ a QVariant. An instance of QSequentialIterable can be extracted from a QVariant if it can
+ be converted to a QVariantList.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 9
+
+ The container itself is not copied before iterating over it.
+
+ \sa QVariant
+*/
+
+/*! \fn QSequentialIterable::QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl)
+
+ \internal
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::begin() const
+
+ Returns a QSequentialIterable::const_iterator for the beginning of the container. This
+ can be used in stl-style iteration.
+
+ \sa end()
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::end() const
+
+ Returns a QSequentialIterable::const_iterator for the end of the container. This
+ can be used in stl-style iteration.
+
+ \sa begin()
+*/
+
+/*! \fn QVariant QSequentialIterable::at(int idx) const
+
+ Returns the element at position \a idx in the container.
+*/
+
+/*! \fn int QSequentialIterable::size() const
+
+ Returns the number of elements in the container.
+*/
+
+/*! \fn bool QSequentialIterable::canReverseIterate() const
+
+ Returns whether it is possible to iterate over the container in reverse. This
+ corresponds to the std::bidirectional_iterator_tag iterator trait of the
+ const_iterator of the container.
+*/
+
+/*!
+ \class QSequentialIterable::const_iterator
+
+ \inmodule QtCore
+ \brief The QSequentialIterable::const_iterator allows iteration over a container in a QVariant.
+
+ A QSequentialIterable::const_iterator can only be created by a QSequentialIterable instance,
+ and can be used in a way similar to other stl-style iterators.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 9
+
+ \sa QSequentialIterable
+*/
+
+
+/*! \fn QSequentialIterable::const_iterator::~const_iterator()
+
+ Destroys the QSequentialIterable::const_iterator.
+*/
+
+/*! \fn QSequentialIterable::const_iterator::const_iterator(const const_iterator &other)
+
+ Creates a copy of \a other.
+*/
+
+/*! \fn QVariant QSequentialIterable::const_iterator::operator*() const
+
+ Returns the current item, converted to a QVariant.
+*/
+
+/*! \fn bool QSequentialIterable::const_iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QSequentialIterable::const_iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*! \fn QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator++()
+
+ The prefix ++ operator (\c{++it}) advances the iterator to the
+ next item in the container and returns an iterator to the new current
+ item.
+
+ Calling this function on QSequentialIterable::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{it++}) advances the iterator to the
+ next item in the container and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator--()
+
+ The prefix -- operator (\c{--it}) makes the preceding item
+ current and returns an iterator to the new current item.
+
+ Calling this function on QSequentialIterable::begin() leads to undefined results.
+
+ If the container in the QVariant does not support bi-directional iteration, calling this function
+ leads to undefined results.
+
+ \sa operator++(), canReverseIterate()
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{it--}) makes the preceding item
+ current and returns an iterator to the previously current item.
+
+ If the container in the QVariant does not support bi-directional iteration, calling this function
+ leads to undefined results.
+
+ \sa canReverseIterate()
+*/
+
+/*! \fn QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator+=(int j)
+
+ Advances the iterator by \a j items.
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QSequentialIterable::const_iterator &QSequentialIterable::const_iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items.
+
+ If the container in the QVariant does not support bi-directional iteration, calling this function
+ leads to undefined results.
+
+ \sa operator+=(), operator-(), canReverseIterate()
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator.
+
+ \sa operator-(), operator+=()
+*/
+
+/*! \fn QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator.
+
+ If the container in the QVariant does not support bi-directional iteration, calling this function
+ leads to undefined results.
+
+ \sa operator+(), operator-=(), canReverseIterate()
+*/
+
+/*!
+ \class QAssociativeIterable
+
+ \inmodule QtCore
+ \brief The QAssociativeIterable class is an iterable interface for an associative container in a QVariant.
+
+ This class allows several methods of accessing the elements of an associative container held within
+ a QVariant. An instance of QAssociativeIterable can be extracted from a QVariant if it can
+ be converted to a QVariantHash or QVariantMap.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 10
+
+ The container itself is not copied before iterating over it.
+
+ \sa QVariant
+*/
+
+/*! \fn QAssociativeIterable::QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl)
+
+ \internal
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::begin() const
+
+ Returns a QAssociativeIterable::const_iterator for the beginning of the container. This
+ can be used in stl-style iteration.
+
+ \sa end()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::end() const
+
+ Returns a QAssociativeIterable::const_iterator for the end of the container. This
+ can be used in stl-style iteration.
+
+ \sa begin()
+*/
+
+/*! \fn QVariant QAssociativeIterable::value(const QVariant &key) const
+
+ Returns the value for the given \a key in the container, if the types are convertible.
+*/
+
+/*! \fn int QAssociativeIterable::size() const
+
+ Returns the number of elements in the container.
+*/
+
+/*!
+ \class QAssociativeIterable::const_iterator
+
+ \inmodule QtCore
+ \brief The QAssociativeIterable::const_iterator allows iteration over a container in a QVariant.
+
+ A QAssociativeIterable::const_iterator can only be created by a QAssociativeIterable instance,
+ and can be used in a way similar to other stl-style iterators.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 10
+
+ \sa QAssociativeIterable
+*/
+
+
+/*! \fn QAssociativeIterable::const_iterator::~const_iterator()
+
+ Destroys the QAssociativeIterable::const_iterator.
+*/
+
+/*! \fn QAssociativeIterable::const_iterator::const_iterator(const const_iterator &other)
+
+ Creates a copy of \a other.
+*/
+
+/*! \fn QVariant QAssociativeIterable::const_iterator::operator*() const
+
+ Returns the current value, converted to a QVariant.
+*/
+
+/*! \fn QVariant QAssociativeIterable::const_iterator::key() const
+
+ Returns the current key, converted to a QVariant.
+*/
+
+/*! \fn QVariant QAssociativeIterable::const_iterator::value() const
+
+ Returns the current value, converted to a QVariant.
+*/
+
+/*! \fn bool QAssociativeIterable::const_iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QAssociativeIterable::const_iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator++()
+
+ The prefix ++ operator (\c{++it}) advances the iterator to the
+ next item in the container and returns an iterator to the new current
+ item.
+
+ Calling this function on QAssociativeIterable::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{it++}) advances the iterator to the
+ next item in the container and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator--()
+
+ The prefix -- operator (\c{--it}) makes the preceding item
+ current and returns an iterator to the new current item.
+
+ Calling this function on QAssociativeIterable::begin() leads to undefined results.
+
+ \sa operator++()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{it--}) makes the preceding item
+ current and returns an iterator to the previously current item.
+*/
+
+/*! \fn QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator+=(int j)
+
+ Advances the iterator by \a j items.
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator &QAssociativeIterable::const_iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items.
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator.
+
+ \sa operator-(), operator+=()
+*/
+
+/*! \fn QAssociativeIterable::const_iterator QAssociativeIterable::const_iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator.
+
+ \sa operator+(), operator-=()
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 6f212f5000..d5ea491288 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -49,6 +49,7 @@
#include <QtCore/qmap.h>
#include <QtCore/qhash.h>
#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
#include <QtCore/qobject.h>
QT_BEGIN_NAMESPACE
@@ -432,6 +433,14 @@ class Q_CORE_EXPORT QVariant
{ return cmp(v); }
inline bool operator!=(const QVariant &v) const
{ return !cmp(v); }
+ inline bool operator<(const QVariant &v) const
+ { return compare(v) < 0; }
+ inline bool operator<=(const QVariant &v) const
+ { return compare(v) <= 0; }
+ inline bool operator>(const QVariant &v) const
+ { return compare(v) > 0; }
+ inline bool operator>=(const QVariant &v) const
+ { return compare(v) >= 0; }
protected:
friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
@@ -449,6 +458,7 @@ public:
Private d;
void create(int type, const void *copy);
bool cmp(const QVariant &other) const;
+ int compare(const QVariant &other) const;
bool convert(const int t, void *ptr) const;
private:
@@ -562,6 +572,173 @@ inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
}
#endif
+class QSequentialIterable
+{
+ QtMetaTypePrivate::QSequentialIterableImpl m_impl;
+public:
+ struct const_iterator
+ {
+ private:
+ QtMetaTypePrivate::QSequentialIterableImpl m_impl;
+ QAtomicInt *ref;
+ friend class QSequentialIterable;
+ inline explicit const_iterator(const QSequentialIterable &iter, QAtomicInt *ref_)
+ : m_impl(iter.m_impl), ref(ref_) { ref->ref(); }
+
+ inline explicit const_iterator(const QtMetaTypePrivate::QSequentialIterableImpl &impl, QAtomicInt *ref_)
+ : m_impl(impl), ref(ref_) { ref->ref(); }
+
+ inline void begin() { m_impl.moveToBegin(); }
+ inline void end() { m_impl.moveToEnd(); }
+ public:
+ inline ~const_iterator() {
+ if (!ref->deref()) {
+ m_impl.destroyIter();
+ }
+ }
+
+ inline const_iterator(const const_iterator &other) : m_impl(other.m_impl), ref(other.ref) {
+ ref->ref();
+ }
+
+ inline const QVariant operator*() const {
+ const QtMetaTypePrivate::VariantData d = m_impl.getCurrent();
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return QVariant(d.metaTypeId, d.data, d.flags);
+ }
+ inline bool operator==(const const_iterator &o) const { return m_impl.equal(o.m_impl); }
+ inline bool operator!=(const const_iterator &o) const { return !m_impl.equal(o.m_impl); }
+ inline const_iterator &operator++() { m_impl.advance(1); return *this; }
+ inline const_iterator operator++(int) { QtMetaTypePrivate::QSequentialIterableImpl impl = m_impl; m_impl.advance(1); return const_iterator(impl, this->ref); }
+ inline const_iterator &operator--() { m_impl.advance(-1); return *this; }
+ inline const_iterator operator--(int) { QtMetaTypePrivate::QSequentialIterableImpl impl = m_impl; m_impl.advance(-1); return const_iterator(impl, this->ref); }
+ inline const_iterator &operator+=(int j) { m_impl.advance(j); return *this; }
+ inline const_iterator &operator-=(int j) { m_impl.advance(-j); return *this; }
+ inline const_iterator operator+(int j) const { QtMetaTypePrivate::QSequentialIterableImpl impl = m_impl; impl.advance(j); return const_iterator(impl, this->ref); }
+ inline const_iterator operator-(int j) const { QtMetaTypePrivate::QSequentialIterableImpl impl = m_impl; impl.advance(-j); return const_iterator(impl, this->ref); }
+ };
+
+ friend struct const_iterator;
+
+ explicit QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl)
+ : m_impl(impl)
+ {
+ }
+
+ const_iterator begin() const { const_iterator it(*this, new QAtomicInt(0)); it.begin(); return it; }
+ const_iterator end() const { const_iterator it(*this, new QAtomicInt(0)); it.end(); return it; }
+
+ QVariant at(int idx) const {
+ const QtMetaTypePrivate::VariantData d = m_impl.at(idx);
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return QVariant(d.metaTypeId, d.data, d.flags);
+ }
+ int size() const { return m_impl.size(); }
+
+ bool canReverseIterate() const
+ { return m_impl._iteratorCapabilities & QtMetaTypePrivate::BiDirectionalCapability; }
+};
+
+class QAssociativeIterable
+{
+ QtMetaTypePrivate::QAssociativeIterableImpl m_impl;
+public:
+ struct const_iterator
+ {
+ private:
+ QtMetaTypePrivate::QAssociativeIterableImpl m_impl;
+ QAtomicInt *ref;
+ friend class QAssociativeIterable;
+ inline explicit const_iterator(const QAssociativeIterable &iter, QAtomicInt *ref_)
+ : m_impl(iter.m_impl), ref(ref_) { ref->ref(); }
+
+ inline explicit const_iterator(const QtMetaTypePrivate::QAssociativeIterableImpl &impl, QAtomicInt *ref_)
+ : m_impl(impl), ref(ref_) { ref->ref(); }
+
+ inline void begin() { m_impl.begin(); }
+ inline void end() { m_impl.end(); }
+ public:
+ inline ~const_iterator() {
+ if (!ref->deref()) {
+ m_impl.destroyIter();
+ }
+ }
+ inline const_iterator(const const_iterator &other) : m_impl(other.m_impl), ref(other.ref) {
+ ref->ref();
+ }
+
+ inline const QVariant key() const {
+ const QtMetaTypePrivate::VariantData d = m_impl.getCurrentKey();
+ QVariant v(d.metaTypeId, d.data, d.flags);
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return v;
+ }
+
+ inline const QVariant value() const {
+ const QtMetaTypePrivate::VariantData d = m_impl.getCurrentValue();
+ QVariant v(d.metaTypeId, d.data, d.flags);
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return v;
+ }
+
+ inline const QVariant operator*() const {
+ const QtMetaTypePrivate::VariantData d = m_impl.getCurrentValue();
+ QVariant v(d.metaTypeId, d.data, d.flags);
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return v;
+ }
+ inline bool operator==(const const_iterator &o) const { return m_impl.equal(o.m_impl); }
+ inline bool operator!=(const const_iterator &o) const { return !m_impl.equal(o.m_impl); }
+ inline const_iterator &operator++() { m_impl.advance(1); return *this; }
+ inline const_iterator operator++(int) { QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl; m_impl.advance(1); return const_iterator(impl, this->ref); }
+ inline const_iterator &operator--() { m_impl.advance(-1); return *this; }
+ inline const_iterator operator--(int) { QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl; m_impl.advance(-1); return const_iterator(impl, this->ref); }
+ inline const_iterator &operator+=(int j) { m_impl.advance(j); return *this; }
+ inline const_iterator &operator-=(int j) { m_impl.advance(-j); return *this; }
+ inline const_iterator operator+(int j) const { QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl; impl.advance(j); return const_iterator(impl, this->ref); }
+ inline const_iterator operator-(int j) const { QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl; impl.advance(-j); return const_iterator(impl, this->ref); }
+ };
+
+ friend struct const_iterator;
+
+ explicit QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl)
+ : m_impl(impl)
+ {
+ }
+
+ const_iterator begin() const { const_iterator it(*this, new QAtomicInt(0)); it.begin(); return it; }
+ const_iterator end() const { const_iterator it(*this, new QAtomicInt(0)); it.end(); return it; }
+
+ QVariant value(const QVariant &key) const
+ {
+ QVariant key_ = key;
+ if (!key_.canConvert(m_impl._metaType_id_key))
+ return QVariant();
+ if (!key_.convert(m_impl._metaType_id_key))
+ return QVariant();
+ const QtMetaTypePrivate::VariantData dkey(key_.userType(), key_.constData(), 0 /*key.flags()*/);
+ QtMetaTypePrivate::QAssociativeIterableImpl impl = m_impl;
+ impl.find(dkey);
+ QtMetaTypePrivate::QAssociativeIterableImpl endIt = m_impl;
+ endIt.end();
+ if (impl.equal(endIt))
+ return QVariant();
+ const QtMetaTypePrivate::VariantData d = impl.getCurrentValue();
+ QVariant v(d.metaTypeId, d.data, d.flags);
+ if (d.metaTypeId == qMetaTypeId<QVariant>())
+ return *reinterpret_cast<const QVariant*>(d.data);
+ return v;
+ }
+
+ int size() const { return m_impl.size(); }
+};
+
+#ifndef QT_MOC
namespace QtPrivate {
template<typename T>
struct QVariantValueHelper : TreatAsQObjectBeforeMetaType<QVariantValueHelper<T>, T, const QVariant &, T>
@@ -571,11 +748,9 @@ namespace QtPrivate {
const int vid = qMetaTypeId<T>();
if (vid == v.userType())
return *reinterpret_cast<const T *>(v.constData());
- if (vid < int(QMetaType::User)) {
- T t;
- if (v.convert(vid, &t))
- return t;
- }
+ T t;
+ if (v.convert(vid, &t))
+ return t;
return T();
}
#ifndef QT_NO_QOBJECT
@@ -585,12 +760,118 @@ namespace QtPrivate {
}
#endif
};
+
+ template<typename T>
+ struct QVariantValueHelperInterface : QVariantValueHelper<T>
+ {
+ };
+
+ template<>
+ struct QVariantValueHelperInterface<QSequentialIterable>
+ {
+ static QSequentialIterable invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QVariantList>()) {
+ return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QVariantList*>(v.constData())));
+ }
+ if (v.userType() == qMetaTypeId<QStringList>()) {
+ return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QStringList*>(v.constData())));
+ }
+ return QSequentialIterable(v.value<QtMetaTypePrivate::QSequentialIterableImpl>());
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QAssociativeIterable>
+ {
+ static QAssociativeIterable invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QVariantMap>()) {
+ return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantMap*>(v.constData())));
+ }
+ if (v.userType() == qMetaTypeId<QVariantHash>()) {
+ return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantHash*>(v.constData())));
+ }
+ return QAssociativeIterable(v.value<QtMetaTypePrivate::QAssociativeIterableImpl>());
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantList>
+ {
+ static QVariantList invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QStringList>() || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) {
+ QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v);
+ QVariantList l;
+ l.reserve(iter.size());
+ for (QSequentialIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l << *it;
+ return l;
+ }
+ return QVariantValueHelper<QVariantList>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantHash>
+ {
+ static QVariantHash invoke(const QVariant &v)
+ {
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
+ QVariantHash l;
+ l.reserve(iter.size());
+ for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l.insert(it.key().toString(), it.value());
+ return l;
+ }
+ return QVariantValueHelper<QVariantHash>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QVariantMap>
+ {
+ static QVariantMap invoke(const QVariant &v)
+ {
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
+ QVariantMap l;
+ for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
+ l.insert(it.key().toString(), it.value());
+ return l;
+ }
+ return QVariantValueHelper<QVariantMap>::invoke(v);
+ }
+ };
+ template<>
+ struct QVariantValueHelperInterface<QPair<QVariant, QVariant> >
+ {
+ static QPair<QVariant, QVariant> invoke(const QVariant &v)
+ {
+ if (v.userType() == qMetaTypeId<QPair<QVariant, QVariant> >())
+ return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
+
+ if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
+ QtMetaTypePrivate::QPairVariantInterfaceImpl pi = v.value<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
+
+ const QtMetaTypePrivate::VariantData d1 = pi.first();
+ QVariant v1(d1.metaTypeId, d1.data, d1.flags);
+ if (d1.metaTypeId == qMetaTypeId<QVariant>())
+ v1 = *reinterpret_cast<const QVariant*>(d1.data);
+
+ const QtMetaTypePrivate::VariantData d2 = pi.second();
+ QVariant v2(d2.metaTypeId, d2.data, d2.flags);
+ if (d2.metaTypeId == qMetaTypeId<QVariant>())
+ v2 = *reinterpret_cast<const QVariant*>(d2.data);
+
+ return QPair<QVariant, QVariant>(v1, v2);
+ }
+ return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
+ }
+ };
}
-#ifndef QT_MOC
template<typename T> inline T qvariant_cast(const QVariant &v)
{
- return QtPrivate::QVariantValueHelper<T>::invoke(v);
+ return QtPrivate::QVariantValueHelperInterface<T>::invoke(v);
}
template<> inline QVariant qvariant_cast<QVariant>(const QVariant &v)
diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri
index eb7a7f7fa8..338b3d0972 100644
--- a/src/corelib/plugin/plugin.pri
+++ b/src/corelib/plugin/plugin.pri
@@ -9,14 +9,16 @@ HEADERS += \
plugin/quuid.h \
plugin/qfactoryloader_p.h \
plugin/qsystemlibrary_p.h \
- plugin/qelfparser_p.h
+ plugin/qelfparser_p.h \
+ plugin/qmachparser_p.h
SOURCES += \
plugin/qpluginloader.cpp \
plugin/qfactoryloader.cpp \
plugin/quuid.cpp \
plugin/qlibrary.cpp \
- plugin/qelfparser_p.cpp
+ plugin/qelfparser_p.cpp \
+ plugin/qmachparser.cpp
win32 {
SOURCES += \
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 3432f9619d..92e60c2216 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -1,7 +1,7 @@
-
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -64,6 +64,7 @@
#include <qjsondocument.h>
#include <qjsonvalue.h>
#include "qelfparser_p.h"
+#include "qmachparser_p.h"
QT_BEGIN_NAMESPACE
@@ -180,8 +181,6 @@ QT_BEGIN_NAMESPACE
*/
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
-
static long qt_find_pattern(const char *s, ulong s_len,
const char *pattern, ulong p_len)
{
@@ -228,7 +227,7 @@ static long qt_find_pattern(const char *s, ulong s_len,
information could not be read.
Returns true if version information is present and successfully read.
*/
-static bool qt_unix_query(const QString &library, QLibraryPrivate *lib)
+static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
{
QFile file(library);
if (!file.open(QIODevice::ReadOnly)) {
@@ -253,7 +252,7 @@ static bool qt_unix_query(const QString &library, QLibraryPrivate *lib)
}
/*
- ELF binaries on GNU, have .qplugin sections.
+ ELF and Mach-O binaries with GCC have .qplugin sections.
*/
bool hasMetaData = false;
long pos = 0;
@@ -274,6 +273,26 @@ static bool qt_unix_query(const QString &library, QLibraryPrivate *lib)
pos += rel;
hasMetaData = true;
}
+#elif defined (Q_OF_MACH_O)
+ {
+ QString errorString;
+ int r = QMachOParser::parse(filedata, fdlen, library, &errorString, &pos, &fdlen);
+ if (r == QMachOParser::NotSuitable) {
+ if (qt_debug_component())
+ qWarning("QMachOParser: %s", qPrintable(errorString));
+ if (lib)
+ lib->errorString = errorString;
+ return false;
+ }
+ // even if the metadata section was not found, the Mach-O parser will
+ // at least return the boundaries of the right architecture
+ long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen);
+ if (rel < 0)
+ pos = -1;
+ else
+ pos += rel;
+ hasMetaData = true;
+ }
#else
pos = qt_find_pattern(filedata, fdlen, pattern, plen);
if (pos > 0)
@@ -300,8 +319,6 @@ static bool qt_unix_query(const QString &library, QLibraryPrivate *lib)
return ret;
}
-#endif // Q_OS_UNIX && !Q_OS_MAC
-
static void installCoverageTool(QLibraryPrivate *libPrivate)
{
#ifdef __COVERAGESCANNER__
@@ -618,41 +635,18 @@ bool QLibrary::isLibrary(const QString &fileName)
}
-#if defined (Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(Q_CC_INTEL)
-#define QT_USE_MS_STD_EXCEPTION 1
-const char* qt_try_versioninfo(void *pfn, bool *exceptionThrown)
-{
- *exceptionThrown = false;
- const char *szData = 0;
- typedef const char * (*VerificationFunction)();
- VerificationFunction func = reinterpret_cast<VerificationFunction>(pfn);
- __try {
- if(func)
- szData = func();
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- *exceptionThrown = true;
- }
- return szData;
-}
-#endif
-
typedef const char * (*QtPluginQueryVerificationDataFunction)();
-bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv, bool *exceptionThrown)
+static bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv)
{
- *exceptionThrown = false;
const char *szData = 0;
if (!pfn)
return false;
-#ifdef QT_USE_MS_STD_EXCEPTION
- szData = qt_try_versioninfo((void *)pfn, exceptionThrown);
- if (*exceptionThrown)
- return false;
-#else
+
szData = pfn();
-#endif
if (!szData)
return false;
+
QJsonDocument doc = QLibraryPrivate::fromRawMetaData(szData);
if (doc.isNull())
return false;
@@ -690,80 +684,15 @@ void QLibraryPrivate::updatePluginState()
}
#endif
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
if (!pHnd) {
- // use unix shortcut to avoid loading the library
- success = qt_unix_query(fileName, this);
- } else
-#endif
- {
- bool retryLoadLibrary = false; // Only used on Windows with MS compiler.(false in other cases)
- do {
- bool temporary_load = false;
-#ifdef Q_OS_WIN
- HMODULE hTempModule = 0;
-#endif
- if (!pHnd) {
-#ifdef Q_OS_WIN
- DWORD dwFlags = (retryLoadLibrary) ? 0: DONT_RESOLVE_DLL_REFERENCES;
- //avoid 'Bad Image' message box
- UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
- hTempModule = ::LoadLibraryEx((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, dwFlags);
- SetErrorMode(oldmode);
-#else
- temporary_load = load();
-#endif
- }
- QtPluginQueryVerificationDataFunction getMetaData = NULL;
-
- bool exceptionThrown = false;
- bool ret = false;
-#ifdef Q_OS_WIN
- if (hTempModule) {
- getMetaData = (QtPluginQueryVerificationDataFunction)
-#ifdef Q_OS_WINCE
- ::GetProcAddress(hTempModule, L"qt_plugin_query_metadata")
-#else
- ::GetProcAddress(hTempModule, "qt_plugin_query_metadata")
-#endif
- ;
- } else
-#endif
- {
- getMetaData = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_metadata");
- }
-
- if (getMetaData)
- ret = qt_get_metadata(getMetaData, this, &exceptionThrown);
-
- if (temporary_load)
- unload();
- if (!exceptionThrown) {
- if (ret) {
- success = true;
- }
- retryLoadLibrary = false;
- }
-#ifdef QT_USE_MS_STD_EXCEPTION
- else {
- // An exception was thrown when calling qt_plugin_query_verification_data().
- // This usually happens when plugin is compiled with the /clr compiler flag,
- // & will only work if the dependencies are loaded & DLLMain() is called.
- // LoadLibrary() will do this, try once with this & if it fails don't load.
- retryLoadLibrary = !retryLoadLibrary;
- }
-#endif
-#ifdef Q_OS_WIN
- if (hTempModule) {
- BOOL ok = ::FreeLibrary(hTempModule);
- if (ok) {
- hTempModule = 0;
- }
-
- }
-#endif
- } while (retryLoadLibrary); // Will be 'false' in all cases other than when an
- // exception is thrown(will happen only when using a MS compiler)
+ // scan for the plugin metadata without loading
+ success = findPatternUnloaded(fileName, this);
+ } else {
+ // library is already loaded (probably via QLibrary)
+ // simply get the target function and call it.
+ QtPluginQueryVerificationDataFunction getMetaData = NULL;
+ getMetaData = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_metadata");
+ success = qt_get_metadata(getMetaData, this);
}
if (!success) {
diff --git a/src/corelib/plugin/qmachparser.cpp b/src/corelib/plugin/qmachparser.cpp
new file mode 100644
index 0000000000..5152a92d1d
--- /dev/null
+++ b/src/corelib/plugin/qmachparser.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Intel Corporation
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmachparser_p.h"
+
+#if defined(Q_OF_MACH_O) && !defined(QT_NO_LIBRARY)
+
+#include <qendian.h>
+#include "qlibrary_p.h"
+
+#include <mach-o/loader.h>
+#include <mach-o/fat.h>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(Q_PROCESSOR_X86_64)
+# define MACHO64
+static const cpu_type_t my_cputype = CPU_TYPE_X86_64;
+#elif defined(Q_PROCESSOR_X86_32)
+static const cpu_type_t my_cputype = CPU_TYPE_X86;
+#elif defined(Q_PROCESSOR_POWER_64)
+# define MACHO64
+static const cpu_type_t my_cputype = CPU_TYPE_POWERPC64;
+#elif defined(Q_PROCESSOR_POWER_32)
+static const cpu_type_t my_cputype = CPU_TYPE_POWERPC;
+#elif defined(Q_PROCESSOR_ARM)
+static const cpu_type_t my_cputype = CPU_TYPE_ARM;
+#else
+# error "Unknown CPU type"
+#endif
+
+#ifdef MACHO64
+# undef MACHO64
+typedef mach_header_64 my_mach_header;
+typedef segment_command_64 my_segment_command;
+typedef section_64 my_section;
+static const uint32_t my_magic = MH_MAGIC_64;
+#else
+typedef mach_header my_mach_header;
+typedef segment_command my_segment_command;
+typedef section my_section;
+static const uint32_t my_magic = MH_MAGIC;
+#endif
+
+static int ns(const QString &reason, const QString &library, QString *errorString)
+{
+ if (errorString)
+ *errorString = QLibrary::tr("'%1' is not a valid Mach-O binary (%2)")
+ .arg(library, reason.isEmpty() ? QLibrary::tr("file is corrupt") : reason);
+ return QMachOParser::NotSuitable;
+}
+
+int QMachOParser::parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, long *pos, ulong *sectionlen)
+{
+ // The minimum size of a Mach-O binary we're interested in.
+ // It must have a full Mach header, at least one segment and at least one
+ // section. It's probably useless with just the "qtmetadata" section, but
+ // it's valid nonetheless.
+ // A fat binary must have this plus the fat header, of course.
+ static const size_t MinFileSize = sizeof(my_mach_header) + sizeof(my_segment_command) + sizeof(my_section);
+ static const size_t MinFatHeaderSize = sizeof(fat_header) + 2 * sizeof(fat_arch);
+
+ if (Q_UNLIKELY(fdlen < MinFileSize))
+ return ns(QLibrary::tr("file too small"), library, errorString);
+
+ // find out if this is a fat Mach-O binary first
+ const my_mach_header *header = 0;
+ const fat_header *fat = reinterpret_cast<const fat_header *>(m_s);
+ if (fat->magic == qToBigEndian(FAT_MAGIC)) {
+ // find our architecture in the binary
+ const fat_arch *arch = reinterpret_cast<const fat_arch *>(fat + 1);
+ if (Q_UNLIKELY(fdlen < MinFatHeaderSize)) {
+ return ns(QLibrary::tr("file too small"), library, errorString);
+ }
+
+ int count = qFromBigEndian(fat->nfat_arch);
+ if (Q_UNLIKELY(fdlen < sizeof(*fat) + sizeof(*arch) * count))
+ return ns(QString(), library, errorString);
+
+ for (int i = 0; i < count; ++i) {
+ if (arch[i].cputype == qToBigEndian(my_cputype)) {
+ // ### should we check the CPU subtype? Maybe on ARM?
+ uint32_t size = qFromBigEndian(arch[i].size);
+ uint32_t offset = qFromBigEndian(arch[i].offset);
+ if (Q_UNLIKELY(size > fdlen) || Q_UNLIKELY(offset > fdlen)
+ || Q_UNLIKELY(size + offset > fdlen) || Q_UNLIKELY(size < MinFileSize))
+ return ns(QString(), library, errorString);
+
+ header = reinterpret_cast<const my_mach_header *>(m_s + offset);
+ fdlen = size;
+ break;
+ }
+ }
+ if (!header)
+ return ns(QLibrary::tr("no suitable architecture in fat binary"), library, errorString);
+
+ // check the magic again
+ if (Q_UNLIKELY(header->magic != my_magic))
+ return ns(QString(), library, errorString);
+ } else {
+ header = reinterpret_cast<const my_mach_header *>(m_s);
+ fat = 0;
+
+ // check magic
+ if (header->magic != my_magic)
+ return ns(QLibrary::tr("invalid magic %1").arg(qFromBigEndian(header->magic), 8, 16, QLatin1Char('0')),
+ library, errorString);
+ }
+
+ // from this point on, fdlen is specific to this architecture
+ // from this point on, everything is in host byte order
+ *pos = reinterpret_cast<const char *>(header) - m_s;
+
+ // (re-)check the CPU type
+ // ### should we check the CPU subtype? Maybe on ARM?
+ if (header->cputype != my_cputype) {
+ if (fat)
+ return ns(QString(), library, errorString);
+ return ns(QLibrary::tr("wrong architecture"), library, errorString);
+ }
+
+ // check the file type
+ if (Q_UNLIKELY(header->filetype != MH_BUNDLE && header->filetype != MH_DYLIB))
+ return ns(QLibrary::tr("not a dynamic library"), library, errorString);
+
+ // find the __TEXT segment, "qtmetadata" section
+ const my_segment_command *seg = reinterpret_cast<const my_segment_command *>(header + 1);
+ ulong minsize = sizeof(*header);
+
+ for (uint i = 0; i < header->ncmds; ++i,
+ seg = reinterpret_cast<const my_segment_command *>(reinterpret_cast<const char *>(seg) + seg->cmdsize)) {
+ // We're sure that the file size includes at least one load command
+ // but we have to check anyway if we're past the first
+ if (Q_UNLIKELY(fdlen < minsize + sizeof(load_command)))
+ return ns(QString(), library, errorString);
+
+ // cmdsize can't be trusted until validated
+ // so check it against fdlen anyway
+ // (these are unsigned operations, with overflow behavior specified in the standard)
+ minsize += seg->cmdsize;
+ if (Q_UNLIKELY(fdlen < minsize) || Q_UNLIKELY(fdlen < seg->cmdsize))
+ return ns(QString(), library, errorString);
+
+ const uint32_t MyLoadCommand = sizeof(void *) > 4 ? LC_SEGMENT_64 : LC_SEGMENT;
+ if (seg->cmd != MyLoadCommand)
+ continue;
+
+ // is this the __TEXT segment?
+ if (strcmp(seg->segname, "__TEXT") == 0) {
+ const my_section *sect = reinterpret_cast<const my_section *>(seg + 1);
+ for (uint j = 0; j < seg->nsects; ++j) {
+ // is this the "qtmetadata" section?
+ if (strcmp(sect[j].sectname, "qtmetadata") != 0)
+ continue;
+
+ // found it!
+ if (Q_UNLIKELY(fdlen < sect[j].offset) || Q_UNLIKELY(fdlen < sect[j].size)
+ || Q_UNLIKELY(fdlen < sect[j].offset + sect[j].size))
+ return ns(QString(), library, errorString);
+
+ *pos += sect[j].offset;
+ *sectionlen = sect[j].size;
+ return QtMetaDataSection;
+ }
+ }
+
+ // other type of segment
+ seg = reinterpret_cast<const my_segment_command *>(reinterpret_cast<const char *>(seg) + seg->cmdsize);
+ }
+
+// // No Qt section was found, but at least we know that where the proper architecture's boundaries are
+// return NoQtSection;
+ if (errorString)
+ *errorString = QLibrary::tr("'%1' is not a Qt plugin").arg(library);
+ return NotSuitable;
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/corelib/plugin/qmachparser_p.h b/src/corelib/plugin/qmachparser_p.h
new file mode 100644
index 0000000000..6b2774dab6
--- /dev/null
+++ b/src/corelib/plugin/qmachparser_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Intel Corporation
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMACHPARSER_P_H
+#define QMACHPARSER_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 <qendian.h>
+#include <qglobal.h>
+
+#ifndef QT_NO_LIBRARY
+#if defined(Q_OF_MACH_O)
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+class QLibraryPrivate;
+
+class Q_AUTOTEST_EXPORT QMachOParser
+{
+public:
+ enum { QtMetaDataSection, NoQtSection, NotSuitable };
+ static int parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, long *pos, ulong *sectionlen);
+};
+
+QT_END_NAMESPACE
+
+#endif // defined(Q_OF_ELF) && defined(Q_CC_GNU)
+#endif // QT_NO_LIBRARY
+
+#endif // QMACHPARSER_P_H
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
index e3b76886f1..8337afcb9d 100644
--- a/src/corelib/tools/qalgorithms.h
+++ b/src/corelib/tools/qalgorithms.h
@@ -516,6 +516,73 @@ Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator
} //namespace QAlgorithmsPrivate
+
+// Use __builtin_popcount on gcc. Clang claims to be gcc
+// but has a bug where __builtin_popcount is not marked as
+// constexpr.
+#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
+#define QALGORITHMS_USE_BUILTIN_POPCOUNT
+#endif
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint32 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint8 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint16 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcount(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(quint64 v)
+{
+#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT
+ return __builtin_popcountll(v);
+#else
+ return
+ (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 12) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 24) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 36) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 48) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f +
+ (((v >> 60) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+#endif
+}
+
+Q_DECL_CONSTEXPR inline uint qPopulationCount(long unsigned int v)
+{
+ return qPopulationCount(static_cast<quint64>(v));
+}
+
+#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
+#undef QALGORITHMS_USE_BUILTIN_POPCOUNT
+#endif
+
+
QT_END_NAMESPACE
#endif // QALGORITHMS_H
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index ad6c3d913c..f3dfddec77 100644
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -635,3 +635,34 @@ of \a value in the variable passed as a reference in argument \a n.
\sa {qLess()}{qLess<T>()}
*/
+
+
+/*!
+ \fn uint qPopulationCount(quint8 v)
+ \relates <QtAlgorithms>
+ \since 5.2
+
+ Returns the number of bits set in \a v. This number also called
+ the Hamming Weight of \a v.
+ */
+
+/*!
+ \fn uint qPopulationCount(quint16 v)
+ \relates <QtAlgorithms>
+ \since 5.2
+ \overload
+ */
+
+/*!
+ \fn uint qPopulationCount(quint32 v)
+ \relates <QtAlgorithms>
+ \since 5.2
+ \overload
+ */
+
+/*!
+ \fn uint qPopulationCount(quint64 v)
+ \relates <QtAlgorithms>
+ \since 5.2
+ \overload
+ */
diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp
index b04c4f9c3d..54c1ff8843 100644
--- a/src/corelib/tools/qbitarray.cpp
+++ b/src/corelib/tools/qbitarray.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qbitarray.h"
+#include <qalgorithms.h>
#include <qdatastream.h>
#include <qdebug.h>
#include <string.h>
@@ -160,24 +161,18 @@ int QBitArray::count(bool on) const
for (int i = 0; i < len; ++i)
numBits += testBit(i);
#else
- // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
const quint8 *bits = reinterpret_cast<const quint8 *>(d.data()) + 1;
while (len >= 32) {
quint32 v = quint32(bits[0]) | (quint32(bits[1]) << 8) | (quint32(bits[2]) << 16) | (quint32(bits[3]) << 24);
- quint32 c = ((v & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
- c += (((v & 0xfff000) >> 12) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
- c += ((v >> 24) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
len -= 32;
bits += 4;
- numBits += int(c);
+ numBits += int(qPopulationCount(v));
}
while (len >= 24) {
quint32 v = quint32(bits[0]) | (quint32(bits[1]) << 8) | (quint32(bits[2]) << 16);
- quint32 c = ((v & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
- c += (((v & 0xfff000) >> 12) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
len -= 24;
bits += 3;
- numBits += int(c);
+ numBits += int(qPopulationCount(v));
}
while (len >= 0) {
if (bits[len / 8] & (1 << ((len - 1) & 7)))
diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h
index 1103712627..eaf9b2ff25 100644
--- a/src/corelib/tools/qbitarray.h
+++ b/src/corelib/tools/qbitarray.h
@@ -61,6 +61,7 @@ public:
QBitArray(const QBitArray &other) : d(other.d) {}
inline QBitArray &operator=(const QBitArray &other) { d = other.d; return *this; }
#ifdef Q_COMPILER_RVALUE_REFS
+ inline QBitArray(QBitArray &&other) : d(std::move(other.d)) {}
inline QBitArray &operator=(QBitArray &&other)
{ qSwap(d, other.d); return *this; }
#endif
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 6ce17e5e13..a2d3891f00 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -556,6 +556,7 @@ QByteArray qUncompress(const uchar* data, int nbytes)
d.take(); // realloc was successful
d.reset(p);
d->offset = sizeof(QByteArrayData);
+ d->size = 0; // Shut up valgrind "uninitialized variable" warning
int res = ::uncompress((uchar*)d->data(), &len,
(uchar*)data+4, nbytes-4);
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index d8e3a78cdf..7b99aa1e06 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -158,9 +158,19 @@ static const char monthDays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,
static const char * const qt_shortMonthNames[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+int qt_monthNumberFromShortName(const QString &shortName)
+{
+ for (unsigned int i = 0; i < sizeof(qt_shortMonthNames) / sizeof(qt_shortMonthNames[0]); ++i) {
+ if (shortName == QLatin1String(qt_shortMonthNames[i]))
+ return i + 1;
+ }
+ return -1;
+}
#endif
#ifndef QT_NO_DATESTRING
static QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* dd = 0);
+static void rfcDateImpl(const QString &s, QDate *dd = 0, QTime *dt = 0, int *utfcOffset = 0);
#endif
/*****************************************************************************
@@ -735,6 +745,10 @@ QString QDate::longDayName(int weekday, MonthNameType type)
QLocale::ShortFormat) or QLocale().toString(date,
QLocale::LongFormat).
+ If the \a format is Qt::RFC2822Date, the string is formatted in
+ an \l{RFC 2822} compatible way. An example of this formatting is
+ "20 May 1995".
+
If the date is invalid, an empty string will be returned.
\warning The Qt::ISODate format is only valid for years in the
@@ -771,6 +785,8 @@ QString QDate::toString(Qt::DateFormat f) const
.arg(y);
}
#endif
+ case Qt::RFC2822Date:
+ return toString(QStringLiteral("dd MMM yyyy"));
case Qt::ISODate:
{
if (year() < 0 || year() > 9999)
@@ -1124,6 +1140,11 @@ QDate QDate::fromString(const QString& s, Qt::DateFormat f)
case Qt::DefaultLocaleLongDate:
return fromString(s, QLocale().dateFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
: QLocale::ShortFormat));
+ case Qt::RFC2822Date: {
+ QDate date;
+ rfcDateImpl(s, &date);
+ return date;
+ }
default:
#ifndef QT_NO_TEXTDATE
case Qt::TextDate: {
@@ -1474,15 +1495,15 @@ int QTime::msec() const
/*!
\overload
- Returns the time as a string. Milliseconds are not included. The
- \a format parameter determines the format of the string.
+ Returns the time as a string. The \a format parameter determines
+ the format of the string.
- If \a format is Qt::TextDate, the string format is HH:MM:SS; e.g. 1
- second before midnight would be "23:59:59".
+ If \a format is Qt::TextDate, the string format is HH:MM:SS.zzz;
+ e.g. 1 second before midnight would be "23:59:59.000".
If \a format is Qt::ISODate, the string format corresponds to the
- ISO 8601 extended specification for representations of dates,
- which is also HH:MM:SS.
+ ISO 8601 extended specification (with decimal fractions) for
+ representations of dates; also HH:MM:SS.zzz.
If the \a format is Qt::SystemLocaleShortDate or
Qt::SystemLocaleLongDate, the string format depends on the locale
@@ -1498,6 +1519,10 @@ int QTime::msec() const
QLocale::ShortFormat) or QLocale().toString(time,
QLocale::LongFormat).
+ If the \a format is Qt::RFC2822Date, the string is formatted in
+ an \l{RFC 2822} compatible way. An example of this formatting is
+ "23:59:20".
+
If the time is invalid, an empty string will be returned.
*/
@@ -1518,13 +1543,19 @@ QString QTime::toString(Qt::DateFormat format) const
return QLocale().toString(*this, format == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
: QLocale::ShortFormat);
+ case Qt::RFC2822Date:
+ return QString::fromLatin1("%1:%2:%3")
+ .arg(hour(), 2, 10, QLatin1Char('0'))
+ .arg(minute(), 2, 10, QLatin1Char('0'))
+ .arg(second(), 2, 10, QLatin1Char('0'));
default:
case Qt::ISODate:
case Qt::TextDate:
- return QString::fromLatin1("%1:%2:%3")
+ return QString::fromLatin1("%1:%2:%3.%4")
.arg(hour(), 2, 10, QLatin1Char('0'))
.arg(minute(), 2, 10, QLatin1Char('0'))
- .arg(second(), 2, 10, QLatin1Char('0'));
+ .arg(second(), 2, 10, QLatin1Char('0'))
+ .arg(msec(), 3, 10, QLatin1Char('0'));
}
}
@@ -1789,6 +1820,11 @@ QTime fromStringImpl(const QString &s, Qt::DateFormat f, bool &isMidnight24)
QLocale::FormatType formatType(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat : QLocale::ShortFormat);
return QTime::fromString(s, QLocale().timeFormat(formatType));
}
+ case Qt::RFC2822Date: {
+ QTime time;
+ rfcDateImpl(s, 0, &time);
+ return time;
+ }
case Qt::TextDate:
case Qt::ISODate:
{
@@ -2465,15 +2501,15 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
the default way. QDate::shortDayName(), QDate::shortMonthName(),
and QTime::toString() are used to generate the string, so the
day and month names will be localized names. An example of this
- formatting is "Wed May 20 03:40:13 1998".
+ formatting is "Wed May 20 03:40:13.456 1998".
If the \a format is Qt::ISODate, the string format corresponds
- to the ISO 8601 extended specification for representations of
- dates and times, taking the form YYYY-MM-DDTHH:MM:SS[Z|[+|-]HH:MM],
- depending on the timeSpec() of the QDateTime. If the timeSpec()
- is Qt::UTC, Z will be appended to the string; if the timeSpec() is
- Qt::OffsetFromUTC, the offset in hours and minutes from UTC will
- be appended to the string.
+ to the ISO 8601 extended specification (with decimal fractions) for
+ representations of dates and times, taking the form
+ YYYY-MM-DDTHH:MM:SS.zzz[Z|[+|-]HH:MM], depending on the timeSpec()
+ of the QDateTime. If the timeSpec() is Qt::UTC, Z will be appended
+ to the string; if the timeSpec() is Qt::OffsetFromUTC, the offset
+ in hours and minutes from UTC will be appended to the string.
If the \a format is Qt::SystemLocaleShortDate or
Qt::SystemLocaleLongDate, the string format depends on the locale
@@ -2489,6 +2525,9 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
QLocale::ShortFormat) or QLocale().toString(datetime,
QLocale::LongFormat).
+ If the \a format is Qt::RFC2822Date, the string is formatted
+ following \l{RFC 2822}.
+
If the datetime is invalid, an empty string will be returned.
\warning The Qt::ISODate format is only valid for years in the
@@ -2525,6 +2564,28 @@ QString QDateTime::toString(Qt::DateFormat f) const
default:
break;
}
+ } else if (f == Qt::RFC2822Date) {
+ buf = toString(QStringLiteral("dd MMM yyyy hh:mm:ss "));
+
+ int utcOffset = d->utcOffset;
+ if (timeSpec() == Qt::LocalTime) {
+ QDateTime utc = toUTC();
+ utc.setTimeSpec(timeSpec());
+ utcOffset = utc.secsTo(*this);
+ }
+
+ const int offset = qAbs(utcOffset);
+ buf += QLatin1Char((offset == utcOffset) ? '+' : '-');
+
+ const int hour = offset / 3600;
+ if (hour < 10)
+ buf += QLatin1Char('0');
+ buf += QString::number(hour);
+
+ const int min = (offset - (hour * 3600)) / 60;
+ if (min < 10)
+ buf += QLatin1Char('0');
+ buf += QString::number(min);
}
#ifndef QT_NO_TEXTDATE
else if (f == Qt::TextDate) {
@@ -3332,6 +3393,19 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
return QDateTime(date, time, ts);
}
+ case Qt::RFC2822Date: {
+ QDate date;
+ QTime time;
+ int utcOffset = 0;
+ rfcDateImpl(s, &date, &time, &utcOffset);
+
+ if (!date.isValid() || !time.isValid())
+ return QDateTime();
+
+ QDateTime dateTime(date, time, Qt::UTC);
+ dateTime.setUtcOffset(utcOffset);
+ return dateTime;
+ }
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
case Qt::SystemLocaleLongDate:
@@ -3408,13 +3482,29 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
return QDateTime();
}
- int second = (timeParts.count() > 2) ? timeParts.at(2).toInt(&ok) : 0;
- if (!ok) {
- return QDateTime();
+ int second = 0;
+ int millisecond = 0;
+ if (timeParts.count() > 2) {
+ QStringList secondParts = timeParts.at(2).split(QLatin1Char('.'));
+ if (secondParts.size() > 2) {
+ return QDateTime();
+ }
+
+ second = secondParts.first().toInt(&ok);
+ if (!ok) {
+ return QDateTime();
+ }
+
+ if (secondParts.size() > 1) {
+ millisecond = secondParts.last().toInt(&ok);
+ if (!ok) {
+ return QDateTime();
+ }
+ }
}
QDate date(year, month, day);
- QTime time(hour, minute, second);
+ QTime time(hour, minute, second, millisecond);
if (parts.count() == 5)
return QDateTime(date, time, Qt::LocalTime);
@@ -3936,6 +4026,68 @@ static QString fmtDateTime(const QString& f, const QTime* dt, const QDate* dd)
return buf;
}
+
+static void rfcDateImpl(const QString &s, QDate *dd, QTime *dt, int *utcOffset)
+{
+ int day = -1;
+ int month = -1;
+ int year = -1;
+ int hour = -1;
+ int min = -1;
+ int sec = -1;
+ int hourOffset = 0;
+ int minOffset = 0;
+ bool positiveOffset = false;
+
+ // Matches "Wdy, DD Mon YYYY HH:MM:SS ±hhmm" (Wdy, being optional)
+ QRegExp rex(QStringLiteral("^(?:[A-Z][a-z]+,)?[ \\t]*(\\d{1,2})[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d)(?::(\\d\\d))?)?[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?"));
+ if (s.indexOf(rex) == 0) {
+ if (dd) {
+ day = rex.cap(1).toInt();
+ month = qt_monthNumberFromShortName(rex.cap(2));
+ year = rex.cap(3).toInt();
+ }
+ if (dt) {
+ if (!rex.cap(4).isEmpty()) {
+ hour = rex.cap(4).toInt();
+ min = rex.cap(5).toInt();
+ sec = rex.cap(6).toInt();
+ }
+ positiveOffset = (rex.cap(7) == QStringLiteral("+"));
+ hourOffset = rex.cap(8).toInt();
+ minOffset = rex.cap(9).toInt();
+ }
+ if (utcOffset)
+ *utcOffset = ((hourOffset * 60 + minOffset) * (positiveOffset ? 60 : -60));
+ } else {
+ // Matches "Wdy Mon DD HH:MM:SS YYYY"
+ QRegExp rex(QStringLiteral("^[A-Z][a-z]+[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d):(\\d\\d))?[ \\t]+(\\d\\d\\d\\d)[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?"));
+ if (s.indexOf(rex) == 0) {
+ if (dd) {
+ month = qt_monthNumberFromShortName(rex.cap(1));
+ day = rex.cap(2).toInt();
+ year = rex.cap(6).toInt();
+ }
+ if (dt) {
+ if (!rex.cap(3).isEmpty()) {
+ hour = rex.cap(3).toInt();
+ min = rex.cap(4).toInt();
+ sec = rex.cap(5).toInt();
+ }
+ positiveOffset = (rex.cap(7) == QStringLiteral("+"));
+ hourOffset = rex.cap(8).toInt();
+ minOffset = rex.cap(9).toInt();
+ }
+ if (utcOffset)
+ *utcOffset = ((hourOffset * 60 + minOffset) * (positiveOffset ? 60 : -60));
+ }
+ }
+
+ if (dd)
+ *dd = QDate(year, month, day);
+ if (dt)
+ *dt = QTime(hour, min, sec);
+}
#endif // QT_NO_DATESTRING
#ifdef Q_OS_WIN
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
index 5c1668033c..e5c1e104a2 100644
--- a/src/corelib/tools/qdatetime.h
+++ b/src/corelib/tools/qdatetime.h
@@ -217,11 +217,13 @@ public:
QTime time() const;
Qt::TimeSpec timeSpec() const;
qint64 toMSecsSinceEpoch() const;
+ // ### Qt 6: use quint64 instead of uint
uint toTime_t() const;
void setDate(const QDate &date);
void setTime(const QTime &time);
void setTimeSpec(Qt::TimeSpec spec);
void setMSecsSinceEpoch(qint64 msecs);
+ // ### Qt 6: use quint64 instead of uint
void setTime_t(uint secsSince1Jan1970UTC);
#ifndef QT_NO_DATESTRING
QString toString(Qt::DateFormat f = Qt::TextDate) const;
@@ -255,6 +257,7 @@ public:
static QDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
static QDateTime fromString(const QString &s, const QString &format);
#endif
+ // ### Qt 6: use quint64 instead of uint
static QDateTime fromTime_t(uint secsSince1Jan1970UTC);
static QDateTime fromMSecsSinceEpoch(qint64 msecs);
static qint64 currentMSecsSinceEpoch() Q_DECL_NOTHROW;
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index bc0a14ea72..67e0711796 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -608,14 +608,16 @@ struct BezierEase : public QEasingCurveFunction
sign = -1;
d = d * sign;
- qreal t_i = _fast_cbrt(d);
+ qreal t = _fast_cbrt(d);
//one step of Halley's Method to get a better approximation
- const qreal t_i_cubic = t_i * t_i * t_i;
- qreal t = t_i * (t_i_cubic + d + d) / (t_i_cubic + t_i_cubic + d);
+ const qreal t_cubic = t * t * t;
+ const qreal f = t_cubic + t_cubic + d;
+ if (f != qreal(0.0))
+ t = t * (t_cubic + d + d) / f;
//another step
- /*t_i = t;
+ /*qreal t_i = t;
t_i_cubic = pow(t_i, 3);
t = t_i * (t_i_cubic + d + d) / (t_i_cubic + t_i_cubic + d);*/
diff --git a/src/corelib/tools/qharfbuzz_p.h b/src/corelib/tools/qharfbuzz_p.h
index 27ddb44e91..1471fd5712 100644
--- a/src/corelib/tools/qharfbuzz_p.h
+++ b/src/corelib/tools/qharfbuzz_p.h
@@ -140,20 +140,6 @@ typedef enum {
HB_ScriptCount = HB_Script_Inherited
} HB_Script;
-typedef enum {
- HB_NoJustification= 0, /* Justification can't be applied after this glyph */
- HB_Arabic_Space = 1, /* This glyph represents a space inside arabic text */
- HB_Character = 2, /* Inter-character justification point follows this glyph */
- HB_Space = 4, /* This glyph represents a blank outside an Arabic run */
- HB_Arabic_Normal = 7, /* Normal Middle-Of-Word glyph that connects to the right (begin) */
- HB_Arabic_Waw = 8, /* Next character is final form of Waw/Ain/Qaf/Fa */
- HB_Arabic_BaRa = 9, /* Next two chars are Ba + Ra/Ya/AlefMaksura */
- HB_Arabic_Alef = 10, /* Next character is final form of Alef/Tah/Lam/Kaf/Gaf */
- HB_Arabic_HaaDal = 11, /* Next character is final form of Haa/Dal/Taa Marbutah */
- HB_Arabic_Seen = 12, /* Initial or Medial form Of Seen/Sad */
- HB_Arabic_Kashida = 13 /* Kashida(U+640) in middle of word */
-} HB_JustificationClass;
-
#ifdef __xlC__
typedef unsigned hb_bitfield;
#else
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index e99a67d1e3..25029afe1f 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -509,6 +509,25 @@ private:
static void deleteNode2(QHashData::Node *node);
static void duplicateNode(QHashData::Node *originalNode, void *newNode);
+
+ bool isValidIterator(const iterator &it) const
+ {
+#if defined(QT_DEBUG) && !defined(Q_HASH_NO_ITERATOR_DEBUG)
+ union {
+ QHashData *iteratorHashData;
+ QHashData::Node *node;
+ };
+ node = it.i;
+ while (node->next)
+ node = node->next;
+
+ return (iteratorHashData == d);
+#else
+ Q_UNUSED(it);
+ return true;
+#endif
+ }
+ friend class QSet<Key>;
};
@@ -831,6 +850,8 @@ 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_ASSERT_X(isValidIterator(it), "QHash::erase", "The specified const_iterator argument 'it' is invalid");
+
if (it == iterator(e))
return it;
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 72e1403e76..28d35745a5 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -346,6 +346,11 @@ private:
void node_destruct(Node *n);
void node_copy(Node *from, Node *to, Node *src);
void node_destruct(Node *from, Node *to);
+
+ bool isValidIterator(const iterator &i) const
+ {
+ return (constBegin().i <= i.i) && (i.i <= constEnd().i);
+ }
};
#if defined(Q_CC_BOR)
@@ -433,6 +438,8 @@ Q_INLINE_TEMPLATE QList<T> &QList<T>::operator=(const QList<T> &l)
template <typename T>
inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QList::insert", "The specified iterator argument 'before' is invalid");
+
int iBefore = int(before.i - reinterpret_cast<Node *>(p.begin()));
Node *n = reinterpret_cast<Node *>(p.insert(iBefore));
QT_TRY {
@@ -445,8 +452,11 @@ inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t)
}
template <typename T>
inline typename QList<T>::iterator QList<T>::erase(iterator it)
-{ node_destruct(it.i);
- return reinterpret_cast<Node *>(p.erase(reinterpret_cast<void**>(it.i))); }
+{
+ Q_ASSERT_X(isValidIterator(it), "QList::erase", "The specified iterator argument 'it' is invalid");
+ node_destruct(it.i);
+ return reinterpret_cast<Node *>(p.erase(reinterpret_cast<void**>(it.i)));
+}
template <typename T>
inline const T &QList<T>::at(int i) const
{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::at", "index out of range");
@@ -807,6 +817,9 @@ template <typename T>
Q_OUTOFLINE_TEMPLATE typename QList<T>::iterator QList<T>::erase(typename QList<T>::iterator afirst,
typename QList<T>::iterator alast)
{
+ Q_ASSERT_X(isValidIterator(afirst), "QList::erase", "The specified iterator argument 'afirst' is invalid");
+ Q_ASSERT_X(isValidIterator(alast), "QList::erase", "The specified iterator argument 'alast' is invalid");
+
for (Node *n = afirst.i; n < alast.i; ++n)
node_destruct(n);
int idx = afirst - begin();
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index 78fa336b7c..0fc3f87726 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -775,13 +775,14 @@ public:
SouthSudan = 254,
Bonaire = 255,
SintMaarten = 256,
+ Kosovo = 257,
DemocraticRepublicOfCongo = CongoKinshasa,
PeoplesRepublicOfCongo = CongoBrazzaville,
DemocraticRepublicOfKorea = NorthKorea,
RepublicOfKorea = SouthKorea,
RussianFederation = Russia,
SyrianArabRepublic = Syria,
- LastCountry = SintMaarten
+ LastCountry = Kosovo
};
// GENERATED PART ENDS HERE
diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc
index 150e4a18ce..a3b38c41f4 100644
--- a/src/corelib/tools/qlocale.qdoc
+++ b/src/corelib/tools/qlocale.qdoc
@@ -92,7 +92,7 @@
\note For the current keyboard input locale take a look at
QInputMethod::locale().
- QLocale's data is based on Common Locale Data Repository v23.
+ QLocale's data is based on Common Locale Data Repository v23.1.
The double-to-string and string-to-double conversion functions are
covered by the following licenses:
@@ -584,6 +584,7 @@
\value SouthKorea
\value DemocraticRepublicOfKorea Obsolete, please use NorthKorea
\value RepublicOfKorea Obsolete, please use SouthKorea
+ \value Kosovo
\value Kuwait
\value Kyrgyzstan
\value Laos
diff --git a/src/corelib/tools/qlocale_data_p.h b/src/corelib/tools/qlocale_data_p.h
index 6642f824ea..46b3eef658 100644
--- a/src/corelib/tools/qlocale_data_p.h
+++ b/src/corelib/tools/qlocale_data_p.h
@@ -77,8 +77,8 @@ static const int ImperialMeasurementSystemsCount =
// GENERATED PART STARTS HERE
/*
- This part of the file was generated on 2013-03-16 from the
- Common Locale Data Repository v23
+ This part of the file was generated on 2013-08-10 from the
+ Common Locale Data Repository v23.1
http://www.unicode.org/cldr/
@@ -771,215 +771,215 @@ static const quint16 locale_index[] = {
3, // Afar
6, // Afrikaans
8, // Albanian
- 10, // Amharic
- 11, // Arabic
- 37, // Armenian
- 38, // Assamese
+ 11, // Amharic
+ 12, // Arabic
+ 38, // Armenian
+ 39, // Assamese
0, // Aymara
- 39, // Azerbaijani
+ 40, // Azerbaijani
0, // Bashkir
- 41, // Basque
- 42, // Bengali
- 44, // Dzongkha
+ 42, // Basque
+ 43, // Bengali
+ 45, // Dzongkha
0, // Bihari
0, // Bislama
- 45, // Breton
- 46, // Bulgarian
- 47, // Burmese
- 48, // Belarusian
- 49, // Khmer
- 50, // Catalan
- 52, // Chinese
+ 46, // Breton
+ 47, // Bulgarian
+ 48, // Burmese
+ 49, // Belarusian
+ 50, // Khmer
+ 51, // Catalan
+ 53, // Chinese
0, // Corsican
- 59, // Croatian
- 61, // Czech
- 62, // Danish
- 63, // Dutch
- 69, // English
+ 60, // Croatian
+ 62, // Czech
+ 63, // Danish
+ 64, // Dutch
+ 70, // English
0, // Esperanto
- 140, // Estonian
- 141, // Faroese
+ 141, // Estonian
+ 142, // Faroese
0, // Fijian
- 142, // Finnish
- 143, // French
+ 143, // Finnish
+ 144, // French
0, // Western Frisian
- 187, // Gaelic
- 188, // Galician
- 189, // Georgian
- 190, // German
- 196, // Greek
- 198, // Greenlandic
+ 188, // Gaelic
+ 189, // Galician
+ 190, // Georgian
+ 191, // German
+ 197, // Greek
+ 199, // Greenlandic
0, // Guarani
- 199, // Gujarati
- 200, // Hausa
- 203, // Hebrew
- 204, // Hindi
- 205, // Hungarian
- 206, // Icelandic
- 207, // Indonesian
- 208, // Interlingua
+ 200, // Gujarati
+ 201, // Hausa
+ 204, // Hebrew
+ 205, // Hindi
+ 206, // Hungarian
+ 207, // Icelandic
+ 208, // Indonesian
+ 209, // Interlingua
0, // Interlingue
0, // Inuktitut
0, // Inupiak
- 209, // Irish
- 210, // Italian
- 213, // Japanese
+ 210, // Irish
+ 211, // Italian
+ 214, // Japanese
0, // Javanese
- 214, // Kannada
- 215, // Kashmiri
- 216, // Kazakh
- 217, // Kinyarwanda
- 218, // Kirghiz
- 219, // Korean
+ 215, // Kannada
+ 216, // Kashmiri
+ 217, // Kazakh
+ 218, // Kinyarwanda
+ 219, // Kirghiz
+ 220, // Korean
0, // Kurdish
- 221, // Rundi
- 222, // Lao
+ 222, // Rundi
+ 223, // Lao
0, // Latin
- 223, // Latvian
- 224, // Lingala
- 228, // Lithuanian
- 229, // Macedonian
- 230, // Malagasy
- 231, // Malay
- 234, // Malayalam
- 235, // Maltese
+ 224, // Latvian
+ 225, // Lingala
+ 229, // Lithuanian
+ 230, // Macedonian
+ 231, // Malagasy
+ 232, // Malay
+ 235, // Malayalam
+ 236, // Maltese
0, // Maori
- 236, // Marathi
+ 237, // Marathi
0, // Marshallese
- 237, // Mongolian
+ 238, // Mongolian
0, // Nauru
- 238, // Nepali
- 240, // NorwegianBokmal
+ 239, // Nepali
+ 241, // NorwegianBokmal
0, // Occitan
- 241, // Oriya
- 242, // Pashto
- 243, // Persian
- 245, // Polish
- 246, // Portuguese
- 255, // Punjabi
+ 242, // Oriya
+ 243, // Pashto
+ 244, // Persian
+ 246, // Polish
+ 247, // Portuguese
+ 256, // Punjabi
0, // Quechua
- 257, // Romansh
- 258, // Romanian
- 260, // Russian
+ 258, // Romansh
+ 259, // Romanian
+ 261, // Russian
0, // Samoan
- 266, // Sango
+ 267, // Sango
0, // Sanskrit
- 267, // Serbian
- 273, // Ossetic
- 275, // Southern Sotho
- 277, // Tswana
- 279, // Shona
+ 268, // Serbian
+ 276, // Ossetic
+ 278, // Southern Sotho
+ 280, // Tswana
+ 282, // Shona
0, // Sindhi
- 280, // Sinhala
- 281, // Swati
- 283, // Slovak
- 284, // Slovenian
- 285, // Somali
- 289, // Spanish
+ 283, // Sinhala
+ 284, // Swati
+ 286, // Slovak
+ 287, // Slovenian
+ 288, // Somali
+ 292, // Spanish
0, // Sundanese
- 315, // Swahili
- 318, // Swedish
+ 318, // Swahili
+ 321, // Swedish
0, // Sardinian
- 321, // Tajik
- 322, // Tamil
+ 324, // Tajik
+ 325, // Tamil
0, // Tatar
- 326, // Telugu
- 327, // Thai
- 328, // Tibetan
- 330, // Tigrinya
- 332, // Tongan
- 333, // Tsonga
- 334, // Turkish
+ 329, // Telugu
+ 330, // Thai
+ 331, // Tibetan
+ 333, // Tigrinya
+ 335, // Tongan
+ 336, // Tsonga
+ 337, // Turkish
0, // Turkmen
0, // Tahitian
0, // Uighur
- 336, // Ukrainian
- 337, // Urdu
- 339, // Uzbek
- 342, // Vietnamese
+ 339, // Ukrainian
+ 340, // Urdu
+ 342, // Uzbek
+ 345, // Vietnamese
0, // Volapuk
- 343, // Welsh
+ 346, // Welsh
0, // Wolof
- 344, // Xhosa
+ 347, // Xhosa
0, // Yiddish
- 345, // Yoruba
+ 348, // Yoruba
0, // Zhuang
- 346, // Zulu
- 347, // NorwegianNynorsk
- 348, // Bosnian
+ 349, // Zulu
+ 350, // NorwegianNynorsk
+ 351, // Bosnian
0, // Divehi
- 350, // Manx
- 351, // Cornish
- 352, // Akan
- 353, // Konkani
+ 353, // Manx
+ 354, // Cornish
+ 355, // Akan
+ 356, // Konkani
0, // Ga
- 354, // Igbo
- 355, // Kamba
+ 357, // Igbo
+ 358, // Kamba
0, // Syriac
- 356, // Blin
+ 359, // Blin
0, // Geez
0, // Koro
0, // Sidamo
0, // Atsam
- 357, // Tigre
+ 360, // Tigre
0, // Jju
- 358, // Friulian
- 359, // Venda
- 360, // Ewe
- 362, // Walamo
- 363, // Hawaiian
+ 361, // Friulian
+ 362, // Venda
+ 363, // Ewe
+ 365, // Walamo
+ 366, // Hawaiian
0, // Tyap
0, // Nyanja
- 364, // Filipino
- 365, // Swiss German
- 366, // Sichuan Yi
+ 367, // Filipino
+ 368, // Swiss German
+ 369, // Sichuan Yi
0, // Kpelle
0, // Low German
- 367, // South Ndebele
- 368, // Northern Sotho
- 369, // Northern Sami
+ 370, // South Ndebele
+ 371, // Northern Sotho
+ 372, // Northern Sami
0, // Taroko
- 371, // Gusii
- 372, // Taita
- 373, // Fulah
- 374, // Kikuyu
- 375, // Samburu
- 376, // Sena
- 377, // North Ndebele
- 378, // Rombo
- 379, // Tachelhit
- 381, // Kabyle
- 382, // Nyankole
- 383, // Bena
- 384, // Vunjo
- 385, // Bambara
- 386, // Embu
- 387, // Cherokee
- 388, // Morisyen
- 389, // Makonde
- 390, // Langi
- 391, // Ganda
- 392, // Bemba
- 393, // Kabuverdianu
- 394, // Meru
- 395, // Kalenjin
- 396, // Nama
- 397, // Machame
- 398, // Colognian
- 399, // Masai
- 401, // Soga
- 402, // Luyia
- 403, // Asu
- 404, // Teso
- 406, // Saho
- 407, // Koyra Chiini
- 408, // Rwa
- 409, // Luo
- 410, // Chiga
- 411, // Central Morocco Tamazight
- 412, // Koyraboro Senni
- 413, // Shambala
- 414, // Bodo
+ 374, // Gusii
+ 375, // Taita
+ 376, // Fulah
+ 377, // Kikuyu
+ 378, // Samburu
+ 379, // Sena
+ 380, // North Ndebele
+ 381, // Rombo
+ 382, // Tachelhit
+ 384, // Kabyle
+ 385, // Nyankole
+ 386, // Bena
+ 387, // Vunjo
+ 388, // Bambara
+ 389, // Embu
+ 390, // Cherokee
+ 391, // Morisyen
+ 392, // Makonde
+ 393, // Langi
+ 394, // Ganda
+ 395, // Bemba
+ 396, // Kabuverdianu
+ 397, // Meru
+ 398, // Kalenjin
+ 399, // Nama
+ 400, // Machame
+ 401, // Colognian
+ 402, // Masai
+ 404, // Soga
+ 405, // Luyia
+ 406, // Asu
+ 407, // Teso
+ 409, // Saho
+ 410, // Koyra Chiini
+ 411, // Rwa
+ 412, // Luo
+ 413, // Chiga
+ 414, // Central Morocco Tamazight
+ 415, // Koyraboro Senni
+ 416, // Shambala
+ 417, // Bodo
0, // Avaric
0, // Chamorro
0, // Chechen
@@ -994,37 +994,37 @@ static const quint16 locale_index[] = {
0, // Kongo
0, // Kwanyama
0, // Limburgish
- 415, // LubaKatanga
+ 418, // LubaKatanga
0, // Luxembourgish
0, // Navaho
0, // Ndonga
0, // Ojibwa
0, // Pali
0, // Walloon
- 416, // Aghem
- 417, // Basaa
- 418, // Zarma
- 419, // Duala
- 420, // JolaFonyi
- 421, // Ewondo
- 422, // Bafia
- 423, // MakhuwaMeetto
- 424, // Mundang
- 425, // Kwasio
- 426, // Nuer
- 427, // Sakha
- 428, // Sangu
- 429, // Congo Swahili
- 430, // Tasawaq
- 431, // Vai
- 433, // Walser
- 434, // Yangben
+ 419, // Aghem
+ 420, // Basaa
+ 421, // Zarma
+ 422, // Duala
+ 423, // JolaFonyi
+ 424, // Ewondo
+ 425, // Bafia
+ 426, // MakhuwaMeetto
+ 427, // Mundang
+ 428, // Kwasio
+ 429, // Nuer
+ 430, // Sakha
+ 431, // Sangu
+ 432, // Congo Swahili
+ 433, // Tasawaq
+ 434, // Vai
+ 436, // Walser
+ 437, // Yangben
0, // Avestan
- 435, // Asturian
- 436, // Ngomba
- 437, // Kako
- 438, // Meta
- 439, // Ngiemboon
+ 438, // Asturian
+ 439, // Ngomba
+ 440, // Kako
+ 441, // Meta
+ 442, // Ngiemboon
0, // Aragonese
0, // Akkadian
0, // AncientEgyptian
@@ -1091,436 +1091,439 @@ static const QLocaleData locale_data[] = {
{ 5, 7, 148, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 72,10 , 99,16 , 37,5 , 8,10 , 653,48 , 701,92 , 134,24 , 653,48 , 701,92 , 134,24 , 290,21 , 311,58 , 369,14 , 290,21 , 311,58 , 369,14 , 4,3 , 4,3 , {78,65,68}, 12,1 , 58,23 , 14,5 , 4,0 , 50,9 , 70,7 , 2, 1, 1, 6, 7 }, // Afrikaans/Latin/Namibia
{ 6, 7, 2, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 115,8 , 123,18 , 42,7 , 49,12 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,2 , 7,2 , {65,76,76}, 13,3 , 0,7 , 4,4 , 4,0 , 77,5 , 82,9 , 0, 0, 1, 6, 7 }, // Albanian/Latin/Albania
{ 6, 7, 127, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 115,8 , 123,18 , 42,7 , 49,12 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,2 , 7,2 , {77,75,68}, 16,3 , 0,7 , 4,4 , 4,0 , 77,5 , 91,8 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Macedonia
- { 7, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 14,6 , 14,6 , 20,9 , 29,8 , 141,10 , 10,17 , 18,7 , 25,12 , 943,46 , 989,61 , 1050,24 , 1074,46 , 1120,62 , 1050,24 , 483,27 , 510,28 , 538,14 , 483,27 , 510,28 , 538,14 , 9,3 , 9,4 , {69,84,66}, 19,2 , 81,34 , 4,4 , 8,6 , 99,4 , 103,5 , 2, 1, 7, 6, 7 }, // Amharic/Ethiopic/Ethiopia
- { 8, 1, 64, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {69,71,80}, 21,5 , 115,70 , 14,5 , 19,6 , 108,7 , 115,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Egypt
- { 8, 1, 3, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {68,90,68}, 26,5 , 185,91 , 14,5 , 19,6 , 108,7 , 118,7 , 2, 1, 6, 4, 5 }, // Arabic/Arabic/Algeria
- { 8, 1, 17, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {66,72,68}, 31,5 , 276,91 , 14,5 , 19,6 , 108,7 , 125,7 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Bahrain
- { 8, 1, 42, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {88,65,70}, 36,4 , 367,84 , 14,5 , 19,6 , 108,7 , 132,4 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Chad
- { 8, 1, 48, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {75,77,70}, 40,7 , 451,105 , 14,5 , 19,6 , 108,7 , 136,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Comoros
- { 8, 1, 59, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {68,74,70}, 5,3 , 556,84 , 14,5 , 19,6 , 108,7 , 145,6 , 0, 0, 6, 6, 7 }, // Arabic/Arabic/Djibouti
- { 8, 1, 67, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {69,82,78}, 8,3 , 640,91 , 14,5 , 19,6 , 108,7 , 151,7 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Eritrea
- { 8, 1, 103, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1376,92 , 1376,92 , 1468,24 , 1492,92 , 1376,92 , 1468,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,81,68}, 47,5 , 731,84 , 14,5 , 19,6 , 108,7 , 158,6 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Iraq
- { 8, 1, 105, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,76,83}, 52,1 , 815,133 , 14,5 , 19,6 , 108,7 , 164,7 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Israel
- { 8, 1, 109, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {74,79,68}, 53,5 , 948,84 , 14,5 , 19,6 , 108,7 , 171,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Jordan
- { 8, 1, 115, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {75,87,68}, 58,5 , 1032,84 , 14,5 , 19,6 , 108,7 , 177,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Kuwait
- { 8, 1, 119, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {76,66,80}, 63,5 , 1116,84 , 14,5 , 19,6 , 108,7 , 183,5 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Lebanon
- { 8, 1, 122, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {76,89,68}, 68,5 , 1200,77 , 14,5 , 19,6 , 108,7 , 188,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Libya
- { 8, 1, 136, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,82,79}, 73,5 , 1277,112 , 14,5 , 19,6 , 108,7 , 193,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Mauritania
- { 8, 1, 145, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1584,71 , 1655,71 , 1726,24 , 1655,71 , 1750,71 , 1821,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,65,68}, 78,5 , 1389,77 , 14,5 , 19,6 , 108,7 , 202,6 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Morocco
- { 8, 1, 162, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {79,77,82}, 83,5 , 1466,77 , 14,5 , 19,6 , 108,7 , 208,5 , 3, 0, 6, 4, 5 }, // Arabic/Arabic/Oman
- { 8, 1, 165, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,76,83}, 52,1 , 815,133 , 14,5 , 19,6 , 108,7 , 213,6 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/PalestinianTerritories
- { 8, 1, 175, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {81,65,82}, 88,5 , 1543,70 , 4,4 , 4,0 , 108,7 , 219,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Qatar
- { 8, 1, 186, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,65,82}, 93,5 , 1613,77 , 4,4 , 4,0 , 108,7 , 222,24 , 2, 1, 6, 4, 5 }, // Arabic/Arabic/SaudiArabia
- { 8, 1, 194, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,79,83}, 98,1 , 1690,77 , 14,5 , 19,6 , 108,7 , 246,7 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Somalia
- { 8, 1, 201, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,68,71}, 0,0 , 1767,84 , 14,5 , 19,6 , 108,7 , 253,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Sudan
- { 8, 1, 207, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,89,80}, 99,5 , 1851,77 , 4,4 , 4,0 , 108,7 , 260,5 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Syria
- { 8, 1, 216, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {84,78,68}, 104,5 , 1928,77 , 4,4 , 4,0 , 108,7 , 265,4 , 3, 0, 7, 5, 6 }, // Arabic/Arabic/Tunisia
- { 8, 1, 223, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {65,69,68}, 109,5 , 2005,91 , 14,5 , 19,6 , 108,7 , 269,24 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/UnitedArabEmirates
- { 8, 1, 236, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,65,68}, 78,5 , 1389,77 , 14,5 , 19,6 , 108,7 , 293,15 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/WesternSahara
- { 8, 1, 237, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {89,69,82}, 114,5 , 2096,70 , 4,4 , 4,0 , 108,7 , 308,5 , 0, 0, 6, 4, 5 }, // Arabic/Arabic/Yemen
- { 9, 10, 11, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 58,7 , 58,7 , 187,8 , 195,21 , 61,4 , 65,10 , 1845,48 , 1893,106 , 1999,24 , 1845,48 , 1893,106 , 1999,24 , 618,28 , 646,62 , 708,15 , 618,28 , 646,62 , 708,15 , 13,12 , 14,12 , {65,77,68}, 119,3 , 2166,46 , 25,5 , 4,0 , 313,7 , 320,8 , 0, 0, 1, 6, 7 }, // Armenian/Armenian/Armenia
- { 10, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 216,8 , 224,18 , 75,8 , 83,12 , 2023,62 , 2085,88 , 158,27 , 2023,62 , 2085,88 , 158,27 , 723,37 , 760,58 , 85,14 , 723,37 , 760,58 , 85,14 , 25,9 , 26,7 , {73,78,82}, 122,1 , 0,7 , 14,5 , 4,0 , 328,7 , 335,4 , 2, 1, 7, 7, 7 }, // Assamese/Bengali/India
- { 12, 7, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 250,19 , 37,5 , 8,10 , 2173,48 , 2221,77 , 158,27 , 2173,48 , 2221,77 , 158,27 , 818,26 , 844,67 , 99,14 , 818,26 , 844,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 123,4 , 2212,41 , 14,5 , 4,0 , 339,12 , 351,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Latin/Azerbaijan
- { 12, 2, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 250,19 , 37,5 , 8,10 , 2298,77 , 2298,77 , 158,27 , 2298,77 , 2298,77 , 158,27 , 911,67 , 911,67 , 99,14 , 911,67 , 911,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 127,4 , 2253,12 , 14,5 , 4,0 , 361,10 , 361,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Cyrillic/Azerbaijan
- { 14, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 65,9 , 65,9 , 72,10 , 269,18 , 37,5 , 8,10 , 2375,48 , 2423,93 , 2516,24 , 2375,48 , 2423,93 , 2516,24 , 978,21 , 999,68 , 1067,14 , 978,21 , 999,68 , 1081,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2265,12 , 25,5 , 30,7 , 371,7 , 378,8 , 2, 1, 1, 6, 7 }, // Basque/Latin/Spain
- { 15, 11, 18, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 74,10 , 84,9 , 287,6 , 224,18 , 18,7 , 25,12 , 2540,90 , 2540,90 , 2630,33 , 2540,90 , 2540,90 , 2630,33 , 1095,37 , 1132,58 , 1190,18 , 1095,37 , 1132,58 , 1190,18 , 34,9 , 33,7 , {66,68,84}, 132,1 , 2277,21 , 0,4 , 37,6 , 386,5 , 391,8 , 2, 1, 5, 6, 7 }, // Bengali/Bengali/Bangladesh
- { 15, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 74,10 , 84,9 , 287,6 , 224,18 , 18,7 , 25,12 , 2540,90 , 2540,90 , 2630,33 , 2540,90 , 2540,90 , 2630,33 , 1095,37 , 1132,58 , 1190,18 , 1095,37 , 1132,58 , 1190,18 , 34,9 , 33,7 , {73,78,82}, 122,1 , 2298,19 , 0,4 , 37,6 , 386,5 , 399,4 , 2, 1, 7, 7, 7 }, // Bengali/Bengali/India
- { 16, 31, 25, 46, 44, 59, 37, 3872, 45, 43, 101, 8220, 8221, 8216, 8217, 93,9 , 93,9 , 93,9 , 93,9 , 72,10 , 293,30 , 95,22 , 117,27 , 2663,63 , 2726,191 , 2917,27 , 2944,27 , 2971,132 , 3103,27 , 1208,34 , 1242,79 , 1321,27 , 1208,34 , 1242,79 , 1321,27 , 43,5 , 40,6 , {66,84,78}, 133,3 , 2317,15 , 4,4 , 4,0 , 403,6 , 409,5 , 2, 1, 7, 6, 7 }, // Dzongkha/Tibetan/Bhutan
- { 19, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 3130,55 , 3185,78 , 158,27 , 3130,55 , 3185,78 , 158,27 , 1348,33 , 1381,43 , 1424,21 , 1348,33 , 1381,43 , 1424,21 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2332,11 , 14,5 , 4,0 , 414,9 , 423,5 , 2, 1, 1, 6, 7 }, // Breton/Latin/France
- { 20, 2, 33, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 340,18 , 37,5 , 8,10 , 3263,59 , 3322,82 , 3404,24 , 3263,59 , 3322,82 , 3404,24 , 1445,21 , 1466,55 , 1521,14 , 1445,21 , 1466,55 , 1521,14 , 48,7 , 46,7 , {66,71,78}, 136,3 , 2343,47 , 25,5 , 4,0 , 428,9 , 437,8 , 2, 1, 1, 6, 7 }, // Bulgarian/Cyrillic/Bulgaria
- { 21, 25, 147, 46, 44, 4170, 37, 4160, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 3428,43 , 3471,88 , 3559,24 , 3428,43 , 3471,88 , 3559,24 , 1535,25 , 1560,54 , 1614,14 , 1535,25 , 1560,54 , 1614,14 , 55,5 , 53,3 , {77,77,75}, 139,1 , 2390,18 , 14,5 , 4,0 , 445,3 , 448,6 , 0, 0, 7, 6, 7 }, // Burmese/Myanmar/Myanmar
- { 22, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 358,6 , 10,17 , 144,5 , 149,10 , 3583,48 , 3631,99 , 3730,24 , 3754,48 , 3802,95 , 3897,24 , 1628,21 , 1649,56 , 1705,14 , 1628,21 , 1649,56 , 1705,14 , 60,10 , 56,13 , {66,89,82}, 140,2 , 2408,23 , 4,4 , 4,0 , 454,10 , 464,8 , 0, 0, 7, 6, 7 }, // Belarusian/Cyrillic/Belarus
- { 23, 20, 36, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 109,9 , 364,8 , 10,17 , 18,7 , 25,12 , 3921,71 , 3921,71 , 158,27 , 3921,71 , 3921,71 , 158,27 , 1719,46 , 1719,46 , 1765,14 , 1719,46 , 1719,46 , 1765,14 , 70,5 , 69,5 , {75,72,82}, 142,1 , 2431,18 , 4,4 , 8,6 , 472,5 , 477,7 , 2, 1, 7, 6, 7 }, // Khmer/Khmer/Cambodia
- { 24, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 27,8 , 372,21 , 159,4 , 163,9 , 3992,60 , 4052,82 , 4134,24 , 4158,93 , 4251,115 , 4366,24 , 1779,21 , 1800,60 , 1779,21 , 1860,28 , 1888,60 , 1779,21 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2449,20 , 4,4 , 8,6 , 484,6 , 490,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Spain
- { 24, 7, 5, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 27,8 , 372,21 , 159,4 , 163,9 , 3992,60 , 4052,82 , 4134,24 , 4158,93 , 4251,115 , 4366,24 , 1779,21 , 1800,60 , 1779,21 , 1860,28 , 1888,60 , 1779,21 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2449,20 , 4,4 , 8,6 , 484,6 , 497,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Andorra
- { 25, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 393,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {67,78,89}, 143,1 , 2469,10 , 4,4 , 8,6 , 504,4 , 508,2 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/China
- { 25, 5, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {72,75,68}, 12,1 , 2479,9 , 4,4 , 4,0 , 504,4 , 510,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/HongKong
- { 25, 5, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {77,79,80}, 144,4 , 2488,10 , 4,4 , 4,0 , 504,4 , 519,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Macau
- { 25, 5, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 27,8 , 399,13 , 188,7 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {83,71,68}, 12,1 , 2498,11 , 4,4 , 4,0 , 504,4 , 528,3 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Singapore
- { 25, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 195,13 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {72,75,68}, 12,1 , 2479,9 , 4,4 , 8,6 , 531,4 , 535,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/HongKong
- { 25, 6, 126, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 412,7 , 419,15 , 172,6 , 195,13 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {77,79,80}, 144,4 , 2509,10 , 4,4 , 4,0 , 531,4 , 549,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Macau
- { 25, 6, 208, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 179,8 , 399,13 , 172,6 , 208,11 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {84,87,68}, 148,3 , 2519,10 , 4,4 , 4,0 , 531,4 , 563,2 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Taiwan
- { 27, 7, 54, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 434,9 , 443,19 , 37,5 , 8,10 , 4467,49 , 4516,94 , 4610,39 , 4467,49 , 4649,98 , 4610,39 , 2032,28 , 2060,58 , 2118,14 , 2032,28 , 2060,58 , 2132,14 , 0,2 , 0,2 , {72,82,75}, 151,2 , 2529,74 , 25,5 , 4,0 , 565,8 , 573,8 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Croatia
- { 27, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 434,9 , 443,19 , 37,5 , 8,10 , 4467,49 , 4516,94 , 4610,39 , 4467,49 , 4649,98 , 4610,39 , 2032,28 , 2060,58 , 2118,14 , 2032,28 , 2060,58 , 2132,14 , 0,2 , 0,2 , {66,65,77}, 153,2 , 2603,106 , 25,5 , 4,0 , 565,8 , 581,19 , 2, 1, 1, 6, 7 }, // Croatian/Latin/BosniaAndHerzegowina
- { 28, 7, 57, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 135,7 , 135,7 , 187,8 , 462,18 , 61,4 , 219,9 , 4747,48 , 4795,82 , 4877,24 , 4747,48 , 4901,84 , 158,27 , 2146,21 , 2167,49 , 2216,14 , 2146,21 , 2167,49 , 2216,14 , 81,4 , 80,4 , {67,90,75}, 155,2 , 2709,56 , 25,5 , 4,0 , 600,7 , 607,15 , 2, 1, 1, 6, 7 }, // Czech/Latin/CzechRepublic
- { 29, 7, 58, 44, 46, 44, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 27,8 , 480,23 , 144,5 , 149,10 , 4985,48 , 5033,84 , 134,24 , 5117,59 , 5033,84 , 134,24 , 2230,28 , 2258,51 , 2309,14 , 2323,35 , 2258,51 , 2309,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 2765,42 , 25,5 , 4,0 , 622,5 , 627,7 , 2, 1, 1, 6, 7 }, // Danish/Latin/Denmark
- { 30, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2807,19 , 14,5 , 19,6 , 634,10 , 644,9 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Netherlands
- { 30, 7, 12, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,87,71}, 159,4 , 2826,55 , 14,5 , 19,6 , 634,10 , 653,5 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Aruba
- { 30, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 511,7 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2807,19 , 25,5 , 4,0 , 658,6 , 664,6 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Belgium
- { 30, 7, 152, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,78,71}, 163,4 , 2881,97 , 14,5 , 19,6 , 634,10 , 670,7 , 2, 1, 1, 6, 7 }, // Dutch/Latin/CuraSao
- { 30, 7, 202, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {83,82,68}, 12,1 , 2978,24 , 14,5 , 19,6 , 634,10 , 677,8 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Suriname
- { 30, 7, 256, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,78,71}, 163,4 , 2881,97 , 14,5 , 19,6 , 634,10 , 685,12 , 2, 1, 1, 6, 7 }, // Dutch/Latin/SintMaarten
- { 31, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 697,12 , 709,13 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStates
- { 31, 3, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 5371,80 , 5451,154 , 5605,36 , 5371,80 , 5451,154 , 5605,36 , 2452,49 , 2501,85 , 2586,21 , 2452,49 , 2501,85 , 2586,21 , 85,4 , 84,4 , {85,83,68}, 12,1 , 0,7 , 14,5 , 4,0 , 722,10 , 732,25 , 2, 1, 7, 6, 7 }, // English/Deseret/UnitedStates
- { 31, 7, 4, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 764,14 , 2, 1, 7, 6, 7 }, // English/Latin/AmericanSamoa
- { 31, 7, 9, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 778,19 , 2, 1, 7, 6, 7 }, // English/Latin/AntiguaAndBarbuda
- { 31, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 511,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {65,85,68}, 12,1 , 3108,59 , 4,4 , 4,0 , 797,18 , 815,9 , 2, 1, 7, 6, 7 }, // English/Latin/Australia
- { 31, 7, 16, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,83,68}, 12,1 , 3167,53 , 4,4 , 8,6 , 757,7 , 824,7 , 2, 1, 7, 6, 7 }, // English/Latin/Bahamas
- { 31, 7, 19, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,66,68}, 12,1 , 3220,56 , 4,4 , 8,6 , 757,7 , 831,8 , 2, 1, 1, 6, 7 }, // English/Latin/Barbados
- { 31, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 37,5 , 228,24 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {69,85,82}, 131,1 , 2807,19 , 25,5 , 4,0 , 757,7 , 839,7 , 2, 1, 1, 6, 7 }, // English/Latin/Belgium
- { 31, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 27,8 , 524,12 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,90,68}, 12,1 , 3276,47 , 4,4 , 4,0 , 757,7 , 846,6 , 2, 1, 7, 6, 7 }, // English/Latin/Belize
- { 31, 7, 24, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,77,68}, 12,1 , 3323,53 , 4,4 , 8,6 , 757,7 , 852,7 , 2, 1, 1, 6, 7 }, // English/Latin/Bermuda
- { 31, 7, 28, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 27,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,87,80}, 170,1 , 3376,50 , 4,4 , 4,0 , 757,7 , 859,8 , 2, 1, 7, 6, 7 }, // English/Latin/Botswana
- { 31, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 3426,50 , 4,4 , 8,6 , 757,7 , 867,8 , 0, 0, 1, 6, 7 }, // English/Latin/Cameroon
- { 31, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 3476,53 , 4,4 , 8,6 , 875,16 , 891,6 , 2, 0, 7, 6, 7 }, // English/Latin/Canada
- { 31, 7, 40, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,89,68}, 12,1 , 3529,71 , 4,4 , 8,6 , 757,7 , 897,14 , 2, 1, 1, 6, 7 }, // English/Latin/CaymanIslands
- { 31, 7, 60, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 911,8 , 2, 1, 7, 6, 7 }, // English/Latin/Dominica
- { 31, 7, 72, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {70,74,68}, 12,1 , 3600,47 , 4,4 , 8,6 , 757,7 , 919,4 , 2, 1, 1, 6, 7 }, // English/Latin/Fiji
- { 31, 7, 75, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3647,47 , 4,4 , 4,0 , 757,7 , 923,8 , 2, 1, 1, 6, 7 }, // English/Latin/Guernsey
- { 31, 7, 80, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,77,68}, 172,1 , 3694,50 , 4,4 , 8,6 , 757,7 , 931,6 , 2, 1, 1, 6, 7 }, // English/Latin/Gambia
- { 31, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,72,83}, 173,3 , 3744,47 , 4,4 , 8,6 , 757,7 , 937,5 , 2, 1, 1, 6, 7 }, // English/Latin/Ghana
- { 31, 7, 84, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,73,80}, 171,1 , 3791,53 , 4,4 , 4,0 , 757,7 , 942,9 , 2, 1, 1, 6, 7 }, // English/Latin/Gibraltar
- { 31, 7, 87, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 951,7 , 2, 1, 1, 6, 7 }, // English/Latin/Grenada
- { 31, 7, 89, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 958,4 , 2, 1, 7, 6, 7 }, // English/Latin/Guam
- { 31, 7, 93, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,89,68}, 12,1 , 3844,56 , 4,4 , 8,6 , 757,7 , 962,6 , 0, 0, 1, 6, 7 }, // English/Latin/Guyana
- { 31, 7, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 287,6 , 224,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {72,75,68}, 12,1 , 3900,56 , 4,4 , 8,6 , 757,7 , 968,19 , 2, 1, 7, 6, 7 }, // English/Latin/HongKong
- { 31, 7, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {73,78,82}, 122,1 , 3956,44 , 14,5 , 4,0 , 757,7 , 987,5 , 2, 1, 7, 7, 7 }, // English/Latin/India
- { 31, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 99,16 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2807,19 , 4,4 , 4,0 , 757,7 , 992,7 , 2, 1, 7, 6, 7 }, // English/Latin/Ireland
- { 31, 7, 107, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 287,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {74,77,68}, 12,1 , 4000,53 , 4,4 , 4,0 , 757,7 , 999,7 , 2, 1, 7, 6, 7 }, // English/Latin/Jamaica
- { 31, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,69,83}, 2,3 , 4053,53 , 4,4 , 8,6 , 757,7 , 1006,5 , 2, 1, 7, 6, 7 }, // English/Latin/Kenya
- { 31, 7, 112, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,85,68}, 12,1 , 3108,59 , 4,4 , 8,6 , 757,7 , 1011,8 , 2, 1, 1, 6, 7 }, // English/Latin/Kiribati
- { 31, 7, 120, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4106,61 , 4,4 , 8,6 , 757,7 , 1019,7 , 2, 1, 1, 6, 7 }, // English/Latin/Lesotho
- { 31, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 4167,53 , 4,4 , 8,6 , 757,7 , 1026,7 , 2, 1, 1, 6, 7 }, // English/Latin/Liberia
- { 31, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 4220,54 , 4,4 , 8,6 , 757,7 , 1033,10 , 0, 0, 1, 6, 7 }, // English/Latin/Madagascar
- { 31, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,87,75}, 178,2 , 4274,53 , 4,4 , 8,6 , 757,7 , 1043,6 , 2, 1, 1, 6, 7 }, // English/Latin/Malawi
- { 31, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {69,85,82}, 131,1 , 2807,19 , 4,4 , 4,0 , 757,7 , 1049,5 , 2, 1, 7, 6, 7 }, // English/Latin/Malta
- { 31, 7, 134, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1054,16 , 2, 1, 7, 6, 7 }, // English/Latin/MarshallIslands
- { 31, 7, 137, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 4327,53 , 4,4 , 8,6 , 757,7 , 1070,9 , 0, 0, 1, 6, 7 }, // English/Latin/Mauritius
- { 31, 7, 140, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1079,10 , 2, 1, 1, 6, 7 }, // English/Latin/Micronesia
- { 31, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,65,68}, 12,1 , 4380,53 , 4,4 , 4,0 , 757,7 , 1089,7 , 2, 1, 1, 6, 7 }, // English/Latin/Namibia
- { 31, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 511,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {78,90,68}, 12,1 , 4433,62 , 4,4 , 4,0 , 757,7 , 1096,11 , 2, 1, 7, 6, 7 }, // English/Latin/NewZealand
- { 31, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,71,78}, 182,1 , 4495,50 , 4,4 , 8,6 , 757,7 , 1107,7 , 2, 1, 1, 6, 7 }, // English/Latin/Nigeria
- { 31, 7, 160, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1114,24 , 2, 1, 1, 6, 7 }, // English/Latin/NorthernMarianaIslands
- { 31, 7, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {80,75,82}, 180,2 , 4545,53 , 14,5 , 4,0 , 757,7 , 1138,8 , 0, 0, 7, 6, 7 }, // English/Latin/Pakistan
- { 31, 7, 164, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1146,5 , 2, 1, 1, 6, 7 }, // English/Latin/Palau
- { 31, 7, 167, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,71,75}, 139,1 , 4598,73 , 4,4 , 8,6 , 757,7 , 1151,16 , 2, 1, 1, 6, 7 }, // English/Latin/PapuaNewGuinea
- { 31, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,72,80}, 183,1 , 4671,42 , 4,4 , 8,6 , 757,7 , 1167,11 , 2, 1, 7, 6, 7 }, // English/Latin/Philippines
- { 31, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1178,11 , 2, 1, 7, 6, 7 }, // English/Latin/PuertoRico
- { 31, 7, 180, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 1189,21 , 2, 1, 1, 6, 7 }, // English/Latin/SaintKittsAndNevis
- { 31, 7, 181, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 1210,11 , 2, 1, 1, 6, 7 }, // English/Latin/SaintLucia
- { 31, 7, 182, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3037,71 , 4,4 , 8,6 , 757,7 , 1221,32 , 2, 1, 1, 6, 7 }, // English/Latin/SaintVincentAndTheGrenadines
- { 31, 7, 183, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {87,83,84}, 184,3 , 4713,40 , 4,4 , 8,6 , 757,7 , 1253,5 , 2, 1, 7, 6, 7 }, // English/Latin/Samoa
- { 31, 7, 188, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,67,82}, 187,2 , 4753,59 , 4,4 , 8,6 , 757,7 , 1258,10 , 2, 1, 1, 6, 7 }, // English/Latin/Seychelles
- { 31, 7, 189, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,76,76}, 189,2 , 4812,68 , 4,4 , 8,6 , 757,7 , 1268,12 , 0, 0, 1, 6, 7 }, // English/Latin/SierraLeone
- { 31, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 287,6 , 224,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {83,71,68}, 12,1 , 4880,56 , 4,4 , 8,6 , 757,7 , 1280,9 , 2, 1, 7, 6, 7 }, // English/Latin/Singapore
- { 31, 7, 193, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,66,68}, 12,1 , 4936,74 , 4,4 , 8,6 , 757,7 , 1289,15 , 2, 1, 1, 6, 7 }, // English/Latin/SolomonIslands
- { 31, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 536,10 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4106,61 , 4,4 , 8,6 , 757,7 , 1304,12 , 2, 1, 7, 6, 7 }, // English/Latin/SouthAfrica
- { 31, 7, 204, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,90,76}, 191,1 , 5010,53 , 4,4 , 8,6 , 757,7 , 1316,9 , 2, 1, 1, 6, 7 }, // English/Latin/Swaziland
- { 31, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,90,83}, 192,3 , 5063,62 , 4,4 , 8,6 , 757,7 , 1325,8 , 0, 0, 1, 6, 7 }, // English/Latin/Tanzania
- { 31, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,79,80}, 195,2 , 5125,49 , 4,4 , 8,6 , 757,7 , 1333,5 , 2, 1, 1, 6, 7 }, // English/Latin/Tonga
- { 31, 7, 215, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,84,68}, 12,1 , 5174,86 , 4,4 , 4,0 , 757,7 , 1338,19 , 2, 1, 7, 6, 7 }, // English/Latin/TrinidadAndTobago
- { 31, 7, 219, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1357,24 , 2, 1, 1, 6, 7 }, // English/Latin/TurksAndCaicosIslands
- { 31, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 5260,56 , 4,4 , 8,6 , 757,7 , 1381,6 , 0, 0, 1, 6, 7 }, // English/Latin/Uganda
- { 31, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3647,47 , 4,4 , 4,0 , 1387,15 , 1402,14 , 2, 1, 1, 6, 7 }, // English/Latin/UnitedKingdom
- { 31, 7, 226, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1416,21 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesMinorOutlyingIslands
- { 31, 7, 229, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {86,85,86}, 200,2 , 5316,44 , 4,4 , 8,6 , 757,7 , 1437,7 , 0, 0, 1, 6, 7 }, // English/Latin/Vanuatu
- { 31, 7, 233, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1444,22 , 2, 1, 1, 6, 7 }, // English/Latin/BritishVirginIslands
- { 31, 7, 234, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3002,35 , 4,4 , 8,6 , 757,7 , 1466,19 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesVirginIslands
- { 31, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,77,87}, 202,2 , 5360,50 , 4,4 , 8,6 , 757,7 , 1485,6 , 2, 1, 1, 6, 7 }, // English/Latin/Zambia
- { 31, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 364,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 3002,35 , 4,4 , 4,0 , 757,7 , 1491,8 , 2, 1, 7, 6, 7 }, // English/Latin/Zimbabwe
- { 31, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3647,47 , 4,4 , 4,0 , 757,7 , 1499,11 , 2, 1, 1, 6, 7 }, // English/Latin/IsleOfMan
- { 31, 7, 252, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3647,47 , 4,4 , 4,0 , 757,7 , 1510,6 , 2, 1, 1, 6, 7 }, // English/Latin/Jersey
- { 31, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,83,80}, 171,1 , 5410,68 , 4,4 , 8,6 , 757,7 , 1516,11 , 2, 1, 1, 6, 7 }, // English/Latin/SouthSudan
- { 33, 7, 68, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 169,8 , 169,8 , 187,8 , 462,18 , 61,4 , 252,9 , 5641,59 , 5700,91 , 5791,24 , 5641,59 , 5700,91 , 5791,24 , 2607,14 , 2621,63 , 2607,14 , 2607,14 , 2621,63 , 2607,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 5478,20 , 25,5 , 30,7 , 1527,5 , 1532,5 , 2, 1, 1, 6, 7 }, // Estonian/Latin/Estonia
- { 34, 7, 71, 44, 46, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 503,8 , 82,17 , 37,5 , 8,10 , 5815,48 , 5863,83 , 134,24 , 5815,48 , 5863,83 , 134,24 , 2684,28 , 2712,74 , 2786,14 , 2684,28 , 2712,74 , 2786,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 5498,42 , 4,4 , 43,5 , 1537,8 , 1545,7 , 2, 1, 1, 6, 7 }, // Faroese/Latin/FaroeIslands
- { 36, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 546,8 , 554,17 , 159,4 , 163,9 , 5946,69 , 6015,105 , 6120,24 , 6144,129 , 6144,129 , 6120,24 , 2800,21 , 2821,67 , 2888,14 , 2800,21 , 2902,81 , 2888,14 , 91,3 , 90,3 , {69,85,82}, 131,1 , 5540,20 , 25,5 , 4,0 , 1552,5 , 1557,5 , 2, 1, 1, 6, 7 }, // Finnish/Latin/Finland
- { 37, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1570,6 , 2, 1, 1, 6, 7 }, // French/Latin/France
- { 37, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {68,90,68}, 207,2 , 5560,51 , 25,5 , 30,7 , 1562,8 , 1576,7 , 2, 1, 6, 4, 5 }, // French/Latin/Algeria
- { 37, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 511,7 , 99,16 , 37,5 , 261,23 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1583,8 , 2, 1, 1, 6, 7 }, // French/Latin/Belgium
- { 37, 7, 23, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1591,5 , 0, 0, 1, 6, 7 }, // French/Latin/Benin
- { 37, 7, 34, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1596,12 , 0, 0, 1, 6, 7 }, // French/Latin/BurkinaFaso
- { 37, 7, 35, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {66,73,70}, 212,3 , 5670,53 , 25,5 , 30,7 , 1562,8 , 1608,7 , 0, 0, 1, 6, 7 }, // French/Latin/Burundi
- { 37, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1615,8 , 0, 0, 1, 6, 7 }, // French/Latin/Cameroon
- { 37, 7, 38, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 177,8 , 177,8 , 115,8 , 99,16 , 37,5 , 228,24 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 5779,54 , 25,5 , 30,7 , 1623,17 , 891,6 , 2, 0, 7, 6, 7 }, // French/Latin/Canada
- { 37, 7, 41, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1640,25 , 0, 0, 1, 6, 7 }, // French/Latin/CentralAfricanRepublic
- { 37, 7, 42, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1665,5 , 0, 0, 1, 6, 7 }, // French/Latin/Chad
- { 37, 7, 48, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {75,77,70}, 215,2 , 5833,51 , 25,5 , 30,7 , 1562,8 , 1670,7 , 0, 0, 1, 6, 7 }, // French/Latin/Comoros
- { 37, 7, 49, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,68,70}, 217,2 , 5884,53 , 25,5 , 30,7 , 1562,8 , 1677,32 , 2, 1, 1, 6, 7 }, // French/Latin/CongoKinshasa
- { 37, 7, 50, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1709,17 , 0, 0, 1, 6, 7 }, // French/Latin/CongoBrazzaville
- { 37, 7, 53, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1726,13 , 0, 0, 1, 6, 7 }, // French/Latin/IvoryCoast
- { 37, 7, 59, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {68,74,70}, 5,3 , 5937,57 , 25,5 , 30,7 , 1562,8 , 1739,8 , 0, 0, 6, 6, 7 }, // French/Latin/Djibouti
- { 37, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1747,18 , 0, 0, 1, 6, 7 }, // French/Latin/EquatorialGuinea
- { 37, 7, 76, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1765,16 , 2, 1, 1, 6, 7 }, // French/Latin/FrenchGuiana
- { 37, 7, 77, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,80,70}, 219,4 , 5994,35 , 25,5 , 30,7 , 1562,8 , 1781,19 , 0, 0, 1, 6, 7 }, // French/Latin/FrenchPolynesia
- { 37, 7, 79, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 36,4 , 5723,56 , 25,5 , 30,7 , 1562,8 , 1800,5 , 0, 0, 1, 6, 7 }, // French/Latin/Gabon
- { 37, 7, 88, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1805,10 , 2, 1, 1, 6, 7 }, // French/Latin/Guadeloupe
- { 37, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {71,78,70}, 223,2 , 6029,48 , 25,5 , 30,7 , 1562,8 , 1815,6 , 0, 0, 1, 6, 7 }, // French/Latin/Guinea
- { 37, 7, 94, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {72,84,71}, 225,1 , 6077,57 , 25,5 , 30,7 , 1562,8 , 1821,5 , 2, 1, 1, 6, 7 }, // French/Latin/Haiti
- { 37, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1826,10 , 2, 1, 1, 6, 7 }, // French/Latin/Luxembourg
- { 37, 7, 128, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 6134,54 , 25,5 , 30,7 , 1562,8 , 1033,10 , 0, 0, 1, 6, 7 }, // French/Latin/Madagascar
- { 37, 7, 132, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1836,4 , 0, 0, 1, 6, 7 }, // French/Latin/Mali
- { 37, 7, 135, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1840,10 , 2, 1, 1, 6, 7 }, // French/Latin/Martinique
- { 37, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,82,79}, 226,2 , 6188,66 , 25,5 , 30,7 , 1562,8 , 1850,10 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritania
- { 37, 7, 137, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 6254,63 , 25,5 , 30,7 , 1562,8 , 1860,7 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritius
- { 37, 7, 138, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1867,7 , 2, 1, 1, 6, 7 }, // French/Latin/Mayotte
- { 37, 7, 142, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1874,6 , 2, 1, 1, 6, 7 }, // French/Latin/Monaco
- { 37, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,65,68}, 0,0 , 6317,54 , 25,5 , 30,7 , 1562,8 , 1880,5 , 2, 1, 6, 5, 6 }, // French/Latin/Morocco
- { 37, 7, 153, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,80,70}, 219,4 , 5994,35 , 25,5 , 30,7 , 1562,8 , 1885,18 , 0, 0, 1, 6, 7 }, // French/Latin/NewCaledonia
- { 37, 7, 156, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1903,5 , 0, 0, 1, 6, 7 }, // French/Latin/Niger
- { 37, 7, 176, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1908,7 , 2, 1, 1, 6, 7 }, // French/Latin/Reunion
- { 37, 7, 179, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {82,87,70}, 228,2 , 6371,50 , 25,5 , 30,7 , 1562,8 , 1915,6 , 0, 0, 1, 6, 7 }, // French/Latin/Rwanda
- { 37, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1921,7 , 0, 0, 1, 6, 7 }, // French/Latin/Senegal
- { 37, 7, 188, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {83,67,82}, 187,2 , 6421,71 , 25,5 , 30,7 , 1562,8 , 1258,10 , 2, 1, 1, 6, 7 }, // French/Latin/Seychelles
- { 37, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 177,8 , 177,8 , 187,8 , 10,17 , 37,5 , 284,14 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,72,70}, 230,3 , 6492,45 , 14,5 , 48,5 , 1928,15 , 1943,6 , 2, 0, 1, 6, 7 }, // French/Latin/Switzerland
- { 37, 7, 207, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {83,89,80}, 233,2 , 6537,51 , 25,5 , 30,7 , 1562,8 , 1949,5 , 0, 0, 6, 5, 6 }, // French/Latin/Syria
- { 37, 7, 212, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5611,59 , 25,5 , 30,7 , 1562,8 , 1954,4 , 0, 0, 1, 6, 7 }, // French/Latin/Togo
- { 37, 7, 216, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {84,78,68}, 235,2 , 6588,51 , 25,5 , 30,7 , 1562,8 , 1958,7 , 3, 0, 7, 5, 6 }, // French/Latin/Tunisia
- { 37, 7, 229, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {86,85,86}, 200,2 , 6639,51 , 25,5 , 30,7 , 1562,8 , 1437,7 , 0, 0, 1, 6, 7 }, // French/Latin/Vanuatu
- { 37, 7, 244, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1965,16 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Barthelemy
- { 37, 7, 245, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 30,7 , 1562,8 , 1981,31 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Martin
- { 39, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 185,11 , 196,10 , 141,10 , 10,17 , 37,5 , 8,10 , 6421,61 , 6482,142 , 6624,36 , 6421,61 , 6482,142 , 6624,36 , 3084,28 , 3112,69 , 3181,14 , 3084,28 , 3112,69 , 3181,14 , 0,2 , 0,2 , {71,66,80}, 171,1 , 6690,22 , 4,4 , 8,6 , 2012,8 , 2020,22 , 2, 1, 1, 6, 7 }, // Gaelic/Latin/UnitedKingdom
- { 40, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 82,17 , 37,5 , 8,10 , 6660,48 , 6708,87 , 6795,24 , 6660,48 , 6708,87 , 6795,24 , 3195,28 , 3223,49 , 3272,14 , 3195,28 , 3223,49 , 3272,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 6712,20 , 4,4 , 8,6 , 2042,6 , 2048,6 , 2, 1, 1, 6, 7 }, // Galician/Latin/Spain
- { 41, 15, 81, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 213,8 , 213,8 , 187,8 , 571,19 , 37,5 , 8,10 , 6819,48 , 6867,99 , 6966,24 , 6819,48 , 6867,99 , 6966,24 , 3286,28 , 3314,62 , 3376,14 , 3286,28 , 3314,62 , 3376,14 , 0,2 , 0,2 , {71,69,76}, 0,0 , 6732,19 , 25,5 , 4,0 , 2054,7 , 2061,10 , 2, 1, 1, 6, 7 }, // Georgian/Georgian/Georgia
- { 42, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 131,1 , 6751,19 , 25,5 , 4,0 , 2071,7 , 2078,11 , 2, 1, 1, 6, 7 }, // German/Latin/Germany
- { 42, 7, 14, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 590,19 , 37,5 , 8,10 , 7180,48 , 7038,83 , 134,24 , 7228,58 , 7286,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 131,1 , 6751,19 , 14,5 , 4,0 , 2089,24 , 2113,10 , 2, 1, 1, 6, 7 }, // German/Latin/Austria
- { 42, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 131,1 , 6751,19 , 25,5 , 4,0 , 2071,7 , 2123,7 , 2, 1, 1, 6, 7 }, // German/Latin/Belgium
- { 42, 7, 123, 46, 39, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {67,72,70}, 0,0 , 6770,58 , 14,5 , 4,0 , 2071,7 , 2130,13 , 2, 0, 1, 6, 7 }, // German/Latin/Liechtenstein
- { 42, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 131,1 , 6751,19 , 25,5 , 4,0 , 2071,7 , 2143,9 , 2, 1, 1, 6, 7 }, // German/Latin/Luxembourg
- { 42, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {67,72,70}, 230,3 , 6770,58 , 14,5 , 48,5 , 2152,21 , 2173,7 , 2, 0, 1, 6, 7 }, // German/Latin/Switzerland
- { 43, 16, 85, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 230,9 , 230,9 , 287,6 , 10,17 , 18,7 , 25,12 , 7369,50 , 7419,115 , 7534,24 , 7558,50 , 7608,115 , 7534,24 , 3513,28 , 3541,55 , 3596,14 , 3513,28 , 3541,55 , 3596,14 , 99,4 , 99,4 , {69,85,82}, 131,1 , 6828,19 , 25,5 , 4,0 , 2180,8 , 2188,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Greece
- { 43, 16, 56, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 230,9 , 230,9 , 287,6 , 10,17 , 18,7 , 25,12 , 7369,50 , 7419,115 , 7534,24 , 7558,50 , 7608,115 , 7534,24 , 3513,28 , 3541,55 , 3596,14 , 3513,28 , 3541,55 , 3596,14 , 99,4 , 99,4 , {69,85,82}, 131,1 , 6828,19 , 4,4 , 4,0 , 2180,8 , 2194,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Cyprus
- { 44, 7, 86, 44, 46, 59, 37, 48, 8722, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 239,11 , 239,11 , 72,10 , 82,17 , 18,7 , 25,12 , 4985,48 , 7723,96 , 134,24 , 4985,48 , 7723,96 , 134,24 , 3610,28 , 3638,98 , 3736,14 , 3610,28 , 3638,98 , 3736,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 6847,59 , 4,4 , 43,5 , 2200,11 , 2211,16 , 2, 1, 1, 6, 7 }, // Greenlandic/Latin/Greenland
- { 46, 17, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 250,9 , 250,9 , 609,7 , 224,18 , 298,8 , 306,13 , 7819,64 , 7883,87 , 7970,31 , 8001,67 , 8068,87 , 7970,31 , 3750,32 , 3782,53 , 3835,19 , 3750,32 , 3782,53 , 3835,19 , 0,2 , 0,2 , {73,78,82}, 122,1 , 6906,20 , 4,4 , 8,6 , 2227,7 , 2234,4 , 2, 1, 7, 7, 7 }, // Gujarati/Gujarati/India
- { 47, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {78,71,78}, 182,1 , 6926,12 , 14,5 , 4,0 , 2238,5 , 2243,8 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Nigeria
- { 47, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {71,72,83}, 173,3 , 0,7 , 14,5 , 4,0 , 2238,5 , 2251,4 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Ghana
- { 47, 7, 156, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 6938,36 , 14,5 , 4,0 , 2238,5 , 2255,5 , 0, 0, 1, 6, 7 }, // Hausa/Latin/Niger
- { 48, 18, 105, 46, 44, 59, 37, 48, 45, 43, 101, 34, 34, 39, 39, 0,6 , 0,6 , 259,6 , 259,6 , 27,8 , 616,18 , 37,5 , 8,10 , 8312,58 , 8370,72 , 158,27 , 8442,48 , 8370,72 , 158,27 , 3941,46 , 3987,65 , 4052,19 , 3941,46 , 3987,65 , 4071,21 , 103,6 , 103,5 , {73,76,83}, 52,1 , 6974,54 , 25,5 , 4,0 , 2260,5 , 2265,5 , 2, 1, 7, 5, 6 }, // Hebrew/Hebrew/Israel
- { 49, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 265,9 , 274,8 , 634,6 , 10,17 , 18,7 , 25,12 , 8490,75 , 8490,75 , 8565,30 , 8490,75 , 8490,75 , 8565,30 , 4092,38 , 4130,57 , 4187,19 , 4092,38 , 4130,57 , 4187,19 , 109,9 , 108,7 , {73,78,82}, 122,1 , 7028,19 , 14,5 , 4,0 , 2270,6 , 2276,4 , 2, 1, 7, 7, 7 }, // Hindi/Devanagari/India
- { 50, 7, 98, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 187, 171, 0,6 , 0,6 , 282,8 , 282,8 , 640,11 , 651,19 , 61,4 , 219,9 , 8595,64 , 8659,98 , 8757,25 , 8595,64 , 8659,98 , 8782,25 , 4206,19 , 4225,52 , 4277,17 , 4206,19 , 4225,52 , 4277,17 , 118,3 , 115,3 , {72,85,70}, 237,2 , 7047,20 , 25,5 , 4,0 , 2280,6 , 2286,12 , 0, 0, 1, 6, 7 }, // Hungarian/Latin/Hungary
- { 51, 7, 99, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 142,8 , 142,8 , 546,8 , 462,18 , 37,5 , 8,10 , 8807,48 , 8855,82 , 8937,24 , 8807,48 , 8855,82 , 8961,24 , 4294,28 , 4322,81 , 4403,14 , 4294,28 , 4322,81 , 4417,14 , 121,4 , 118,4 , {73,83,75}, 157,2 , 7067,49 , 4,4 , 8,6 , 2298,8 , 2306,6 , 0, 0, 1, 6, 7 }, // Icelandic/Latin/Iceland
- { 52, 7, 101, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 27,8 , 123,18 , 144,5 , 149,10 , 8985,48 , 9033,87 , 134,24 , 8985,48 , 9033,87 , 134,24 , 4431,28 , 4459,43 , 4502,14 , 4431,28 , 4459,43 , 4502,14 , 0,2 , 0,2 , {73,68,82}, 239,2 , 7116,23 , 4,4 , 4,0 , 2312,16 , 2328,9 , 0, 0, 7, 6, 7 }, // Indonesian/Latin/Indonesia
- { 53, 7, 74, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 9120,48 , 9168,93 , 158,27 , 9120,48 , 9168,93 , 158,27 , 4516,28 , 4544,57 , 85,14 , 4516,28 , 4544,57 , 85,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 7139,12 , 14,5 , 4,0 , 2337,11 , 2348,7 , 2, 1, 1, 6, 7 }, // Interlingua/Latin/France
- { 57, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 99,16 , 37,5 , 8,10 , 9261,62 , 9323,107 , 9430,24 , 9261,62 , 9323,107 , 9430,24 , 4601,37 , 4638,75 , 4713,14 , 4601,37 , 4638,75 , 4713,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 7151,11 , 4,4 , 4,0 , 2355,7 , 2362,4 , 2, 1, 7, 6, 7 }, // Irish/Latin/Ireland
- { 58, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 309,8 , 206,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2807,19 , 14,5 , 4,0 , 2366,8 , 2374,6 , 2, 1, 1, 6, 7 }, // Italian/Latin/Italy
- { 58, 7, 184, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 309,8 , 206,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2807,19 , 14,5 , 4,0 , 2366,8 , 2380,10 , 2, 1, 1, 6, 7 }, // Italian/Latin/SanMarino
- { 58, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 309,8 , 206,7 , 187,8 , 10,17 , 37,5 , 284,14 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {67,72,70}, 230,3 , 7162,53 , 14,5 , 48,5 , 2366,8 , 2390,8 , 2, 0, 1, 6, 7 }, // Italian/Latin/Switzerland
- { 59, 19, 108, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 125,5 , 125,5 , 536,10 , 399,13 , 61,4 , 319,10 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 4883,14 , 4897,28 , 4883,14 , 4883,14 , 4897,28 , 4883,14 , 125,2 , 122,2 , {74,80,89}, 143,1 , 7215,10 , 4,4 , 4,0 , 2398,3 , 2401,2 , 0, 0, 7, 6, 7 }, // Japanese/Japanese/Japan
- { 61, 21, 100, 46, 44, 59, 37, 48, 45, 43, 3208, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 317,12 , 329,11 , 634,6 , 99,16 , 298,8 , 306,13 , 9714,91 , 9805,86 , 9891,31 , 9714,91 , 9805,86 , 9922,31 , 4925,28 , 4953,53 , 5006,19 , 4925,28 , 4953,53 , 5006,19 , 0,2 , 0,2 , {73,78,82}, 122,1 , 7225,20 , 4,4 , 8,6 , 2403,5 , 2408,4 , 2, 1, 7, 7, 7 }, // Kannada/Kannada/India
- { 62, 1, 100, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 9953,72 , 9953,72 , 10025,24 , 9953,72 , 9953,72 , 10025,24 , 5025,54 , 5079,56 , 5135,14 , 5025,54 , 5079,56 , 5135,14 , 0,2 , 0,2 , {73,78,82}, 122,1 , 7245,23 , 14,5 , 4,0 , 2412,5 , 2417,10 , 2, 1, 7, 7, 7 }, // Kashmiri/Arabic/India
- { 63, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 187,8 , 670,22 , 37,5 , 8,10 , 10049,61 , 10110,83 , 158,27 , 10049,61 , 10110,83 , 158,27 , 5149,28 , 5177,54 , 85,14 , 5149,28 , 5177,54 , 85,14 , 0,2 , 0,2 , {75,90,84}, 241,1 , 7268,24 , 25,5 , 4,0 , 2427,10 , 2437,9 , 2, 1, 1, 6, 7 }, // Kazakh/Cyrillic/Kazakhstan
- { 64, 7, 179, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 10193,60 , 10253,101 , 158,27 , 10193,60 , 10253,101 , 158,27 , 5231,35 , 5266,84 , 85,14 , 5231,35 , 5266,84 , 85,14 , 0,2 , 0,2 , {82,87,70}, 228,2 , 0,7 , 14,5 , 4,0 , 2446,11 , 1915,6 , 0, 0, 1, 6, 7 }, // Kinyarwanda/Latin/Rwanda
- { 65, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 187,8 , 670,22 , 37,5 , 8,10 , 10354,60 , 10414,80 , 158,27 , 10494,59 , 10553,80 , 158,27 , 5350,28 , 5378,57 , 85,14 , 5435,28 , 5463,57 , 85,14 , 0,2 , 0,2 , {75,71,83}, 242,3 , 0,7 , 14,5 , 4,0 , 2457,6 , 2463,10 , 2, 1, 1, 6, 7 }, // Kirghiz/Cyrillic/Kyrgyzstan
- { 66, 22, 114, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 340,7 , 340,7 , 692,9 , 701,16 , 329,7 , 336,13 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 5520,14 , 5534,28 , 5520,14 , 5520,14 , 5534,28 , 5520,14 , 127,2 , 124,2 , {75,82,87}, 245,1 , 7292,13 , 4,4 , 8,6 , 2473,3 , 2476,4 , 0, 0, 7, 6, 7 }, // Korean/Korean/SouthKorea
- { 66, 22, 113, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 340,7 , 340,7 , 692,9 , 701,16 , 329,7 , 336,13 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 5520,14 , 5534,28 , 5520,14 , 5520,14 , 5534,28 , 5520,14 , 127,2 , 124,2 , {75,80,87}, 0,0 , 7305,23 , 4,4 , 8,6 , 2473,3 , 2480,14 , 0, 0, 1, 6, 7 }, // Korean/Korean/NorthKorea
- { 68, 7, 35, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 10672,60 , 10732,106 , 158,27 , 10672,60 , 10732,106 , 158,27 , 5562,34 , 5596,89 , 85,14 , 5562,34 , 5596,89 , 85,14 , 129,5 , 126,5 , {66,73,70}, 212,3 , 7328,27 , 0,4 , 4,0 , 2494,8 , 2502,8 , 0, 0, 1, 6, 7 }, // Rundi/Latin/Burundi
- { 69, 23, 117, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 717,18 , 61,4 , 349,24 , 10838,62 , 10900,75 , 158,27 , 10975,61 , 10900,75 , 158,27 , 5685,23 , 5708,57 , 5765,18 , 5783,24 , 5708,57 , 1765,14 , 134,8 , 131,8 , {76,65,75}, 246,1 , 7355,14 , 4,4 , 48,5 , 2510,3 , 2513,9 , 0, 0, 7, 6, 7 }, // Lao/Lao/Laos
- { 71, 7, 118, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 347,8 , 347,8 , 187,8 , 735,26 , 37,5 , 8,10 , 11036,65 , 11101,101 , 134,24 , 11202,65 , 11267,101 , 134,24 , 5807,21 , 5828,72 , 5900,14 , 5807,21 , 5914,72 , 5900,14 , 142,14 , 139,11 , {76,86,76}, 247,2 , 7369,59 , 4,4 , 8,6 , 2522,8 , 2530,7 , 2, 1, 1, 6, 7 }, // Latvian/Latin/Latvia
- { 72, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {67,68,70}, 217,2 , 7428,23 , 25,5 , 4,0 , 2537,7 , 2544,29 , 2, 1, 1, 6, 7 }, // Lingala/Latin/CongoKinshasa
- { 72, 7, 6, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {65,79,65}, 249,2 , 7451,23 , 25,5 , 4,0 , 2537,7 , 2573,6 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Angola
- { 72, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {88,65,70}, 36,4 , 7474,23 , 25,5 , 4,0 , 2537,7 , 2579,26 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CentralAfricanRepublic
- { 72, 7, 50, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {88,65,70}, 36,4 , 7474,23 , 25,5 , 4,0 , 2537,7 , 2605,5 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CongoBrazzaville
- { 73, 7, 124, 44, 160, 59, 37, 48, 8211, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 364,8 , 364,8 , 72,10 , 761,27 , 37,5 , 8,10 , 11643,70 , 11713,96 , 11809,24 , 11643,70 , 11713,96 , 11809,24 , 6128,21 , 6149,89 , 6238,14 , 6128,21 , 6149,89 , 6238,14 , 164,9 , 156,6 , {76,84,76}, 251,2 , 7497,62 , 25,5 , 4,0 , 2610,8 , 2618,7 , 2, 1, 1, 6, 7 }, // Lithuanian/Latin/Lithuania
- { 74, 2, 127, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 788,7 , 123,18 , 37,5 , 8,10 , 11833,63 , 11896,85 , 11981,24 , 11833,63 , 11896,85 , 11981,24 , 6252,34 , 6286,54 , 1521,14 , 6252,34 , 6286,54 , 1521,14 , 173,10 , 162,8 , {77,75,68}, 253,3 , 7559,23 , 14,5 , 4,0 , 2625,10 , 2635,10 , 2, 1, 1, 6, 7 }, // Macedonian/Cyrillic/Macedonia
- { 75, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 12005,48 , 12053,92 , 134,24 , 12005,48 , 12053,92 , 134,24 , 6340,34 , 6374,60 , 6434,14 , 6340,34 , 6374,60 , 6434,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 7582,13 , 4,4 , 4,0 , 2645,8 , 2653,12 , 0, 0, 1, 6, 7 }, // Malagasy/Latin/Madagascar
- { 76, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 10,17 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {77,89,82}, 256,2 , 7595,23 , 4,4 , 8,6 , 2665,13 , 2678,8 , 2, 1, 1, 6, 7 }, // Malay/Latin/Malaysia
- { 76, 7, 32, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 524,12 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {66,78,68}, 12,1 , 7618,19 , 14,5 , 4,0 , 2665,13 , 2686,6 , 2, 1, 1, 6, 7 }, // Malay/Latin/Brunei
- { 76, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 10,17 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {83,71,68}, 12,1 , 7637,22 , 4,4 , 8,6 , 2665,13 , 2692,9 , 2, 1, 7, 6, 7 }, // Malay/Latin/Singapore
- { 77, 24, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 372,13 , 385,12 , 27,8 , 795,18 , 18,7 , 25,12 , 12300,62 , 12362,87 , 12449,31 , 12300,62 , 12362,87 , 12449,31 , 6533,41 , 6574,70 , 6644,22 , 6533,41 , 6574,70 , 6644,22 , 0,2 , 0,2 , {73,78,82}, 122,1 , 7659,40 , 0,4 , 4,0 , 2701,6 , 2707,6 , 2, 1, 7, 7, 7 }, // Malayalam/Malayalam/India
- { 78, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 397,8 , 405,7 , 141,10 , 813,23 , 37,5 , 8,10 , 12480,48 , 12528,86 , 12614,24 , 12480,48 , 12528,86 , 12614,24 , 6666,28 , 6694,63 , 6757,14 , 6666,28 , 6694,63 , 6757,14 , 185,2 , 173,2 , {69,85,82}, 131,1 , 7699,11 , 4,4 , 4,0 , 2713,5 , 1049,5 , 2, 1, 7, 6, 7 }, // Maltese/Latin/Malta
- { 80, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 412,9 , 412,9 , 634,6 , 99,16 , 373,7 , 380,12 , 12638,66 , 12704,86 , 12790,32 , 12638,66 , 12704,86 , 12790,32 , 6771,32 , 6803,53 , 4187,19 , 6771,32 , 6803,53 , 4187,19 , 0,2 , 0,2 , {73,78,82}, 122,1 , 7710,19 , 4,4 , 8,6 , 2718,5 , 2276,4 , 2, 1, 7, 7, 7 }, // Marathi/Devanagari/India
- { 82, 2, 143, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 836,31 , 37,5 , 8,10 , 12822,48 , 12870,66 , 158,27 , 12822,48 , 12870,66 , 158,27 , 6856,21 , 6877,43 , 1765,14 , 6856,21 , 6877,43 , 1765,14 , 187,2 , 175,2 , {77,78,84}, 258,1 , 7729,25 , 14,5 , 4,0 , 2723,6 , 2729,6 , 0, 0, 1, 6, 7 }, // Mongolian/Cyrillic/Mongolia
- { 84, 13, 150, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 12936,56 , 12992,85 , 13077,27 , 12936,56 , 12992,85 , 13077,27 , 6920,33 , 6953,54 , 7007,14 , 6920,33 , 6953,54 , 7007,14 , 189,14 , 177,14 , {78,80,82}, 259,4 , 7754,52 , 14,5 , 4,0 , 2735,6 , 2741,5 , 2, 1, 7, 6, 7 }, // Nepali/Devanagari/Nepal
- { 84, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 12936,56 , 12992,85 , 13077,27 , 12936,56 , 13104,80 , 13077,27 , 6920,33 , 6953,54 , 7007,14 , 6920,33 , 7021,54 , 7007,14 , 109,9 , 108,7 , {73,78,82}, 122,1 , 7806,49 , 14,5 , 4,0 , 2735,6 , 2276,4 , 2, 1, 7, 7, 7 }, // Nepali/Devanagari/India
- { 85, 7, 161, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 187,8 , 554,17 , 37,5 , 392,16 , 5815,48 , 13184,83 , 134,24 , 13267,59 , 13184,83 , 134,24 , 7075,28 , 2258,51 , 2309,14 , 2323,35 , 2258,51 , 2309,14 , 0,2 , 0,2 , {78,79,75}, 157,2 , 7855,44 , 14,5 , 4,0 , 2746,12 , 2758,5 , 2, 1, 1, 6, 7 }, // NorwegianBokmal/Latin/Norway
- { 87, 26, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 634,6 , 10,17 , 18,7 , 25,12 , 13326,89 , 13326,89 , 13415,32 , 13326,89 , 13326,89 , 13415,32 , 7103,33 , 7136,54 , 7190,18 , 7103,33 , 7136,54 , 7190,18 , 89,2 , 88,2 , {73,78,82}, 122,1 , 7899,11 , 14,5 , 4,0 , 2763,5 , 2768,4 , 2, 1, 7, 7, 7 }, // Oriya/Oriya/India
- { 88, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 179,8 , 867,20 , 61,4 , 408,11 , 13447,68 , 13447,68 , 158,27 , 13447,68 , 13447,68 , 158,27 , 7208,49 , 7208,49 , 85,14 , 7208,49 , 7208,49 , 85,14 , 203,4 , 191,4 , {65,70,78}, 263,1 , 7910,13 , 25,5 , 4,0 , 2772,4 , 2776,9 , 0, 0, 6, 4, 5 }, // Pashto/Arabic/Afghanistan
- { 89, 1, 102, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 171, 187, 8249, 8250, 421,7 , 421,7 , 43,8 , 51,7 , 179,8 , 99,16 , 61,4 , 408,11 , 13515,70 , 13515,70 , 13585,24 , 13609,74 , 13609,74 , 13585,24 , 7208,49 , 7208,49 , 7257,14 , 7208,49 , 7208,49 , 7257,14 , 207,9 , 195,8 , {73,82,82}, 264,1 , 7923,17 , 53,5 , 58,7 , 2785,5 , 2790,5 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Iran
- { 89, 1, 1, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 171, 187, 8249, 8250, 421,7 , 421,7 , 43,8 , 51,7 , 179,8 , 99,16 , 61,4 , 408,11 , 13515,70 , 13515,70 , 13683,24 , 13707,64 , 13771,68 , 13585,24 , 7208,49 , 7208,49 , 7257,14 , 7208,49 , 7208,49 , 7257,14 , 207,9 , 195,8 , {65,70,78}, 263,1 , 7940,23 , 53,5 , 58,7 , 2795,3 , 2776,9 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Afghanistan
- { 90, 7, 172, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 887,10 , 10,17 , 37,5 , 8,10 , 13839,48 , 13887,97 , 13984,24 , 13839,48 , 14008,99 , 13984,24 , 7271,34 , 7305,59 , 7364,14 , 7271,34 , 7305,59 , 7364,14 , 0,2 , 0,2 , {80,76,78}, 265,2 , 7963,77 , 25,5 , 30,7 , 2798,6 , 2804,6 , 2, 1, 1, 6, 7 }, // Polish/Latin/Poland
- { 91, 7, 30, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14107,48 , 14155,89 , 134,24 , 14107,48 , 14155,89 , 134,24 , 7378,28 , 7406,79 , 7485,14 , 7378,28 , 7406,79 , 7485,14 , 0,2 , 0,2 , {66,82,76}, 267,2 , 8040,54 , 4,4 , 8,6 , 2810,19 , 2829,6 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Brazil
- { 91, 7, 6, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {65,79,65}, 249,2 , 8094,54 , 25,5 , 4,0 , 2835,9 , 2844,6 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Angola
- { 91, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {67,86,69}, 0,0 , 8148,69 , 25,5 , 4,0 , 2835,9 , 2850,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/CapeVerde
- { 91, 7, 62, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 8217,81 , 25,5 , 4,0 , 2835,9 , 2860,11 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/EastTimor
- { 91, 7, 92, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 8298,62 , 25,5 , 4,0 , 2835,9 , 2871,12 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/GuineaBissau
- { 91, 7, 126, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {77,79,80}, 144,4 , 8360,53 , 25,5 , 4,0 , 2835,9 , 2883,19 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Macau
- { 91, 7, 146, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {77,90,78}, 269,3 , 8413,72 , 25,5 , 4,0 , 2835,9 , 2902,10 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Mozambique
- { 91, 7, 173, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 8485,20 , 25,5 , 4,0 , 2912,17 , 2929,8 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Portugal
- { 91, 7, 185, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {83,84,68}, 272,2 , 8505,92 , 25,5 , 4,0 , 2835,9 , 2937,19 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/SaoTomeAndPrincipe
- { 92, 4, 100, 46, 44, 59, 37, 48, 45, 43, 101, 39, 39, 34, 34, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 123,18 , 18,7 , 25,12 , 14381,68 , 14381,68 , 14449,27 , 14381,68 , 14381,68 , 14449,27 , 7578,38 , 7616,55 , 7671,23 , 7578,38 , 7616,55 , 7671,23 , 216,11 , 203,11 , {73,78,82}, 122,1 , 8597,12 , 14,5 , 4,0 , 2956,6 , 2962,4 , 2, 1, 7, 7, 7 }, // Punjabi/Gurmukhi/India
- { 92, 1, 163, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 123,18 , 18,7 , 25,12 , 14476,67 , 14476,67 , 158,27 , 14476,67 , 14476,67 , 158,27 , 7694,37 , 7694,37 , 85,14 , 7694,37 , 7694,37 , 85,14 , 0,2 , 0,2 , {80,75,82}, 274,1 , 8609,13 , 14,5 , 4,0 , 2966,5 , 2971,6 , 0, 0, 7, 6, 7 }, // Punjabi/Arabic/Pakistan
- { 94, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 503,8 , 924,28 , 37,5 , 8,10 , 14543,67 , 14610,92 , 14702,24 , 14543,67 , 14610,92 , 14702,24 , 7731,23 , 7754,56 , 7810,14 , 7731,23 , 7754,56 , 7810,14 , 89,2 , 214,2 , {67,72,70}, 230,3 , 8622,20 , 25,5 , 4,0 , 2977,9 , 2986,6 , 2, 0, 1, 6, 7 }, // Romansh/Latin/Switzerland
- { 95, 7, 177, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 428,8 , 428,8 , 887,10 , 10,17 , 37,5 , 8,10 , 14726,60 , 14786,98 , 14884,24 , 14726,60 , 14786,98 , 14884,24 , 7824,21 , 7845,48 , 3070,14 , 7824,21 , 7845,48 , 3070,14 , 0,2 , 0,2 , {82,79,78}, 0,0 , 8642,57 , 25,5 , 4,0 , 2992,6 , 2998,7 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Romania
- { 95, 7, 141, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 428,8 , 428,8 , 887,10 , 10,17 , 37,5 , 8,10 , 14726,60 , 14786,98 , 14884,24 , 14726,60 , 14786,98 , 14884,24 , 7824,21 , 7845,48 , 3070,14 , 7824,21 , 7845,48 , 3070,14 , 0,2 , 0,2 , {77,68,76}, 0,0 , 8699,69 , 25,5 , 4,0 , 2992,6 , 3005,17 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Moldova
- { 96, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {82,85,66}, 275,4 , 8768,89 , 25,5 , 4,0 , 3022,7 , 3029,6 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Russia
- { 96, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {66,89,82}, 140,2 , 8857,94 , 25,5 , 4,0 , 3022,7 , 464,8 , 0, 0, 7, 6, 7 }, // Russian/Cyrillic/Belarus
- { 96, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {75,90,84}, 241,1 , 8951,83 , 25,5 , 4,0 , 3022,7 , 3035,9 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kazakhstan
- { 96, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {75,71,83}, 242,3 , 9034,81 , 25,5 , 4,0 , 3022,7 , 3044,8 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kyrgyzstan
- { 96, 2, 141, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {77,68,76}, 0,0 , 9115,79 , 25,5 , 4,0 , 3022,7 , 3052,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Moldova
- { 96, 2, 222, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 37,5 , 8,10 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {85,65,72}, 279,1 , 9194,92 , 25,5 , 4,0 , 3022,7 , 3059,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Ukraine
- { 98, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 15139,48 , 15187,91 , 15278,24 , 15139,48 , 15187,91 , 15278,24 , 8073,28 , 8101,66 , 8167,14 , 8073,28 , 8101,66 , 8167,14 , 237,2 , 229,2 , {88,65,70}, 36,4 , 9286,25 , 4,4 , 48,5 , 3066,5 , 3071,22 , 0, 0, 1, 6, 7 }, // Sango/Latin/CentralAfricanRepublic
- { 100, 2, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {82,83,68}, 280,4 , 9311,72 , 25,5 , 4,0 , 3093,6 , 3099,6 , 0, 0, 1, 6, 7 }, // Serbian/Cyrillic/Serbia
- { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 115,8 , 981,20 , 37,5 , 419,40 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15431,83 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8275,28 , 8303,54 , 8261,14 , 239,9 , 231,7 , {66,65,77}, 284,2 , 9383,196 , 25,5 , 4,0 , 3105,6 , 3111,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/BosniaAndHerzegowina
- { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {69,85,82}, 131,1 , 9579,27 , 25,5 , 4,0 , 3093,6 , 3130,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro
- { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15514,48 , 15562,81 , 15643,24 , 15514,48 , 15562,81 , 15643,24 , 8357,28 , 8385,54 , 2118,14 , 8357,28 , 8385,54 , 2118,14 , 248,9 , 238,7 , {66,65,77}, 153,2 , 9606,196 , 25,5 , 4,0 , 3139,6 , 581,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/BosniaAndHerzegowina
- { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15514,48 , 15562,81 , 15643,24 , 15514,48 , 15562,81 , 15643,24 , 8357,28 , 8385,54 , 2118,14 , 8357,28 , 8385,54 , 2118,14 , 248,9 , 238,7 , {69,85,82}, 131,1 , 9802,27 , 25,5 , 4,0 , 3139,6 , 3145,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro
- { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15514,48 , 15562,81 , 15643,24 , 15514,48 , 15562,81 , 15643,24 , 8357,28 , 8385,54 , 2118,14 , 8357,28 , 8385,54 , 2118,14 , 248,9 , 238,7 , {82,83,68}, 286,4 , 9829,72 , 25,5 , 4,0 , 3139,6 , 3154,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia
- { 101, 2, 81, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 436,9 , 436,9 , 187,8 , 1001,23 , 37,5 , 8,10 , 14908,62 , 15667,82 , 14970,24 , 15749,59 , 15808,86 , 14970,24 , 8439,28 , 8467,61 , 8528,14 , 8542,28 , 8570,61 , 8528,14 , 0,2 , 0,2 , {71,69,76}, 0,0 , 9901,17 , 14,5 , 4,0 , 3160,4 , 3164,11 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Georgia
- { 101, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 436,9 , 436,9 , 187,8 , 1001,23 , 37,5 , 8,10 , 14908,62 , 15667,82 , 14970,24 , 15749,59 , 15808,86 , 14970,24 , 8439,28 , 8467,61 , 8528,14 , 8542,28 , 8570,61 , 8528,14 , 0,2 , 0,2 , {82,85,66}, 275,4 , 9918,17 , 14,5 , 4,0 , 3160,4 , 3175,6 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Russia
- { 102, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 15894,48 , 15942,105 , 158,27 , 15894,48 , 15942,105 , 158,27 , 8631,27 , 8658,61 , 85,14 , 8631,27 , 8658,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3181,7 , 0,0 , 2, 1, 7, 6, 7 }, // Southern Sotho/Latin/SouthAfrica
- { 102, 7, 120, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 15894,48 , 15942,105 , 158,27 , 15894,48 , 15942,105 , 158,27 , 8631,27 , 8658,61 , 85,14 , 8631,27 , 8658,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3181,7 , 0,0 , 2, 1, 1, 6, 7 }, // Southern Sotho/Latin/Lesotho
- { 103, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16047,48 , 16095,117 , 158,27 , 16047,48 , 16095,117 , 158,27 , 8719,27 , 8746,64 , 85,14 , 8719,27 , 8746,64 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3188,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/SouthAfrica
- { 103, 7, 28, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16047,48 , 16095,117 , 158,27 , 16047,48 , 16095,117 , 158,27 , 8719,27 , 8746,64 , 85,14 , 8719,27 , 8746,64 , 85,14 , 0,2 , 0,2 , {66,87,80}, 170,1 , 0,7 , 4,4 , 4,0 , 3188,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/Botswana
- { 104, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 16212,47 , 16259,100 , 16359,24 , 16212,47 , 16259,100 , 16359,24 , 8810,32 , 8842,55 , 8897,14 , 8810,32 , 8842,55 , 8897,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 9935,22 , 4,4 , 8,6 , 3196,8 , 1491,8 , 2, 1, 7, 6, 7 }, // Shona/Latin/Zimbabwe
- { 106, 32, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 536,10 , 323,17 , 459,7 , 466,13 , 16383,59 , 16442,96 , 16538,32 , 16570,61 , 16442,96 , 16538,32 , 8911,30 , 8941,62 , 9003,19 , 8911,30 , 8941,62 , 9003,19 , 257,5 , 245,4 , {76,75,82}, 290,3 , 9957,19 , 14,5 , 4,0 , 3204,5 , 3209,11 , 2, 1, 1, 6, 7 }, // Sinhala/Sinhala/SriLanka
- { 107, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16631,48 , 16679,114 , 158,27 , 16631,48 , 16679,114 , 158,27 , 9022,27 , 9049,68 , 85,14 , 9022,27 , 9049,68 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3220,7 , 0,0 , 2, 1, 7, 6, 7 }, // Swati/Latin/SouthAfrica
- { 107, 7, 204, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16631,48 , 16679,114 , 158,27 , 16631,48 , 16679,114 , 158,27 , 9022,27 , 9049,68 , 85,14 , 9022,27 , 9049,68 , 85,14 , 0,2 , 0,2 , {83,90,76}, 191,1 , 0,7 , 4,4 , 4,0 , 3220,7 , 0,0 , 2, 1, 1, 6, 7 }, // Swati/Latin/Swaziland
- { 108, 7, 191, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 135,7 , 135,7 , 546,8 , 462,18 , 61,4 , 219,9 , 16793,48 , 16841,82 , 15643,24 , 16793,48 , 16923,89 , 15643,24 , 9117,21 , 9138,52 , 9190,14 , 9117,21 , 9138,52 , 9190,14 , 262,10 , 249,9 , {69,85,82}, 131,1 , 9976,28 , 25,5 , 4,0 , 3227,10 , 3237,9 , 2, 1, 1, 6, 7 }, // Slovak/Latin/Slovakia
- { 109, 7, 192, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 445,8 , 445,8 , 1024,9 , 590,19 , 37,5 , 8,10 , 15514,48 , 17012,86 , 15643,24 , 17098,59 , 17012,86 , 15643,24 , 9204,28 , 9232,52 , 9284,14 , 9298,35 , 9232,52 , 9284,14 , 81,4 , 258,4 , {69,85,82}, 131,1 , 10004,28 , 4,4 , 8,6 , 3246,11 , 3257,9 , 2, 1, 1, 6, 7 }, // Slovenian/Latin/Slovenia
- { 110, 7, 194, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {83,79,83}, 98,1 , 10032,22 , 4,4 , 4,0 , 3266,8 , 3274,10 , 0, 0, 1, 6, 7 }, // Somali/Latin/Somalia
- { 110, 7, 59, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {68,74,70}, 5,3 , 10054,21 , 4,4 , 4,0 , 3266,8 , 3284,7 , 0, 0, 6, 6, 7 }, // Somali/Latin/Djibouti
- { 110, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {69,84,66}, 0,2 , 10075,22 , 4,4 , 4,0 , 3266,8 , 3291,8 , 2, 1, 7, 6, 7 }, // Somali/Latin/Ethiopia
- { 110, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {75,69,83}, 2,3 , 0,7 , 4,4 , 4,0 , 3266,8 , 3299,7 , 2, 1, 7, 6, 7 }, // Somali/Latin/Kenya
- { 111, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 4,0 , 3306,17 , 2048,6 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Spain
- { 111, 7, 10, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 479,14 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {65,82,83}, 12,1 , 10097,51 , 4,4 , 4,0 , 3323,7 , 3330,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Argentina
- { 111, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {66,79,66}, 293,2 , 10148,35 , 4,4 , 4,0 , 3323,7 , 3339,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Bolivia
- { 111, 7, 43, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 503,8 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,76,80}, 12,1 , 10183,45 , 4,4 , 48,5 , 3323,7 , 3346,5 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Chile
- { 111, 7, 47, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,79,80}, 12,1 , 10228,54 , 4,4 , 4,0 , 3323,7 , 3351,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Colombia
- { 111, 7, 52, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,82,67}, 295,1 , 10282,67 , 4,4 , 4,0 , 3323,7 , 3359,10 , 0, 0, 1, 6, 7 }, // Spanish/Latin/CostaRica
- { 111, 7, 55, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,85,80}, 12,1 , 10349,42 , 4,4 , 4,0 , 3323,7 , 3369,4 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Cuba
- { 111, 7, 61, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {68,79,80}, 12,1 , 10391,54 , 4,4 , 4,0 , 3323,7 , 3373,20 , 2, 1, 7, 6, 7 }, // Spanish/Latin/DominicanRepublic
- { 111, 7, 63, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 48,5 , 3323,7 , 3393,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ecuador
- { 111, 7, 65, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 204,3 , 10445,70 , 4,4 , 4,0 , 3323,7 , 3400,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/ElSalvador
- { 111, 7, 66, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {88,65,70}, 36,4 , 10515,53 , 4,4 , 4,0 , 3323,7 , 3411,17 , 0, 0, 1, 6, 7 }, // Spanish/Latin/EquatorialGuinea
- { 111, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {71,84,81}, 296,1 , 10568,70 , 4,4 , 4,0 , 3323,7 , 3428,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Guatemala
- { 111, 7, 96, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 1033,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {72,78,76}, 297,1 , 10638,60 , 4,4 , 4,0 , 3323,7 , 3437,8 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Honduras
- { 111, 7, 139, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {77,88,78}, 12,1 , 10698,48 , 4,4 , 4,0 , 3323,7 , 3445,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Mexico
- { 111, 7, 155, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {78,73,79}, 298,2 , 10746,69 , 4,4 , 4,0 , 3323,7 , 3451,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Nicaragua
- { 111, 7, 166, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 1060,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,65,66}, 300,3 , 10815,54 , 4,4 , 4,0 , 3323,7 , 3460,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Panama
- { 111, 7, 168, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,89,71}, 303,1 , 10869,61 , 14,5 , 65,6 , 3323,7 , 3466,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Paraguay
- { 111, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 37,5 , 493,15 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,69,78}, 304,3 , 10930,62 , 4,4 , 4,0 , 3323,7 , 3474,4 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Peru
- { 111, 7, 170, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {80,72,80}, 183,1 , 10992,48 , 25,5 , 4,0 , 3323,7 , 3478,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Philippines
- { 111, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 1060,8 , 897,27 , 18,7 , 25,12 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 4,0 , 3323,7 , 1178,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/PuertoRico
- { 111, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 518,6 , 897,27 , 18,7 , 25,12 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 4,0 , 3323,7 , 3487,14 , 2, 1, 7, 6, 7 }, // Spanish/Latin/UnitedStates
- { 111, 7, 227, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,89,85}, 12,1 , 11040,48 , 14,5 , 71,7 , 3323,7 , 3501,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Uruguay
- { 111, 7, 231, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {86,69,70}, 307,3 , 11088,64 , 4,4 , 48,5 , 3323,7 , 3508,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Venezuela
- { 111, 7, 238, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 4,0 , 3323,7 , 3517,14 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CanaryIslands
- { 111, 7, 246, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {0,0,0}, 0,0 , 11152,0 , 4,4 , 4,0 , 3531,23 , 3554,13 , 2, 1, 1, 6, 7 }, // Spanish/Latin/LatinAmericaAndTheCaribbean
- { 111, 7, 250, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 4,0 , 3323,7 , 3567,15 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CeutaAndMelilla
- { 113, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {84,90,83}, 192,3 , 11152,27 , 4,4 , 8,6 , 3582,9 , 1325,8 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Tanzania
- { 113, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {75,69,83}, 2,3 , 11179,24 , 4,4 , 4,0 , 3582,9 , 1006,5 , 2, 1, 7, 6, 7 }, // Swahili/Latin/Kenya
- { 113, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {85,71,88}, 197,3 , 11203,25 , 4,4 , 8,6 , 3582,9 , 1381,6 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Uganda
- { 114, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {83,69,75}, 157,2 , 11228,45 , 25,5 , 4,0 , 3591,7 , 3598,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Sweden
- { 114, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {69,85,82}, 131,1 , 11273,19 , 25,5 , 4,0 , 3591,7 , 3605,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Finland
- { 114, 7, 248, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {69,85,82}, 131,1 , 11273,19 , 25,5 , 4,0 , 3591,7 , 3612,5 , 2, 1, 1, 6, 7 }, // Swedish/Latin/AlandIslands
- { 116, 2, 209, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 171, 8222, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 17980,48 , 18028,71 , 158,27 , 17980,48 , 18028,71 , 158,27 , 9770,28 , 9798,55 , 85,14 , 9770,28 , 9798,55 , 85,14 , 0,2 , 0,2 , {84,74,83}, 242,3 , 11292,13 , 14,5 , 4,0 , 3617,6 , 3623,10 , 2, 1, 1, 6, 7 }, // Tajik/Cyrillic/Tajikistan
- { 117, 27, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {73,78,82}, 122,1 , 11305,13 , 14,5 , 4,0 , 3633,5 , 3638,7 , 2, 1, 7, 7, 7 }, // Tamil/Tamil/India
- { 117, 27, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {77,89,82}, 256,2 , 11318,22 , 14,5 , 4,0 , 3633,5 , 3645,7 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Malaysia
- { 117, 27, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {83,71,68}, 12,1 , 11340,24 , 14,5 , 4,0 , 3633,5 , 3652,11 , 2, 1, 7, 6, 7 }, // Tamil/Tamil/Singapore
- { 117, 27, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {76,75,82}, 310,3 , 11364,20 , 14,5 , 4,0 , 3633,5 , 3663,6 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/SriLanka
- { 119, 28, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 499,11 , 499,11 , 503,8 , 99,16 , 18,7 , 25,12 , 18360,66 , 18426,86 , 18512,31 , 18543,78 , 18426,86 , 18621,31 , 9922,32 , 9954,60 , 10014,18 , 9922,32 , 9954,60 , 10014,18 , 0,2 , 0,2 , {73,78,82}, 122,1 , 11384,26 , 4,4 , 8,6 , 3669,6 , 3675,9 , 2, 1, 7, 7, 7 }, // Telugu/Telugu/India
- { 120, 30, 211, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 510,5 , 510,5 , 515,8 , 523,7 , 287,6 , 1098,19 , 37,5 , 508,28 , 18652,63 , 18715,98 , 18652,63 , 18652,63 , 18715,98 , 18813,62 , 10032,23 , 10055,68 , 10032,23 , 10032,23 , 10055,68 , 10032,23 , 284,10 , 274,10 , {84,72,66}, 313,1 , 11410,13 , 4,4 , 8,6 , 3684,3 , 3684,3 , 2, 1, 7, 6, 7 }, // Thai/Thai/Thailand
- { 121, 31, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 2663,63 , 18875,158 , 158,27 , 2663,63 , 18875,158 , 158,27 , 10123,49 , 10172,77 , 10249,21 , 10123,49 , 10172,77 , 10270,22 , 294,7 , 284,8 , {67,78,89}, 314,1 , 11423,13 , 14,5 , 4,0 , 3687,8 , 3695,6 , 2, 1, 7, 6, 7 }, // Tibetan/Tibetan/China
- { 121, 31, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 2663,63 , 18875,158 , 158,27 , 2663,63 , 18875,158 , 158,27 , 10123,49 , 10172,77 , 10249,21 , 10123,49 , 10172,77 , 10270,22 , 294,7 , 284,8 , {73,78,82}, 122,1 , 11436,22 , 14,5 , 4,0 , 3687,8 , 3701,7 , 2, 1, 7, 7, 7 }, // Tibetan/Tibetan/India
- { 122, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1117,23 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 10292,29 , 10292,29 , 10321,14 , 10292,29 , 10292,29 , 10321,14 , 301,7 , 292,7 , {69,84,66}, 0,2 , 11458,16 , 4,4 , 4,0 , 3708,4 , 103,5 , 2, 1, 7, 6, 7 }, // Tigrinya/Ethiopic/Ethiopia
- { 122, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1140,23 , 18,7 , 25,12 , 19141,46 , 19187,54 , 1050,24 , 19141,46 , 19187,54 , 1050,24 , 10335,29 , 10335,29 , 10321,14 , 10335,29 , 10335,29 , 10321,14 , 301,7 , 292,7 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 3708,4 , 3712,4 , 2, 1, 1, 6, 7 }, // Tigrinya/Ethiopic/Eritrea
- { 123, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 530,8 , 530,8 , 530,8 , 530,8 , 287,6 , 99,16 , 37,5 , 8,10 , 19241,51 , 19292,87 , 19379,24 , 19241,51 , 19292,87 , 19379,24 , 10364,29 , 10393,60 , 10453,14 , 10364,29 , 10393,60 , 10453,14 , 0,2 , 0,2 , {84,79,80}, 195,2 , 0,7 , 14,5 , 4,0 , 3716,13 , 1333,5 , 2, 1, 1, 6, 7 }, // Tongan/Latin/Tonga
- { 124, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 19403,48 , 19451,122 , 158,27 , 19403,48 , 19451,122 , 158,27 , 10467,27 , 10494,72 , 85,14 , 10467,27 , 10494,72 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3729,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tsonga/Latin/SouthAfrica
- { 125, 7, 217, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 538,8 , 538,8 , 1163,9 , 1172,16 , 37,5 , 8,10 , 19573,48 , 19621,75 , 19696,24 , 19573,48 , 19621,75 , 19696,24 , 10566,28 , 10594,54 , 10648,14 , 10566,28 , 10594,54 , 10648,14 , 308,2 , 299,2 , {84,82,89}, 315,1 , 11474,18 , 25,5 , 30,7 , 3737,6 , 3743,7 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Turkey
- { 125, 7, 56, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 538,8 , 538,8 , 1163,9 , 1172,16 , 37,5 , 8,10 , 19573,48 , 19621,75 , 19696,24 , 19573,48 , 19621,75 , 19696,24 , 10566,28 , 10594,54 , 10648,14 , 10566,28 , 10594,54 , 10648,14 , 308,2 , 299,2 , {69,85,82}, 131,1 , 7151,11 , 25,5 , 30,7 , 3737,6 , 3750,23 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Cyprus
- { 129, 2, 222, 44, 160, 59, 37, 48, 45, 43, 1077, 171, 187, 8222, 8220, 0,6 , 0,6 , 546,8 , 546,8 , 187,8 , 1188,22 , 37,5 , 8,10 , 19720,48 , 19768,95 , 19863,24 , 19887,67 , 19954,87 , 19863,24 , 10662,21 , 10683,56 , 10739,14 , 10662,21 , 10683,56 , 10739,14 , 310,2 , 301,2 , {85,65,72}, 279,1 , 11492,49 , 25,5 , 4,0 , 3773,10 , 3783,7 , 2, 1, 1, 6, 7 }, // Ukrainian/Cyrillic/Ukraine
- { 130, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 554,10 , 564,9 , 287,6 , 161,18 , 18,7 , 25,12 , 20041,66 , 20041,66 , 134,24 , 20041,66 , 20041,66 , 134,24 , 10753,36 , 10753,36 , 85,14 , 10753,36 , 10753,36 , 85,14 , 312,9 , 303,9 , {80,75,82}, 180,2 , 11541,21 , 4,4 , 4,0 , 3790,4 , 3794,7 , 0, 0, 7, 6, 7 }, // Urdu/Arabic/Pakistan
- { 130, 1, 100, 46, 44, 59, 37, 1776, 45, 43, 1602, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 554,10 , 564,9 , 287,6 , 161,18 , 18,7 , 25,12 , 20041,66 , 20041,66 , 134,24 , 20041,66 , 20041,66 , 134,24 , 10753,36 , 10753,36 , 85,14 , 10753,36 , 10753,36 , 85,14 , 312,9 , 303,9 , {73,78,82}, 122,1 , 11562,18 , 14,5 , 4,0 , 3790,4 , 3801,5 , 2, 1, 7, 7, 7 }, // Urdu/Arabic/India
- { 131, 2, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 17980,48 , 18028,71 , 14970,24 , 17980,48 , 18028,71 , 14970,24 , 10789,28 , 10817,53 , 10870,14 , 10789,28 , 10817,53 , 10870,14 , 0,2 , 0,2 , {85,90,83}, 316,3 , 11580,21 , 14,5 , 4,0 , 3806,5 , 3811,10 , 0, 0, 1, 6, 7 }, // Uzbek/Cyrillic/Uzbekistan
- { 131, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 179,8 , 1210,33 , 61,4 , 408,11 , 20107,48 , 13771,68 , 158,27 , 20107,48 , 13771,68 , 158,27 , 10884,21 , 7208,49 , 85,14 , 10884,21 , 7208,49 , 85,14 , 0,2 , 0,2 , {65,70,78}, 263,1 , 11601,13 , 25,5 , 4,0 , 3821,6 , 2776,9 , 0, 0, 6, 4, 5 }, // Uzbek/Arabic/Afghanistan
- { 131, 7, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 20155,52 , 20207,77 , 20284,24 , 20155,52 , 20207,77 , 20284,24 , 10905,34 , 10939,61 , 11000,14 , 10905,34 , 10939,61 , 11000,14 , 0,2 , 0,2 , {85,90,83}, 319,4 , 11614,23 , 14,5 , 4,0 , 3827,9 , 3836,11 , 0, 0, 1, 6, 7 }, // Uzbek/Latin/Uzbekistan
- { 132, 7, 232, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 573,8 , 573,8 , 141,10 , 1243,31 , 37,5 , 8,10 , 20308,75 , 20383,130 , 158,27 , 20308,75 , 20383,130 , 158,27 , 11014,33 , 11047,55 , 11102,21 , 11014,33 , 11047,55 , 11102,21 , 321,2 , 312,2 , {86,78,68}, 323,1 , 11637,20 , 25,5 , 4,0 , 3847,10 , 3857,8 , 0, 0, 1, 6, 7 }, // Vietnamese/Latin/Vietnam
- { 134, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 135,7 , 135,7 , 141,10 , 10,17 , 37,5 , 8,10 , 20513,52 , 20565,87 , 20652,26 , 20678,62 , 20565,87 , 20652,26 , 11123,29 , 11152,77 , 11229,15 , 11244,30 , 11152,77 , 11229,15 , 0,2 , 0,2 , {71,66,80}, 171,1 , 11657,154 , 4,4 , 4,0 , 3865,7 , 3872,16 , 2, 1, 1, 6, 7 }, // Welsh/Latin/UnitedKingdom
- { 136, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 20740,48 , 20788,91 , 158,27 , 20740,48 , 20788,91 , 158,27 , 11274,28 , 11302,61 , 85,14 , 11274,28 , 11302,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3888,8 , 0,0 , 2, 1, 7, 6, 7 }, // Xhosa/Latin/SouthAfrica
- { 138, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 20879,73 , 20952,121 , 158,27 , 20879,73 , 20952,121 , 158,27 , 11363,44 , 11407,69 , 85,14 , 11363,44 , 11407,69 , 85,14 , 323,5 , 314,5 , {78,71,78}, 182,1 , 11811,34 , 4,4 , 8,6 , 3896,10 , 3906,18 , 2, 1, 1, 6, 7 }, // Yoruba/Latin/Nigeria
- { 140, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 581,9 , 590,10 , 72,10 , 82,17 , 18,7 , 25,12 , 21073,48 , 21121,104 , 134,24 , 21073,48 , 21225,90 , 134,24 , 11476,28 , 11504,68 , 11572,14 , 11476,28 , 11504,68 , 11572,14 , 328,7 , 319,8 , {90,65,82}, 11,1 , 11845,27 , 4,4 , 8,6 , 3924,7 , 3931,17 , 2, 1, 7, 6, 7 }, // Zulu/Latin/SouthAfrica
- { 141, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 187,8 , 554,17 , 37,5 , 392,16 , 5815,48 , 13184,83 , 134,24 , 13267,59 , 13184,83 , 134,24 , 11586,28 , 11614,51 , 2309,14 , 11665,28 , 11614,51 , 2309,14 , 335,9 , 327,11 , {78,79,75}, 157,2 , 11872,42 , 25,5 , 4,0 , 3948,7 , 3955,5 , 2, 1, 1, 6, 7 }, // NorwegianNynorsk/Latin/Norway
- { 142, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 118,7 , 118,7 , 1274,9 , 981,20 , 37,5 , 8,10 , 15514,48 , 21315,83 , 15643,24 , 15514,48 , 21315,83 , 15643,24 , 2032,28 , 2060,58 , 85,14 , 2032,28 , 2060,58 , 85,14 , 248,9 , 238,7 , {66,65,77}, 153,2 , 11914,218 , 14,5 , 4,0 , 3960,8 , 581,19 , 2, 1, 1, 6, 7 }, // Bosnian/Latin/BosniaAndHerzegowina
- { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 37,5 , 8,10 , 15302,48 , 15431,83 , 11981,24 , 15302,48 , 15431,83 , 11981,24 , 8275,28 , 8303,54 , 8261,14 , 8275,28 , 8303,54 , 8261,14 , 239,9 , 231,7 , {66,65,77}, 284,2 , 12132,195 , 25,5 , 4,0 , 3968,8 , 3111,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/BosniaAndHerzegowina
- { 144, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 82,17 , 37,5 , 8,10 , 21398,102 , 21500,140 , 158,27 , 21398,102 , 21500,140 , 158,27 , 11693,30 , 11723,57 , 85,14 , 11693,30 , 11723,57 , 85,14 , 75,4 , 74,4 , {71,66,80}, 171,1 , 0,7 , 4,4 , 4,0 , 3976,5 , 3981,14 , 2, 1, 1, 6, 7 }, // Manx/Latin/UnitedKingdom
- { 145, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 99,16 , 37,5 , 8,10 , 21640,46 , 21686,124 , 158,27 , 21640,46 , 21686,124 , 158,27 , 11780,28 , 11808,60 , 85,14 , 11780,28 , 11808,60 , 85,14 , 75,4 , 74,4 , {71,66,80}, 171,1 , 0,7 , 4,4 , 4,0 , 3995,8 , 3981,14 , 2, 1, 1, 6, 7 }, // Cornish/Latin/UnitedKingdom
- { 146, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 21810,48 , 21858,192 , 158,27 , 21810,48 , 21858,192 , 158,27 , 11868,28 , 11896,49 , 11945,14 , 11868,28 , 11896,49 , 11945,14 , 344,2 , 338,2 , {71,72,83}, 173,3 , 12327,17 , 4,4 , 4,0 , 4003,4 , 4007,5 , 2, 1, 1, 6, 7 }, // Akan/Latin/Ghana
- { 147, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 634,6 , 99,16 , 18,7 , 25,12 , 22050,87 , 22050,87 , 158,27 , 22050,87 , 22050,87 , 158,27 , 6771,32 , 11959,55 , 85,14 , 6771,32 , 11959,55 , 85,14 , 346,5 , 340,5 , {73,78,82}, 122,1 , 0,7 , 14,5 , 4,0 , 4012,6 , 2276,4 , 2, 1, 7, 7, 7 }, // Konkani/Devanagari/India
- { 149, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 22137,48 , 22185,86 , 158,27 , 22137,48 , 22185,86 , 158,27 , 12014,29 , 12043,57 , 85,14 , 12014,29 , 12043,57 , 85,14 , 351,4 , 345,4 , {78,71,78}, 182,1 , 12344,12 , 4,4 , 8,6 , 4018,4 , 1107,7 , 2, 1, 1, 6, 7 }, // Igbo/Latin/Nigeria
- { 150, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 22271,48 , 22319,189 , 22508,24 , 22271,48 , 22319,189 , 22508,24 , 12100,28 , 12128,74 , 12202,14 , 12100,28 , 12128,74 , 12202,14 , 355,9 , 349,7 , {75,69,83}, 2,3 , 12356,23 , 4,4 , 8,6 , 4022,7 , 1006,5 , 2, 1, 7, 6, 7 }, // Kamba/Latin/Kenya
- { 152, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1283,22 , 18,7 , 25,12 , 22532,47 , 22579,77 , 22656,24 , 22532,47 , 22579,77 , 22656,24 , 12216,26 , 12242,43 , 12285,14 , 12216,26 , 12242,43 , 12285,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4029,3 , 3712,4 , 2, 1, 1, 6, 7 }, // Blin/Ethiopic/Eritrea
- { 157, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1305,21 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 12299,27 , 12326,41 , 12367,14 , 12299,27 , 12326,41 , 12367,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4032,3 , 3712,4 , 2, 1, 1, 6, 7 }, // Tigre/Ethiopic/Eritrea
- { 159, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 1326,27 , 37,5 , 8,10 , 22680,48 , 22728,77 , 22805,24 , 22680,48 , 22728,77 , 22805,24 , 12381,28 , 12409,50 , 3070,14 , 12381,28 , 12409,50 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 14,5 , 4,0 , 4035,6 , 4041,6 , 2, 1, 1, 6, 7 }, // Friulian/Latin/Italy
- { 160, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 22829,48 , 22877,111 , 158,27 , 22829,48 , 22877,111 , 158,27 , 12459,27 , 12486,70 , 85,14 , 12459,27 , 12486,70 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4047,9 , 0,0 , 2, 1, 7, 6, 7 }, // Venda/Latin/SouthAfrica
- { 161, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 600,11 , 611,10 , 518,6 , 1353,23 , 536,12 , 548,12 , 22988,48 , 23036,87 , 23123,24 , 22988,48 , 23036,87 , 23123,24 , 12556,28 , 12584,44 , 12628,14 , 12556,28 , 12584,44 , 12628,14 , 364,3 , 356,5 , {71,72,83}, 173,3 , 12379,37 , 4,4 , 8,6 , 4056,6 , 4062,12 , 2, 1, 1, 6, 7 }, // Ewe/Latin/Ghana
- { 161, 7, 212, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 600,11 , 611,10 , 518,6 , 1353,23 , 536,12 , 548,12 , 22988,48 , 23036,87 , 23123,24 , 22988,48 , 23036,87 , 23123,24 , 12556,28 , 12584,44 , 12628,14 , 12556,28 , 12584,44 , 12628,14 , 364,3 , 356,5 , {88,79,70}, 209,3 , 12416,106 , 4,4 , 8,6 , 4056,6 , 4074,11 , 0, 0, 1, 6, 7 }, // Ewe/Latin/Togo
- { 162, 14, 69, 46, 8217, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1376,22 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 12642,27 , 12642,27 , 12669,14 , 12642,27 , 12642,27 , 12669,14 , 0,2 , 0,2 , {69,84,66}, 0,2 , 11458,16 , 4,4 , 4,0 , 4085,5 , 103,5 , 2, 1, 7, 6, 7 }, // Walamo/Ethiopic/Ethiopia
- { 163, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 10,17 , 18,7 , 25,12 , 23147,59 , 23206,95 , 158,27 , 23147,59 , 23206,95 , 158,27 , 12683,21 , 12704,57 , 85,14 , 12683,21 , 12704,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 0,7 , 4,4 , 8,6 , 4090,14 , 4104,19 , 2, 1, 7, 6, 7 }, // Hawaiian/Latin/UnitedStates
- { 166, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 621,8 , 621,8 , 518,6 , 1398,18 , 37,5 , 8,10 , 23301,48 , 23349,88 , 23437,24 , 23301,48 , 23349,88 , 23437,24 , 12761,28 , 12789,55 , 12844,14 , 12858,28 , 12789,55 , 12844,14 , 0,2 , 0,2 , {80,72,80}, 183,1 , 12522,22 , 4,4 , 8,6 , 4123,8 , 4131,9 , 2, 1, 7, 6, 7 }, // Filipino/Latin/Philippines
- { 167, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 23461,86 , 134,24 , 6990,48 , 23461,86 , 134,24 , 12886,28 , 12914,63 , 3471,14 , 12886,28 , 12914,63 , 3471,14 , 94,5 , 361,4 , {67,72,70}, 230,3 , 12544,55 , 25,5 , 4,0 , 4140,16 , 4156,7 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Switzerland
- { 168, 34, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 158,27 , 23547,38 , 158,27 , 158,27 , 23547,38 , 158,27 , 12977,21 , 12998,28 , 13026,14 , 12977,21 , 12998,28 , 13026,14 , 367,2 , 365,2 , {67,78,89}, 314,1 , 0,7 , 14,5 , 4,0 , 4163,3 , 4166,2 , 2, 1, 7, 6, 7 }, // Sichuan Yi/Yi/China
- { 171, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 23585,48 , 23633,100 , 158,27 , 23585,48 , 23633,100 , 158,27 , 13040,27 , 13067,66 , 85,14 , 13040,27 , 13067,66 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4168,10 , 0,0 , 2, 1, 7, 6, 7 }, // South Ndebele/Latin/SouthAfrica
- { 172, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 23733,48 , 23781,94 , 158,27 , 23733,48 , 23781,94 , 158,27 , 13133,27 , 13160,63 , 85,14 , 13133,27 , 13160,63 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4178,16 , 0,0 , 2, 1, 7, 6, 7 }, // Northern Sotho/Latin/SouthAfrica
- { 173, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 72,10 , 323,17 , 37,5 , 8,10 , 23875,59 , 23934,145 , 24079,24 , 23875,59 , 23934,145 , 24079,24 , 13223,33 , 13256,75 , 13331,14 , 13223,33 , 13256,75 , 13331,14 , 0,2 , 0,2 , {78,79,75}, 157,2 , 12599,63 , 25,5 , 4,0 , 4194,15 , 4209,5 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Norway
- { 173, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 72,10 , 323,17 , 37,5 , 8,10 , 24103,85 , 23934,145 , 24079,24 , 24103,85 , 23934,145 , 24079,24 , 13223,33 , 13345,65 , 13410,14 , 13223,33 , 13345,65 , 13410,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 12662,23 , 25,5 , 4,0 , 4194,15 , 4214,6 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Finland
- { 175, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24188,48 , 24236,88 , 24324,24 , 24188,48 , 24236,88 , 24324,24 , 13424,28 , 13452,62 , 13514,14 , 13424,28 , 13452,62 , 13514,14 , 369,5 , 367,10 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4220,8 , 1006,5 , 2, 1, 7, 6, 7 }, // Gusii/Latin/Kenya
- { 176, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24348,48 , 24396,221 , 24617,24 , 24348,48 , 24396,221 , 24617,24 , 13528,28 , 13556,105 , 13661,14 , 13528,28 , 13556,105 , 13661,14 , 374,10 , 377,10 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4228,7 , 1006,5 , 2, 1, 7, 6, 7 }, // Taita/Latin/Kenya
- { 177, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 24641,48 , 24689,77 , 24766,24 , 24641,48 , 24689,77 , 24766,24 , 13675,28 , 13703,59 , 13762,14 , 13675,28 , 13703,59 , 13762,14 , 384,6 , 387,7 , {88,79,70}, 209,3 , 12709,26 , 25,5 , 4,0 , 4235,6 , 4241,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Senegal
- { 178, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24790,48 , 24838,185 , 25023,24 , 24790,48 , 24838,185 , 25023,24 , 13776,28 , 13804,63 , 13867,14 , 13776,28 , 13804,63 , 13867,14 , 390,6 , 394,8 , {75,69,83}, 2,3 , 12735,23 , 4,4 , 8,6 , 4249,6 , 1006,5 , 2, 1, 7, 6, 7 }, // Kikuyu/Latin/Kenya
- { 179, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25047,48 , 25095,173 , 25268,24 , 25047,48 , 25095,173 , 25268,24 , 13881,28 , 13909,105 , 14014,14 , 13881,28 , 13909,105 , 14014,14 , 396,7 , 402,5 , {75,69,83}, 2,3 , 12758,25 , 4,4 , 8,6 , 4255,8 , 1006,5 , 2, 1, 7, 6, 7 }, // Samburu/Latin/Kenya
- { 180, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 897,27 , 37,5 , 8,10 , 25292,48 , 25340,88 , 134,24 , 25292,48 , 25340,88 , 134,24 , 14028,28 , 14056,55 , 14111,14 , 14028,28 , 14056,55 , 14111,14 , 0,2 , 0,2 , {77,90,78}, 269,3 , 12783,28 , 0,4 , 4,0 , 4263,4 , 2902,10 , 2, 1, 7, 6, 7 }, // Sena/Latin/Mozambique
- { 181, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25428,52 , 25480,112 , 25592,24 , 25428,52 , 25480,112 , 25592,24 , 14125,28 , 14153,50 , 14203,14 , 14125,28 , 14153,50 , 14203,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 12811,24 , 4,4 , 8,6 , 4168,10 , 1491,8 , 2, 1, 7, 6, 7 }, // North Ndebele/Latin/Zimbabwe
- { 182, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25616,39 , 25655,194 , 25849,24 , 25616,39 , 25655,194 , 25849,24 , 14217,29 , 14246,65 , 14311,14 , 14217,29 , 14246,65 , 14311,14 , 403,8 , 407,7 , {84,90,83}, 192,3 , 12835,25 , 4,4 , 4,0 , 4267,9 , 1325,8 , 0, 0, 1, 6, 7 }, // Rombo/Latin/Tanzania
- { 183, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 25873,48 , 25921,81 , 26002,24 , 25873,48 , 25921,81 , 26002,24 , 14325,30 , 14355,47 , 85,14 , 14325,30 , 14355,47 , 85,14 , 411,6 , 414,8 , {77,65,68}, 0,0 , 12860,21 , 0,4 , 4,0 , 4276,8 , 4284,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Tifinagh/Morocco
- { 183, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26026,48 , 26074,81 , 26155,24 , 26026,48 , 26074,81 , 26155,24 , 14402,30 , 14432,48 , 85,14 , 14402,30 , 14432,48 , 85,14 , 417,6 , 422,8 , {77,65,68}, 0,0 , 12881,21 , 0,4 , 4,0 , 4290,9 , 4299,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Latin/Morocco
- { 184, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26179,48 , 26227,84 , 26311,24 , 26179,48 , 26227,84 , 26311,24 , 14480,30 , 14510,51 , 14561,14 , 14480,30 , 14510,51 , 14561,14 , 423,7 , 430,9 , {68,90,68}, 207,2 , 12902,21 , 0,4 , 4,0 , 4305,9 , 4314,8 , 2, 1, 6, 4, 5 }, // Kabyle/Latin/Algeria
- { 185, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26335,48 , 26383,152 , 134,24 , 26335,48 , 26383,152 , 134,24 , 14575,28 , 14603,74 , 14677,14 , 14575,28 , 14603,74 , 14677,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 12923,26 , 4,4 , 78,5 , 4322,10 , 1381,6 , 0, 0, 1, 6, 7 }, // Nyankole/Latin/Uganda
- { 186, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26535,48 , 26583,254 , 26837,24 , 26535,48 , 26583,254 , 26837,24 , 14691,28 , 14719,82 , 14801,14 , 14691,28 , 14719,82 , 14801,14 , 430,7 , 439,7 , {84,90,83}, 192,3 , 12949,29 , 0,4 , 4,0 , 4332,6 , 4338,10 , 0, 0, 1, 6, 7 }, // Bena/Latin/Tanzania
- { 187, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 4,0 , 4348,8 , 1325,8 , 0, 0, 1, 6, 7 }, // Vunjo/Latin/Tanzania
- { 188, 7, 132, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26948,47 , 26995,92 , 27087,24 , 26948,47 , 26995,92 , 27087,24 , 14919,28 , 14947,44 , 14991,14 , 14919,28 , 14947,44 , 14991,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 13005,24 , 4,4 , 8,6 , 4356,9 , 1836,4 , 0, 0, 1, 6, 7 }, // Bambara/Latin/Mali
- { 189, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 27111,48 , 27159,207 , 27366,24 , 27111,48 , 27159,207 , 27366,24 , 15005,28 , 15033,64 , 15097,14 , 15005,28 , 15033,64 , 15097,14 , 442,2 , 455,2 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4365,6 , 1006,5 , 2, 1, 7, 6, 7 }, // Embu/Latin/Kenya
- { 190, 12, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 27390,36 , 27426,58 , 27484,24 , 27390,36 , 27426,58 , 27484,24 , 15111,28 , 15139,49 , 15188,14 , 15111,28 , 15139,49 , 15188,14 , 444,3 , 457,6 , {85,83,68}, 12,1 , 13029,19 , 4,4 , 8,6 , 4371,3 , 4374,4 , 2, 1, 7, 6, 7 }, // Cherokee/Cherokee/UnitedStates
- { 191, 7, 137, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 27508,47 , 27555,68 , 27623,24 , 27508,47 , 27555,68 , 27623,24 , 15202,27 , 15229,48 , 15277,14 , 15202,27 , 15229,48 , 15277,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 13048,21 , 14,5 , 4,0 , 4378,14 , 4392,5 , 0, 0, 1, 6, 7 }, // Morisyen/Latin/Mauritius
- { 192, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 27647,264 , 134,24 , 17628,48 , 27647,264 , 134,24 , 15291,28 , 15319,133 , 14311,14 , 15291,28 , 15319,133 , 14311,14 , 447,4 , 463,5 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 8,6 , 4397,10 , 1325,8 , 0, 0, 1, 6, 7 }, // Makonde/Latin/Tanzania
- { 193, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 27911,83 , 27994,111 , 28105,24 , 27911,83 , 27994,111 , 28105,24 , 15452,36 , 15488,63 , 15551,14 , 15452,36 , 15488,63 , 15551,14 , 451,3 , 468,3 , {84,90,83}, 192,3 , 13069,29 , 14,5 , 4,0 , 4407,8 , 4415,9 , 0, 0, 1, 6, 7 }, // Langi/Latin/Tanzania
- { 194, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28129,48 , 28177,97 , 134,24 , 28129,48 , 28177,97 , 134,24 , 15565,28 , 15593,66 , 15659,14 , 15565,28 , 15593,66 , 15659,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 13098,26 , 0,4 , 4,0 , 4424,7 , 4431,7 , 0, 0, 1, 6, 7 }, // Ganda/Latin/Uganda
- { 195, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28274,48 , 28322,83 , 28405,24 , 28274,48 , 28322,83 , 28405,24 , 15673,80 , 15673,80 , 85,14 , 15673,80 , 15673,80 , 85,14 , 454,8 , 471,7 , {90,77,87}, 202,2 , 0,7 , 4,4 , 8,6 , 4438,9 , 1485,6 , 2, 1, 1, 6, 7 }, // Bemba/Latin/Zambia
- { 196, 7, 39, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 453,7 , 453,7 , 364,8 , 1416,27 , 37,5 , 8,10 , 28429,48 , 28477,86 , 134,24 , 28429,48 , 28477,86 , 134,24 , 15753,28 , 15781,73 , 15854,14 , 15753,28 , 15781,73 , 15854,14 , 89,2 , 88,2 , {67,86,69}, 0,0 , 13124,25 , 0,4 , 4,0 , 4447,12 , 4459,10 , 2, 1, 1, 6, 7 }, // Kabuverdianu/Latin/CapeVerde
- { 197, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28563,48 , 28611,86 , 28697,24 , 28563,48 , 28611,86 , 28697,24 , 15868,28 , 15896,51 , 15947,14 , 15868,28 , 15896,51 , 15947,14 , 462,2 , 478,2 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4469,6 , 1006,5 , 2, 1, 7, 6, 7 }, // Meru/Latin/Kenya
- { 198, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28721,48 , 28769,111 , 28880,24 , 28721,48 , 28769,111 , 28880,24 , 15961,28 , 15989,93 , 16082,14 , 15961,28 , 15989,93 , 16082,14 , 464,4 , 480,4 , {75,69,83}, 2,3 , 13149,26 , 4,4 , 8,6 , 4475,8 , 4483,12 , 2, 1, 7, 6, 7 }, // Kalenjin/Latin/Kenya
- { 199, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 0,48 , 28904,136 , 134,24 , 0,48 , 28904,136 , 134,24 , 16096,23 , 16119,92 , 16211,14 , 16096,23 , 16119,92 , 16211,14 , 468,7 , 484,5 , {78,65,68}, 12,1 , 13175,22 , 4,4 , 4,0 , 4495,13 , 4508,8 , 2, 1, 1, 6, 7 }, // Nama/Latin/Namibia
- { 200, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 4,0 , 4516,9 , 1325,8 , 0, 0, 1, 6, 7 }, // Machame/Latin/Tanzania
- { 201, 7, 82, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 347,8 , 347,8 , 1443,10 , 1453,23 , 37,5 , 8,10 , 29040,59 , 29099,87 , 134,24 , 29186,48 , 29099,87 , 134,24 , 16225,28 , 16253,72 , 3471,14 , 16225,28 , 16253,72 , 3471,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 7151,11 , 25,5 , 4,0 , 4525,6 , 4531,11 , 2, 1, 1, 6, 7 }, // Colognian/Latin/Germany
- { 202, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29234,51 , 29285,132 , 158,27 , 29234,51 , 29285,132 , 158,27 , 14815,28 , 16325,58 , 14311,14 , 14815,28 , 16325,58 , 14311,14 , 475,9 , 489,6 , {75,69,83}, 2,3 , 13197,25 , 4,4 , 8,6 , 4542,3 , 1006,5 , 2, 1, 7, 6, 7 }, // Masai/Latin/Kenya
- { 202, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29234,51 , 29285,132 , 158,27 , 29234,51 , 29285,132 , 158,27 , 14815,28 , 16325,58 , 14311,14 , 14815,28 , 16325,58 , 14311,14 , 475,9 , 489,6 , {84,90,83}, 192,3 , 13222,28 , 4,4 , 8,6 , 4542,3 , 4545,8 , 0, 0, 1, 6, 7 }, // Masai/Latin/Tanzania
- { 203, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28129,48 , 28177,97 , 134,24 , 28129,48 , 28177,97 , 134,24 , 16383,35 , 16418,65 , 16483,14 , 16383,35 , 16418,65 , 16483,14 , 484,6 , 495,6 , {85,71,88}, 197,3 , 13098,26 , 25,5 , 4,0 , 4553,7 , 4431,7 , 0, 0, 1, 6, 7 }, // Soga/Latin/Uganda
- { 204, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29417,48 , 17676,84 , 134,24 , 29417,48 , 17676,84 , 134,24 , 16497,21 , 16518,75 , 85,14 , 16497,21 , 16518,75 , 85,14 , 75,4 , 74,4 , {75,69,83}, 2,3 , 13250,23 , 4,4 , 83,6 , 4560,7 , 1006,5 , 2, 1, 7, 6, 7 }, // Luyia/Latin/Kenya
- { 205, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29465,48 , 17676,84 , 134,24 , 29465,48 , 17676,84 , 134,24 , 16593,28 , 9539,60 , 14905,14 , 16593,28 , 9539,60 , 14905,14 , 490,9 , 501,8 , {84,90,83}, 192,3 , 13273,28 , 25,5 , 4,0 , 4567,6 , 4573,8 , 0, 0, 1, 6, 7 }, // Asu/Latin/Tanzania
- { 206, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29513,48 , 29561,94 , 29655,24 , 29513,48 , 29561,94 , 29655,24 , 16621,28 , 16649,69 , 16718,14 , 16621,28 , 16649,69 , 16718,14 , 499,9 , 509,6 , {85,71,88}, 197,3 , 13301,28 , 4,4 , 8,6 , 4581,6 , 1381,6 , 0, 0, 1, 6, 7 }, // Teso/Latin/Uganda
- { 206, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29513,48 , 29561,94 , 29655,24 , 29513,48 , 29561,94 , 29655,24 , 16621,28 , 16649,69 , 16718,14 , 16621,28 , 16649,69 , 16718,14 , 499,9 , 509,6 , {75,69,83}, 2,3 , 13329,27 , 4,4 , 8,6 , 4581,6 , 4587,5 , 2, 1, 7, 6, 7 }, // Teso/Latin/Kenya
+ { 6, 7, 257, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 115,8 , 123,18 , 42,7 , 49,12 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,2 , 7,2 , {69,85,82}, 19,1 , 81,11 , 4,4 , 4,0 , 77,5 , 99,6 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Kosovo
+ { 7, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 14,6 , 14,6 , 20,9 , 29,8 , 141,10 , 10,17 , 18,7 , 25,12 , 943,46 , 989,61 , 1050,24 , 1074,46 , 1120,62 , 1050,24 , 483,27 , 510,28 , 538,14 , 483,27 , 510,28 , 538,14 , 9,3 , 9,4 , {69,84,66}, 20,2 , 92,34 , 4,4 , 8,6 , 105,4 , 109,5 , 2, 1, 7, 6, 7 }, // Amharic/Ethiopic/Ethiopia
+ { 8, 1, 64, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {69,71,80}, 22,5 , 126,70 , 14,5 , 19,6 , 114,7 , 121,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Egypt
+ { 8, 1, 3, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {68,90,68}, 27,5 , 196,91 , 14,5 , 19,6 , 114,7 , 124,7 , 2, 1, 6, 4, 5 }, // Arabic/Arabic/Algeria
+ { 8, 1, 17, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {66,72,68}, 32,5 , 287,91 , 14,5 , 19,6 , 114,7 , 131,7 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Bahrain
+ { 8, 1, 42, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {88,65,70}, 37,4 , 378,84 , 14,5 , 19,6 , 114,7 , 138,4 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Chad
+ { 8, 1, 48, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {75,77,70}, 41,7 , 462,105 , 14,5 , 19,6 , 114,7 , 142,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Comoros
+ { 8, 1, 59, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {68,74,70}, 5,3 , 567,84 , 14,5 , 19,6 , 114,7 , 151,6 , 0, 0, 6, 6, 7 }, // Arabic/Arabic/Djibouti
+ { 8, 1, 67, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {69,82,78}, 8,3 , 651,91 , 14,5 , 19,6 , 114,7 , 157,7 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Eritrea
+ { 8, 1, 103, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1376,92 , 1376,92 , 1468,24 , 1492,92 , 1376,92 , 1468,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,81,68}, 48,5 , 742,84 , 14,5 , 19,6 , 114,7 , 164,6 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Iraq
+ { 8, 1, 105, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,76,83}, 53,1 , 826,133 , 14,5 , 19,6 , 114,7 , 170,7 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Israel
+ { 8, 1, 109, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {74,79,68}, 54,5 , 959,84 , 14,5 , 19,6 , 114,7 , 177,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Jordan
+ { 8, 1, 115, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {75,87,68}, 59,5 , 1043,84 , 14,5 , 19,6 , 114,7 , 183,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Kuwait
+ { 8, 1, 119, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {76,66,80}, 64,5 , 1127,84 , 14,5 , 19,6 , 114,7 , 189,5 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Lebanon
+ { 8, 1, 122, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {76,89,68}, 69,5 , 1211,77 , 14,5 , 19,6 , 114,7 , 194,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Libya
+ { 8, 1, 136, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,82,79}, 74,5 , 1288,112 , 14,5 , 19,6 , 114,7 , 199,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Mauritania
+ { 8, 1, 145, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1584,71 , 1655,71 , 1726,24 , 1655,71 , 1750,71 , 1821,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,65,68}, 79,5 , 1400,77 , 14,5 , 19,6 , 114,7 , 208,6 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Morocco
+ { 8, 1, 162, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {79,77,82}, 84,5 , 1477,77 , 14,5 , 19,6 , 114,7 , 214,5 , 3, 0, 6, 4, 5 }, // Arabic/Arabic/Oman
+ { 8, 1, 165, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,76,83}, 53,1 , 826,133 , 14,5 , 19,6 , 114,7 , 219,6 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/PalestinianTerritories
+ { 8, 1, 175, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {81,65,82}, 89,5 , 1554,70 , 4,4 , 4,0 , 114,7 , 225,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Qatar
+ { 8, 1, 186, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,65,82}, 94,5 , 1624,77 , 4,4 , 4,0 , 114,7 , 228,24 , 2, 1, 6, 4, 5 }, // Arabic/Arabic/SaudiArabia
+ { 8, 1, 194, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,79,83}, 99,1 , 1701,77 , 14,5 , 19,6 , 114,7 , 252,7 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Somalia
+ { 8, 1, 201, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,68,71}, 0,0 , 1778,84 , 14,5 , 19,6 , 114,7 , 259,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Sudan
+ { 8, 1, 207, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,89,80}, 100,5 , 1862,77 , 4,4 , 4,0 , 114,7 , 266,5 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Syria
+ { 8, 1, 216, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {84,78,68}, 105,5 , 1939,77 , 4,4 , 4,0 , 114,7 , 271,4 , 3, 0, 7, 5, 6 }, // Arabic/Arabic/Tunisia
+ { 8, 1, 223, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {65,69,68}, 110,5 , 2016,91 , 14,5 , 19,6 , 114,7 , 275,24 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/UnitedArabEmirates
+ { 8, 1, 236, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,65,68}, 79,5 , 1400,77 , 14,5 , 19,6 , 114,7 , 299,15 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/WesternSahara
+ { 8, 1, 237, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {89,69,82}, 115,5 , 2107,70 , 4,4 , 4,0 , 114,7 , 314,5 , 0, 0, 6, 4, 5 }, // Arabic/Arabic/Yemen
+ { 9, 10, 11, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 58,7 , 58,7 , 187,8 , 195,21 , 61,4 , 65,10 , 1845,48 , 1893,106 , 1999,24 , 1845,48 , 1893,106 , 1999,24 , 618,28 , 646,62 , 708,15 , 618,28 , 646,62 , 708,15 , 13,12 , 14,12 , {65,77,68}, 120,3 , 2177,46 , 25,5 , 4,0 , 319,7 , 326,8 , 0, 0, 1, 6, 7 }, // Armenian/Armenian/Armenia
+ { 10, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 216,8 , 224,18 , 75,8 , 83,12 , 2023,62 , 2085,88 , 158,27 , 2023,62 , 2085,88 , 158,27 , 723,37 , 760,58 , 85,14 , 723,37 , 760,58 , 85,14 , 25,9 , 26,7 , {73,78,82}, 123,1 , 0,7 , 14,5 , 4,0 , 334,7 , 341,4 , 2, 1, 7, 7, 7 }, // Assamese/Bengali/India
+ { 12, 7, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 250,19 , 37,5 , 8,10 , 2173,48 , 2221,77 , 158,27 , 2173,48 , 2221,77 , 158,27 , 818,26 , 844,67 , 99,14 , 818,26 , 844,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 124,4 , 2223,41 , 14,5 , 4,0 , 345,12 , 357,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Latin/Azerbaijan
+ { 12, 2, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 250,19 , 37,5 , 8,10 , 2298,77 , 2298,77 , 158,27 , 2298,77 , 2298,77 , 158,27 , 911,67 , 911,67 , 99,14 , 911,67 , 911,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 128,4 , 2264,12 , 14,5 , 4,0 , 367,10 , 367,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Cyrillic/Azerbaijan
+ { 14, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 65,9 , 65,9 , 72,10 , 269,18 , 37,5 , 8,10 , 2375,48 , 2423,93 , 2516,24 , 2375,48 , 2423,93 , 2516,24 , 978,21 , 999,68 , 1067,14 , 978,21 , 999,68 , 1081,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2276,12 , 25,5 , 30,7 , 377,7 , 384,8 , 2, 1, 1, 6, 7 }, // Basque/Latin/Spain
+ { 15, 11, 18, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 74,10 , 84,9 , 287,6 , 224,18 , 18,7 , 25,12 , 2540,90 , 2540,90 , 2630,33 , 2540,90 , 2540,90 , 2630,33 , 1095,37 , 1132,58 , 1190,18 , 1095,37 , 1132,58 , 1190,18 , 34,9 , 33,7 , {66,68,84}, 132,1 , 2288,21 , 0,4 , 37,6 , 392,5 , 397,8 , 2, 1, 5, 6, 7 }, // Bengali/Bengali/Bangladesh
+ { 15, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 74,10 , 84,9 , 287,6 , 224,18 , 18,7 , 25,12 , 2540,90 , 2540,90 , 2630,33 , 2540,90 , 2540,90 , 2630,33 , 1095,37 , 1132,58 , 1190,18 , 1095,37 , 1132,58 , 1190,18 , 34,9 , 33,7 , {73,78,82}, 123,1 , 2309,19 , 0,4 , 37,6 , 392,5 , 405,4 , 2, 1, 7, 7, 7 }, // Bengali/Bengali/India
+ { 16, 31, 25, 46, 44, 59, 37, 3872, 45, 43, 101, 8220, 8221, 8216, 8217, 93,9 , 93,9 , 93,9 , 93,9 , 72,10 , 293,30 , 95,22 , 117,27 , 2663,63 , 2726,191 , 2917,27 , 2944,27 , 2971,132 , 3103,27 , 1208,34 , 1242,79 , 1321,27 , 1208,34 , 1242,79 , 1321,27 , 43,5 , 40,6 , {66,84,78}, 133,3 , 2328,15 , 4,4 , 4,0 , 409,6 , 415,5 , 2, 1, 7, 6, 7 }, // Dzongkha/Tibetan/Bhutan
+ { 19, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 3130,55 , 3185,78 , 158,27 , 3130,55 , 3185,78 , 158,27 , 1348,33 , 1381,43 , 1424,21 , 1348,33 , 1381,43 , 1424,21 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2343,11 , 14,5 , 4,0 , 420,9 , 429,5 , 2, 1, 1, 6, 7 }, // Breton/Latin/France
+ { 20, 2, 33, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 340,18 , 37,5 , 8,10 , 3263,59 , 3322,82 , 3404,24 , 3263,59 , 3322,82 , 3404,24 , 1445,21 , 1466,55 , 1521,14 , 1445,21 , 1466,55 , 1521,14 , 48,7 , 46,7 , {66,71,78}, 136,3 , 2354,47 , 25,5 , 4,0 , 434,9 , 443,8 , 2, 1, 1, 6, 7 }, // Bulgarian/Cyrillic/Bulgaria
+ { 21, 25, 147, 46, 44, 4170, 37, 4160, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 3428,43 , 3471,88 , 3559,24 , 3428,43 , 3471,88 , 3559,24 , 1535,25 , 1560,54 , 1614,14 , 1535,25 , 1560,54 , 1614,14 , 55,5 , 53,3 , {77,77,75}, 139,1 , 2401,18 , 14,5 , 4,0 , 451,3 , 454,6 , 0, 0, 7, 6, 7 }, // Burmese/Myanmar/Myanmar
+ { 22, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 358,6 , 10,17 , 144,5 , 149,10 , 3583,48 , 3631,99 , 3730,24 , 3754,48 , 3802,95 , 3897,24 , 1628,21 , 1649,56 , 1705,14 , 1628,21 , 1649,56 , 1705,14 , 60,10 , 56,13 , {66,89,82}, 140,2 , 2419,23 , 4,4 , 4,0 , 460,10 , 470,8 , 0, 0, 7, 6, 7 }, // Belarusian/Cyrillic/Belarus
+ { 23, 20, 36, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 109,9 , 364,8 , 10,17 , 18,7 , 25,12 , 3921,71 , 3921,71 , 158,27 , 3921,71 , 3921,71 , 158,27 , 1719,46 , 1719,46 , 1765,14 , 1719,46 , 1719,46 , 1765,14 , 70,5 , 69,5 , {75,72,82}, 142,1 , 2442,18 , 4,4 , 8,6 , 478,5 , 483,7 , 2, 1, 7, 6, 7 }, // Khmer/Khmer/Cambodia
+ { 24, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 27,8 , 372,21 , 159,4 , 163,9 , 3992,60 , 4052,82 , 4134,24 , 4158,93 , 4251,115 , 4366,24 , 1779,21 , 1800,60 , 1779,21 , 1860,28 , 1888,60 , 1779,21 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 4,4 , 8,6 , 490,6 , 496,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Spain
+ { 24, 7, 5, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 27,8 , 372,21 , 159,4 , 163,9 , 3992,60 , 4052,82 , 4134,24 , 4158,93 , 4251,115 , 4366,24 , 1779,21 , 1800,60 , 1779,21 , 1860,28 , 1888,60 , 1779,21 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 4,4 , 8,6 , 490,6 , 503,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Andorra
+ { 25, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 393,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {67,78,89}, 143,1 , 2480,10 , 4,4 , 8,6 , 510,4 , 514,2 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/China
+ { 25, 5, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {72,75,68}, 12,1 , 2490,9 , 4,4 , 4,0 , 510,4 , 516,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/HongKong
+ { 25, 5, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {77,79,80}, 144,4 , 2499,10 , 4,4 , 4,0 , 510,4 , 525,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Macau
+ { 25, 5, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 27,8 , 399,13 , 188,7 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {83,71,68}, 12,1 , 2509,11 , 4,4 , 4,0 , 510,4 , 534,3 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Singapore
+ { 25, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 195,13 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {72,75,68}, 12,1 , 2490,9 , 4,4 , 8,6 , 537,4 , 541,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/HongKong
+ { 25, 6, 126, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 412,7 , 419,15 , 172,6 , 195,13 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {77,79,80}, 144,4 , 2520,10 , 4,4 , 4,0 , 537,4 , 555,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Macau
+ { 25, 6, 208, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 179,8 , 399,13 , 172,6 , 208,11 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {84,87,68}, 148,3 , 2530,10 , 4,4 , 4,0 , 537,4 , 569,2 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Taiwan
+ { 27, 7, 54, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 434,9 , 443,19 , 37,5 , 8,10 , 4467,49 , 4516,94 , 4610,39 , 4467,49 , 4649,98 , 4610,39 , 2032,28 , 2060,58 , 2118,14 , 2032,28 , 2060,58 , 2132,14 , 0,2 , 0,2 , {72,82,75}, 151,2 , 2540,74 , 25,5 , 4,0 , 571,8 , 579,8 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Croatia
+ { 27, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 434,9 , 443,19 , 37,5 , 8,10 , 4467,49 , 4516,94 , 4610,39 , 4467,49 , 4649,98 , 4610,39 , 2032,28 , 2060,58 , 2118,14 , 2032,28 , 2060,58 , 2132,14 , 0,2 , 0,2 , {66,65,77}, 153,2 , 2614,106 , 25,5 , 4,0 , 571,8 , 587,19 , 2, 1, 1, 6, 7 }, // Croatian/Latin/BosniaAndHerzegowina
+ { 28, 7, 57, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 135,7 , 135,7 , 187,8 , 462,18 , 61,4 , 219,9 , 4747,48 , 4795,82 , 4877,24 , 4747,48 , 4901,84 , 158,27 , 2146,21 , 2167,49 , 2216,14 , 2146,21 , 2167,49 , 2216,14 , 81,4 , 80,4 , {67,90,75}, 155,2 , 2720,56 , 25,5 , 4,0 , 606,7 , 613,15 , 2, 1, 1, 6, 7 }, // Czech/Latin/CzechRepublic
+ { 29, 7, 58, 44, 46, 44, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 27,8 , 480,23 , 144,5 , 149,10 , 4985,48 , 5033,84 , 134,24 , 5117,59 , 5033,84 , 134,24 , 2230,28 , 2258,51 , 2309,14 , 2323,35 , 2258,51 , 2309,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 2776,42 , 25,5 , 4,0 , 628,5 , 633,7 , 2, 1, 1, 6, 7 }, // Danish/Latin/Denmark
+ { 30, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 14,5 , 19,6 , 640,10 , 650,9 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Netherlands
+ { 30, 7, 12, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,87,71}, 159,4 , 2837,55 , 14,5 , 19,6 , 640,10 , 659,5 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Aruba
+ { 30, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 511,7 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 25,5 , 4,0 , 664,6 , 670,6 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Belgium
+ { 30, 7, 152, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,78,71}, 163,4 , 2892,97 , 14,5 , 19,6 , 640,10 , 676,7 , 2, 1, 1, 6, 7 }, // Dutch/Latin/CuraSao
+ { 30, 7, 202, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {83,82,68}, 12,1 , 2989,24 , 14,5 , 19,6 , 640,10 , 683,8 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Suriname
+ { 30, 7, 256, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,78,71}, 163,4 , 2892,97 , 14,5 , 19,6 , 640,10 , 691,12 , 2, 1, 1, 6, 7 }, // Dutch/Latin/SintMaarten
+ { 31, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 703,12 , 715,13 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStates
+ { 31, 3, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 5371,80 , 5451,154 , 5605,36 , 5371,80 , 5451,154 , 5605,36 , 2452,49 , 2501,85 , 2586,21 , 2452,49 , 2501,85 , 2586,21 , 85,4 , 84,4 , {85,83,68}, 12,1 , 0,7 , 14,5 , 4,0 , 728,10 , 738,25 , 2, 1, 7, 6, 7 }, // English/Deseret/UnitedStates
+ { 31, 7, 4, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 770,14 , 2, 1, 7, 6, 7 }, // English/Latin/AmericanSamoa
+ { 31, 7, 9, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 784,19 , 2, 1, 7, 6, 7 }, // English/Latin/AntiguaAndBarbuda
+ { 31, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 511,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {65,85,68}, 12,1 , 3119,59 , 4,4 , 4,0 , 803,18 , 821,9 , 2, 1, 7, 6, 7 }, // English/Latin/Australia
+ { 31, 7, 16, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,83,68}, 12,1 , 3178,53 , 4,4 , 8,6 , 763,7 , 830,7 , 2, 1, 7, 6, 7 }, // English/Latin/Bahamas
+ { 31, 7, 19, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,66,68}, 12,1 , 3231,56 , 4,4 , 8,6 , 763,7 , 837,8 , 2, 1, 1, 6, 7 }, // English/Latin/Barbados
+ { 31, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 37,5 , 228,24 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {69,85,82}, 19,1 , 2818,19 , 25,5 , 4,0 , 763,7 , 845,7 , 2, 1, 1, 6, 7 }, // English/Latin/Belgium
+ { 31, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 27,8 , 524,12 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,90,68}, 12,1 , 3287,47 , 4,4 , 4,0 , 763,7 , 852,6 , 2, 1, 7, 6, 7 }, // English/Latin/Belize
+ { 31, 7, 24, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,77,68}, 12,1 , 3334,53 , 4,4 , 8,6 , 763,7 , 858,7 , 2, 1, 1, 6, 7 }, // English/Latin/Bermuda
+ { 31, 7, 28, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 27,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,87,80}, 170,1 , 3387,50 , 4,4 , 4,0 , 763,7 , 865,8 , 2, 1, 7, 6, 7 }, // English/Latin/Botswana
+ { 31, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 3437,50 , 4,4 , 8,6 , 763,7 , 873,8 , 0, 0, 1, 6, 7 }, // English/Latin/Cameroon
+ { 31, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 3487,53 , 4,4 , 8,6 , 881,16 , 897,6 , 2, 0, 7, 6, 7 }, // English/Latin/Canada
+ { 31, 7, 40, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,89,68}, 12,1 , 3540,71 , 4,4 , 8,6 , 763,7 , 903,14 , 2, 1, 1, 6, 7 }, // English/Latin/CaymanIslands
+ { 31, 7, 60, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 917,8 , 2, 1, 7, 6, 7 }, // English/Latin/Dominica
+ { 31, 7, 72, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {70,74,68}, 12,1 , 3611,47 , 4,4 , 8,6 , 763,7 , 925,4 , 2, 1, 1, 6, 7 }, // English/Latin/Fiji
+ { 31, 7, 75, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 763,7 , 929,8 , 2, 1, 1, 6, 7 }, // English/Latin/Guernsey
+ { 31, 7, 80, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,77,68}, 172,1 , 3705,50 , 4,4 , 8,6 , 763,7 , 937,6 , 2, 1, 1, 6, 7 }, // English/Latin/Gambia
+ { 31, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,72,83}, 173,3 , 3755,47 , 4,4 , 8,6 , 763,7 , 943,5 , 2, 1, 1, 6, 7 }, // English/Latin/Ghana
+ { 31, 7, 84, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,73,80}, 171,1 , 3802,53 , 4,4 , 4,0 , 763,7 , 948,9 , 2, 1, 1, 6, 7 }, // English/Latin/Gibraltar
+ { 31, 7, 87, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 957,7 , 2, 1, 1, 6, 7 }, // English/Latin/Grenada
+ { 31, 7, 89, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 964,4 , 2, 1, 7, 6, 7 }, // English/Latin/Guam
+ { 31, 7, 93, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,89,68}, 12,1 , 3855,56 , 4,4 , 8,6 , 763,7 , 968,6 , 0, 0, 1, 6, 7 }, // English/Latin/Guyana
+ { 31, 7, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 287,6 , 224,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {72,75,68}, 12,1 , 3911,56 , 4,4 , 8,6 , 763,7 , 974,19 , 2, 1, 7, 6, 7 }, // English/Latin/HongKong
+ { 31, 7, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {73,78,82}, 123,1 , 3967,44 , 14,5 , 4,0 , 763,7 , 993,5 , 2, 1, 7, 7, 7 }, // English/Latin/India
+ { 31, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 99,16 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2818,19 , 4,4 , 4,0 , 763,7 , 998,7 , 2, 1, 7, 6, 7 }, // English/Latin/Ireland
+ { 31, 7, 107, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 287,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {74,77,68}, 12,1 , 4011,53 , 4,4 , 4,0 , 763,7 , 1005,7 , 2, 1, 7, 6, 7 }, // English/Latin/Jamaica
+ { 31, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,69,83}, 2,3 , 4064,53 , 4,4 , 8,6 , 763,7 , 1012,5 , 2, 1, 7, 6, 7 }, // English/Latin/Kenya
+ { 31, 7, 112, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,85,68}, 12,1 , 3119,59 , 4,4 , 8,6 , 763,7 , 1017,8 , 2, 1, 1, 6, 7 }, // English/Latin/Kiribati
+ { 31, 7, 120, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4117,61 , 4,4 , 8,6 , 763,7 , 1025,7 , 2, 1, 1, 6, 7 }, // English/Latin/Lesotho
+ { 31, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 4178,53 , 4,4 , 8,6 , 763,7 , 1032,7 , 2, 1, 1, 6, 7 }, // English/Latin/Liberia
+ { 31, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 4231,54 , 4,4 , 8,6 , 763,7 , 1039,10 , 0, 0, 1, 6, 7 }, // English/Latin/Madagascar
+ { 31, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,87,75}, 178,2 , 4285,53 , 4,4 , 8,6 , 763,7 , 1049,6 , 2, 1, 1, 6, 7 }, // English/Latin/Malawi
+ { 31, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {69,85,82}, 19,1 , 2818,19 , 4,4 , 4,0 , 763,7 , 1055,5 , 2, 1, 7, 6, 7 }, // English/Latin/Malta
+ { 31, 7, 134, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1060,16 , 2, 1, 7, 6, 7 }, // English/Latin/MarshallIslands
+ { 31, 7, 137, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 4338,53 , 4,4 , 8,6 , 763,7 , 1076,9 , 0, 0, 1, 6, 7 }, // English/Latin/Mauritius
+ { 31, 7, 140, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1085,10 , 2, 1, 1, 6, 7 }, // English/Latin/Micronesia
+ { 31, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,65,68}, 12,1 , 4391,53 , 4,4 , 4,0 , 763,7 , 1095,7 , 2, 1, 1, 6, 7 }, // English/Latin/Namibia
+ { 31, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 511,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {78,90,68}, 12,1 , 4444,62 , 4,4 , 4,0 , 763,7 , 1102,11 , 2, 1, 7, 6, 7 }, // English/Latin/NewZealand
+ { 31, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,71,78}, 182,1 , 4506,50 , 4,4 , 8,6 , 763,7 , 1113,7 , 2, 1, 1, 6, 7 }, // English/Latin/Nigeria
+ { 31, 7, 160, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1120,24 , 2, 1, 1, 6, 7 }, // English/Latin/NorthernMarianaIslands
+ { 31, 7, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {80,75,82}, 180,2 , 4556,53 , 14,5 , 4,0 , 763,7 , 1144,8 , 0, 0, 7, 6, 7 }, // English/Latin/Pakistan
+ { 31, 7, 164, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1152,5 , 2, 1, 1, 6, 7 }, // English/Latin/Palau
+ { 31, 7, 167, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,71,75}, 139,1 , 4609,73 , 4,4 , 8,6 , 763,7 , 1157,16 , 2, 1, 1, 6, 7 }, // English/Latin/PapuaNewGuinea
+ { 31, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,72,80}, 183,1 , 4682,42 , 4,4 , 8,6 , 763,7 , 1173,11 , 2, 1, 7, 6, 7 }, // English/Latin/Philippines
+ { 31, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1184,11 , 2, 1, 7, 6, 7 }, // English/Latin/PuertoRico
+ { 31, 7, 180, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 1195,21 , 2, 1, 1, 6, 7 }, // English/Latin/SaintKittsAndNevis
+ { 31, 7, 181, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 1216,11 , 2, 1, 1, 6, 7 }, // English/Latin/SaintLucia
+ { 31, 7, 182, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 1227,32 , 2, 1, 1, 6, 7 }, // English/Latin/SaintVincentAndTheGrenadines
+ { 31, 7, 183, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {87,83,84}, 184,3 , 4724,40 , 4,4 , 8,6 , 763,7 , 1259,5 , 2, 1, 7, 6, 7 }, // English/Latin/Samoa
+ { 31, 7, 188, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,67,82}, 187,2 , 4764,59 , 4,4 , 8,6 , 763,7 , 1264,10 , 2, 1, 1, 6, 7 }, // English/Latin/Seychelles
+ { 31, 7, 189, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,76,76}, 189,2 , 4823,68 , 4,4 , 8,6 , 763,7 , 1274,12 , 0, 0, 1, 6, 7 }, // English/Latin/SierraLeone
+ { 31, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 287,6 , 224,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {83,71,68}, 12,1 , 4891,56 , 4,4 , 8,6 , 763,7 , 1286,9 , 2, 1, 7, 6, 7 }, // English/Latin/Singapore
+ { 31, 7, 193, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,66,68}, 12,1 , 4947,74 , 4,4 , 8,6 , 763,7 , 1295,15 , 2, 1, 1, 6, 7 }, // English/Latin/SolomonIslands
+ { 31, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 536,10 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4117,61 , 4,4 , 8,6 , 763,7 , 1310,12 , 2, 1, 7, 6, 7 }, // English/Latin/SouthAfrica
+ { 31, 7, 204, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,90,76}, 191,1 , 5021,53 , 4,4 , 8,6 , 763,7 , 1322,9 , 2, 1, 1, 6, 7 }, // English/Latin/Swaziland
+ { 31, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,90,83}, 192,3 , 5074,62 , 4,4 , 8,6 , 763,7 , 1331,8 , 0, 0, 1, 6, 7 }, // English/Latin/Tanzania
+ { 31, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,79,80}, 195,2 , 5136,49 , 4,4 , 8,6 , 763,7 , 1339,5 , 2, 1, 1, 6, 7 }, // English/Latin/Tonga
+ { 31, 7, 215, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,84,68}, 12,1 , 5185,86 , 4,4 , 4,0 , 763,7 , 1344,19 , 2, 1, 7, 6, 7 }, // English/Latin/TrinidadAndTobago
+ { 31, 7, 219, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1363,24 , 2, 1, 1, 6, 7 }, // English/Latin/TurksAndCaicosIslands
+ { 31, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 5271,56 , 4,4 , 8,6 , 763,7 , 1387,6 , 0, 0, 1, 6, 7 }, // English/Latin/Uganda
+ { 31, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 1393,15 , 1408,14 , 2, 1, 1, 6, 7 }, // English/Latin/UnitedKingdom
+ { 31, 7, 226, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1422,21 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesMinorOutlyingIslands
+ { 31, 7, 229, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {86,85,86}, 200,2 , 5327,44 , 4,4 , 8,6 , 763,7 , 1443,7 , 0, 0, 1, 6, 7 }, // English/Latin/Vanuatu
+ { 31, 7, 233, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1450,22 , 2, 1, 1, 6, 7 }, // English/Latin/BritishVirginIslands
+ { 31, 7, 234, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1472,19 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesVirginIslands
+ { 31, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,77,87}, 202,2 , 5371,50 , 4,4 , 8,6 , 763,7 , 1491,6 , 2, 1, 1, 6, 7 }, // English/Latin/Zambia
+ { 31, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 364,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 3013,35 , 4,4 , 4,0 , 763,7 , 1497,8 , 2, 1, 7, 6, 7 }, // English/Latin/Zimbabwe
+ { 31, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 763,7 , 1505,11 , 2, 1, 1, 6, 7 }, // English/Latin/IsleOfMan
+ { 31, 7, 252, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 763,7 , 1516,6 , 2, 1, 1, 6, 7 }, // English/Latin/Jersey
+ { 31, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,83,80}, 171,1 , 5421,68 , 4,4 , 8,6 , 763,7 , 1522,11 , 2, 1, 1, 6, 7 }, // English/Latin/SouthSudan
+ { 33, 7, 68, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 169,8 , 169,8 , 187,8 , 462,18 , 61,4 , 252,9 , 5641,59 , 5700,91 , 5791,24 , 5641,59 , 5700,91 , 5791,24 , 2607,14 , 2621,63 , 2607,14 , 2607,14 , 2621,63 , 2607,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 5489,20 , 25,5 , 30,7 , 1533,5 , 1538,5 , 2, 1, 1, 6, 7 }, // Estonian/Latin/Estonia
+ { 34, 7, 71, 44, 46, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 503,8 , 82,17 , 37,5 , 8,10 , 5815,48 , 5863,83 , 134,24 , 5815,48 , 5863,83 , 134,24 , 2684,28 , 2712,74 , 2786,14 , 2684,28 , 2712,74 , 2786,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 5509,42 , 4,4 , 43,5 , 1543,8 , 1551,7 , 2, 1, 1, 6, 7 }, // Faroese/Latin/FaroeIslands
+ { 36, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 546,8 , 554,17 , 159,4 , 163,9 , 5946,69 , 6015,105 , 6120,24 , 6144,129 , 6144,129 , 6120,24 , 2800,21 , 2821,67 , 2888,14 , 2800,21 , 2902,81 , 2888,14 , 91,3 , 90,3 , {69,85,82}, 19,1 , 5551,20 , 25,5 , 4,0 , 1558,5 , 1563,5 , 2, 1, 1, 6, 7 }, // Finnish/Latin/Finland
+ { 37, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1576,6 , 2, 1, 1, 6, 7 }, // French/Latin/France
+ { 37, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {68,90,68}, 207,2 , 5571,51 , 25,5 , 30,7 , 1568,8 , 1582,7 , 2, 1, 6, 4, 5 }, // French/Latin/Algeria
+ { 37, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 511,7 , 99,16 , 37,5 , 261,23 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1589,8 , 2, 1, 1, 6, 7 }, // French/Latin/Belgium
+ { 37, 7, 23, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1597,5 , 0, 0, 1, 6, 7 }, // French/Latin/Benin
+ { 37, 7, 34, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1602,12 , 0, 0, 1, 6, 7 }, // French/Latin/BurkinaFaso
+ { 37, 7, 35, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {66,73,70}, 212,3 , 5681,53 , 25,5 , 30,7 , 1568,8 , 1614,7 , 0, 0, 1, 6, 7 }, // French/Latin/Burundi
+ { 37, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1621,8 , 0, 0, 1, 6, 7 }, // French/Latin/Cameroon
+ { 37, 7, 38, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 177,8 , 177,8 , 115,8 , 99,16 , 37,5 , 228,24 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 5790,54 , 25,5 , 30,7 , 1629,17 , 897,6 , 2, 0, 7, 6, 7 }, // French/Latin/Canada
+ { 37, 7, 41, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1646,25 , 0, 0, 1, 6, 7 }, // French/Latin/CentralAfricanRepublic
+ { 37, 7, 42, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1671,5 , 0, 0, 1, 6, 7 }, // French/Latin/Chad
+ { 37, 7, 48, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {75,77,70}, 215,2 , 5844,51 , 25,5 , 30,7 , 1568,8 , 1676,7 , 0, 0, 1, 6, 7 }, // French/Latin/Comoros
+ { 37, 7, 49, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,68,70}, 217,2 , 5895,53 , 25,5 , 30,7 , 1568,8 , 1683,32 , 2, 1, 1, 6, 7 }, // French/Latin/CongoKinshasa
+ { 37, 7, 50, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1715,17 , 0, 0, 1, 6, 7 }, // French/Latin/CongoBrazzaville
+ { 37, 7, 53, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1732,13 , 0, 0, 1, 6, 7 }, // French/Latin/IvoryCoast
+ { 37, 7, 59, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {68,74,70}, 5,3 , 5948,57 , 25,5 , 30,7 , 1568,8 , 1745,8 , 0, 0, 6, 6, 7 }, // French/Latin/Djibouti
+ { 37, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1753,18 , 0, 0, 1, 6, 7 }, // French/Latin/EquatorialGuinea
+ { 37, 7, 76, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1771,16 , 2, 1, 1, 6, 7 }, // French/Latin/FrenchGuiana
+ { 37, 7, 77, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,80,70}, 219,4 , 6005,35 , 25,5 , 30,7 , 1568,8 , 1787,19 , 0, 0, 1, 6, 7 }, // French/Latin/FrenchPolynesia
+ { 37, 7, 79, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1806,5 , 0, 0, 1, 6, 7 }, // French/Latin/Gabon
+ { 37, 7, 88, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1811,10 , 2, 1, 1, 6, 7 }, // French/Latin/Guadeloupe
+ { 37, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {71,78,70}, 223,2 , 6040,48 , 25,5 , 30,7 , 1568,8 , 1821,6 , 0, 0, 1, 6, 7 }, // French/Latin/Guinea
+ { 37, 7, 94, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {72,84,71}, 225,1 , 6088,57 , 25,5 , 30,7 , 1568,8 , 1827,5 , 2, 1, 1, 6, 7 }, // French/Latin/Haiti
+ { 37, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1832,10 , 2, 1, 1, 6, 7 }, // French/Latin/Luxembourg
+ { 37, 7, 128, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 6145,54 , 25,5 , 30,7 , 1568,8 , 1039,10 , 0, 0, 1, 6, 7 }, // French/Latin/Madagascar
+ { 37, 7, 132, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1842,4 , 0, 0, 1, 6, 7 }, // French/Latin/Mali
+ { 37, 7, 135, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1846,10 , 2, 1, 1, 6, 7 }, // French/Latin/Martinique
+ { 37, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,82,79}, 226,2 , 6199,66 , 25,5 , 30,7 , 1568,8 , 1856,10 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritania
+ { 37, 7, 137, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 6265,63 , 25,5 , 30,7 , 1568,8 , 1866,7 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritius
+ { 37, 7, 138, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1873,7 , 2, 1, 1, 6, 7 }, // French/Latin/Mayotte
+ { 37, 7, 142, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1880,6 , 2, 1, 1, 6, 7 }, // French/Latin/Monaco
+ { 37, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,65,68}, 0,0 , 6328,54 , 25,5 , 30,7 , 1568,8 , 1886,5 , 2, 1, 6, 5, 6 }, // French/Latin/Morocco
+ { 37, 7, 153, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,80,70}, 219,4 , 6005,35 , 25,5 , 30,7 , 1568,8 , 1891,18 , 0, 0, 1, 6, 7 }, // French/Latin/NewCaledonia
+ { 37, 7, 156, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1909,5 , 0, 0, 1, 6, 7 }, // French/Latin/Niger
+ { 37, 7, 176, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1914,7 , 2, 1, 1, 6, 7 }, // French/Latin/Reunion
+ { 37, 7, 179, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {82,87,70}, 228,2 , 6382,50 , 25,5 , 30,7 , 1568,8 , 1921,6 , 0, 0, 1, 6, 7 }, // French/Latin/Rwanda
+ { 37, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1927,7 , 0, 0, 1, 6, 7 }, // French/Latin/Senegal
+ { 37, 7, 188, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {83,67,82}, 187,2 , 6432,71 , 25,5 , 30,7 , 1568,8 , 1264,10 , 2, 1, 1, 6, 7 }, // French/Latin/Seychelles
+ { 37, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 177,8 , 177,8 , 187,8 , 10,17 , 37,5 , 284,14 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,72,70}, 230,3 , 6503,45 , 14,5 , 48,5 , 1934,15 , 1949,6 , 2, 0, 1, 6, 7 }, // French/Latin/Switzerland
+ { 37, 7, 207, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {83,89,80}, 233,2 , 6548,51 , 25,5 , 30,7 , 1568,8 , 1955,5 , 0, 0, 6, 5, 6 }, // French/Latin/Syria
+ { 37, 7, 212, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1960,4 , 0, 0, 1, 6, 7 }, // French/Latin/Togo
+ { 37, 7, 216, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {84,78,68}, 235,2 , 6599,51 , 25,5 , 30,7 , 1568,8 , 1964,7 , 3, 0, 7, 5, 6 }, // French/Latin/Tunisia
+ { 37, 7, 229, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {86,85,86}, 200,2 , 6650,51 , 25,5 , 30,7 , 1568,8 , 1443,7 , 0, 0, 1, 6, 7 }, // French/Latin/Vanuatu
+ { 37, 7, 244, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1971,16 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Barthelemy
+ { 37, 7, 245, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1987,31 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Martin
+ { 39, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 185,11 , 196,10 , 141,10 , 10,17 , 37,5 , 8,10 , 6421,61 , 6482,142 , 6624,36 , 6421,61 , 6482,142 , 6624,36 , 3084,28 , 3112,69 , 3181,14 , 3084,28 , 3112,69 , 3181,14 , 0,2 , 0,2 , {71,66,80}, 171,1 , 6701,22 , 4,4 , 8,6 , 2018,8 , 2026,22 , 2, 1, 1, 6, 7 }, // Gaelic/Latin/UnitedKingdom
+ { 40, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 82,17 , 37,5 , 8,10 , 6660,48 , 6708,87 , 6795,24 , 6660,48 , 6708,87 , 6795,24 , 3195,28 , 3223,49 , 3272,14 , 3195,28 , 3223,49 , 3272,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 6723,20 , 4,4 , 8,6 , 2048,6 , 2054,6 , 2, 1, 1, 6, 7 }, // Galician/Latin/Spain
+ { 41, 15, 81, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 213,8 , 213,8 , 187,8 , 571,19 , 37,5 , 8,10 , 6819,48 , 6867,99 , 6966,24 , 6819,48 , 6867,99 , 6966,24 , 3286,28 , 3314,62 , 3376,14 , 3286,28 , 3314,62 , 3376,14 , 0,2 , 0,2 , {71,69,76}, 0,0 , 6743,19 , 25,5 , 4,0 , 2060,7 , 2067,10 , 2, 1, 1, 6, 7 }, // Georgian/Georgian/Georgia
+ { 42, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 25,5 , 4,0 , 2077,7 , 2084,11 , 2, 1, 1, 6, 7 }, // German/Latin/Germany
+ { 42, 7, 14, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 590,19 , 37,5 , 8,10 , 7180,48 , 7038,83 , 134,24 , 7228,58 , 7286,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 14,5 , 4,0 , 2095,24 , 2119,10 , 2, 1, 1, 6, 7 }, // German/Latin/Austria
+ { 42, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 25,5 , 4,0 , 2077,7 , 2129,7 , 2, 1, 1, 6, 7 }, // German/Latin/Belgium
+ { 42, 7, 123, 46, 39, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {67,72,70}, 0,0 , 6781,58 , 14,5 , 4,0 , 2077,7 , 2136,13 , 2, 0, 1, 6, 7 }, // German/Latin/Liechtenstein
+ { 42, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 25,5 , 4,0 , 2077,7 , 2149,9 , 2, 1, 1, 6, 7 }, // German/Latin/Luxembourg
+ { 42, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {67,72,70}, 230,3 , 6781,58 , 14,5 , 48,5 , 2158,21 , 2179,7 , 2, 0, 1, 6, 7 }, // German/Latin/Switzerland
+ { 43, 16, 85, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 230,9 , 230,9 , 287,6 , 10,17 , 18,7 , 25,12 , 7369,50 , 7419,115 , 7534,24 , 7558,50 , 7608,115 , 7534,24 , 3513,28 , 3541,55 , 3596,14 , 3513,28 , 3541,55 , 3596,14 , 99,4 , 99,4 , {69,85,82}, 19,1 , 6839,19 , 25,5 , 4,0 , 2186,8 , 2194,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Greece
+ { 43, 16, 56, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 230,9 , 230,9 , 287,6 , 10,17 , 18,7 , 25,12 , 7369,50 , 7419,115 , 7534,24 , 7558,50 , 7608,115 , 7534,24 , 3513,28 , 3541,55 , 3596,14 , 3513,28 , 3541,55 , 3596,14 , 99,4 , 99,4 , {69,85,82}, 19,1 , 6839,19 , 4,4 , 4,0 , 2186,8 , 2200,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Cyprus
+ { 44, 7, 86, 44, 46, 59, 37, 48, 8722, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 239,11 , 239,11 , 72,10 , 82,17 , 18,7 , 25,12 , 4985,48 , 7723,96 , 134,24 , 4985,48 , 7723,96 , 134,24 , 3610,28 , 3638,98 , 3736,14 , 3610,28 , 3638,98 , 3736,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 6858,59 , 4,4 , 43,5 , 2206,11 , 2217,16 , 2, 1, 1, 6, 7 }, // Greenlandic/Latin/Greenland
+ { 46, 17, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 250,9 , 250,9 , 609,7 , 224,18 , 298,8 , 306,13 , 7819,64 , 7883,87 , 7970,31 , 8001,67 , 8068,87 , 7970,31 , 3750,32 , 3782,53 , 3835,19 , 3750,32 , 3782,53 , 3835,19 , 0,2 , 0,2 , {73,78,82}, 123,1 , 6917,20 , 4,4 , 8,6 , 2233,7 , 2240,4 , 2, 1, 7, 7, 7 }, // Gujarati/Gujarati/India
+ { 47, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {78,71,78}, 182,1 , 6937,12 , 14,5 , 4,0 , 2244,5 , 2249,8 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Nigeria
+ { 47, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {71,72,83}, 173,3 , 0,7 , 14,5 , 4,0 , 2244,5 , 2257,4 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Ghana
+ { 47, 7, 156, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 6949,36 , 14,5 , 4,0 , 2244,5 , 2261,5 , 0, 0, 1, 6, 7 }, // Hausa/Latin/Niger
+ { 48, 18, 105, 46, 44, 59, 37, 48, 45, 43, 101, 34, 34, 39, 39, 0,6 , 0,6 , 259,6 , 259,6 , 27,8 , 616,18 , 37,5 , 8,10 , 8312,58 , 8370,72 , 158,27 , 8442,48 , 8370,72 , 158,27 , 3941,46 , 3987,65 , 4052,19 , 3941,46 , 3987,65 , 4071,21 , 103,6 , 103,5 , {73,76,83}, 53,1 , 6985,54 , 25,5 , 4,0 , 2266,5 , 2271,5 , 2, 1, 7, 5, 6 }, // Hebrew/Hebrew/Israel
+ { 49, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 265,9 , 274,8 , 634,6 , 10,17 , 18,7 , 25,12 , 8490,75 , 8490,75 , 8565,30 , 8490,75 , 8490,75 , 8565,30 , 4092,38 , 4130,57 , 4187,19 , 4092,38 , 4130,57 , 4187,19 , 109,9 , 108,7 , {73,78,82}, 123,1 , 7039,19 , 14,5 , 4,0 , 2276,6 , 2282,4 , 2, 1, 7, 7, 7 }, // Hindi/Devanagari/India
+ { 50, 7, 98, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 187, 171, 0,6 , 0,6 , 282,8 , 282,8 , 640,11 , 651,19 , 61,4 , 219,9 , 8595,64 , 8659,98 , 8757,25 , 8595,64 , 8659,98 , 8782,25 , 4206,19 , 4225,52 , 4277,17 , 4206,19 , 4225,52 , 4277,17 , 118,3 , 115,3 , {72,85,70}, 237,2 , 7058,20 , 25,5 , 4,0 , 2286,6 , 2292,12 , 0, 0, 1, 6, 7 }, // Hungarian/Latin/Hungary
+ { 51, 7, 99, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 142,8 , 142,8 , 546,8 , 462,18 , 37,5 , 8,10 , 8807,48 , 8855,82 , 8937,24 , 8807,48 , 8855,82 , 8961,24 , 4294,28 , 4322,81 , 4403,14 , 4294,28 , 4322,81 , 4417,14 , 121,4 , 118,4 , {73,83,75}, 157,2 , 7078,49 , 4,4 , 8,6 , 2304,8 , 2312,6 , 0, 0, 1, 6, 7 }, // Icelandic/Latin/Iceland
+ { 52, 7, 101, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 27,8 , 123,18 , 144,5 , 149,10 , 8985,48 , 9033,87 , 134,24 , 8985,48 , 9033,87 , 134,24 , 4431,28 , 4459,43 , 4502,14 , 4431,28 , 4459,43 , 4502,14 , 0,2 , 0,2 , {73,68,82}, 239,2 , 7127,23 , 4,4 , 4,0 , 2318,16 , 2334,9 , 0, 0, 7, 6, 7 }, // Indonesian/Latin/Indonesia
+ { 53, 7, 74, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 9120,48 , 9168,93 , 158,27 , 9120,48 , 9168,93 , 158,27 , 4516,28 , 4544,57 , 85,14 , 4516,28 , 4544,57 , 85,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 7150,12 , 14,5 , 4,0 , 2343,11 , 2354,7 , 2, 1, 1, 6, 7 }, // Interlingua/Latin/France
+ { 57, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 99,16 , 37,5 , 8,10 , 9261,62 , 9323,107 , 9430,24 , 9261,62 , 9323,107 , 9430,24 , 4601,37 , 4638,75 , 4713,14 , 4601,37 , 4638,75 , 4713,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 81,11 , 4,4 , 4,0 , 2361,7 , 2368,4 , 2, 1, 7, 6, 7 }, // Irish/Latin/Ireland
+ { 58, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 309,8 , 206,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 14,5 , 4,0 , 2372,8 , 2380,6 , 2, 1, 1, 6, 7 }, // Italian/Latin/Italy
+ { 58, 7, 184, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 309,8 , 206,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 14,5 , 4,0 , 2372,8 , 2386,10 , 2, 1, 1, 6, 7 }, // Italian/Latin/SanMarino
+ { 58, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 309,8 , 206,7 , 187,8 , 10,17 , 37,5 , 284,14 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {67,72,70}, 230,3 , 7162,53 , 14,5 , 48,5 , 2372,8 , 2396,8 , 2, 0, 1, 6, 7 }, // Italian/Latin/Switzerland
+ { 59, 19, 108, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 125,5 , 125,5 , 536,10 , 399,13 , 61,4 , 319,10 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 4883,14 , 4897,28 , 4883,14 , 4883,14 , 4897,28 , 4883,14 , 125,2 , 122,2 , {74,80,89}, 143,1 , 7215,10 , 4,4 , 4,0 , 2404,3 , 2407,2 , 0, 0, 7, 6, 7 }, // Japanese/Japanese/Japan
+ { 61, 21, 100, 46, 44, 59, 37, 48, 45, 43, 3208, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 317,12 , 329,11 , 634,6 , 99,16 , 298,8 , 306,13 , 9714,91 , 9805,86 , 9891,31 , 9714,91 , 9805,86 , 9922,31 , 4925,28 , 4953,53 , 5006,19 , 4925,28 , 4953,53 , 5006,19 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7225,20 , 4,4 , 8,6 , 2409,5 , 2414,4 , 2, 1, 7, 7, 7 }, // Kannada/Kannada/India
+ { 62, 1, 100, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 9953,72 , 9953,72 , 10025,24 , 9953,72 , 9953,72 , 10025,24 , 5025,54 , 5079,56 , 5135,14 , 5025,54 , 5079,56 , 5135,14 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7245,23 , 14,5 , 4,0 , 2418,5 , 2423,10 , 2, 1, 7, 7, 7 }, // Kashmiri/Arabic/India
+ { 63, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 187,8 , 670,22 , 37,5 , 8,10 , 10049,61 , 10110,83 , 158,27 , 10049,61 , 10110,83 , 158,27 , 5149,28 , 5177,54 , 85,14 , 5149,28 , 5177,54 , 85,14 , 0,2 , 0,2 , {75,90,84}, 241,1 , 7268,24 , 25,5 , 4,0 , 2433,10 , 2443,9 , 2, 1, 1, 6, 7 }, // Kazakh/Cyrillic/Kazakhstan
+ { 64, 7, 179, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 10193,60 , 10253,101 , 158,27 , 10193,60 , 10253,101 , 158,27 , 5231,35 , 5266,84 , 85,14 , 5231,35 , 5266,84 , 85,14 , 0,2 , 0,2 , {82,87,70}, 228,2 , 0,7 , 14,5 , 4,0 , 2452,11 , 1921,6 , 0, 0, 1, 6, 7 }, // Kinyarwanda/Latin/Rwanda
+ { 65, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 187,8 , 670,22 , 37,5 , 8,10 , 10354,60 , 10414,80 , 158,27 , 10494,59 , 10553,80 , 158,27 , 5350,28 , 5378,57 , 85,14 , 5435,28 , 5463,57 , 85,14 , 0,2 , 0,2 , {75,71,83}, 242,3 , 0,7 , 14,5 , 4,0 , 2463,6 , 2469,10 , 2, 1, 1, 6, 7 }, // Kirghiz/Cyrillic/Kyrgyzstan
+ { 66, 22, 114, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 340,7 , 340,7 , 692,9 , 701,16 , 329,7 , 336,13 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 5520,14 , 5534,28 , 5520,14 , 5520,14 , 5534,28 , 5520,14 , 127,2 , 124,2 , {75,82,87}, 245,1 , 7292,13 , 4,4 , 8,6 , 2479,3 , 2482,4 , 0, 0, 7, 6, 7 }, // Korean/Korean/SouthKorea
+ { 66, 22, 113, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 340,7 , 340,7 , 692,9 , 701,16 , 329,7 , 336,13 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 5520,14 , 5534,28 , 5520,14 , 5520,14 , 5534,28 , 5520,14 , 127,2 , 124,2 , {75,80,87}, 0,0 , 7305,23 , 4,4 , 8,6 , 2479,3 , 2486,14 , 0, 0, 1, 6, 7 }, // Korean/Korean/NorthKorea
+ { 68, 7, 35, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 10672,60 , 10732,106 , 158,27 , 10672,60 , 10732,106 , 158,27 , 5562,34 , 5596,89 , 85,14 , 5562,34 , 5596,89 , 85,14 , 129,5 , 126,5 , {66,73,70}, 212,3 , 7328,27 , 0,4 , 4,0 , 2500,8 , 2508,8 , 0, 0, 1, 6, 7 }, // Rundi/Latin/Burundi
+ { 69, 23, 117, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 717,18 , 61,4 , 349,24 , 10838,62 , 10900,75 , 158,27 , 10975,61 , 10900,75 , 158,27 , 5685,23 , 5708,57 , 5765,18 , 5783,24 , 5708,57 , 1765,14 , 134,8 , 131,8 , {76,65,75}, 246,1 , 7355,14 , 4,4 , 48,5 , 2516,3 , 2519,9 , 0, 0, 7, 6, 7 }, // Lao/Lao/Laos
+ { 71, 7, 118, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 347,8 , 347,8 , 187,8 , 735,26 , 37,5 , 8,10 , 11036,65 , 11101,101 , 134,24 , 11202,65 , 11267,101 , 134,24 , 5807,21 , 5828,72 , 5900,14 , 5807,21 , 5914,72 , 5900,14 , 142,14 , 139,11 , {76,86,76}, 247,2 , 7369,59 , 4,4 , 8,6 , 2528,8 , 2536,7 , 2, 1, 1, 6, 7 }, // Latvian/Latin/Latvia
+ { 72, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {67,68,70}, 217,2 , 7428,23 , 25,5 , 4,0 , 2543,7 , 2550,29 , 2, 1, 1, 6, 7 }, // Lingala/Latin/CongoKinshasa
+ { 72, 7, 6, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {65,79,65}, 249,2 , 7451,23 , 25,5 , 4,0 , 2543,7 , 2579,6 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Angola
+ { 72, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {88,65,70}, 37,4 , 7474,23 , 25,5 , 4,0 , 2543,7 , 2585,26 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CentralAfricanRepublic
+ { 72, 7, 50, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {88,65,70}, 37,4 , 7474,23 , 25,5 , 4,0 , 2543,7 , 2611,5 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CongoBrazzaville
+ { 73, 7, 124, 44, 160, 59, 37, 48, 8211, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 364,8 , 364,8 , 72,10 , 761,27 , 37,5 , 8,10 , 11643,70 , 11713,96 , 11809,24 , 11643,70 , 11713,96 , 11809,24 , 6128,21 , 6149,89 , 6238,14 , 6128,21 , 6149,89 , 6238,14 , 164,9 , 156,6 , {76,84,76}, 251,2 , 7497,62 , 25,5 , 4,0 , 2616,8 , 2624,7 , 2, 1, 1, 6, 7 }, // Lithuanian/Latin/Lithuania
+ { 74, 2, 127, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 788,7 , 123,18 , 37,5 , 8,10 , 11833,63 , 11896,85 , 11981,24 , 11833,63 , 11896,85 , 11981,24 , 6252,34 , 6286,54 , 1521,14 , 6252,34 , 6286,54 , 1521,14 , 173,10 , 162,8 , {77,75,68}, 253,3 , 7559,23 , 14,5 , 4,0 , 2631,10 , 2641,10 , 2, 1, 1, 6, 7 }, // Macedonian/Cyrillic/Macedonia
+ { 75, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 12005,48 , 12053,92 , 134,24 , 12005,48 , 12053,92 , 134,24 , 6340,34 , 6374,60 , 6434,14 , 6340,34 , 6374,60 , 6434,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 7582,13 , 4,4 , 4,0 , 2651,8 , 2659,12 , 0, 0, 1, 6, 7 }, // Malagasy/Latin/Madagascar
+ { 76, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 10,17 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {77,89,82}, 256,2 , 7595,23 , 4,4 , 8,6 , 2671,13 , 2684,8 , 2, 1, 1, 6, 7 }, // Malay/Latin/Malaysia
+ { 76, 7, 32, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 524,12 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {66,78,68}, 12,1 , 7618,19 , 14,5 , 4,0 , 2671,13 , 2692,6 , 2, 1, 1, 6, 7 }, // Malay/Latin/Brunei
+ { 76, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 10,17 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {83,71,68}, 12,1 , 7637,22 , 4,4 , 8,6 , 2671,13 , 2698,9 , 2, 1, 7, 6, 7 }, // Malay/Latin/Singapore
+ { 77, 24, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 372,13 , 385,12 , 27,8 , 795,18 , 18,7 , 25,12 , 12300,62 , 12362,87 , 12449,31 , 12300,62 , 12362,87 , 12449,31 , 6533,41 , 6574,70 , 6644,22 , 6533,41 , 6574,70 , 6644,22 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7659,40 , 0,4 , 4,0 , 2707,6 , 2713,6 , 2, 1, 7, 7, 7 }, // Malayalam/Malayalam/India
+ { 78, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 397,8 , 405,7 , 141,10 , 813,23 , 37,5 , 8,10 , 12480,48 , 12528,86 , 12614,24 , 12480,48 , 12528,86 , 12614,24 , 6666,28 , 6694,63 , 6757,14 , 6666,28 , 6694,63 , 6757,14 , 185,2 , 173,2 , {69,85,82}, 19,1 , 7699,11 , 4,4 , 4,0 , 2719,5 , 1055,5 , 2, 1, 7, 6, 7 }, // Maltese/Latin/Malta
+ { 80, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 412,9 , 412,9 , 634,6 , 99,16 , 373,7 , 380,12 , 12638,66 , 12704,86 , 12790,32 , 12638,66 , 12704,86 , 12790,32 , 6771,32 , 6803,53 , 4187,19 , 6771,32 , 6803,53 , 4187,19 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7710,19 , 4,4 , 8,6 , 2724,5 , 2282,4 , 2, 1, 7, 7, 7 }, // Marathi/Devanagari/India
+ { 82, 2, 143, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 836,31 , 37,5 , 8,10 , 12822,48 , 12870,66 , 158,27 , 12822,48 , 12870,66 , 158,27 , 6856,21 , 6877,43 , 1765,14 , 6856,21 , 6877,43 , 1765,14 , 187,2 , 175,2 , {77,78,84}, 258,1 , 7729,25 , 14,5 , 4,0 , 2729,6 , 2735,6 , 0, 0, 1, 6, 7 }, // Mongolian/Cyrillic/Mongolia
+ { 84, 13, 150, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 12936,56 , 12992,85 , 13077,27 , 12936,56 , 12992,85 , 13077,27 , 6920,33 , 6953,54 , 7007,14 , 6920,33 , 6953,54 , 7007,14 , 189,14 , 177,14 , {78,80,82}, 259,4 , 7754,52 , 14,5 , 4,0 , 2741,6 , 2747,5 , 2, 1, 7, 6, 7 }, // Nepali/Devanagari/Nepal
+ { 84, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 12936,56 , 12992,85 , 13077,27 , 12936,56 , 13104,80 , 13077,27 , 6920,33 , 6953,54 , 7007,14 , 6920,33 , 7021,54 , 7007,14 , 109,9 , 108,7 , {73,78,82}, 123,1 , 7806,49 , 14,5 , 4,0 , 2741,6 , 2282,4 , 2, 1, 7, 7, 7 }, // Nepali/Devanagari/India
+ { 85, 7, 161, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 187,8 , 554,17 , 37,5 , 392,16 , 5815,48 , 13184,83 , 134,24 , 13267,59 , 13184,83 , 134,24 , 7075,28 , 2258,51 , 2309,14 , 2323,35 , 2258,51 , 2309,14 , 0,2 , 0,2 , {78,79,75}, 157,2 , 7855,44 , 14,5 , 4,0 , 2752,12 , 2764,5 , 2, 1, 1, 6, 7 }, // NorwegianBokmal/Latin/Norway
+ { 87, 26, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 634,6 , 10,17 , 18,7 , 25,12 , 13326,89 , 13326,89 , 13415,32 , 13326,89 , 13326,89 , 13415,32 , 7103,33 , 7136,54 , 7190,18 , 7103,33 , 7136,54 , 7190,18 , 89,2 , 88,2 , {73,78,82}, 123,1 , 7899,11 , 14,5 , 4,0 , 2769,5 , 2774,4 , 2, 1, 7, 7, 7 }, // Oriya/Oriya/India
+ { 88, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 179,8 , 867,20 , 61,4 , 408,11 , 13447,68 , 13447,68 , 158,27 , 13447,68 , 13447,68 , 158,27 , 7208,49 , 7208,49 , 85,14 , 7208,49 , 7208,49 , 85,14 , 203,4 , 191,4 , {65,70,78}, 263,1 , 7910,13 , 25,5 , 4,0 , 2778,4 , 2782,9 , 0, 0, 6, 4, 5 }, // Pashto/Arabic/Afghanistan
+ { 89, 1, 102, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 171, 187, 8249, 8250, 421,7 , 421,7 , 43,8 , 51,7 , 179,8 , 99,16 , 61,4 , 408,11 , 13515,70 , 13515,70 , 13585,24 , 13609,74 , 13609,74 , 13585,24 , 7208,49 , 7208,49 , 7257,14 , 7208,49 , 7208,49 , 7257,14 , 207,9 , 195,8 , {73,82,82}, 264,1 , 7923,17 , 53,5 , 58,7 , 2791,5 , 2796,5 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Iran
+ { 89, 1, 1, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 171, 187, 8249, 8250, 421,7 , 421,7 , 43,8 , 51,7 , 179,8 , 99,16 , 61,4 , 408,11 , 13515,70 , 13515,70 , 13683,24 , 13707,64 , 13771,68 , 13585,24 , 7208,49 , 7208,49 , 7257,14 , 7208,49 , 7208,49 , 7257,14 , 207,9 , 195,8 , {65,70,78}, 263,1 , 7940,23 , 53,5 , 58,7 , 2801,3 , 2782,9 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Afghanistan
+ { 90, 7, 172, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 887,10 , 10,17 , 37,5 , 8,10 , 13839,48 , 13887,97 , 13984,24 , 13839,48 , 14008,99 , 13984,24 , 7271,34 , 7305,59 , 7364,14 , 7271,34 , 7305,59 , 7364,14 , 0,2 , 0,2 , {80,76,78}, 265,2 , 7963,77 , 25,5 , 30,7 , 2804,6 , 2810,6 , 2, 1, 1, 6, 7 }, // Polish/Latin/Poland
+ { 91, 7, 30, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14107,48 , 14155,89 , 134,24 , 14107,48 , 14155,89 , 134,24 , 7378,28 , 7406,79 , 7485,14 , 7378,28 , 7406,79 , 7485,14 , 0,2 , 0,2 , {66,82,76}, 267,2 , 8040,54 , 4,4 , 8,6 , 2816,19 , 2835,6 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Brazil
+ { 91, 7, 6, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {65,79,65}, 249,2 , 8094,54 , 25,5 , 4,0 , 2841,9 , 2850,6 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Angola
+ { 91, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {67,86,69}, 0,0 , 8148,69 , 25,5 , 4,0 , 2841,9 , 2856,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/CapeVerde
+ { 91, 7, 62, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 8217,81 , 25,5 , 4,0 , 2841,9 , 2866,11 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/EastTimor
+ { 91, 7, 92, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 8298,62 , 25,5 , 4,0 , 2841,9 , 2877,12 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/GuineaBissau
+ { 91, 7, 126, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {77,79,80}, 144,4 , 8360,53 , 25,5 , 4,0 , 2841,9 , 2889,19 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Macau
+ { 91, 7, 146, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {77,90,78}, 269,3 , 8413,72 , 25,5 , 4,0 , 2841,9 , 2908,10 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Mozambique
+ { 91, 7, 173, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 8485,20 , 25,5 , 4,0 , 2918,17 , 2935,8 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Portugal
+ { 91, 7, 185, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {83,84,68}, 272,2 , 8505,92 , 25,5 , 4,0 , 2841,9 , 2943,19 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/SaoTomeAndPrincipe
+ { 92, 4, 100, 46, 44, 59, 37, 48, 45, 43, 101, 39, 39, 34, 34, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 123,18 , 18,7 , 25,12 , 14381,68 , 14381,68 , 14449,27 , 14381,68 , 14381,68 , 14449,27 , 7578,38 , 7616,55 , 7671,23 , 7578,38 , 7616,55 , 7671,23 , 216,11 , 203,11 , {73,78,82}, 123,1 , 8597,12 , 14,5 , 4,0 , 2962,6 , 2968,4 , 2, 1, 7, 7, 7 }, // Punjabi/Gurmukhi/India
+ { 92, 1, 163, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 123,18 , 18,7 , 25,12 , 14476,67 , 14476,67 , 158,27 , 14476,67 , 14476,67 , 158,27 , 7694,37 , 7694,37 , 85,14 , 7694,37 , 7694,37 , 85,14 , 0,2 , 0,2 , {80,75,82}, 274,1 , 8609,13 , 14,5 , 4,0 , 2972,5 , 2977,6 , 0, 0, 7, 6, 7 }, // Punjabi/Arabic/Pakistan
+ { 94, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 503,8 , 924,28 , 37,5 , 8,10 , 14543,67 , 14610,92 , 14702,24 , 14543,67 , 14610,92 , 14702,24 , 7731,23 , 7754,56 , 7810,14 , 7731,23 , 7754,56 , 7810,14 , 89,2 , 214,2 , {67,72,70}, 230,3 , 8622,20 , 25,5 , 4,0 , 2983,9 , 2992,6 , 2, 0, 1, 6, 7 }, // Romansh/Latin/Switzerland
+ { 95, 7, 177, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 428,8 , 428,8 , 887,10 , 10,17 , 37,5 , 8,10 , 14726,60 , 14786,98 , 14884,24 , 14726,60 , 14786,98 , 14884,24 , 7824,21 , 7845,48 , 3070,14 , 7824,21 , 7845,48 , 3070,14 , 0,2 , 0,2 , {82,79,78}, 0,0 , 8642,57 , 25,5 , 4,0 , 2998,6 , 3004,7 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Romania
+ { 95, 7, 141, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 428,8 , 428,8 , 887,10 , 10,17 , 37,5 , 8,10 , 14726,60 , 14786,98 , 14884,24 , 14726,60 , 14786,98 , 14884,24 , 7824,21 , 7845,48 , 3070,14 , 7824,21 , 7845,48 , 3070,14 , 0,2 , 0,2 , {77,68,76}, 0,0 , 8699,69 , 25,5 , 4,0 , 2998,6 , 3011,17 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Moldova
+ { 96, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {82,85,66}, 275,4 , 8768,89 , 25,5 , 4,0 , 3028,7 , 3035,6 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Russia
+ { 96, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {66,89,82}, 140,2 , 8857,94 , 25,5 , 4,0 , 3028,7 , 470,8 , 0, 0, 7, 6, 7 }, // Russian/Cyrillic/Belarus
+ { 96, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {75,90,84}, 241,1 , 8951,83 , 25,5 , 4,0 , 3028,7 , 3041,9 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kazakhstan
+ { 96, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {75,71,83}, 242,3 , 9034,81 , 25,5 , 4,0 , 3028,7 , 3050,8 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kyrgyzstan
+ { 96, 2, 141, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {77,68,76}, 0,0 , 9115,79 , 25,5 , 4,0 , 3028,7 , 3058,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Moldova
+ { 96, 2, 222, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 37,5 , 8,10 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {85,65,72}, 279,1 , 9194,92 , 25,5 , 4,0 , 3028,7 , 3065,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Ukraine
+ { 98, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 15139,48 , 15187,91 , 15278,24 , 15139,48 , 15187,91 , 15278,24 , 8073,28 , 8101,66 , 8167,14 , 8073,28 , 8101,66 , 8167,14 , 237,2 , 229,2 , {88,65,70}, 37,4 , 9286,25 , 4,4 , 48,5 , 3072,5 , 3077,22 , 0, 0, 1, 6, 7 }, // Sango/Latin/CentralAfricanRepublic
+ { 100, 2, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {82,83,68}, 280,4 , 9311,72 , 25,5 , 4,0 , 3099,6 , 3105,6 , 0, 0, 1, 6, 7 }, // Serbian/Cyrillic/Serbia
+ { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {66,65,77}, 153,2 , 9383,196 , 25,5 , 4,0 , 3111,6 , 587,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/BosniaAndHerzegowina
+ { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {69,85,82}, 19,1 , 9579,27 , 25,5 , 4,0 , 3111,6 , 3117,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro
+ { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {82,83,68}, 284,4 , 9606,72 , 25,5 , 4,0 , 3111,6 , 3126,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia
+ { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 115,8 , 981,20 , 37,5 , 419,40 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15584,83 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8357,28 , 8385,54 , 8261,14 , 239,9 , 231,7 , {66,65,77}, 288,2 , 9678,196 , 25,5 , 4,0 , 3132,6 , 3138,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/BosniaAndHerzegowina
+ { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {69,85,82}, 19,1 , 9874,27 , 25,5 , 4,0 , 3099,6 , 3157,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro
+ { 100, 2, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {69,85,82}, 19,1 , 9874,27 , 25,5 , 4,0 , 3099,6 , 3166,6 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Kosovo
+ { 100, 7, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {69,85,82}, 19,1 , 9579,27 , 25,5 , 4,0 , 3111,6 , 3172,6 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Kosovo
+ { 101, 2, 81, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 436,9 , 436,9 , 187,8 , 1001,23 , 37,5 , 8,10 , 14908,62 , 15667,82 , 14970,24 , 15749,59 , 15808,86 , 14970,24 , 8439,28 , 8467,61 , 8528,14 , 8542,28 , 8570,61 , 8528,14 , 0,2 , 0,2 , {71,69,76}, 0,0 , 9901,17 , 14,5 , 4,0 , 3178,4 , 3182,11 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Georgia
+ { 101, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 436,9 , 436,9 , 187,8 , 1001,23 , 37,5 , 8,10 , 14908,62 , 15667,82 , 14970,24 , 15749,59 , 15808,86 , 14970,24 , 8439,28 , 8467,61 , 8528,14 , 8542,28 , 8570,61 , 8528,14 , 0,2 , 0,2 , {82,85,66}, 275,4 , 9918,17 , 14,5 , 4,0 , 3178,4 , 3193,6 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Russia
+ { 102, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 15894,48 , 15942,105 , 158,27 , 15894,48 , 15942,105 , 158,27 , 8631,27 , 8658,61 , 85,14 , 8631,27 , 8658,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3199,7 , 0,0 , 2, 1, 7, 6, 7 }, // Southern Sotho/Latin/SouthAfrica
+ { 102, 7, 120, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 15894,48 , 15942,105 , 158,27 , 15894,48 , 15942,105 , 158,27 , 8631,27 , 8658,61 , 85,14 , 8631,27 , 8658,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3199,7 , 0,0 , 2, 1, 1, 6, 7 }, // Southern Sotho/Latin/Lesotho
+ { 103, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16047,48 , 16095,117 , 158,27 , 16047,48 , 16095,117 , 158,27 , 8719,27 , 8746,64 , 85,14 , 8719,27 , 8746,64 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3206,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/SouthAfrica
+ { 103, 7, 28, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16047,48 , 16095,117 , 158,27 , 16047,48 , 16095,117 , 158,27 , 8719,27 , 8746,64 , 85,14 , 8719,27 , 8746,64 , 85,14 , 0,2 , 0,2 , {66,87,80}, 170,1 , 0,7 , 4,4 , 4,0 , 3206,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/Botswana
+ { 104, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 16212,47 , 16259,100 , 16359,24 , 16212,47 , 16259,100 , 16359,24 , 8810,32 , 8842,55 , 8897,14 , 8810,32 , 8842,55 , 8897,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 9935,22 , 4,4 , 8,6 , 3214,8 , 1497,8 , 2, 1, 7, 6, 7 }, // Shona/Latin/Zimbabwe
+ { 106, 32, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 536,10 , 323,17 , 459,7 , 466,13 , 16383,59 , 16442,96 , 16538,32 , 16570,61 , 16442,96 , 16538,32 , 8911,30 , 8941,62 , 9003,19 , 8911,30 , 8941,62 , 9003,19 , 257,5 , 245,4 , {76,75,82}, 290,3 , 9957,19 , 14,5 , 4,0 , 3222,5 , 3227,11 , 2, 1, 1, 6, 7 }, // Sinhala/Sinhala/SriLanka
+ { 107, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16631,48 , 16679,114 , 158,27 , 16631,48 , 16679,114 , 158,27 , 9022,27 , 9049,68 , 85,14 , 9022,27 , 9049,68 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3238,7 , 0,0 , 2, 1, 7, 6, 7 }, // Swati/Latin/SouthAfrica
+ { 107, 7, 204, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16631,48 , 16679,114 , 158,27 , 16631,48 , 16679,114 , 158,27 , 9022,27 , 9049,68 , 85,14 , 9022,27 , 9049,68 , 85,14 , 0,2 , 0,2 , {83,90,76}, 191,1 , 0,7 , 4,4 , 4,0 , 3238,7 , 0,0 , 2, 1, 1, 6, 7 }, // Swati/Latin/Swaziland
+ { 108, 7, 191, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 135,7 , 135,7 , 546,8 , 462,18 , 61,4 , 219,9 , 16793,48 , 16841,82 , 15560,24 , 16793,48 , 16923,89 , 15560,24 , 9117,21 , 9138,52 , 9190,14 , 9117,21 , 9138,52 , 9190,14 , 262,10 , 249,9 , {69,85,82}, 19,1 , 9976,28 , 25,5 , 4,0 , 3245,10 , 3255,9 , 2, 1, 1, 6, 7 }, // Slovak/Latin/Slovakia
+ { 109, 7, 192, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 445,8 , 445,8 , 1024,9 , 590,19 , 37,5 , 8,10 , 15431,48 , 17012,86 , 15560,24 , 17098,59 , 17012,86 , 15560,24 , 9204,28 , 9232,52 , 9284,14 , 9298,35 , 9232,52 , 9284,14 , 81,4 , 258,4 , {69,85,82}, 19,1 , 10004,28 , 4,4 , 8,6 , 3264,11 , 3275,9 , 2, 1, 1, 6, 7 }, // Slovenian/Latin/Slovenia
+ { 110, 7, 194, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {83,79,83}, 99,1 , 10032,22 , 4,4 , 4,0 , 3284,8 , 3292,10 , 0, 0, 1, 6, 7 }, // Somali/Latin/Somalia
+ { 110, 7, 59, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {68,74,70}, 5,3 , 10054,21 , 4,4 , 4,0 , 3284,8 , 3302,7 , 0, 0, 6, 6, 7 }, // Somali/Latin/Djibouti
+ { 110, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {69,84,66}, 0,2 , 10075,22 , 4,4 , 4,0 , 3284,8 , 3309,8 , 2, 1, 7, 6, 7 }, // Somali/Latin/Ethiopia
+ { 110, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {75,69,83}, 2,3 , 0,7 , 4,4 , 4,0 , 3284,8 , 3317,7 , 2, 1, 7, 6, 7 }, // Somali/Latin/Kenya
+ { 111, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 3324,17 , 2054,6 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Spain
+ { 111, 7, 10, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 479,14 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {65,82,83}, 12,1 , 10097,51 , 4,4 , 4,0 , 3341,7 , 3348,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Argentina
+ { 111, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {66,79,66}, 293,2 , 10148,35 , 4,4 , 4,0 , 3341,7 , 3357,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Bolivia
+ { 111, 7, 43, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 503,8 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,76,80}, 12,1 , 10183,45 , 4,4 , 48,5 , 3341,7 , 3364,5 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Chile
+ { 111, 7, 47, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,79,80}, 12,1 , 10228,54 , 4,4 , 4,0 , 3341,7 , 3369,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Colombia
+ { 111, 7, 52, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,82,67}, 295,1 , 10282,67 , 4,4 , 4,0 , 3341,7 , 3377,10 , 0, 0, 1, 6, 7 }, // Spanish/Latin/CostaRica
+ { 111, 7, 55, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,85,80}, 12,1 , 10349,42 , 4,4 , 4,0 , 3341,7 , 3387,4 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Cuba
+ { 111, 7, 61, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {68,79,80}, 12,1 , 10391,54 , 4,4 , 4,0 , 3341,7 , 3391,20 , 2, 1, 7, 6, 7 }, // Spanish/Latin/DominicanRepublic
+ { 111, 7, 63, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 48,5 , 3341,7 , 3411,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ecuador
+ { 111, 7, 65, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 204,3 , 10445,70 , 4,4 , 4,0 , 3341,7 , 3418,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/ElSalvador
+ { 111, 7, 66, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {88,65,70}, 37,4 , 10515,53 , 4,4 , 4,0 , 3341,7 , 3429,17 , 0, 0, 1, 6, 7 }, // Spanish/Latin/EquatorialGuinea
+ { 111, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {71,84,81}, 296,1 , 10568,70 , 4,4 , 4,0 , 3341,7 , 3446,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Guatemala
+ { 111, 7, 96, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 1033,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {72,78,76}, 297,1 , 10638,60 , 4,4 , 4,0 , 3341,7 , 3455,8 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Honduras
+ { 111, 7, 139, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {77,88,78}, 12,1 , 10698,48 , 4,4 , 4,0 , 3341,7 , 3463,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Mexico
+ { 111, 7, 155, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {78,73,79}, 298,2 , 10746,69 , 4,4 , 4,0 , 3341,7 , 3469,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Nicaragua
+ { 111, 7, 166, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 1060,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,65,66}, 300,3 , 10815,54 , 4,4 , 4,0 , 3341,7 , 3478,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Panama
+ { 111, 7, 168, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,89,71}, 303,1 , 10869,61 , 14,5 , 65,6 , 3341,7 , 3484,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Paraguay
+ { 111, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 37,5 , 493,15 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,69,78}, 304,3 , 10930,62 , 4,4 , 4,0 , 3341,7 , 3492,4 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Peru
+ { 111, 7, 170, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {80,72,80}, 183,1 , 10992,48 , 25,5 , 4,0 , 3341,7 , 3496,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Philippines
+ { 111, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 1060,8 , 897,27 , 18,7 , 25,12 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 4,0 , 3341,7 , 1184,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/PuertoRico
+ { 111, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 518,6 , 897,27 , 18,7 , 25,12 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 4,0 , 3341,7 , 3505,14 , 2, 1, 7, 6, 7 }, // Spanish/Latin/UnitedStates
+ { 111, 7, 227, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,89,85}, 12,1 , 11040,48 , 14,5 , 71,7 , 3341,7 , 3519,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Uruguay
+ { 111, 7, 231, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {86,69,70}, 307,3 , 11088,64 , 4,4 , 48,5 , 3341,7 , 3526,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Venezuela
+ { 111, 7, 238, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 3341,7 , 3535,14 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CanaryIslands
+ { 111, 7, 246, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {0,0,0}, 0,0 , 11152,0 , 4,4 , 4,0 , 3549,23 , 3572,13 , 2, 1, 1, 6, 7 }, // Spanish/Latin/LatinAmericaAndTheCaribbean
+ { 111, 7, 250, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 3341,7 , 3585,15 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CeutaAndMelilla
+ { 113, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {84,90,83}, 192,3 , 11152,27 , 4,4 , 8,6 , 3600,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Tanzania
+ { 113, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {75,69,83}, 2,3 , 11179,24 , 4,4 , 4,0 , 3600,9 , 1012,5 , 2, 1, 7, 6, 7 }, // Swahili/Latin/Kenya
+ { 113, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {85,71,88}, 197,3 , 11203,25 , 4,4 , 8,6 , 3600,9 , 1387,6 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Uganda
+ { 114, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {83,69,75}, 157,2 , 11228,45 , 25,5 , 4,0 , 3609,7 , 3616,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Sweden
+ { 114, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {69,85,82}, 19,1 , 11273,19 , 25,5 , 4,0 , 3609,7 , 3623,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Finland
+ { 114, 7, 248, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {69,85,82}, 19,1 , 11273,19 , 25,5 , 4,0 , 3609,7 , 3630,5 , 2, 1, 1, 6, 7 }, // Swedish/Latin/AlandIslands
+ { 116, 2, 209, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 171, 8222, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 17980,48 , 18028,71 , 158,27 , 17980,48 , 18028,71 , 158,27 , 9770,28 , 9798,55 , 85,14 , 9770,28 , 9798,55 , 85,14 , 0,2 , 0,2 , {84,74,83}, 242,3 , 11292,13 , 14,5 , 4,0 , 3635,6 , 3641,10 , 2, 1, 1, 6, 7 }, // Tajik/Cyrillic/Tajikistan
+ { 117, 27, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {73,78,82}, 123,1 , 11305,13 , 14,5 , 4,0 , 3651,5 , 3656,7 , 2, 1, 7, 7, 7 }, // Tamil/Tamil/India
+ { 117, 27, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {77,89,82}, 256,2 , 11318,22 , 14,5 , 4,0 , 3651,5 , 3663,7 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Malaysia
+ { 117, 27, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {83,71,68}, 12,1 , 11340,24 , 14,5 , 4,0 , 3651,5 , 3670,11 , 2, 1, 7, 6, 7 }, // Tamil/Tamil/Singapore
+ { 117, 27, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {76,75,82}, 310,3 , 11364,20 , 14,5 , 4,0 , 3651,5 , 3681,6 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/SriLanka
+ { 119, 28, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 499,11 , 499,11 , 503,8 , 99,16 , 18,7 , 25,12 , 18360,66 , 18426,86 , 18512,31 , 18543,78 , 18426,86 , 18621,31 , 9922,32 , 9954,60 , 10014,18 , 9922,32 , 9954,60 , 10014,18 , 0,2 , 0,2 , {73,78,82}, 123,1 , 11384,26 , 4,4 , 8,6 , 3687,6 , 3693,9 , 2, 1, 7, 7, 7 }, // Telugu/Telugu/India
+ { 120, 30, 211, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 510,5 , 510,5 , 515,8 , 523,7 , 287,6 , 1098,19 , 37,5 , 508,28 , 18652,63 , 18715,98 , 18652,63 , 18652,63 , 18715,98 , 18813,62 , 10032,23 , 10055,68 , 10032,23 , 10032,23 , 10055,68 , 10032,23 , 284,10 , 274,10 , {84,72,66}, 313,1 , 11410,13 , 4,4 , 8,6 , 3702,3 , 3702,3 , 2, 1, 7, 6, 7 }, // Thai/Thai/Thailand
+ { 121, 31, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 2663,63 , 18875,158 , 158,27 , 2663,63 , 18875,158 , 158,27 , 10123,49 , 10172,77 , 10249,21 , 10123,49 , 10172,77 , 10270,22 , 294,7 , 284,8 , {67,78,89}, 314,1 , 11423,13 , 14,5 , 4,0 , 3705,8 , 3713,6 , 2, 1, 7, 6, 7 }, // Tibetan/Tibetan/China
+ { 121, 31, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 2663,63 , 18875,158 , 158,27 , 2663,63 , 18875,158 , 158,27 , 10123,49 , 10172,77 , 10249,21 , 10123,49 , 10172,77 , 10270,22 , 294,7 , 284,8 , {73,78,82}, 123,1 , 11436,22 , 14,5 , 4,0 , 3705,8 , 3719,7 , 2, 1, 7, 7, 7 }, // Tibetan/Tibetan/India
+ { 122, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1117,23 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 10292,29 , 10292,29 , 10321,14 , 10292,29 , 10292,29 , 10321,14 , 301,7 , 292,7 , {69,84,66}, 0,2 , 11458,16 , 4,4 , 4,0 , 3726,4 , 109,5 , 2, 1, 7, 6, 7 }, // Tigrinya/Ethiopic/Ethiopia
+ { 122, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1140,23 , 18,7 , 25,12 , 19141,46 , 19187,54 , 1050,24 , 19141,46 , 19187,54 , 1050,24 , 10335,29 , 10335,29 , 10321,14 , 10335,29 , 10335,29 , 10321,14 , 301,7 , 292,7 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 3726,4 , 3730,4 , 2, 1, 1, 6, 7 }, // Tigrinya/Ethiopic/Eritrea
+ { 123, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 530,8 , 530,8 , 530,8 , 530,8 , 287,6 , 99,16 , 37,5 , 8,10 , 19241,51 , 19292,87 , 19379,24 , 19241,51 , 19292,87 , 19379,24 , 10364,29 , 10393,60 , 10453,14 , 10364,29 , 10393,60 , 10453,14 , 0,2 , 0,2 , {84,79,80}, 195,2 , 0,7 , 14,5 , 4,0 , 3734,13 , 1339,5 , 2, 1, 1, 6, 7 }, // Tongan/Latin/Tonga
+ { 124, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 19403,48 , 19451,122 , 158,27 , 19403,48 , 19451,122 , 158,27 , 10467,27 , 10494,72 , 85,14 , 10467,27 , 10494,72 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3747,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tsonga/Latin/SouthAfrica
+ { 125, 7, 217, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 538,8 , 538,8 , 1163,9 , 1172,16 , 37,5 , 8,10 , 19573,48 , 19621,75 , 19696,24 , 19573,48 , 19621,75 , 19696,24 , 10566,28 , 10594,54 , 10648,14 , 10566,28 , 10594,54 , 10648,14 , 308,2 , 299,2 , {84,82,89}, 315,1 , 11474,18 , 25,5 , 30,7 , 3755,6 , 3761,7 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Turkey
+ { 125, 7, 56, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 538,8 , 538,8 , 1163,9 , 1172,16 , 37,5 , 8,10 , 19573,48 , 19621,75 , 19696,24 , 19573,48 , 19621,75 , 19696,24 , 10566,28 , 10594,54 , 10648,14 , 10566,28 , 10594,54 , 10648,14 , 308,2 , 299,2 , {69,85,82}, 19,1 , 81,11 , 25,5 , 30,7 , 3755,6 , 3768,23 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Cyprus
+ { 129, 2, 222, 44, 160, 59, 37, 48, 45, 43, 1077, 171, 187, 8222, 8220, 0,6 , 0,6 , 546,8 , 546,8 , 187,8 , 1188,22 , 37,5 , 8,10 , 19720,48 , 19768,95 , 19863,24 , 19887,67 , 19954,87 , 19863,24 , 10662,21 , 10683,56 , 10739,14 , 10662,21 , 10683,56 , 10739,14 , 310,2 , 301,2 , {85,65,72}, 279,1 , 11492,49 , 25,5 , 4,0 , 3791,10 , 3801,7 , 2, 1, 1, 6, 7 }, // Ukrainian/Cyrillic/Ukraine
+ { 130, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 554,10 , 564,9 , 287,6 , 161,18 , 18,7 , 25,12 , 20041,66 , 20041,66 , 134,24 , 20041,66 , 20041,66 , 134,24 , 10753,36 , 10753,36 , 85,14 , 10753,36 , 10753,36 , 85,14 , 312,9 , 303,9 , {80,75,82}, 180,2 , 11541,21 , 4,4 , 4,0 , 3808,4 , 3812,7 , 0, 0, 7, 6, 7 }, // Urdu/Arabic/Pakistan
+ { 130, 1, 100, 46, 44, 59, 37, 1776, 45, 43, 1602, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 554,10 , 564,9 , 287,6 , 161,18 , 18,7 , 25,12 , 20041,66 , 20041,66 , 134,24 , 20041,66 , 20041,66 , 134,24 , 10753,36 , 10753,36 , 85,14 , 10753,36 , 10753,36 , 85,14 , 312,9 , 303,9 , {73,78,82}, 123,1 , 11562,18 , 14,5 , 4,0 , 3808,4 , 3819,5 , 2, 1, 7, 7, 7 }, // Urdu/Arabic/India
+ { 131, 2, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 17980,48 , 18028,71 , 14970,24 , 17980,48 , 18028,71 , 14970,24 , 10789,28 , 10817,53 , 10870,14 , 10789,28 , 10817,53 , 10870,14 , 0,2 , 0,2 , {85,90,83}, 316,3 , 11580,21 , 14,5 , 4,0 , 3824,5 , 3829,10 , 0, 0, 1, 6, 7 }, // Uzbek/Cyrillic/Uzbekistan
+ { 131, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 179,8 , 1210,33 , 61,4 , 408,11 , 20107,48 , 13771,68 , 158,27 , 20107,48 , 13771,68 , 158,27 , 10884,21 , 7208,49 , 85,14 , 10884,21 , 7208,49 , 85,14 , 0,2 , 0,2 , {65,70,78}, 263,1 , 11601,13 , 25,5 , 4,0 , 3839,6 , 2782,9 , 0, 0, 6, 4, 5 }, // Uzbek/Arabic/Afghanistan
+ { 131, 7, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 20155,52 , 20207,77 , 20284,24 , 20155,52 , 20207,77 , 20284,24 , 10905,34 , 10939,61 , 11000,14 , 10905,34 , 10939,61 , 11000,14 , 0,2 , 0,2 , {85,90,83}, 319,4 , 11614,23 , 14,5 , 4,0 , 3845,9 , 3854,11 , 0, 0, 1, 6, 7 }, // Uzbek/Latin/Uzbekistan
+ { 132, 7, 232, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 573,8 , 573,8 , 141,10 , 1243,31 , 37,5 , 8,10 , 20308,75 , 20383,130 , 158,27 , 20308,75 , 20383,130 , 158,27 , 11014,33 , 11047,55 , 11102,21 , 11014,33 , 11047,55 , 11102,21 , 321,2 , 312,2 , {86,78,68}, 323,1 , 11637,20 , 25,5 , 4,0 , 3865,10 , 3875,8 , 0, 0, 1, 6, 7 }, // Vietnamese/Latin/Vietnam
+ { 134, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 135,7 , 135,7 , 141,10 , 10,17 , 37,5 , 8,10 , 20513,52 , 20565,87 , 20652,26 , 20678,62 , 20565,87 , 20652,26 , 11123,29 , 11152,77 , 11229,15 , 11244,30 , 11152,77 , 11229,15 , 0,2 , 0,2 , {71,66,80}, 171,1 , 11657,154 , 4,4 , 4,0 , 3883,7 , 3890,16 , 2, 1, 1, 6, 7 }, // Welsh/Latin/UnitedKingdom
+ { 136, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 20740,48 , 20788,91 , 158,27 , 20740,48 , 20788,91 , 158,27 , 11274,28 , 11302,61 , 85,14 , 11274,28 , 11302,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3906,8 , 0,0 , 2, 1, 7, 6, 7 }, // Xhosa/Latin/SouthAfrica
+ { 138, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 20879,73 , 20952,121 , 158,27 , 20879,73 , 20952,121 , 158,27 , 11363,44 , 11407,69 , 85,14 , 11363,44 , 11407,69 , 85,14 , 323,5 , 314,5 , {78,71,78}, 182,1 , 11811,34 , 4,4 , 8,6 , 3914,10 , 3924,18 , 2, 1, 1, 6, 7 }, // Yoruba/Latin/Nigeria
+ { 140, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 581,9 , 590,10 , 72,10 , 82,17 , 18,7 , 25,12 , 21073,48 , 21121,104 , 134,24 , 21073,48 , 21225,90 , 134,24 , 11476,28 , 11504,68 , 11572,14 , 11476,28 , 11504,68 , 11572,14 , 328,7 , 319,8 , {90,65,82}, 11,1 , 11845,27 , 4,4 , 8,6 , 3942,7 , 3949,17 , 2, 1, 7, 6, 7 }, // Zulu/Latin/SouthAfrica
+ { 141, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 187,8 , 554,17 , 37,5 , 392,16 , 5815,48 , 13184,83 , 134,24 , 13267,59 , 13184,83 , 134,24 , 11586,28 , 11614,51 , 2309,14 , 11665,28 , 11614,51 , 2309,14 , 335,9 , 327,11 , {78,79,75}, 157,2 , 11872,42 , 25,5 , 4,0 , 3966,7 , 3973,5 , 2, 1, 1, 6, 7 }, // NorwegianNynorsk/Latin/Norway
+ { 142, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 118,7 , 118,7 , 1274,9 , 981,20 , 37,5 , 8,10 , 15431,48 , 21315,83 , 15560,24 , 15431,48 , 21315,83 , 15560,24 , 2032,28 , 2060,58 , 85,14 , 2032,28 , 2060,58 , 85,14 , 248,9 , 238,7 , {66,65,77}, 153,2 , 11914,218 , 14,5 , 4,0 , 3978,8 , 587,19 , 2, 1, 1, 6, 7 }, // Bosnian/Latin/BosniaAndHerzegowina
+ { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 37,5 , 8,10 , 15302,48 , 15584,83 , 11981,24 , 15302,48 , 15584,83 , 11981,24 , 8357,28 , 8385,54 , 8261,14 , 8357,28 , 8385,54 , 8261,14 , 239,9 , 231,7 , {66,65,77}, 288,2 , 12132,195 , 25,5 , 4,0 , 3986,8 , 3138,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/BosniaAndHerzegowina
+ { 144, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 82,17 , 37,5 , 8,10 , 21398,102 , 21500,140 , 158,27 , 21398,102 , 21500,140 , 158,27 , 11693,30 , 11723,57 , 85,14 , 11693,30 , 11723,57 , 85,14 , 75,4 , 74,4 , {71,66,80}, 171,1 , 0,7 , 4,4 , 4,0 , 3994,5 , 3999,14 , 2, 1, 1, 6, 7 }, // Manx/Latin/UnitedKingdom
+ { 145, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 99,16 , 37,5 , 8,10 , 21640,46 , 21686,124 , 158,27 , 21640,46 , 21686,124 , 158,27 , 11780,28 , 11808,60 , 85,14 , 11780,28 , 11808,60 , 85,14 , 75,4 , 74,4 , {71,66,80}, 171,1 , 0,7 , 4,4 , 4,0 , 4013,8 , 3999,14 , 2, 1, 1, 6, 7 }, // Cornish/Latin/UnitedKingdom
+ { 146, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 21810,48 , 21858,192 , 158,27 , 21810,48 , 21858,192 , 158,27 , 11868,28 , 11896,49 , 11945,14 , 11868,28 , 11896,49 , 11945,14 , 344,2 , 338,2 , {71,72,83}, 173,3 , 12327,17 , 4,4 , 4,0 , 4021,4 , 4025,5 , 2, 1, 1, 6, 7 }, // Akan/Latin/Ghana
+ { 147, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 634,6 , 99,16 , 18,7 , 25,12 , 22050,87 , 22050,87 , 158,27 , 22050,87 , 22050,87 , 158,27 , 6771,32 , 11959,55 , 85,14 , 6771,32 , 11959,55 , 85,14 , 346,5 , 340,5 , {73,78,82}, 123,1 , 0,7 , 14,5 , 4,0 , 4030,6 , 2282,4 , 2, 1, 7, 7, 7 }, // Konkani/Devanagari/India
+ { 149, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 22137,48 , 22185,86 , 158,27 , 22137,48 , 22185,86 , 158,27 , 12014,29 , 12043,57 , 85,14 , 12014,29 , 12043,57 , 85,14 , 351,4 , 345,4 , {78,71,78}, 182,1 , 12344,12 , 4,4 , 8,6 , 4036,4 , 1113,7 , 2, 1, 1, 6, 7 }, // Igbo/Latin/Nigeria
+ { 150, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 22271,48 , 22319,189 , 22508,24 , 22271,48 , 22319,189 , 22508,24 , 12100,28 , 12128,74 , 12202,14 , 12100,28 , 12128,74 , 12202,14 , 355,9 , 349,7 , {75,69,83}, 2,3 , 12356,23 , 4,4 , 8,6 , 4040,7 , 1012,5 , 2, 1, 7, 6, 7 }, // Kamba/Latin/Kenya
+ { 152, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1283,22 , 18,7 , 25,12 , 22532,47 , 22579,77 , 22656,24 , 22532,47 , 22579,77 , 22656,24 , 12216,26 , 12242,43 , 12285,14 , 12216,26 , 12242,43 , 12285,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4047,3 , 3730,4 , 2, 1, 1, 6, 7 }, // Blin/Ethiopic/Eritrea
+ { 157, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1305,21 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 12299,27 , 12326,41 , 12367,14 , 12299,27 , 12326,41 , 12367,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4050,3 , 3730,4 , 2, 1, 1, 6, 7 }, // Tigre/Ethiopic/Eritrea
+ { 159, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 1326,27 , 37,5 , 8,10 , 22680,48 , 22728,77 , 22805,24 , 22680,48 , 22728,77 , 22805,24 , 12381,28 , 12409,50 , 3070,14 , 12381,28 , 12409,50 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 14,5 , 4,0 , 4053,6 , 4059,6 , 2, 1, 1, 6, 7 }, // Friulian/Latin/Italy
+ { 160, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 22829,48 , 22877,111 , 158,27 , 22829,48 , 22877,111 , 158,27 , 12459,27 , 12486,70 , 85,14 , 12459,27 , 12486,70 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4065,9 , 0,0 , 2, 1, 7, 6, 7 }, // Venda/Latin/SouthAfrica
+ { 161, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 600,11 , 611,10 , 518,6 , 1353,23 , 536,12 , 548,12 , 22988,48 , 23036,87 , 23123,24 , 22988,48 , 23036,87 , 23123,24 , 12556,28 , 12584,44 , 12628,14 , 12556,28 , 12584,44 , 12628,14 , 364,3 , 356,5 , {71,72,83}, 173,3 , 12379,37 , 4,4 , 8,6 , 4074,6 , 4080,12 , 2, 1, 1, 6, 7 }, // Ewe/Latin/Ghana
+ { 161, 7, 212, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 600,11 , 611,10 , 518,6 , 1353,23 , 536,12 , 548,12 , 22988,48 , 23036,87 , 23123,24 , 22988,48 , 23036,87 , 23123,24 , 12556,28 , 12584,44 , 12628,14 , 12556,28 , 12584,44 , 12628,14 , 364,3 , 356,5 , {88,79,70}, 209,3 , 12416,106 , 4,4 , 8,6 , 4074,6 , 4092,11 , 0, 0, 1, 6, 7 }, // Ewe/Latin/Togo
+ { 162, 14, 69, 46, 8217, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1376,22 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 12642,27 , 12642,27 , 12669,14 , 12642,27 , 12642,27 , 12669,14 , 0,2 , 0,2 , {69,84,66}, 0,2 , 11458,16 , 4,4 , 4,0 , 4103,5 , 109,5 , 2, 1, 7, 6, 7 }, // Walamo/Ethiopic/Ethiopia
+ { 163, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 10,17 , 18,7 , 25,12 , 23147,59 , 23206,95 , 158,27 , 23147,59 , 23206,95 , 158,27 , 12683,21 , 12704,57 , 85,14 , 12683,21 , 12704,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 0,7 , 4,4 , 8,6 , 4108,14 , 4122,19 , 2, 1, 7, 6, 7 }, // Hawaiian/Latin/UnitedStates
+ { 166, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 621,8 , 621,8 , 518,6 , 1398,18 , 37,5 , 8,10 , 23301,48 , 23349,88 , 23437,24 , 23301,48 , 23349,88 , 23437,24 , 12761,28 , 12789,55 , 12844,14 , 12858,28 , 12789,55 , 12844,14 , 0,2 , 0,2 , {80,72,80}, 183,1 , 12522,22 , 4,4 , 8,6 , 4141,8 , 4149,9 , 2, 1, 7, 6, 7 }, // Filipino/Latin/Philippines
+ { 167, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 23461,86 , 134,24 , 6990,48 , 23461,86 , 134,24 , 12886,28 , 12914,63 , 3471,14 , 12886,28 , 12914,63 , 3471,14 , 94,5 , 361,4 , {67,72,70}, 230,3 , 12544,55 , 25,5 , 4,0 , 4158,16 , 4174,7 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Switzerland
+ { 168, 34, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 158,27 , 23547,38 , 158,27 , 158,27 , 23547,38 , 158,27 , 12977,21 , 12998,28 , 13026,14 , 12977,21 , 12998,28 , 13026,14 , 367,2 , 365,2 , {67,78,89}, 314,1 , 0,7 , 14,5 , 4,0 , 4181,3 , 4184,2 , 2, 1, 7, 6, 7 }, // Sichuan Yi/Yi/China
+ { 171, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 23585,48 , 23633,100 , 158,27 , 23585,48 , 23633,100 , 158,27 , 13040,27 , 13067,66 , 85,14 , 13040,27 , 13067,66 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4186,10 , 0,0 , 2, 1, 7, 6, 7 }, // South Ndebele/Latin/SouthAfrica
+ { 172, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 23733,48 , 23781,94 , 158,27 , 23733,48 , 23781,94 , 158,27 , 13133,27 , 13160,63 , 85,14 , 13133,27 , 13160,63 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4196,16 , 0,0 , 2, 1, 7, 6, 7 }, // Northern Sotho/Latin/SouthAfrica
+ { 173, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 72,10 , 323,17 , 37,5 , 8,10 , 23875,59 , 23934,145 , 24079,24 , 23875,59 , 23934,145 , 24079,24 , 13223,33 , 13256,75 , 13331,14 , 13223,33 , 13256,75 , 13331,14 , 0,2 , 0,2 , {78,79,75}, 157,2 , 12599,63 , 25,5 , 4,0 , 4212,15 , 4227,5 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Norway
+ { 173, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 72,10 , 323,17 , 37,5 , 8,10 , 24103,85 , 23934,145 , 24079,24 , 24103,85 , 23934,145 , 24079,24 , 13223,33 , 13345,65 , 13410,14 , 13223,33 , 13345,65 , 13410,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 12662,23 , 25,5 , 4,0 , 4212,15 , 4232,6 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Finland
+ { 175, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24188,48 , 24236,88 , 24324,24 , 24188,48 , 24236,88 , 24324,24 , 13424,28 , 13452,62 , 13514,14 , 13424,28 , 13452,62 , 13514,14 , 369,5 , 367,10 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4238,8 , 1012,5 , 2, 1, 7, 6, 7 }, // Gusii/Latin/Kenya
+ { 176, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24348,48 , 24396,221 , 24617,24 , 24348,48 , 24396,221 , 24617,24 , 13528,28 , 13556,105 , 13661,14 , 13528,28 , 13556,105 , 13661,14 , 374,10 , 377,10 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4246,7 , 1012,5 , 2, 1, 7, 6, 7 }, // Taita/Latin/Kenya
+ { 177, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 24641,48 , 24689,77 , 24766,24 , 24641,48 , 24689,77 , 24766,24 , 13675,28 , 13703,59 , 13762,14 , 13675,28 , 13703,59 , 13762,14 , 384,6 , 387,7 , {88,79,70}, 209,3 , 12709,26 , 25,5 , 4,0 , 4253,6 , 4259,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Senegal
+ { 178, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24790,48 , 24838,185 , 25023,24 , 24790,48 , 24838,185 , 25023,24 , 13776,28 , 13804,63 , 13867,14 , 13776,28 , 13804,63 , 13867,14 , 390,6 , 394,8 , {75,69,83}, 2,3 , 12735,23 , 4,4 , 8,6 , 4267,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Kikuyu/Latin/Kenya
+ { 179, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25047,48 , 25095,173 , 25268,24 , 25047,48 , 25095,173 , 25268,24 , 13881,28 , 13909,105 , 14014,14 , 13881,28 , 13909,105 , 14014,14 , 396,7 , 402,5 , {75,69,83}, 2,3 , 12758,25 , 4,4 , 8,6 , 4273,8 , 1012,5 , 2, 1, 7, 6, 7 }, // Samburu/Latin/Kenya
+ { 180, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 897,27 , 37,5 , 8,10 , 25292,48 , 25340,88 , 134,24 , 25292,48 , 25340,88 , 134,24 , 14028,28 , 14056,55 , 14111,14 , 14028,28 , 14056,55 , 14111,14 , 0,2 , 0,2 , {77,90,78}, 269,3 , 12783,28 , 0,4 , 4,0 , 4281,4 , 2908,10 , 2, 1, 7, 6, 7 }, // Sena/Latin/Mozambique
+ { 181, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25428,52 , 25480,112 , 25592,24 , 25428,52 , 25480,112 , 25592,24 , 14125,28 , 14153,50 , 14203,14 , 14125,28 , 14153,50 , 14203,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 12811,24 , 4,4 , 8,6 , 4186,10 , 1497,8 , 2, 1, 7, 6, 7 }, // North Ndebele/Latin/Zimbabwe
+ { 182, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25616,39 , 25655,194 , 25849,24 , 25616,39 , 25655,194 , 25849,24 , 14217,29 , 14246,65 , 14311,14 , 14217,29 , 14246,65 , 14311,14 , 403,8 , 407,7 , {84,90,83}, 192,3 , 12835,25 , 4,4 , 4,0 , 4285,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Rombo/Latin/Tanzania
+ { 183, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 25873,48 , 25921,81 , 26002,24 , 25873,48 , 25921,81 , 26002,24 , 14325,30 , 14355,47 , 85,14 , 14325,30 , 14355,47 , 85,14 , 411,6 , 414,8 , {77,65,68}, 0,0 , 12860,21 , 0,4 , 4,0 , 4294,8 , 4302,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Tifinagh/Morocco
+ { 183, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26026,48 , 26074,81 , 26155,24 , 26026,48 , 26074,81 , 26155,24 , 14402,30 , 14432,48 , 85,14 , 14402,30 , 14432,48 , 85,14 , 417,6 , 422,8 , {77,65,68}, 0,0 , 12881,21 , 0,4 , 4,0 , 4308,9 , 4317,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Latin/Morocco
+ { 184, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26179,48 , 26227,84 , 26311,24 , 26179,48 , 26227,84 , 26311,24 , 14480,30 , 14510,51 , 14561,14 , 14480,30 , 14510,51 , 14561,14 , 423,7 , 430,9 , {68,90,68}, 207,2 , 12902,21 , 0,4 , 4,0 , 4323,9 , 4332,8 , 2, 1, 6, 4, 5 }, // Kabyle/Latin/Algeria
+ { 185, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26335,48 , 26383,152 , 134,24 , 26335,48 , 26383,152 , 134,24 , 14575,28 , 14603,74 , 14677,14 , 14575,28 , 14603,74 , 14677,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 12923,26 , 4,4 , 78,5 , 4340,10 , 1387,6 , 0, 0, 1, 6, 7 }, // Nyankole/Latin/Uganda
+ { 186, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26535,48 , 26583,254 , 26837,24 , 26535,48 , 26583,254 , 26837,24 , 14691,28 , 14719,82 , 14801,14 , 14691,28 , 14719,82 , 14801,14 , 430,7 , 439,7 , {84,90,83}, 192,3 , 12949,29 , 0,4 , 4,0 , 4350,6 , 4356,10 , 0, 0, 1, 6, 7 }, // Bena/Latin/Tanzania
+ { 187, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 4,0 , 4366,8 , 1331,8 , 0, 0, 1, 6, 7 }, // Vunjo/Latin/Tanzania
+ { 188, 7, 132, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26948,47 , 26995,92 , 27087,24 , 26948,47 , 26995,92 , 27087,24 , 14919,28 , 14947,44 , 14991,14 , 14919,28 , 14947,44 , 14991,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 13005,24 , 4,4 , 8,6 , 4374,9 , 1842,4 , 0, 0, 1, 6, 7 }, // Bambara/Latin/Mali
+ { 189, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 27111,48 , 27159,207 , 27366,24 , 27111,48 , 27159,207 , 27366,24 , 15005,28 , 15033,64 , 15097,14 , 15005,28 , 15033,64 , 15097,14 , 442,2 , 455,2 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4383,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Embu/Latin/Kenya
+ { 190, 12, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 27390,36 , 27426,58 , 27484,24 , 27390,36 , 27426,58 , 27484,24 , 15111,28 , 15139,49 , 15188,14 , 15111,28 , 15139,49 , 15188,14 , 444,3 , 457,6 , {85,83,68}, 12,1 , 13029,19 , 4,4 , 8,6 , 4389,3 , 4392,4 , 2, 1, 7, 6, 7 }, // Cherokee/Cherokee/UnitedStates
+ { 191, 7, 137, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 27508,47 , 27555,68 , 27623,24 , 27508,47 , 27555,68 , 27623,24 , 15202,27 , 15229,48 , 15277,14 , 15202,27 , 15229,48 , 15277,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 13048,21 , 14,5 , 4,0 , 4396,14 , 4410,5 , 0, 0, 1, 6, 7 }, // Morisyen/Latin/Mauritius
+ { 192, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 27647,264 , 134,24 , 17628,48 , 27647,264 , 134,24 , 15291,28 , 15319,133 , 14311,14 , 15291,28 , 15319,133 , 14311,14 , 447,4 , 463,5 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 8,6 , 4415,10 , 1331,8 , 0, 0, 1, 6, 7 }, // Makonde/Latin/Tanzania
+ { 193, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 27911,83 , 27994,111 , 28105,24 , 27911,83 , 27994,111 , 28105,24 , 15452,36 , 15488,63 , 15551,14 , 15452,36 , 15488,63 , 15551,14 , 451,3 , 468,3 , {84,90,83}, 192,3 , 13069,29 , 14,5 , 4,0 , 4425,8 , 4433,9 , 0, 0, 1, 6, 7 }, // Langi/Latin/Tanzania
+ { 194, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28129,48 , 28177,97 , 134,24 , 28129,48 , 28177,97 , 134,24 , 15565,28 , 15593,66 , 15659,14 , 15565,28 , 15593,66 , 15659,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 13098,26 , 0,4 , 4,0 , 4442,7 , 4449,7 , 0, 0, 1, 6, 7 }, // Ganda/Latin/Uganda
+ { 195, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28274,48 , 28322,83 , 28405,24 , 28274,48 , 28322,83 , 28405,24 , 15673,80 , 15673,80 , 85,14 , 15673,80 , 15673,80 , 85,14 , 454,8 , 471,7 , {90,77,87}, 202,2 , 0,7 , 4,4 , 8,6 , 4456,9 , 1491,6 , 2, 1, 1, 6, 7 }, // Bemba/Latin/Zambia
+ { 196, 7, 39, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 453,7 , 453,7 , 364,8 , 1416,27 , 37,5 , 8,10 , 28429,48 , 28477,86 , 134,24 , 28429,48 , 28477,86 , 134,24 , 15753,28 , 15781,73 , 15854,14 , 15753,28 , 15781,73 , 15854,14 , 89,2 , 88,2 , {67,86,69}, 0,0 , 13124,25 , 0,4 , 4,0 , 4465,12 , 4477,10 , 2, 1, 1, 6, 7 }, // Kabuverdianu/Latin/CapeVerde
+ { 197, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28563,48 , 28611,86 , 28697,24 , 28563,48 , 28611,86 , 28697,24 , 15868,28 , 15896,51 , 15947,14 , 15868,28 , 15896,51 , 15947,14 , 462,2 , 478,2 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4487,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Meru/Latin/Kenya
+ { 198, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28721,48 , 28769,111 , 28880,24 , 28721,48 , 28769,111 , 28880,24 , 15961,28 , 15989,93 , 16082,14 , 15961,28 , 15989,93 , 16082,14 , 464,4 , 480,4 , {75,69,83}, 2,3 , 13149,26 , 4,4 , 8,6 , 4493,8 , 4501,12 , 2, 1, 7, 6, 7 }, // Kalenjin/Latin/Kenya
+ { 199, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 0,48 , 28904,136 , 134,24 , 0,48 , 28904,136 , 134,24 , 16096,23 , 16119,92 , 16211,14 , 16096,23 , 16119,92 , 16211,14 , 468,7 , 484,5 , {78,65,68}, 12,1 , 13175,22 , 4,4 , 4,0 , 4513,13 , 4526,8 , 2, 1, 1, 6, 7 }, // Nama/Latin/Namibia
+ { 200, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 4,0 , 4534,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Machame/Latin/Tanzania
+ { 201, 7, 82, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 347,8 , 347,8 , 1443,10 , 1453,23 , 37,5 , 8,10 , 29040,59 , 29099,87 , 134,24 , 29186,48 , 29099,87 , 134,24 , 16225,28 , 16253,72 , 3471,14 , 16225,28 , 16253,72 , 3471,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 81,11 , 25,5 , 4,0 , 4543,6 , 4549,11 , 2, 1, 1, 6, 7 }, // Colognian/Latin/Germany
+ { 202, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29234,51 , 29285,132 , 158,27 , 29234,51 , 29285,132 , 158,27 , 14815,28 , 16325,58 , 14311,14 , 14815,28 , 16325,58 , 14311,14 , 475,9 , 489,6 , {75,69,83}, 2,3 , 13197,25 , 4,4 , 8,6 , 4560,3 , 1012,5 , 2, 1, 7, 6, 7 }, // Masai/Latin/Kenya
+ { 202, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29234,51 , 29285,132 , 158,27 , 29234,51 , 29285,132 , 158,27 , 14815,28 , 16325,58 , 14311,14 , 14815,28 , 16325,58 , 14311,14 , 475,9 , 489,6 , {84,90,83}, 192,3 , 13222,28 , 4,4 , 8,6 , 4560,3 , 4563,8 , 0, 0, 1, 6, 7 }, // Masai/Latin/Tanzania
+ { 203, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28129,48 , 28177,97 , 134,24 , 28129,48 , 28177,97 , 134,24 , 16383,35 , 16418,65 , 16483,14 , 16383,35 , 16418,65 , 16483,14 , 484,6 , 495,6 , {85,71,88}, 197,3 , 13098,26 , 25,5 , 4,0 , 4571,7 , 4449,7 , 0, 0, 1, 6, 7 }, // Soga/Latin/Uganda
+ { 204, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29417,48 , 17676,84 , 134,24 , 29417,48 , 17676,84 , 134,24 , 16497,21 , 16518,75 , 85,14 , 16497,21 , 16518,75 , 85,14 , 75,4 , 74,4 , {75,69,83}, 2,3 , 13250,23 , 4,4 , 83,6 , 4578,7 , 1012,5 , 2, 1, 7, 6, 7 }, // Luyia/Latin/Kenya
+ { 205, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29465,48 , 17676,84 , 134,24 , 29465,48 , 17676,84 , 134,24 , 16593,28 , 9539,60 , 14905,14 , 16593,28 , 9539,60 , 14905,14 , 490,9 , 501,8 , {84,90,83}, 192,3 , 13273,28 , 25,5 , 4,0 , 4585,6 , 4591,8 , 0, 0, 1, 6, 7 }, // Asu/Latin/Tanzania
+ { 206, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29513,48 , 29561,94 , 29655,24 , 29513,48 , 29561,94 , 29655,24 , 16621,28 , 16649,69 , 16718,14 , 16621,28 , 16649,69 , 16718,14 , 499,9 , 509,6 , {85,71,88}, 197,3 , 13301,28 , 4,4 , 8,6 , 4599,6 , 1387,6 , 0, 0, 1, 6, 7 }, // Teso/Latin/Uganda
+ { 206, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29513,48 , 29561,94 , 29655,24 , 29513,48 , 29561,94 , 29655,24 , 16621,28 , 16649,69 , 16718,14 , 16621,28 , 16649,69 , 16718,14 , 499,9 , 509,6 , {75,69,83}, 2,3 , 13329,27 , 4,4 , 8,6 , 4599,6 , 4605,5 , 2, 1, 7, 6, 7 }, // Teso/Latin/Kenya
{ 207, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 344,48 , 392,118 , 510,24 , 344,48 , 392,118 , 510,24 , 16732,28 , 16760,56 , 16816,14 , 16732,28 , 16760,56 , 16816,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 0,0 , 43,7 , 2, 1, 1, 6, 7 }, // Saho/Latin/Eritrea
- { 208, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 16830,28 , 16858,53 , 16911,14 , 16830,28 , 16858,53 , 16911,14 , 508,6 , 515,6 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4592,11 , 4603,5 , 0, 0, 1, 6, 7 }, // Koyra Chiini/Latin/Mali
- { 209, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 0,4 , 4,0 , 4608,6 , 1325,8 , 0, 0, 1, 6, 7 }, // Rwa/Latin/Tanzania
- { 210, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29837,48 , 29885,186 , 30071,24 , 29837,48 , 29885,186 , 30071,24 , 16925,28 , 16953,69 , 17022,14 , 16925,28 , 16953,69 , 17022,14 , 514,2 , 521,2 , {75,69,83}, 2,3 , 13379,23 , 0,4 , 4,0 , 4614,6 , 1006,5 , 2, 1, 7, 6, 7 }, // Luo/Latin/Kenya
- { 211, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26335,48 , 26383,152 , 134,24 , 26335,48 , 26383,152 , 134,24 , 14575,28 , 14603,74 , 14677,14 , 14575,28 , 14603,74 , 14677,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 12923,26 , 4,4 , 78,5 , 4620,6 , 1381,6 , 0, 0, 1, 6, 7 }, // Chiga/Latin/Uganda
- { 212, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 30095,48 , 30143,86 , 30229,24 , 30095,48 , 30143,86 , 30229,24 , 17036,28 , 17064,48 , 17112,14 , 17036,28 , 17064,48 , 17112,14 , 516,9 , 523,10 , {77,65,68}, 0,0 , 13402,22 , 25,5 , 4,0 , 4626,8 , 4634,6 , 2, 1, 6, 5, 6 }, // Central Morocco Tamazight/Latin/Morocco
- { 213, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17154,54 , 16911,14 , 17126,28 , 17154,54 , 16911,14 , 508,6 , 515,6 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4640,15 , 4603,5 , 0, 0, 1, 6, 7 }, // Koyraboro Senni/Latin/Mali
- { 214, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 30253,84 , 134,24 , 17628,48 , 30253,84 , 134,24 , 17208,28 , 17236,63 , 9599,14 , 17208,28 , 17236,63 , 9599,14 , 525,5 , 533,8 , {84,90,83}, 192,3 , 11152,27 , 0,4 , 4,0 , 4655,9 , 1325,8 , 0, 0, 1, 6, 7 }, // Shambala/Latin/Tanzania
- { 215, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 30337,88 , 30337,88 , 30425,31 , 30337,88 , 30337,88 , 30425,31 , 17299,33 , 17332,54 , 17386,19 , 17299,33 , 17332,54 , 17386,19 , 530,3 , 541,6 , {73,78,82}, 122,1 , 13424,10 , 14,5 , 4,0 , 4664,4 , 2276,4 , 2, 1, 7, 7, 7 }, // Bodo/Devanagari/India
- { 230, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30456,49 , 30505,99 , 30604,24 , 30456,49 , 30505,99 , 30604,24 , 17405,28 , 17433,50 , 17483,14 , 17405,28 , 17433,50 , 17483,14 , 533,5 , 547,6 , {67,68,70}, 217,2 , 13434,24 , 0,4 , 4,0 , 4668,8 , 4676,16 , 2, 1, 1, 6, 7 }, // LubaKatanga/Latin/CongoKinshasa
- { 237, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30628,48 , 30676,195 , 30871,24 , 30628,48 , 30676,195 , 30871,24 , 17497,28 , 17525,72 , 17597,14 , 17497,28 , 17525,72 , 17597,14 , 538,3 , 553,3 , {88,65,70}, 36,4 , 13458,21 , 0,4 , 4,0 , 4692,5 , 4697,7 , 0, 0, 1, 6, 7 }, // Aghem/Latin/Cameroon
- { 238, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30895,48 , 30943,90 , 31033,24 , 30895,48 , 30943,90 , 31033,24 , 17611,28 , 17639,70 , 17709,14 , 17611,28 , 17639,70 , 17709,14 , 541,10 , 556,9 , {88,65,70}, 36,4 , 13479,22 , 25,5 , 4,0 , 4704,5 , 4709,8 , 0, 0, 1, 6, 7 }, // Basaa/Latin/Cameroon
- { 239, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17723,53 , 17776,14 , 17126,28 , 17723,53 , 17776,14 , 551,8 , 565,10 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4717,10 , 4727,5 , 0, 0, 1, 6, 7 }, // Zarma/Latin/Niger
- { 240, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31057,49 , 31106,99 , 31205,24 , 31057,49 , 31106,99 , 31205,24 , 17790,28 , 17818,45 , 17863,14 , 17790,28 , 17818,45 , 17863,14 , 559,5 , 575,6 , {88,65,70}, 36,4 , 0,7 , 25,5 , 4,0 , 4732,5 , 1615,8 , 0, 0, 1, 6, 7 }, // Duala/Latin/Cameroon
- { 241, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31229,36 , 31265,82 , 31347,24 , 31229,36 , 31265,82 , 31347,24 , 17877,28 , 17905,50 , 17955,14 , 17877,28 , 17905,50 , 17955,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 13501,23 , 25,5 , 4,0 , 4737,5 , 4742,7 , 0, 0, 1, 6, 7 }, // JolaFonyi/Latin/Senegal
- { 242, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31371,50 , 31421,141 , 31562,24 , 31371,50 , 31421,141 , 31562,24 , 17969,30 , 17999,85 , 18084,14 , 17969,30 , 17999,85 , 18084,14 , 564,7 , 581,9 , {88,65,70}, 36,4 , 13524,23 , 25,5 , 4,0 , 4749,6 , 4755,7 , 0, 0, 1, 6, 7 }, // Ewondo/Latin/Cameroon
- { 243, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31586,39 , 31625,191 , 158,27 , 31586,39 , 31625,191 , 158,27 , 18098,29 , 18127,45 , 18172,14 , 18098,29 , 18127,45 , 18172,14 , 571,6 , 590,7 , {88,65,70}, 36,4 , 13547,11 , 25,5 , 4,0 , 4762,5 , 4767,7 , 0, 0, 1, 6, 7 }, // Bafia/Latin/Cameroon
- { 244, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 31816,48 , 31864,213 , 32077,24 , 31816,48 , 31864,213 , 32077,24 , 18186,28 , 18214,59 , 18273,14 , 18186,28 , 18214,59 , 18273,14 , 577,8 , 597,10 , {77,90,78}, 269,3 , 0,7 , 14,5 , 4,0 , 4774,5 , 4779,10 , 2, 1, 7, 6, 7 }, // MakhuwaMeetto/Latin/Mozambique
- { 245, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 32101,48 , 32149,139 , 32288,24 , 32101,48 , 32149,139 , 32288,24 , 18287,28 , 18315,74 , 18389,14 , 18287,28 , 18315,74 , 18389,14 , 585,5 , 607,5 , {88,65,70}, 36,4 , 13558,17 , 4,4 , 8,6 , 4789,6 , 4795,7 , 0, 0, 1, 6, 7 }, // Mundang/Latin/Cameroon
- { 246, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 32312,51 , 32363,143 , 158,27 , 32312,51 , 32363,143 , 158,27 , 18403,30 , 18433,89 , 18522,14 , 18403,30 , 18433,89 , 18522,14 , 590,4 , 612,4 , {88,65,70}, 36,4 , 13575,20 , 25,5 , 4,0 , 4802,6 , 4808,7 , 0, 0, 1, 6, 7 }, // Kwasio/Latin/Cameroon
- { 247, 7, 201, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1476,9 , 99,16 , 18,7 , 560,12 , 32506,54 , 32560,96 , 32656,24 , 32506,54 , 32560,96 , 32656,24 , 18536,38 , 18574,79 , 18653,14 , 18536,38 , 18574,79 , 18653,14 , 594,2 , 616,2 , {83,68,71}, 0,0 , 0,7 , 4,4 , 8,6 , 4815,9 , 4824,5 , 2, 1, 6, 5, 6 }, // Nuer/Latin/Sudan
- { 248, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1485,6 , 1491,30 , 37,5 , 8,10 , 32680,75 , 32755,121 , 32876,24 , 32680,75 , 32755,121 , 32876,24 , 18667,21 , 18688,73 , 18761,14 , 18667,21 , 18688,73 , 18761,14 , 0,2 , 0,2 , {82,85,66}, 275,4 , 0,7 , 14,5 , 4,0 , 4829,9 , 0,0 , 2, 1, 1, 6, 7 }, // Sakha/Cyrillic/Russia
- { 249, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 32900,48 , 32948,117 , 158,27 , 32900,48 , 32948,117 , 158,27 , 18775,28 , 18803,60 , 18863,14 , 18775,28 , 18803,60 , 18863,14 , 596,9 , 618,9 , {84,90,83}, 192,3 , 13595,25 , 0,4 , 4,0 , 4838,9 , 4847,9 , 0, 0, 1, 6, 7 }, // Sangu/Latin/Tanzania
- { 250, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 33065,48 , 33113,188 , 33301,24 , 33065,48 , 33113,188 , 33301,24 , 18877,28 , 18905,93 , 18998,14 , 18877,28 , 18905,93 , 18998,14 , 605,10 , 627,10 , {67,68,70}, 217,2 , 13620,23 , 4,4 , 4,0 , 4856,18 , 4874,32 , 2, 1, 1, 6, 7 }, // Congo Swahili/Latin/CongoKinshasa
- { 251, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17154,54 , 16911,14 , 17126,28 , 17154,54 , 16911,14 , 551,8 , 565,10 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4906,13 , 4727,5 , 0, 0, 1, 6, 7 }, // Tasawaq/Latin/Niger
- { 252, 35, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 33325,50 , 33325,50 , 158,27 , 33325,50 , 33325,50 , 158,27 , 19012,30 , 19012,30 , 85,14 , 19012,30 , 19012,30 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 13643,15 , 4,4 , 8,6 , 4919,2 , 4921,4 , 2, 1, 1, 6, 7 }, // Vai/Vai/Liberia
- { 252, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 33375,81 , 33375,81 , 158,27 , 33375,81 , 33375,81 , 158,27 , 19042,48 , 19042,48 , 85,14 , 19042,48 , 19042,48 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 13658,20 , 4,4 , 8,6 , 4925,3 , 4928,8 , 2, 1, 1, 6, 7 }, // Vai/Latin/Liberia
- { 253, 7, 206, 44, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 72,10 , 462,18 , 37,5 , 8,10 , 33456,48 , 33504,99 , 33603,24 , 33456,48 , 33504,99 , 33603,24 , 19090,28 , 19118,53 , 19171,14 , 19090,28 , 19118,53 , 19171,14 , 0,2 , 0,2 , {67,72,70}, 0,0 , 0,7 , 14,5 , 4,0 , 4936,6 , 4942,6 , 2, 0, 1, 6, 7 }, // Walser/Latin/Switzerland
- { 254, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 33627,51 , 33678,191 , 158,27 , 33627,51 , 33678,191 , 158,27 , 19185,21 , 19206,71 , 19277,14 , 19185,21 , 19206,71 , 19277,14 , 615,8 , 637,8 , {88,65,70}, 36,4 , 0,7 , 25,5 , 30,7 , 4948,6 , 4954,7 , 0, 0, 1, 6, 7 }, // Yangben/Latin/Cameroon
- { 256, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 453,7 , 453,7 , 287,6 , 1521,23 , 37,5 , 8,10 , 33869,48 , 33917,85 , 34002,24 , 34026,48 , 34074,117 , 34002,24 , 19291,28 , 19319,54 , 3272,14 , 19291,28 , 19319,54 , 3272,14 , 0,2 , 0,2 , {69,85,82}, 131,1 , 2449,20 , 25,5 , 4,0 , 4961,9 , 2048,6 , 2, 1, 1, 6, 7 }, // Asturian/Latin/Spain
- { 257, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 629,11 , 629,11 , 640,16 , 656,9 , 72,10 , 269,18 , 37,5 , 8,10 , 34191,174 , 34191,174 , 158,27 , 34191,174 , 34191,174 , 158,27 , 19373,60 , 19373,60 , 19433,25 , 19373,60 , 19373,60 , 19433,25 , 623,8 , 645,13 , {88,65,70}, 36,4 , 13678,12 , 14,5 , 4,0 , 4970,5 , 4975,7 , 0, 0, 1, 6, 7 }, // Ngomba/Latin/Cameroon
- { 258, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 1544,10 , 82,17 , 37,5 , 8,10 , 34365,102 , 34365,102 , 158,27 , 34365,102 , 34365,102 , 158,27 , 19458,54 , 19458,54 , 19512,21 , 19458,54 , 19458,54 , 19512,21 , 0,2 , 0,2 , {88,65,70}, 36,4 , 13690,16 , 14,5 , 4,0 , 4982,4 , 4986,7 , 0, 0, 1, 6, 7 }, // Kako/Latin/Cameroon
- { 259, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 269,18 , 37,5 , 8,10 , 34467,137 , 34604,142 , 34746,36 , 34467,137 , 34604,142 , 34746,36 , 19533,49 , 19533,49 , 19582,21 , 19533,49 , 19533,49 , 19582,21 , 0,2 , 0,2 , {88,65,70}, 36,4 , 13706,12 , 14,5 , 4,0 , 4993,5 , 4998,7 , 0, 0, 1, 6, 7 }, // Meta/Latin/Cameroon
- { 260, 7, 37, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1554,32 , 37,5 , 8,10 , 34782,164 , 34782,164 , 158,27 , 34782,164 , 34782,164 , 158,27 , 19603,111 , 19603,111 , 85,14 , 19603,111 , 19603,111 , 85,14 , 631,9 , 658,8 , {88,65,70}, 36,4 , 13718,16 , 14,5 , 4,0 , 5005,16 , 5021,7 , 0, 0, 1, 6, 7 }, // Ngiemboon/Latin/Cameroon
+ { 208, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 16830,28 , 16858,53 , 16911,14 , 16830,28 , 16858,53 , 16911,14 , 508,6 , 515,6 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4610,11 , 4621,5 , 0, 0, 1, 6, 7 }, // Koyra Chiini/Latin/Mali
+ { 209, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 0,4 , 4,0 , 4626,6 , 1331,8 , 0, 0, 1, 6, 7 }, // Rwa/Latin/Tanzania
+ { 210, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29837,48 , 29885,186 , 30071,24 , 29837,48 , 29885,186 , 30071,24 , 16925,28 , 16953,69 , 17022,14 , 16925,28 , 16953,69 , 17022,14 , 514,2 , 521,2 , {75,69,83}, 2,3 , 13379,23 , 0,4 , 4,0 , 4632,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Luo/Latin/Kenya
+ { 211, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26335,48 , 26383,152 , 134,24 , 26335,48 , 26383,152 , 134,24 , 14575,28 , 14603,74 , 14677,14 , 14575,28 , 14603,74 , 14677,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 12923,26 , 4,4 , 78,5 , 4638,6 , 1387,6 , 0, 0, 1, 6, 7 }, // Chiga/Latin/Uganda
+ { 212, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 30095,48 , 30143,86 , 30229,24 , 30095,48 , 30143,86 , 30229,24 , 17036,28 , 17064,48 , 17112,14 , 17036,28 , 17064,48 , 17112,14 , 516,9 , 523,10 , {77,65,68}, 0,0 , 13402,22 , 25,5 , 4,0 , 4644,8 , 4652,6 , 2, 1, 6, 5, 6 }, // Central Morocco Tamazight/Latin/Morocco
+ { 213, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17154,54 , 16911,14 , 17126,28 , 17154,54 , 16911,14 , 508,6 , 515,6 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4658,15 , 4621,5 , 0, 0, 1, 6, 7 }, // Koyraboro Senni/Latin/Mali
+ { 214, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 30253,84 , 134,24 , 17628,48 , 30253,84 , 134,24 , 17208,28 , 17236,63 , 9599,14 , 17208,28 , 17236,63 , 9599,14 , 525,5 , 533,8 , {84,90,83}, 192,3 , 11152,27 , 0,4 , 4,0 , 4673,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Shambala/Latin/Tanzania
+ { 215, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 30337,88 , 30337,88 , 30425,31 , 30337,88 , 30337,88 , 30425,31 , 17299,33 , 17332,54 , 17386,19 , 17299,33 , 17332,54 , 17386,19 , 530,3 , 541,6 , {73,78,82}, 123,1 , 13424,10 , 14,5 , 4,0 , 4682,4 , 2282,4 , 2, 1, 7, 7, 7 }, // Bodo/Devanagari/India
+ { 230, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30456,49 , 30505,99 , 30604,24 , 30456,49 , 30505,99 , 30604,24 , 17405,28 , 17433,50 , 17483,14 , 17405,28 , 17433,50 , 17483,14 , 533,5 , 547,6 , {67,68,70}, 217,2 , 13434,24 , 0,4 , 4,0 , 4686,8 , 4694,16 , 2, 1, 1, 6, 7 }, // LubaKatanga/Latin/CongoKinshasa
+ { 237, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30628,48 , 30676,195 , 30871,24 , 30628,48 , 30676,195 , 30871,24 , 17497,28 , 17525,72 , 17597,14 , 17497,28 , 17525,72 , 17597,14 , 538,3 , 553,3 , {88,65,70}, 37,4 , 13458,21 , 0,4 , 4,0 , 4710,5 , 4715,7 , 0, 0, 1, 6, 7 }, // Aghem/Latin/Cameroon
+ { 238, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30895,48 , 30943,90 , 31033,24 , 30895,48 , 30943,90 , 31033,24 , 17611,28 , 17639,70 , 17709,14 , 17611,28 , 17639,70 , 17709,14 , 541,10 , 556,9 , {88,65,70}, 37,4 , 13479,22 , 25,5 , 4,0 , 4722,5 , 4727,8 , 0, 0, 1, 6, 7 }, // Basaa/Latin/Cameroon
+ { 239, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17723,53 , 17776,14 , 17126,28 , 17723,53 , 17776,14 , 551,8 , 565,10 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4735,10 , 4745,5 , 0, 0, 1, 6, 7 }, // Zarma/Latin/Niger
+ { 240, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31057,49 , 31106,99 , 31205,24 , 31057,49 , 31106,99 , 31205,24 , 17790,28 , 17818,45 , 17863,14 , 17790,28 , 17818,45 , 17863,14 , 559,5 , 575,6 , {88,65,70}, 37,4 , 0,7 , 25,5 , 4,0 , 4750,5 , 1621,8 , 0, 0, 1, 6, 7 }, // Duala/Latin/Cameroon
+ { 241, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31229,36 , 31265,82 , 31347,24 , 31229,36 , 31265,82 , 31347,24 , 17877,28 , 17905,50 , 17955,14 , 17877,28 , 17905,50 , 17955,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 13501,23 , 25,5 , 4,0 , 4755,5 , 4760,7 , 0, 0, 1, 6, 7 }, // JolaFonyi/Latin/Senegal
+ { 242, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31371,50 , 31421,141 , 31562,24 , 31371,50 , 31421,141 , 31562,24 , 17969,30 , 17999,85 , 18084,14 , 17969,30 , 17999,85 , 18084,14 , 564,7 , 581,9 , {88,65,70}, 37,4 , 13524,23 , 25,5 , 4,0 , 4767,6 , 4773,7 , 0, 0, 1, 6, 7 }, // Ewondo/Latin/Cameroon
+ { 243, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31586,39 , 31625,191 , 158,27 , 31586,39 , 31625,191 , 158,27 , 18098,29 , 18127,45 , 18172,14 , 18098,29 , 18127,45 , 18172,14 , 571,6 , 590,7 , {88,65,70}, 37,4 , 13547,11 , 25,5 , 4,0 , 4780,5 , 4785,7 , 0, 0, 1, 6, 7 }, // Bafia/Latin/Cameroon
+ { 244, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 31816,48 , 31864,213 , 32077,24 , 31816,48 , 31864,213 , 32077,24 , 18186,28 , 18214,59 , 18273,14 , 18186,28 , 18214,59 , 18273,14 , 577,8 , 597,10 , {77,90,78}, 269,3 , 0,7 , 14,5 , 4,0 , 4792,5 , 4797,10 , 2, 1, 7, 6, 7 }, // MakhuwaMeetto/Latin/Mozambique
+ { 245, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 32101,48 , 32149,139 , 32288,24 , 32101,48 , 32149,139 , 32288,24 , 18287,28 , 18315,74 , 18389,14 , 18287,28 , 18315,74 , 18389,14 , 585,5 , 607,5 , {88,65,70}, 37,4 , 13558,17 , 4,4 , 8,6 , 4807,6 , 4813,7 , 0, 0, 1, 6, 7 }, // Mundang/Latin/Cameroon
+ { 246, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 32312,51 , 32363,143 , 158,27 , 32312,51 , 32363,143 , 158,27 , 18403,30 , 18433,89 , 18522,14 , 18403,30 , 18433,89 , 18522,14 , 590,4 , 612,4 , {88,65,70}, 37,4 , 13575,20 , 25,5 , 4,0 , 4820,6 , 4826,7 , 0, 0, 1, 6, 7 }, // Kwasio/Latin/Cameroon
+ { 247, 7, 201, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1476,9 , 99,16 , 18,7 , 560,12 , 32506,54 , 32560,96 , 32656,24 , 32506,54 , 32560,96 , 32656,24 , 18536,38 , 18574,79 , 18653,14 , 18536,38 , 18574,79 , 18653,14 , 594,2 , 616,2 , {83,68,71}, 0,0 , 0,7 , 4,4 , 8,6 , 4833,9 , 4842,5 , 2, 1, 6, 5, 6 }, // Nuer/Latin/Sudan
+ { 248, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1485,6 , 1491,30 , 37,5 , 8,10 , 32680,75 , 32755,121 , 32876,24 , 32680,75 , 32755,121 , 32876,24 , 18667,21 , 18688,73 , 18761,14 , 18667,21 , 18688,73 , 18761,14 , 0,2 , 0,2 , {82,85,66}, 275,4 , 0,7 , 14,5 , 4,0 , 4847,9 , 0,0 , 2, 1, 1, 6, 7 }, // Sakha/Cyrillic/Russia
+ { 249, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 32900,48 , 32948,117 , 158,27 , 32900,48 , 32948,117 , 158,27 , 18775,28 , 18803,60 , 18863,14 , 18775,28 , 18803,60 , 18863,14 , 596,9 , 618,9 , {84,90,83}, 192,3 , 13595,25 , 0,4 , 4,0 , 4856,9 , 4865,9 , 0, 0, 1, 6, 7 }, // Sangu/Latin/Tanzania
+ { 250, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 33065,48 , 33113,188 , 33301,24 , 33065,48 , 33113,188 , 33301,24 , 18877,28 , 18905,93 , 18998,14 , 18877,28 , 18905,93 , 18998,14 , 605,10 , 627,10 , {67,68,70}, 217,2 , 13620,23 , 4,4 , 4,0 , 4874,18 , 4892,32 , 2, 1, 1, 6, 7 }, // Congo Swahili/Latin/CongoKinshasa
+ { 251, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17154,54 , 16911,14 , 17126,28 , 17154,54 , 16911,14 , 551,8 , 565,10 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4924,13 , 4745,5 , 0, 0, 1, 6, 7 }, // Tasawaq/Latin/Niger
+ { 252, 35, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 33325,50 , 33325,50 , 158,27 , 33325,50 , 33325,50 , 158,27 , 19012,30 , 19012,30 , 85,14 , 19012,30 , 19012,30 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 13643,15 , 4,4 , 8,6 , 4937,2 , 4939,4 , 2, 1, 1, 6, 7 }, // Vai/Vai/Liberia
+ { 252, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 33375,81 , 33375,81 , 158,27 , 33375,81 , 33375,81 , 158,27 , 19042,48 , 19042,48 , 85,14 , 19042,48 , 19042,48 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 13658,20 , 4,4 , 8,6 , 4943,3 , 4946,8 , 2, 1, 1, 6, 7 }, // Vai/Latin/Liberia
+ { 253, 7, 206, 44, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 72,10 , 462,18 , 37,5 , 8,10 , 33456,48 , 33504,99 , 33603,24 , 33456,48 , 33504,99 , 33603,24 , 19090,28 , 19118,53 , 19171,14 , 19090,28 , 19118,53 , 19171,14 , 0,2 , 0,2 , {67,72,70}, 0,0 , 0,7 , 14,5 , 4,0 , 4954,6 , 4960,6 , 2, 0, 1, 6, 7 }, // Walser/Latin/Switzerland
+ { 254, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 33627,51 , 33678,191 , 158,27 , 33627,51 , 33678,191 , 158,27 , 19185,21 , 19206,71 , 19277,14 , 19185,21 , 19206,71 , 19277,14 , 615,8 , 637,8 , {88,65,70}, 37,4 , 0,7 , 25,5 , 30,7 , 4966,6 , 4972,7 , 0, 0, 1, 6, 7 }, // Yangben/Latin/Cameroon
+ { 256, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 453,7 , 453,7 , 287,6 , 1521,23 , 37,5 , 8,10 , 33869,48 , 33917,85 , 34002,24 , 34026,48 , 34074,117 , 34002,24 , 19291,28 , 19319,54 , 3272,14 , 19291,28 , 19319,54 , 3272,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 4979,9 , 2054,6 , 2, 1, 1, 6, 7 }, // Asturian/Latin/Spain
+ { 257, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 629,11 , 629,11 , 640,16 , 656,9 , 72,10 , 269,18 , 37,5 , 8,10 , 34191,174 , 34191,174 , 158,27 , 34191,174 , 34191,174 , 158,27 , 19373,60 , 19373,60 , 19433,25 , 19373,60 , 19373,60 , 19433,25 , 623,8 , 645,13 , {88,65,70}, 37,4 , 13678,12 , 14,5 , 4,0 , 4988,5 , 4993,7 , 0, 0, 1, 6, 7 }, // Ngomba/Latin/Cameroon
+ { 258, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 1544,10 , 82,17 , 37,5 , 8,10 , 34365,102 , 34365,102 , 158,27 , 34365,102 , 34365,102 , 158,27 , 19458,54 , 19458,54 , 19512,21 , 19458,54 , 19458,54 , 19512,21 , 0,2 , 0,2 , {88,65,70}, 37,4 , 13690,16 , 14,5 , 4,0 , 5000,4 , 5004,7 , 0, 0, 1, 6, 7 }, // Kako/Latin/Cameroon
+ { 259, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 269,18 , 37,5 , 8,10 , 34467,137 , 34604,142 , 34746,36 , 34467,137 , 34604,142 , 34746,36 , 19533,49 , 19533,49 , 19582,21 , 19533,49 , 19533,49 , 19582,21 , 0,2 , 0,2 , {88,65,70}, 37,4 , 13706,12 , 14,5 , 4,0 , 5011,5 , 5016,7 , 0, 0, 1, 6, 7 }, // Meta/Latin/Cameroon
+ { 260, 7, 37, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1554,32 , 37,5 , 8,10 , 34782,164 , 34782,164 , 158,27 , 34782,164 , 34782,164 , 158,27 , 19603,111 , 19603,111 , 85,14 , 19603,111 , 19603,111 , 85,14 , 631,9 , 658,8 , {88,65,70}, 37,4 , 13718,16 , 14,5 , 4,0 , 5023,16 , 5039,7 , 0, 0, 1, 6, 7 }, // Ngiemboon/Latin/Cameroon
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, {0,0,0}, 0,0, 0,0, 0,0, 0,0, 0, 0, 0, 0, 0, 0,0, 0,0 } // trailing 0s
};
@@ -2448,19 +2451,19 @@ static const ushort months_data[] = {
0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b,
0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435,
0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435, 0x43c, 0x431, 0x430,
-0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, 0x444, 0x435,
-0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458,
-0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435,
-0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435,
-0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65,
-0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75,
-0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65,
-0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72,
-0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b,
-0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74,
-0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62,
-0x61, 0x72, 0x3b, 0x6a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73,
-0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b,
+0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d,
+0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61,
+0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a,
+0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61,
+0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67,
+0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x61,
+0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b,
+0x6a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x6f, 0x3b,
+0x6e, 0x3b, 0x64, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c,
+0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458,
+0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440,
+0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435,
+0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b,
0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439, 0x3b,
0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d,
0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x44c,
@@ -3841,15 +3844,15 @@ static const ushort days_data[] = {
0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435,
0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447,
0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430,
-0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x443, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x43d, 0x435, 0x434, 0x3b, 0x43f,
-0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x438, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441,
-0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b,
-0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440,
-0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x6e, 0x65, 0x64,
-0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x65, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74,
-0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c,
-0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74,
-0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x425,
+0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x443, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70,
+0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x65, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73,
+0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61,
+0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72,
+0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x43d, 0x435, 0x434,
+0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x438, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442,
+0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430,
+0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442,
+0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x425,
0x446, 0x431, 0x3b, 0x41a, 0x440, 0x441, 0x3b, 0x414, 0x446, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x3b, 0x426, 0x43f, 0x440, 0x3b, 0x41c,
0x440, 0x431, 0x3b, 0x421, 0x431, 0x442, 0x3b, 0x425, 0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x41a, 0x44a, 0x443,
0x44b, 0x440, 0x438, 0x441, 0x4d5, 0x440, 0x3b, 0x414, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x44b, 0x446, 0x446,
@@ -4490,13 +4493,13 @@ static const ushort pm_data[] = {
};
static const ushort currency_symbol_data[] = {
-0x42, 0x72, 0x4b, 0x73, 0x68, 0x46, 0x64, 0x6a, 0x4e, 0x66, 0x6b, 0x52, 0x24, 0x4c, 0x65, 0x6b, 0x64, 0x65, 0x6e, 0x1265,
-0x122d, 0x62c, 0x2e, 0x645, 0x2e, 0x200f, 0x62f, 0x2e, 0x62c, 0x2e, 0x200f, 0x62f, 0x2e, 0x628, 0x2e, 0x200f, 0x46, 0x43, 0x46, 0x41,
-0x641, 0x2e, 0x62c, 0x2e, 0x642, 0x2e, 0x200f, 0x62f, 0x2e, 0x639, 0x2e, 0x200f, 0x20aa, 0x62f, 0x2e, 0x623, 0x2e, 0x200f, 0x62f, 0x2e,
-0x643, 0x2e, 0x200f, 0x644, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x644, 0x2e, 0x200f, 0x623, 0x2e, 0x645, 0x2e, 0x200f, 0x62f, 0x2e,
-0x645, 0x2e, 0x200f, 0x631, 0x2e, 0x639, 0x2e, 0x200f, 0x631, 0x2e, 0x642, 0x2e, 0x200f, 0x631, 0x2e, 0x633, 0x2e, 0x200f, 0x53, 0x644,
-0x2e, 0x633, 0x2e, 0x200f, 0x62f, 0x2e, 0x62a, 0x2e, 0x200f, 0x62f, 0x2e, 0x625, 0x2e, 0x200f, 0x631, 0x2e, 0x64a, 0x2e, 0x200f, 0x564,
-0x580, 0x2e, 0x20b9, 0x6d, 0x61, 0x6e, 0x2e, 0x43c, 0x430, 0x43d, 0x2e, 0x20ac, 0x9f3, 0x4e, 0x75, 0x2e, 0x43b, 0x432, 0x2e, 0x4b,
+0x42, 0x72, 0x4b, 0x73, 0x68, 0x46, 0x64, 0x6a, 0x4e, 0x66, 0x6b, 0x52, 0x24, 0x4c, 0x65, 0x6b, 0x64, 0x65, 0x6e, 0x20ac,
+0x1265, 0x122d, 0x62c, 0x2e, 0x645, 0x2e, 0x200f, 0x62f, 0x2e, 0x62c, 0x2e, 0x200f, 0x62f, 0x2e, 0x628, 0x2e, 0x200f, 0x46, 0x43, 0x46,
+0x41, 0x641, 0x2e, 0x62c, 0x2e, 0x642, 0x2e, 0x200f, 0x62f, 0x2e, 0x639, 0x2e, 0x200f, 0x20aa, 0x62f, 0x2e, 0x623, 0x2e, 0x200f, 0x62f,
+0x2e, 0x643, 0x2e, 0x200f, 0x644, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x644, 0x2e, 0x200f, 0x623, 0x2e, 0x645, 0x2e, 0x200f, 0x62f,
+0x2e, 0x645, 0x2e, 0x200f, 0x631, 0x2e, 0x639, 0x2e, 0x200f, 0x631, 0x2e, 0x642, 0x2e, 0x200f, 0x631, 0x2e, 0x633, 0x2e, 0x200f, 0x53,
+0x644, 0x2e, 0x633, 0x2e, 0x200f, 0x62f, 0x2e, 0x62a, 0x2e, 0x200f, 0x62f, 0x2e, 0x625, 0x2e, 0x200f, 0x631, 0x2e, 0x64a, 0x2e, 0x200f,
+0x564, 0x580, 0x2e, 0x20b9, 0x6d, 0x61, 0x6e, 0x2e, 0x43c, 0x430, 0x43d, 0x2e, 0x9f3, 0x4e, 0x75, 0x2e, 0x43b, 0x432, 0x2e, 0x4b,
0x440, 0x2e, 0x17db, 0xffe5, 0x4d, 0x4f, 0x50, 0x24, 0x4e, 0x54, 0x24, 0x6b, 0x6e, 0x4b, 0x4d, 0x4b, 0x10d, 0x6b, 0x72, 0x41,
0x66, 0x6c, 0x2e, 0x4e, 0x41, 0x66, 0x2e, 0x45, 0x43, 0x24, 0x50, 0xa3, 0x44, 0x47, 0x48, 0x20b5, 0x41, 0x72, 0x4d, 0x4b,
0x52, 0x73, 0x20a6, 0x20b1, 0x57, 0x53, 0x24, 0x53, 0x52, 0x4c, 0x65, 0x45, 0x54, 0x53, 0x68, 0x54, 0x24, 0x55, 0x53, 0x68,
@@ -4504,7 +4507,7 @@ static const ushort currency_symbol_data[] = {
0x43, 0x46, 0x50, 0x46, 0x47, 0x47, 0x55, 0x4d, 0x52, 0x46, 0x43, 0x48, 0x46, 0x4c, 0x53, 0x44, 0x54, 0x46, 0x74, 0x52,
0x70, 0x20b8, 0x441, 0x43e, 0x43c, 0x20a9, 0x20ad, 0x4c, 0x73, 0x4b, 0x7a, 0x4c, 0x74, 0x434, 0x435, 0x43d, 0x52, 0x4d, 0x20ae, 0x928,
0x947, 0x930, 0x942, 0x60b, 0xfdfc, 0x7a, 0x142, 0x52, 0x24, 0x4d, 0x54, 0x6e, 0x44, 0x62, 0x631, 0x440, 0x443, 0x431, 0x2e, 0x20b4,
-0x434, 0x438, 0x43d, 0x2e, 0x41a, 0x41c, 0x64, 0x69, 0x6e, 0x2e, 0xdbb, 0xdd4, 0x2e, 0x42, 0x73, 0x20a1, 0x51, 0x4c, 0x43, 0x24,
+0x434, 0x438, 0x43d, 0x2e, 0x64, 0x69, 0x6e, 0x2e, 0x41a, 0x41c, 0xdbb, 0xdd4, 0x2e, 0x42, 0x73, 0x20a1, 0x51, 0x4c, 0x43, 0x24,
0x42, 0x2f, 0x2e, 0x20b2, 0x53, 0x2f, 0x2e, 0x42, 0x73, 0x2e, 0x52, 0x73, 0x2e, 0xe3f, 0xa5, 0x20ba, 0x441, 0x45e, 0x43c, 0x73,
0x6f, 0x2bb, 0x6d, 0x20ab
};
@@ -4514,360 +4517,360 @@ static const ushort currency_display_name_data[] = {
0x72, 0x72, 0x69, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x75, 0x69, 0x64, 0x2d, 0x41, 0x66, 0x72, 0x69,
0x6b, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61,
0x6d, 0x69, 0x62, 0x69, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265,
-0x122d, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20,
-0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20,
-0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20,
-0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20,
-0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a,
-0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627,
-0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646,
-0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626,
-0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627,
-0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646,
-0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
-0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a,
-0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20,
-0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641,
-0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a,
-0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20,
-0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641,
-0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20,
-0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631,
-0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643,
-0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20,
-0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631,
-0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643,
-0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b,
-0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628,
-0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643,
-0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b,
-0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623,
-0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646,
-0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631,
-0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627,
-0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627,
-0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
-0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f,
-0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627,
-0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20,
-0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625,
-0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633,
-0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631,
-0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627,
-0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626,
-0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a,
-0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b,
-0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631,
-0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627,
-0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b,
-0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648,
-0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627,
-0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b,
-0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648,
-0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629,
-0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b,
-0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646,
-0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629,
-0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b,
-0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628,
+0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265,
+0x122d, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee,
+0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647,
+0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647,
+0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647,
+0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627,
+0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631,
+0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
+0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a,
+0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20,
+0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b,
+0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628,
+0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f,
+0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d,
+0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x641, 0x631,
+0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642,
+0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623,
+0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631,
+0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642,
+0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646,
+0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631,
+0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645,
+0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646,
+0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631,
+0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641,
+0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648,
+0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20,
+0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641,
+0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a,
+0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643,
+0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a,
+0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641,
+0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631,
+0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20,
+0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a,
+0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642,
+0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20,
+0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20,
+0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c,
+0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f,
+0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a,
+0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f,
+0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b,
+0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x62f,
+0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f,
+0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
+0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f,
+0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f,
+0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
+0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f,
+0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a,
+0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
+0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c,
+0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627,
+0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20,
+0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c,
+0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628,
0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644,
0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
-0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x623, 0x648, 0x642,
-0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645,
-0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a,
-0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629,
-0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642,
-0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645,
-0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b,
+0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646,
+0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627,
+0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b,
+0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a,
+0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648,
+0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627,
+0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b,
0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628,
0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a,
0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20,
-0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
+0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631,
0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a,
0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627,
-0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637,
-0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637,
-0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637,
-0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639,
-0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20,
+0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
+0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
+0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
+0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
+0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20,
0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631,
-0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a,
+0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a,
0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627,
0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648,
0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20,
-0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c,
-0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627,
-0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20,
-0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c,
-0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a,
-0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648,
+0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x62c, 0x646,
+0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646,
+0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633,
+0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646,
+0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646,
+0x64a, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648,
0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20,
0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631,
-0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f,
+0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x62f,
0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a,
0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646,
0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a,
-0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631,
-0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631,
-0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647,
-0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627,
-0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644,
-0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644,
-0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644,
-0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644,
-0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b,
-0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x3b, 0x3b, 0x3b, 0x540, 0x561,
-0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63,
-0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62,
-0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x43c, 0x430, 0x43d, 0x430, 0x442, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ac, 0x9be, 0x982,
-0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be, 0x995, 0x9be, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ad, 0x9be,
-0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa, 0x9bf, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xf51, 0xf44, 0xf74,
-0xf63, 0xf0b, 0xf40, 0xfb2, 0xf58, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b, 0x431, 0x44a,
-0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b, 0x3b, 0x3b, 0x431, 0x44a, 0x43b, 0x433, 0x430,
-0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x430, 0x3b, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x20, 0x1000, 0x103b, 0x1015,
-0x103a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x20, 0x440, 0x443,
-0x431, 0x435, 0x43b, 0x44c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x179a, 0x17c0, 0x179b, 0x20, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb,
-0x1787, 0x17b6, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b,
-0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x4eba, 0x6c11, 0x5e01, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f,
-0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3, 0x95e8, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x52a0,
-0x5761, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3, 0x9580, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0,
-0x81fa, 0x5e63, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75,
-0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68,
-0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x75, 0x6e, 0x65, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b,
-0x69, 0x68, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x75,
-0x6e, 0x61, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72,
-0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61,
-0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d,
-0x61, 0x72, 0x6b, 0x65, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20,
-0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69,
-0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e,
-0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73,
-0x6b, 0xe9, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x79, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xfd, 0x63, 0x68, 0x20, 0x6b,
-0x6f, 0x72, 0x75, 0x6e, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x44, 0x61,
-0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x65, 0x20,
-0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b,
-0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72,
-0x69, 0x6e, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e,
-0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e,
-0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61,
-0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61,
-0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c,
-0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e,
-0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x53, 0x75,
-0x72, 0x69, 0x6e, 0x61, 0x61, 0x6d, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x55, 0x53, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x45, 0x61, 0x73,
-0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
-0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61,
-0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20,
-0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x44,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f,
-0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
-0x3b, 0x3b, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
-0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x61,
-0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x61,
-0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x65, 0x6c, 0x69,
-0x7a, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f,
-0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61,
-0x72, 0x73, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
-0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42,
-0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x6f, 0x74, 0x73,
-0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20, 0x50, 0x75, 0x6c, 0x61, 0x3b, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61,
-0x6e, 0x20, 0x70, 0x75, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20,
-0x70, 0x75, 0x6c, 0x61, 0x73, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x45, 0x41, 0x43,
-0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b,
-0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x43, 0x61, 0x6e, 0x61,
-0x64, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61,
-0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e,
-0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61,
-0x6e, 0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49,
-0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x61, 0x79,
-0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
-0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61,
-0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64,
-0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x42,
-0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61,
-0x6e, 0x20, 0x44, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61,
-0x6c, 0x61, 0x73, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61,
-0x73, 0x69, 0x73, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x43, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x47,
-0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e,
-0x61, 0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69, 0x73, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72,
-0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f,
-0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75,
-0x6e, 0x64, 0x73, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
-0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
-0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
-0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x48, 0x6f,
-0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x48, 0x6f,
-0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x49, 0x6e, 0x64, 0x69,
-0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70,
-0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b,
-0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4a, 0x61, 0x6d,
-0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61,
-0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20,
-0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69,
-0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c,
-0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20,
-0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20,
-0x72, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
-0x6e, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
-0x3b, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
-0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x4d, 0x61, 0x6c,
-0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61,
-0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61, 0x72, 0x69, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69,
-0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20,
-0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b,
-0x77, 0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70,
-0x65, 0x65, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b,
-0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b,
-0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x61, 0x6d,
-0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69,
-0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61,
-0x6c, 0x61, 0x6e, 0x64, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61,
-0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a,
-0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72,
-0x69, 0x61, 0x6e, 0x20, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20,
-0x6e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61,
-0x69, 0x72, 0x61, 0x73, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65,
-0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b,
-0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x50, 0x61,
-0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4b, 0x69, 0x6e, 0x61,
-0x3b, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20,
-0x6b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75,
-0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e, 0x61, 0x3b, 0x50, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x50, 0x68, 0x69,
-0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c,
-0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20,
-0x54, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b,
-0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c,
-0x6c, 0x6f, 0x69, 0x73, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c,
-0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c,
-0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c,
-0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61,
-0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69,
-0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x73, 0x3b,
-0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x69,
-0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69,
-0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x53, 0x6f, 0x6c, 0x6f,
-0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
-0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64,
-0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x4c, 0x69, 0x6c, 0x61,
-0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x6c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65,
-0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x65,
-0x6e, 0x69, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e,
-0x67, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e,
-0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c,
-0x69, 0x6e, 0x67, 0x73, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x50, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b,
-0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x54,
-0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64,
-0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
-0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67,
-0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64,
-0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
-0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x55, 0x67,
-0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x67,
-0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x56, 0x61, 0x6e, 0x75,
-0x61, 0x74, 0x75, 0x20, 0x56, 0x61, 0x74, 0x75, 0x3b, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61,
-0x74, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x73, 0x3b,
-0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62,
-0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61,
-0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61,
-0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75,
-0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74,
-0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x65, 0x75,
-0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x74, 0x3b, 0x64, 0x6f,
-0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3,
-0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b,
-0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x61, 0x3b,
-0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61,
-0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73,
-0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41,
-0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20,
-0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46,
-0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75,
-0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61,
-0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61,
-0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61,
-0x72, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63,
-0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72,
-0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69,
-0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b,
-0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61,
-0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
-0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
-0x73, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
-0x43, 0x46, 0x50, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72,
-0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9,
-0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x73, 0x3b, 0x67, 0x6f, 0x75,
-0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64,
-0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64,
-0x65, 0x73, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79,
-0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61,
-0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x73, 0x20, 0x6d, 0x61,
-0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x73, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75, 0x72,
-0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75,
-0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x73,
-0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65,
-0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65,
-0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70,
-0x69, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x72,
-0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d,
-0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x73,
-0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61,
-0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69,
-0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73,
-0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c,
-0x65, 0x73, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68,
-0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x64, 0x65, 0x73,
-0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75,
-0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b,
-0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x73, 0x3b, 0x6c, 0x69, 0x76,
-0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73,
-0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x73, 0x20, 0x73, 0x79,
-0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69,
-0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b,
-0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x76,
-0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20,
-0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x73, 0x20, 0x76,
-0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x73, 0x3b, 0x50, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61,
-0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75,
-0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x20,
-0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x45, 0x75, 0x72,
-0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20,
-0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46,
-0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20,
-0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x395, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x64, 0x61, 0x6e, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f,
-0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72,
-0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f,
-0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0xaad, 0xabe, 0xab0, 0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xac0, 0xaaf, 0xabe, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x75,
-0x257, 0x69, 0x6e, 0x20, 0x53, 0x65, 0x66, 0x61, 0x20, 0x6e, 0x61, 0x20, 0x41, 0x66, 0x69, 0x72, 0x6b, 0x61, 0x20, 0x54,
-0x61, 0x20, 0x59, 0x61, 0x6d, 0x6d, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x5e9, 0x5f4, 0x5d7, 0x3b, 0x3b, 0x5e9,
-0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9,
-0x5d9, 0x5dd, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9,
-0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x92f, 0x93e,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e, 0x74,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xcd, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61,
-0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0xed,
-0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x72, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x52, 0x75, 0x70, 0x69,
-0x61, 0x68, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45,
-0x75, 0x72, 0x6f, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645,
+0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a,
+0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20,
+0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a,
+0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625,
+0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
+0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
+0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
+0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x540, 0x561, 0x575,
+0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576,
+0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x3b, 0x3b, 0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580,
+0x561, 0x574, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e,
+0x61, 0x74, 0x131, 0x3b, 0x43c, 0x430, 0x43d, 0x430, 0x442, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be,
+0x995, 0x9be, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa,
+0x9bf, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xf51, 0xf44, 0xf74, 0xf63, 0xf0b, 0xf40, 0xfb2, 0xf58, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440,
+0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b,
+0x435, 0x432, 0x3b, 0x3b, 0x3b, 0x3b, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x430,
+0x3b, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x20, 0x1000, 0x103b, 0x1015, 0x103a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x431,
+0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x20, 0x440, 0x443, 0x431, 0x435, 0x43b, 0x44c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x179a, 0x17c0, 0x179b, 0x20, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787, 0x17b6, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x3b,
+0x4eba, 0x6c11, 0x5e01, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3,
+0x95e8, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x52a0, 0x5761, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x6fb3, 0x9580, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x81fa, 0x5e63, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74,
+0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x65, 0x20, 0x6b,
+0x75, 0x6e, 0x65, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x68,
+0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72,
+0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65,
+0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76,
+0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x6b, 0x6f, 0x6e, 0x76,
+0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x6b, 0x6f,
+0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b,
+0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20,
+0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe9, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x79,
+0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xfd, 0x63, 0x68, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x3b, 0x44, 0x61, 0x6e, 0x73,
+0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65,
+0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x45, 0x75,
+0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x41, 0x72, 0x75,
+0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61,
+0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61,
+0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e,
+0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64,
+0x65, 0x6e, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c,
+0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65,
+0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73,
+0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x61, 0x6d, 0x73, 0x65, 0x20,
+0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20,
+0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65,
+0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69,
+0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x61, 0x73, 0x74,
+0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x41,
+0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x41, 0x75,
+0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x41,
+0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x61,
+0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d,
+0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69,
+0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e,
+0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
+0x3b, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42,
+0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64,
+0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20,
+0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20, 0x50, 0x75, 0x6c,
+0x61, 0x3b, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20, 0x70, 0x75, 0x6c, 0x61, 0x3b, 0x3b, 0x3b,
+0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20, 0x70, 0x75, 0x6c, 0x61, 0x73, 0x3b, 0x43, 0x46, 0x41,
+0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63,
+0x73, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
+0x3b, 0x3b, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
+0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61,
+0x72, 0x3b, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e,
+0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
+0x3b, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x72,
+0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68,
+0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x70, 0x6f,
+0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b,
+0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47,
+0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x73, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61,
+0x69, 0x61, 0x6e, 0x20, 0x43, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x63,
+0x65, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69,
+0x73, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x47,
+0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x69,
+0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e,
+0x61, 0x65, 0x73, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65,
+0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65,
+0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67,
+0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b,
+0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x6e, 0x64,
+0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20,
+0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c,
+0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x73, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b,
+0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b,
+0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x53, 0x6f, 0x75,
+0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75,
+0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53,
+0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x4c, 0x69,
+0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72,
+0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69,
+0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20,
+0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69,
+0x61, 0x72, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61,
+0x72, 0x69, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61,
+0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x3b,
+0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x4d, 0x61,
+0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69,
+0x74, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74,
+0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20,
+0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c,
+0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x73, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x4e, 0x61, 0x69, 0x72, 0x61,
+0x3b, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
+0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72, 0x61, 0x73, 0x3b, 0x50, 0x61, 0x6b, 0x69,
+0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61,
+0x6e, 0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e,
+0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47,
+0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e,
+0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x50,
+0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e,
+0x61, 0x3b, 0x50, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70,
+0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x65,
+0x73, 0x6f, 0x73, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x54, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x53, 0x61, 0x6d,
+0x6f, 0x61, 0x6e, 0x20, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x74,
+0x61, 0x6c, 0x61, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x52, 0x75, 0x70, 0x65,
+0x65, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65,
+0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65,
+0x65, 0x73, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4c, 0x65,
+0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20,
+0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e,
+0x65, 0x61, 0x6e, 0x20, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65,
+0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e,
+0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49,
+0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x6c,
+0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73,
+0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x4c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x3b, 0x53, 0x77,
+0x61, 0x7a, 0x69, 0x20, 0x6c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x77, 0x61,
+0x7a, 0x69, 0x20, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e,
+0x69, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e,
+0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a,
+0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x54, 0x6f, 0x6e, 0x67,
+0x61, 0x6e, 0x20, 0x50, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70,
+0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb,
+0x61, 0x6e, 0x67, 0x61, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f,
+0x62, 0x61, 0x67, 0x6f, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61,
+0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
+0x3b, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61,
+0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x53,
+0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69,
+0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69,
+0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x56, 0x61, 0x74, 0x75, 0x3b,
+0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x56, 0x61, 0x6e,
+0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x73, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x4b,
+0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73,
+0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x6f, 0x75, 0x6e,
+0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f,
+0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73,
+0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b,
+0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x74, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61,
+0x3b, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6e,
+0x73, 0x6b, 0x61, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72,
+0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x61, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67,
+0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65,
+0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e,
+0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b,
+0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b,
+0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29,
+0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72,
+0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x73, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
+0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46,
+0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43,
+0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e,
+0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69,
+0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69,
+0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72,
+0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
+0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f,
+0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f,
+0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75,
+0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69,
+0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74,
+0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e,
+0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x50, 0x3b,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
+0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x67,
+0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x73, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69,
+0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e,
+0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x73, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65,
+0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65,
+0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b, 0x3b, 0x3b,
+0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x73, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x73, 0x3b, 0x6f,
+0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b, 0x3b,
+0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b,
+0x3b, 0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e,
+0x69, 0x65, 0x6e, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65,
+0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65,
+0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69,
+0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63,
+0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e,
+0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x73, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e,
+0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72,
+0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e,
+0x63, 0x73, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x64,
+0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69,
+0x65, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x3b, 0x3b,
+0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c,
+0x65, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20,
+0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x73, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e,
+0x6e, 0x65, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b,
+0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x73, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64,
+0x69, 0x6e, 0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72,
+0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x20,
+0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61,
+0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e,
+0x3b, 0x3b, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x73, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x73,
+0x3b, 0x50, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61, 0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72,
+0x6f, 0x73, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x20, 0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f,
+0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b,
+0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b, 0x3b,
+0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x395,
+0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x64, 0x61,
+0x6e, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x64, 0x61,
+0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x64,
+0x61, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0xaad, 0xabe, 0xab0,
+0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xac0, 0xaaf, 0xabe, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x69,
+0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x75, 0x257, 0x69, 0x6e, 0x20, 0x53, 0x65, 0x66, 0x61, 0x20,
+0x6e, 0x61, 0x20, 0x41, 0x66, 0x69, 0x72, 0x6b, 0x61, 0x20, 0x54, 0x61, 0x20, 0x59, 0x61, 0x6d, 0x6d, 0x61, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x5e9, 0x5f4, 0x5d7, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9,
+0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd,
+0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x92d,
+0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61,
+0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e, 0x74, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xcd, 0x73,
+0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b,
+0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x72, 0x20,
+0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x52, 0x75, 0x70, 0x69, 0x61, 0x68, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65,
+0x73, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x53, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x66,
0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72,
0x61, 0x6e, 0x63, 0x68, 0x69, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x69, 0x3b, 0x65e5, 0x672c, 0x5186, 0x3b, 0x3b,
@@ -4979,32 +4982,32 @@ static const ushort currency_display_name_data[] = {
0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441,
0x440, 0x43f, 0x441, 0x43a, 0x430, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x445,
0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x434, 0x438, 0x43d, 0x430,
-0x440, 0x430, 0x3b, 0x41a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x41c, 0x430, 0x440,
-0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e,
-0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20,
-0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446,
-0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b,
-0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x65, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435,
-0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x430,
-0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441,
-0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d,
-0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x415,
-0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x435, 0x432, 0x440, 0x430,
-0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x4b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20,
+0x440, 0x430, 0x3b, 0x4b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72,
+0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f,
+0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20,
0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63,
-0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c,
-0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68,
-0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69,
-0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f,
-0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65,
-0x72, 0x74, 0x61, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x62, 0x6f, 0x73,
-0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20,
-0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b,
-0x61, 0x3b, 0x45, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x65,
-0x76, 0x72, 0x61, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61,
-0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70,
-0x73, 0x6b, 0x61, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64,
-0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61,
+0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c,
+0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65,
+0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x61,
+0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73,
+0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e,
+0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x45,
+0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x65, 0x76, 0x72, 0x61,
+0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b,
+0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x61,
+0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61,
+0x72, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x41a, 0x43e,
+0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x41c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431,
+0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430,
+0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430,
+0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430,
+0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430,
+0x440, 0x43a, 0x65, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e,
+0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x430, 0x431, 0x438, 0x43b, 0x43d, 0x438,
+0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435,
+0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438,
+0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x415, 0x432, 0x440, 0x43e, 0x3b, 0x3b,
+0x435, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x435, 0x432, 0x440, 0x430,
0x3b, 0x41b, 0x430, 0x440, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x3b, 0x3b, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x44b, 0x3b, 0x421, 0x43e,
0x43c, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x44b, 0x3b, 0x44, 0x6f, 0x72, 0x61, 0x20,
0x72, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xdbd, 0xd82, 0xd9a,
@@ -5211,254 +5214,255 @@ static const ushort endonyms_data[] = {
0x69, 0x79, 0x61, 0x61, 0x51, 0x61, 0x66, 0x61, 0x72, 0x4f, 0x74, 0x6f, 0x62, 0x62, 0x69, 0x61, 0x59, 0x61, 0x62, 0x75,
0x75, 0x74, 0x69, 0x45, 0x72, 0x65, 0x74, 0x72, 0x69, 0x61, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x61, 0x6e, 0x73, 0x53,
0x75, 0x69, 0x64, 0x2d, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0xeb, 0x73, 0x68, 0x71,
-0x69, 0x70, 0x53, 0x68, 0x71, 0x69, 0x70, 0xeb, 0x72, 0x69, 0x61, 0x4d, 0x61, 0x71, 0x65, 0x64, 0x6f, 0x6e, 0x69, 0x12a0,
-0x121b, 0x122d, 0x129b, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a, 0x629, 0x645, 0x635, 0x631, 0x627, 0x644,
-0x62c, 0x632, 0x627, 0x626, 0x631, 0x627, 0x644, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x62a, 0x634, 0x627, 0x62f, 0x62c, 0x632, 0x631, 0x20,
-0x627, 0x644, 0x642, 0x645, 0x631, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x627, 0x627, 0x644,
-0x639, 0x631, 0x627, 0x642, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x627, 0x644, 0x623, 0x631, 0x62f, 0x646, 0x627, 0x644, 0x643,
-0x648, 0x64a, 0x62a, 0x644, 0x628, 0x646, 0x627, 0x646, 0x644, 0x64a, 0x628, 0x64a, 0x627, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646,
-0x64a, 0x627, 0x627, 0x644, 0x645, 0x63a, 0x631, 0x628, 0x639, 0x64f, 0x645, 0x627, 0x646, 0x641, 0x644, 0x633, 0x637, 0x64a, 0x646, 0x642,
-0x637, 0x631, 0x627, 0x644, 0x645, 0x645, 0x644, 0x643, 0x629, 0x20, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a, 0x629, 0x20, 0x627, 0x644,
-0x633, 0x639, 0x648, 0x62f, 0x64a, 0x629, 0x627, 0x644, 0x635, 0x648, 0x645, 0x627, 0x644, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646,
-0x633, 0x648, 0x631, 0x64a, 0x627, 0x62a, 0x648, 0x646, 0x633, 0x627, 0x644, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x20, 0x627, 0x644,
-0x639, 0x631, 0x628, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x645, 0x62a, 0x62d, 0x62f, 0x629, 0x627, 0x644, 0x635, 0x62d, 0x631, 0x627, 0x621,
-0x20, 0x627, 0x644, 0x63a, 0x631, 0x628, 0x64a, 0x629, 0x627, 0x644, 0x64a, 0x645, 0x646, 0x570, 0x561, 0x575, 0x565, 0x580, 0x565, 0x576,
-0x540, 0x561, 0x575, 0x561, 0x57d, 0x57f, 0x561, 0x576, 0x985, 0x9b8, 0x9ae, 0x9c0, 0x9af, 0x9bc, 0x9be, 0x9ad, 0x9be, 0x9f0, 0x9a4, 0x61,
-0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x63, 0x61, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61,
-0x6e, 0x410, 0x437, 0x4d9, 0x440, 0x431, 0x430, 0x458, 0x4b9, 0x430, 0x43d, 0x65, 0x75, 0x73, 0x6b, 0x61, 0x72, 0x61, 0x45, 0x73,
-0x70, 0x61, 0x69, 0x6e, 0x69, 0x61, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9ad,
-0x9be, 0x9b0, 0x9a4, 0xf62, 0xfab, 0xf7c, 0xf44, 0xf0b, 0xf41, 0xf60, 0xf56, 0xfb2, 0xf74, 0xf42, 0x62, 0x72, 0x65, 0x7a, 0x68, 0x6f,
-0x6e, 0x65, 0x67, 0x46, 0x72, 0x61, 0xf1, 0x73, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x411, 0x44a, 0x43b,
-0x433, 0x430, 0x440, 0x438, 0x44f, 0x1017, 0x1019, 0x102c, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x431, 0x435, 0x43b, 0x430, 0x440, 0x443,
-0x441, 0x43a, 0x430, 0x44f, 0x411, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x44c, 0x1781, 0x17d2, 0x1798, 0x17c2, 0x179a, 0x1780, 0x1798, 0x17d2,
-0x1796, 0x17bb, 0x1787, 0x17b6, 0x63, 0x61, 0x74, 0x61, 0x6c, 0xe0, 0x45, 0x73, 0x70, 0x61, 0x6e, 0x79, 0x61, 0x41, 0x6e, 0x64,
-0x6f, 0x72, 0x72, 0x61, 0x7b80, 0x4f53, 0x4e2d, 0x6587, 0x4e2d, 0x56fd, 0x4e2d, 0x56fd, 0x9999, 0x6e2f, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x4e2d,
-0x56fd, 0x6fb3, 0x95e8, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x65b0, 0x52a0, 0x5761, 0x7e41, 0x9ad4, 0x4e2d, 0x6587, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171,
-0x548c, 0x570b, 0x9999, 0x6e2f, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171, 0x548c, 0x570b, 0x6fb3, 0x9580, 0x7279, 0x5225,
-0x884c, 0x653f, 0x5340, 0x53f0, 0x7063, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x48, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b,
-0x61, 0x42, 0x6f, 0x73, 0x6e, 0x61, 0x20, 0x69, 0x20, 0x48, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x69, 0x6e, 0x61,
-0x10d, 0x65, 0x161, 0x74, 0x69, 0x6e, 0x61, 0x10c, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x72, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69,
-0x6b, 0x61, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x44, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c,
-0x61, 0x6e, 0x64, 0x73, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x75, 0x62, 0x61, 0x56, 0x6c,
-0x61, 0x61, 0x6d, 0x73, 0x42, 0x65, 0x6c, 0x67, 0x69, 0xeb, 0x43, 0x75, 0x72, 0x61, 0xe7, 0x61, 0x6f, 0x53, 0x75, 0x72,
-0x69, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x61, 0x72, 0x74, 0x65, 0x6e, 0x55, 0x2e, 0x53,
-0x2e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x53, 0x74, 0x61, 0x74,
-0x65, 0x73, 0xd801, 0xdc00, 0xd801, 0xdc4d, 0xd801, 0xdc4a, 0xd801, 0xdc2e, 0xd801, 0xdc47, 0xd801, 0xdc0f, 0xd801, 0xdc2d, 0xd801, 0xdc4c, 0xd801, 0xdc34,
-0xd801, 0xdc3b, 0xd801, 0xdc32, 0xd801, 0xdc3c, 0x20, 0xd801, 0xdc1d, 0xd801, 0xdc3b, 0xd801, 0xdc29, 0xd801, 0xdc3b, 0xd801, 0xdc45, 0x45, 0x6e, 0x67,
-0x6c, 0x69, 0x73, 0x68, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x41, 0x6e,
-0x74, 0x69, 0x67, 0x75, 0x61, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x42, 0x61, 0x72, 0x62, 0x75, 0x64, 0x61, 0x41, 0x75, 0x73,
-0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x75, 0x73, 0x74, 0x72,
-0x61, 0x6c, 0x69, 0x61, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x61, 0x73, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x6f, 0x73, 0x42,
-0x65, 0x6c, 0x67, 0x69, 0x75, 0x6d, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x42,
-0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6f, 0x6e, 0x43, 0x61, 0x6e, 0x61, 0x64,
-0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x61, 0x43, 0x61, 0x79,
-0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x46,
-0x69, 0x6a, 0x69, 0x47, 0x75, 0x65, 0x72, 0x6e, 0x73, 0x65, 0x79, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x47, 0x68, 0x61,
-0x6e, 0x61, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x61, 0x47, 0x75,
-0x61, 0x6d, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x53, 0x41,
-0x52, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x49, 0x72, 0x65, 0x6c, 0x61, 0x6e, 0x64, 0x4a,
-0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x69, 0x72, 0x69, 0x62, 0x61, 0x74, 0x69, 0x4c,
-0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x4d, 0x61, 0x64, 0x61, 0x67, 0x61, 0x73,
-0x63, 0x61, 0x72, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x4d, 0x61, 0x6c, 0x74, 0x61, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61,
-0x6c, 0x6c, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x75, 0x73, 0x4d,
-0x69, 0x63, 0x72, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x4e, 0x65, 0x77, 0x20,
-0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x65,
-0x72, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x61, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x50, 0x61,
-0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x50, 0x61, 0x6c, 0x61, 0x75, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77,
-0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x73, 0x50, 0x75,
-0x65, 0x72, 0x74, 0x6f, 0x20, 0x52, 0x69, 0x63, 0x6f, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x4b, 0x69, 0x74, 0x74, 0x73,
-0x20, 0x61, 0x6e, 0x64, 0x20, 0x4e, 0x65, 0x76, 0x69, 0x73, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x4c, 0x75, 0x63, 0x69,
-0x61, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74,
-0x68, 0x65, 0x20, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x53, 0x65,
-0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65,
-0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c,
-0x61, 0x6e, 0x64, 0x73, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x53, 0x77, 0x61, 0x7a,
-0x69, 0x6c, 0x61, 0x6e, 0x64, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0x72,
-0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x54, 0x75, 0x72,
-0x6b, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x61, 0x69, 0x63, 0x6f, 0x73, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64,
-0x73, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69,
-0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x55, 0x2e, 0x53, 0x2e,
-0x20, 0x4f, 0x75, 0x74, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x56, 0x61, 0x6e,
-0x75, 0x61, 0x74, 0x75, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x49,
-0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x49, 0x73,
-0x6c, 0x61, 0x6e, 0x64, 0x73, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x5a, 0x69, 0x6d, 0x62, 0x61, 0x62, 0x77, 0x65, 0x49,
-0x73, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x4d, 0x61, 0x6e, 0x4a, 0x65, 0x72, 0x73, 0x65, 0x79, 0x53, 0x6f, 0x75, 0x74,
-0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x65, 0x73, 0x74, 0x69, 0x45, 0x65, 0x73, 0x74, 0x69, 0x66, 0xf8, 0x72,
-0x6f, 0x79, 0x73, 0x6b, 0x74, 0x46, 0xf8, 0x72, 0x6f, 0x79, 0x61, 0x72, 0x73, 0x75, 0x6f, 0x6d, 0x69, 0x53, 0x75, 0x6f,
-0x6d, 0x69, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x6c, 0x67, 0xe9,
-0x72, 0x69, 0x65, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x71, 0x75, 0x65, 0x42, 0xe9, 0x6e, 0x69, 0x6e, 0x42, 0x75, 0x72, 0x6b,
-0x69, 0x6e, 0x61, 0x20, 0x46, 0x61, 0x73, 0x6f, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x43, 0x61, 0x6d, 0x65, 0x72,
-0x6f, 0x75, 0x6e, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e,
-0x52, 0xe9, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x66, 0x72, 0x69,
-0x63, 0x61, 0x69, 0x6e, 0x65, 0x54, 0x63, 0x68, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6f, 0x72, 0x65, 0x73, 0x52, 0xe9, 0x70,
-0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x64, 0xe9, 0x6d, 0x6f, 0x63, 0x72, 0x61, 0x74, 0x69, 0x71, 0x75, 0x65,
-0x20, 0x64, 0x75, 0x20, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x2d, 0x42, 0x72, 0x61, 0x7a, 0x7a,
-0x61, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x43, 0xf4, 0x74, 0x65, 0x20, 0x64, 0x2019, 0x49, 0x76, 0x6f, 0x69, 0x72, 0x65, 0x44,
-0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x20, 0xe9, 0x71, 0x75, 0x61, 0x74, 0x6f,
-0x72, 0x69, 0x61, 0x6c, 0x65, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73,
-0x65, 0x50, 0x6f, 0x6c, 0x79, 0x6e, 0xe9, 0x73, 0x69, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65,
-0x47, 0x61, 0x62, 0x6f, 0x6e, 0x47, 0x75, 0x61, 0x64, 0x65, 0x6c, 0x6f, 0x75, 0x70, 0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9,
-0x65, 0x48, 0x61, 0xef, 0x74, 0x69, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x6f, 0x75, 0x72, 0x67, 0x4d, 0x61, 0x6c, 0x69,
-0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65,
-0x4d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x79, 0x6f, 0x74, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x61, 0x63, 0x6f,
-0x4d, 0x61, 0x72, 0x6f, 0x63, 0x4e, 0x6f, 0x75, 0x76, 0x65, 0x6c, 0x6c, 0x65, 0x2d, 0x43, 0x61, 0x6c, 0xe9, 0x64, 0x6f,
-0x6e, 0x69, 0x65, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x52, 0xe9, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x52, 0x77, 0x61, 0x6e, 0x64,
-0x61, 0x53, 0xe9, 0x6e, 0xe9, 0x67, 0x61, 0x6c, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20, 0x73, 0x75, 0x69,
-0x73, 0x73, 0x65, 0x53, 0x75, 0x69, 0x73, 0x73, 0x65, 0x53, 0x79, 0x72, 0x69, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x54, 0x75,
-0x6e, 0x69, 0x73, 0x69, 0x65, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x42, 0x61, 0x72, 0x74, 0x68, 0xe9, 0x6c, 0xe9, 0x6d,
-0x79, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x20, 0x5b, 0x70, 0x61, 0x72, 0x74, 0x69,
-0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x5d, 0x47, 0xe0, 0x69, 0x64, 0x68, 0x6c, 0x69, 0x67,
-0x41, 0x6e, 0x20, 0x52, 0xec, 0x6f, 0x67, 0x68, 0x61, 0x63, 0x68, 0x64, 0x20, 0x41, 0x6f, 0x6e, 0x61, 0x69, 0x63, 0x68,
-0x74, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x67, 0x6f, 0x45, 0x73, 0x70, 0x61, 0xf1, 0x61, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da,
-0x10d8, 0x10e1, 0x10d0, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10d5, 0x10d4, 0x10da, 0x10dd, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x44, 0x65,
-0x75, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0xd6, 0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x69, 0x63, 0x68, 0x69,
-0x73, 0x63, 0x68, 0x65, 0x73, 0x20, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0xd6, 0x73, 0x74, 0x65, 0x72, 0x72, 0x65,
-0x69, 0x63, 0x68, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x65, 0x6e, 0x4c, 0x69, 0x65, 0x63, 0x68, 0x74, 0x65, 0x6e, 0x73, 0x74,
-0x65, 0x69, 0x6e, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x75, 0x72, 0x67, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65,
-0x72, 0x20, 0x48, 0x6f, 0x63, 0x68, 0x64, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a,
-0x395, 0x3bb, 0x3bb, 0x3b7, 0x3bd, 0x3b9, 0x3ba, 0x3ac, 0x395, 0x3bb, 0x3bb, 0x3ac, 0x3b4, 0x3b1, 0x39a, 0x3cd, 0x3c0, 0x3c1, 0x3bf, 0x3c2,
-0x6b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c, 0x69, 0x73, 0x75, 0x74, 0x4b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c, 0x69, 0x74,
-0x20, 0x4e, 0x75, 0x6e, 0x61, 0x61, 0x74, 0xa97, 0xac1, 0xa9c, 0xab0, 0xabe, 0xaa4, 0xac0, 0xaad, 0xabe, 0xab0, 0xaa4, 0x48, 0x61,
-0x75, 0x73, 0x61, 0x4e, 0x61, 0x6a, 0x65, 0x72, 0x69, 0x79, 0x61, 0x47, 0x61, 0x6e, 0x61, 0x4e, 0x69, 0x6a, 0x61, 0x72,
-0x5e2, 0x5d1, 0x5e8, 0x5d9, 0x5ea, 0x5d9, 0x5e9, 0x5e8, 0x5d0, 0x5dc, 0x939, 0x93f, 0x928, 0x94d, 0x926, 0x940, 0x92d, 0x93e, 0x930, 0x924,
-0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x4d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x6f, 0x72, 0x73, 0x7a, 0xe1, 0x67, 0xed, 0x73,
-0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0xcd, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20, 0x49,
-0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x69, 0x6e, 0x74,
-0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x75, 0x61, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x61, 0x47, 0x61, 0x65, 0x69, 0x6c,
-0x67, 0x65, 0xc9, 0x69, 0x72, 0x65, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x6f, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x61,
-0x53, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x53, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x61, 0x65e5, 0x672c,
-0x8a9e, 0x65e5, 0x672c, 0xc95, 0xca8, 0xccd, 0xca8, 0xca1, 0xcad, 0xcbe, 0xcb0, 0xca4, 0x6a9, 0x672, 0x634, 0x64f, 0x631, 0x6c1, 0x650, 0x646,
-0x65b, 0x62f, 0x648, 0x633, 0x62a, 0x627, 0x646, 0x49b, 0x430, 0x437, 0x430, 0x49b, 0x20, 0x442, 0x456, 0x43b, 0x456, 0x49a, 0x430, 0x437,
-0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x4b, 0x69, 0x6e, 0x79, 0x61, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x41a, 0x44b, 0x440,
-0x433, 0x44b, 0x437, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0xd55c, 0xad6d, 0xc5b4, 0xb300, 0xd55c, 0xbbfc, 0xad6d,
-0xc870, 0xc120, 0x20, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0x20, 0xc778, 0xbbfc, 0x20, 0xacf5, 0xd654, 0xad6d, 0x49, 0x6b, 0x69, 0x72, 0x75, 0x6e,
-0x64, 0x69, 0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0xea5, 0xeb2, 0xea7, 0xeaa, 0x2e, 0xe9b, 0x2e, 0xe9b, 0x20, 0xea5,
-0xeb2, 0xea7, 0x6c, 0x61, 0x74, 0x76, 0x69, 0x65, 0x161, 0x75, 0x4c, 0x61, 0x74, 0x76, 0x69, 0x6a, 0x61, 0x6c, 0x69, 0x6e,
-0x67, 0xe1, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61,
-0x74, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0xf3, 0x41, 0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x52,
-0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x41, 0x66, 0x72, 0xed, 0x6b, 0x61, 0x20, 0x79, 0x61,
-0x20, 0x4b, 0xe1, 0x74, 0x69, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x69, 0x173, 0x4c, 0x69,
-0x65, 0x74, 0x75, 0x76, 0x61, 0x43c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x41c, 0x430, 0x43a, 0x435, 0x434,
-0x43e, 0x43d, 0x438, 0x458, 0x430, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x4d, 0x61, 0x64, 0x61, 0x67, 0x61, 0x73,
-0x69, 0x6b, 0x61, 0x72, 0x61, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20, 0x4d, 0x65, 0x6c, 0x61, 0x79, 0x75, 0x4d, 0x61,
-0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x75, 0x72,
-0x61, 0xd2e, 0xd32, 0xd2f, 0xd3e, 0xd33, 0xd02, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0x4d, 0x61, 0x6c, 0x74, 0x69, 0x92e, 0x930,
-0x93e, 0x920, 0x940, 0x43c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x41c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x928, 0x947, 0x92a, 0x93e, 0x932,
-0x940, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f, 0x6b, 0x6d, 0xe5, 0x6c, 0x4e, 0x6f,
-0x72, 0x67, 0x65, 0xb13, 0xb21, 0xb3c, 0xb3f, 0xb06, 0xb2d, 0xb3e, 0xb30, 0xb24, 0x67e, 0x69a, 0x62a, 0x648, 0x627, 0x641, 0x63a, 0x627,
-0x646, 0x633, 0x62a, 0x627, 0x646, 0x641, 0x627, 0x631, 0x633, 0x6cc, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x62f, 0x631, 0x6cc, 0x70, 0x6f,
-0x6c, 0x73, 0x6b, 0x69, 0x50, 0x6f, 0x6c, 0x73, 0x6b, 0x61, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x20,
-0x64, 0x6f, 0x20, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x70, 0x6f, 0x72, 0x74, 0x75,
-0x67, 0x75, 0xea, 0x73, 0x41, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x43, 0x61, 0x62, 0x6f, 0x20, 0x56, 0x65, 0x72, 0x64, 0x65,
-0x54, 0x69, 0x6d, 0x6f, 0x72, 0x2d, 0x4c, 0x65, 0x73, 0x74, 0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x2d, 0x42, 0x69, 0x73,
-0x73, 0x61, 0x75, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x2c, 0x20, 0x52, 0x41, 0x45, 0x20, 0x64, 0x61, 0x20, 0x43, 0x68, 0x69,
-0x6e, 0x61, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea,
-0x73, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x75, 0x50, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x61, 0x6c, 0x53, 0xe3, 0x6f,
-0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0xa2a, 0xa70, 0xa1c, 0xa3e,
-0xa2c, 0xa40, 0xa2d, 0xa3e, 0xa30, 0xa24, 0x67e, 0x646, 0x62c, 0x627, 0x628, 0x67e, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x72, 0x75, 0x6d,
-0x61, 0x6e, 0x74, 0x73, 0x63, 0x68, 0x53, 0x76, 0x69, 0x7a, 0x72, 0x61, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x103, 0x52, 0x6f,
-0x6d, 0xe2, 0x6e, 0x69, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x20, 0x4d, 0x6f, 0x6c, 0x64, 0x6f,
-0x76, 0x61, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x44f, 0x41a, 0x430, 0x437, 0x430, 0x445,
-0x441, 0x442, 0x430, 0x43d, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x438, 0x44f, 0x41c, 0x43e, 0x43b, 0x434, 0x43e, 0x432, 0x430, 0x423,
-0x43a, 0x440, 0x430, 0x438, 0x43d, 0x430, 0x53, 0xe4, 0x6e, 0x67, 0xf6, 0x4b, 0xf6, 0x64, 0xf6, 0x72, 0xf6, 0x73, 0xea, 0x73,
-0x65, 0x20, 0x74, 0xee, 0x20, 0x42, 0xea, 0x61, 0x66, 0x72, 0xee, 0x6b, 0x61, 0x421, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x421,
-0x440, 0x431, 0x438, 0x458, 0x430, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x411, 0x43e, 0x441, 0x43d, 0x430, 0x20, 0x438, 0x20, 0x425,
-0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x438, 0x43d, 0x430, 0x426, 0x440, 0x43d, 0x430, 0x20, 0x413, 0x43e, 0x440, 0x430, 0x53,
-0x72, 0x70, 0x73, 0x6b, 0x69, 0x43, 0x72, 0x6e, 0x61, 0x20, 0x47, 0x6f, 0x72, 0x61, 0x53, 0x72, 0x62, 0x69, 0x6a, 0x61,
-0x438, 0x440, 0x43e, 0x43d, 0x413, 0x443, 0x44b, 0x440, 0x434, 0x437, 0x44b, 0x441, 0x442, 0x43e, 0x43d, 0x423, 0x4d5, 0x440, 0x4d5, 0x441,
-0x435, 0x53, 0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x53, 0x65, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x63, 0x68, 0x69, 0x53,
-0x68, 0x6f, 0x6e, 0x61, 0xdc3, 0xdd2, 0xd82, 0xdc4, 0xdbd, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0xdc0,
-0x53, 0x69, 0x73, 0x77, 0x61, 0x74, 0x69, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f,
-0x76, 0x65, 0x6e, 0x73, 0x6b, 0x6f, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x161, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f,
-0x76, 0x65, 0x6e, 0x69, 0x6a, 0x61, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61,
-0x6c, 0x69, 0x79, 0x61, 0x4a, 0x61, 0x62, 0x75, 0x75, 0x74, 0x69, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x69, 0x79, 0x61, 0x4b,
-0x69, 0x69, 0x6e, 0x69, 0x79, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x45, 0x73, 0x70,
-0x61, 0xf1, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x42,
-0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x43,
-0x6f, 0x73, 0x74, 0x61, 0x20, 0x52, 0x69, 0x63, 0x61, 0x43, 0x75, 0x62, 0x61, 0x52, 0x65, 0x70, 0xfa, 0x62, 0x6c, 0x69,
-0x63, 0x61, 0x20, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x61, 0x45, 0x63, 0x75, 0x61, 0x64, 0x6f, 0x72,
-0x45, 0x6c, 0x20, 0x53, 0x61, 0x6c, 0x76, 0x61, 0x64, 0x6f, 0x72, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x20, 0x45, 0x63,
-0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x48, 0x6f, 0x6e,
-0x64, 0x75, 0x72, 0x61, 0x73, 0x4d, 0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61,
-0x50, 0x61, 0x6e, 0x61, 0x6d, 0xe1, 0x50, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x50, 0x65, 0x72, 0xfa, 0x46, 0x69,
-0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f,
-0x73, 0x55, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x56, 0x65, 0x6e, 0x65, 0x7a, 0x75, 0x65, 0x6c, 0x61, 0x49, 0x73, 0x6c,
-0x61, 0x73, 0x20, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x6c,
-0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x4c, 0x61, 0x74, 0x69, 0x6e, 0x6f,
-0x61, 0x6d, 0xe9, 0x72, 0x69, 0x63, 0x61, 0x43, 0x65, 0x75, 0x74, 0x61, 0x20, 0x79, 0x20, 0x4d, 0x65, 0x6c, 0x69, 0x6c,
-0x6c, 0x61, 0x4b, 0x69, 0x73, 0x77, 0x61, 0x68, 0x69, 0x6c, 0x69, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x53, 0x76,
-0x65, 0x72, 0x69, 0x67, 0x65, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0xc5, 0x6c, 0x61, 0x6e, 0x64, 0x422, 0x43e, 0x4b7,
-0x438, 0x43a, 0x4e3, 0x422, 0x43e, 0x4b7, 0x438, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0xba4, 0xbae, 0xbbf, 0xbb4, 0xbcd, 0xb87, 0xba8,
-0xbcd, 0xba4, 0xbbf, 0xbaf, 0xbbe, 0xbae, 0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf, 0xbbe, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa,
-0xbc2, 0xbb0, 0xbcd, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0xc24, 0xc46, 0xc32, 0xc41, 0xc17, 0xc41, 0xc2d, 0xc3e, 0xc30, 0xc24, 0x20,
-0xc26, 0xc47, 0xc36, 0xc02, 0xe44, 0xe17, 0xe22, 0xf54, 0xf7c, 0xf51, 0xf0b, 0xf66, 0xf90, 0xf51, 0xf0b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf53,
-0xf42, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0x1275, 0x130d, 0x122d, 0x129b, 0x12a4, 0x122d, 0x1275, 0x122b, 0x6c, 0x65, 0x61, 0x20,
-0x66, 0x61, 0x6b, 0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x58, 0x69, 0x74, 0x73, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0xfc, 0x72,
-0x6b, 0xe7, 0x65, 0x54, 0xfc, 0x72, 0x6b, 0x69, 0x79, 0x65, 0x47, 0xfc, 0x6e, 0x65, 0x79, 0x20, 0x4b, 0x131, 0x62, 0x72,
-0x131, 0x73, 0x20, 0x52, 0x75, 0x6d, 0x20, 0x4b, 0x65, 0x73, 0x69, 0x6d, 0x69, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441,
-0x44c, 0x43a, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x430, 0x627, 0x631, 0x62f, 0x648, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627,
-0x646, 0x628, 0x6be, 0x627, 0x631, 0x62a, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e,
-0x43d, 0x627, 0x648, 0x632, 0x628, 0x6cc, 0x6a9, 0x6f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b, 0x63, 0x68, 0x61, 0x4f, 0x2bb, 0x7a, 0x62,
-0x65, 0x6b, 0x69, 0x73, 0x74, 0x6f, 0x6e, 0x54, 0x69, 0x1ebf, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x56, 0x69, 0x1ec7,
-0x74, 0x20, 0x4e, 0x61, 0x6d, 0x43, 0x79, 0x6d, 0x72, 0x61, 0x65, 0x67, 0x79, 0x20, 0x44, 0x65, 0x79, 0x72, 0x6e, 0x61,
-0x73, 0x20, 0x55, 0x6e, 0x65, 0x64, 0x69, 0x67, 0x69, 0x73, 0x69, 0x58, 0x68, 0x6f, 0x73, 0x61, 0xc8, 0x64, 0xe8, 0x20,
-0x59, 0x6f, 0x72, 0xf9, 0x62, 0xe1, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x4e, 0xe0, 0xec, 0x6a,
-0xed, 0x72, 0xed, 0xe0, 0x69, 0x73, 0x69, 0x5a, 0x75, 0x6c, 0x75, 0x69, 0x4e, 0x69, 0x6e, 0x67, 0x69, 0x7a, 0x69, 0x6d,
-0x75, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x6e, 0x79, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x4e, 0x6f, 0x72, 0x65, 0x67,
-0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x438, 0x47, 0x61, 0x65, 0x6c,
-0x67, 0x52, 0x79, 0x77, 0x76, 0x61, 0x6e, 0x65, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x79, 0x73, 0x6b, 0x65, 0x72, 0x6e, 0x65,
-0x77, 0x65, 0x6b, 0x41, 0x6b, 0x61, 0x6e, 0x47, 0x61, 0x61, 0x6e, 0x61, 0x915, 0x94b, 0x902, 0x915, 0x923, 0x940, 0x49, 0x67,
-0x62, 0x6f, 0x4b, 0x69, 0x6b, 0x61, 0x6d, 0x62, 0x61, 0x1265, 0x120a, 0x1295, 0x1275, 0x130d, 0x1228, 0x66, 0x75, 0x72, 0x6c, 0x61,
-0x6e, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x65, 0x54, 0x73, 0x68, 0x69, 0x76, 0x65, 0x6e, 0x1e13, 0x61, 0x65, 0x28b, 0x65, 0x67,
-0x62, 0x65, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x20, 0x6e,
-0x75, 0x74, 0x6f, 0x6d, 0x65, 0x12c8, 0x120b, 0x12ed, 0x1273, 0x1271, 0x2bb, 0x14c, 0x6c, 0x65, 0x6c, 0x6f, 0x20, 0x48, 0x61, 0x77,
-0x61, 0x69, 0x2bb, 0x69, 0x2bb, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x75, 0x69, 0x20, 0x50, 0x16b, 0x20,
-0x2bb, 0x49, 0x61, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73,
-0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x74, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77,
-0x69, 0x69, 0x7a, 0xa188, 0xa320, 0xa259, 0xa34f, 0xa1e9, 0x69, 0x73, 0x69, 0x4e, 0x64, 0x65, 0x62, 0x65, 0x6c, 0x65, 0x53, 0x65,
-0x73, 0x6f, 0x74, 0x68, 0x6f, 0x20, 0x73, 0x61, 0x20, 0x4c, 0x65, 0x62, 0x6f, 0x61, 0x64, 0x61, 0x76, 0x76, 0x69, 0x73,
-0xe1, 0x6d, 0x65, 0x67, 0x69, 0x65, 0x6c, 0x6c, 0x61, 0x4e, 0x6f, 0x72, 0x67, 0x61, 0x53, 0x75, 0x6f, 0x70, 0x6d, 0x61,
-0x45, 0x6b, 0x65, 0x67, 0x75, 0x73, 0x69, 0x69, 0x4b, 0x69, 0x74, 0x61, 0x69, 0x74, 0x61, 0x50, 0x75, 0x6c, 0x61, 0x61,
-0x72, 0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x61, 0x6c, 0x47, 0x69, 0x6b, 0x75, 0x79, 0x75, 0x4b, 0x69, 0x73, 0x61, 0x6d,
-0x70, 0x75, 0x72, 0x73, 0x65, 0x6e, 0x61, 0x4b, 0x69, 0x68, 0x6f, 0x72, 0x6f, 0x6d, 0x62, 0x6f, 0x2d5c, 0x2d30, 0x2d4e, 0x2d30,
-0x2d63, 0x2d49, 0x2d56, 0x2d5c, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x74, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x67, 0x68, 0x74, 0x6c,
-0x6d, 0x263, 0x72, 0x69, 0x62, 0x54, 0x61, 0x71, 0x62, 0x61, 0x79, 0x6c, 0x69, 0x74, 0x4c, 0x65, 0x7a, 0x7a, 0x61, 0x79,
-0x65, 0x72, 0x52, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x6b, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x62, 0x65, 0x6e, 0x61, 0x48, 0x75,
-0x74, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x79, 0x69, 0x76, 0x75, 0x6e, 0x6a, 0x6f, 0x62, 0x61, 0x6d, 0x61,
-0x6e, 0x61, 0x6b, 0x61, 0x6e, 0x4b, 0x129, 0x65, 0x6d, 0x62, 0x75, 0x13e3, 0x13b3, 0x13a9, 0x13a0, 0x13b9, 0x13f0, 0x13df, 0x6b, 0x72,
-0x65, 0x6f, 0x6c, 0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x4d, 0x6f, 0x72, 0x69, 0x73, 0x43, 0x68, 0x69,
-0x6d, 0x61, 0x6b, 0x6f, 0x6e, 0x64, 0x65, 0x4b, 0x268, 0x6c, 0x61, 0x61, 0x6e, 0x67, 0x69, 0x54, 0x61, 0x61, 0x6e, 0x73,
-0x61, 0x6e, 0xed, 0x61, 0x4c, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x49, 0x63,
-0x68, 0x69, 0x62, 0x65, 0x6d, 0x62, 0x61, 0x6b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x4b,
-0x61, 0x62, 0x75, 0x20, 0x56, 0x65, 0x72, 0x64, 0x69, 0x4b, 0x129, 0x6d, 0x129, 0x72, 0x169, 0x4b, 0x61, 0x6c, 0x65, 0x6e,
-0x6a, 0x69, 0x6e, 0x45, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x68, 0x6f, 0x65, 0x6b,
-0x68, 0x6f, 0x65, 0x67, 0x6f, 0x77, 0x61, 0x62, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x62, 0x4b, 0x69, 0x6d, 0x61,
-0x63, 0x68, 0x61, 0x6d, 0x65, 0x4b, 0xf6, 0x6c, 0x73, 0x63, 0x68, 0x44, 0x6f, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61,
-0x6e, 0x64, 0x4d, 0x61, 0x61, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x61, 0x4f, 0x6c, 0x75, 0x73, 0x6f, 0x67, 0x61,
-0x4c, 0x75, 0x6c, 0x75, 0x68, 0x69, 0x61, 0x4b, 0x69, 0x70, 0x61, 0x72, 0x65, 0x54, 0x61, 0x64, 0x68, 0x61, 0x6e, 0x69,
-0x61, 0x4b, 0x69, 0x74, 0x65, 0x73, 0x6f, 0x4b, 0x65, 0x6e, 0x69, 0x61, 0x4b, 0x6f, 0x79, 0x72, 0x61, 0x20, 0x63, 0x69,
-0x69, 0x6e, 0x69, 0x4d, 0x61, 0x61, 0x6c, 0x69, 0x4b, 0x69, 0x72, 0x75, 0x77, 0x61, 0x44, 0x68, 0x6f, 0x6c, 0x75, 0x6f,
-0x52, 0x75, 0x6b, 0x69, 0x67, 0x61, 0x54, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x263, 0x74, 0x4d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b,
-0x4b, 0x6f, 0x79, 0x72, 0x61, 0x62, 0x6f, 0x72, 0x6f, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0x4b, 0x69, 0x73, 0x68, 0x61,
-0x6d, 0x62, 0x61, 0x61, 0x92c, 0x921, 0x93c, 0x94b, 0x54, 0x73, 0x68, 0x69, 0x6c, 0x75, 0x62, 0x61, 0x44, 0x69, 0x74, 0x75,
-0x6e, 0x67, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x41, 0x67, 0x68, 0x65, 0x6d, 0x4b, 0xe0, 0x6d,
-0xe0, 0x6c, 0xfb, 0x14b, 0x181, 0xe0, 0x73, 0xe0, 0x61, 0x4b, 0xe0, 0x6d, 0x25b, 0x300, 0x72, 0xfb, 0x6e, 0x5a, 0x61, 0x72,
-0x6d, 0x61, 0x63, 0x69, 0x69, 0x6e, 0x65, 0x4e, 0x69, 0x17e, 0x65, 0x72, 0x64, 0x75, 0xe1, 0x6c, 0xe1, 0x6a, 0x6f, 0x6f,
-0x6c, 0x61, 0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x77, 0x6f, 0x6e, 0x64, 0x6f, 0x4b, 0x61, 0x6d, 0x259, 0x72,
-0xfa, 0x6e, 0x72, 0x69, 0x6b, 0x70, 0x61, 0x6b, 0x61, 0x6d, 0x25b, 0x72, 0xfa, 0x6e, 0x4d, 0x61, 0x6b, 0x75, 0x61, 0x55,
-0x6d, 0x6f, 0x7a, 0x61, 0x6d, 0x62, 0x69, 0x6b, 0x69, 0x4d, 0x55, 0x4e, 0x44, 0x41, 0x14a, 0x6b, 0x61, 0x6d, 0x65, 0x72,
-0x75, 0x14b, 0x4b, 0x77, 0x61, 0x73, 0x69, 0x6f, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x6e, 0x54, 0x68, 0x6f, 0x6b, 0x20,
-0x4e, 0x61, 0x74, 0x68, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x441, 0x430, 0x445, 0x430, 0x20, 0x442, 0x44b, 0x43b, 0x430, 0x49, 0x73,
-0x68, 0x69, 0x73, 0x61, 0x6e, 0x67, 0x75, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x4b, 0x69, 0x73, 0x77,
-0x61, 0x68, 0x69, 0x6c, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x4a, 0x61, 0x6d, 0x68, 0x75, 0x72,
-0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x69, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x73, 0x69, 0x61, 0x20, 0x79, 0x61,
-0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x54, 0x61, 0x73, 0x61, 0x77, 0x61, 0x71, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0xa559,
-0xa524, 0xa55e, 0xa524, 0xa52b, 0xa569, 0x56, 0x61, 0x69, 0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x57, 0x61, 0x6c, 0x73,
-0x65, 0x72, 0x53, 0x63, 0x68, 0x77, 0x69, 0x7a, 0x6e, 0x75, 0x61, 0x73, 0x75, 0x65, 0x4b, 0x65, 0x6d, 0x65, 0x6c, 0xfa,
-0x6e, 0x61, 0x73, 0x74, 0x75, 0x72, 0x69, 0x61, 0x6e, 0x75, 0x4e, 0x64, 0x61, 0xa78c, 0x61, 0x4b, 0x61, 0x6d, 0x25b, 0x6c,
-0xfb, 0x6e, 0x6b, 0x61, 0x6b, 0x254, 0x4b, 0x61, 0x6d, 0x25b, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x2bc, 0x4b, 0x61,
-0x6d, 0x61, 0x6c, 0x75, 0x6e, 0x53, 0x68, 0x77, 0xf3, 0x14b, 0xf2, 0x20, 0x6e, 0x67, 0x69, 0x65, 0x6d, 0x62, 0x254, 0x254,
-0x6e, 0x4b, 0xe0, 0x6d, 0x61, 0x6c, 0xfb, 0x6d
+0x69, 0x70, 0x53, 0x68, 0x71, 0x69, 0x70, 0xeb, 0x72, 0x69, 0x61, 0x4d, 0x61, 0x71, 0x65, 0x64, 0x6f, 0x6e, 0x69, 0x4b,
+0x6f, 0x73, 0x6f, 0x76, 0xeb, 0x12a0, 0x121b, 0x122d, 0x129b, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a,
+0x629, 0x645, 0x635, 0x631, 0x627, 0x644, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x627, 0x644, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x62a, 0x634,
+0x627, 0x62f, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x623, 0x631, 0x64a,
+0x62a, 0x631, 0x64a, 0x627, 0x627, 0x644, 0x639, 0x631, 0x627, 0x642, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x627, 0x644, 0x623,
+0x631, 0x62f, 0x646, 0x627, 0x644, 0x643, 0x648, 0x64a, 0x62a, 0x644, 0x628, 0x646, 0x627, 0x646, 0x644, 0x64a, 0x628, 0x64a, 0x627, 0x645,
+0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x627, 0x627, 0x644, 0x645, 0x63a, 0x631, 0x628, 0x639, 0x64f, 0x645, 0x627, 0x646, 0x641,
+0x644, 0x633, 0x637, 0x64a, 0x646, 0x642, 0x637, 0x631, 0x627, 0x644, 0x645, 0x645, 0x644, 0x643, 0x629, 0x20, 0x627, 0x644, 0x639, 0x631,
+0x628, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x629, 0x627, 0x644, 0x635, 0x648, 0x645, 0x627, 0x644, 0x627,
+0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x633, 0x648, 0x631, 0x64a, 0x627, 0x62a, 0x648, 0x646, 0x633, 0x627, 0x644, 0x625, 0x645, 0x627,
+0x631, 0x627, 0x62a, 0x20, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x645, 0x62a, 0x62d, 0x62f, 0x629, 0x627,
+0x644, 0x635, 0x62d, 0x631, 0x627, 0x621, 0x20, 0x627, 0x644, 0x63a, 0x631, 0x628, 0x64a, 0x629, 0x627, 0x644, 0x64a, 0x645, 0x646, 0x570,
+0x561, 0x575, 0x565, 0x580, 0x565, 0x576, 0x540, 0x561, 0x575, 0x561, 0x57d, 0x57f, 0x561, 0x576, 0x985, 0x9b8, 0x9ae, 0x9c0, 0x9af, 0x9bc,
+0x9be, 0x9ad, 0x9be, 0x9f0, 0x9a4, 0x61, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x63, 0x61, 0x41, 0x7a, 0x259,
+0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x410, 0x437, 0x4d9, 0x440, 0x431, 0x430, 0x458, 0x4b9, 0x430, 0x43d, 0x65, 0x75, 0x73,
+0x6b, 0x61, 0x72, 0x61, 0x45, 0x73, 0x70, 0x61, 0x69, 0x6e, 0x69, 0x61, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9ac, 0x9be, 0x982,
+0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0xf62, 0xfab, 0xf7c, 0xf44, 0xf0b, 0xf41, 0xf60, 0xf56, 0xfb2, 0xf74, 0xf42,
+0x62, 0x72, 0x65, 0x7a, 0x68, 0x6f, 0x6e, 0x65, 0x67, 0x46, 0x72, 0x61, 0xf1, 0x73, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440,
+0x441, 0x43a, 0x438, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x438, 0x44f, 0x1017, 0x1019, 0x102c, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c,
+0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x430, 0x44f, 0x411, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x44c, 0x1781, 0x17d2,
+0x1798, 0x17c2, 0x179a, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787, 0x17b6, 0x63, 0x61, 0x74, 0x61, 0x6c, 0xe0, 0x45, 0x73, 0x70, 0x61,
+0x6e, 0x79, 0x61, 0x41, 0x6e, 0x64, 0x6f, 0x72, 0x72, 0x61, 0x7b80, 0x4f53, 0x4e2d, 0x6587, 0x4e2d, 0x56fd, 0x4e2d, 0x56fd, 0x9999, 0x6e2f,
+0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x4e2d, 0x56fd, 0x6fb3, 0x95e8, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x65b0, 0x52a0, 0x5761, 0x7e41, 0x9ad4, 0x4e2d,
+0x6587, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171, 0x548c, 0x570b, 0x9999, 0x6e2f, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171,
+0x548c, 0x570b, 0x6fb3, 0x9580, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x53f0, 0x7063, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x48,
+0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x42, 0x6f, 0x73, 0x6e, 0x61, 0x20, 0x69, 0x20, 0x48, 0x65, 0x72, 0x63, 0x65,
+0x67, 0x6f, 0x76, 0x69, 0x6e, 0x61, 0x10d, 0x65, 0x161, 0x74, 0x69, 0x6e, 0x61, 0x10c, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x72,
+0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x6b, 0x61, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x44, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b,
+0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x41,
+0x72, 0x75, 0x62, 0x61, 0x56, 0x6c, 0x61, 0x61, 0x6d, 0x73, 0x42, 0x65, 0x6c, 0x67, 0x69, 0xeb, 0x43, 0x75, 0x72, 0x61,
+0xe7, 0x61, 0x6f, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x61, 0x72,
+0x74, 0x65, 0x6e, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65,
+0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0xd801, 0xdc00, 0xd801, 0xdc4d, 0xd801, 0xdc4a, 0xd801, 0xdc2e, 0xd801, 0xdc47, 0xd801, 0xdc0f,
+0xd801, 0xdc2d, 0xd801, 0xdc4c, 0xd801, 0xdc34, 0xd801, 0xdc3b, 0xd801, 0xdc32, 0xd801, 0xdc3c, 0x20, 0xd801, 0xdc1d, 0xd801, 0xdc3b, 0xd801, 0xdc29, 0xd801,
+0xdc3b, 0xd801, 0xdc45, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x53,
+0x61, 0x6d, 0x6f, 0x61, 0x41, 0x6e, 0x74, 0x69, 0x67, 0x75, 0x61, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x42, 0x61, 0x72, 0x62,
+0x75, 0x64, 0x61, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73,
+0x68, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x61, 0x73, 0x42, 0x61, 0x72,
+0x62, 0x61, 0x64, 0x6f, 0x73, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x75, 0x6d, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x42, 0x65,
+0x72, 0x6d, 0x75, 0x64, 0x61, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6f,
+0x6e, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x43, 0x61, 0x6e,
+0x61, 0x64, 0x61, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x44, 0x6f, 0x6d,
+0x69, 0x6e, 0x69, 0x63, 0x61, 0x46, 0x69, 0x6a, 0x69, 0x47, 0x75, 0x65, 0x72, 0x6e, 0x73, 0x65, 0x79, 0x47, 0x61, 0x6d,
+0x62, 0x69, 0x61, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x47, 0x72, 0x65,
+0x6e, 0x61, 0x64, 0x61, 0x47, 0x75, 0x61, 0x6d, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b,
+0x6f, 0x6e, 0x67, 0x20, 0x53, 0x41, 0x52, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x49, 0x72,
+0x65, 0x6c, 0x61, 0x6e, 0x64, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x69, 0x72,
+0x69, 0x62, 0x61, 0x74, 0x69, 0x4c, 0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x4d,
+0x61, 0x64, 0x61, 0x67, 0x61, 0x73, 0x63, 0x61, 0x72, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x4d, 0x61, 0x6c, 0x74, 0x61,
+0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x6c, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4d, 0x61, 0x75, 0x72,
+0x69, 0x74, 0x69, 0x75, 0x73, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x4e, 0x61, 0x6d, 0x69, 0x62,
+0x69, 0x61, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61,
+0x4e, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x61, 0x20, 0x49, 0x73, 0x6c,
+0x61, 0x6e, 0x64, 0x73, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x50, 0x61, 0x6c, 0x61, 0x75, 0x50, 0x61, 0x70,
+0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70,
+0x69, 0x6e, 0x65, 0x73, 0x50, 0x75, 0x65, 0x72, 0x74, 0x6f, 0x20, 0x52, 0x69, 0x63, 0x6f, 0x53, 0x61, 0x69, 0x6e, 0x74,
+0x20, 0x4b, 0x69, 0x74, 0x74, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x4e, 0x65, 0x76, 0x69, 0x73, 0x53, 0x61, 0x69, 0x6e,
+0x74, 0x20, 0x4c, 0x75, 0x63, 0x69, 0x61, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x74,
+0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x53,
+0x61, 0x6d, 0x6f, 0x61, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61,
+0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x53, 0x6f, 0x6c, 0x6f, 0x6d,
+0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69,
+0x63, 0x61, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x6c, 0x61, 0x6e, 0x64, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x54,
+0x6f, 0x6e, 0x67, 0x61, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62,
+0x61, 0x67, 0x6f, 0x54, 0x75, 0x72, 0x6b, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x61, 0x69, 0x63, 0x6f, 0x73, 0x20,
+0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68,
+0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, 0x69, 0x6e, 0x67, 0x64,
+0x6f, 0x6d, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x4f, 0x75, 0x74, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x49, 0x73, 0x6c, 0x61,
+0x6e, 0x64, 0x73, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x56, 0x69,
+0x72, 0x67, 0x69, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x56, 0x69, 0x72,
+0x67, 0x69, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x5a, 0x69, 0x6d,
+0x62, 0x61, 0x62, 0x77, 0x65, 0x49, 0x73, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x4d, 0x61, 0x6e, 0x4a, 0x65, 0x72, 0x73,
+0x65, 0x79, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x65, 0x73, 0x74, 0x69, 0x45, 0x65,
+0x73, 0x74, 0x69, 0x66, 0xf8, 0x72, 0x6f, 0x79, 0x73, 0x6b, 0x74, 0x46, 0xf8, 0x72, 0x6f, 0x79, 0x61, 0x72, 0x73, 0x75,
+0x6f, 0x6d, 0x69, 0x53, 0x75, 0x6f, 0x6d, 0x69, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x46, 0x72, 0x61, 0x6e,
+0x63, 0x65, 0x41, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x71, 0x75, 0x65, 0x42, 0xe9, 0x6e,
+0x69, 0x6e, 0x42, 0x75, 0x72, 0x6b, 0x69, 0x6e, 0x61, 0x20, 0x46, 0x61, 0x73, 0x6f, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64,
+0x69, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x75, 0x6e, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20, 0x63, 0x61,
+0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x52, 0xe9, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x63, 0x65, 0x6e,
+0x74, 0x72, 0x61, 0x66, 0x72, 0x69, 0x63, 0x61, 0x69, 0x6e, 0x65, 0x54, 0x63, 0x68, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6f,
+0x72, 0x65, 0x73, 0x52, 0xe9, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x64, 0xe9, 0x6d, 0x6f, 0x63, 0x72,
+0x61, 0x74, 0x69, 0x71, 0x75, 0x65, 0x20, 0x64, 0x75, 0x20, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x43, 0x6f, 0x6e, 0x67, 0x6f,
+0x2d, 0x42, 0x72, 0x61, 0x7a, 0x7a, 0x61, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x43, 0xf4, 0x74, 0x65, 0x20, 0x64, 0x2019, 0x49,
+0x76, 0x6f, 0x69, 0x72, 0x65, 0x44, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x20,
+0xe9, 0x71, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x65, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x65, 0x20, 0x66, 0x72,
+0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x50, 0x6f, 0x6c, 0x79, 0x6e, 0xe9, 0x73, 0x69, 0x65, 0x20, 0x66, 0x72, 0x61,
+0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x47, 0x61, 0x62, 0x6f, 0x6e, 0x47, 0x75, 0x61, 0x64, 0x65, 0x6c, 0x6f, 0x75, 0x70,
+0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x48, 0x61, 0xef, 0x74, 0x69, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x6f, 0x75,
+0x72, 0x67, 0x4d, 0x61, 0x6c, 0x69, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4d, 0x61, 0x75, 0x72,
+0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x79, 0x6f, 0x74, 0x74, 0x65,
+0x4d, 0x6f, 0x6e, 0x61, 0x63, 0x6f, 0x4d, 0x61, 0x72, 0x6f, 0x63, 0x4e, 0x6f, 0x75, 0x76, 0x65, 0x6c, 0x6c, 0x65, 0x2d,
+0x43, 0x61, 0x6c, 0xe9, 0x64, 0x6f, 0x6e, 0x69, 0x65, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x52, 0xe9, 0x75, 0x6e, 0x69, 0x6f,
+0x6e, 0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x53, 0xe9, 0x6e, 0xe9, 0x67, 0x61, 0x6c, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61,
+0x69, 0x73, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x53, 0x75, 0x69, 0x73, 0x73, 0x65, 0x53, 0x79, 0x72, 0x69, 0x65,
+0x54, 0x6f, 0x67, 0x6f, 0x54, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x42, 0x61, 0x72,
+0x74, 0x68, 0xe9, 0x6c, 0xe9, 0x6d, 0x79, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x20,
+0x5b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x5d, 0x47, 0xe0,
+0x69, 0x64, 0x68, 0x6c, 0x69, 0x67, 0x41, 0x6e, 0x20, 0x52, 0xec, 0x6f, 0x67, 0x68, 0x61, 0x63, 0x68, 0x64, 0x20, 0x41,
+0x6f, 0x6e, 0x61, 0x69, 0x63, 0x68, 0x74, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x67, 0x6f, 0x45, 0x73, 0x70, 0x61, 0xf1, 0x61,
+0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x10e1, 0x10d0, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10d5, 0x10d4, 0x10da, 0x10dd, 0x44, 0x65, 0x75,
+0x74, 0x73, 0x63, 0x68, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0xd6, 0x73, 0x74, 0x65, 0x72,
+0x72, 0x65, 0x69, 0x63, 0x68, 0x69, 0x73, 0x63, 0x68, 0x65, 0x73, 0x20, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0xd6,
+0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x69, 0x63, 0x68, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x65, 0x6e, 0x4c, 0x69, 0x65, 0x63,
+0x68, 0x74, 0x65, 0x6e, 0x73, 0x74, 0x65, 0x69, 0x6e, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x75, 0x72, 0x67, 0x53, 0x63,
+0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x48, 0x6f, 0x63, 0x68, 0x64, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x53,
+0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x395, 0x3bb, 0x3bb, 0x3b7, 0x3bd, 0x3b9, 0x3ba, 0x3ac, 0x395, 0x3bb, 0x3bb, 0x3ac, 0x3b4, 0x3b1,
+0x39a, 0x3cd, 0x3c0, 0x3c1, 0x3bf, 0x3c2, 0x6b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c, 0x69, 0x73, 0x75, 0x74, 0x4b, 0x61, 0x6c,
+0x61, 0x61, 0x6c, 0x6c, 0x69, 0x74, 0x20, 0x4e, 0x75, 0x6e, 0x61, 0x61, 0x74, 0xa97, 0xac1, 0xa9c, 0xab0, 0xabe, 0xaa4, 0xac0,
+0xaad, 0xabe, 0xab0, 0xaa4, 0x48, 0x61, 0x75, 0x73, 0x61, 0x4e, 0x61, 0x6a, 0x65, 0x72, 0x69, 0x79, 0x61, 0x47, 0x61, 0x6e,
+0x61, 0x4e, 0x69, 0x6a, 0x61, 0x72, 0x5e2, 0x5d1, 0x5e8, 0x5d9, 0x5ea, 0x5d9, 0x5e9, 0x5e8, 0x5d0, 0x5dc, 0x939, 0x93f, 0x928, 0x94d,
+0x926, 0x940, 0x92d, 0x93e, 0x930, 0x924, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x4d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x6f, 0x72,
+0x73, 0x7a, 0xe1, 0x67, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0xcd, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x42, 0x61,
+0x68, 0x61, 0x73, 0x61, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65,
+0x73, 0x69, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x75, 0x61, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69,
+0x61, 0x47, 0x61, 0x65, 0x69, 0x6c, 0x67, 0x65, 0xc9, 0x69, 0x72, 0x65, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x6f,
+0x49, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x53, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x53, 0x76, 0x69, 0x7a,
+0x7a, 0x65, 0x72, 0x61, 0x65e5, 0x672c, 0x8a9e, 0x65e5, 0x672c, 0xc95, 0xca8, 0xccd, 0xca8, 0xca1, 0xcad, 0xcbe, 0xcb0, 0xca4, 0x6a9, 0x672,
+0x634, 0x64f, 0x631, 0x6c1, 0x650, 0x646, 0x65b, 0x62f, 0x648, 0x633, 0x62a, 0x627, 0x646, 0x49b, 0x430, 0x437, 0x430, 0x49b, 0x20, 0x442,
+0x456, 0x43b, 0x456, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x4b, 0x69, 0x6e, 0x79, 0x61, 0x72, 0x77, 0x61,
+0x6e, 0x64, 0x61, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0xd55c,
+0xad6d, 0xc5b4, 0xb300, 0xd55c, 0xbbfc, 0xad6d, 0xc870, 0xc120, 0x20, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0x20, 0xc778, 0xbbfc, 0x20, 0xacf5, 0xd654, 0xad6d,
+0x49, 0x6b, 0x69, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0xea5, 0xeb2, 0xea7, 0xeaa,
+0x2e, 0xe9b, 0x2e, 0xe9b, 0x20, 0xea5, 0xeb2, 0xea7, 0x6c, 0x61, 0x74, 0x76, 0x69, 0x65, 0x161, 0x75, 0x4c, 0x61, 0x74, 0x76,
+0x69, 0x6a, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0xe1, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x64,
+0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x74, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0xf3, 0x41,
+0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x41, 0x66, 0x72,
+0xed, 0x6b, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0xe1, 0x74, 0x69, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x69, 0x65, 0x74,
+0x75, 0x76, 0x69, 0x173, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x61, 0x43c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a,
+0x438, 0x41c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x438, 0x458, 0x430, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x4d,
+0x61, 0x64, 0x61, 0x67, 0x61, 0x73, 0x69, 0x6b, 0x61, 0x72, 0x61, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20, 0x4d, 0x65,
+0x6c, 0x61, 0x79, 0x75, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x53, 0x69,
+0x6e, 0x67, 0x61, 0x70, 0x75, 0x72, 0x61, 0xd2e, 0xd32, 0xd2f, 0xd3e, 0xd33, 0xd02, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0x4d,
+0x61, 0x6c, 0x74, 0x69, 0x92e, 0x930, 0x93e, 0x920, 0x940, 0x43c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x41c, 0x43e, 0x43d, 0x433, 0x43e,
+0x43b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f,
+0x6b, 0x6d, 0xe5, 0x6c, 0x4e, 0x6f, 0x72, 0x67, 0x65, 0xb13, 0xb21, 0xb3c, 0xb3f, 0xb06, 0xb2d, 0xb3e, 0xb30, 0xb24, 0x67e, 0x69a,
+0x62a, 0x648, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x641, 0x627, 0x631, 0x633, 0x6cc, 0x627, 0x6cc, 0x631, 0x627,
+0x646, 0x62f, 0x631, 0x6cc, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x50, 0x6f, 0x6c, 0x73, 0x6b, 0x61, 0x70, 0x6f, 0x72, 0x74,
+0x75, 0x67, 0x75, 0xea, 0x73, 0x20, 0x64, 0x6f, 0x20, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x42, 0x72, 0x61, 0x73, 0x69,
+0x6c, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x41, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x43, 0x61, 0x62, 0x6f,
+0x20, 0x56, 0x65, 0x72, 0x64, 0x65, 0x54, 0x69, 0x6d, 0x6f, 0x72, 0x2d, 0x4c, 0x65, 0x73, 0x74, 0x65, 0x47, 0x75, 0x69,
+0x6e, 0xe9, 0x2d, 0x42, 0x69, 0x73, 0x73, 0x61, 0x75, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x2c, 0x20, 0x52, 0x41, 0x45, 0x20,
+0x64, 0x61, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x70, 0x6f,
+0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x75, 0x50, 0x6f, 0x72, 0x74, 0x75,
+0x67, 0x61, 0x6c, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69,
+0x70, 0x65, 0xa2a, 0xa70, 0xa1c, 0xa3e, 0xa2c, 0xa40, 0xa2d, 0xa3e, 0xa30, 0xa24, 0x67e, 0x646, 0x62c, 0x627, 0x628, 0x67e, 0x6a9, 0x633,
+0x62a, 0x627, 0x646, 0x72, 0x75, 0x6d, 0x61, 0x6e, 0x74, 0x73, 0x63, 0x68, 0x53, 0x76, 0x69, 0x7a, 0x72, 0x61, 0x72, 0x6f,
+0x6d, 0xe2, 0x6e, 0x103, 0x52, 0x6f, 0x6d, 0xe2, 0x6e, 0x69, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61,
+0x20, 0x4d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x61, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x420, 0x43e, 0x441, 0x441, 0x438,
+0x44f, 0x41a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x442, 0x430, 0x43d, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x438, 0x44f, 0x41c, 0x43e,
+0x43b, 0x434, 0x43e, 0x432, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x430, 0x53, 0xe4, 0x6e, 0x67, 0xf6, 0x4b, 0xf6, 0x64,
+0xf6, 0x72, 0xf6, 0x73, 0xea, 0x73, 0x65, 0x20, 0x74, 0xee, 0x20, 0x42, 0xea, 0x61, 0x66, 0x72, 0xee, 0x6b, 0x61, 0x421,
+0x440, 0x43f, 0x441, 0x43a, 0x438, 0x421, 0x440, 0x431, 0x438, 0x458, 0x430, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x43, 0x72, 0x6e,
+0x61, 0x20, 0x47, 0x6f, 0x72, 0x61, 0x53, 0x72, 0x62, 0x69, 0x6a, 0x61, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x411, 0x43e,
+0x441, 0x43d, 0x430, 0x20, 0x438, 0x20, 0x425, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x438, 0x43d, 0x430, 0x426, 0x440, 0x43d,
+0x430, 0x20, 0x413, 0x43e, 0x440, 0x430, 0x41a, 0x43e, 0x441, 0x43e, 0x432, 0x43e, 0x4b, 0x6f, 0x73, 0x6f, 0x76, 0x6f, 0x438, 0x440,
+0x43e, 0x43d, 0x413, 0x443, 0x44b, 0x440, 0x434, 0x437, 0x44b, 0x441, 0x442, 0x43e, 0x43d, 0x423, 0x4d5, 0x440, 0x4d5, 0x441, 0x435, 0x53,
+0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x53, 0x65, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x63, 0x68, 0x69, 0x53, 0x68, 0x6f,
+0x6e, 0x61, 0xdc3, 0xdd2, 0xd82, 0xdc4, 0xdbd, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0xdc0, 0x53, 0x69,
+0x73, 0x77, 0x61, 0x74, 0x69, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65,
+0x6e, 0x73, 0x6b, 0x6f, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x161, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65,
+0x6e, 0x69, 0x6a, 0x61, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69,
+0x79, 0x61, 0x4a, 0x61, 0x62, 0x75, 0x75, 0x74, 0x69, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x69, 0x79, 0x61, 0x4b, 0x69, 0x69,
+0x6e, 0x69, 0x79, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x45, 0x73, 0x70, 0x61, 0xf1,
+0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x42, 0x6f, 0x6c,
+0x69, 0x76, 0x69, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x43, 0x6f, 0x73,
+0x74, 0x61, 0x20, 0x52, 0x69, 0x63, 0x61, 0x43, 0x75, 0x62, 0x61, 0x52, 0x65, 0x70, 0xfa, 0x62, 0x6c, 0x69, 0x63, 0x61,
+0x20, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x61, 0x45, 0x63, 0x75, 0x61, 0x64, 0x6f, 0x72, 0x45, 0x6c,
+0x20, 0x53, 0x61, 0x6c, 0x76, 0x61, 0x64, 0x6f, 0x72, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x20, 0x45, 0x63, 0x75, 0x61,
+0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x48, 0x6f, 0x6e, 0x64, 0x75,
+0x72, 0x61, 0x73, 0x4d, 0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x50, 0x61,
+0x6e, 0x61, 0x6d, 0xe1, 0x50, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x50, 0x65, 0x72, 0xfa, 0x46, 0x69, 0x6c, 0x69,
+0x70, 0x69, 0x6e, 0x61, 0x73, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x55,
+0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x56, 0x65, 0x6e, 0x65, 0x7a, 0x75, 0x65, 0x6c, 0x61, 0x49, 0x73, 0x6c, 0x61, 0x73,
+0x20, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x6c, 0x61, 0x74,
+0x69, 0x6e, 0x6f, 0x61, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x4c, 0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d,
+0xe9, 0x72, 0x69, 0x63, 0x61, 0x43, 0x65, 0x75, 0x74, 0x61, 0x20, 0x79, 0x20, 0x4d, 0x65, 0x6c, 0x69, 0x6c, 0x6c, 0x61,
+0x4b, 0x69, 0x73, 0x77, 0x61, 0x68, 0x69, 0x6c, 0x69, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x53, 0x76, 0x65, 0x72,
+0x69, 0x67, 0x65, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0xc5, 0x6c, 0x61, 0x6e, 0x64, 0x422, 0x43e, 0x4b7, 0x438, 0x43a,
+0x4e3, 0x422, 0x43e, 0x4b7, 0x438, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0xba4, 0xbae, 0xbbf, 0xbb4, 0xbcd, 0xb87, 0xba8, 0xbcd, 0xba4,
+0xbbf, 0xbaf, 0xbbe, 0xbae, 0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf, 0xbbe, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0,
+0xbcd, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0xc24, 0xc46, 0xc32, 0xc41, 0xc17, 0xc41, 0xc2d, 0xc3e, 0xc30, 0xc24, 0x20, 0xc26, 0xc47,
+0xc36, 0xc02, 0xe44, 0xe17, 0xe22, 0xf54, 0xf7c, 0xf51, 0xf0b, 0xf66, 0xf90, 0xf51, 0xf0b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf53, 0xf42, 0xf62,
+0xf92, 0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0x1275, 0x130d, 0x122d, 0x129b, 0x12a4, 0x122d, 0x1275, 0x122b, 0x6c, 0x65, 0x61, 0x20, 0x66, 0x61,
+0x6b, 0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x58, 0x69, 0x74, 0x73, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0xfc, 0x72, 0x6b, 0xe7,
+0x65, 0x54, 0xfc, 0x72, 0x6b, 0x69, 0x79, 0x65, 0x47, 0xfc, 0x6e, 0x65, 0x79, 0x20, 0x4b, 0x131, 0x62, 0x72, 0x131, 0x73,
+0x20, 0x52, 0x75, 0x6d, 0x20, 0x4b, 0x65, 0x73, 0x69, 0x6d, 0x69, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c, 0x43a,
+0x430, 0x423, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x430, 0x627, 0x631, 0x62f, 0x648, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x628,
+0x6be, 0x627, 0x631, 0x62a, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x627,
+0x648, 0x632, 0x628, 0x6cc, 0x6a9, 0x6f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b, 0x63, 0x68, 0x61, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b,
+0x69, 0x73, 0x74, 0x6f, 0x6e, 0x54, 0x69, 0x1ebf, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x56, 0x69, 0x1ec7, 0x74, 0x20,
+0x4e, 0x61, 0x6d, 0x43, 0x79, 0x6d, 0x72, 0x61, 0x65, 0x67, 0x79, 0x20, 0x44, 0x65, 0x79, 0x72, 0x6e, 0x61, 0x73, 0x20,
+0x55, 0x6e, 0x65, 0x64, 0x69, 0x67, 0x69, 0x73, 0x69, 0x58, 0x68, 0x6f, 0x73, 0x61, 0xc8, 0x64, 0xe8, 0x20, 0x59, 0x6f,
+0x72, 0xf9, 0x62, 0xe1, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72,
+0xed, 0xe0, 0x69, 0x73, 0x69, 0x5a, 0x75, 0x6c, 0x75, 0x69, 0x4e, 0x69, 0x6e, 0x67, 0x69, 0x7a, 0x69, 0x6d, 0x75, 0x20,
+0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x6e, 0x79, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x4e, 0x6f, 0x72, 0x65, 0x67, 0x62, 0x6f,
+0x73, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x438, 0x47, 0x61, 0x65, 0x6c, 0x67, 0x52,
+0x79, 0x77, 0x76, 0x61, 0x6e, 0x65, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x79, 0x73, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x77, 0x65,
+0x6b, 0x41, 0x6b, 0x61, 0x6e, 0x47, 0x61, 0x61, 0x6e, 0x61, 0x915, 0x94b, 0x902, 0x915, 0x923, 0x940, 0x49, 0x67, 0x62, 0x6f,
+0x4b, 0x69, 0x6b, 0x61, 0x6d, 0x62, 0x61, 0x1265, 0x120a, 0x1295, 0x1275, 0x130d, 0x1228, 0x66, 0x75, 0x72, 0x6c, 0x61, 0x6e, 0x49,
+0x74, 0x61, 0x6c, 0x69, 0x65, 0x54, 0x73, 0x68, 0x69, 0x76, 0x65, 0x6e, 0x1e13, 0x61, 0x65, 0x28b, 0x65, 0x67, 0x62, 0x65,
+0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x20, 0x6e, 0x75, 0x74,
+0x6f, 0x6d, 0x65, 0x12c8, 0x120b, 0x12ed, 0x1273, 0x1271, 0x2bb, 0x14c, 0x6c, 0x65, 0x6c, 0x6f, 0x20, 0x48, 0x61, 0x77, 0x61, 0x69,
+0x2bb, 0x69, 0x2bb, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x75, 0x69, 0x20, 0x50, 0x16b, 0x20, 0x2bb, 0x49,
+0x61, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x53, 0x63,
+0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x74, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69,
+0x7a, 0xa188, 0xa320, 0xa259, 0xa34f, 0xa1e9, 0x69, 0x73, 0x69, 0x4e, 0x64, 0x65, 0x62, 0x65, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x6f,
+0x74, 0x68, 0x6f, 0x20, 0x73, 0x61, 0x20, 0x4c, 0x65, 0x62, 0x6f, 0x61, 0x64, 0x61, 0x76, 0x76, 0x69, 0x73, 0xe1, 0x6d,
+0x65, 0x67, 0x69, 0x65, 0x6c, 0x6c, 0x61, 0x4e, 0x6f, 0x72, 0x67, 0x61, 0x53, 0x75, 0x6f, 0x70, 0x6d, 0x61, 0x45, 0x6b,
+0x65, 0x67, 0x75, 0x73, 0x69, 0x69, 0x4b, 0x69, 0x74, 0x61, 0x69, 0x74, 0x61, 0x50, 0x75, 0x6c, 0x61, 0x61, 0x72, 0x53,
+0x65, 0x6e, 0x65, 0x67, 0x61, 0x61, 0x6c, 0x47, 0x69, 0x6b, 0x75, 0x79, 0x75, 0x4b, 0x69, 0x73, 0x61, 0x6d, 0x70, 0x75,
+0x72, 0x73, 0x65, 0x6e, 0x61, 0x4b, 0x69, 0x68, 0x6f, 0x72, 0x6f, 0x6d, 0x62, 0x6f, 0x2d5c, 0x2d30, 0x2d4e, 0x2d30, 0x2d63, 0x2d49,
+0x2d56, 0x2d5c, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x74, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x67, 0x68, 0x74, 0x6c, 0x6d, 0x263,
+0x72, 0x69, 0x62, 0x54, 0x61, 0x71, 0x62, 0x61, 0x79, 0x6c, 0x69, 0x74, 0x4c, 0x65, 0x7a, 0x7a, 0x61, 0x79, 0x65, 0x72,
+0x52, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x6b, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x62, 0x65, 0x6e, 0x61, 0x48, 0x75, 0x74, 0x61,
+0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x79, 0x69, 0x76, 0x75, 0x6e, 0x6a, 0x6f, 0x62, 0x61, 0x6d, 0x61, 0x6e, 0x61,
+0x6b, 0x61, 0x6e, 0x4b, 0x129, 0x65, 0x6d, 0x62, 0x75, 0x13e3, 0x13b3, 0x13a9, 0x13a0, 0x13b9, 0x13f0, 0x13df, 0x6b, 0x72, 0x65, 0x6f,
+0x6c, 0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x4d, 0x6f, 0x72, 0x69, 0x73, 0x43, 0x68, 0x69, 0x6d, 0x61,
+0x6b, 0x6f, 0x6e, 0x64, 0x65, 0x4b, 0x268, 0x6c, 0x61, 0x61, 0x6e, 0x67, 0x69, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e,
+0xed, 0x61, 0x4c, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x49, 0x63, 0x68, 0x69,
+0x62, 0x65, 0x6d, 0x62, 0x61, 0x6b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x4b, 0x61, 0x62,
+0x75, 0x20, 0x56, 0x65, 0x72, 0x64, 0x69, 0x4b, 0x129, 0x6d, 0x129, 0x72, 0x169, 0x4b, 0x61, 0x6c, 0x65, 0x6e, 0x6a, 0x69,
+0x6e, 0x45, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x68, 0x6f, 0x65, 0x6b, 0x68, 0x6f,
+0x65, 0x67, 0x6f, 0x77, 0x61, 0x62, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x62, 0x4b, 0x69, 0x6d, 0x61, 0x63, 0x68,
+0x61, 0x6d, 0x65, 0x4b, 0xf6, 0x6c, 0x73, 0x63, 0x68, 0x44, 0x6f, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64,
+0x4d, 0x61, 0x61, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x61, 0x4f, 0x6c, 0x75, 0x73, 0x6f, 0x67, 0x61, 0x4c, 0x75,
+0x6c, 0x75, 0x68, 0x69, 0x61, 0x4b, 0x69, 0x70, 0x61, 0x72, 0x65, 0x54, 0x61, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x4b,
+0x69, 0x74, 0x65, 0x73, 0x6f, 0x4b, 0x65, 0x6e, 0x69, 0x61, 0x4b, 0x6f, 0x79, 0x72, 0x61, 0x20, 0x63, 0x69, 0x69, 0x6e,
+0x69, 0x4d, 0x61, 0x61, 0x6c, 0x69, 0x4b, 0x69, 0x72, 0x75, 0x77, 0x61, 0x44, 0x68, 0x6f, 0x6c, 0x75, 0x6f, 0x52, 0x75,
+0x6b, 0x69, 0x67, 0x61, 0x54, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x263, 0x74, 0x4d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x4b, 0x6f,
+0x79, 0x72, 0x61, 0x62, 0x6f, 0x72, 0x6f, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0x4b, 0x69, 0x73, 0x68, 0x61, 0x6d, 0x62,
+0x61, 0x61, 0x92c, 0x921, 0x93c, 0x94b, 0x54, 0x73, 0x68, 0x69, 0x6c, 0x75, 0x62, 0x61, 0x44, 0x69, 0x74, 0x75, 0x6e, 0x67,
+0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x41, 0x67, 0x68, 0x65, 0x6d, 0x4b, 0xe0, 0x6d, 0xe0, 0x6c,
+0xfb, 0x14b, 0x181, 0xe0, 0x73, 0xe0, 0x61, 0x4b, 0xe0, 0x6d, 0x25b, 0x300, 0x72, 0xfb, 0x6e, 0x5a, 0x61, 0x72, 0x6d, 0x61,
+0x63, 0x69, 0x69, 0x6e, 0x65, 0x4e, 0x69, 0x17e, 0x65, 0x72, 0x64, 0x75, 0xe1, 0x6c, 0xe1, 0x6a, 0x6f, 0x6f, 0x6c, 0x61,
+0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x77, 0x6f, 0x6e, 0x64, 0x6f, 0x4b, 0x61, 0x6d, 0x259, 0x72, 0xfa, 0x6e,
+0x72, 0x69, 0x6b, 0x70, 0x61, 0x6b, 0x61, 0x6d, 0x25b, 0x72, 0xfa, 0x6e, 0x4d, 0x61, 0x6b, 0x75, 0x61, 0x55, 0x6d, 0x6f,
+0x7a, 0x61, 0x6d, 0x62, 0x69, 0x6b, 0x69, 0x4d, 0x55, 0x4e, 0x44, 0x41, 0x14a, 0x6b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x14b,
+0x4b, 0x77, 0x61, 0x73, 0x69, 0x6f, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x6e, 0x54, 0x68, 0x6f, 0x6b, 0x20, 0x4e, 0x61,
+0x74, 0x68, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x441, 0x430, 0x445, 0x430, 0x20, 0x442, 0x44b, 0x43b, 0x430, 0x49, 0x73, 0x68, 0x69,
+0x73, 0x61, 0x6e, 0x67, 0x75, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x4b, 0x69, 0x73, 0x77, 0x61, 0x68,
+0x69, 0x6c, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x4a, 0x61, 0x6d, 0x68, 0x75, 0x72, 0x69, 0x20,
+0x79, 0x61, 0x20, 0x4b, 0x69, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x73, 0x69, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b,
+0x6f, 0x6e, 0x67, 0x6f, 0x54, 0x61, 0x73, 0x61, 0x77, 0x61, 0x71, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0xa559, 0xa524, 0xa55e,
+0xa524, 0xa52b, 0xa569, 0x56, 0x61, 0x69, 0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x57, 0x61, 0x6c, 0x73, 0x65, 0x72,
+0x53, 0x63, 0x68, 0x77, 0x69, 0x7a, 0x6e, 0x75, 0x61, 0x73, 0x75, 0x65, 0x4b, 0x65, 0x6d, 0x65, 0x6c, 0xfa, 0x6e, 0x61,
+0x73, 0x74, 0x75, 0x72, 0x69, 0x61, 0x6e, 0x75, 0x4e, 0x64, 0x61, 0xa78c, 0x61, 0x4b, 0x61, 0x6d, 0x25b, 0x6c, 0xfb, 0x6e,
+0x6b, 0x61, 0x6b, 0x254, 0x4b, 0x61, 0x6d, 0x25b, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x2bc, 0x4b, 0x61, 0x6d, 0x61,
+0x6c, 0x75, 0x6e, 0x53, 0x68, 0x77, 0xf3, 0x14b, 0xf2, 0x20, 0x6e, 0x67, 0x69, 0x65, 0x6d, 0x62, 0x254, 0x254, 0x6e, 0x4b,
+0xe0, 0x6d, 0x61, 0x6c, 0xfb, 0x6d
};
static const char language_name_list[] =
@@ -6565,6 +6569,7 @@ static const char country_name_list[] =
"SouthSudan\0"
"Bonaire\0"
"SintMaarten\0"
+"Kosovo\0"
;
static const quint16 country_name_index[] = {
@@ -6825,6 +6830,7 @@ static const quint16 country_name_index[] = {
2676, // SouthSudan
2687, // Bonaire
2695, // SintMaarten
+ 2707, // Kosovo
};
static const unsigned char language_code_list[] =
@@ -7507,6 +7513,7 @@ static const unsigned char country_code_list[] =
"SS\0" // SouthSudan
"BQ\0" // Bonaire
"SX\0" // SintMaarten
+"XK\0" // Kosovo
;
// GENERATED PART ENDS HERE
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 56ed6c7534..34223d5af9 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -62,7 +62,7 @@
QT_BEGIN_NAMESPACE
#ifndef QT_NO_SYSTEMLOCALE
-class QSystemLocale
+class Q_CORE_EXPORT QSystemLocale
{
public:
QSystemLocale();
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 449fcbca0a..8c15afd9f8 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -557,6 +557,18 @@ public:
private:
void detach_helper();
+ bool isValidIterator(const const_iterator &ci) const
+ {
+#if defined(QT_DEBUG) && !defined(Q_MAP_NO_ITERATOR_DEBUG)
+ const QMapNodeBase *n = ci.i;
+ while (n->parent())
+ n = n->parent();
+ return n->left == d->root();
+#else
+ Q_UNUSED(ci);
+ return true;
+#endif
+ }
};
template <class Key, class T>
@@ -670,6 +682,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insert(const_iterator pos, const K
if (d->ref.isShared())
return this->insert(akey, avalue);
+ Q_ASSERT_X(isValidIterator(pos), "QMap::insert", "The specified const_iterator argument 'it' is invalid");
+
if (pos == constEnd()) {
// Hint is that the Node is larger than (or equal to) the largest value.
Node *n = static_cast<Node *>(pos.i->left);
@@ -753,6 +767,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const_iterator pos, co
if (d->ref.isShared())
return this->insertMulti(akey, avalue);
+ Q_ASSERT_X(isValidIterator(pos), "QMap::insertMulti", "The specified const_iterator argument 'pos' is invalid");
+
if (pos == constEnd()) {
// Hint is that the Node is larger than (or equal to) the largest value.
Node *n = static_cast<Node *>(pos.i->left);
@@ -895,6 +911,8 @@ Q_OUTOFLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::erase(iterato
if (it == iterator(d->end()))
return it;
+ Q_ASSERT_X(isValidIterator(const_iterator(it)), "QMap::erase", "The specified iterator argument 'it' is invalid");
+
Node *n = it.i;
++it;
d->deleteNode(n);
diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h
index 96b1b65e33..9b8691a3d8 100644
--- a/src/corelib/tools/qpair.h
+++ b/src/corelib/tools/qpair.h
@@ -57,6 +57,19 @@ struct QPair
QPair(const T1 &t1, const T2 &t2) : first(t1), second(t2) {}
// compiler-generated copy/move ctor/assignment operators are fine!
+ template <typename TT1, typename TT2>
+ QPair(const QPair<TT1, TT2> &p) : first(p.first), second(p.second) {}
+ template <typename TT1, typename TT2>
+ QPair &operator=(const QPair<TT1, TT2> &p)
+ { first = p.first; second = p.second; return *this; }
+#ifdef Q_COMPILER_RVALUE_REFS
+ template <typename TT1, typename TT2>
+ QPair(QPair<TT1, TT2> &&p) : first(std::move(p.first)), second(std::move(p.second)) {}
+ template <typename TT1, typename TT2>
+ QPair &operator=(QPair<TT1, TT2> &&p)
+ { first = std::move(p.first); second = std::move(p.second); return *this; }
+#endif
+
T1 first;
T2 second;
};
diff --git a/src/corelib/tools/qpair.qdoc b/src/corelib/tools/qpair.qdoc
index b0caf1aaf0..dd3df8c464 100644
--- a/src/corelib/tools/qpair.qdoc
+++ b/src/corelib/tools/qpair.qdoc
@@ -96,6 +96,26 @@
\sa qMakePair()
*/
+/*!
+ \fn QPair::QPair(const QPair<TT1, TT2> &p)
+ \since 5.2
+
+ Constructs a pair from the other pair \a p, of types TT1 and TT2. This
+ constructor will fail if \c first cannot be initialized from \c p.first or
+ if \c second cannot be initialized from \c p.second.
+
+ \sa qMakePair()
+*/
+
+/*!
+ \fn QPair &QPair::operator=(const QPair<TT1, TT2> &p)
+ \since 5.2
+
+ Copies the pair \a p onto this pair.
+
+ \sa qMakePair()
+*/
+
/*! \fn bool operator==(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2)
\relates QPair
diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp
index 0848754de5..047fcbfc30 100644
--- a/src/corelib/tools/qscopedpointer.cpp
+++ b/src/corelib/tools/qscopedpointer.cpp
@@ -95,6 +95,9 @@ QT_BEGIN_NAMESPACE
this handler for pointers that were allocated with \c{new []}.
\li QScopedPointerPodDeleter - deletes the pointer using \c{free()}. Use this
handler for pointers that were allocated with \c{malloc()}.
+ \li QScopedPointerDeleteLater - deletes a pointer by calling \c{deleteLater()}
+ on it. Use this handler for pointers to QObject's that are actively
+ participating in a QEventLoop.
\endlist
You can pass your own classes as handlers, provided that they have a public
@@ -130,6 +133,33 @@ QT_BEGIN_NAMESPACE
Constructs this QScopedPointer instance and sets its pointer to \a p.
*/
+#ifndef Q_QDOC // QTBUG-32675, qdoc can't parse rvalue refs
+/*!
+ \fn QScopedPointer::QScopedPointer(QScopedPointer<T, Cleanup> &&other)
+
+ Move-constructs a QScopedPointer instance, making it point at the same
+ object that \a other was pointing to. \a other is reset to point to \c{NULL}.
+
+ \since 5.2
+*/
+
+/*!
+ \fn QScopedPointer<T, Cleanup> &operator=(QScopedPointer<T, Cleanup> &&other)
+
+ Move-assigns \a other to this QScopedPointer instance, transferring the
+ ownership of the managed pointer to this instance.
+
+ If \a other and this instance are actually the same object, this operator
+ does nothing.
+
+ Otherwise, this instance is set to point to the object \a other
+ is pointing to, and \a other is set to point to \c{NULL}.
+ If this instance was pointing to an object, that object is destroyed,
+
+ \since 5.2
+*/
+#endif
+
/*!
\fn QScopedPointer::~QScopedPointer()
diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h
index 2155c56e27..dba37dae23 100644
--- a/src/corelib/tools/qscopedpointer.h
+++ b/src/corelib/tools/qscopedpointer.h
@@ -83,6 +83,17 @@ struct QScopedPointerPodDeleter
static inline void cleanup(void *pointer) { if (pointer) free(pointer); }
};
+#ifndef QT_NO_QOBJECT
+template <typename T>
+struct QScopedPointerObjectDeleteLater
+{
+ static inline void cleanup(T *pointer) { if (pointer) pointer->deleteLater(); }
+};
+
+class QObject;
+typedef QScopedPointerObjectDeleteLater<QObject> QScopedPointerDeleteLater;
+#endif
+
template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer
{
@@ -98,6 +109,19 @@ public:
Cleanup::cleanup(oldD);
}
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QScopedPointer(QScopedPointer<T, Cleanup> &&other)
+ : d(other.take())
+ {
+ }
+
+ inline QScopedPointer<T, Cleanup> &operator=(QScopedPointer<T, Cleanup> &&other)
+ {
+ reset(other.take());
+ return *this;
+ }
+#endif
+
inline T &operator*() const
{
Q_ASSERT(d);
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index d5c3637293..ad2f91b983 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -70,6 +70,7 @@ public:
inline QSet<T> &operator=(const QSet<T> &other)
{ q_hash = other.q_hash; return *this; }
#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSet(QSet &&other) : q_hash(qMove(other.q_hash)) {}
inline QSet<T> &operator=(QSet<T> &&other)
{ qSwap(q_hash, other.q_hash); return *this; }
#endif
@@ -180,7 +181,10 @@ public:
inline const_iterator cend() const { return q_hash.end(); }
inline const_iterator constEnd() const { return q_hash.constEnd(); }
iterator erase(iterator i)
- { return q_hash.erase(reinterpret_cast<typename Hash::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));
+ }
// more Qt
typedef iterator Iterator;
@@ -233,6 +237,10 @@ public:
private:
Hash q_hash;
+ bool isValidIterator(const iterator &i) const
+ {
+ return q_hash.isValidIterator(reinterpret_cast<const typename Hash::iterator&>(i));
+ }
};
template <class T>
@@ -253,8 +261,16 @@ Q_INLINE_TEMPLATE QSet<T> &QSet<T>::unite(const QSet<T> &other)
template <class T>
Q_INLINE_TEMPLATE QSet<T> &QSet<T>::intersect(const QSet<T> &other)
{
- QSet<T> copy1(*this);
- QSet<T> copy2(other);
+ QSet<T> copy1;
+ QSet<T> copy2;
+ if (size() <= other.size()) {
+ copy1 = *this;
+ copy2 = other;
+ } else {
+ copy1 = other;
+ copy2 = *this;
+ *this = copy1;
+ }
typename QSet<T>::const_iterator i = copy1.constEnd();
while (i != copy1.constBegin()) {
--i;
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 37d28b0904..36bd61098a 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -820,17 +820,43 @@ const QString::Null QString::null = { };
*/
/*!
+ \typedef QString::size_type
+
+ The QString::size_type typedef provides an STL-style type for sizes (int).
+*/
+
+/*!
+ \typedef QString::difference_type
+
+ The QString::size_type typedef provides an STL-style type for difference between pointers.
+*/
+
+/*!
\typedef QString::const_reference
The QString::const_reference typedef provides an STL-style
- const reference for QString.
+ const reference for a QString element (QChar).
*/
/*!
\typedef QString::reference
- The QString::const_reference typedef provides an STL-style
- reference for QString.
+ The QString::reference typedef provides an STL-style
+ reference for a QString element (QChar).
*/
+
+/*!
+ \typedef QString::const_pointer
+
+ The QString::const_pointer typedef provides an STL-style
+ const pointer to a QString element (QChar).
+*/
+/*!
+ \typedef QString::pointer
+
+ The QString::const_pointer typedef provides an STL-style
+ pointer to a QString element (QChar).
+*/
+
/*!
\typedef QString::value_type
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index d8aaa929dc..7010a954b4 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -657,8 +657,12 @@ public:
const_iterator constEnd() const;
// STL compatibility
+ typedef int size_type;
+ typedef qptrdiff difference_type;
typedef const QChar & const_reference;
typedef QChar & reference;
+ typedef QChar *pointer;
+ typedef const QChar *const_pointer;
typedef QChar value_type;
inline void push_back(QChar c) { append(c); }
inline void push_back(const QString &s) { append(s); }
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 825e05ae1b..d9b85c4173 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -192,6 +192,11 @@ private:
qint64 q_for_alignment_1;
double q_for_alignment_2;
};
+
+ bool isValidIterator(const const_iterator &i) const
+ {
+ return (i <= constEnd()) && (constBegin() <= i);
+ }
};
template <class T, int Prealloc>
@@ -355,6 +360,8 @@ inline void QVarLengthArray<T, Prealloc>::replace(int i, const T &t)
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, size_type n, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
+
int offset = int(before - ptr);
if (n != 0) {
resize(s + n);
@@ -382,6 +389,9 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::erase(const_iterator abegin, const_iterator aend)
{
+ Q_ASSERT_X(isValidIterator(abegin), "QVarLengthArray::insert", "The specified const_iterator argument 'abegin' is invalid");
+ Q_ASSERT_X(isValidIterator(aend), "QVarLengthArray::insert", "The specified const_iterator argument 'aend' is invalid");
+
int f = int(abegin - ptr);
int l = int(aend - ptr);
int n = l - f;
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 489ee821b9..de64d7a670 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -238,7 +238,10 @@ private:
void defaultConstruct(T *from, T *to);
void copyConstruct(const T *srcFrom, const T *srcTo, T *dstFrom);
void destruct(T *from, T *to);
-
+ bool isValidIterator(const iterator &i) const
+ {
+ return (i <= d->end()) && (d->begin() <= i);
+ }
class AlignmentDummy { Data header; T array[1]; };
};
@@ -578,6 +581,8 @@ inline void QVector<T>::removeLast()
template <typename T>
typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, const T &t)
{
+ Q_ASSERT_X(isValidIterator(before), "QVector::insert", "The specified iterator argument 'before' is invalid");
+
int offset = std::distance(d->begin(), before);
if (n != 0) {
const T copy(t);
@@ -611,6 +616,9 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
template <typename T>
typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
{
+ Q_ASSERT_X(isValidIterator(abegin), "QVector::erase", "The specified iterator argument 'abegin' is invalid");
+ Q_ASSERT_X(isValidIterator(aend), "QVector::erase", "The specified iterator argument 'aend' is invalid");
+
const int itemsToErase = aend - abegin;
if (!itemsToErase)
diff --git a/src/dbus/doc/qtdbus.qdocconf b/src/dbus/doc/qtdbus.qdocconf
index b47e02ff43..1233ae3d47 100644
--- a/src/dbus/doc/qtdbus.qdocconf
+++ b/src/dbus/doc/qtdbus.qdocconf
@@ -20,7 +20,7 @@ excludedirs += ../../../examples/widgets/doc
examplesinstallpath = dbus
-depends += qtcore
+depends += qtdoc qtcore
# The following parameters are for creating a qhp file, the qhelpgenerator
# program can convert the qhp file into a qch file which can be opened in
@@ -49,3 +49,6 @@ qhp.QtDBus.subprojects.classes.title = C++ Classes
qhp.QtDBus.subprojects.classes.indexTitle = Qt D-Bus C++ Classes
qhp.QtDBus.subprojects.classes.selectors = class fake:headerfile
qhp.QtDBus.subprojects.classes.sortPages = true
+
+navigation.landingpage = "Qt D-Bus"
+navigation.cppclassespage = "Qt D-Bus C++ Classes"
diff --git a/src/dbus/doc/src/qtdbus-module.qdoc b/src/dbus/doc/src/qtdbus-module.qdoc
index fe3b11b926..ac9cac428b 100644
--- a/src/dbus/doc/src/qtdbus-module.qdoc
+++ b/src/dbus/doc/src/qtdbus-module.qdoc
@@ -32,6 +32,7 @@
to perform Inter-Process Communication using the \l{D-Bus} protocol.
\ingroup modules
+ \qtvariable dbus
\target The QDBus compiler
diff --git a/src/dbus/qdbusabstractadaptor.cpp b/src/dbus/qdbusabstractadaptor.cpp
index 02ff40068b..04accee037 100644
--- a/src/dbus/qdbusabstractadaptor.cpp
+++ b/src/dbus/qdbusabstractadaptor.cpp
@@ -307,15 +307,18 @@ void QDBusAdaptorConnector::relay(QObject *senderObj, int lastSignalIdx, void **
// break down the parameter list
QVector<int> types;
- int inputCount = qDBusParametersForMethod(mm, types);
- if (inputCount == -1)
+ QString errorMsg;
+ int inputCount = qDBusParametersForMethod(mm, types, errorMsg);
+ if (inputCount == -1) {
// invalid signal signature
- // qDBusParametersForMethod has already complained
+ qWarning("QDBusAbstractAdaptor: Cannot relay signal %s::%s: %s",
+ senderMetaObject->className(), mm.methodSignature().constData(),
+ qPrintable(errorMsg));
return;
+ }
if (inputCount + 1 != types.count() ||
types.at(inputCount) == QDBusMetaTypeId::message()) {
// invalid signal signature
- // qDBusParametersForMethod has not yet complained about this one
qWarning("QDBusAbstractAdaptor: Cannot relay signal %s::%s",
senderMetaObject->className(), mm.methodSignature().constData());
return;
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index c702de141a..013896bd32 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -341,9 +341,9 @@ public:
};
// in qdbusmisc.cpp
-extern int qDBusParametersForMethod(const QMetaMethod &mm, QVector<int> &metaTypes);
+extern int qDBusParametersForMethod(const QMetaMethod &mm, QVector<int> &metaTypes, QString &errorMsg);
#endif // QT_BOOTSTRAPPED
-extern Q_DBUS_EXPORT int qDBusParametersForMethod(const QList<QByteArray> &parameters, QVector<int>& metaTypes);
+extern Q_DBUS_EXPORT int qDBusParametersForMethod(const QList<QByteArray> &parameters, QVector<int>& metaTypes, QString &errorMsg);
extern Q_DBUS_EXPORT bool qDBusCheckAsyncTag(const char *tag);
#ifndef QT_BOOTSTRAPPED
extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name);
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 3f25f02bee..e5f3fbdc53 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -721,7 +721,8 @@ static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags,
if (isAsync && returnType != QMetaType::Void)
continue;
- int inputCount = qDBusParametersForMethod(mm, metaTypes);
+ QString errorMsg;
+ int inputCount = qDBusParametersForMethod(mm, metaTypes, errorMsg);
if (inputCount == -1)
continue; // problem parsing
@@ -1312,7 +1313,8 @@ int QDBusConnectionPrivate::findSlot(QObject* obj, const QByteArray &normalizedN
if (midx == -1)
return -1;
- int inputCount = qDBusParametersForMethod(obj->metaObject()->method(midx), params);
+ QString errorMsg;
+ int inputCount = qDBusParametersForMethod(obj->metaObject()->method(midx), params, errorMsg);
if ( inputCount == -1 || inputCount + 1 != params.count() )
return -1; // failed to parse or invalid arguments or output arguments
diff --git a/src/dbus/qdbusmisc.cpp b/src/dbus/qdbusmisc.cpp
index d28d5598c6..5d3512845a 100644
--- a/src/dbus/qdbusmisc.cpp
+++ b/src/dbus/qdbusmisc.cpp
@@ -131,14 +131,14 @@ bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name)
// metaTypes.count() >= retval + 1 in all cases
//
// sig must be the normalised signature for the method
-int qDBusParametersForMethod(const QMetaMethod &mm, QVector<int> &metaTypes)
+int qDBusParametersForMethod(const QMetaMethod &mm, QVector<int> &metaTypes, QString &errorMsg)
{
- return qDBusParametersForMethod(mm.parameterTypes(), metaTypes);
+ return qDBusParametersForMethod(mm.parameterTypes(), metaTypes, errorMsg);
}
#endif // QT_BOOTSTRAPPED
-int qDBusParametersForMethod(const QList<QByteArray> &parameterTypes, QVector<int>& metaTypes)
+int qDBusParametersForMethod(const QList<QByteArray> &parameterTypes, QVector<int>& metaTypes, QString &errorMsg)
{
QDBusMetaTypeId::init();
metaTypes.clear();
@@ -151,8 +151,7 @@ int qDBusParametersForMethod(const QList<QByteArray> &parameterTypes, QVector<in
for ( ; it != end; ++it) {
const QByteArray &type = *it;
if (type.endsWith('*')) {
- //qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
- // pointer?
+ errorMsg = QLatin1String("Pointers are not supported: ") + QLatin1String(type);
return -1;
}
@@ -162,8 +161,7 @@ int qDBusParametersForMethod(const QList<QByteArray> &parameterTypes, QVector<in
int id = QMetaType::type(basictype);
if (id == 0) {
- //qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
- // invalid type in method parameter list
+ errorMsg = QLatin1String("Unregistered output type in parameter list: ") + QLatin1String(type);
return -1;
} else if (QDBusMetaType::typeToSignature(id) == 0)
return -1;
@@ -174,22 +172,22 @@ int qDBusParametersForMethod(const QList<QByteArray> &parameterTypes, QVector<in
}
if (seenMessage) { // && !type.endsWith('&')
- //qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
- // non-output parameters after message or after output params
+ errorMsg = QLatin1String("Invalid method, non-output parameters after message or after output parameters: ") + QLatin1String(type);
return -1; // not allowed
}
int id = QMetaType::type(type);
if (id == QMetaType::UnknownType) {
- //qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
- // invalid type in method parameter list
+ errorMsg = QLatin1String("Unregistered input type in parameter list: ") + QLatin1String(type);
return -1;
}
if (id == QDBusMetaTypeId::message())
seenMessage = true;
- else if (QDBusMetaType::typeToSignature(id) == 0)
+ else if (QDBusMetaType::typeToSignature(id) == 0) {
+ errorMsg = QLatin1String("Type not registered with QtDBus in parameter list: ") + QLatin1String(type);
return -1;
+ }
metaTypes.append(id);
++inputCount;
diff --git a/src/dbus/qdbusxmlgenerator.cpp b/src/dbus/qdbusxmlgenerator.cpp
index 8c822162e4..c724ac573a 100644
--- a/src/dbus/qdbusxmlgenerator.cpp
+++ b/src/dbus/qdbusxmlgenerator.cpp
@@ -41,6 +41,7 @@
#include <QtCore/qmetaobject.h>
#include <QtCore/qstringlist.h>
+#include <QtCore/qdebug.h>
#include "qdbusinterface_p.h" // for ANNOTATION_NO_WAIT
#include "qdbusabstractadaptor_p.h" // for QCLASSINFO_DBUS_*
@@ -159,17 +160,24 @@ static QString generateInterfaceXml(const QMetaObject *mo, int flags, int method
if (QDBusMetaType::signatureToType(typeName) == QVariant::Invalid)
xml += QString::fromLatin1(" <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"%1\"/>\n")
.arg(typeNameToXml(QMetaType::typeName(typeId)));
- } else
+ } else {
+ qWarning() << "Unsupported return type" << typeId << QMetaType::typeName(typeId) << "in method" << mm.name();
continue;
+ }
}
- else if (typeId == QMetaType::UnknownType)
+ else if (typeId == QMetaType::UnknownType) {
+ qWarning() << "Invalid return type in method" << mm.name();
continue; // wasn't a valid type
+ }
QList<QByteArray> names = mm.parameterNames();
QVector<int> types;
- int inputCount = qDBusParametersForMethod(mm, types);
- if (inputCount == -1)
+ QString errorMsg;
+ int inputCount = qDBusParametersForMethod(mm, types, errorMsg);
+ if (inputCount == -1) {
+ qWarning() << "Skipped method" << mm.name() << ":" << qPrintable(errorMsg);
continue; // invalid form
+ }
if (isSignal && inputCount + 1 != types.count())
continue; // signal with output arguments?
if (isSignal && types.at(inputCount) == QDBusMetaTypeId::message())
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index 5073dd7f0f..ed30172376 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -48,3 +48,6 @@ exampledirs += ../../../examples/gui \
imagedirs += images \
../../../examples/gui/doc/images \
../../../doc/src/images \
+
+navigation.landingpage = "Qt GUI"
+navigation.cppclassespage = "Qt GUI C++ Classes"
diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc
index 6c3e9a4938..75c74c8072 100644
--- a/src/gui/doc/src/qtgui.qdoc
+++ b/src/gui/doc/src/qtgui.qdoc
@@ -29,6 +29,7 @@
\module QtGui
\title Qt GUI C++ Classes
\ingroup modules
+ \qtvariable gui
\brief The Qt GUI module provides the basic enablers for graphical
applications written with Qt.
@@ -172,11 +173,3 @@
\endlist
\endlist
*/
-
-/*!
- \group events
- \title Event Classes
- \ingroup groups
-
- \brief Classes that provide UI and input events.
-*/
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index cb4e45f1d0..c03d9b8e5d 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -781,6 +781,8 @@ bool QBmpHandler::write(const QImage &img)
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_ARGB6666_Premultiplied:
case QImage::Format_ARGB4444_Premultiplied:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied:
image = img.convertToFormat(QImage::Format_ARGB32);
break;
case QImage::Format_RGB16:
@@ -788,6 +790,7 @@ bool QBmpHandler::write(const QImage &img)
case QImage::Format_RGB666:
case QImage::Format_RGB555:
case QImage::Format_RGB444:
+ case QImage::Format_RGBX8888:
image = img.convertToFormat(QImage::Format_RGB32);
break;
default:
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index aef7324171..cb508ae6c7 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -1068,7 +1068,6 @@ void QIcon::setThemeName(const QString &name)
*/
QString QIcon::themeName()
{
- QIconLoader::instance()->ensureInitialized();
return QIconLoader::instance()->themeName();
}
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index e81bea69d6..f1a78b508c 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -62,6 +62,10 @@ public:
QIcon();
QIcon(const QPixmap &pixmap);
QIcon(const QIcon &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ QIcon(QIcon &&other)
+ :d(0) { qSwap(d, other.d); }
+#endif
explicit QIcon(const QString &fileName); // file or resource name
explicit QIcon(QIconEngine *engine);
~QIcon();
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 105dc26c9b..d202d62957 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -128,6 +128,7 @@ void QIconLoader::ensureInitialized()
QIconLoader *QIconLoader::instance()
{
+ iconLoaderInstance()->ensureInitialized();
return iconLoaderInstance();
}
@@ -368,17 +369,14 @@ bool QIconLoaderEngine::hasIcon() const
// Lazily load the icon
void QIconLoaderEngine::ensureLoaded()
{
-
- iconLoaderInstance()->ensureInitialized();
-
- if (!(iconLoaderInstance()->themeKey() == m_key)) {
+ if (!(QIconLoader::instance()->themeKey() == m_key)) {
while (!m_entries.isEmpty())
delete m_entries.takeLast();
Q_ASSERT(m_entries.size() == 0);
- m_entries = iconLoaderInstance()->loadIcon(m_iconName);
- m_key = iconLoaderInstance()->themeKey();
+ m_entries = QIconLoader::instance()->loadIcon(m_iconName);
+ m_key = QIconLoader::instance()->themeKey();
}
}
@@ -565,7 +563,7 @@ void QIconLoaderEngine::virtual_hook(int id, void *data)
{
QIconEngine::AvailableSizesArgument &arg
= *reinterpret_cast<QIconEngine::AvailableSizesArgument*>(data);
- const QList<QIconDirInfo> directoryKey = iconLoaderInstance()->theme().keyList();
+ const QList<QIconDirInfo> directoryKey = QIconLoader::instance()->theme().keyList();
arg.sizes.clear();
// Gets all sizes from the DirectoryInfo entries
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 98f3aeeeb9..8e5f6391a7 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -212,6 +212,16 @@ bool QImageData::checkForAlphaPixels() const
}
} break;
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied: {
+ uchar *bits = data;
+ for (int y=0; y<height && !has_alpha_pixels; ++y) {
+ for (int x=0; x<width; ++x)
+ has_alpha_pixels |= bits[x*4+3] != 0xff;
+ bits += bytes_per_line;
+ }
+ } break;
+
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_ARGB8565_Premultiplied: {
uchar *bits = data;
@@ -621,9 +631,9 @@ bool QImageData::checkForAlphaPixels() const
/*!
\enum QImage::Format
- The following image formats are available in Qt. Values greater
- than QImage::Format_RGB16 were added in Qt 4.4. See the notes
- after the table.
+ The following image formats are available in Qt. Values from Format_ARGB8565_Premultiplied
+ to Format_ARGB4444_Premultiplied were added in Qt 4.4. Values Format_RGBX8888, Format_RGBA8888
+ and Format_RGBA8888_Premultiplied were added in Qt 5.2. See the notes after the table.
\value Format_Invalid The image is invalid.
\value Format_Mono The image is stored using 1-bit per pixel. Bytes are
@@ -665,6 +675,15 @@ bool QImageData::checkForAlphaPixels() const
The unused bits are always zero.
\value Format_ARGB4444_Premultiplied The image is stored using a
premultiplied 16-bit ARGB format (4-4-4-4).
+ \value Format_RGBX8888 The image is stored using a 32-bit byte-ordered RGB(x) format (8-8-8-8).
+ This is the same as the Format_RGBA8888 except alpha must always be 255.
+ \value Format_RGBA8888 The image is stored using a 32-bit byte-ordered RGBA format (8-8-8-8).
+ Unlike ARGB32 this is a byte-ordered format, which means the 32bit
+ encoding differs between big endian and little endian architectures,
+ being respectively (0xRRGGBBAA) and (0xAABBGGRR). The order of the colors
+ is the same on any architecture if read as bytes 0xRR,0xGG,0xBB,0xAA.
+ \value Format_RGBA8888_Premultiplied The image is stored using a
+ premultiplied 32-bit byte-ordered RGBA format (8-8-8-8).
\note Drawing into a QImage with QImage::Format_Indexed8 is not
supported.
@@ -1663,9 +1682,12 @@ void QImage::fill(uint pixel)
return;
}
- if (d->format == Format_RGB32)
+ if (d->format == Format_RGB32 || d->format == Format_RGBX8888)
pixel |= 0xff000000;
+ if (d->format == Format_RGBX8888 || d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied)
+ pixel = ARGB2RGBA(pixel);
+
qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel,
0, 0, d->width, d->height, d->bytes_per_line);
}
@@ -1716,7 +1738,7 @@ void QImage::fill(const QColor &color)
if (d->depth == 32) {
uint pixel = color.rgba();
- if (d->format == QImage::Format_ARGB32_Premultiplied)
+ if (d->format == QImage::Format_ARGB32_Premultiplied || d->format == QImage::Format_RGBA8888_Premultiplied)
pixel = PREMUL(pixel);
fill((uint) pixel);
@@ -1871,8 +1893,8 @@ typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFla
static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
- Q_ASSERT(src->format == QImage::Format_ARGB32);
- Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
Q_ASSERT(src->width == dest->width);
Q_ASSERT(src->height == dest->height);
@@ -1912,6 +1934,191 @@ static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversio
return true;
}
+static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(0xff000000 | *src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_ARGB_to_RGBA_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_ARGB32_Premultiplied);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ quint32 *rgb_data = (quint32 *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const quint32 *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = ARGB2RGBA(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ if (data->format == QImage::Format_ARGB32)
+ data->format = QImage::Format_RGBA8888;
+ else
+ data->format = QImage::Format_RGBA8888_Premultiplied;
+ return true;
+}
+
+static void convert_ARGB_to_RGBA_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(PREMUL(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBX8888 || src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = RGBA2ARGB(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGBX8888 || data->format == QImage::Format_RGBA8888 || data->format == QImage::Format_RGBA8888_Premultiplied);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = RGBA2ARGB(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ if (data->format == QImage::Format_RGBA8888_Premultiplied)
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ else if (data->format == QImage::Format_RGBX8888)
+ data->format = QImage::Format_RGB32;
+ else
+ data->format = QImage::Format_ARGB32;
+ return true;
+}
+
+static void convert_RGBA_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = PREMUL(RGBA2ARGB(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_RGBA_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGBA8888);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = PREMUL(RGBA2ARGB(*rgb_data));
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ return true;
+}
+
static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
{
Q_ASSERT(data->format == QImage::Format_Indexed8);
@@ -2099,8 +2306,8 @@ static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFl
static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
- Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_ARGB32);
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
Q_ASSERT(src->width == dest->width);
Q_ASSERT(src->height == dest->height);
@@ -2123,20 +2330,164 @@ static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt:
static void convert_ARGB_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = 0xff000000 | INV_PREMUL(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_PM_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(0xff000000 | INV_PREMUL(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_PM_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(INV_PREMUL(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBX8888);
Q_ASSERT(dest->format == QImage::Format_RGB32);
Q_ASSERT(src->width == dest->width);
Q_ASSERT(src->height == dest->height);
const int src_pad = (src->bytes_per_line >> 2) - src->width;
const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = RGBA2ARGB(*src_data) | 0xff000000;
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(*src_data | 0xff000000);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
const QRgb *src_data = (QRgb *) src->data;
QRgb *dest_data = (QRgb *) dest->data;
for (int i = 0; i < src->height; ++i) {
const QRgb *end = src_data + src->width;
while (src_data < end) {
- *dest_data = 0xff000000 | INV_PREMUL(*src_data);
+ *dest_data = INV_PREMUL(RGBA2ARGB(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGB32);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = 0xff000000 | INV_PREMUL(RGBA2ARGB(*src_data));
++src_data;
++dest_data;
}
@@ -2188,6 +2539,33 @@ static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::Im
}
}
+static void mask_alpha_converter_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ return mask_alpha_converter(dest, src, flags);
+#else
+ Q_UNUSED(flags);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = *src_data | 0x000000ff;
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+#endif
+}
+
static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
{
QVector<QRgb> colorTable = ctbl;
@@ -2941,6 +3319,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_Mono
@@ -2960,6 +3341,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_MonoLSB
@@ -2979,6 +3363,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_Indexed8
@@ -2998,7 +3385,10 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_generic,
convert_generic,
convert_generic,
- convert_generic
+ convert_generic,
+ convert_RGB_to_RGBA,
+ convert_RGB_to_RGBA,
+ convert_RGB_to_RGBA
}, // Format_RGB32
{
@@ -3017,7 +3407,10 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_generic,
convert_generic,
convert_generic,
- convert_generic
+ convert_generic,
+ convert_ARGB_to_RGBx,
+ convert_ARGB_to_RGBA,
+ convert_ARGB_to_RGBA_PM,
}, // Format_ARGB32
{
@@ -3036,7 +3429,10 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0
+ 0,
+ convert_ARGB_PM_to_RGBx,
+ convert_ARGB_PM_to_RGBA,
+ convert_ARGB_to_RGBA,
}, // Format_ARGB32_Premultiplied
{
@@ -3059,6 +3455,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_RGB16
@@ -3078,6 +3477,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_ARGB8565_Premultiplied
@@ -3097,6 +3499,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_RGB666
@@ -3116,6 +3521,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_ARGB6666_Premultiplied
@@ -3139,6 +3547,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_RGB555
@@ -3158,6 +3569,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_ARGB8555_Premultiplied
@@ -3177,6 +3591,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_RGB888
@@ -3196,6 +3613,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
+ 0,
0
}, // Format_RGB444
@@ -3215,20 +3635,97 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ 0,
+ 0,
0
- } // Format_ARGB4444_Premultiplied
+ }, // Format_ARGB4444_Premultiplied
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_RGB,
+ convert_RGBA_to_ARGB,
+ convert_RGBA_to_ARGB_PM,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ mask_alpha_converter_RGBx,
+ mask_alpha_converter_RGBx,
+ }, // Format_RGBX8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_RGB,
+ convert_RGBA_to_ARGB,
+ convert_RGBA_to_ARGB_PM,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ mask_alpha_converter_RGBx,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ 0,
+ convert_ARGB_to_ARGB_PM,
+#else
+ 0,
+ 0
+#endif
+ }, // Format_RGBA8888
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_PM_to_RGB,
+ convert_RGBA_PM_to_ARGB,
+ convert_RGBA_to_ARGB,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ convert_ARGB_PM_to_RGB,
+ convert_ARGB_PM_to_ARGB,
+ 0,
+#else
+ 0,
+ 0,
+ 0
+#endif
+ } // Format_RGBA8888_Premultiplied
};
static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
{
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
},
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Mono
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_MonoLSB
{
0,
@@ -3247,6 +3744,9 @@ static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
+ 0,
+ 0,
+ 0,
}, // Format_Indexed8
{
0,
@@ -3265,7 +3765,10 @@ static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- }, // Format_ARGB32
+ 0,
+ 0,
+ 0,
+ }, // Format_RGB32
{
0,
0,
@@ -3283,37 +3786,118 @@ static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
+ 0,
+ convert_ARGB_to_RGBA_inplace,
+ 0,
}, // Format_ARGB32
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_ARGB_to_RGBA_inplace
}, // Format_ARGB32_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB16
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8565_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB666
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB6666_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB555
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8555_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB888
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB444
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- } // Format_ARGB4444_Premultiplied
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ convert_RGBA_to_ARGB_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_RGBX8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ convert_RGBA_to_ARGB_PM_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_RGBA8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ } // Format_RGBA8888_Premultiplied
};
void qInitImageConversions()
@@ -3633,6 +4217,10 @@ QRgb QImage::pixel(int x, int y) const
case Format_ARGB32: // Keep old behaviour.
case Format_ARGB32_Premultiplied:
return reinterpret_cast<const QRgb *>(s)[x];
+ case Format_RGBX8888:
+ case Format_RGBA8888: // Match ARGB32 behavior.
+ case Format_RGBA8888_Premultiplied:
+ return RGBA2ARGB(reinterpret_cast<const quint32 *>(s)[x]);
case Format_RGB16:
return qConvertRgb16To32(reinterpret_cast<const quint16 *>(s)[x]);
default:
@@ -3716,6 +4304,13 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
case Format_RGB16:
((quint16 *)s)[x] = qConvertRgb32To16(INV_PREMUL(index_or_rgb));
return;
+ case Format_RGBX8888:
+ ((uint *)s)[x] = ARGB2RGBA(index_or_rgb | 0xff000000);
+ return;
+ case Format_RGBA8888:
+ case Format_RGBA8888_Premultiplied:
+ ((uint *)s)[x] = ARGB2RGBA(index_or_rgb);
+ return;
case Format_Invalid:
case NImageFormats:
Q_ASSERT(false);
@@ -3756,6 +4351,11 @@ bool QImage::allGray() const
case Format_RGB32:
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ case Format_RGBX8888:
+ case Format_RGBA8888:
+ case Format_RGBA8888_Premultiplied:
+#endif
for (int j = 0; j < d->height; ++j) {
const QRgb *b = (const QRgb *)constScanLine(j);
for (int i = 0; i < d->width; ++i) {
@@ -4330,6 +4930,11 @@ QImage QImage::rgbSwapped() const
case Format_RGB32:
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ case Format_RGBX8888:
+ case Format_RGBA8888:
+ case Format_RGBA8888_Premultiplied:
+#endif
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
@@ -5373,7 +5978,11 @@ QImage QImage::alphaChannel() const
}
} else {
QImage alpha32 = *this;
- if (d->format != Format_ARGB32 && d->format != Format_ARGB32_Premultiplied)
+ bool canSkipConversion = (d->format == Format_ARGB32 || d->format == Format_ARGB32_Premultiplied);
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ canSkipConversion = canSkipConversion || (d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied);
+#endif
+ if (!canSkipConversion)
alpha32 = convertToFormat(Format_ARGB32);
const uchar *src_data = alpha32.d->data;
@@ -5408,6 +6017,8 @@ bool QImage::hasAlphaChannel() const
|| d->format == Format_ARGB8555_Premultiplied
|| d->format == Format_ARGB6666_Premultiplied
|| d->format == Format_ARGB4444_Premultiplied
+ || d->format == Format_RGBA8888
+ || d->format == Format_RGBA8888_Premultiplied
|| (d->has_alpha_clut && (d->format == Format_Indexed8
|| d->format == Format_Mono
|| d->format == Format_MonoLSB)));
@@ -5434,6 +6045,7 @@ int QImage::bitPlaneCount() const
case QImage::Format_Invalid:
break;
case QImage::Format_RGB32:
+ case QImage::Format_RGBX8888:
bpc = 24;
break;
case QImage::Format_RGB666:
@@ -5457,9 +6069,11 @@ int QImage::bitPlaneCount() const
static QImage smoothScaled(const QImage &source, int w, int h) {
QImage src = source;
- if (src.format() == QImage::Format_ARGB32)
- src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- else if (src.depth() < 32) {
+ bool canSkipConversion = (src.format() == QImage::Format_RGB32 || src.format() == QImage::Format_ARGB32_Premultiplied);
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ canSkipConversion = canSkipConversion || (src.format() == QImage::Format_RGBX8888 || src.format() == QImage::Format_RGBA8888_Premultiplied);
+#endif
+ if (!canSkipConversion) {
if (src.hasAlphaChannel())
src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied);
else
@@ -5480,6 +6094,9 @@ static QImage rotated90(const QImage &image) {
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied:
qt_memrotate270(reinterpret_cast<const quint32*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint32*>(out.bits()),
@@ -5539,6 +6156,9 @@ static QImage rotated270(const QImage &image) {
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied:
qt_memrotate90(reinterpret_cast<const quint32*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint32*>(out.bits()),
@@ -5684,6 +6304,9 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode
case QImage::Format_RGB444:
target_format = Format_ARGB4444_Premultiplied;
break;
+ case QImage::Format_RGBX8888:
+ target_format = Format_RGBA8888_Premultiplied;
+ break;
default:
target_format = Format_ARGB32_Premultiplied;
break;
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 50d4bc7666..02f0c18243 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -110,6 +110,9 @@ public:
Format_RGB888,
Format_RGB444,
Format_ARGB4444_Premultiplied,
+ Format_RGBX8888,
+ Format_RGBA8888,
+ Format_RGBA8888_Premultiplied,
#if 0
// reserved for future use
Format_RGB15,
@@ -139,6 +142,11 @@ public:
explicit QImage(const QString &fileName, const char *format = 0);
QImage(const QImage &);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QImage(QImage &&other)
+ : QPaintDevice(), d(0)
+ { qSwap(d, other.d); }
+#endif
~QImage();
QImage &operator=(const QImage &);
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 18c686e917..36f117df60 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -128,6 +128,9 @@ inline int qt_depthForFormat(QImage::Format format)
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied:
depth = 32;
break;
case QImage::Format_RGB555:
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index 6fc41df77c..39f63a620c 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -274,12 +274,15 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy
case QImage::Format_RGB555:
case QImage::Format_RGB888:
case QImage::Format_RGB444:
+ case QImage::Format_RGBX8888:
image = image.convertToFormat(QImage::Format_RGB32);
break;
case QImage::Format_ARGB8565_Premultiplied:
case QImage::Format_ARGB6666_Premultiplied:
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_ARGB4444_Premultiplied:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied:
image = image.convertToFormat(QImage::Format_ARGB32);
break;
default:
diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp
index a7936f915d..3bd8ca92b4 100644
--- a/src/gui/image/qxpmhandler.cpp
+++ b/src/gui/image/qxpmhandler.cpp
@@ -1092,7 +1092,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const
return false;
QImage image;
- if (sourceImage.depth() != 32)
+ if (sourceImage.format() != QImage::Format_RGB32 || sourceImage.format() != QImage::Format_ARGB32 || sourceImage.format() != QImage::Format_ARGB32_Premultiplied)
image = sourceImage.convertToFormat(QImage::Format_RGB32);
else
image = sourceImage;
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index fa289bbf8b..49cc411c4f 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -654,6 +654,9 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta
event data: \a qt4Delta specifies the rotation, and \a qt4Orientation the
direction.
+ The phase() is initialized to QWheelEvent::Changed. Use the other constructor
+ to specify the phase explicitly.
+
\sa posF(), globalPosF(), angleDelta(), pixelDelta()
*/
@@ -661,9 +664,38 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
: QInputEvent(Wheel, modifiers), p(pos), g(globalPos), pixelD(pixelDelta),
- angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons)
+ angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), ph(Changed)
{}
+/*!
+ Constructs a wheel event object.
+
+ The \a pos provides the location of the mouse cursor
+ within the window. The position in global coordinates is specified
+ by \a globalPos.
+
+ \a pixelDelta contains the scrolling distance in pixels on screen, while
+ \a angleDelta contains the wheel rotation distance. \a pixelDelta is
+ optional and can be null.
+
+ The mouse and keyboard states at the time of the event are specified by
+ \a buttons and \a modifiers.
+
+ For backwards compatibility, the event can also hold monodirectional wheel
+ event data: \a qt4Delta specifies the rotation, and \a qt4Orientation the
+ direction.
+
+ The phase of the event is specified by \a phase.
+
+ \sa posF(), globalPosF(), angleDelta(), pixelDelta(), phase()
+*/
+
+QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
+ QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Phase phase)
+ : QInputEvent(Wheel, modifiers), p(pos), g(globalPos), pixelD(pixelDelta),
+ angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), ph(phase)
+{}
#endif // QT_NO_WHEELEVENT
@@ -794,6 +826,28 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
\sa posF()
*/
+/*!
+ \enum QWheelEvent::Phase
+ \since 5.2
+
+ This enum describes the phase of a wheel event.
+
+ \value Started Scrolling has started, but the scrolling
+ distance did not yet change.
+
+ \value Changed The scrolling distance has changed (default).
+
+ \value Ended Scrolling has ended, but the scrolling distance
+ did not change anymore.
+*/
+
+/*!
+ \fn QWheelEvent::Phase QWheelEvent::phase() const
+ \since 5.2
+
+ Returns the phase of this wheel event.
+*/
+
/*!
\class QKeyEvent
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 7142450322..2de88cf010 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -167,6 +167,8 @@ protected:
class Q_GUI_EXPORT QWheelEvent : public QInputEvent
{
public:
+ enum Phase { Started, Changed, Ended };
+
QWheelEvent(const QPointF &pos, int delta,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
Qt::Orientation orient = Qt::Vertical);
@@ -176,6 +178,9 @@ public:
QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
+ QWheelEvent(const QPointF &pos, const QPointF& globalPos,
+ QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Phase phase);
~QWheelEvent();
@@ -198,6 +203,9 @@ public:
inline const QPointF &globalPosF() const { return g; }
inline Qt::MouseButtons buttons() const { return mouseState; }
+
+ inline Phase phase() const { return Phase(ph); }
+
protected:
QPointF p;
QPointF g;
@@ -206,7 +214,8 @@ protected:
int qt4D;
Qt::Orientation qt4O;
Qt::MouseButtons mouseState;
- int reserved;
+ uint ph : 2;
+ int reserved : 30;
};
#endif
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 7d2c710c52..6be3b066d8 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -101,6 +101,8 @@
# include <QtCore/QLibraryInfo>
#endif // Q_OS_WIN && !Q_OS_WINCE
+#include <ctype.h>
+
QT_BEGIN_NAMESPACE
Q_GUI_EXPORT bool qt_is_gui_used = true;
@@ -215,6 +217,106 @@ static inline bool isPopupWindow(const QWindow *w)
return (w->flags() & Qt::WindowType_Mask) == Qt::Popup;
}
+// Geometry specification for top level windows following the convention of the
+// -geometry command line arguments in X11 (see XParseGeometry).
+struct QWindowGeometrySpecification
+{
+ QWindowGeometrySpecification() : corner(Qt::TopLeftCorner), xOffset(-1), yOffset(-1), width(-1), height(-1) {}
+ static QWindowGeometrySpecification fromArgument(const QByteArray &a);
+ QRect apply(const QRect &windowGeometry, const QSize &windowMinimumSize, const QSize &windowMaximumSize, const QRect &availableGeometry) const;
+ inline QRect apply(const QRect &windowGeometry, const QWindow *window) const
+ { return apply(windowGeometry, window->minimumSize(), window->maximumSize(), window->screen()->virtualGeometry()); }
+
+ Qt::Corner corner;
+ int xOffset;
+ int yOffset;
+ int width;
+ int height;
+};
+
+// Parse a token of a X11 geometry specification "200x100+10-20".
+static inline int nextGeometryToken(const QByteArray &a, int &pos, char *op)
+{
+ *op = 0;
+ const int size = a.size();
+ if (pos >= size)
+ return -1;
+
+ *op = a.at(pos);
+ if (*op == '+' || *op == '-' || *op == 'x')
+ pos++;
+ else if (isdigit(*op))
+ *op = 'x'; // If it starts with a digit, it is supposed to be a width specification.
+ else
+ return -1;
+
+ const int numberPos = pos;
+ for ( ; pos < size && isdigit(a.at(pos)); ++pos) ;
+
+ bool ok;
+ const int result = a.mid(numberPos, pos - numberPos).toInt(&ok);
+ return ok ? result : -1;
+}
+
+QWindowGeometrySpecification QWindowGeometrySpecification::fromArgument(const QByteArray &a)
+{
+ QWindowGeometrySpecification result;
+ int pos = 0;
+ for (int i = 0; i < 4; ++i) {
+ char op;
+ const int value = nextGeometryToken(a, pos, &op);
+ if (value < 0)
+ break;
+ switch (op) {
+ case 'x':
+ (result.width >= 0 ? result.height : result.width) = value;
+ break;
+ case '+':
+ case '-':
+ if (result.xOffset >= 0) {
+ result.yOffset = value;
+ if (op == '-')
+ result.corner = result.corner == Qt::TopRightCorner ? Qt::BottomRightCorner : Qt::BottomLeftCorner;
+ } else {
+ result.xOffset = value;
+ if (op == '-')
+ result.corner = Qt::TopRightCorner;
+ }
+ }
+ }
+ return result;
+}
+
+QRect QWindowGeometrySpecification::apply(const QRect &windowGeometry, const QSize &windowMinimumSize, const QSize &windowMaximumSize, const QRect &availableGeometry) const
+{
+ QRect result = windowGeometry;
+ if (width >= 0 || height >= 0) {
+ QSize size = windowGeometry.size();
+ if (width >= 0)
+ size.setWidth(qBound(windowMinimumSize.width(), width, windowMaximumSize.width()));
+ if (height >= 0)
+ size.setHeight(qBound(windowMinimumSize.height(), height, windowMaximumSize.height()));
+ result.setSize(size);
+ }
+ if (xOffset >= 0 || yOffset >= 0) {
+ QPoint topLeft = windowGeometry.topLeft();
+ if (xOffset >= 0) {
+ topLeft.setX(corner == Qt::TopLeftCorner || corner == Qt::BottomLeftCorner ?
+ xOffset :
+ qMax(availableGeometry.right() - result.width() - xOffset, availableGeometry.left()));
+ }
+ if (yOffset >= 0) {
+ topLeft.setY(corner == Qt::TopLeftCorner || corner == Qt::TopRightCorner ?
+ yOffset :
+ qMax(availableGeometry.bottom() - result.height() - yOffset, availableGeometry.top()));
+ }
+ result.moveTopLeft(topLeft);
+ }
+ return result;
+}
+
+static QWindowGeometrySpecification windowGeometrySpecification;
+
/*!
\class QGuiApplication
\brief The QGuiApplication class manages the GUI application's control
@@ -785,14 +887,14 @@ QString QGuiApplication::platformName()
*QGuiApplicationPrivate::platform_name : QString();
}
-static void init_platform(const QString &pluginArgument, const QString &platformPluginPath)
+static void init_platform(const QString &pluginArgument, const QString &platformPluginPath, int &argc, char **argv)
{
// Split into platform name and arguments
QStringList arguments = pluginArgument.split(QLatin1Char(':'));
const QString name = arguments.takeFirst().toLower();
// Create the platform integration.
- QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, platformPluginPath);
+ QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath);
if (QGuiApplicationPrivate::platform_integration) {
QGuiApplicationPrivate::platform_name = new QString(name);
} else {
@@ -910,6 +1012,9 @@ void QGuiApplicationPrivate::createPlatformIntegration()
} else if (arg == "-platform") {
if (++i < argc)
platformName = argv[i];
+ } else if (arg == "-qwindowgeometry" || (platformName == "xcb" && arg == "-geometry")) {
+ if (++i < argc)
+ windowGeometrySpecification = QWindowGeometrySpecification::fromArgument(argv[i]);
} else {
argv[j++] = argv[i];
}
@@ -920,7 +1025,7 @@ void QGuiApplicationPrivate::createPlatformIntegration()
argc = j;
}
- init_platform(QLatin1String(platformName), platformPluginPath);
+ init_platform(QLatin1String(platformName), platformPluginPath, argc, argv);
}
@@ -1375,6 +1480,8 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
static_cast<QWindowSystemInterfacePrivate::ContextMenuEvent *>(e));
break;
#endif
+ case QWindowSystemInterfacePrivate::EnterWhatsThisMode:
+ QGuiApplication::postEvent(QGuiApplication::instance(), new QEvent(QEvent::EnterWhatsThisMode));
default:
qWarning() << "Unknown user input event type:" << e->type;
break;
@@ -1531,7 +1638,7 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
return;
}
- QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, buttons, e->modifiers);
+ QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, buttons, e->modifiers, e->phase);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &ev);
#endif /* ifndef QT_NO_WHEELEVENT */
@@ -2398,6 +2505,11 @@ void QGuiApplication::setPalette(const QPalette &pal)
applicationResourceFlags |= ApplicationPaletteExplicitlySet;
}
+QRect QGuiApplicationPrivate::applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window)
+{
+ return windowGeometrySpecification.apply(windowGeometry, window);
+}
+
/*!
Returns the default application font.
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 3a4b692b69..11f68ba2ff 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -275,6 +275,8 @@ public:
// hook reimplemented in QApplication to apply the QStyle function on the QIcon
virtual QPixmap applyQIconStyleHelper(QIcon::Mode, const QPixmap &basePixmap) const { return basePixmap; }
+ static QRect applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window);
+
protected:
virtual void notifyThemeChanged();
#ifndef QT_NO_DRAGANDDROP
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index af3a46c675..6933f26816 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -637,6 +637,14 @@ static const struct {
{ Qt::Key_Hangul_PostHanja,QT_TRANSLATE_NOOP("QShortcut", "Hangul PostHanja") },
{ Qt::Key_Hangul_Special, QT_TRANSLATE_NOOP("QShortcut", "Hangul Special") },
+ // --------------------------------------------------------------
+ // Miscellaenous keys
+ { Qt::Key_Cancel, QT_TRANSLATE_NOOP("QShortcut", "Cancel") },
+ { Qt::Key_Printer, QT_TRANSLATE_NOOP("QShortcut", "Printer") },
+ { Qt::Key_Execute, QT_TRANSLATE_NOOP("QShortcut", "Execute") },
+ { Qt::Key_Play, QT_TRANSLATE_NOOP("QShortcut", "Play") },
+ { Qt::Key_Zoom, QT_TRANSLATE_NOOP("QShortcut", "Zoom") },
+
{ 0, 0 }
};
diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h
index 05460c6651..8a989682d8 100644
--- a/src/gui/kernel/qkeysequence.h
+++ b/src/gui/kernel/qkeysequence.h
@@ -44,6 +44,7 @@
#include <QtCore/qnamespace.h>
#include <QtCore/qstring.h>
+#include <QtCore/qobjectdefs.h>
QT_BEGIN_NAMESPACE
@@ -68,6 +69,9 @@ class QKeySequencePrivate;
class Q_GUI_EXPORT QKeySequence
{
+ Q_GADGET
+ Q_ENUMS(StandardKey)
+
public:
enum StandardKey {
UnknownKey,
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp
index 5f86b511f7..74442736c3 100644
--- a/src/gui/kernel/qplatformdialoghelper.cpp
+++ b/src/gui/kernel/qplatformdialoghelper.cpp
@@ -376,9 +376,9 @@ public:
QStringList nameFilters;
QString defaultSuffix;
QStringList history;
- QString initialDirectory;
+ QUrl initialDirectory;
QString initiallySelectedNameFilter;
- QStringList initiallySelectedFiles;
+ QList<QUrl> initiallySelectedFiles;
};
QFileDialogOptions::QFileDialogOptions() : d(new QFileDialogOptionsPrivate)
@@ -495,6 +495,8 @@ QStringList QFileDialogOptions::nameFilters() const
void QFileDialogOptions::setDefaultSuffix(const QString &suffix)
{
d->defaultSuffix = suffix;
+ if (d->defaultSuffix.size() > 1 && d->defaultSuffix.startsWith(QLatin1Char('.')))
+ d->defaultSuffix.remove(0, 1); // Silently change ".txt" -> "txt".
}
QString QFileDialogOptions::defaultSuffix() const
@@ -528,12 +530,12 @@ bool QFileDialogOptions::isLabelExplicitlySet(DialogLabel label)
return label >= 0 && label < DialogLabelCount && !d->labels[label].isEmpty();
}
-QString QFileDialogOptions::initialDirectory() const
+QUrl QFileDialogOptions::initialDirectory() const
{
return d->initialDirectory;
}
-void QFileDialogOptions::setInitialDirectory(const QString &directory)
+void QFileDialogOptions::setInitialDirectory(const QUrl &directory)
{
d->initialDirectory = directory;
}
@@ -548,16 +550,21 @@ void QFileDialogOptions::setInitiallySelectedNameFilter(const QString &filter)
d->initiallySelectedNameFilter = filter;
}
-QStringList QFileDialogOptions::initiallySelectedFiles() const
+QList<QUrl> QFileDialogOptions::initiallySelectedFiles() const
{
return d->initiallySelectedFiles;
}
-void QFileDialogOptions::setInitiallySelectedFiles(const QStringList &files)
+void QFileDialogOptions::setInitiallySelectedFiles(const QList<QUrl> &files)
{
d->initiallySelectedFiles = files;
}
+bool QPlatformFileDialogHelper::isSupportedUrl(const QUrl &url) const
+{
+ return url.isLocalFile();
+}
+
/*!
\class QPlatformFileDialogHelper
\since 5.0
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index ecc00ed8c6..092839aaed 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -57,6 +57,7 @@
#include <QtCore/QSharedDataPointer>
#include <QtCore/QSharedPointer>
#include <QtCore/QDir>
+#include <QtCore/QUrl>
#include <QtGui/QRgb>
QT_BEGIN_NAMESPACE
@@ -163,7 +164,11 @@ class Q_GUI_EXPORT QFontDialogOptions
public:
enum FontDialogOption {
NoButtons = 0x00000001,
- DontUseNativeDialog = 0x00000002
+ DontUseNativeDialog = 0x00000002,
+ ScalableFonts = 0x00000004,
+ NonScalableFonts = 0x00000008,
+ MonospacedFonts = 0x00000010,
+ ProportionalFonts = 0x00000020
};
Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption)
@@ -217,13 +222,14 @@ public:
enum FileDialogOption
{
- ShowDirsOnly = 0x00000001,
- DontResolveSymlinks = 0x00000002,
- DontConfirmOverwrite = 0x00000004,
- DontUseSheet = 0x00000008,
- DontUseNativeDialog = 0x00000010,
- ReadOnly = 0x00000020,
- HideNameFilterDetails = 0x00000040
+ ShowDirsOnly = 0x00000001,
+ DontResolveSymlinks = 0x00000002,
+ DontConfirmOverwrite = 0x00000004,
+ DontUseSheet = 0x00000008,
+ DontUseNativeDialog = 0x00000010,
+ ReadOnly = 0x00000020,
+ HideNameFilterDetails = 0x00000040,
+ DontUseCustomDirectoryIcons = 0x00000080
};
Q_DECLARE_FLAGS(FileDialogOptions, FileDialogOption)
@@ -270,14 +276,14 @@ public:
QString labelText(DialogLabel label) const;
bool isLabelExplicitlySet(DialogLabel label);
- QString initialDirectory() const;
- void setInitialDirectory(const QString &);
+ QUrl initialDirectory() const;
+ void setInitialDirectory(const QUrl &);
QString initiallySelectedNameFilter() const;
void setInitiallySelectedNameFilter(const QString &);
- QStringList initiallySelectedFiles() const;
- void setInitiallySelectedFiles(const QStringList &);
+ QList<QUrl> initiallySelectedFiles() const;
+ void setInitiallySelectedFiles(const QList<QUrl> &);
private:
QSharedDataPointer<QFileDialogOptionsPrivate> d;
@@ -290,14 +296,16 @@ class Q_GUI_EXPORT QPlatformFileDialogHelper : public QPlatformDialogHelper
Q_OBJECT
public:
virtual bool defaultNameFilterDisables() const = 0;
- virtual void setDirectory(const QString &directory) = 0;
- virtual QString directory() const = 0;
- virtual void selectFile(const QString &filename) = 0;
- virtual QStringList selectedFiles() const = 0;
+ virtual void setDirectory(const QUrl &directory) = 0;
+ virtual QUrl directory() const = 0;
+ virtual void selectFile(const QUrl &filename) = 0;
+ virtual QList<QUrl> selectedFiles() const = 0;
virtual void setFilter() = 0;
virtual void selectNameFilter(const QString &filter) = 0;
virtual QString selectedNameFilter() const = 0;
+ virtual bool isSupportedUrl(const QUrl &url) const;
+
const QSharedPointer<QFileDialogOptions> &options() const;
void setOptions(const QSharedPointer<QFileDialogOptions> &options);
@@ -305,10 +313,10 @@ public:
static const char *filterRegExp;
Q_SIGNALS:
- void fileSelected(const QString &file);
- void filesSelected(const QStringList &files);
- void currentChanged(const QString &path);
- void directoryEntered(const QString &directory);
+ void fileSelected(const QUrl &file);
+ void filesSelected(const QList<QUrl> &files);
+ void currentChanged(const QUrl &path);
+ void directoryEntered(const QUrl &directory);
void filterSelected(const QString &filter);
private:
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index e4f45ebb6e..434344df08 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -237,7 +237,7 @@ QPlatformServices *QPlatformIntegration::services() const
bool QPlatformIntegration::hasCapability(Capability cap) const
{
- return cap == NonFullScreenWindows;
+ return cap == NonFullScreenWindows || cap == NativeWidgets;
}
QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
@@ -328,6 +328,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
return QVariant(false);
case SynthesizeMouseFromTouchEvents:
return true;
+ case SetFocusOnTouchRelease:
+ return QVariant(false);
}
return 0;
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index b7a44b13de..9350553efd 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -91,7 +91,8 @@ public:
MultipleWindows,
ApplicationState,
ForeignWindows,
- NonFullScreenWindows
+ NonFullScreenWindows,
+ NativeWidgets
};
virtual ~QPlatformIntegration() { }
@@ -141,7 +142,8 @@ public:
StartDragVelocity,
UseRtlExtensions,
SynthesizeMouseFromTouchEvents,
- PasswordMaskCharacter
+ PasswordMaskCharacter,
+ SetFocusOnTouchRelease
};
virtual QVariant styleHint(StyleHint hint) const;
diff --git a/src/gui/kernel/qplatformintegrationfactory.cpp b/src/gui/kernel/qplatformintegrationfactory.cpp
index 21f53d17de..365edd2010 100644
--- a/src/gui/kernel/qplatformintegrationfactory.cpp
+++ b/src/gui/kernel/qplatformintegrationfactory.cpp
@@ -55,18 +55,30 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QPlatformIntegrationFactoryInterface_iid, QLatin1String("/platforms"), Qt::CaseInsensitive))
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader,
(QPlatformIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive))
-#endif
-QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platform, const QStringList &paramList, const QString &platformPluginPath)
+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)
{
#ifndef QT_NO_LIBRARY
// Try loading the plugin from platformPluginPath first:
if (!platformPluginPath.isEmpty()) {
QCoreApplication::addLibraryPath(platformPluginPath);
- if (QPlatformIntegration *ret = qLoadPlugin1<QPlatformIntegration, QPlatformIntegrationPlugin>(directLoader(), platform, paramList))
+ if (QPlatformIntegration *ret = loadIntegration(directLoader(), platform, paramList, argc, argv))
return ret;
}
- if (QPlatformIntegration *ret = qLoadPlugin1<QPlatformIntegration, QPlatformIntegrationPlugin>(loader(), platform, paramList))
+ if (QPlatformIntegration *ret = loadIntegration(loader(), platform, paramList, argc, argv))
return ret;
#endif
return 0;
diff --git a/src/gui/kernel/qplatformintegrationfactory_p.h b/src/gui/kernel/qplatformintegrationfactory_p.h
index fb3ba55316..bc8ce11609 100644
--- a/src/gui/kernel/qplatformintegrationfactory_p.h
+++ b/src/gui/kernel/qplatformintegrationfactory_p.h
@@ -64,7 +64,7 @@ class Q_GUI_EXPORT QPlatformIntegrationFactory
{
public:
static QStringList keys(const QString &platformPluginPath = QString());
- static QPlatformIntegration *create(const QString &name, const QStringList &args, const QString &platformPluginPath = QString());
+ static QPlatformIntegration *create(const QString &name, const QStringList &args, int &argc, char **argv, const QString &platformPluginPath = QString());
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegrationplugin.cpp b/src/gui/kernel/qplatformintegrationplugin.cpp
index 0f7f365d2a..2a9a047141 100644
--- a/src/gui/kernel/qplatformintegrationplugin.cpp
+++ b/src/gui/kernel/qplatformintegrationplugin.cpp
@@ -52,4 +52,18 @@ QPlatformIntegrationPlugin::~QPlatformIntegrationPlugin()
{
}
+QPlatformIntegration *QPlatformIntegrationPlugin::create(const QString &key, const QStringList &paramList)
+{
+ Q_UNUSED(key)
+ Q_UNUSED(paramList);
+ return 0;
+}
+
+QPlatformIntegration *QPlatformIntegrationPlugin::create(const QString &key, const QStringList &paramList, int &argc, char **argv)
+{
+ Q_UNUSED(argc)
+ Q_UNUSED(argv)
+ return create(key, paramList); // Fallback for platform plugins that do not implement the argc/argv version.
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegrationplugin.h b/src/gui/kernel/qplatformintegrationplugin.h
index 434366f0b0..e624e2d31d 100644
--- a/src/gui/kernel/qplatformintegrationplugin.h
+++ b/src/gui/kernel/qplatformintegrationplugin.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
class QPlatformIntegration;
-#define QPlatformIntegrationFactoryInterface_iid "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1"
+#define QPlatformIntegrationFactoryInterface_iid "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2"
class Q_GUI_EXPORT QPlatformIntegrationPlugin : public QObject
{
@@ -68,7 +68,8 @@ public:
explicit QPlatformIntegrationPlugin(QObject *parent = 0);
~QPlatformIntegrationPlugin();
- virtual QPlatformIntegration *create(const QString &key, const QStringList &paramList) = 0;
+ virtual QPlatformIntegration *create(const QString &key, const QStringList &paramList);
+ virtual QPlatformIntegration *create(const QString &key, const QStringList &paramList, int &argc, char **argv);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformservices.cpp b/src/gui/kernel/qplatformservices.cpp
index f2cade0a35..d09b74c6fe 100644
--- a/src/gui/kernel/qplatformservices.cpp
+++ b/src/gui/kernel/qplatformservices.cpp
@@ -74,7 +74,10 @@ bool QPlatformServices::openDocument(const QUrl &url)
/*!
* \brief QPlatformServices::desktopEnvironment returns the active desktop environment.
*
- * On Unix this function returns KDE, GNOME or UNKNOWN.
+ * On Unix this function returns the uppercase desktop environment name, such as
+ * KDE, GNOME, UNITY, XFCE, LXDE etc. or UNKNOWN if none was detected.
+ * The primary way to detect the desktop environment is the environment variable
+ * XDG_CURRENT_DESKTOP.
*/
QByteArray QPlatformServices::desktopEnvironment() const
{
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 02b69bcb4d..098b8dad66 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -208,10 +208,12 @@ QPixmap QPlatformTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) co
return QPixmap();
}
-QPixmap QPlatformTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const
+QPixmap QPlatformTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions) const
{
Q_UNUSED(fileInfo);
Q_UNUSED(size);
+ Q_UNUSED(iconOptions);
// TODO Should return QCommonStyle pixmaps?
return QPixmap();
}
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 80ba29a028..1d7a1ccffa 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -154,6 +154,7 @@ public:
ComboLineEditFont,
SmallFont,
MiniFont,
+ FixedFont,
NFonts
};
@@ -253,6 +254,11 @@ public:
AnimateToolBoxUiEffect = 0x40
};
+ enum IconOption {
+ DontUseCustomDirectoryIcons = 0x01
+ };
+ Q_DECLARE_FLAGS(IconOptions, IconOption)
+
explicit QPlatformTheme();
virtual ~QPlatformTheme();
@@ -274,7 +280,8 @@ public:
virtual QVariant themeHint(ThemeHint hint) const;
virtual QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const;
- virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const;
+ virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions = 0) const;
virtual QIconEngine *createIconEngine(const QString &iconName) const;
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index cd822090e2..513e21937e 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -324,6 +324,9 @@ bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e)
{
Q_D(QShortcutMap);
+ if (e->key() == Qt::Key_unknown)
+ return false;
+
bool wasAccepted = e->isAccepted();
bool wasSpontaneous = e->spont;
if (d->currentState == QKeySequence::NoMatch) {
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 30b12835f7..a302f2186c 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -218,4 +218,15 @@ bool QStyleHints::useRtlExtensions() const
return hint(QPlatformIntegration::UseRtlExtensions).toBool();
}
+/*!
+ Returns \c true if focus objects (line edits etc) should receive
+ input focus after a touch/mouse release. This is normal behavior on
+ touch platforms. On desktop platforms, the standard is to set
+ focus already on touch/mouse press.
+*/
+bool QStyleHints::setFocusOnTouchRelease() const
+{
+ return hint(QPlatformIntegration::SetFocusOnTouchRelease).toBool();
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index 64ef182aab..a0facd5f94 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -65,6 +65,7 @@ public:
QChar passwordMaskCharacter() const;
qreal fontSmoothingGamma() const;
bool useRtlExtensions() const;
+ bool setFocusOnTouchRelease() const;
private:
friend class QGuiApplication;
diff --git a/src/gui/kernel/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp
index 02c6dd9efc..3ad4b4161e 100644
--- a/src/gui/kernel/qtouchdevice.cpp
+++ b/src/gui/kernel/qtouchdevice.cpp
@@ -140,6 +140,16 @@ QTouchDevice::Capabilities QTouchDevice::capabilities() const
}
/*!
+ Returns the maximum number of simultaneous touch points (fingers) that
+ can be detected.
+ \since 5.2
+ */
+int QTouchDevice::maximumTouchPoints() const
+{
+ return d->maxTouchPoints;
+}
+
+/*!
Returns the touch device name.
This string may often be empty. It is however useful for systems that have
@@ -169,6 +179,15 @@ void QTouchDevice::setCapabilities(Capabilities caps)
}
/*!
+ Sets the maximum number of simultaneous touchpoints \a max
+ supported by the device and its driver.
+ */
+void QTouchDevice::setMaximumTouchPoints(int max)
+{
+ d->maxTouchPoints = max;
+}
+
+/*!
Sets the \a name (a unique identifier) for the device. In most systems it is
enough to leave this unset and keep the default empty name. This identifier
becomes important when having multiple touch devices and a need to
diff --git a/src/gui/kernel/qtouchdevice.h b/src/gui/kernel/qtouchdevice.h
index 312bdce3e6..6aca93907c 100644
--- a/src/gui/kernel/qtouchdevice.h
+++ b/src/gui/kernel/qtouchdevice.h
@@ -75,10 +75,12 @@ public:
QString name() const;
DeviceType type() const;
Capabilities capabilities() const;
+ int maximumTouchPoints() const;
void setName(const QString &name);
void setType(DeviceType devType);
void setCapabilities(Capabilities caps);
+ void setMaximumTouchPoints(int max);
private:
QTouchDevicePrivate *d;
diff --git a/src/gui/kernel/qtouchdevice_p.h b/src/gui/kernel/qtouchdevice_p.h
index 435f8a5c37..fb87f49736 100644
--- a/src/gui/kernel/qtouchdevice_p.h
+++ b/src/gui/kernel/qtouchdevice_p.h
@@ -64,12 +64,14 @@ class QTouchDevicePrivate
public:
QTouchDevicePrivate()
: type(QTouchDevice::TouchScreen),
- caps(QTouchDevice::Position)
+ caps(QTouchDevice::Position),
+ maxTouchPoints(1)
{ }
QTouchDevice::DeviceType type;
QTouchDevice::Capabilities caps;
QString name;
+ int maxTouchPoints;
static void registerDevice(QTouchDevice *dev);
static bool isRegistered(QTouchDevice *dev);
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 6fc63fe96c..b094ccb33b 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -298,13 +298,13 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
handleWheelEvent(tlw, timestamp, local, global, QPoint(), point, mods);
}
-void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods, QWheelEvent::Phase phase)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleWheelEvent(w, time, local, global, pixelDelta, angleDelta, mods);
+ handleWheelEvent(w, time, local, global, pixelDelta, angleDelta, mods, phase);
}
-void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods, QWheelEvent::Phase phase)
{
// Qt 4 sends two separate wheel events for horizontal and vertical
// deltas. For Qt 5 we want to send the deltas in one event, but at the
@@ -315,19 +315,21 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Angle deltas must always be sent in addition to pixel deltas.
QWindowSystemInterfacePrivate::WheelEvent *e;
- if (angleDelta.isNull())
+ // Pass QWheelEvent::Started and QWheelEvent::Ended through
+ // even if the wheel delta is null.
+ if (angleDelta.isNull() && phase == QWheelEvent::Changed)
return;
// Simple case: vertical deltas only:
if (angleDelta.y() != 0 && angleDelta.x() == 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
// Simple case: horizontal deltas only:
if (angleDelta.y() == 0 && angleDelta.x() != 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
@@ -335,12 +337,12 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Both horizontal and vertical deltas: Send two wheel events.
// The first event contains the Qt 5 pixel and angle delta as points,
// and in addition the Qt 4 compatibility vertical angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
// The second event contains null pixel and angle points and the
// Qt 4 compatibility horizontal angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -692,6 +694,15 @@ void QWindowSystemInterface::handleContextMenuEvent(QWindow *w, bool mouseTrigge
}
#endif
+#ifndef QT_NO_WHATSTHIS
+void QWindowSystemInterface::handleEnterWhatsThisEvent()
+{
+ QWindowSystemInterfacePrivate::WindowSystemEvent *e =
+ new QWindowSystemInterfacePrivate::WindowSystemEvent(QWindowSystemInterfacePrivate::EnterWhatsThisMode);
+ QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+}
+#endif
+
#ifndef QT_NO_DEBUG_STREAM
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPoint &p) {
dbg.nospace() << "TouchPoint(" << p.id << " @" << p.normalPosition << " press " << p.pressure << " vel " << p.velocity << " state " << (int)p.state;
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index b0327701bb..f9efdbf8ce 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -61,6 +61,7 @@
#include <QtGui/QTouchEvent>
#include <QtCore/QEventLoop>
#include <QtGui/QVector2D>
+#include <QtGui/QWheelEvent>
QT_BEGIN_NAMESPACE
@@ -103,8 +104,8 @@ public:
quint32 nativeModifiers,
const QString& text = QString(), bool autorep = false,
ushort count = 1);
- static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier);
- static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier);
+ static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier, QWheelEvent::Phase phase = QWheelEvent::Changed);
+ static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier, QWheelEvent::Phase phase = QWheelEvent::Changed);
// Wheel event compatibility functions. Will be removed: do not use.
static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods = Qt::NoModifier);
@@ -183,6 +184,9 @@ public:
const QPoint &pos, const QPoint &globalPos,
Qt::KeyboardModifiers modifiers);
#endif
+#ifndef QT_NO_WHATSTHIS
+ static void handleEnterWhatsThisEvent();
+#endif
// For event dispatcher implementations
static bool sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags);
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 398df0a96f..7dbc3ad8ed 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -90,6 +90,7 @@ public:
TabletLeaveProximity = UserInputEvent | 0x16,
PlatformPanel = UserInputEvent | 0x17,
ContextMenu = UserInputEvent | 0x18,
+ EnterWhatsThisMode = UserInputEvent | 0x19,
ApplicationStateChanged = 0x19,
FlushEvents = 0x20,
WindowScreenChanged = 0x21
@@ -217,14 +218,15 @@ public:
class WheelEvent : public InputEvent {
public:
WheelEvent(QWindow *w, ulong time, const QPointF & local, const QPointF & global, QPoint pixelD, QPoint angleD, int qt4D, Qt::Orientation qt4O,
- Qt::KeyboardModifiers mods)
- : InputEvent(w, time, Wheel, mods), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D), qt4Orientation(qt4O), localPos(local), globalPos(global) { }
+ Qt::KeyboardModifiers mods, QWheelEvent::Phase phase = QWheelEvent::Changed)
+ : InputEvent(w, time, Wheel, mods), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D), qt4Orientation(qt4O), localPos(local), globalPos(global), phase(phase) { }
QPoint pixelDelta;
QPoint angleDelta;
int qt4Delta;
Qt::Orientation qt4Orientation;
QPointF localPos;
QPointF globalPos;
+ QWheelEvent::Phase phase;
};
class KeyEvent : public InputEvent {
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 90416db72b..247ecf7351 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -1012,23 +1012,28 @@ QOpenGLFramebufferObjectFormat QOpenGLFramebufferObject::format() const
Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
{
- QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
- : QImage::Format_RGB32);
int w = size.width();
int h = size.height();
+ while (glGetError());
+
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_RGB32);
#ifdef QT_OPENGL_ES
GLint fmt = GL_BGRA_EXT;
#else
GLint fmt = GL_BGRA;
#endif
- while (glGetError());
glReadPixels(0, 0, w, h, fmt, GL_UNSIGNED_BYTE, img.bits());
- if (glGetError()) {
- glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
- img = img.rgbSwapped();
- }
- return img.mirrored();
+ if (!glGetError())
+ return img.mirrored();
+#endif
+
+ QImage rgbaImage(size, (alpha_format && include_alpha) ? QImage::Format_RGBA8888_Premultiplied
+ : QImage::Format_RGBX8888);
+ glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgbaImage.bits());
+ return rgbaImage.mirrored();
}
/*!
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 3737df7497..60591a34d2 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -141,8 +141,8 @@ QT_BEGIN_NAMESPACE
/*!
\enum QOpenGLFunctions::OpenGLFeature
- This enum defines OpenGL/ES 2.0 features that may be optional
- on other platforms.
+ This enum defines OpenGL and OpenGL ES features whose presence
+ may depend on the implementation.
\value Multitexture glActiveTexture() function is available.
\value Shaders Shader functions are available.
@@ -158,6 +158,7 @@ QT_BEGIN_NAMESPACE
\value StencilSeparate Separate stencil functions are available.
\value NPOTTextures Non power of two textures are available.
\value NPOTTextureRepeat Non power of two textures can use GL_REPEAT as wrap parameter.
+ \value FixedFunctionPipeline The fixed function pipeline is available.
*/
// Hidden private fields for additional extension data.
@@ -331,6 +332,13 @@ static int qt_gl_resolve_features()
if (format.majorVersion() >= 3)
features |= QOpenGLFunctions::Framebuffers;
+ const QPair<int, int> version = format.version();
+ if (version < qMakePair(3, 0)
+ || (version == qMakePair(3, 0) && format.testOption(QSurfaceFormat::DeprecatedFunctions))
+ || (version == qMakePair(3, 1) && extensions.match("GL_ARB_compatibility"))
+ || (version >= qMakePair(3, 2) && format.profile() == QSurfaceFormat::CompatibilityProfile)) {
+ features |= QOpenGLFunctions::FixedFunctionPipeline;
+ }
return features;
#endif
}
diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h
index 1548ad4a24..9d8da209ad 100644
--- a/src/gui/opengl/qopenglfunctions.h
+++ b/src/gui/opengl/qopenglfunctions.h
@@ -199,7 +199,8 @@ public:
Multisample = 0x0400,
StencilSeparate = 0x0800,
NPOTTextures = 0x1000,
- NPOTTextureRepeat = 0x2000
+ NPOTTextureRepeat = 0x2000,
+ FixedFunctionPipeline = 0x4000
};
Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature)
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 47ba27d72a..aadcc0f686 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -91,9 +91,12 @@ SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp
AVX_SOURCES += painting/qdrawhelper_avx.cpp
-NEON_SOURCES += painting/qdrawhelper_neon.cpp
-NEON_HEADERS += painting/qdrawhelper_neon_p.h
-NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
+
+!ios {
+ NEON_SOURCES += painting/qdrawhelper_neon.cpp
+ NEON_HEADERS += painting/qdrawhelper_neon_p.h
+ NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
+}
MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp_p.h
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 6d9168ecf4..23eaa9a3e7 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -604,7 +604,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Mono
0, // Format_Invalid,
@@ -622,7 +625,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_MonoLSB
0, // Format_Invalid,
@@ -640,7 +646,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Indexed8
0, // Format_Invalid,
@@ -658,7 +667,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB32
0, // Format_Invalid,
@@ -676,7 +688,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32
0, // Format_Invalid,
@@ -694,7 +709,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32_Premultiplied
0, // Format_Invalid,
@@ -712,7 +730,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB16
0, // Format_Invalid,
@@ -730,7 +751,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8565_Premultiplied
0, // Format_Invalid,
@@ -748,7 +772,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB666
0, // Format_Invalid,
@@ -766,7 +793,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB6666_Premultiplied
0, // Format_Invalid,
@@ -784,7 +814,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB555
0, // Format_Invalid,
@@ -802,7 +835,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8555_Premultiplied
0, // Format_Invalid,
@@ -820,7 +856,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB888
0, // Format_Invalid,
@@ -838,7 +877,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB444
0, // Format_Invalid,
@@ -856,7 +898,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB4444_Premultiplied
0, // Format_Invalid,
@@ -874,7 +919,85 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBX8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_scale_image_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_scale_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
+ },
+ { // Format_RGBA8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBA8888_Premultiplied
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_scale_image_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_scale_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
}
};
@@ -896,7 +1019,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Mono
0, // Format_Invalid,
@@ -914,7 +1040,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_MonoLSB
0, // Format_Invalid,
@@ -932,7 +1061,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Indexed8
0, // Format_Invalid,
@@ -950,7 +1082,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB32
0, // Format_Invalid,
@@ -968,7 +1103,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32
0, // Format_Invalid,
@@ -986,7 +1124,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32_Premultiplied
0, // Format_Invalid,
@@ -1004,7 +1145,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB16
0, // Format_Invalid,
@@ -1022,7 +1166,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8565_Premultiplied
0, // Format_Invalid,
@@ -1040,7 +1187,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB666
0, // Format_Invalid,
@@ -1058,7 +1208,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB6666_Premultiplied
0, // Format_Invalid,
@@ -1076,7 +1229,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB555
0, // Format_Invalid,
@@ -1094,7 +1250,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8555_Premultiplied
0, // Format_Invalid,
@@ -1112,7 +1271,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB888
0, // Format_Invalid,
@@ -1130,7 +1292,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB444
0, // Format_Invalid,
@@ -1148,7 +1313,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB4444_Premultiplied
0, // Format_Invalid,
@@ -1166,7 +1334,85 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBX8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_blend_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_blend_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
+ },
+ { // Format_RGBA8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBA8888_Premultiplied
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_blend_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_blend_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
}
};
@@ -1187,7 +1433,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Mono
0, // Format_Invalid,
@@ -1205,7 +1454,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_MonoLSB
0, // Format_Invalid,
@@ -1223,7 +1475,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_Indexed8
0, // Format_Invalid,
@@ -1241,7 +1496,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB32
0, // Format_Invalid,
@@ -1259,7 +1517,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32
0, // Format_Invalid,
@@ -1277,7 +1538,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB32_Premultiplied
0, // Format_Invalid,
@@ -1295,7 +1559,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB16
0, // Format_Invalid,
@@ -1313,7 +1580,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8565_Premultiplied
0, // Format_Invalid,
@@ -1331,7 +1601,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB666
0, // Format_Invalid,
@@ -1349,7 +1622,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB6666_Premultiplied
0, // Format_Invalid,
@@ -1367,7 +1643,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB555
0, // Format_Invalid,
@@ -1385,7 +1664,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB8555_Premultiplied
0, // Format_Invalid,
@@ -1403,7 +1685,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB888
0, // Format_Invalid,
@@ -1421,7 +1706,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_RGB444
0, // Format_Invalid,
@@ -1439,7 +1727,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
},
{ // Format_ARGB4444_Premultiplied
0, // Format_Invalid,
@@ -1457,7 +1748,85 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB8555_Premultiplied,
0, // Format_RGB888,
0, // Format_RGB444,
- 0 // Format_ARGB4444_Premultiplied,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBX8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_transform_image_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_transform_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
+ },
+ { // Format_RGBA8888
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+ },
+ { // Format_RGBA8888_Premultiplied
+ 0, // Format_Invalid,
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB,
+ 0, // Format_Indexed8,
+ 0, // Format_RGB32,
+ 0, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied,
+ 0, // Format_RGB16,
+ 0, // Format_ARGB8565_Premultiplied,
+ 0, // Format_RGB666,
+ 0, // Format_ARGB6666_Premultiplied,
+ 0, // Format_RGB555,
+ 0, // Format_ARGB8555_Premultiplied,
+ 0, // Format_RGB888,
+ 0, // Format_RGB444,
+ 0, // Format_ARGB4444_Premultiplied,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_transform_image_rgb32_on_rgb32, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ qt_transform_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied,
+#else
+ 0, // Format_RGBX8888,
+ 0, // Format_RGBA8888,
+ 0 // Format_RGBA8888_Premultiplied,
+#endif
}
};
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 12ca84d8d1..c93320c491 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -90,7 +90,8 @@ QT_BEGIN_NAMESPACE
specified.
A color can be set by passing an RGB string (such as "#112233"),
- or a color name (such as "blue"), to the setNamedColor() function.
+ or an ARGB string (such as "#ff112233") or a color name (such as "blue"),
+ to the setNamedColor() function.
The color names are taken from the SVG 1.0 color names. The name()
function returns the name of the color in the format
"#RRGGBB". Colors can also be set using setRgb(), setHsv() and
@@ -301,6 +302,17 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QColor::NameFormat
+
+ How to format the output of the name() function
+
+ \value HexRgb #RRGGBB A "#" character followed by three two-digit hexadecimal numbers (i.e. \c{#RRGGBB}).
+ \value HexArgb #AARRGGBB A "#" character followed by four two-digit hexadecimal numbers (i.e. \c{#AARRGGBB}).
+
+ \sa name()
+*/
+
+/*!
\fn Spec QColor::spec() const
Returns how the color was specified.
@@ -489,8 +501,28 @@ QColor::QColor(Spec spec)
QString QColor::name() const
{
+ return name(HexRgb);
+}
+
+/*!
+ \since 5.2
+
+ Returns the name of the color in the specified \a format.
+
+ \sa setNamedColor(), NameFormat
+*/
+
+QString QColor::name(NameFormat format) const
+{
QString s;
- s.sprintf("#%02x%02x%02x", red(), green(), blue());
+ switch (format) {
+ case HexRgb:
+ s.sprintf("#%02x%02x%02x", red(), green(), blue());
+ break;
+ case HexArgb:
+ s.sprintf("#%02x%02x%02x%02x", alpha(), red(), green(), blue());
+ break;
+ }
return s;
}
@@ -501,6 +533,7 @@ QString QColor::name() const
\list
\li #RGB (each of R, G, and B is a single hex digit)
\li #RRGGBB
+ \li #AARRGGBB (Since 5.2)
\li #RRRGGGBBB
\li #RRRRGGGGBBBB
\li A name from the list of colors defined in the list of \l{http://www.w3.org/TR/SVG/types.html#ColorKeywords}{SVG color keyword names}
@@ -545,9 +578,9 @@ bool QColor::setColorFromString(const QString &name)
}
if (name.startsWith(QLatin1Char('#'))) {
- QRgb rgb;
- if (qt_get_hex_rgb(name.constData(), name.length(), &rgb)) {
- setRgb(rgb);
+ QRgb rgba;
+ if (qt_get_hex_rgb(name.constData(), name.length(), &rgba)) {
+ setRgba(rgba);
return true;
} else {
invalidate();
diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h
index ef3503e8d8..1ede5a3682 100644
--- a/src/gui/painting/qcolor.h
+++ b/src/gui/painting/qcolor.h
@@ -65,6 +65,7 @@ class Q_GUI_EXPORT QColor
{
public:
enum Spec { Invalid, Rgb, Hsv, Cmyk, Hsl };
+ enum NameFormat { HexRgb, HexArgb };
QColor();
QColor(Qt::GlobalColor color);
@@ -77,7 +78,9 @@ public:
bool isValid() const;
+ // ### Qt 6: merge overloads
QString name() const;
+ QString name(NameFormat format) const;
void setNamedColor(const QString& name);
static QStringList colorNames();
diff --git a/src/gui/painting/qcolor_p.cpp b/src/gui/painting/qcolor_p.cpp
index 35e607ec54..b913f5338c 100644
--- a/src/gui/painting/qcolor_p.cpp
+++ b/src/gui/painting/qcolor_p.cpp
@@ -79,7 +79,8 @@ bool qt_get_hex_rgb(const char *name, QRgb *rgb)
return false;
name++;
int len = qstrlen(name);
- int r, g, b;
+ int a, r, g, b;
+ a = 255;
if (len == 12) {
r = hex2int(name);
g = hex2int(name + 4);
@@ -88,6 +89,11 @@ bool qt_get_hex_rgb(const char *name, QRgb *rgb)
r = hex2int(name);
g = hex2int(name + 3);
b = hex2int(name + 6);
+ } else if (len == 8) {
+ a = hex2int(name);
+ r = hex2int(name + 2);
+ g = hex2int(name + 4);
+ b = hex2int(name + 6);
} else if (len == 6) {
r = hex2int(name);
g = hex2int(name + 2);
@@ -99,11 +105,11 @@ bool qt_get_hex_rgb(const char *name, QRgb *rgb)
} else {
r = g = b = -1;
}
- if ((uint)r > 255 || (uint)g > 255 || (uint)b > 255) {
+ if ((uint)r > 255 || (uint)g > 255 || (uint)b > 255 || (uint)a > 255) {
*rgb = 0;
return false;
}
- *rgb = qRgb(r, g ,b);
+ *rgb = qRgba(r, g ,b, a);
return true;
}
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index de0ab53c1b..a037545dc2 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -255,6 +255,33 @@ static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src
return buffer;
}
+static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *layout, const QRgb *)
+{
+ Q_ASSERT(layout->redWidth <= 8);
+ Q_ASSERT(layout->greenWidth <= 8);
+ Q_ASSERT(layout->blueWidth <= 8);
+ Q_ASSERT(layout->alphaWidth == 0);
+
+ const uint redMask = (1 << layout->redWidth) - 1;
+ const uint greenMask = (1 << layout->greenWidth) - 1;
+ const uint blueMask = (1 << layout->blueWidth) - 1;
+
+ const uchar redRightShift = 24 - layout->redWidth;
+ const uchar greenRightShift = 16 - layout->greenWidth;
+ const uchar blueRightShift = 8 - layout->blueWidth;
+
+ for (int i = 0; i < count; ++i) {
+ uint color = INV_PREMUL(src[i]);
+ uint red = ((color >> redRightShift) & redMask) << layout->redShift;
+ uint green = ((color >> greenRightShift) & greenMask) << layout->greenShift;
+ uint blue = ((color >> blueRightShift) & blueMask) << layout->blueShift;
+ uint alpha = 0xff << layout->alphaShift;
+ buffer[i] = red | green | blue | alpha;
+ }
+ return buffer;
+}
+
template <QPixelLayout::BPP bpp> static
uint QT_FASTCALL fetchPixel(const uchar *src, int index);
@@ -386,7 +413,16 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = {
{ 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8555_Premultiplied
{ 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB888
{ 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB444
- { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM } // Format_ARGB4444_Premultiplied
+ { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB4444_Premultiplied
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888
+ { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888
+ { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888_Premultiplied
+#else
+ { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888
+ { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888 (ABGR32)
+ { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM } // Format_RGBA8888_Premultiplied
+#endif
};
FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = {
@@ -490,7 +526,10 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] =
destFetch, // Format_ARGB8555_Premultiplied
destFetch, // Format_RGB888
destFetch, // Format_RGB444
- destFetch // Format_ARGB4444_Premultiplied
+ destFetch, // Format_ARGB4444_Premultiplied
+ destFetch, // Format_RGBX8888
+ destFetch, // Format_RGBA8888
+ destFetch, // Format_RGBA8888_Premultiplied
};
/*
@@ -622,7 +661,10 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] =
destStore, // Format_ARGB8555_Premultiplied
destStore, // Format_RGB888
destStore, // Format_RGB444
- destStore // Format_ARGB4444_Premultiplied
+ destStore, // Format_ARGB4444_Premultiplied
+ destStore, // Format_RGBX8888
+ destStore, // Format_RGBA8888
+ destStore // Format_RGBA8888_Premultiplied
};
/*
@@ -1766,7 +1808,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchUntransformed, // ARGB8555_Premultiplied
fetchUntransformed, // RGB888
fetchUntransformed, // RGB444
- fetchUntransformed // ARGB4444_Premultiplied
+ fetchUntransformed, // ARGB4444_Premultiplied
+ fetchUntransformed, // RGBX8888
+ fetchUntransformed, // RGBA8888
+ fetchUntransformed // RGBA8888_Premultiplied
},
// Tiled
{
@@ -1785,7 +1830,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchUntransformed, // ARGB8555_Premultiplied
fetchUntransformed, // RGB888
fetchUntransformed, // RGB444
- fetchUntransformed // ARGB4444_Premultiplied
+ fetchUntransformed, // ARGB4444_Premultiplied
+ fetchUntransformed, // RGBX8888
+ fetchUntransformed, // RGBA8888
+ fetchUntransformed // RGBA8888_Premultiplied
},
// Transformed
{
@@ -1805,6 +1853,9 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchTransformed<BlendTransformed>, // RGB888
fetchTransformed<BlendTransformed>, // RGB444
fetchTransformed<BlendTransformed>, // ARGB4444_Premultiplied
+ fetchTransformed<BlendTransformed>, // RGBX8888
+ fetchTransformed<BlendTransformed>, // RGBA8888
+ fetchTransformed<BlendTransformed>, // RGBA8888_Premultiplied
},
{
0, // TransformedTiled
@@ -1823,6 +1874,9 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchTransformed<BlendTransformedTiled>, // RGB888
fetchTransformed<BlendTransformedTiled>, // RGB444
fetchTransformed<BlendTransformedTiled>, // ARGB4444_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // RGBX8888
+ fetchTransformed<BlendTransformedTiled>, // RGBA8888
+ fetchTransformed<BlendTransformedTiled>, // RGBA8888_Premultiplied
},
{
0, // Bilinear
@@ -1840,7 +1894,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB8555_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinear>, // RGB888
fetchTransformedBilinear<BlendTransformedBilinear>, // RGB444
- fetchTransformedBilinear<BlendTransformedBilinear> // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear>, // RGBX8888
+ fetchTransformedBilinear<BlendTransformedBilinear>, // RGBA8888
+ fetchTransformedBilinear<BlendTransformedBilinear> // RGBA8888_Premultiplied
},
{
0, // BilinearTiled
@@ -1858,7 +1915,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB8555_Premultiplied
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB888
fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB444
- fetchTransformedBilinear<BlendTransformedBilinearTiled> // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBX8888
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBA8888
+ fetchTransformedBilinear<BlendTransformedBilinearTiled> // RGBA8888_Premultiplied
},
};
@@ -5268,6 +5328,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_untransformed_generic,
blend_untransformed_generic,
blend_untransformed_generic,
+ blend_untransformed_generic,
+ blend_untransformed_generic,
+ blend_untransformed_generic,
},
// Tiled
{
@@ -5287,6 +5350,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_tiled_generic,
blend_tiled_generic,
blend_tiled_generic,
+ blend_tiled_generic,
+ blend_tiled_generic,
+ blend_tiled_generic,
},
// Transformed
{
@@ -5306,6 +5372,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic,
blend_src_generic,
blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
},
// TransformedTiled
{
@@ -5324,6 +5393,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic,
blend_src_generic,
blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
blend_src_generic
},
// Bilinear
@@ -5344,6 +5416,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic,
blend_src_generic,
blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
},
// BilinearTiled
{
@@ -5363,6 +5438,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
blend_src_generic, // RGB888
blend_src_generic, // RGB444
blend_src_generic, // ARGB4444_Premultiplied
+ blend_src_generic, // RGBX8888
+ blend_src_generic, // RGBA8888
+ blend_src_generic, // RGBA8888_Premultiplied
}
};
@@ -5823,9 +5901,9 @@ static void qt_alphargbblit_quint32(QRasterBuffer *rasterBuffer,
}
}
-static void qt_rectfill_quint32(QRasterBuffer *rasterBuffer,
- int x, int y, int width, int height,
- quint32 color)
+static void qt_rectfill_argb32(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
color, x, y, width, height, rasterBuffer->bytesPerLine());
@@ -5839,14 +5917,30 @@ static void qt_rectfill_quint16(QRasterBuffer *rasterBuffer,
qConvertRgb32To16(color), x, y, width, height, rasterBuffer->bytesPerLine());
}
-static void qt_rectfill_nonpremul_quint32(QRasterBuffer *rasterBuffer,
- int x, int y, int width, int height,
- quint32 color)
+static void qt_rectfill_nonpremul_argb32(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
INV_PREMUL(color), x, y, width, height, rasterBuffer->bytesPerLine());
}
+static void qt_rectfill_rgba(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
+{
+ qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
+ ARGB2RGBA(color), x, y, width, height, rasterBuffer->bytesPerLine());
+}
+
+static void qt_rectfill_nonpremul_rgba(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
+{
+ qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
+ ARGB2RGBA(INV_PREMUL(color)), x, y, width, height, rasterBuffer->bytesPerLine());
+}
+
// Map table for destination image format. Contains function pointers
// for blends of various types unto the destination
@@ -5880,7 +5974,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
qt_bitmapblit_quint32,
qt_alphamapblit_quint32,
qt_alphargbblit_quint32,
- qt_rectfill_quint32
+ qt_rectfill_argb32
},
// Format_ARGB32,
{
@@ -5889,7 +5983,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
qt_bitmapblit_quint32,
qt_alphamapblit_quint32,
qt_alphargbblit_quint32,
- qt_rectfill_nonpremul_quint32
+ qt_rectfill_nonpremul_argb32
},
// Format_ARGB32_Premultiplied
{
@@ -5898,7 +5992,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
qt_bitmapblit_quint32,
qt_alphamapblit_quint32,
qt_alphargbblit_quint32,
- qt_rectfill_quint32
+ qt_rectfill_argb32
},
// Format_RGB16
{
@@ -5956,6 +6050,48 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
blend_color_generic,
blend_src_generic,
0, 0, 0, 0
+ },
+ // Format_RGBX8888
+ {
+ blend_color_generic,
+ qt_gradient_quint32,
+ qt_bitmapblit_quint32,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_alphamapblit_quint32,
+ qt_alphargbblit_quint32,
+#else
+ 0,
+ 0,
+#endif
+ qt_rectfill_rgba
+ },
+ // Format_RGBA8888
+ {
+ blend_color_generic,
+ qt_gradient_quint32,
+ qt_bitmapblit_quint32,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_alphamapblit_quint32,
+ qt_alphargbblit_quint32,
+#else
+ 0,
+ 0,
+#endif
+ qt_rectfill_nonpremul_rgba
+ },
+ // Format_RGB8888_Premultiplied
+ {
+ blend_color_generic,
+ qt_gradient_quint32,
+ qt_bitmapblit_quint32,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qt_alphamapblit_quint32,
+ qt_alphargbblit_quint32,
+#else
+ 0,
+ 0,
+#endif
+ qt_rectfill_rgba
}
};
@@ -6043,6 +6179,9 @@ void qInitDrawhelperAsm()
qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_avx;
qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_avx;
qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_avx;
+ qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_avx;
+ qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_avx;
+ qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_avx;
extern void qt_scale_image_argb32_on_argb32_avx(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
@@ -6052,6 +6191,10 @@ void qInitDrawhelperAsm()
int const_alpha);
qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
+ qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
+#endif
#endif
#ifdef QT_COMPILER_SUPPORTS_SSE2
} else if (features & SSE2) {
@@ -6061,6 +6204,9 @@ void qInitDrawhelperAsm()
qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
+ qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
@@ -6070,6 +6216,10 @@ void qInitDrawhelperAsm()
int const_alpha);
qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+ qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+#endif
#endif
}
@@ -6088,6 +6238,12 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+#endif
extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length);
@@ -6104,6 +6260,10 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
+#endif
}
#endif // SSSE3
@@ -6122,6 +6282,12 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx;
+#endif
extern const uint * QT_FASTCALL qt_fetch_radial_gradient_avx(uint *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length);
@@ -6163,7 +6329,7 @@ void qInitDrawhelperAsm()
}
#endif // IWMMXT
-#if defined(QT_COMPILER_SUPPORTS_NEON)
+#if defined(QT_COMPILER_SUPPORTS_NEON) && !defined(Q_OS_IOS)
if (features & NEON) {
qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
@@ -6172,6 +6338,12 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+#endif
qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 0b8a41c904..f4c29996b4 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -653,6 +653,30 @@ static Q_ALWAYS_INLINE uint PREMUL(uint x) {
}
#endif
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
+ quint32 rgb = x >> 8;
+ quint32 a = x << 24;
+ return a | rgb;
+}
+
+static Q_ALWAYS_INLINE quint32 ARGB2RGBA(quint32 x) {
+ quint32 rgb = x << 8;
+ quint32 a = x >> 24;
+ return a | rgb;
+}
+#else
+static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
+ // RGBA8888 is ABGR32 on little endian.
+ quint32 ag = x & 0xff00ff00;
+ quint32 rg = x & 0x00ff00ff;
+ return ag | (rg << 16) | (rg >> 16);
+}
+
+static Q_ALWAYS_INLINE quint32 ARGB2RGBA(quint32 x) {
+ return RGBA2ARGB(x);
+}
+#endif
static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16(uint x, uint a) {
a += 1;
diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp
index 27cb08f353..89ccdd42f0 100644
--- a/src/gui/painting/qimagescale.cpp
+++ b/src/gui/painting/qimagescale.cpp
@@ -1017,7 +1017,7 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh)
return QImage();
}
- if (src.format() == QImage::Format_ARGB32_Premultiplied)
+ if (src.format() == QImage::Format_ARGB32_Premultiplied || src.format() == QImage::Format_RGBA8888_Premultiplied)
qt_qimageScaleArgb(scaleinfo, (unsigned int *)buffer.scanLine(0),
0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4);
else
diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp
index 747881bbd1..087231df43 100644
--- a/src/gui/painting/qmemrotate.cpp
+++ b/src/gui/painting/qmemrotate.cpp
@@ -529,7 +529,10 @@ MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3] =
{ 0, 0, 0 }, // Format_ARGB8555_Premultiplied,
{ 0, 0, 0 }, // Format_RGB888,
{ 0, 0, 0 }, // Format_RGB444,
- { 0, 0, 0 } // Format_ARGB4444_Premultiplied,
+ { 0, 0, 0 }, // Format_ARGB4444_Premultiplied,
+ { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGBX8888,
+ { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGBA8888,
+ { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 } // Format_RGBA8888_Premultiplied,
};
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp
index bb0c441b40..f855e9e32d 100644
--- a/src/gui/painting/qpaintbuffer.cpp
+++ b/src/gui/painting/qpaintbuffer.cpp
@@ -89,9 +89,9 @@ QTextItemIntCopy::QTextItemIntCopy(const QTextItem &item)
QTextItemIntCopy::~QTextItemIntCopy()
{
- delete m_item.chars;
- delete m_item.logClusters;
- delete m_item.glyphs.data();
+ delete [] m_item.chars;
+ delete [] m_item.logClusters;
+ delete [] m_item.glyphs.data();
if (!m_item.fontEngine->ref.deref())
delete m_item.fontEngine;
}
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index d1e9b81faa..7112380043 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -435,6 +435,8 @@ void QRasterPaintEngine::init()
case QImage::Format_ARGB4444_Premultiplied:
case QImage::Format_ARGB32_Premultiplied:
case QImage::Format_ARGB32:
+ case QImage::Format_RGBA8888_Premultiplied:
+ case QImage::Format_RGBA8888:
gccaps |= PorterDuff;
break;
case QImage::Format_RGB32:
@@ -443,6 +445,7 @@ void QRasterPaintEngine::init()
case QImage::Format_RGB666:
case QImage::Format_RGB888:
case QImage::Format_RGB16:
+ case QImage::Format_RGBX8888:
break;
default:
break;
@@ -2261,6 +2264,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
case QImage::Format_ARGB6666_Premultiplied:
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_ARGB4444_Premultiplied:
+ case QImage::Format_RGBA8888_Premultiplied:
// Combine premultiplied color with the opacity set on the painter.
d->solid_color_filler.solid.color =
((((color & 0x00ff00ff) * s->intOpacity) >> 8) & 0x00ff00ff)
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 62379cd592..2e4f341e39 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -53,6 +53,7 @@
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformfontdatabase.h>
+#include <qpa/qplatformtheme.h>
#include <stdlib.h>
#include <limits.h>
@@ -1103,6 +1104,17 @@ QFontDatabase::QFontDatabase()
*/
/*!
+ \enum QFontDatabase::SystemFont
+
+ \value GeneralFont The default system font.
+ \value FixedFont The fixed font that the system recommends.
+ \value TitleFont The system standard font for titles.
+ \value SmallestReadableFont The smallest readable system font.
+
+ \since 5.2
+*/
+
+/*!
Returns a sorted list of the available writing systems. This is
list generated from information about all installed fonts on the
system.
@@ -2114,6 +2126,43 @@ QStringList QFontDatabase::applicationFontFamilies(int id)
}
/*!
+ \since 5.2
+
+ Returns the most adequate font for a given \a type case for proper integration
+ with the system's look and feel.
+
+ \sa QGuiApplication::font()
+*/
+
+QFont QFontDatabase::systemFont(QFontDatabase::SystemFont type)
+{
+ const QFont *font = 0;
+ if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
+ switch (type) {
+ case GeneralFont:
+ font = theme->font(QPlatformTheme::SystemFont);
+ break;
+ case FixedFont:
+ font = theme->font(QPlatformTheme::FixedFont);
+ break;
+ case TitleFont:
+ font = theme->font(QPlatformTheme::TitleBarFont);
+ break;
+ case SmallestReadableFont:
+ font = theme->font(QPlatformTheme::MiniFont);
+ break;
+ }
+ }
+
+ if (font)
+ return *font;
+ else if (QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration())
+ return integration->fontDatabase()->defaultFont();
+ else
+ return QFont();
+}
+
+/*!
\fn bool QFontDatabase::removeApplicationFont(int id)
\since 4.2
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index 05f1a85f24..bd603c3c4a 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -60,6 +60,7 @@ class Q_GUI_EXPORT QFontDatabase
{
Q_GADGET
Q_ENUMS(WritingSystem)
+ Q_ENUMS(SystemFont)
public:
// do not re-order or delete entries from this enum without updating the
// QPF2 format and makeqpf!!
@@ -106,6 +107,13 @@ public:
WritingSystemsCount
};
+ enum SystemFont {
+ GeneralFont,
+ FixedFont,
+ TitleFont,
+ SmallestReadableFont
+ };
+
static QList<int> standardSizes();
QFontDatabase();
@@ -144,6 +152,8 @@ public:
static bool supportsThreadedFontRendering();
+ static QFont systemFont(SystemFont type);
+
private:
static void createDatabase();
static void parseFontName(const QString &name, QString &foundry, QString &family);
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp
index 62b99968bc..8e6ad7cd97 100644
--- a/src/gui/text/qfontdatabase_qpa.cpp
+++ b/src/gui/text/qfontdatabase_qpa.cpp
@@ -85,7 +85,7 @@ Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &sty
size->handle = handle;
}
-Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias)
+void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias)
{
if (alias.isEmpty())
return;
diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp
index 4399aff9da..293535a2e1 100644
--- a/src/gui/text/qplatformfontdatabase.cpp
+++ b/src/gui/text/qplatformfontdatabase.cpp
@@ -53,6 +53,8 @@ extern void qt_registerFont(const QString &familyname, const QString &stylename,
bool scalable, int pixelSize, bool fixedPitch,
const QSupportedWritingSystems &writingSystems, void *hanlde);
+void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
+
/*!
\fn void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *handle)
@@ -517,6 +519,17 @@ QSupportedWritingSystems QPlatformFontDatabase::writingSystemsFromTrueTypeBits(q
}
/*!
+ Helper function that register the \a alias for the \a familyName.
+
+ \since 5.2
+*/
+
+void QPlatformFontDatabase::registerAliasToFontFamily(const QString &familyName, const QString &alias)
+{
+ qt_registerAliasToFontFamily(familyName, alias);
+}
+
+/*!
\class QPlatformFontDatabase
\since 5.0
\internal
diff --git a/src/gui/text/qplatformfontdatabase.h b/src/gui/text/qplatformfontdatabase.h
index 6e53eba98b..6053f11051 100644
--- a/src/gui/text/qplatformfontdatabase.h
+++ b/src/gui/text/qplatformfontdatabase.h
@@ -122,6 +122,8 @@ public:
QFont::Style style, QFont::Stretch stretch, bool antialiased,
bool scalable, int pixelSize, bool fixedPitch,
const QSupportedWritingSystems &writingSystems, void *handle);
+
+ static void registerAliasToFontFamily(const QString &familyName, const QString &alias);
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 2fa7f0232d..229db80186 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -59,9 +59,9 @@
#include <algorithm>
#include <stdlib.h>
+#ifndef QT_NO_RAWFONT
#include "qfontengine_qpa_p.h"
-
-#include <private/qharfbuzz_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -838,21 +838,6 @@ void QTextEngine::bidiReorder(int numItems, const quint8 *levels, int *visualOrd
#endif
}
-// ask the font engine to find out which glyphs (as an index in the specific font) to use for the text in one item.
-static bool stringToGlyphs(HB_ShaperItem *item, QGlyphLayout *glyphs, QFontEngine *fontEngine)
-{
- int nGlyphs = item->num_glyphs;
-
- QFontEngine::ShaperFlags shaperFlags(QFontEngine::GlyphIndicesOnly);
- if (item->item.bidiLevel % 2)
- shaperFlags |= QFontEngine::RightToLeft;
-
- bool result = fontEngine->stringToCMap(reinterpret_cast<const QChar *>(item->string + item->item.pos), item->item.length, glyphs, &nGlyphs, shaperFlags);
- item->num_glyphs = nGlyphs;
- glyphs->numGlyphs = nGlyphs;
- return result;
-}
-
// shape all the items that intersect with the line, taking tab widths into account to find out what text actually fits in the line.
void QTextEngine::shapeLine(const QScriptLine &line)
{
@@ -892,19 +877,48 @@ void QTextEngine::shapeText(int item) const
if (si.num_glyphs)
return;
- shapeTextWithHarfbuzz(item);
-
si.width = 0;
+ si.glyph_data_offset = layoutData->used;
- if (!si.num_glyphs)
- return;
- QGlyphLayout glyphs = shapedGlyphs(&si);
+ const ushort *string = reinterpret_cast<const ushort *>(layoutData->string.constData()) + si.position;
+ const int itemLength = length(item);
+
+ if (!ensureSpace(itemLength))
+ return; // ### report OOM error somehow
+
+ QString casedString;
+ if (si.analysis.flags && si.analysis.flags <= QScriptAnalysis::SmallCaps) {
+ casedString.resize(itemLength);
+ ushort *uc = reinterpret_cast<ushort *>(casedString.data());
+ for (int i = 0; i < itemLength; ++i) {
+ uint ucs4 = string[i];
+ if (QChar::isHighSurrogate(ucs4) && i + 1 < itemLength) {
+ uint low = string[i + 1];
+ if (QChar::isLowSurrogate(low)) {
+ ++i;
+ ucs4 = QChar::surrogateToUcs4(ucs4, low);
+ ucs4 = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
+ : QChar::toUpper(ucs4);
+ // high part never changes in simple casing
+ uc[i] = QChar::lowSurrogate(ucs4);
+ }
+ } else {
+ uc[i] = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
+ : QChar::toUpper(ucs4);
+ }
+ }
+ string = reinterpret_cast<const ushort *>(casedString.constData());
+ }
+ QFontEngine *fontEngine = this->fontEngine(si, &si.ascent, &si.descent, &si.leading);
+
+ bool kerningEnabled;
bool letterSpacingIsAbsolute;
QFixed letterSpacing, wordSpacing;
#ifndef QT_NO_RAWFONT
if (useRawFont) {
QTextCharFormat f = format(&si);
+ kerningEnabled = f.fontKerning();
wordSpacing = QFixed::fromReal(f.fontWordSpacing());
letterSpacing = QFixed::fromReal(f.fontLetterSpacing());
letterSpacingIsAbsolute = true;
@@ -912,6 +926,7 @@ void QTextEngine::shapeText(int item) const
#endif
{
QFont font = this->font(si);
+ kerningEnabled = font.d->kerning;
letterSpacingIsAbsolute = font.d->letterSpacingIsAbsolute;
letterSpacing = font.d->letterSpacing;
wordSpacing = font.d->wordSpacing;
@@ -920,6 +935,13 @@ void QTextEngine::shapeText(int item) const
letterSpacing *= font.d->dpi / qt_defaultDpiY();
}
+ si.num_glyphs = shapeTextWithHarfbuzz(si, string, itemLength, fontEngine, kerningEnabled);
+ if (!si.num_glyphs)
+ return; // ### report shaping errors somehow
+ layoutData->used += si.num_glyphs;
+
+ QGlyphLayout glyphs = shapedGlyphs(&si);
+
if (letterSpacing != 0) {
for (int i = 1; i < si.num_glyphs; ++i) {
if (glyphs.attributes[i].clusterStart) {
@@ -940,12 +962,12 @@ void QTextEngine::shapeText(int item) const
}
if (wordSpacing != 0) {
for (int i = 0; i < si.num_glyphs; ++i) {
- if (glyphs.attributes[i].justification == HB_Space
- || glyphs.attributes[i].justification == HB_Arabic_Space) {
+ if (glyphs.attributes[i].justification == QGlyphAttributes::Space
+ || glyphs.attributes[i].justification == QGlyphAttributes::Arabic_Space) {
// word spacing only gets added once to a consecutive run of spaces (see CSS spec)
if (i + 1 == si.num_glyphs
- ||(glyphs.attributes[i+1].justification != HB_Space
- && glyphs.attributes[i+1].justification != HB_Arabic_Space))
+ ||(glyphs.attributes[i+1].justification != QGlyphAttributes::Space
+ && glyphs.attributes[i+1].justification != QGlyphAttributes::Arabic_Space))
glyphs.advances_x[i] += wordSpacing;
}
}
@@ -955,14 +977,6 @@ void QTextEngine::shapeText(int item) const
si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
}
-static inline bool hasCaseChange(const QScriptItem &si)
-{
- return si.analysis.flags == QScriptAnalysis::SmallCaps ||
- si.analysis.flags == QScriptAnalysis::Uppercase ||
- si.analysis.flags == QScriptAnalysis::Lowercase;
-}
-
-
static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num)
{
if (num > 0 && destination.glyphs != source.glyphs) {
@@ -973,84 +987,60 @@ static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLa
}
}
+QT_BEGIN_INCLUDE_NAMESPACE
+
+#include <private/qharfbuzz_p.h>
+
+QT_END_INCLUDE_NAMESPACE
+
Q_STATIC_ASSERT(sizeof(HB_Glyph) == sizeof(glyph_t));
Q_STATIC_ASSERT(sizeof(HB_GlyphAttributes) == sizeof(QGlyphAttributes));
Q_STATIC_ASSERT(sizeof(HB_Fixed) == sizeof(QFixed));
Q_STATIC_ASSERT(sizeof(HB_FixedPoint) == sizeof(QFixedPoint));
-/// take the item from layoutData->items and
-void QTextEngine::shapeTextWithHarfbuzz(int item) const
+// ask the font engine to find out which glyphs (as an index in the specific font) to use for the text in one item.
+static bool stringToGlyphs(HB_ShaperItem *item, QGlyphLayout *glyphs, QFontEngine *fontEngine)
{
- QScriptItem &si = layoutData->items[item];
-
- si.glyph_data_offset = layoutData->used;
+ int nGlyphs = item->num_glyphs;
- QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
+ QFontEngine::ShaperFlags shaperFlags(QFontEngine::GlyphIndicesOnly);
+ if (item->item.bidiLevel % 2)
+ shaperFlags |= QFontEngine::RightToLeft;
- bool kerningEnabled;
-#ifndef QT_NO_RAWFONT
- if (useRawFont) {
- QTextCharFormat f = format(&si);
- kerningEnabled = f.fontKerning();
- } else
-#endif
- kerningEnabled = this->font(si).d->kerning;
+ bool result = fontEngine->stringToCMap(reinterpret_cast<const QChar *>(item->string + item->item.pos), item->item.length, glyphs, &nGlyphs, shaperFlags);
+ item->num_glyphs = nGlyphs;
+ glyphs->numGlyphs = nGlyphs;
+ return result;
+}
+int QTextEngine::shapeTextWithHarfbuzz(QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, bool kerningEnabled) const
+{
HB_ShaperItem entire_shaper_item;
memset(&entire_shaper_item, 0, sizeof(entire_shaper_item));
- entire_shaper_item.string = reinterpret_cast<const HB_UChar16 *>(layoutData->string.constData());
- entire_shaper_item.stringLength = layoutData->string.length();
+ entire_shaper_item.string = reinterpret_cast<const HB_UChar16 *>(string);
+ entire_shaper_item.stringLength = itemLength;
entire_shaper_item.item.script = script_to_hbscript(si.analysis.script);
- entire_shaper_item.item.pos = si.position;
- entire_shaper_item.item.length = length(item);
+ entire_shaper_item.item.pos = 0;
+ entire_shaper_item.item.length = itemLength;
entire_shaper_item.item.bidiLevel = si.analysis.bidiLevel;
- QVarLengthArray<HB_UChar16, 256> casedString;
- if (hasCaseChange(si)) {
- if (casedString.size() < static_cast<int>(entire_shaper_item.item.length))
- casedString.resize(entire_shaper_item.item.length);
- HB_UChar16 *uc = casedString.data();
- for (uint i = 0; i < entire_shaper_item.item.length; ++i) {
- uint ucs4 = entire_shaper_item.string[si.position + i];
- if (QChar::isHighSurrogate(ucs4)) {
- uc[i] = ucs4; // high part never changes in simple casing
- if (i + 1 < entire_shaper_item.item.length) {
- ushort low = entire_shaper_item.string[si.position + i + 1];
- if (QChar::isLowSurrogate(low)) {
- ucs4 = QChar::surrogateToUcs4(ucs4, low);
- ucs4 = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
- : QChar::toUpper(ucs4);
- uc[++i] = QChar::lowSurrogate(ucs4);
- }
- }
- } else {
- uc[i] = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
- : QChar::toUpper(ucs4);
- }
- }
- entire_shaper_item.item.pos = 0;
- entire_shaper_item.string = uc;
- entire_shaper_item.stringLength = entire_shaper_item.item.length;
- }
-
entire_shaper_item.shaperFlags = 0;
if (!kerningEnabled)
entire_shaper_item.shaperFlags |= HB_ShaperFlag_NoKerning;
if (option.useDesignMetrics())
entire_shaper_item.shaperFlags |= HB_ShaperFlag_UseDesignMetrics;
- entire_shaper_item.num_glyphs = qMax(layoutData->glyphLayout.numGlyphs - layoutData->used, int(entire_shaper_item.item.length));
- if (!ensureSpace(entire_shaper_item.num_glyphs))
- return;
+ entire_shaper_item.num_glyphs = itemLength;
+
QGlyphLayout initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs);
- if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, font)) {
+ if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, fontEngine)) {
if (!ensureSpace(entire_shaper_item.num_glyphs))
- return;
+ return 0;
initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs);
- if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, font)) {
+ if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, fontEngine)) {
// ############ if this happens there's a bug in the fontengine
- return;
+ return 0;
}
}
@@ -1060,7 +1050,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
itemBoundaries[0] = entire_shaper_item.item.pos;
itemBoundaries[1] = 0;
- if (font->type() == QFontEngine::Multi) {
+ if (fontEngine->type() == QFontEngine::Multi) {
uint lastEngine = 0;
int charIdx = entire_shaper_item.item.pos;
const int stringEnd = charIdx + entire_shaper_item.item.length;
@@ -1099,18 +1089,17 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
if (shaper_item.num_glyphs < shaper_item.item.length)
shaper_item.num_glyphs = shaper_item.item.length;
- QFontEngine *actualFontEngine = font;
+ QFontEngine *actualFontEngine = fontEngine;
uint engineIdx = 0;
- if (font->type() == QFontEngine::Multi) {
+ if (fontEngine->type() == QFontEngine::Multi) {
engineIdx = uint(availableGlyphs(&si).glyphs[glyph_pos] >> 24);
- actualFontEngine = static_cast<QFontEngineMulti *>(font)->engine(engineIdx);
+ actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
+ si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
+ si.descent = qMax(actualFontEngine->descent(), si.descent);
+ si.leading = qMax(actualFontEngine->leading(), si.leading);
}
- si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
- si.descent = qMax(actualFontEngine->descent(), si.descent);
- si.leading = qMax(actualFontEngine->leading(), si.leading);
-
shaper_item.font = (HB_Font)actualFontEngine->harfbuzzFont();
shaper_item.face = (HB_Face)actualFontEngine->harfbuzzFace();
@@ -1120,7 +1109,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
do {
if (!ensureSpace(glyph_pos + shaper_item.num_glyphs + remaining_glyphs))
- return;
+ return 0;
const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos);
if (shaper_item.num_glyphs > shaper_item.item.length)
@@ -1137,8 +1126,6 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
}
shaper_item.log_clusters = logClusters(&si) + shaper_item.item.pos - entire_shaper_item.item.pos;
-
-// qDebug(" .. num_glyphs=%d, used=%d, item.num_glyphs=%d", num_glyphs, used, shaper_item.num_glyphs);
} while (!qShapeItem(&shaper_item)); // this does the actual shaping via harfbuzz.
QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos, shaper_item.num_glyphs);
@@ -1158,10 +1145,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
glyph_pos += shaper_item.num_glyphs;
}
-// qDebug(" -> item: script=%d num_glyphs=%d", shaper_item.script, shaper_item.num_glyphs);
- si.num_glyphs = glyph_pos;
-
- layoutData->used += si.num_glyphs;
+ return glyph_pos;
}
void QTextEngine::init(QTextEngine *e)
@@ -1821,7 +1805,7 @@ static void set(QJustificationPoint *point, int type, const QGlyphLayout &glyph,
point->type = type;
point->glyph = glyph;
- if (type >= HB_Arabic_Normal) {
+ if (type >= QGlyphAttributes::Arabic_Normal) {
QChar ch(0x640); // Kashida character
QGlyphLayoutArray<8> glyphs;
int nglyphs = 7;
@@ -1829,7 +1813,7 @@ static void set(QJustificationPoint *point, int type, const QGlyphLayout &glyph,
if (glyphs.glyphs[0] && glyphs.advances_x[0] != 0) {
point->kashidaWidth = glyphs.advances_x[0];
} else {
- point->type = HB_NoJustification;
+ point->type = QGlyphAttributes::NoJustification;
point->kashidaWidth = 0;
}
}
@@ -1897,7 +1881,7 @@ void QTextEngine::justify(const QScriptLine &line)
for (int i = 0; i < nItems; ++i) {
QScriptItem &si = layoutData->items[firstItem + i];
- int kashida_type = HB_Arabic_Normal;
+ int kashida_type = QGlyphAttributes::Arabic_Normal;
int kashida_pos = -1;
int start = qMax(line.from - si.position, 0);
@@ -1921,11 +1905,11 @@ void QTextEngine::justify(const QScriptLine &line)
int justification = g.attributes[i].justification;
switch(justification) {
- case HB_NoJustification:
+ case QGlyphAttributes::NoJustification:
break;
- case HB_Space :
+ case QGlyphAttributes::Space :
// fall through
- case HB_Arabic_Space :
+ case QGlyphAttributes::Arabic_Space :
if (kashida_pos >= 0) {
// qDebug("kashida position at %d in word", kashida_pos);
set(&justificationPoints[nPoints], kashida_type, g.mid(kashida_pos), fontEngine(si));
@@ -1936,19 +1920,19 @@ void QTextEngine::justify(const QScriptLine &line)
}
}
kashida_pos = -1;
- kashida_type = HB_Arabic_Normal;
+ kashida_type = QGlyphAttributes::Arabic_Normal;
// fall through
- case HB_Character :
+ case QGlyphAttributes::Character :
set(&justificationPoints[nPoints++], justification, g.mid(i), fontEngine(si));
maxJustify = qMax(maxJustify, justification);
break;
- case HB_Arabic_Normal :
- case HB_Arabic_Waw :
- case HB_Arabic_BaRa :
- case HB_Arabic_Alef :
- case HB_Arabic_HaaDal :
- case HB_Arabic_Seen :
- case HB_Arabic_Kashida :
+ case QGlyphAttributes::Arabic_Normal :
+ case QGlyphAttributes::Arabic_Waw :
+ case QGlyphAttributes::Arabic_BaRa :
+ case QGlyphAttributes::Arabic_Alef :
+ case QGlyphAttributes::Arabic_HaaDal :
+ case QGlyphAttributes::Arabic_Seen :
+ case QGlyphAttributes::Arabic_Kashida :
if (justification >= kashida_type) {
kashida_pos = i;
kashida_type = justification;
@@ -1977,9 +1961,9 @@ void QTextEngine::justify(const QScriptLine &line)
// qDebug(" minKashida=%f, need=%f", minKashida.toReal(), need.toReal());
// distribute in priority order
- if (maxJustify >= HB_Arabic_Normal) {
+ if (maxJustify >= QGlyphAttributes::Arabic_Normal) {
while (need >= minKashida) {
- for (int type = maxJustify; need >= minKashida && type >= HB_Arabic_Normal; --type) {
+ for (int type = maxJustify; need >= minKashida && type >= QGlyphAttributes::Arabic_Normal; --type) {
for (int i = 0; need >= minKashida && i < nPoints; ++i) {
if (justificationPoints[i].type == type && justificationPoints[i].kashidaWidth <= need) {
justificationPoints[i].glyph.justifications->nKashidas++;
@@ -1996,7 +1980,7 @@ void QTextEngine::justify(const QScriptLine &line)
if (!need)
goto end;
- maxJustify = qMin(maxJustify, (int)HB_Space);
+ maxJustify = qMin(maxJustify, int(QGlyphAttributes::Space));
for (int type = maxJustify; need != 0 && type > 0; --type) {
int n = 0;
for (int i = 0; i < nPoints; ++i) {
@@ -2438,12 +2422,13 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
const int end = si.position + length(&si);
for (int i = si.position; i < end - 1; ++i) {
- if (layoutData->string.at(i) == QLatin1Char('&')) {
+ if (layoutData->string.at(i) == QLatin1Char('&')
+ && !attributes[i + 1].whiteSpace && attributes[i + 1].graphemeBoundary) {
const int gp = logClusters[i - si.position];
glyphs.attributes[gp].dontPrint = true;
- attributes[i + 1].graphemeBoundary = false;
- attributes[i + 1].lineBreak = false;
- attributes[i + 1].whiteSpace = false;
+ // emulate grapheme cluster
+ attributes[i] = attributes[i + 1];
+ memset(attributes + i + 1, 0, sizeof(QCharAttributes));
if (layoutData->string.at(i + 1) == QLatin1Char('&'))
++i;
}
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index ec7f7407b2..6d46231c67 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -96,6 +96,20 @@ typedef quint8 q_hb_bitfield;
#endif
typedef struct {
+ typedef enum {
+ NoJustification= 0, /* Justification can't be applied after this glyph */
+ Arabic_Space = 1, /* This glyph represents a space inside arabic text */
+ Character = 2, /* Inter-character justification point follows this glyph */
+ Space = 4, /* This glyph represents a blank outside an Arabic run */
+ Arabic_Normal = 7, /* Normal Middle-Of-Word glyph that connects to the right (begin) */
+ Arabic_Waw = 8, /* Next character is final form of Waw/Ain/Qaf/Fa */
+ Arabic_BaRa = 9, /* Next two chars are Ba + Ra/Ya/AlefMaksura */
+ Arabic_Alef = 10, /* Next character is final form of Alef/Tah/Lam/Kaf/Gaf */
+ Arabic_HaaDal = 11, /* Next character is final form of Haa/Dal/Taa Marbutah */
+ Arabic_Seen = 12, /* Initial or Medial form Of Seen/Sad */
+ Arabic_Kashida = 13 /* Kashida(U+640) in middle of word */
+ } JustificationClass;
+
q_hb_bitfield justification :4; /* Justification class */
q_hb_bitfield clusterStart :1; /* First glyph of representation of cluster */
q_hb_bitfield mark :1; /* needs to be positioned around base char */
@@ -685,7 +699,7 @@ private:
void setBoundary(int strPos) const;
void addRequiredBoundaries() const;
void shapeText(int item) const;
- void shapeTextWithHarfbuzz(int item) const;
+ int shapeTextWithHarfbuzz(QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, bool kerningEnabled) const;
void splitItem(int item, int pos) const;
int endOfLine(int lineNum);
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index a279990f4c..c3e3716b26 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -85,6 +85,7 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
+ , preConnectRequests(0)
{
channels = new QHttpNetworkConnectionChannel[channelCount];
}
@@ -96,6 +97,7 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCoun
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
+ , preConnectRequests(0)
{
channels = new QHttpNetworkConnectionChannel[channelCount];
}
@@ -541,6 +543,9 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor
reply->d_func()->connectionChannel = &channels[0]; // will have the correct one set later
HttpMessagePair pair = qMakePair(request, reply);
+ if (request.isPreConnect())
+ preConnectRequests++;
+
switch (request.priority()) {
case QHttpNetworkRequest::HighPriority:
highPriorityQueue.prepend(pair);
@@ -925,13 +930,24 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
// If there is not already any connected channels we need to connect a new one.
// We do not pair the channel with the request until we know if it is
// connected or not. This is to reuse connected channels before we connect new once.
- int queuedRequest = highPriorityQueue.count() + lowPriorityQueue.count();
- for (int i = 0; i < channelCount; ++i) {
+ int queuedRequests = highPriorityQueue.count() + lowPriorityQueue.count();
+
+ // in case we have in-flight preconnect requests and normal requests,
+ // we only need one socket for each (preconnect, normal request) pair
+ int neededOpenChannels = queuedRequests;
+ if (preConnectRequests > 0) {
+ int normalRequests = queuedRequests - preConnectRequests;
+ neededOpenChannels = qMax(normalRequests, preConnectRequests);
+ }
+ for (int i = 0; i < channelCount && neededOpenChannels > 0; ++i) {
bool connectChannel = false;
if (channels[i].socket) {
- if ((channels[i].socket->state() == QAbstractSocket::ConnectingState) || (channels[i].socket->state() == QAbstractSocket::HostLookupState))
- queuedRequest--;
- if ( queuedRequest <=0 )
+ if ((channels[i].socket->state() == QAbstractSocket::ConnectingState)
+ || (channels[i].socket->state() == QAbstractSocket::HostLookupState)
+ || channels[i].pendingEncrypt) // pendingEncrypt == "EncryptingState"
+ neededOpenChannels--;
+
+ if (neededOpenChannels <= 0)
break;
if (!channels[i].reply && !channels[i].isSocketBusy() && (channels[i].socket->state() == QAbstractSocket::UnconnectedState))
connectChannel = true;
@@ -945,11 +961,8 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
else if (networkLayerState == IPv6)
channels[i].networkLayerPreference = QAbstractSocket::IPv6Protocol;
channels[i].ensureConnection();
- queuedRequest--;
+ neededOpenChannels--;
}
-
- if ( queuedRequest <=0 )
- break;
}
}
@@ -1270,6 +1283,11 @@ void QHttpNetworkConnection::ignoreSslErrors(const QList<QSslError> &errors, int
#endif //QT_NO_SSL
+void QHttpNetworkConnection::preConnectFinished()
+{
+ d_func()->preConnectRequests--;
+}
+
#ifndef QT_NO_NETWORKPROXY
// only called from QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired, not
// from QHttpNetworkConnectionChannel::handleAuthenticationChallenge
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 956499ddab..c54250f6ed 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -131,6 +131,8 @@ public:
void setSslContext(QSharedPointer<QSslContext> context);
#endif
+ void preConnectFinished();
+
private:
Q_DECLARE_PRIVATE(QHttpNetworkConnection)
Q_DISABLE_COPY(QHttpNetworkConnection)
@@ -239,6 +241,8 @@ public:
QList<HttpMessagePair> highPriorityQueue;
QList<HttpMessagePair> lowPriorityQueue;
+ int preConnectRequests;
+
#ifndef QT_NO_SSL
QSharedPointer<QSslContext> sslContext;
#endif
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index e14f426583..6e61eea5a4 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -183,6 +183,9 @@ void QHttpNetworkConnectionChannel::close()
else
state = QHttpNetworkConnectionChannel::ClosingState;
+ // pendingEncrypt must only be true in between connected and encrypted states
+ pendingEncrypt = false;
+
if (socket)
socket->close();
}
@@ -205,6 +208,17 @@ bool QHttpNetworkConnectionChannel::sendRequest()
// _q_connected or _q_encrypted
return false;
}
+ QString scheme = request.url().scheme();
+ if (scheme == QLatin1String("preconnect-http")
+ || scheme == QLatin1String("preconnect-https")) {
+ state = QHttpNetworkConnectionChannel::IdleState;
+ reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;
+ allDone();
+ connection->preConnectFinished(); // will only decrease the counter
+ reply = 0; // so we can reuse this channel
+ return true; // we have a working connection and are done
+ }
+
written = 0; // excluding the header
bytesTotal = 0;
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index eb8a8869cc..1b9e1f5a53 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -290,6 +290,11 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
#endif
{
+ QString scheme = newUrl.scheme();
+ if (scheme == QLatin1String("preconnect-http")
+ || scheme == QLatin1String("preconnect-https"))
+ // make sure we do not close the socket after preconnecting
+ connectionCloseEnabled = false;
}
QHttpNetworkReplyPrivate::~QHttpNetworkReplyPrivate()
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index e5b2eced99..d9f9b555d7 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -49,7 +49,8 @@ QT_BEGIN_NAMESPACE
QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op,
QHttpNetworkRequest::Priority pri, const QUrl &newUrl)
: QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), uploadByteDevice(0),
- autoDecompress(false), pipeliningAllowed(false), withCredentials(true)
+ autoDecompress(false), pipeliningAllowed(false), withCredentials(true),
+ preConnect(false)
{
}
@@ -64,6 +65,7 @@ QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequest
customVerb = other.customVerb;
withCredentials = other.withCredentials;
ssl = other.ssl;
+ preConnect = other.preConnect;
}
QHttpNetworkRequestPrivate::~QHttpNetworkRequestPrivate()
@@ -74,8 +76,15 @@ bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &ot
{
return QHttpNetworkHeaderPrivate::operator==(other)
&& (operation == other.operation)
+ && (priority == other.priority)
+ && (uploadByteDevice == other.uploadByteDevice)
+ && (autoDecompress == other.autoDecompress)
+ && (pipeliningAllowed == other.pipeliningAllowed)
+ // we do not clear the customVerb in setOperation
+ && (operation != QHttpNetworkRequest::Custom || (customVerb == other.customVerb))
+ && (withCredentials == other.withCredentials)
&& (ssl == other.ssl)
- && (uploadByteDevice == other.uploadByteDevice);
+ && (preConnect == other.preConnect);
}
QByteArray QHttpNetworkRequestPrivate::methodName() const
@@ -205,6 +214,15 @@ void QHttpNetworkRequest::setSsl(bool s)
d->ssl = s;
}
+bool QHttpNetworkRequest::isPreConnect() const
+{
+ return d->preConnect;
+}
+void QHttpNetworkRequest::setPreConnect(bool preConnect)
+{
+ d->preConnect = preConnect;
+}
+
qint64 QHttpNetworkRequest::contentLength() const
{
return d->contentLength();
diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h
index fc4a6928c6..ce9fbb1509 100644
--- a/src/network/access/qhttpnetworkrequest_p.h
+++ b/src/network/access/qhttpnetworkrequest_p.h
@@ -120,6 +120,9 @@ public:
bool isSsl() const;
void setSsl(bool);
+ bool isPreConnect() const;
+ void setPreConnect(bool preConnect);
+
void setUploadByteDevice(QNonContiguousByteDevice *bd);
QNonContiguousByteDevice* uploadByteDevice() const;
@@ -151,6 +154,7 @@ public:
bool pipeliningAllowed;
bool withCredentials;
bool ssl;
+ bool preConnect;
};
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index a2cee48b22..ee3911c72c 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -107,8 +107,14 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
{
QString result;
QUrl copy = url;
- bool isEncrypted = copy.scheme().toLower() == QLatin1String("https");
+ QString scheme = copy.scheme().toLower();
+ bool isEncrypted = scheme == QLatin1String("https");
copy.setPort(copy.port(isEncrypted ? 443 : 80));
+ if (scheme == QLatin1String("preconnect-http")) {
+ copy.setScheme(QLatin1String("http"));
+ } else if (scheme == QLatin1String("preconnect-https")) {
+ copy.setScheme(QLatin1String("https"));
+ }
result = copy.toString(QUrl::RemoveUserInfo | QUrl::RemovePath |
QUrl::RemoveQuery | QUrl::RemoveFragment | QUrl::FullyEncoded);
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index a895864d76..47cd928541 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -47,6 +47,7 @@
#include "qnetworkreply_p.h"
#include "QtCore/qhash.h"
#include "QtCore/qmutex.h"
+#include "QtCore/qstringlist.h"
#include "QtNetwork/private/qnetworksession_p.h"
#include "qnetworkaccesscachebackend_p.h"
@@ -110,6 +111,22 @@ QNetworkAccessBackend *QNetworkAccessManagerPrivate::findBackend(QNetworkAccessM
return 0;
}
+QStringList QNetworkAccessManagerPrivate::backendSupportedSchemes() const
+{
+ if (QNetworkAccessBackendFactoryData::valid.load()) {
+ QMutexLocker locker(&factoryData()->mutex);
+ QNetworkAccessBackendFactoryData::ConstIterator it = factoryData()->constBegin();
+ QNetworkAccessBackendFactoryData::ConstIterator end = factoryData()->constEnd();
+ QStringList schemes;
+ while (it != end) {
+ schemes += (*it)->supportedSchemes();
+ ++it;
+ }
+ return schemes;
+ }
+ return QStringList();
+}
+
QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
{
if (reply->outgoingDataBuffer)
diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h
index bf284414e0..d9657cf750 100644
--- a/src/network/access/qnetworkaccessbackend_p.h
+++ b/src/network/access/qnetworkaccessbackend_p.h
@@ -62,6 +62,7 @@ class QAuthenticator;
class QNetworkProxy;
class QNetworkProxyQuery;
class QNetworkRequest;
+class QStringList;
class QUrl;
class QUrlInfo;
class QSslConfiguration;
@@ -219,6 +220,7 @@ class QNetworkAccessBackendFactory
public:
QNetworkAccessBackendFactory();
virtual ~QNetworkAccessBackendFactory();
+ virtual QStringList supportedSchemes() const = 0;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const = 0;
};
diff --git a/src/network/access/qnetworkaccessdebugpipebackend.cpp b/src/network/access/qnetworkaccessdebugpipebackend.cpp
index b6c04dddea..a91751523a 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend.cpp
+++ b/src/network/access/qnetworkaccessdebugpipebackend.cpp
@@ -42,6 +42,7 @@
#include "qnetworkaccessdebugpipebackend_p.h"
#include "QtCore/qdatastream.h"
#include <QCoreApplication>
+#include <QStringList>
#include <QUrlQuery>
#include "private/qnoncontiguousbytedevice_p.h"
@@ -54,6 +55,11 @@ enum {
WriteBufferSize = ReadBufferSize
};
+QStringList QNetworkAccessDebugPipeBackendFactory::supportedSchemes() const
+{
+ return QStringList(QStringLiteral("debugpipe"));
+}
+
QNetworkAccessBackend *
QNetworkAccessDebugPipeBackendFactory::create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const
diff --git a/src/network/access/qnetworkaccessdebugpipebackend_p.h b/src/network/access/qnetworkaccessdebugpipebackend_p.h
index 0ae49de132..7593dfa9b7 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend_p.h
+++ b/src/network/access/qnetworkaccessdebugpipebackend_p.h
@@ -102,6 +102,7 @@ private:
class QNetworkAccessDebugPipeBackendFactory: public QNetworkAccessBackendFactory
{
public:
+ virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const;
};
diff --git a/src/network/access/qnetworkaccessfilebackend.cpp b/src/network/access/qnetworkaccessfilebackend.cpp
index 13428cc802..13e7394003 100644
--- a/src/network/access/qnetworkaccessfilebackend.cpp
+++ b/src/network/access/qnetworkaccessfilebackend.cpp
@@ -49,6 +49,17 @@
QT_BEGIN_NAMESPACE
+QStringList QNetworkAccessFileBackendFactory::supportedSchemes() const
+{
+ QStringList schemes;
+ schemes << QStringLiteral("file")
+ << QStringLiteral("qrc");
+#if defined(Q_OS_ANDROID)
+ schemes << QStringLiteral("assets");
+#endif
+ return schemes;
+}
+
QNetworkAccessBackend *
QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const
diff --git a/src/network/access/qnetworkaccessfilebackend_p.h b/src/network/access/qnetworkaccessfilebackend_p.h
index a52ecef165..157461fee7 100644
--- a/src/network/access/qnetworkaccessfilebackend_p.h
+++ b/src/network/access/qnetworkaccessfilebackend_p.h
@@ -88,6 +88,7 @@ private:
class QNetworkAccessFileBackendFactory: public QNetworkAccessBackendFactory
{
public:
+ virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const;
};
diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index 737d7d0151..246eb41657 100644
--- a/src/network/access/qnetworkaccessftpbackend.cpp
+++ b/src/network/access/qnetworkaccessftpbackend.cpp
@@ -43,6 +43,7 @@
#include "qnetworkaccessmanager_p.h"
#include "QtNetwork/qauthenticator.h"
#include "private/qnoncontiguousbytedevice_p.h"
+#include <QStringList>
#ifndef QT_NO_FTP
@@ -61,6 +62,11 @@ static QByteArray makeCacheKey(const QUrl &url)
QUrl::RemoveFragment);
}
+QStringList QNetworkAccessFtpBackendFactory::supportedSchemes() const
+{
+ return QStringList(QStringLiteral("ftp"));
+}
+
QNetworkAccessBackend *
QNetworkAccessFtpBackendFactory::create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const
diff --git a/src/network/access/qnetworkaccessftpbackend_p.h b/src/network/access/qnetworkaccessftpbackend_p.h
index 1bc377d80e..c006d450b8 100644
--- a/src/network/access/qnetworkaccessftpbackend_p.h
+++ b/src/network/access/qnetworkaccessftpbackend_p.h
@@ -111,6 +111,7 @@ private:
class QNetworkAccessFtpBackendFactory: public QNetworkAccessBackendFactory
{
public:
+ virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
const QNetworkRequest &request) const;
};
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 10d19bb7aa..91655ef485 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -96,9 +96,11 @@ bool getProxyAuth(const QString& proxyHostname, const QString &scheme, QString&
SecProtocolType protocolType = kSecProtocolTypeAny;
if (scheme.compare(QLatin1String("ftp"),Qt::CaseInsensitive)==0) {
protocolType = kSecProtocolTypeFTP;
- } else if (scheme.compare(QLatin1String("http"),Qt::CaseInsensitive)==0) {
+ } else if (scheme.compare(QLatin1String("http"),Qt::CaseInsensitive)==0
+ || scheme.compare(QLatin1String("preconnect-http"),Qt::CaseInsensitive)==0) {
protocolType = kSecProtocolTypeHTTP;
- } else if (scheme.compare(QLatin1String("https"),Qt::CaseInsensitive)==0) {
+ } else if (scheme.compare(QLatin1String("https"),Qt::CaseInsensitive)==0
+ || scheme.compare(QLatin1String("preconnect-https"),Qt::CaseInsensitive)==0) {
protocolType = kSecProtocolTypeHTTPS;
}
QByteArray proxyHostnameUtf8(proxyHostname.toUtf8());
@@ -431,6 +433,7 @@ static void ensureInitialized()
QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
: QObject(*new QNetworkAccessManagerPrivate, parent)
{
+ Q_D(QNetworkAccessManager);
ensureInitialized();
qRegisterMetaType<QNetworkReply::NetworkError>();
@@ -447,6 +450,19 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
#endif
qRegisterMetaType<QNetworkReply::NetworkError>();
qRegisterMetaType<QSharedPointer<char> >();
+
+#ifndef QT_NO_BEARERMANAGEMENT
+ if (!d->networkSessionRequired) {
+ // if a session is required, we track online state through
+ // the QNetworkSession's signals
+ connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)),
+ SLOT(_q_onlineStateChanged(bool)));
+ // we would need all active configurations to check for
+ // d->networkConfigurationManager.isOnline(), which is asynchronous
+ // and potentially expensive. We can just check the configuration here
+ d->online = (d->networkConfiguration.state() & QNetworkConfiguration::Active);
+ }
+#endif
}
/*!
@@ -833,6 +849,11 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ
To restore the default network configuration set the network configuration to the value
returned from QNetworkConfigurationManager::defaultConfiguration().
+ Setting a network configuration means that the QNetworkAccessManager instance will only
+ be using the specified one. In particular, if the default network configuration changes
+ (upon e.g. Wifi being available), this new configuration needs to be enabled
+ manually if desired.
+
\snippet code/src_network_access_qnetworkaccessmanager.cpp 2
If an invalid network configuration is set, a network session will not be created. In this
@@ -844,7 +865,10 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ
*/
void QNetworkAccessManager::setConfiguration(const QNetworkConfiguration &config)
{
- d_func()->createSession(config);
+ Q_D(QNetworkAccessManager);
+ d->networkConfiguration = config;
+ d->customNetworkConfiguration = true;
+ d->createSession(config);
}
/*!
@@ -926,19 +950,73 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess
{
Q_D(const QNetworkAccessManager);
- QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
- if (networkSession) {
- // d->online holds online/offline state of this network session.
+ if (d->networkSessionRequired) {
+ QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
+ if (networkSession) {
+ // d->online holds online/offline state of this network session.
+ if (d->online)
+ return d->networkAccessible;
+ else
+ return NotAccessible;
+ } else {
+ // Network accessibility is either disabled or unknown.
+ return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility;
+ }
+ } else {
if (d->online)
return d->networkAccessible;
else
return NotAccessible;
- } else {
- // Network accessibility is either disabled or unknown.
- return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility;
}
}
+#ifndef QT_NO_SSL
+/*!
+ \since 5.2
+
+ Initiates a connection to the host given by \a hostName at port \a port, using
+ \a sslConfiguration. This function is useful to complete the TCP and SSL handshake
+ to a host before the HTTPS request is made, resulting in a lower network latency.
+
+ \note This function has no possibility to report errors.
+
+ \sa connectToHost(), get(), post(), put(), deleteResource()
+*/
+void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quint16 port,
+ const QSslConfiguration &sslConfiguration)
+{
+ QUrl url;
+ url.setHost(hostName);
+ url.setPort(port);
+ url.setScheme(QLatin1String("preconnect-https"));
+ QNetworkRequest request(url);
+ if (sslConfiguration != QSslConfiguration::defaultConfiguration())
+ request.setSslConfiguration(sslConfiguration);
+ get(request);
+}
+#endif
+
+/*!
+ \since 5.2
+
+ Initiates a connection to the host given by \a hostName at port \a port.
+ This function is useful to complete the TCP handshake
+ to a host before the HTTP request is made, resulting in a lower network latency.
+
+ \note This function has no possibility to report errors.
+
+ \sa connectToHostEncrypted(), get(), post(), put(), deleteResource()
+*/
+void QNetworkAccessManager::connectToHost(const QString &hostName, quint16 port)
+{
+ QUrl url;
+ url.setHost(hostName);
+ url.setPort(port);
+ url.setScheme(QLatin1String("preconnect-http"));
+ QNetworkRequest request(url);
+ get(request);
+}
+
/*!
\internal
@@ -1050,10 +1128,10 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return new QDisabledNetworkReply(this, req, op);
}
- if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.isEmpty())) {
+ if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.identifier().isEmpty())) {
QNetworkConfigurationManager manager;
- if (!d->networkConfiguration.isEmpty()) {
- d->createSession(manager.configurationFromIdentifier(d->networkConfiguration));
+ if (!d->networkConfiguration.identifier().isEmpty()) {
+ d->createSession(d->networkConfiguration);
} else {
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)
d->createSession(manager.defaultConfiguration());
@@ -1083,9 +1161,9 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
#ifndef QT_NO_HTTP
// Since Qt 5 we use the new QNetworkReplyHttpImpl
- if (scheme == QLatin1String("http")
+ if (scheme == QLatin1String("http") || scheme == QLatin1String("preconnect-http")
#ifndef QT_NO_SSL
- || scheme == QLatin1String("https")
+ || scheme == QLatin1String("https") || scheme == QLatin1String("preconnect-https")
#endif
) {
QNetworkReplyHttpImpl *reply = new QNetworkReplyHttpImpl(this, request, op, outgoingData);
@@ -1130,6 +1208,57 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return reply;
}
+/*!
+ \since 5.2
+
+ Lists all the URL schemes supported by the access manager.
+
+ \sa supportedSchemesImplementation()
+*/
+QStringList QNetworkAccessManager::supportedSchemes() const
+{
+ QStringList schemes;
+ QNetworkAccessManager *self = const_cast<QNetworkAccessManager *>(this); // We know we call a const slot
+ QMetaObject::invokeMethod(self, "supportedSchemesImplementation", Qt::DirectConnection,
+ Q_RETURN_ARG(QStringList, schemes));
+ schemes.removeDuplicates();
+ return schemes;
+}
+
+/*!
+ \since 5.2
+
+ Lists all the URL schemes supported by the access manager.
+
+ You should not call this function directly; use
+ QNetworkAccessManager::supportedSchemes() instead.
+
+ Reimplement this slot to provide your own supported schemes
+ in a QNetworkAccessManager subclass. It is for instance necessary
+ when your subclass provides support for new protocols.
+
+ Because of binary compatibility constraints, the supportedSchemes()
+ method (introduced in Qt 5.2) is not virtual. Instead, supportedSchemes()
+ will dynamically detect and call this slot.
+
+ \sa supportedSchemes()
+*/
+QStringList QNetworkAccessManager::supportedSchemesImplementation() const
+{
+ Q_D(const QNetworkAccessManager);
+
+ QStringList schemes = d->backendSupportedSchemes();
+ // Those ones don't exist in backends
+#ifndef QT_NO_HTTP
+ schemes << QStringLiteral("http");
+#ifndef QT_NO_SSL
+ if (QSslSocket::supportsSsl())
+ schemes << QStringLiteral("https");
+#endif
+#endif
+ schemes << QStringLiteral("data");
+ return schemes;
+}
/*!
\since 5.0
@@ -1403,7 +1532,7 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
Q_Q(QNetworkAccessManager);
QSharedPointer<QNetworkSession> networkSession(getNetworkSession());
if (networkSession) {
- networkConfiguration = networkSession->configuration().identifier();
+ networkConfiguration = networkSession->configuration();
//disconnect from old session
QObject::disconnect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
@@ -1437,6 +1566,18 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession
}
}
}
+
+void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline)
+{
+ // if the user set a config, we only care whether this one is active.
+ // Otherwise, this QNAM is online if there is an online config.
+ if (customNetworkConfiguration) {
+ online = (networkConfiguration.state() & QNetworkConfiguration::Active);
+ } else {
+ online = isOnline;
+ }
+}
+
#endif // QT_NO_BEARERMANAGEMENT
QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart)
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 826c8e47d7..67b9bbcb07 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -43,6 +43,9 @@
#define QNETWORKACCESSMANAGER_H
#include <QtCore/QObject>
+#ifndef QT_NO_SSL
+#include <QtNetwork/QSslConfiguration>
+#endif
QT_BEGIN_NAMESPACE
@@ -97,6 +100,9 @@ public:
explicit QNetworkAccessManager(QObject *parent = 0);
~QNetworkAccessManager();
+ // ### Qt 6: turn into virtual
+ QStringList supportedSchemes() const;
+
void clearAccessCache();
#ifndef QT_NO_NETWORKPROXY
@@ -132,6 +138,12 @@ public:
NetworkAccessibility networkAccessible() const;
#endif
+#ifndef QT_NO_SSL
+ void connectToHostEncrypted(const QString &hostName, quint16 port = 443,
+ const QSslConfiguration &sslConfiguration = QSslConfiguration::defaultConfiguration());
+#endif
+ void connectToHost(const QString &hostName, quint16 port = 80);
+
Q_SIGNALS:
#ifndef QT_NO_NETWORKPROXY
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
@@ -153,6 +165,9 @@ protected:
virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request,
QIODevice *outgoingData = 0);
+protected Q_SLOTS:
+ QStringList supportedSchemesImplementation() const;
+
private:
friend class QNetworkReplyImplPrivate;
friend class QNetworkReplyHttpImpl;
@@ -165,6 +180,7 @@ private:
#ifndef QT_NO_BEARERMANAGEMENT
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed())
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State))
+ Q_PRIVATE_SLOT(d_func(), void _q_onlineStateChanged(bool))
#endif
};
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index cf756dad7b..292755e7eb 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -60,6 +60,9 @@
#include "QtNetwork/qnetworkproxy.h"
#include "QtNetwork/qnetworksession.h"
#include "qnetworkaccessauthenticationmanager_p.h"
+#ifndef QT_NO_BEARERMANAGEMENT
+#include "QtNetwork/qnetworkconfigmanager.h"
+#endif
QT_BEGIN_NAMESPACE
@@ -79,6 +82,10 @@ public:
#endif
#ifndef QT_NO_BEARERMANAGEMENT
lastSessionState(QNetworkSession::Invalid),
+ networkConfiguration(networkConfigurationManager.defaultConfiguration()),
+ customNetworkConfiguration(false),
+ networkSessionRequired(networkConfigurationManager.capabilities()
+ & QNetworkConfigurationManager::NetworkSessionRequired),
networkAccessible(QNetworkAccessManager::Accessible),
activeReplyCount(0),
online(false),
@@ -117,6 +124,7 @@ public:
#endif
QNetworkAccessBackend *findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request);
+ QStringList backendSupportedSchemes() const;
#ifndef QT_NO_BEARERMANAGEMENT
void createSession(const QNetworkConfiguration &config);
@@ -127,6 +135,7 @@ public:
void _q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &config,
bool isSeamless);
void _q_networkSessionStateChanged(QNetworkSession::State state);
+ void _q_onlineStateChanged(bool isOnline);
#endif
QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart);
@@ -148,7 +157,12 @@ public:
QSharedPointer<QNetworkSession> networkSessionStrongRef;
QWeakPointer<QNetworkSession> networkSessionWeakRef;
QNetworkSession::State lastSessionState;
- QString networkConfiguration;
+ QNetworkConfigurationManager networkConfigurationManager;
+ QNetworkConfiguration networkConfiguration;
+ // we need to track whether the user set a config or not,
+ // because the default config might change
+ bool customNetworkConfiguration;
+ bool networkSessionRequired;
QNetworkAccessManager::NetworkAccessibility networkAccessible;
int activeReplyCount;
bool online;
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index c7d3846465..ddef970966 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -629,10 +629,15 @@ void QNetworkReplyHttpImplPrivate::postRequest()
QUrl url = request.url();
httpRequest.setUrl(url);
- bool ssl = url.scheme().toLower() == QLatin1String("https");
+ QString scheme = url.scheme().toLower();
+ bool ssl = (scheme == QLatin1String("https")
+ || scheme == QLatin1String("preconnect-https"));
q->setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, ssl);
httpRequest.setSsl(ssl);
+ bool preConnect = (scheme == QLatin1String("preconnect-http")
+ || scheme == QLatin1String("preconnect-https"));
+ httpRequest.setPreConnect(preConnect);
#ifndef QT_NO_NETWORKPROXY
QNetworkProxy transparentProxy, cacheProxy;
diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp
index 615ef21661..fae4aad76e 100644
--- a/src/network/bearer/qnetworkconfiguration.cpp
+++ b/src/network/bearer/qnetworkconfiguration.cpp
@@ -41,6 +41,12 @@
#include "qnetworkconfiguration.h"
#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
@@ -193,13 +199,88 @@ QT_BEGIN_NAMESPACE
\value BearerEthernet The configuration is for an Ethernet interfaces.
\value BearerWLAN The configuration is for a Wireless LAN interface.
\value Bearer2G The configuration is for a CSD, GPRS, HSCSD, EDGE or cdmaOne interface.
+ \value Bearer3G The configuration is for a 3G interface.
+ \value Bearer4G The configuration is for a 4G interface.
\value BearerCDMA2000 The configuration is for CDMA interface.
\value BearerWCDMA The configuration is for W-CDMA/UMTS interface.
\value BearerHSPA The configuration is for High Speed Packet Access (HSPA) interface.
\value BearerBluetooth The configuration is for a Bluetooth interface.
\value BearerWiMAX The configuration is for a WiMAX interface.
+ \value BearerEVDO The configuration is for an EVDO (3G) interface.
+ \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() << Q_FUNC_INFO << "failed to open" << cellularStatusFile;
+ return ret;
+ }
+ char buf[2048];
+ if (qt_safe_read(cellularStatusFD, &buf, sizeof(buf)) == -1) {
+ qWarning() << Q_FUNC_INFO << "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() << Q_FUNC_INFO << "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() << Q_FUNC_INFO << "pps_decoder_push failed" << err;
+ pps_decoder_cleanup(&ppsDecoder);
+ qt_safe_close(cellularStatusFD);
+ return ret;
+ }
+ if (!pps_decoder_is_integer(&ppsDecoder, "network_technology")) {
+ qWarning() << Q_FUNC_INFO << "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() << Q_FUNC_INFO << "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() << Q_FUNC_INFO << "unhandled bearer type" << type;
+ break;
+ }
+ pps_decoder_cleanup(&ppsDecoder);
+ qt_safe_close(cellularStatusFD);
+ return ret;
+}
+#endif // Q_OS_BLACKBERRY
+
/*!
Constructs an invalid configuration object.
@@ -412,6 +493,8 @@ QList<QNetworkConfiguration> QNetworkConfiguration::children() const
function can be used to retrieve a textural type name for the bearer.
An invalid network configuration always returns the BearerUnknown value.
+
+ \sa bearerTypeName(), bearerTypeFamily()
*/
QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType() const
{
@@ -420,10 +503,74 @@ QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType() const
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;
}
/*!
+ \since 5.2
+
+ Returns the bearer type family used by this network configuration.
+ The following table lists how bearerType() values map to
+ bearerTypeFamily() values:
+
+ \table
+ \header
+ \li bearer type
+ \li bearer type family
+ \row
+ \li BearerUnknown, Bearer2G, BearerEthernet, BearerWLAN,
+ BearerBluetooth
+ \li (same type)
+ \row
+ \li BearerCDMA2000, BearerEVDO, BearerWCDMA, BearerHSPA, Bearer3G
+ \li Bearer3G
+ \row
+ \li BearerWiMAX, BearerLTE, Bearer4G
+ \li Bearer4G
+ \endtable
+
+ An invalid network configuration always returns the BearerUnknown value.
+
+ \sa bearerType(), bearerTypeName()
+*/
+QNetworkConfiguration::BearerType QNetworkConfiguration::bearerTypeFamily() const
+{
+ QNetworkConfiguration::BearerType type = bearerType();
+ switch (type) {
+ case QNetworkConfiguration::BearerUnknown: // fallthrough
+ case QNetworkConfiguration::Bearer2G: // fallthrough
+ case QNetworkConfiguration::BearerEthernet: // fallthrough
+ case QNetworkConfiguration::BearerWLAN: // fallthrough
+ case QNetworkConfiguration::BearerBluetooth:
+ return type;
+ case QNetworkConfiguration::BearerCDMA2000: // fallthrough
+ case QNetworkConfiguration::BearerEVDO: // fallthrough
+ case QNetworkConfiguration::BearerWCDMA: // fallthrough
+ case QNetworkConfiguration::BearerHSPA: // fallthrough
+ case QNetworkConfiguration::Bearer3G:
+ return QNetworkConfiguration::Bearer3G;
+ case QNetworkConfiguration::BearerWiMAX: // fallthrough
+ case QNetworkConfiguration::BearerLTE: // fallthrough
+ case QNetworkConfiguration::Bearer4G:
+ return QNetworkConfiguration::Bearer4G;
+ default:
+ qWarning() << "unknown bearer type" << type;
+ return QNetworkConfiguration::BearerUnknown;
+ }
+}
+/*!
Returns the type of bearer used by this network configuration as a string.
The string is not translated and therefore can not be shown to the user. The subsequent table
@@ -450,6 +597,12 @@ QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType() const
\li Bearer2G
\li 2G
\row
+ \li Bearer3G
+ \li 3G
+ \row
+ \li Bearer4G
+ \li 4G
+ \row
\li BearerCDMA2000
\li CDMA2000
\row
@@ -464,13 +617,19 @@ QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType() const
\row
\li BearerWiMAX
\li WiMAX
+ \row
+ \li BearerEVDO
+ \li EVDO
+ \row
+ \li BearerLTE
+ \li LTE
\endtable
This function returns an empty string if this is an invalid configuration, a network
configuration of type \l QNetworkConfiguration::ServiceNetwork or
\l QNetworkConfiguration::UserChoice.
- \sa bearerType()
+ \sa bearerType(), bearerTypeFamily()
*/
QString QNetworkConfiguration::bearerTypeName() const
{
@@ -489,7 +648,25 @@ 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");
+ case Bearer4G:
+ return QStringLiteral("4G");
case BearerCDMA2000:
return QStringLiteral("CDMA2000");
case BearerWCDMA:
@@ -500,6 +677,10 @@ QString QNetworkConfiguration::bearerTypeName() const
return QStringLiteral("Bluetooth");
case BearerWiMAX:
return QStringLiteral("WiMAX");
+ case BearerEVDO:
+ return QStringLiteral("EVDO");
+ case BearerLTE:
+ return QStringLiteral("LTE");
case BearerUnknown:
break;
}
diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h
index 25dafcb282..8887525a2f 100644
--- a/src/network/bearer/qnetworkconfiguration.h
+++ b/src/network/bearer/qnetworkconfiguration.h
@@ -97,7 +97,11 @@ public:
BearerWCDMA,
BearerHSPA,
BearerBluetooth,
- BearerWiMAX
+ BearerWiMAX,
+ BearerEVDO,
+ BearerLTE,
+ Bearer3G,
+ Bearer4G
};
StateFlags state() const;
@@ -105,6 +109,7 @@ public:
Purpose purpose() const;
BearerType bearerType() const;
+ BearerType bearerTypeFamily() const;
QString bearerTypeName() const;
QString identifier() const;
diff --git a/src/network/doc/qtnetwork.qdocconf b/src/network/doc/qtnetwork.qdocconf
index 048b3325b6..f4779ae8fe 100644
--- a/src/network/doc/qtnetwork.qdocconf
+++ b/src/network/doc/qtnetwork.qdocconf
@@ -40,3 +40,6 @@ exampledirs += ../../../examples/network \
imagedirs += images \
../../../examples/network/doc/images
+
+navigation.landingpage = "Qt Network"
+navigation.cppclassespage = "Qt Network C++ Classes"
diff --git a/src/network/doc/src/qtnetwork.qdoc b/src/network/doc/src/qtnetwork.qdoc
index 6d9f6023ab..2faafff82e 100644
--- a/src/network/doc/src/qtnetwork.qdoc
+++ b/src/network/doc/src/qtnetwork.qdoc
@@ -65,6 +65,7 @@
\module QtNetwork
\title Qt Network C++ Classes
\ingroup modules
+ \qtvariable network
\brief Provides classes to make network programming easier and portable
To include the definitions of the module's classes, use the
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index dc67b0d835..5ef428305c 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -189,7 +189,7 @@ static bool parseIp6(const QString &address, QIPAddressUtils::IPv6Address &addr,
} else {
scopeId->clear();
}
- return QIPAddressUtils::parseIp6(addr, tmp.constBegin(), tmp.constEnd());
+ return QIPAddressUtils::parseIp6(addr, tmp.constBegin(), tmp.constEnd()) == 0;
}
bool QHostAddressPrivate::parse()
diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp
index 4e33001d8d..ec771e1f49 100644
--- a/src/network/ssl/qssl.cpp
+++ b/src/network/ssl/qssl.cpp
@@ -161,12 +161,20 @@ QT_BEGIN_NAMESPACE
mechanism for renegotiating the connection parameters. When enabled, this
option can allow connections for legacy servers, but it introduces the
possibility that an attacker could inject plaintext into the SSL session.
+ \value SslOptionDisableSessionSharing Disables SSL session sharing via
+ the session ID handshake attribute.
+ \value SslOptionDisableSessionPersistence Disables storing the SSL session
+ in ASN.1 format as returned by QSslConfiguration::session(). Enabling
+ this feature adds memory overhead of approximately 1K per used session
+ ticket.
By default, SslOptionDisableEmptyFragments is turned on since this causes
problems with a large number of servers. SslOptionDisableLegacyRenegotiation
is also turned on, since it introduces a security risk.
SslOptionDisableCompression is turned on to prevent the attack publicised by
- CRIME. The other options are turned off.
+ CRIME.
+ SslOptionDisableSessionPersistence is turned on to optimize memory usage.
+ The other options are turned off.
Note: Availability of above options depends on the version of the SSL
backend in use.
diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h
index 06d80965e2..21d03cb703 100644
--- a/src/network/ssl/qssl.h
+++ b/src/network/ssl/qssl.h
@@ -95,7 +95,9 @@ namespace QSsl {
SslOptionDisableSessionTickets = 0x02,
SslOptionDisableCompression = 0x04,
SslOptionDisableServerNameIndication = 0x08,
- SslOptionDisableLegacyRenegotiation = 0x10
+ SslOptionDisableLegacyRenegotiation = 0x10,
+ SslOptionDisableSessionSharing = 0x20,
+ SslOptionDisableSessionPersistence = 0x40
};
Q_DECLARE_FLAGS(SslOptions, SslOption)
}
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index afbd4fac77..6cc06dfbd2 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -49,7 +49,8 @@ QT_BEGIN_NAMESPACE
const QSsl::SslOptions QSslConfigurationPrivate::defaultSslOptions = QSsl::SslOptionDisableEmptyFragments
|QSsl::SslOptionDisableLegacyRenegotiation
- |QSsl::SslOptionDisableCompression;
+ |QSsl::SslOptionDisableCompression
+ |QSsl::SslOptionDisableSessionPersistence;
/*!
\class QSslConfiguration
@@ -182,7 +183,9 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
d->peerVerifyMode == other.d->peerVerifyMode &&
d->peerVerifyDepth == other.d->peerVerifyDepth &&
d->allowRootCertOnDemandLoading == other.d->allowRootCertOnDemandLoading &&
- d->sslOptions == other.d->sslOptions;
+ d->sslOptions == other.d->sslOptions &&
+ d->sslSession == other.d->sslSession &&
+ d->sslSessionTicketLifeTimeHint == other.d->sslSessionTicketLifeTimeHint;
}
/*!
@@ -216,7 +219,9 @@ bool QSslConfiguration::isNull() const
d->privateKey.isNull() &&
d->peerCertificate.isNull() &&
d->peerCertificateChain.count() == 0 &&
- d->sslOptions == QSslConfigurationPrivate::defaultSslOptions);
+ d->sslOptions == QSslConfigurationPrivate::defaultSslOptions &&
+ d->sslSession.isNull() &&
+ d->sslSessionTicketLifeTimeHint == -1);
}
/*!
@@ -594,6 +599,60 @@ bool QSslConfiguration::testSslOption(QSsl::SslOption option) const
}
/*!
+ \since 5.2
+
+ If QSsl::SslOptionDisableSessionPersistence was turned off, this
+ function returns the session used in the SSL handshake in ASN.1
+ format, suitable to e.g. be persisted to disk. If no session was
+ used or QSsl::SslOptionDisableSessionPersistence was not turned off,
+ this function returns an empty QByteArray.
+
+ \b{Note:} When persisting the session to disk or similar, be
+ careful not to expose the session to a potential attacker, as
+ knowledge of the session allows for eavesdropping on data
+ encrypted with the session parameters.
+
+ \sa setSession(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
+ */
+QByteArray QSslConfiguration::session() const
+{
+ return d->sslSession;
+}
+
+/*!
+ \since 5.2
+
+ Sets the session to be used in an SSL handshake.
+ QSsl::SslOptionDisableSessionPersistence must be turned off
+ for this to work, and \a session must be in ASN.1 format
+ as returned by session().
+
+ \sa session(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
+ */
+void QSslConfiguration::setSession(const QByteArray &session)
+{
+ d->sslSession = session;
+}
+
+/*!
+ \since 5.2
+
+ If QSsl::SslOptionDisableSessionPersistence was turned off, this
+ function returns the session ticket life time hint sent by the
+ server (which might be 0).
+ If the server did not send a session ticket (e.g. when
+ resuming a session or when the server does not support it) or
+ QSsl::SslOptionDisableSessionPersistence was not turned off,
+ this function returns -1.
+
+ \sa session(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
+ */
+int QSslConfiguration::sessionTicketLifeTimeHint() const
+{
+ return d->sslSessionTicketLifeTimeHint;
+}
+
+/*!
Returns the default SSL configuration to be used in new SSL
connections.
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index 0000382ed5..949ce70d4c 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -124,6 +124,10 @@ public:
void setSslOption(QSsl::SslOption option, bool on);
bool testSslOption(QSsl::SslOption option) const;
+ QByteArray session() const;
+ void setSession(const QByteArray &session);
+ int sessionTicketLifeTimeHint() const;
+
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h
index 54b7264d3d..71ee8d2bfe 100644
--- a/src/network/ssl/qsslconfiguration_p.h
+++ b/src/network/ssl/qsslconfiguration_p.h
@@ -85,7 +85,8 @@ public:
peerVerifyDepth(0),
allowRootCertOnDemandLoading(true),
peerSessionShared(false),
- sslOptions(QSslConfigurationPrivate::defaultSslOptions)
+ sslOptions(QSslConfigurationPrivate::defaultSslOptions),
+ sslSessionTicketLifeTimeHint(-1)
{ }
QSslCertificate peerCertificate;
@@ -110,6 +111,9 @@ public:
Q_AUTOTEST_EXPORT static const QSsl::SslOptions defaultSslOptions;
+ QByteArray sslSession;
+ int sslSessionTicketLifeTimeHint;
+
// in qsslsocket.cpp:
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
diff --git a/src/network/ssl/qsslcontext.cpp b/src/network/ssl/qsslcontext.cpp
index 22ad42116b..6d281c390d 100644
--- a/src/network/ssl/qsslcontext.cpp
+++ b/src/network/ssl/qsslcontext.cpp
@@ -57,7 +57,8 @@ extern QString getErrorsFromOpenSsl();
QSslContext::QSslContext()
: ctx(0),
pkey(0),
- session(0)
+ session(0),
+ m_sessionTicketLifeTimeHint(-1)
{
}
@@ -258,6 +259,10 @@ init_context:
if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth());
+ // set persisted session if the user set it
+ if (!configuration.session().isEmpty())
+ sslContext->setSessionASN1(configuration.session());
+
return sslContext;
}
@@ -267,6 +272,12 @@ SSL* QSslContext::createSsl()
SSL* ssl = q_SSL_new(ctx);
q_SSL_clear(ssl);
+ if (!session && !sessionASN1().isEmpty()
+ && !sslConfiguration.testSslOption(QSsl::SslOptionDisableSessionPersistence)) {
+ const unsigned char *data = reinterpret_cast<const unsigned char *>(m_sessionASN1.constData());
+ session = q_d2i_SSL_SESSION(0, &data, m_sessionASN1.size()); // refcount is 1 already, set by function above
+ }
+
if (session) {
// Try to resume the last session we cached
if (!q_SSL_set_session(ssl, session)) {
@@ -292,8 +303,34 @@ bool QSslContext::cacheSession(SSL* ssl)
// cache the session the caller gave us and increase reference count
session = q_SSL_get1_session(ssl);
- return (session != NULL);
+ if (session && !sslConfiguration.testSslOption(QSsl::SslOptionDisableSessionPersistence)) {
+ int sessionSize = q_i2d_SSL_SESSION(session, 0);
+ if (sessionSize > 0) {
+ m_sessionASN1.resize(sessionSize);
+ unsigned char *data = reinterpret_cast<unsigned char *>(m_sessionASN1.data());
+ if (!q_i2d_SSL_SESSION(session, &data))
+ qWarning("could not store persistent version of SSL session");
+ m_sessionTicketLifeTimeHint = session->tlsext_tick_lifetime_hint;
+ }
+ }
+
+ return (session != 0);
+}
+
+QByteArray QSslContext::sessionASN1() const
+{
+ return m_sessionASN1;
+}
+
+void QSslContext::setSessionASN1(const QByteArray &session)
+{
+ m_sessionASN1 = session;
+}
+
+int QSslContext::sessionTicketLifeTimeHint() const
+{
+ return m_sessionTicketLifeTimeHint;
}
QSslError::SslError QSslContext::error() const
diff --git a/src/network/ssl/qsslcontext_p.h b/src/network/ssl/qsslcontext_p.h
index c8578d349e..2b596798a6 100644
--- a/src/network/ssl/qsslcontext_p.h
+++ b/src/network/ssl/qsslcontext_p.h
@@ -69,6 +69,9 @@ public:
SSL* createSsl();
bool cacheSession(SSL*); // should be called when handshake completed
+ QByteArray sessionASN1() const;
+ void setSessionASN1(const QByteArray &sessionASN1);
+ int sessionTicketLifeTimeHint() const;
protected:
QSslContext();
@@ -76,6 +79,8 @@ private:
SSL_CTX* ctx;
EVP_PKEY *pkey;
SSL_SESSION *session;
+ QByteArray m_sessionASN1;
+ int m_sessionTicketLifeTimeHint;
QSslError::SslError errorCode;
QString errorStr;
QSslConfiguration sslConfiguration;
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index f2310356df..0e7ac39d14 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -903,6 +903,8 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
d->configuration.peerVerifyMode = configuration.peerVerifyMode();
d->configuration.protocol = configuration.protocol();
d->configuration.sslOptions = configuration.d->sslOptions;
+ d->configuration.sslSession = configuration.session();
+ d->configuration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
// if the CA certificates were set explicitly (either via
// QSslConfiguration::setCaCertificates() or QSslSocket::setCaCertificates(),
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 30103edc29..e94df10fed 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE
#if defined(Q_OS_MACX)
#define kSecTrustSettingsDomainSystem 2 // so we do not need to include the header file
- PtrSecCertificateGetData QSslSocketPrivate::ptrSecCertificateGetData = 0;
+ PtrSecCertificateCopyData QSslSocketPrivate::ptrSecCertificateCopyData = 0;
PtrSecTrustSettingsCopyCertificates QSslSocketPrivate::ptrSecTrustSettingsCopyCertificates = 0;
PtrSecTrustCopyAnchorCertificates QSslSocketPrivate::ptrSecTrustCopyAnchorCertificates = 0;
#elif defined(Q_OS_WIN)
@@ -492,8 +492,8 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
#if defined(Q_OS_MACX)
QLibrary securityLib("/System/Library/Frameworks/Security.framework/Versions/Current/Security");
if (securityLib.load()) {
- ptrSecCertificateGetData = (PtrSecCertificateGetData) securityLib.resolve("SecCertificateGetData");
- if (!ptrSecCertificateGetData)
+ ptrSecCertificateCopyData = (PtrSecCertificateCopyData) securityLib.resolve("SecCertificateCopyData");
+ if (!ptrSecCertificateCopyData)
qWarning("could not resolve symbols in security library"); // should never happen
ptrSecTrustSettingsCopyCertificates = (PtrSecTrustSettingsCopyCertificates) securityLib.resolve("SecTrustSettingsCopyCertificates");
@@ -629,12 +629,11 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
CFArrayRef cfCerts;
OSStatus status = 1;
- OSStatus SecCertificateGetData (
- SecCertificateRef certificate,
- CSSM_DATA_PTR data
+ CFDataRef SecCertificateCopyData (
+ SecCertificateRef certificate
);
- if (ptrSecCertificateGetData) {
+ if (ptrSecCertificateCopyData) {
if (ptrSecTrustSettingsCopyCertificates)
status = ptrSecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &cfCerts);
else if (ptrSecTrustCopyAnchorCertificates)
@@ -643,15 +642,16 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
CFIndex size = CFArrayGetCount(cfCerts);
for (CFIndex i = 0; i < size; ++i) {
SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i);
- CSSM_DATA data;
- CSSM_DATA_PTR dataPtr = &data;
- if (ptrSecCertificateGetData(cfCert, dataPtr)) {
+ CFDataRef data;
+
+ data = ptrSecCertificateCopyData(cfCert);
+
+ if (data == NULL) {
qWarning("error retrieving a CA certificate from the system store");
} else {
- int len = data.Length;
- char *rawData = reinterpret_cast<char *>(data.Data);
- QByteArray rawCert(rawData, len);
+ QByteArray rawCert = QByteArray::fromRawData((const char *)CFDataGetBytePtr(data), CFDataGetLength(data));
systemCerts.append(QSslCertificate::fromData(rawCert, QSsl::Der));
+ CFRelease(data);
}
}
CFRelease(cfCerts);
@@ -1458,9 +1458,17 @@ void QSslSocketBackendPrivate::continueHandshake()
#endif
// Cache this SSL session inside the QSslContext
- if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionTickets)) {
- if (!sslContextPointer->cacheSession(ssl))
+ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) {
+ if (!sslContextPointer->cacheSession(ssl)) {
sslContextPointer.clear(); // we could not cache the session
+ } else {
+ // Cache the session for permanent usage as well
+ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionPersistence)) {
+ if (!sslContextPointer->sessionASN1().isEmpty())
+ configuration.sslSession = sslContextPointer->sessionASN1();
+ configuration.sslSessionTicketLifeTimeHint = sslContextPointer->sessionTicketLifeTimeHint();
+ }
+ }
}
connectionEncrypted = true;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index d2a349455e..a010075436 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -332,6 +332,8 @@ DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYA
DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return)
+DEFINEFUNC2(int, i2d_SSL_SESSION, SSL_SESSION *in, in, unsigned char **pp, pp, return 0, return)
+DEFINEFUNC3(SSL_SESSION *, d2i_SSL_SESSION, SSL_SESSION **a, a, const unsigned char **pp, pp, long length, length, return 0, return)
#define RESOLVEFUNC(func) \
if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \
@@ -548,7 +550,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
#ifdef Q_OS_OPENBSD
libcrypto->setLoadHints(QLibrary::ExportExternalSymbolsHint);
#endif
-#ifdef SHLIB_VERSION_NUMBER
+#if defined(SHLIB_VERSION_NUMBER) && !defined(Q_OS_QNX) // on QNX, the libs are always libssl.so and libcrypto.so
// first attempt: the canonical name is libssl.so.<SHLIB_VERSION_NUMBER>
libssl->setFileNameAndVersion(QLatin1String("ssl"), QLatin1String(SHLIB_VERSION_NUMBER));
libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER));
@@ -801,6 +803,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_CTX_load_verify_locations)
RESOLVEFUNC(SSLeay)
RESOLVEFUNC(SSLeay_version)
+ RESOLVEFUNC(i2d_SSL_SESSION)
+ RESOLVEFUNC(d2i_SSL_SESSION)
symbolsResolved = true;
delete libs.first;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 2e01ee4d31..1fd98cc7fb 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -469,6 +469,8 @@ void q_OPENSSL_add_all_algorithms_conf();
int q_SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath);
long q_SSLeay();
const char *q_SSLeay_version(int type);
+int q_i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
+SSL_SESSION *q_d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length);
// Helper function
class QDateTime;
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 6ce34ba06f..6281753225 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -79,7 +79,7 @@
QT_BEGIN_NAMESPACE
#if defined(Q_OS_MACX)
- typedef OSStatus (*PtrSecCertificateGetData)(SecCertificateRef, CSSM_DATA_PTR);
+ typedef CFDataRef (*PtrSecCertificateCopyData)(SecCertificateRef);
typedef OSStatus (*PtrSecTrustSettingsCopyCertificates)(int, CFArrayRef*);
typedef OSStatus (*PtrSecTrustCopyAnchorCertificates)(CFArrayRef*);
#endif
@@ -146,7 +146,7 @@ public:
static void addDefaultCaCertificates(const QList<QSslCertificate> &certs);
#if defined(Q_OS_MACX)
- static PtrSecCertificateGetData ptrSecCertificateGetData;
+ static PtrSecCertificateCopyData ptrSecCertificateCopyData;
static PtrSecTrustSettingsCopyCertificates ptrSecTrustSettingsCopyCertificates;
static PtrSecTrustCopyAnchorCertificates ptrSecTrustCopyAnchorCertificates;
#elif defined(Q_OS_WIN)
diff --git a/src/opengl/doc/qtopengl.qdocconf b/src/opengl/doc/qtopengl.qdocconf
index e76a23844b..5b6d09dfcd 100644
--- a/src/opengl/doc/qtopengl.qdocconf
+++ b/src/opengl/doc/qtopengl.qdocconf
@@ -19,7 +19,7 @@ exampledirs += ../../../examples/opengl \
imagedirs += images \
../../../examples/opengl/doc/images
-depends += qtcore qtgui qtwidgets
+depends += qtdoc qtcore qtgui qtwidgets
examplesinstallpath = opengl
@@ -50,3 +50,6 @@ qhp.QtOpenGL.subprojects.classes.title = C++ Classes
qhp.QtOpenGL.subprojects.classes.indexTitle = Qt OpenGL C++ Classes
qhp.QtOpenGL.subprojects.classes.selectors = class fake:headerfile
qhp.QtOpenGL.subprojects.classes.sortPages = true
+
+navigation.landingpage = "Qt OpenGL"
+navigation.cppclassespage = "Qt OpenGL C++ Classes"
diff --git a/src/opengl/doc/src/qtopengl-module.qdoc b/src/opengl/doc/src/qtopengl-module.qdoc
index 901766ae46..8619f04a97 100644
--- a/src/opengl/doc/src/qtopengl-module.qdoc
+++ b/src/opengl/doc/src/qtopengl-module.qdoc
@@ -29,6 +29,7 @@
\module QtOpenGL
\title Qt OpenGL C++ Classes
\ingroup modules
+ \qtvariable opengl
\brief The Qt OpenGL module offers classes that make it easy to
use OpenGL in Qt applications.
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_p.h
index c78c57b86f..d9bd9a78e4 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_p.h
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_p.h
@@ -72,7 +72,8 @@ public:
Device_Touchscreen = 0x04,
Device_Keyboard = 0x08,
Device_DRM = 0x10,
- Device_Tablet = 0x20,
+ Device_DRM_PrimaryGPU = 0x20,
+ Device_Tablet = 0x40,
Device_InputMask = Device_Mouse | Device_Touchpad | Device_Touchscreen | Device_Keyboard | Device_Tablet,
Device_VideoMask = Device_DRM
};
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
index 9e0ce47e18..ac902b4140 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
@@ -149,8 +149,16 @@ QStringList QDeviceDiscovery::scanConnectedDevices()
QString candidate = QString::fromUtf8(udev_device_get_devnode(udevice));
if ((m_types & Device_InputMask) && candidate.startsWith(QLatin1String(QT_EVDEV_DEVICE)))
devices << candidate;
- if ((m_types & Device_VideoMask) && candidate.startsWith(QLatin1String(QT_DRM_DEVICE)))
- devices << candidate;
+ if ((m_types & Device_VideoMask) && candidate.startsWith(QLatin1String(QT_DRM_DEVICE))) {
+ if (m_types & Device_DRM_PrimaryGPU) {
+ udev_device *pci = udev_device_get_parent_with_subsystem_devtype(udevice, "pci", 0);
+ if (pci) {
+ if (qstrcmp(udev_device_get_sysattr_value(pci, "boot_vga"), "1") == 0)
+ devices << candidate;
+ }
+ } else
+ devices << candidate;
+ }
udev_device_unref(udevice);
}
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
index 8152f74067..34ba21afdc 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -106,6 +106,14 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
+ // shortcut: on some GPUs, eglMakeCurrent is not a cheap operation
+ if (eglGetCurrentContext() == m_eglContext &&
+ eglGetCurrentDisplay() == m_eglDisplay &&
+ eglGetCurrentSurface(EGL_READ) == eglSurface &&
+ eglGetCurrentSurface(EGL_DRAW) == eglSurface) {
+ return true;
+ }
+
bool ok = eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext);
if (!ok)
qWarning("QEGLPlatformContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
index 58f24c0a04..80453816fc 100644
--- a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
+++ b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
@@ -41,17 +41,6 @@
#include "qxlibeglintegration_p.h"
-static int countBits(unsigned long mask)
-{
- int count = 0;
- while (mask != 0) {
- if (mask & 1)
- ++count;
- mask >>= 1;
- }
- return count;
-}
-
VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config)
{
VisualID visualId = 0;
@@ -92,9 +81,9 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay
return visualId;
}
- int visualRedSize = countBits(chosenVisualInfo->red_mask);
- int visualGreenSize = countBits(chosenVisualInfo->green_mask);
- int visualBlueSize = countBits(chosenVisualInfo->blue_mask);
+ int visualRedSize = qPopulationCount(chosenVisualInfo->red_mask);
+ int visualGreenSize = qPopulationCount(chosenVisualInfo->green_mask);
+ int visualBlueSize = qPopulationCount(chosenVisualInfo->blue_mask);
int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size
bool visualMatchesConfig = false;
diff --git a/src/platformsupport/eventdispatchers/eventdispatchers.pri b/src/platformsupport/eventdispatchers/eventdispatchers.pri
index 6e16a46b34..ec556486b1 100644
--- a/src/platformsupport/eventdispatchers/eventdispatchers.pri
+++ b/src/platformsupport/eventdispatchers/eventdispatchers.pri
@@ -8,6 +8,14 @@ HEADERS +=\
$$PWD/qgenericunixeventdispatcher_p.h\
}
+ios {
+OBJECTIVE_SOURCES +=\
+ $$PWD/qioseventdispatcher.mm
+
+HEADERS +=\
+ $$PWD/qioseventdispatcher_p.h
+}
+
contains(QT_CONFIG, glib) {
SOURCES +=$$PWD/qeventdispatcher_glib.cpp
HEADERS +=$$PWD/qeventdispatcher_glib_p.h
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/platformsupport/eventdispatchers/qioseventdispatcher.mm
index e9bf039047..ab3036143d 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/platformsupport/eventdispatchers/qioseventdispatcher.mm
@@ -39,8 +39,7 @@
**
****************************************************************************/
-#include "qioseventdispatcher.h"
-#import "qiosapplicationdelegate.h"
+#include "qioseventdispatcher_p.h"
#include <qdebug.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/QThread>
@@ -118,7 +117,9 @@ void QIOSEventDispatcher::maybeStartCFRunLoopTimer()
m_runLoopTimerRef = CFRunLoopTimerCreate(0, ttf, oneyear, 0, 0, QIOSEventDispatcher::nonBlockingTimerRunLoopCallback, &info);
Q_ASSERT(m_runLoopTimerRef != 0);
- CFRunLoopAddTimer(CFRunLoopGetMain(), m_runLoopTimerRef, kCFRunLoopCommonModes);
+ CFRunLoopRef mainRunLoop = CFRunLoopGetMain();
+ CFRunLoopAddTimer(mainRunLoop, m_runLoopTimerRef, kCFRunLoopCommonModes);
+ CFRunLoopAddTimer(mainRunLoop, m_runLoopTimerRef, (CFStringRef) UITrackingRunLoopMode);
} else {
struct timespec tv;
// Calculate when the next timer should fire:
@@ -168,6 +169,7 @@ QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent)
m_blockingTimerRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
Q_ASSERT(m_blockingTimerRunLoopSource);
CFRunLoopAddSource(mainRunLoop, m_blockingTimerRunLoopSource, kCFRunLoopCommonModes);
+ CFRunLoopAddSource(mainRunLoop, m_blockingTimerRunLoopSource, (CFStringRef) UITrackingRunLoopMode);
// source used to handle posted events:
context.perform = QIOSEventDispatcher::postedEventsRunLoopCallback;
@@ -184,7 +186,9 @@ QIOSEventDispatcher::~QIOSEventDispatcher()
qDeleteAll(m_timerInfoList);
maybeStopCFRunLoopTimer();
- CFRunLoopRemoveSource(CFRunLoopGetMain(), m_blockingTimerRunLoopSource, kCFRunLoopCommonModes);
+
+ CFRunLoopRemoveSource(mainRunLoop, m_blockingTimerRunLoopSource, kCFRunLoopCommonModes);
+ CFRunLoopRemoveSource(mainRunLoop, m_blockingTimerRunLoopSource, (CFStringRef) UITrackingRunLoopMode);
CFRelease(m_blockingTimerRunLoopSource);
m_cfSocketNotifier.removeSocketNotifiers();
@@ -199,14 +203,42 @@ bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec);
bool useExecMode = execFlagSet && !excludeUserEvents;
+ CFTimeInterval distantFuture = CFTimeInterval(3600. * 24. * 365. * 10.);
+ SInt32 result;
+
if (useExecMode) {
- NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
- while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted);
+ while (!m_interrupted) {
+ // Run a single pass on the runloop to unblock it
+ result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true);
+
+ // Run the default runloop until interrupted (by Qt or UIKit)
+ if (result != kCFRunLoopRunFinished)
+ result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, distantFuture, false);
+
+ // App has quit or Qt has interrupted?
+ if (result == kCFRunLoopRunFinished || m_interrupted)
+ break;
+
+ // Runloop was interrupted by UIKit?
+ if (result == kCFRunLoopRunStopped && !m_interrupted) {
+ // Run runloop in UI tracking mode
+ if (CFRunLoopRunInMode((CFStringRef) UITrackingRunLoopMode,
+ distantFuture, false) == kCFRunLoopRunFinished)
+ break;
+ }
+ }
eventsProcessed = true;
} else {
if (!(flags & QEventLoop::WaitForMoreEvents))
wakeUp();
- eventsProcessed = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
+
+ // Run runloop in default mode
+ result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, distantFuture, true);
+ if (result != kCFRunLoopRunFinished) {
+ // Run runloop in UI tracking mode
+ CFRunLoopRunInMode((CFStringRef) UITrackingRunLoopMode, distantFuture, false);
+ }
+ eventsProcessed = (result == kCFRunLoopRunHandledSource);
}
return eventsProcessed;
}
@@ -309,8 +341,9 @@ void QIOSEventDispatcher::wakeUp()
void QIOSEventDispatcher::interrupt()
{
- wakeUp();
+ // Stop the runloop, which will cause processEvents() to exit
m_interrupted = true;
+ CFRunLoopStop(CFRunLoopGetMain());
}
void QIOSEventDispatcher::flush()
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/platformsupport/eventdispatchers/qioseventdispatcher_p.h
index 53a75618ce..53a75618ce 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.h
+++ b/src/platformsupport/eventdispatchers/qioseventdispatcher_p.h
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index afe634dc4b..6b8a82352d 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -317,8 +317,6 @@ static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
return stylehint;
}
-Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
-
void QFontconfigDatabase::populateFontDatabase()
{
FcFontSet *fonts;
@@ -453,7 +451,7 @@ void QFontconfigDatabase::populateFontDatabase()
// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
for (int k = 1; FcPatternGetString(fonts->fonts[i], FC_FAMILY, k, &value) == FcResultMatch; ++k)
- qt_registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
+ QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
}
FcFontSetDestroy (fonts);
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 1e15a9e62c..5139f11d23 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -176,6 +176,10 @@ QCoreTextFontDatabase::~QCoreTextFontDatabase()
void QCoreTextFontDatabase::populateFontDatabase()
{
+ // The caller (QFontDB) expects the db to be populate only with system fonts, so we need
+ // to make sure that any previously registered app fonts become invisible.
+ removeApplicationFonts();
+
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0);
@@ -186,82 +190,87 @@ void QCoreTextFontDatabase::populateFontDatabase()
if (! fonts)
return;
- QString foundryName = QLatin1String("CoreText");
const int numFonts = CFArrayGetCount(fonts);
for (int i = 0; i < numFonts; ++i) {
CTFontDescriptorRef font = (CTFontDescriptorRef) CFArrayGetValueAtIndex(fonts, i);
- QCFString familyName = (CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontFamilyNameAttribute, NULL);
- QCFString styleName = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(font, kCTFontStyleNameAttribute, NULL);
- QCFType<CFDictionaryRef> styles = (CFDictionaryRef) CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute);
- QFont::Weight weight = QFont::Normal;
- QFont::Style style = QFont::StyleNormal;
- QFont::Stretch stretch = QFont::Unstretched;
- bool fixedPitch = false;
-
- if (styles) {
- if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
- Q_ASSERT(CFNumberIsFloatType(weightValue));
- double d;
- if (CFNumberGetValue(weightValue, kCFNumberDoubleType, &d))
- weight = (d > 0.0) ? QFont::Bold : QFont::Normal;
- }
- if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
- Q_ASSERT(CFNumberIsFloatType(italic));
- double d;
- if (CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
- if (d > 0.0)
- style = QFont::StyleItalic;
- }
- }
- if (CFNumberRef symbolic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSymbolicTrait)) {
- int d;
- if (CFNumberGetValue(symbolic, kCFNumberSInt32Type, &d)) {
- if (d & kCTFontMonoSpaceTrait)
- fixedPitch = true;
- if (d & kCTFontExpandedTrait)
- stretch = QFont::Expanded;
- else if (d & kCTFontCondensedTrait)
- stretch = QFont::Condensed;
- }
- }
- }
+ populateFromDescriptor(font);
+ }
- int pixelSize = 0;
- if (QCFType<CFNumberRef> size = (CFNumberRef) CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
- if (CFNumberIsFloatType(size)) {
- double d;
- CFNumberGetValue(size, kCFNumberDoubleType, &d);
- pixelSize = d;
- } else {
- CFNumberGetValue(size, kCFNumberIntType, &pixelSize);
+ [pool release];
+}
+
+void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font)
+{
+ QString foundryName = QStringLiteral("CoreText");
+ QCFString familyName = (CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontFamilyNameAttribute, NULL);
+ QCFString styleName = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(font, kCTFontStyleNameAttribute, NULL);
+ QCFType<CFDictionaryRef> styles = (CFDictionaryRef) CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute);
+ QFont::Weight weight = QFont::Normal;
+ QFont::Style style = QFont::StyleNormal;
+ QFont::Stretch stretch = QFont::Unstretched;
+ bool fixedPitch = false;
+
+ if (styles) {
+ if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
+ Q_ASSERT(CFNumberIsFloatType(weightValue));
+ double d;
+ if (CFNumberGetValue(weightValue, kCFNumberDoubleType, &d))
+ weight = (d > 0.0) ? QFont::Bold : QFont::Normal;
+ }
+ if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
+ Q_ASSERT(CFNumberIsFloatType(italic));
+ double d;
+ if (CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
+ if (d > 0.0)
+ style = QFont::StyleItalic;
}
}
-
- QSupportedWritingSystems writingSystems;
- if (QCFType<CFArrayRef> languages = (CFArrayRef) CTFontDescriptorCopyAttribute(font, kCTFontLanguagesAttribute)) {
- CFIndex length = CFArrayGetCount(languages);
- for (int i = 1; i < LanguageCount; ++i) {
- if (!languageForWritingSystem[i])
- continue;
- QCFString lang = CFStringCreateWithCString(NULL, languageForWritingSystem[i], kCFStringEncodingASCII);
- if (CFArrayContainsValue(languages, CFRangeMake(0, length), lang))
- writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ if (CFNumberRef symbolic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSymbolicTrait)) {
+ int d;
+ if (CFNumberGetValue(symbolic, kCFNumberSInt32Type, &d)) {
+ if (d & kCTFontMonoSpaceTrait)
+ fixedPitch = true;
+ if (d & kCTFontExpandedTrait)
+ stretch = QFont::Expanded;
+ else if (d & kCTFontCondensedTrait)
+ stretch = QFont::Condensed;
}
}
+ }
- CFRetain(font);
- QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight, style, stretch,
- true /* antialiased */, true /* scalable */,
- pixelSize, fixedPitch, writingSystems, (void *) font);
+ int pixelSize = 0;
+ if (QCFType<CFNumberRef> size = (CFNumberRef) CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
+ if (CFNumberIsFloatType(size)) {
+ double d;
+ CFNumberGetValue(size, kCFNumberDoubleType, &d);
+ pixelSize = d;
+ } else {
+ CFNumberGetValue(size, kCFNumberIntType, &pixelSize);
+ }
+ }
- // We need to map back and forth between PostScript-names and family-names for fallback list construction
- CFStringRef psName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontNameAttribute);
- psNameToFamily[QCFString::toQString((NSString *) psName)] = familyName;
- familyNameToPsName[familyName] = QCFString::toQString((NSString *) psName);
- CFRelease(psName);
+ QSupportedWritingSystems writingSystems;
+ if (QCFType<CFArrayRef> languages = (CFArrayRef) CTFontDescriptorCopyAttribute(font, kCTFontLanguagesAttribute)) {
+ CFIndex length = CFArrayGetCount(languages);
+ for (int i = 1; i < LanguageCount; ++i) {
+ if (!languageForWritingSystem[i])
+ continue;
+ QCFString lang = CFStringCreateWithCString(NULL, languageForWritingSystem[i], kCFStringEncodingASCII);
+ if (CFArrayContainsValue(languages, CFRangeMake(0, length), lang))
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ }
}
- [pool release];
+ CFRetain(font);
+ QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight, style, stretch,
+ true /* antialiased */, true /* scalable */,
+ pixelSize, fixedPitch, writingSystems, (void *) font);
+
+ // We need to map back and forth between PostScript-names and family-names for fallback list construction
+ CFStringRef psName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontNameAttribute);
+ psNameToFamily[QCFString::toQString((NSString *) psName)] = familyName;
+ familyNameToPsName[familyName] = QCFString::toQString((NSString *) psName);
+ CFRelease(psName);
}
void QCoreTextFontDatabase::releaseHandle(void *handle)
@@ -473,6 +482,7 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
bool success = CTFontManagerRegisterGraphicsFont(cgFont, &error);
if (success) {
font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
+ m_applicationGraphicsFonts.append(QCFType<CGFontRef>::constructFromGet(cgFont));
} else {
NSLog(@"Unable to register font: %@", error);
CFRelease(error);
@@ -484,12 +494,13 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
QCFType<CFURLRef> fontURL = CFURLCreateWithFileSystemPath(NULL, QCFString(fileName), kCFURLPOSIXPathStyle, false);
bool success = CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error);
if (success) {
- const void *keys[] = { fontURL };
- const void *values[] = { kCTFontURLAttribute };
+ const void *keys[] = { kCTFontURLAttribute };
+ const void *values[] = { fontURL };
QCFType<CFDictionaryRef> attributes = CFDictionaryCreate(NULL, keys, values, 1,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);
font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL);
+ m_applicationURLFonts.append(QCFType<CFURLRef>::constructFromGet(fontURL));
} else {
NSLog(@"Unable to register font: %@", error);
CFRelease(error);
@@ -499,6 +510,10 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
if (font) {
QStringList families;
families.append(QCFString(CTFontCopyFamilyName(font)));
+
+ QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
+ populateFromDescriptor(descriptor);
+
CFRelease(font);
return families;
}
@@ -534,9 +549,12 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
QStringList families;
for (int i = 0; i < containedFonts.size(); ++i) {
QCFType<CTFontRef> font = CTFontCreateWithPlatformFont(containedFonts[i], 12.0, NULL, NULL);
+ QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
+ populateFromDescriptor(descriptor);
families.append(QCFString(CTFontCopyFamilyName(font)));
}
+ m_applicationFonts.append(fontContainer);
return families;
}
#endif
@@ -569,5 +587,28 @@ QList<int> QCoreTextFontDatabase::standardSizes() const
return ret;
}
+void QCoreTextFontDatabase::removeApplicationFonts()
+{
+#ifdef Q_OS_MACX
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ CFErrorRef error;
+ for (int i = 0; i < m_applicationGraphicsFonts.count(); ++i)
+ CTFontManagerUnregisterGraphicsFont(m_applicationGraphicsFonts[i], &error);
+ m_applicationGraphicsFonts.clear();
+
+ for (int i = 0; i < m_applicationURLFonts.count(); ++i)
+ CTFontManagerUnregisterFontsForURL(m_applicationURLFonts[i], kCTFontManagerScopeProcess, &error);
+ m_applicationURLFonts.clear();
+ }
+#else
+ for (int i = 0; i < m_applicationFonts.count(); ++i)
+ ATSFontDeactivate(m_applicationFonts[i], 0, kATSOptionFlagsDoNotNotify);
+ m_applicationFonts.clear();
+ ATSFontNotify(kATSFontNotifyActionFontsChanged, 0);
+#endif
+#endif
+}
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index 8536ad9123..c3bb4d428a 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -43,6 +43,14 @@
#define QCORETEXTFONTDATABASE_H
#include <qpa/qplatformfontdatabase.h>
+#include <private/qcore_mac_p.h>
+
+#ifndef Q_OS_IOS
+#include <ApplicationServices/ApplicationServices.h>
+#else
+#include <CoreText/CoreText.h>
+#include <CoreGraphics/CoreGraphics.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -63,9 +71,21 @@ public:
QList<int> standardSizes() const;
private:
+ void populateFromDescriptor(CTFontDescriptorRef font);
+
mutable QString defaultFontName;
mutable QHash<QString, QString> psNameToFamily;
mutable QHash<QString, QString> familyNameToPsName;
+
+ void removeApplicationFonts();
+#ifdef Q_OS_MACX
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
+ QVector<QCFType<CGFontRef> > m_applicationGraphicsFonts;
+ QVector<QCFType<CFURLRef> > m_applicationURLFonts;
+#else
+ QVector<ATSFontContainerRef> m_applicationFonts;
+#endif
+#endif
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
index fedaa3a655..77ea0f1db8 100644
--- a/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
@@ -54,16 +54,24 @@ enum { debug = 0 };
static inline QByteArray detectDesktopEnvironment()
{
- if (!qEnvironmentVariableIsEmpty("KDE_FULL_SESSION"))
- return QByteArray("KDE");
- // Check Unity first, whose older versions also have "GNOME_DESKTOP_SESSION_ID" set.
const QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP");
- if (xdgCurrentDesktop == "Unity")
- return QByteArrayLiteral("UNITY");
- // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it
- if (qgetenv("DESKTOP_SESSION") == "gnome" || !qEnvironmentVariableIsEmpty("GNOME_DESKTOP_SESSION_ID"))
- return QByteArray("GNOME");
- return QByteArray("UNKNOWN");
+ if (!xdgCurrentDesktop.isEmpty())
+ return xdgCurrentDesktop.toUpper(); // KDE, GNOME, UNITY, LXDE, MATE, XFCE...
+
+ // Classic fallbacks
+ if (!qEnvironmentVariableIsEmpty("KDE_FULL_SESSION"))
+ return QByteArrayLiteral("KDE");
+ if (!qEnvironmentVariableIsEmpty("GNOME_DESKTOP_SESSION_ID"))
+ return QByteArrayLiteral("GNOME");
+
+ // Fallback to checking $DESKTOP_SESSION (unreliable)
+ const QByteArray desktopSession = qgetenv("DESKTOP_SESSION");
+ if (desktopSession == "gnome")
+ return QByteArrayLiteral("GNOME");
+ if (desktopSession == "xfce")
+ return QByteArrayLiteral("XFCE");
+
+ return QByteArrayLiteral("UNKNOWN");
}
static inline bool checkExecutable(const QString &candidate, QString *result)
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
index fdd45a49c5..fb50230382 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -95,9 +95,13 @@ public:
QGenericUnixThemePrivate()
: QPlatformThemePrivate()
, systemFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize)
- { }
+ , fixedFont(QStringLiteral("monospace"), systemFont.pointSize())
+ {
+ fixedFont.setStyleHint(QFont::TypeWriter);
+ }
const QFont systemFont;
+ QFont fixedFont;
};
QGenericUnixTheme::QGenericUnixTheme()
@@ -108,9 +112,14 @@ QGenericUnixTheme::QGenericUnixTheme()
const QFont *QGenericUnixTheme::font(Font type) const
{
Q_D(const QGenericUnixTheme);
- if (type == QPlatformTheme::SystemFont)
+ switch (type) {
+ case QPlatformTheme::SystemFont:
return &d->systemFont;
- return 0;
+ case QPlatformTheme::FixedFont:
+ return &d->fixedFont;
+ default:
+ return 0;
+ }
}
// Helper to return the icon theme paths from XDG.
@@ -240,11 +249,18 @@ void QKdeThemePrivate::refresh()
toolButtonStyle = Qt::ToolButtonTextUnderIcon;
}
- // Read system font, ignore 'fixed' 'smallestReadableFont'
- if (QFont *systemFont = readKdeFontSetting(kdeSettings, QStringLiteral("font"))) {
+ // Read system font, ignore 'smallestReadableFont'
+ if (QFont *systemFont = readKdeFontSetting(kdeSettings, QStringLiteral("font")))
resources.fonts[QPlatformTheme::SystemFont] = systemFont;
- } else {
+ else
resources.fonts[QPlatformTheme::SystemFont] = new QFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize);
+
+ if (QFont *fixedFont = readKdeFontSetting(kdeSettings, QStringLiteral("fixed"))) {
+ resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
+ } else {
+ fixedFont = new QFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize);
+ fixedFont->setStyleHint(QFont::TypeWriter);
+ resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
}
}
@@ -461,9 +477,13 @@ class QGnomeThemePrivate : public QPlatformThemePrivate
public:
QGnomeThemePrivate()
: systemFont(QLatin1Literal(defaultSystemFontNameC), defaultSystemFontSize)
- {}
+ , fixedFont(QStringLiteral("monospace"), systemFont.pointSize())
+ {
+ fixedFont.setStyleHint(QFont::TypeWriter);
+ }
const QFont systemFont;
+ QFont fixedFont;
};
QGnomeTheme::QGnomeTheme()
@@ -501,10 +521,14 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
const QFont *QGnomeTheme::font(Font type) const
{
Q_D(const QGnomeTheme);
- if (type == QPlatformTheme::SystemFont)
- return &d->systemFont;
-
- return 0;
+ switch (type) {
+ case QPlatformTheme::SystemFont:
+ return &d->systemFont;
+ case QPlatformTheme::FixedFont:
+ return &d->fixedFont;
+ default:
+ return 0;
+ }
}
/*!
@@ -534,7 +558,11 @@ QStringList QGenericUnixTheme::themeNames()
#ifndef QT_NO_SETTINGS
result.push_back(QLatin1String(QKdeTheme::name));
#endif
- } else { // Gnome, Unity, other Gtk-based desktops like XFCE.
+ } else if (desktopEnvironment == QByteArrayLiteral("GNOME") ||
+ desktopEnvironment == QByteArrayLiteral("UNITY") ||
+ desktopEnvironment == QByteArrayLiteral("MATE") ||
+ desktopEnvironment == QByteArrayLiteral("XFCE") ||
+ desktopEnvironment == QByteArrayLiteral("LXDE")) { // Gtk-based desktops
// 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
diff --git a/src/plugins/bearer/blackberry/qbbengine.cpp b/src/plugins/bearer/blackberry/qbbengine.cpp
index ab1ba9aa19..37093a09ec 100644
--- a/src/plugins/bearer/blackberry/qbbengine.cpp
+++ b/src/plugins/bearer/blackberry/qbbengine.cpp
@@ -98,10 +98,9 @@ interfaceType(netstatus_interface_type_t type)
return QNetworkConfiguration::BearerBluetooth;
case NETSTATUS_INTERFACE_TYPE_CELLULAR:
- //### TODO not sure which BearerType would be the best
- //to return here. We need to be able to get more
- //information on the bearer type in order to return
- //the exact match.
+ // 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:
diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp
index 75cb617ca8..b31e74bb52 100644
--- a/src/plugins/platforms/android/src/androidjniinput.cpp
+++ b/src/plugins/platforms/android/src/androidjniinput.cpp
@@ -411,6 +411,24 @@ namespace QtAndroidInput
case 0x00000018:
return Qt::Key_VolumeUp;
+ case 0x000000b7: // KEYCODE_PROG_RED
+ return Qt::Key_Red;
+
+ case 0x000000b8: // KEYCODE_PROG_GREEN
+ return Qt::Key_Green;
+
+ case 0x000000b9: // KEYCODE_PROG_YELLOW
+ return Qt::Key_Yellow;
+
+ case 0x000000ba: // KEYCODE_PROG_BLUE
+ return Qt::Key_Blue;
+
+ case 0x000000a6: // KEYCODE_CHANNEL_UP
+ return Qt::Key_ChannelUp;
+
+ case 0x000000a7: // KEYCODE_CHANNEL_DOWN
+ return Qt::Key_ChannelDown;
+
case 0x00000000: // KEYCODE_UNKNOWN
case 0x00000011: // KEYCODE_STAR ?!?!?
case 0x00000012: // KEYCODE_POUND ?!?!?
diff --git a/src/plugins/platforms/android/src/androidplatformplugin.cpp b/src/plugins/platforms/android/src/androidplatformplugin.cpp
index 71c5096e16..79e23c2d32 100644
--- a/src/plugins/platforms/android/src/androidplatformplugin.cpp
+++ b/src/plugins/platforms/android/src/androidplatformplugin.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QAndroidPlatformIntegrationPlugin: public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "android.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "android.json")
public:
QPlatformIntegration *create(const QString &key, const QStringList &paramList);
};
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
index 91ad2b368f..5ef0998a49 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
@@ -66,6 +66,7 @@
#endif
#include "qandroidplatformtheme.h"
+#include "qandroidsystemlocale.h"
QT_BEGIN_NAMESPACE
@@ -108,6 +109,8 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
m_androidFDB = new QAndroidPlatformFontDatabase();
m_androidPlatformServices = new QAndroidPlatformServices();
m_androidPlatformClipboard = new QAndroidPlatformClipboard();
+
+ m_androidSystemLocale = new QAndroidSystemLocale;
}
bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
@@ -115,6 +118,7 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
switch (cap) {
case ThreadedPixmaps: return true;
case NonFullScreenWindows: return false;
+ case NativeWidgets: return false;
default:
#ifndef ANDROID_PLUGIN_OPENGL
return QPlatformIntegration::hasCapability(cap);
@@ -183,6 +187,7 @@ QAndroidPlatformIntegration::~QAndroidPlatformIntegration()
{
delete m_androidPlatformNativeInterface;
delete m_androidFDB;
+ delete m_androidSystemLocale;
QtAndroid::setAndroidPlatformIntegration(NULL);
}
QPlatformFontDatabase *QAndroidPlatformIntegration::fontDatabase() const
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h
index 6cc191701d..346d0c0953 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h
@@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE
class QDesktopWidget;
class QAndroidPlatformServices;
+class QAndroidSystemLocale;
#ifdef ANDROID_PLUGIN_OPENGL
class QAndroidOpenGLPlatformWindow;
@@ -154,6 +155,7 @@ private:
QAndroidPlatformNativeInterface *m_androidPlatformNativeInterface;
QAndroidPlatformServices *m_androidPlatformServices;
QPlatformClipboard *m_androidPlatformClipboard;
+ QAndroidSystemLocale *m_androidSystemLocale;
mutable QAndroidInputContext m_platformInputContext;
};
diff --git a/src/plugins/platforms/android/src/qandroidsystemlocale.cpp b/src/plugins/platforms/android/src/qandroidsystemlocale.cpp
new file mode 100644
index 0000000000..24ae503335
--- /dev/null
+++ b/src/plugins/platforms/android/src/qandroidsystemlocale.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidsystemlocale.h"
+#include "androidjnimain.h"
+#include "private/qjniobject_p.h"
+#include "private/qjnihelpers_p.h"
+#include "qdatetime.h"
+#include "qstringlist.h"
+#include "qvariant.h"
+
+QT_BEGIN_NAMESPACE
+
+QAndroidSystemLocale::QAndroidSystemLocale() : m_locale(QLocale::C)
+{
+}
+
+void QAndroidSystemLocale::getLocaleFromJava() const
+{
+ QWriteLocker locker(&m_lock);
+
+ QJNILocalRef<jobject> javaLocaleRef;
+ QJNIObject javaActivity(QtAndroid::activity());
+ if (javaActivity.isValid()) {
+ QJNIObject resources(javaActivity.callObjectMethod<jobject>("getResources", "()Landroid/content/res/Resources;").object());
+ QJNIObject configuration(resources.callObjectMethod<jobject>("getConfiguration", "()Landroid/content/res/Configuration;").object());
+
+ javaLocaleRef = configuration.getObjectField<jobject>("locale", "Ljava/util/Locale;");
+ } else {
+ javaLocaleRef = QJNIObject::callStaticObjectMethod<jobject>("java/util/Locale", "getDefault", "()Ljava/util/Locale;");
+ }
+
+ QJNIObject javaLocaleObject(javaLocaleRef.object());
+ QString languageCode = qt_convertJString(javaLocaleObject.callObjectMethod<jstring>("getLanguage", "()Ljava/lang/String;").object());
+ QString countryCode = qt_convertJString(javaLocaleObject.callObjectMethod<jstring>("getCountry", "()Ljava/lang/String;").object());
+
+ m_locale = QLocale(languageCode + QLatin1Char('_') + countryCode);
+}
+
+QVariant QAndroidSystemLocale::query(QueryType type, QVariant in) const
+{
+ if (type == LocaleChanged) {
+ getLocaleFromJava();
+ return QVariant();
+ }
+
+ QReadLocker locker(&m_lock);
+
+ switch (type) {
+ case DecimalPoint:
+ return m_locale.decimalPoint();
+ case GroupSeparator:
+ return m_locale.groupSeparator();
+ case ZeroDigit:
+ return m_locale.zeroDigit();
+ case NegativeSign:
+ return m_locale.negativeSign();
+ case DateFormatLong:
+ return m_locale.dateFormat(QLocale::LongFormat);
+ case DateFormatShort:
+ return m_locale.dateFormat(QLocale::ShortFormat);
+ case TimeFormatLong:
+ return m_locale.timeFormat(QLocale::LongFormat);
+ case TimeFormatShort:
+ return m_locale.timeFormat(QLocale::ShortFormat);
+ case DayNameLong:
+ return m_locale.dayName(in.toInt(), QLocale::LongFormat);
+ case DayNameShort:
+ return m_locale.dayName(in.toInt(), QLocale::ShortFormat);
+ case MonthNameLong:
+ return m_locale.monthName(in.toInt(), QLocale::LongFormat);
+ case MonthNameShort:
+ return m_locale.monthName(in.toInt(), QLocale::ShortFormat);
+ case StandaloneMonthNameLong:
+ return m_locale.standaloneMonthName(in.toInt(), QLocale::LongFormat);
+ case StandaloneMonthNameShort:
+ return m_locale.standaloneMonthName(in.toInt(), QLocale::ShortFormat);
+ case DateToStringLong:
+ return m_locale.toString(in.toDate(), QLocale::LongFormat);
+ case DateToStringShort:
+ return m_locale.toString(in.toDate(), QLocale::ShortFormat);
+ case TimeToStringLong:
+ return m_locale.toString(in.toTime(), QLocale::LongFormat);
+ case TimeToStringShort:
+ return m_locale.toString(in.toTime(), QLocale::ShortFormat);
+ case DateTimeFormatLong:
+ return m_locale.dateTimeFormat(QLocale::LongFormat);
+ case DateTimeFormatShort:
+ return m_locale.dateTimeFormat(QLocale::ShortFormat);
+ case DateTimeToStringLong:
+ return m_locale.toString(in.toDateTime(), QLocale::LongFormat);
+ case DateTimeToStringShort:
+ return m_locale.toString(in.toDateTime(), QLocale::ShortFormat);
+ case PositiveSign:
+ return m_locale.positiveSign();
+ case AMText:
+ return m_locale.amText();
+ case PMText:
+ return m_locale.pmText();
+ case FirstDayOfWeek:
+ return m_locale.firstDayOfWeek();
+ case CurrencySymbol:
+ return m_locale .currencySymbol(QLocale::CurrencySymbolFormat(in.toUInt()));
+ case CurrencyToString: {
+ switch (in.type()) {
+ case QVariant::Int:
+ return m_locale .toCurrencyString(in.toInt());
+ case QVariant::UInt:
+ return m_locale .toCurrencyString(in.toUInt());
+ case QVariant::Double:
+ return m_locale .toCurrencyString(in.toDouble());
+ case QVariant::LongLong:
+ return m_locale .toCurrencyString(in.toLongLong());
+ case QVariant::ULongLong:
+ return m_locale .toCurrencyString(in.toULongLong());
+ default:
+ break;
+ }
+ return QString();
+ }
+ case StringToStandardQuotation:
+ return m_locale.quoteString(in.value<QStringRef>());
+ case StringToAlternateQuotation:
+ return m_locale.quoteString(in.value<QStringRef>(), QLocale::AlternateQuotation);
+ case ListToSeparatedString:
+ return m_locale.createSeparatedList(in.value<QStringList>());
+ case LocaleChanged:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This can't happen.");
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+QLocale QAndroidSystemLocale::fallbackUiLocale() const
+{
+ QReadLocker locker(&m_lock);
+ return m_locale;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsudevdrmhandler.h b/src/plugins/platforms/android/src/qandroidsystemlocale.h
index 4ceecb11a8..fc2f6fad98 100644
--- a/src/plugins/platforms/kms/qkmsudevdrmhandler.h
+++ b/src/plugins/platforms/android/src/qandroidsystemlocale.h
@@ -39,28 +39,29 @@
**
****************************************************************************/
-#ifndef QKMSUDEVDRMHANDLER_H
-#define QKMSUDEVDRMHANDLER_H
+#ifndef QANDROIDSYSTEMLOCALE_H
+#define QANDROIDSYSTEMLOCALE_H
-#include <QObject>
-
-#include <qkmsudevhandler.h>
+#include "private/qlocale_p.h"
+#include <QtCore/qreadwritelock.h>
QT_BEGIN_NAMESPACE
-class QKmsIntegration;
-
-class QKmsUdevDRMHandler : public QKmsUdevHandler
+class QAndroidSystemLocale : public QSystemLocale
{
public:
- QKmsUdevDRMHandler(QKmsIntegration *integration);
+ QAndroidSystemLocale();
- QObject *create(struct udev_device *device);
+ virtual QVariant query(QueryType type, QVariant in) const;
+ virtual QLocale fallbackUiLocale() const;
private:
- QKmsIntegration *m_integration;
+ void getLocaleFromJava() const;
+
+ mutable QLocale m_locale;
+ mutable QReadWriteLock m_lock;
};
QT_END_NAMESPACE
-#endif // QKMSUDEVDRMHANDLER_H
+#endif // QANDROIDSYSTEMLOCALE_H
diff --git a/src/plugins/platforms/android/src/src.pri b/src/plugins/platforms/android/src/src.pri
index 76539b50ab..0fd9ace1fc 100644
--- a/src/plugins/platforms/android/src/src.pri
+++ b/src/plugins/platforms/android/src/src.pri
@@ -23,7 +23,8 @@ SOURCES += $$PWD/androidplatformplugin.cpp \
$$PWD/qandroidplatformtheme.cpp \
$$PWD/qandroidplatformmenubar.cpp \
$$PWD/qandroidplatformmenu.cpp \
- $$PWD/qandroidplatformmenuitem.cpp
+ $$PWD/qandroidplatformmenuitem.cpp \
+ $$PWD/qandroidsystemlocale.cpp
HEADERS += $$PWD/qandroidplatformintegration.h \
@@ -39,7 +40,8 @@ HEADERS += $$PWD/qandroidplatformintegration.h \
$$PWD/qandroidplatformtheme.h \
$$PWD/qandroidplatformmenubar.h \
$$PWD/qandroidplatformmenu.h \
- $$PWD/qandroidplatformmenuitem.h
+ $$PWD/qandroidplatformmenuitem.h \
+ $$PWD/qandroidsystemlocale.h
#Non-standard install directory, QTBUG-29859
diff --git a/src/plugins/platforms/cocoa/main.mm b/src/plugins/platforms/cocoa/main.mm
index 6adcb27817..b730514b12 100644
--- a/src/plugins/platforms/cocoa/main.mm
+++ b/src/plugins/platforms/cocoa/main.mm
@@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE
class QCocoaIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "cocoa.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "cocoa.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.h b/src/plugins/platforms/cocoa/qcocoaapplication.h
index 2376b35501..ffb12ea846 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.h
@@ -89,8 +89,10 @@
Cocoa Application Categories
*/
#include "qglobal.h"
+#include "private/qcore_mac_p.h"
#import <AppKit/AppKit.h>
+
@class QT_MANGLE_NAMESPACE(QCocoaMenuLoader);
@interface NSApplication (QT_MANGLE_NAMESPACE(QApplicationIntegration))
@@ -106,6 +108,8 @@
}
@end
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSApplication);
+
QT_BEGIN_NAMESPACE
void qt_redirectNSApplicationSendEvent();
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm
index d962ef8f75..c293f4cd52 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm
@@ -87,12 +87,12 @@ QT_USE_NAMESPACE
- (void)QT_MANGLE_NAMESPACE(qt_setDockMenu):(NSMenu *)newMenu
{
- [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] setDockMenu:newMenu];
+ [[QCocoaApplicationDelegate sharedDelegate] setDockMenu:newMenu];
}
- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)
{
- return [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] menuLoader];
+ return [[QCocoaApplicationDelegate sharedDelegate] menuLoader];
}
- (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel
@@ -155,7 +155,7 @@ static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSE
@end
-@implementation QT_MANGLE_NAMESPACE(QNSApplication)
+@implementation QNSApplication
- (void)qt_sendEvent_original:(NSEvent *)event
{
@@ -189,7 +189,7 @@ QT_BEGIN_NAMESPACE
void qt_redirectNSApplicationSendEvent()
{
- if ([NSApp isMemberOfClass:[QT_MANGLE_NAMESPACE(QNSApplication) class]]) {
+ if ([NSApp isMemberOfClass:[QNSApplication class]]) {
// No need to change implementation since Qt
// already controls a subclass of NSApplication
return;
@@ -202,7 +202,7 @@ void qt_redirectNSApplicationSendEvent()
qt_cocoa_change_implementation(
[NSApplication class],
@selector(sendEvent:),
- [QT_MANGLE_NAMESPACE(QNSApplication) class],
+ [QNSApplication class],
@selector(qt_sendEvent_replacement:),
@selector(qt_sendEvent_original:));
}
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
index e44b2d1b6d..7f6c4224df 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
@@ -90,6 +90,7 @@
#import <Cocoa/Cocoa.h>
#include <qglobal.h>
+#include <private/qcore_mac_p.h>
@class QT_MANGLE_NAMESPACE(QCocoaMenuLoader);
@@ -108,3 +109,5 @@
- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
- (void) removeAppleEventHandlers;
@end
+
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaApplicationDelegate);
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 3ec6ad7a20..423d552627 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -88,14 +88,14 @@
QT_USE_NAMESPACE
-static QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *sharedCocoaApplicationDelegate = nil;
+static QCocoaApplicationDelegate *sharedCocoaApplicationDelegate = nil;
static void cleanupCocoaApplicationDelegate()
{
[sharedCocoaApplicationDelegate release];
}
-@implementation QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)
+@implementation QCocoaApplicationDelegate
- (id)init
{
@@ -144,7 +144,7 @@ static void cleanupCocoaApplicationDelegate()
return nil;
}
-+ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate
++ (QCocoaApplicationDelegate *)sharedDelegate
{
@synchronized(self) {
if (sharedCocoaApplicationDelegate == nil)
@@ -166,14 +166,14 @@ static void cleanupCocoaApplicationDelegate()
return [[dockMenu retain] autorelease];
}
-- (void)setMenuLoader:(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader
+- (void)setMenuLoader:(QCocoaMenuLoader *)menuLoader
{
[menuLoader retain];
[qtMenuLoader release];
qtMenuLoader = menuLoader;
}
-- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader
+- (QCocoaMenuLoader *)menuLoader
{
return [[qtMenuLoader retain] autorelease];
}
@@ -183,7 +183,7 @@ static void cleanupCocoaApplicationDelegate()
[[NSApp mainMenu] cancelTracking];
bool handle_quit = true;
- NSMenuItem *quitMenuItem = [[[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] menuLoader] quitMenuItem];
+ NSMenuItem *quitMenuItem = [[[QCocoaApplicationDelegate sharedDelegate] menuLoader] quitMenuItem];
if (!QGuiApplicationPrivate::instance()->modalWindowList.isEmpty()
&& [quitMenuItem isEnabled]) {
int visible = 0;
diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
index 3379a26650..d90d77ec1d 100644
--- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
@@ -87,7 +87,9 @@ static NSButton *macCreateButton(const char *text, NSView *superview)
- (void)finishOffWithCode:(NSInteger)code;
@end
-@implementation QT_MANGLE_NAMESPACE(QNSColorPanelDelegate)
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
+
+@implementation QNSColorPanelDelegate
- (id)init
{
@@ -308,12 +310,13 @@ static NSButton *macCreateButton(const char *text, NSView *superview)
// close down during the cleanup.
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
[NSApp runModalForWindow:mColorPanel];
+ mDialogIsExecuting = false;
return (mResultCode == NSOKButton);
}
-- (QT_PREPEND_NAMESPACE(QPlatformDialogHelper::DialogCode))dialogResultCode
+- (QPlatformDialogHelper::DialogCode)dialogResultCode
{
- return (mResultCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Accepted) : QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Rejected);
+ return (mResultCode == NSOKButton) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
}
- (BOOL)windowShouldClose:(id)window
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h
index 701e8e2dbf..8a8b1d946c 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h
@@ -62,10 +62,10 @@ public:
bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
void hide();
- void setDirectory(const QString &directory);
- QString directory() const;
- void selectFile(const QString &filename);
- QStringList selectedFiles() 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;
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 76cd235514..b3bc4a8ebf 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -139,7 +139,9 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
@end
-@implementation QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate)
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
+
+@implementation QNSOpenSavePanelDelegate
- (id)initWithAcceptMode:
(const QString &)selectFile
@@ -148,7 +150,7 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
{
self = [super init];
mOptions = options;
- if (mOptions->acceptMode() == QT_PREPEND_NAMESPACE(QFileDialogOptions::AcceptOpen)){
+ if (mOptions->acceptMode() == QFileDialogOptions::AcceptOpen){
mOpenPanel = [NSOpenPanel openPanel];
mSavePanel = mOpenPanel;
} else {
@@ -234,7 +236,7 @@ static QString strippedText(QString s)
- (void)closePanel
{
- *mCurrentSelection = QT_PREPEND_NAMESPACE(QCFString::toQString)([[mSavePanel URL] path]).normalized(QString::NormalizationForm_C);
+ *mCurrentSelection = QCFString::toQString([[mSavePanel URL] path]).normalized(QString::NormalizationForm_C);
if ([mSavePanel respondsToSelector:@selector(close)])
[mSavePanel close];
if ([mSavePanel isSheet])
@@ -245,7 +247,7 @@ static QString strippedText(QString s)
{
if (mOpenPanel){
QFileInfo info(*mCurrentSelection);
- NSString *filepath = QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath());
+ NSString *filepath = QCFString::toNSString(info.filePath());
bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave)
|| [self panel:nil shouldShowFilename:filepath];
@@ -264,12 +266,12 @@ static QString strippedText(QString s)
- (BOOL)runApplicationModalPanel
{
QFileInfo info(*mCurrentSelection);
- NSString *filepath = QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath());
+ NSString *filepath = QCFString::toNSString(info.filePath());
bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave)
|| [self panel:nil shouldShowFilename:filepath];
[mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]];
- [mSavePanel setNameFieldStringValue:selectable ? QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()) : @""];
+ [mSavePanel setNameFieldStringValue:selectable ? QCFString::toNSString(info.fileName()) : @""];
// Call processEvents in case the event dispatcher has been interrupted, and needs to do
// cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
@@ -281,22 +283,22 @@ static QString strippedText(QString s)
return (mReturnCode == NSOKButton);
}
-- (QT_PREPEND_NAMESPACE(QPlatformDialogHelper::DialogCode))dialogResultCode
+- (QPlatformDialogHelper::DialogCode)dialogResultCode
{
- return (mReturnCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Accepted) : QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Rejected);
+ return (mReturnCode == NSOKButton) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
}
- (void)showWindowModalSheet:(QWindow *)parent
{
QFileInfo info(*mCurrentSelection);
- NSString *filepath = QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath());
+ NSString *filepath = QCFString::toNSString(info.filePath());
bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave)
|| [self panel:nil shouldShowFilename:filepath];
[self updateProperties];
[mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]];
- [mSavePanel setNameFieldStringValue:selectable ? QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()) : @""];
+ [mSavePanel setNameFieldStringValue:selectable ? QCFString::toNSString(info.fileName()) : @""];
NSWindow *nsparent = static_cast<NSWindow *>(qGuiApp->platformNativeInterface()->nativeResourceForWindow("nswindow", parent));
[mSavePanel beginSheetModalForWindow:nsparent completionHandler:^(NSInteger result){
@@ -322,8 +324,8 @@ static QString strippedText(QString s)
}
}
- QString qtFileName = QT_PREPEND_NAMESPACE(QCFString::toQString)(filename);
- QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C)));
+ QString qtFileName = QCFString::toQString(filename);
+ QFileInfo info(qtFileName.normalized(QString::NormalizationForm_C));
QString path = info.absolutePath();
if (mCachedEntries->directory() != path) {
mCachedEntries->updateDirCache(path);
@@ -363,7 +365,7 @@ static QString strippedText(QString s)
if (filters.size() > 0){
for (int i=0; i<filters.size(); ++i) {
QString filter = hideDetails ? [self removeExtensions:filters.at(i)] : filters.at(i);
- [mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(QCFString::toNSString)(filter)];
+ [mPopUpButton addItemWithTitle:QCFString::toNSString(filter)];
}
[mPopUpButton selectItemAtIndex:0];
[mSavePanel setAccessoryView:mAccessoryView];
@@ -391,18 +393,20 @@ static QString strippedText(QString s)
return mNameFilterDropDownList->value([mPopUpButton indexOfSelectedItem]);
}
-- (QStringList)selectedFiles
+- (QList<QUrl>)selectedFiles
{
if (mOpenPanel) {
- QStringList result;
+ QList<QUrl> result;
NSArray* array = [mOpenPanel URLs];
- for (NSUInteger i=0; i<[array count]; ++i)
- result << QCFString::toQString([[array objectAtIndex:i] path]).normalized(QString::NormalizationForm_C);
+ for (NSUInteger i=0; i<[array count]; ++i) {
+ QString path = QCFString::toQString([[array objectAtIndex:i] path]).normalized(QString::NormalizationForm_C);
+ result << QUrl::fromLocalFile(path);
+ }
return result;
} else {
- QStringList result;
- QString filename = QT_PREPEND_NAMESPACE(QCFString::toQString)([[mSavePanel URL] path]).normalized(QString::NormalizationForm_C);
- result << filename.remove(QLatin1String("___qt_very_unlikely_prefix_"));
+ QList<QUrl> result;
+ QString filename = QCFString::toQString([[mSavePanel URL] path]).normalized(QString::NormalizationForm_C);
+ result << QUrl::fromLocalFile(filename.remove(QLatin1String("___qt_very_unlikely_prefix_")));
return result;
}
}
@@ -412,18 +416,18 @@ static QString strippedText(QString s)
// Call this functions if mFileMode, mFileOptions,
// mNameFilterDropDownList or mQDirFilter changes.
// The savepanel does not contain the neccessary functions for this.
- const QT_PREPEND_NAMESPACE(QFileDialogOptions::FileMode) fileMode = mOptions->fileMode();
- bool chooseFilesOnly = fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::ExistingFile)
- || fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::ExistingFiles);
- bool chooseDirsOnly = fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::Directory)
- || fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::DirectoryOnly)
- || mOptions->testOption(QT_PREPEND_NAMESPACE(QFileDialogOptions::ShowDirsOnly));
+ const QFileDialogOptions::FileMode fileMode = mOptions->fileMode();
+ bool chooseFilesOnly = fileMode == QFileDialogOptions::ExistingFile
+ || fileMode == QFileDialogOptions::ExistingFiles;
+ bool chooseDirsOnly = fileMode == QFileDialogOptions::Directory
+ || fileMode == QFileDialogOptions::DirectoryOnly
+ || mOptions->testOption(QFileDialogOptions::ShowDirsOnly);
[mOpenPanel setCanChooseFiles:!chooseDirsOnly];
[mOpenPanel setCanChooseDirectories:!chooseFilesOnly];
- [mSavePanel setCanCreateDirectories:!(mOptions->testOption(QT_PREPEND_NAMESPACE(QFileDialogOptions::ReadOnly)))];
- [mOpenPanel setAllowsMultipleSelection:(fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::ExistingFiles))];
- [mOpenPanel setResolvesAliases:!(mOptions->testOption(QT_PREPEND_NAMESPACE(QFileDialogOptions::DontResolveSymlinks)))];
+ [mSavePanel setCanCreateDirectories:!(mOptions->testOption(QFileDialogOptions::ReadOnly))];
+ [mOpenPanel setAllowsMultipleSelection:(fileMode == QFileDialogOptions::ExistingFiles)];
+ [mOpenPanel setResolvesAliases:!(mOptions->testOption(QFileDialogOptions::DontResolveSymlinks))];
[mOpenPanel setTitle:QCFString::toNSString(mOptions->windowTitle())];
[mSavePanel setTitle:QCFString::toNSString(mOptions->windowTitle())];
[mPopUpButton setHidden:chooseDirsOnly]; // TODO hide the whole sunken pane instead?
@@ -432,7 +436,7 @@ static QString strippedText(QString s)
const QString defaultSuffix = mOptions->defaultSuffix();
if (!ext.isEmpty() && !defaultSuffix.isEmpty())
ext.prepend(defaultSuffix);
- [mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : QT_PREPEND_NAMESPACE(qt_mac_QStringListToNSMutableArray(ext))];
+ [mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : qt_mac_QStringListToNSMutableArray(ext)];
if ([mSavePanel respondsToSelector:@selector(isVisible)] && [mSavePanel isVisible]) {
if ([mSavePanel respondsToSelector:@selector(validateVisibleColumns)])
@@ -444,7 +448,7 @@ static QString strippedText(QString s)
{
Q_UNUSED(sender);
if (mHelper) {
- QString selection = QT_PREPEND_NAMESPACE(QCFString::toQString([[mSavePanel URL] path]));
+ QString selection = QCFString::toQString([[mSavePanel URL] path]);
if (selection != mCurrentSelection) {
*mCurrentSelection = selection;
mHelper->QNSOpenSavePanelDelegate_selectionChanged(selection);
@@ -462,7 +466,7 @@ static QString strippedText(QString s)
[mCurrentDir release];
mCurrentDir = [path retain];
- mHelper->QNSOpenSavePanelDelegate_directoryEntered(QT_PREPEND_NAMESPACE(QCFString::toQString(mCurrentDir)));
+ mHelper->QNSOpenSavePanelDelegate_directoryEntered(QCFString::toQString(mCurrentDir));
}
/*
@@ -489,7 +493,7 @@ static QString strippedText(QString s)
- (QString)removeExtensions:(const QString &)filter
{
- QRegExp regExp(QT_PREPEND_NAMESPACE(QString::fromLatin1)(QT_PREPEND_NAMESPACE(QPlatformFileDialogHelper::filterRegExp)));
+ QRegExp regExp(QString::fromLatin1(QPlatformFileDialogHelper::filterRegExp));
if (regExp.indexIn(filter) != -1)
return regExp.cap(1).trimmed();
return filter;
@@ -525,7 +529,7 @@ static QString strippedText(QString s)
(filterToUse == -1 && currentFilter.startsWith(selectedFilter)))
filterToUse = i;
QString filter = hideDetails ? [self removeExtensions:currentFilter] : currentFilter;
- [mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(QCFString::toNSString)(filter)];
+ [mPopUpButton addItemWithTitle:QCFString::toNSString(filter)];
}
if (filterToUse != -1)
[mPopUpButton selectItemAtIndex:filterToUse];
@@ -563,13 +567,13 @@ QCocoaFileDialogHelper::~QCocoaFileDialogHelper()
if (!mDelegate)
return;
QCocoaAutoReleasePool pool;
- [reinterpret_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate) release];
+ [reinterpret_cast<QNSOpenSavePanelDelegate *>(mDelegate) release];
mDelegate = 0;
}
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_selectionChanged(const QString &newPath)
{
- emit currentChanged(newPath);
+ emit currentChanged(QUrl::fromLocalFile(newPath));
}
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_panelClosed(bool accepted)
@@ -584,7 +588,7 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_panelClosed(bool accepted)
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_directoryEntered(const QString &newDir)
{
// ### fixme: priv->setLastVisitedDirectory(newDir);
- emit directoryEntered(newDir);
+ emit directoryEntered(QUrl::fromLocalFile(newDir));
}
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_filterSelected(int menuIndex)
@@ -596,43 +600,45 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_filterSelected(int menuInd
extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1); // qglobal.cpp
-void QCocoaFileDialogHelper::setDirectory(const QString &directory)
+void QCocoaFileDialogHelper::setDirectory(const QUrl &directory)
{
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (delegate)
- [delegate->mSavePanel setDirectoryURL:[NSURL fileURLWithPath:QCFString::toNSString(directory)]];
+ [delegate->mSavePanel setDirectoryURL:[NSURL fileURLWithPath:QCFString::toNSString(directory.toLocalFile())]];
}
-QString QCocoaFileDialogHelper::directory() const
+QUrl QCocoaFileDialogHelper::directory() const
{
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
- if (delegate)
- return QCFString::toQString([[delegate->mSavePanel directoryURL] path]).normalized(QString::NormalizationForm_C);
- return QString();
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+ if (delegate) {
+ QString path = QCFString::toQString([[delegate->mSavePanel directoryURL] path]).normalized(QString::NormalizationForm_C);
+ return QUrl::fromLocalFile(path);
+ }
+ return QUrl();
}
-void QCocoaFileDialogHelper::selectFile(const QString &filename)
+void QCocoaFileDialogHelper::selectFile(const QUrl &filename)
{
- QString filePath = filename;
+ QString filePath = filename.toLocalFile();
if (QDir::isRelativePath(filePath))
- filePath = QFileInfo(directory(), filePath).filePath();
+ filePath = QFileInfo(directory().toLocalFile(), filePath).filePath();
// There seems to no way to select a file once the dialog is running.
// So do the next best thing, set the file's directory:
setDirectory(QFileInfo(filePath).absolutePath());
}
-QStringList QCocoaFileDialogHelper::selectedFiles() const
+QList<QUrl> QCocoaFileDialogHelper::selectedFiles() const
{
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (delegate)
return [delegate selectedFiles];
- return QStringList();
+ return QList<QUrl>();
}
void QCocoaFileDialogHelper::setFilter()
{
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (!delegate)
return;
const SharedPointerFileDialogOptions &opts = options();
@@ -651,7 +657,7 @@ void QCocoaFileDialogHelper::selectNameFilter(const QString &filter)
return;
const int index = options()->nameFilters().indexOf(filter);
if (index != -1) {
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (!delegate)
return;
[delegate->mPopUpButton selectItemAtIndex:index];
@@ -661,7 +667,7 @@ void QCocoaFileDialogHelper::selectNameFilter(const QString &filter)
QString QCocoaFileDialogHelper::selectedNameFilter() const
{
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (!delegate)
return QString();
int index = [delegate->mPopUpButton indexOfSelectedItem];
@@ -695,11 +701,11 @@ void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate()
return;
QCocoaAutoReleasePool pool;
const SharedPointerFileDialogOptions &opts = options();
- const QStringList selectedFiles = opts->initiallySelectedFiles();
- const QString directory = opts->initialDirectory();
+ const QList<QUrl> selectedFiles = opts->initiallySelectedFiles();
+ const QUrl directory = opts->initialDirectory();
const bool selectDir = selectedFiles.isEmpty();
- QString selection(selectDir ? directory : selectedFiles.front());
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) alloc]
+ QString selection(selectDir ? directory.toLocalFile() : selectedFiles.front().toLocalFile());
+ QNSOpenSavePanelDelegate *delegate = [[QNSOpenSavePanelDelegate alloc]
initWithAcceptMode:
selection
options:opts
@@ -711,7 +717,7 @@ void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate()
bool QCocoaFileDialogHelper::showCocoaFilePanel(Qt::WindowModality windowModality, QWindow *parent)
{
createNSOpenSavePanelDelegate();
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if (!delegate)
return false;
if (windowModality == Qt::NonModal)
@@ -729,7 +735,7 @@ bool QCocoaFileDialogHelper::hideCocoaFilePanel()
// open regarding whether or not to go native:
return false;
} else {
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
[delegate closePanel];
// Even when we hide it, we are still using a
// native dialog, so return true:
@@ -744,7 +750,7 @@ void QCocoaFileDialogHelper::exec()
// yet been reactivated (regardless if [NSApp run] is still on the stack)),
// showing a native modal dialog will fail.
QCocoaAutoReleasePool pool;
- QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
+ QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
if ([delegate runApplicationModalPanel])
emit accept();
else
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h
index c1fef68f42..83aebba6d3 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h
@@ -47,9 +47,6 @@
QT_BEGIN_NAMESPACE
-class QFontDialog;
-class QFontDialogPrivate;
-
class QCocoaFontDialogHelper : public QPlatformFontDialogHelper
{
public:
@@ -63,14 +60,6 @@ public:
void setCurrentFont(const QFont &);
QFont currentFont() const;
-
-protected:
- void createNSFontPanelDelegate();
- bool showCocoaFontPanel(Qt::WindowModality windowModality, QWindow *parent);
- bool hideCocoaFontPanel();
-
-private:
- void *mDelegate;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
index a70ba3749f..91fb52eb6d 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
@@ -128,14 +128,18 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
- (void)finishOffWithCode:(NSInteger)code;
@end
-@implementation QT_MANGLE_NAMESPACE(QNSFontPanelDelegate)
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
-- (id)initWithDialogHelper:
- (QCocoaFontDialogHelper *)helper
+@implementation QNSFontPanelDelegate
+
+- (id)init
{
self = [super init];
mFontPanel = [NSFontPanel sharedFontPanel];
- mHelper = helper;
+ mHelper = 0;
+ mStolenContentView = 0;
+ mOkButton = 0;
+ mCancelButton = 0;
mResultCode = NSCancelButton;
mDialogIsExecuting = false;
mResultSet = false;
@@ -145,13 +149,32 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[mFontPanel setRestorable:NO];
#endif
+ [mFontPanel setDelegate:self];
+ [[NSFontManager sharedFontManager] setDelegate:self];
+
+ [mFontPanel retain];
+ return self;
+}
+
+- (void)dealloc
+{
+ [self restoreOriginalContentView];
+ [mFontPanel setDelegate:nil];
+ [[NSFontManager sharedFontManager] setDelegate:nil];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ [super dealloc];
+}
+
+- (void)setDialogHelper:(QCocoaFontDialogHelper *)helper
+{
+ mHelper = helper;
+
[mFontPanel setTitle:QCFString::toNSString(helper->options()->windowTitle())];
if (mHelper->options()->testOption(QFontDialogOptions::NoButtons)) {
- mStolenContentView = 0;
- mOkButton = 0;
- mCancelButton = 0;
- } else {
+ [self restoreOriginalContentView];
+ } else if (!mStolenContentView) {
// steal the font panel's contents view
mStolenContentView = [mFontPanel contentView];
[mStolenContentView retain];
@@ -176,14 +199,22 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[mCancelButton setAction:@selector(onCancelClicked)];
[mCancelButton setTarget:self];
}
+}
- [mFontPanel retain];
- return self;
+- (void)closePanel
+{
+ [mFontPanel close];
}
-- (void)dealloc
+- (void)windowDidResize:(NSNotification *)notification
{
- if (mOkButton) {
+ Q_UNUSED(notification);
+ [self relayout];
+}
+
+- (void)restoreOriginalContentView
+{
+ if (mStolenContentView) {
NSView *ourContentView = [mFontPanel contentView];
// return stolen stuff to its rightful owner
@@ -192,28 +223,17 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[mOkButton release];
[mCancelButton release];
[ourContentView release];
+ mOkButton = 0;
+ mCancelButton = 0;
+ mStolenContentView = 0;
}
-
- [mFontPanel setDelegate:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self];
-
- [super dealloc];
-}
-
-- (void)closePanel
-{
- [mFontPanel close];
-}
-
-- (void)windowDidResize:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (mOkButton)
- [self relayout];
}
- (void)relayout
{
+ if (!mOkButton)
+ return;
+
[self relayoutToContentSize:[[mStolenContentView superview] frame].size];
}
@@ -289,30 +309,32 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
NSFont *panelFont = [fontManager convertFont:selectedFont];
mQtFont = qfontForCocoaFont(panelFont, mQtFont);
- emit mHelper->currentFontChanged(mQtFont);
+ if (mHelper)
+ emit mHelper->currentFontChanged(mQtFont);
}
- (void)showModelessPanel
{
mDialogIsExecuting = false;
+ mResultSet = false;
[mFontPanel makeKeyAndOrderFront:mFontPanel];
}
- (BOOL)runApplicationModalPanel
{
mDialogIsExecuting = true;
- [mFontPanel setDelegate:self];
// Call processEvents in case the event dispatcher has been interrupted, and needs to do
// cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
// close down during the cleanup.
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
[NSApp runModalForWindow:mFontPanel];
+ mDialogIsExecuting = false;
return (mResultCode == NSOKButton);
}
-- (QT_PREPEND_NAMESPACE(QPlatformDialogHelper::DialogCode))dialogResultCode
+- (QPlatformDialogHelper::DialogCode)dialogResultCode
{
- return (mResultCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Accepted) : QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Rejected);
+ return (mResultCode == NSOKButton) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
}
- (BOOL)windowShouldClose:(id)window
@@ -324,7 +346,8 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[self finishOffWithCode:NSCancelButton];
} else {
mResultSet = true;
- emit mHelper->reject();
+ if (mHelper)
+ emit mHelper->reject();
}
return true;
}
@@ -359,27 +382,101 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
QT_BEGIN_NAMESPACE
-QCocoaFontDialogHelper::QCocoaFontDialogHelper() :
- mDelegate(0)
+class QCocoaFontPanel
+{
+public:
+ QCocoaFontPanel()
+ {
+ mDelegate = [[QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) alloc] init];
+ }
+
+ ~QCocoaFontPanel()
+ {
+ [mDelegate release];
+ }
+
+ void init(QCocoaFontDialogHelper *helper)
+ {
+ [mDelegate setDialogHelper:helper];
+ }
+
+ void cleanup(QCocoaFontDialogHelper *helper)
+ {
+ if (mDelegate->mHelper == helper)
+ mDelegate->mHelper = 0;
+ }
+
+ bool exec()
+ {
+ // Note: If NSApp is not running (which is the case if e.g a top-most
+ // QEventLoop has been interrupted, and the second-most event loop has not
+ // yet been reactivated (regardless if [NSApp run] is still on the stack)),
+ // showing a native modal dialog will fail.
+ return [mDelegate runApplicationModalPanel];
+ }
+
+ bool show(Qt::WindowModality windowModality, QWindow *parent)
+ {
+ Q_UNUSED(parent);
+ if (windowModality != Qt::WindowModal)
+ [mDelegate showModelessPanel];
+ // no need to show a Qt::WindowModal dialog here, because it's necessary to call exec() in that case
+ return true;
+ }
+
+ void hide()
+ {
+ [mDelegate closePanel];
+ }
+
+ QFont currentFont() const
+ {
+ return mDelegate->mQtFont;
+ }
+
+ void setCurrentFont(const QFont &font)
+ {
+ NSFontManager *mgr = [NSFontManager sharedFontManager];
+ const NSFont *nsFont = 0;
+
+ int weight = 5;
+ NSFontTraitMask mask = 0;
+ if (font.style() == QFont::StyleItalic) {
+ mask |= NSItalicFontMask;
+ }
+ if (font.weight() == QFont::Bold) {
+ weight = 9;
+ mask |= NSBoldFontMask;
+ }
+
+ QFontInfo fontInfo(font);
+ nsFont = [mgr fontWithFamily:QCFString::toNSString(fontInfo.family())
+ traits:mask
+ weight:weight
+ size:fontInfo.pointSize()];
+
+ [mgr setSelectedFont:const_cast<NSFont *>(nsFont) isMultiple:NO];
+ mDelegate->mQtFont = font;
+ }
+
+private:
+ QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *mDelegate;
+};
+
+Q_GLOBAL_STATIC(QCocoaFontPanel, sharedFontPanel)
+
+QCocoaFontDialogHelper::QCocoaFontDialogHelper()
{
}
QCocoaFontDialogHelper::~QCocoaFontDialogHelper()
{
- if (!mDelegate)
- return;
- [reinterpret_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate) release];
- mDelegate = 0;
+ sharedFontPanel()->cleanup(this);
}
void QCocoaFontDialogHelper::exec()
{
- // Note: If NSApp is not running (which is the case if e.g a top-most
- // QEventLoop has been interrupted, and the second-most event loop has not
- // yet been reactivated (regardless if [NSApp run] is still on the stack)),
- // showing a native modal dialog will fail.
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
- if ([delegate runApplicationModalPanel])
+ if (sharedFontPanel()->exec())
emit accept();
else
emit reject();
@@ -387,86 +484,26 @@ void QCocoaFontDialogHelper::exec()
bool QCocoaFontDialogHelper::show(Qt::WindowFlags, Qt::WindowModality windowModality, QWindow *parent)
{
- if (windowModality == Qt::WindowModal) {
- // Cocoa's shared font panel cannot be shown as a sheet
- return false;
- }
- return showCocoaFontPanel(windowModality, parent);
+ if (windowModality == Qt::WindowModal)
+ windowModality = Qt::ApplicationModal;
+ sharedFontPanel()->init(this);
+ return sharedFontPanel()->show(windowModality, parent);
}
void QCocoaFontDialogHelper::hide()
{
- if (!mDelegate)
- return;
- [reinterpret_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate)->mFontPanel close];
+ sharedFontPanel()->hide();
}
void QCocoaFontDialogHelper::setCurrentFont(const QFont &font)
{
- NSFontManager *mgr = [NSFontManager sharedFontManager];
- const NSFont *nsFont = 0;
-
- int weight = 5;
- NSFontTraitMask mask = 0;
- if (font.style() == QFont::StyleItalic) {
- mask |= NSItalicFontMask;
- }
- if (font.weight() == QFont::Bold) {
- weight = 9;
- mask |= NSBoldFontMask;
- }
-
- QFontInfo fontInfo(font);
- nsFont = [mgr fontWithFamily:QCFString::toNSString(fontInfo.family())
- traits:mask
- weight:weight
- size:fontInfo.pointSize()];
-
- if (!mDelegate)
- createNSFontPanelDelegate();
-
- [mgr setSelectedFont:const_cast<NSFont *>(nsFont) isMultiple:NO];
- static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate)->mQtFont = font;
+ sharedFontPanel()->init(this);
+ sharedFontPanel()->setCurrentFont(font);
}
QFont QCocoaFontDialogHelper::currentFont() const
{
- if (!mDelegate)
- return QFont();
- return reinterpret_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate)->mQtFont;
-}
-
-void QCocoaFontDialogHelper::createNSFontPanelDelegate()
-{
- if (mDelegate)
- return;
-
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) alloc]
- initWithDialogHelper:this];
-
- mDelegate = delegate;
-}
-
-bool QCocoaFontDialogHelper::showCocoaFontPanel(Qt::WindowModality windowModality, QWindow *parent)
-{
- Q_UNUSED(parent);
- createNSFontPanelDelegate();
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
- if (windowModality == Qt::NonModal)
- [delegate showModelessPanel];
- // no need to show a Qt::ApplicationModal dialog here, since it will be done in _q_platformRunNativeAppModalPanel()
- return true;
-}
-
-bool QCocoaFontDialogHelper::hideCocoaFontPanel()
-{
- if (!mDelegate){
- return false;
- } else {
- QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
- [delegate closePanel];
- return true;
- }
+ return sharedFontPanel()->currentFont();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 3ade0a2a45..3be294de7e 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -508,7 +508,6 @@ CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget)
CGColorSpaceRef colorSpace;
CGDirectDisplayID displayID;
- CMProfileRef displayProfile = 0;
if (widget == 0) {
displayID = CGMainDisplayID();
} else {
@@ -526,18 +525,11 @@ CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget)
if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
return colorSpace;
- CMError err = CMGetProfileByAVID((CMDisplayIDType)displayID, &displayProfile);
- if (err == noErr) {
- colorSpace = CGColorSpaceCreateWithPlatformColorSpace(displayProfile);
- } else if (widget) {
- return qt_mac_displayColorSpace(0); // fall back on main display
- }
-
+ colorSpace = CGDisplayCopyColorSpace(displayID);
if (colorSpace == 0)
colorSpace = CGColorSpaceCreateDeviceRGB();
m_displayColorSpaceHash.insert(displayID, colorSpace);
- CMCloseProfile(displayProfile);
if (!m_postRoutineRegistered) {
m_postRoutineRegistered = true;
void qt_mac_cleanUpMacColorSpaces();
@@ -810,20 +802,7 @@ CGImageRef qt_mac_toCGImage(const QImage &qImage, bool isMask, uchar **dataCopy)
NULL,
false);
} else {
- // Try get a device color space. Using the device color space means
- // that the CGImage can be drawn to screen without per-pixel color
- // space conversion, at the cost of less color accuracy.
- CGColorSpaceRef cgColourSpaceRef = 0;
- CMProfileRef sysProfile;
- if (CMGetSystemProfile(&sysProfile) == noErr)
- {
- cgColourSpaceRef = CGColorSpaceCreateWithPlatformColorSpace(sysProfile);
- CMCloseProfile(sysProfile);
- }
-
- // Fall back to Generic RGB if a profile was not found.
- if (!cgColourSpaceRef)
- cgColourSpaceRef = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ CGColorSpaceRef cgColourSpaceRef = qt_mac_displayColorSpace(0);
// Create a CGBitmapInfo contiaining the image format.
// Support the 8-bit per component (A)RGB formats.
@@ -857,7 +836,6 @@ CGImageRef qt_mac_toCGImage(const QImage &qImage, bool isMask, uchar **dataCopy)
NULL,
false,
kCGRenderingIntentDefault);
- CGColorSpaceRelease(cgColourSpaceRef);
}
CGDataProviderRelease(cgDataProviderRef);
return cgImage;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index fad743439e..6d1882f622 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -232,7 +232,7 @@ QCocoaIntegration::QCocoaIntegration()
qApp->setAttribute(Qt::AA_DontUseNativeMenuBar, false);
- NSApplication *cocoaApplication = [QT_MANGLE_NAMESPACE(QNSApplication) sharedApplication];
+ NSApplication *cocoaApplication = [QNSApplication sharedApplication];
qt_redirectNSApplicationSendEvent();
if (qEnvironmentVariableIsEmpty("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM")) {
@@ -256,12 +256,12 @@ QCocoaIntegration::QCocoaIntegration()
if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
// Set app delegate, link to the current delegate (if any)
- QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
+ QCocoaApplicationDelegate *newDelegate = [QCocoaApplicationDelegate sharedDelegate];
[newDelegate setReflectionDelegate:[cocoaApplication delegate]];
[cocoaApplication setDelegate:newDelegate];
// Load the application menu. This menu contains Preferences, Hide, Quit.
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader = [[QT_MANGLE_NAMESPACE(QCocoaMenuLoader) alloc] init];
+ QCocoaMenuLoader *qtMenuLoader = [[QCocoaMenuLoader alloc] init];
qt_mac_loadMenuNib(qtMenuLoader);
[cocoaApplication setMenu:[qtMenuLoader menu]];
[newDelegate setMenuLoader:qtMenuLoader];
@@ -279,7 +279,7 @@ QCocoaIntegration::~QCocoaIntegration()
QCocoaAutoReleasePool pool;
if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
// remove the apple event handlers installed by QCocoaApplicationDelegate
- QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *delegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
+ QCocoaApplicationDelegate *delegate = [QCocoaApplicationDelegate sharedDelegate];
[delegate removeAppleEventHandlers];
// reset the application delegate
[[NSApplication sharedApplication] setDelegate: 0];
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index f9e033d21b..3ac48df09e 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -74,7 +74,7 @@ NSString *qt_mac_removePrivateUnicode(NSString* string)
return string;
}
-static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
+static inline QCocoaMenuLoader *getMenuLoader()
{
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
}
@@ -87,7 +87,9 @@ static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
@end
-@implementation QT_MANGLE_NAMESPACE(QCocoaMenuDelegate)
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
+
+@implementation QCocoaMenuDelegate
- (id) initWithMenu:(QCocoaMenu*) m
{
@@ -220,11 +222,11 @@ QCocoaMenu::QCocoaMenu() :
m_tag(0),
m_menuBar(0)
{
- m_delegate = [[QT_MANGLE_NAMESPACE(QCocoaMenuDelegate) alloc] initWithMenu:this];
+ m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
m_nativeMenu = [[NSMenu alloc] initWithTitle:@"Untitled"];
[m_nativeMenu setAutoenablesItems:YES];
- m_nativeMenu.delegate = (QT_MANGLE_NAMESPACE(QCocoaMenuDelegate) *) m_delegate;
+ m_nativeMenu.delegate = (QCocoaMenuDelegate *) m_delegate;
[m_nativeItem setSubmenu:m_nativeMenu];
}
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index ddfa9fff96..0fea55ac68 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -52,7 +52,7 @@
static QList<QCocoaMenuBar*> static_menubars;
-static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
+static inline QCocoaMenuLoader *getMenuLoader()
{
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
}
@@ -240,7 +240,7 @@ void QCocoaMenuBar::updateMenuBarImmediately()
}
}
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ QCocoaMenuLoader *loader = getMenuLoader();
[loader ensureAppMenuInMenu:mb->nsMenu()];
NSMutableSet *mergedItems = [[NSMutableSet setWithCapacity:0] retain];
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 6d8174c667..013f9931ff 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -52,7 +52,7 @@
#include <QtCore/QDebug>
-static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
+static inline QCocoaMenuLoader *getMenuLoader()
{
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
}
@@ -199,7 +199,7 @@ NSMenuItem *QCocoaMenuItem::sync()
if ((m_role != NoRole && !m_textSynced) || m_merged) {
NSMenuItem *mergeItem = nil;
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ QCocoaMenuLoader *loader = getMenuLoader();
switch (m_role) {
case ApplicationSpecificRole:
mergeItem = [loader appSpecificMenuItem:reinterpret_cast<NSInteger>(this)];
@@ -326,7 +326,7 @@ QT_END_NAMESPACE
QString QCocoaMenuItem::mergeText()
{
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ QCocoaMenuLoader *loader = getMenuLoader();
if (m_native == [loader aboutMenuItem]) {
return qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName());
} else if (m_native== [loader aboutQtMenuItem]) {
@@ -344,7 +344,7 @@ QString QCocoaMenuItem::mergeText()
QKeySequence QCocoaMenuItem::mergeAccel()
{
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ QCocoaMenuLoader *loader = getMenuLoader();
if (m_native == [loader preferencesMenuItem])
return QKeySequence(QKeySequence::Preferences);
else if (m_native == [loader quitMenuItem])
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.h b/src/plugins/platforms/cocoa/qcocoamenuloader.h
index a45ec0fa89..e07da39995 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.h
@@ -92,9 +92,11 @@
- (NSArray *)mergeable;
@end
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuLoader);
+
QT_BEGIN_NAMESPACE
-void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader);
+void qt_mac_loadMenuNib(QCocoaMenuLoader *qtMenuLoader);
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index 62b722d2d2..29fc0fb674 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -69,7 +69,7 @@ QT_BEGIN_NAMESPACE
and written to QDir::temp() before loading. (Earlier Qt versions used
to require having the nib file in the Qt GUI framework.)
*/
-void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader)
+void qt_mac_loadMenuNib(QCocoaMenuLoader *qtMenuLoader)
{
// Create qt_menu.nib dir in temp.
QDir temp = QDir::temp();
@@ -106,7 +106,7 @@ void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader)
QT_END_NAMESPACE
-@implementation QT_MANGLE_NAMESPACE(QCocoaMenuLoader)
+@implementation QCocoaMenuLoader
- (void)awakeFromNib
{
diff --git a/src/plugins/platforms/cocoa/qcocoaservices.mm b/src/plugins/platforms/cocoa/qcocoaservices.mm
index e4cec8c5f8..de4c688b71 100644
--- a/src/plugins/platforms/cocoa/qcocoaservices.mm
+++ b/src/plugins/platforms/cocoa/qcocoaservices.mm
@@ -55,7 +55,7 @@ bool QCocoaServices::openUrl(const QUrl &url)
const QString scheme = url.scheme();
if (scheme.isEmpty())
return openDocument(url);
- return [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:QT_PREPEND_NAMESPACE(QCFString::toNSString)(url.toString(QUrl::FullyEncoded))]];
+ return [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:QCFString::toNSString(url.toString(QUrl::FullyEncoded))]];
}
bool QCocoaServices::openDocument(const QUrl &url)
@@ -63,7 +63,7 @@ bool QCocoaServices::openDocument(const QUrl &url)
if (!url.isValid())
return false;
- return [[NSWorkspace sharedWorkspace] openFile:QT_PREPEND_NAMESPACE(QCFString::toNSString)(url.toLocalFile())];
+ return [[NSWorkspace sharedWorkspace] openFile:QCFString::toNSString(url.toLocalFile())];
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
index af817bd4c5..194394d11a 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -264,6 +264,10 @@ QHash<QPlatformTheme::Font, QFont *> qt_mac_createRoleFonts()
fonts.insert(QPlatformTheme::SmallFont, qt_mac_qfontForThemeFont(kThemeSmallSystemFont));
fonts.insert(QPlatformTheme::MiniFont, qt_mac_qfontForThemeFont(kThemeMiniSystemFont));
+ QFont* fixedFont = new QFont(QStringLiteral("Monaco"), fonts[QPlatformTheme::SystemFont]->pointSize());
+ fixedFont->setStyleHint(QFont::TypeWriter);
+ fonts.insert(QPlatformTheme::FixedFont, fixedFont);
+
return fonts;
}
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 99f533b33a..83c960d931 100755
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -135,12 +135,16 @@ QT_USE_NAMESPACE
-(id)initWithQMenu:(QPlatformMenu*)qmenu;
@end
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem);
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSImageView);
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSMenu);
+
QT_BEGIN_NAMESPACE
class QSystemTrayIconSys
{
public:
QSystemTrayIconSys(QCocoaSystemTrayIcon *sys) {
- item = [[QT_MANGLE_NAMESPACE(QNSStatusItem) alloc] initWithSysTray:sys];
+ item = [[QNSStatusItem alloc] initWithSysTray:sys];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:item];
@@ -156,7 +160,7 @@ public:
#endif
[item release];
}
- QT_MANGLE_NAMESPACE(QNSStatusItem) *item;
+ QNSStatusItem *item;
};
void QCocoaSystemTrayIcon::init()
@@ -310,8 +314,8 @@ QT_END_NAMESPACE
@implementation NSStatusItem (Qt)
@end
-@implementation QT_MANGLE_NAMESPACE(QNSImageView)
--(id)initWithParent:(QT_MANGLE_NAMESPACE(QNSStatusItem)*)myParent {
+@implementation QNSImageView
+-(id)initWithParent:(QNSStatusItem*)myParent {
self = [super init];
parent = myParent;
down = NO;
@@ -406,7 +410,7 @@ QT_END_NAMESPACE
}
@end
-@implementation QT_MANGLE_NAMESPACE(QNSStatusItem)
+@implementation QNSStatusItem
-(id)initWithSysTray:(QCocoaSystemTrayIcon *)sys
{
@@ -416,7 +420,7 @@ QT_END_NAMESPACE
menu = 0;
menuVisible = false;
systray = sys;
- imageCell = [[QT_MANGLE_NAMESPACE(QNSImageView) alloc] initWithParent:self];
+ imageCell = [[QNSImageView alloc] initWithParent:self];
[item setView: imageCell];
}
return self;
@@ -494,7 +498,7 @@ private:
QSystemTrayIconQMenu();
};
-@implementation QT_MANGLE_NAMESPACE(QNSMenu)
+@implementation QNSMenu
-(id)initWithQMenu:(QPlatformMenu*)qm {
self = [super init];
if (self) {
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index cac059763d..e4237c9b3e 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -68,7 +68,9 @@ public:
const QPalette *palette(Palette type = SystemPalette) const;
const QFont *font(Font type = SystemFont) const;
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const;
- QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const;
+ QPixmap fileIconPixmap(const QFileInfo &fileInfo,
+ const QSizeF &size,
+ QPlatformTheme::IconOptions options = 0) const;
QVariant themeHint(ThemeHint hint) const;
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index 13a387a0a3..1484ae2ba3 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -249,8 +249,10 @@ QPixmap QCocoaTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
return QPlatformTheme::standardPixmap(sp, size);
}
-QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const
+QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions) const
{
+ Q_UNUSED(iconOptions);
QCocoaAutoReleasePool pool;
NSImage *iconImage = [[NSWorkspace sharedWorkspace] iconForFile:QCFString::toNSString(fileInfo.canonicalFilePath())];
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index b82d096bb5..8967445f59 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -61,7 +61,7 @@ QT_FORWARD_DECLARE_CLASS(QCocoaWindow)
@end
@interface QNSPanel : NSPanel {
- @public QT_PREPEND_NAMESPACE(QCocoaWindow) *m_cocoaPlatformWindow;
+ @public QCocoaWindow *m_cocoaPlatformWindow;
}
- (void)clearPlatformWindow;
- (BOOL)canBecomeKeyWindow;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 1126315126..fcebb7e0dc 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -155,6 +155,9 @@ static bool isMouseEvent(NSEvent *ev)
- (BOOL)canBecomeKeyWindow
{
+ if (!m_cocoaPlatformWindow)
+ return NO;
+
// Only tool or dialog windows should become key:
if (m_cocoaPlatformWindow
&& (m_cocoaPlatformWindow->window()->type() == Qt::Tool || m_cocoaPlatformWindow->window()->type() == Qt::Dialog))
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index aff93dd133..b8f0fc3cce 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -876,7 +876,23 @@ static QTouchDevice *touchDevice = 0;
currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
}
- QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers);
+ QWheelEvent::Phase ph = QWheelEvent::Changed;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ // On 10.8 and above, MayBegin is likely to happen. We treat it the same as an actual begin.
+ if (phase == NSEventPhaseMayBegin)
+ ph = QWheelEvent::Started;
+ } else
+#endif
+ if (phase == NSEventPhaseBegan) {
+ // On 10.7, MayBegin will not happen, so Began is the actual beginning.
+ ph = QWheelEvent::Started;
+ }
+ if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled) {
+ ph = QWheelEvent::Ended;
+ }
+
+ QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph);
if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled) {
currentWheelModifiers = Qt::NoModifier;
@@ -919,14 +935,11 @@ static QTouchDevice *touchDevice = 0;
NSString *charactersIgnoringModifiers = [nsevent charactersIgnoringModifiers];
NSString *characters = [nsevent characters];
- // [from Qt 4 impl] There is no way to get the scan code from carbon. But we cannot
+ // There is no way to get the scan code from carbon/cocoa. But we cannot
// use the value 0, since it indicates that the event originates from somewhere
// else than the keyboard.
quint32 nativeScanCode = 1;
-
- UInt32 nativeVirtualKey = 0;
- EventRef eventRef = EventRef([nsevent eventRef]);
- GetEventParameter(eventRef, kEventParamKeyCode, typeUInt32, 0, sizeof(nativeVirtualKey), 0, &nativeVirtualKey);
+ quint32 nativeVirtualKey = [nsevent keyCode];
QChar ch = QChar::ReplacementCharacter;
int keyCode = Qt::Key_unknown;
diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
index 301beb11c1..dc3757ce3c 100644
--- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
@@ -362,7 +362,6 @@ CGColorSpaceRef QCoreGraphicsPaintEngine::macDisplayColorSpace(const QWidget *wi
CGColorSpaceRef colorSpace;
CGDirectDisplayID displayID;
- CMProfileRef displayProfile = 0;
if (widget == 0) {
displayID = CGMainDisplayID();
} else {
@@ -376,18 +375,11 @@ CGColorSpaceRef QCoreGraphicsPaintEngine::macDisplayColorSpace(const QWidget *wi
if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
return colorSpace;
- CMError err = CMGetProfileByAVID((CMDisplayIDType)displayID, &displayProfile);
- if (err == noErr) {
- colorSpace = CGColorSpaceCreateWithPlatformColorSpace(displayProfile);
- } else if (widget) {
- return macDisplayColorSpace(0); // fall back on main display
- }
-
+ colorSpace = CGDisplayCopyColorSpace(displayID);
if (colorSpace == 0)
colorSpace = CGColorSpaceCreateDeviceRGB();
m_displayColorSpaceHash.insert(displayID, colorSpace);
- CMCloseProfile(displayProfile);
if (!m_postRoutineRegistered) {
m_postRoutineRegistered = true;
qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
diff --git a/src/plugins/platforms/directfb/main.cpp b/src/plugins/platforms/directfb/main.cpp
index 3d5d60abaa..5ba1b0996b 100644
--- a/src/plugins/platforms/directfb/main.cpp
+++ b/src/plugins/platforms/directfb/main.cpp
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
class QDirectFbIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "directfb.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "directfb.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
index 939d8c0686..5b4c958616 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
@@ -286,6 +286,14 @@ QDirectFbKeyMap::QDirectFbKeyMap()
insert(DIKS_MAIL , Qt::Key_LaunchMail);
insert(DIKS_FAVORITES , Qt::Key_Favorites);
+ insert(DIKS_RED , Qt::Key_Red);
+ insert(DIKS_GREEN , Qt::Key_Green);
+ insert(DIKS_YELLOW , Qt::Key_Yellow);
+ insert(DIKS_BLUE , Qt::Key_Blue);
+
+ insert(DIKS_CHANNEL_UP , Qt::Key_ChannelUp);
+ insert(DIKS_CHANNEL_DOWN , Qt::Key_ChannelDown);
+
insert(DIKS_BACK , Qt::Key_Back);
insert(DIKS_FORWARD , Qt::Key_Forward);
insert(DIKS_VOLUME_UP , Qt::Key_VolumeUp);
diff --git a/src/plugins/platforms/eglfs/main.cpp b/src/plugins/platforms/eglfs/main.cpp
index df77127b4a..d8e7a3792e 100644
--- a/src/plugins/platforms/eglfs/main.cpp
+++ b/src/plugins/platforms/eglfs/main.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QEglFSIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "eglfs.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "eglfs.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index cf1503b7f9..08f68a20f4 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -74,6 +74,8 @@
QT_BEGIN_NAMESPACE
+static void *eglContextForContext(QOpenGLContext *context);
+
QEglFSIntegration::QEglFSIntegration()
: mEventDispatcher(createUnixEventDispatcher()), mFontDb(new QGenericUnixFontDatabase())
{
@@ -200,6 +202,20 @@ void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource
return 0;
}
+void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
+{
+ QByteArray lowerCaseResource = resource.toLower();
+
+ if (lowerCaseResource == "egldisplay") {
+ if (window)
+ return static_cast<QEglFSScreen *>(window->handle()->screen())->display();
+ else
+ return static_cast<QEglFSScreen *>(mScreen)->display();
+ }
+
+ return 0;
+}
+
void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
{
QByteArray lowerCaseResource = resource.toLower();
@@ -215,6 +231,26 @@ void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QO
return 0;
}
+QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
+{
+ QByteArray lowerCaseResource = resource.toLower();
+ if (lowerCaseResource == "get_egl_context")
+ return NativeResourceForContextFunction(eglContextForContext);
+
+ return 0;
+}
+
+static void *eglContextForContext(QOpenGLContext *context)
+{
+ Q_ASSERT(context);
+
+ QEGLPlatformContext *handle = static_cast<QEGLPlatformContext *>(context->handle());
+ if (!handle)
+ return 0;
+
+ return handle->eglContext();
+}
+
EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
{
class Chooser : public QEglConfigChooser {
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h
index bf044d6919..dd85788bd8 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.h
@@ -72,8 +72,11 @@ public:
// QPlatformNativeInterface
void *nativeResourceForIntegration(const QByteArray &resource);
+ void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
+ NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
+
QPlatformScreen *screen() const { return mScreen; }
static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format);
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 6cb1f88c66..1fe8bcc11b 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE
QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
: m_dpy(dpy)
+ , m_surface(0)
, m_cursor(0)
{
#ifdef QEGL_EXTRA_DEBUG
@@ -95,4 +96,9 @@ QPlatformCursor *QEglFSScreen::cursor() const
return m_cursor;
}
+void QEglFSScreen::setPrimarySurface(EGLSurface surface)
+{
+ m_surface = surface;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 298a67cd3a..b04c85797f 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -69,9 +69,16 @@ public:
QPlatformCursor *cursor() const;
EGLDisplay display() const { return m_dpy; }
+ EGLSurface primarySurface() const { return m_surface; }
+
+protected:
+ void setPrimarySurface(EGLSurface surface);
private:
+ friend class QEglFSWindow;
+
EGLDisplay m_dpy;
+ EGLSurface m_surface;
QEglFSCursor *m_cursor;
};
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index 28ce8c8a33..bf6e375ac0 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -42,6 +42,8 @@
#include "qeglfswindow.h"
#include "qeglfshooks.h"
#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatformintegration.h>
+#include <private/qguiapplication_p.h>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
@@ -66,6 +68,11 @@ QEglFSWindow::~QEglFSWindow()
destroy();
}
+static inline bool supportsMultipleWindows()
+{
+ return QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows);
+}
+
void QEglFSWindow::create()
{
if (has_window)
@@ -80,6 +87,9 @@ void QEglFSWindow::create()
return;
}
+ if (!supportsMultipleWindows() && screen()->primarySurface())
+ return;
+
EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display();
QSurfaceFormat platformFormat = QEglFSHooks::hooks()->surfaceFormatFor(window()->requestedFormat());
m_config = QEglFSIntegration::chooseConfig(display, platformFormat);
@@ -105,11 +115,14 @@ void QEglFSWindow::resetSurface()
m_window = QEglFSHooks::hooks()->createNativeWindow(QEglFSHooks::hooks()->screenSize(), m_format);
has_window = true;
m_surface = eglCreateWindowSurface(display, m_config, m_window, NULL);
+
if (m_surface == EGL_NO_SURFACE) {
EGLint error = eglGetError();
eglTerminate(display);
qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error);
}
+
+ screen()->setPrimarySurface(m_surface);
}
void QEglFSWindow::destroy()
@@ -117,6 +130,12 @@ void QEglFSWindow::destroy()
if (m_surface) {
EGLDisplay display = static_cast<QEglFSScreen *>(screen())->display();
eglDestroySurface(display, m_surface);
+
+ if (!supportsMultipleWindows()) {
+ // ours must be the primary surface
+ screen()->setPrimarySurface(0);
+ }
+
m_surface = 0;
}
@@ -145,9 +164,21 @@ WId QEglFSWindow::winId() const
return WId(m_window);
}
+EGLSurface QEglFSWindow::surface() const
+{
+ if (!supportsMultipleWindows())
+ return screen()->primarySurface();
+ return m_surface;
+}
+
QSurfaceFormat QEglFSWindow::format() const
{
return m_format;
}
+QEglFSScreen *QEglFSWindow::screen() const
+{
+ return static_cast<QEglFSScreen *>(QPlatformWindow::screen());
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index 0997f80e74..936537807a 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -59,9 +59,11 @@ public:
void setWindowState(Qt::WindowState state);
WId winId() const;
- EGLSurface surface() const { return m_surface; }
+ EGLSurface surface() const;
QSurfaceFormat format() const;
+ QEglFSScreen *screen() const;
+
void create();
void destroy();
diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro
index 842ff17f1c..5a2129eb08 100644
--- a/src/plugins/platforms/ios/ios.pro
+++ b/src/plugins/platforms/ios/ios.pro
@@ -1,3 +1,39 @@
-TEMPLATE = subdirs
+TARGET = qios
-SUBDIRS += plugin.pro qtmain.pro
+PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = QIOSIntegrationPlugin
+load(qt_plugin)
+
+QT += core-private gui-private platformsupport-private
+LIBS += -framework Foundation -framework UIKit -framework QuartzCore
+
+OBJECTIVE_SOURCES = \
+ plugin.mm \
+ qiosmain_wrapper.mm \
+ qiosmain_dummy.mm \
+ qiosintegration.mm \
+ qioswindow.mm \
+ qiosscreen.mm \
+ qiosbackingstore.mm \
+ qiosapplicationdelegate.mm \
+ qiosapplicationstate.mm \
+ qiosviewcontroller.mm \
+ qioscontext.mm \
+ qiosinputcontext.mm \
+ qiostheme.mm \
+ qiosglobal.mm
+
+HEADERS = \
+ qiosintegration.h \
+ qioswindow.h \
+ qiosscreen.h \
+ qiosbackingstore.h \
+ qiosapplicationdelegate.h \
+ qiosapplicationstate.h \
+ qiosviewcontroller.h \
+ qioscontext.h \
+ qiosinputcontext.h \
+ qiostheme.h \
+ qiosglobal.h
+
+#HEADERS = qiossoftwareinputhandler.h
diff --git a/src/plugins/platforms/ios/plugin.mm b/src/plugins/platforms/ios/plugin.mm
index a93b6037ad..efb1ad8d74 100644
--- a/src/plugins/platforms/ios/plugin.mm
+++ b/src/plugins/platforms/ios/plugin.mm
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "ios.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "ios.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
@@ -66,4 +66,8 @@ QT_END_NAMESPACE
#include "plugin.moc"
+// Dummy function that we explicitly tell the linker to look for,
+// so that the plugin's static initializer is included and run.
+extern "C" void qt_registerPlatformPlugin() {}
+
Q_IMPORT_PLUGIN(QIOSIntegrationPlugin)
diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro
deleted file mode 100644
index 591a0a67ed..0000000000
--- a/src/plugins/platforms/ios/plugin.pro
+++ /dev/null
@@ -1,36 +0,0 @@
-TARGET = qios
-
-PLUGIN_TYPE = platforms
-load(qt_plugin)
-
-QT += core-private gui-private platformsupport-private
-LIBS += -framework UIKit -framework QuartzCore
-
-OBJECTIVE_SOURCES = \
- plugin.mm \
- qiosintegration.mm \
- qioswindow.mm \
- qiosscreen.mm \
- qioseventdispatcher.mm \
- qiosbackingstore.mm \
- qiosapplicationdelegate.mm \
- qiosviewcontroller.mm \
- qioscontext.mm \
- qiosinputcontext.mm \
- qiostheme.mm \
- qiosglobal.mm
-
-HEADERS = \
- qiosintegration.h \
- qioswindow.h \
- qiosscreen.h \
- qioseventdispatcher.h \
- qiosbackingstore.h \
- qiosapplicationdelegate.h \
- qiosviewcontroller.h \
- qioscontext.h \
- qiosinputcontext.h \
- qiostheme.h \
- qiosglobal.h
-
-#HEADERS = qiossoftwareinputhandler.h
diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h
index 3d3ba58049..bfe31af198 100644
--- a/src/plugins/platforms/ios/qiosapplicationdelegate.h
+++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h
@@ -50,7 +50,3 @@
@property (strong, nonatomic) QIOSViewController *qiosViewController;
@end
-
-@interface QIOSMainWrapperApplicationDelegate : QIOSApplicationDelegate
-@end
-
diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm
index 10cbe529c4..52d94f38fb 100644
--- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm
+++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm
@@ -39,10 +39,15 @@
**
****************************************************************************/
-#import "qiosapplicationdelegate.h"
+#include "qiosapplicationdelegate.h"
+
+#include "qiosviewcontroller.h"
#include "qioswindow.h"
+
#include <QtCore/QtCore>
+extern int qt_user_main(int argc, char *argv[]);
+
@implementation QIOSApplicationDelegate
@synthesize window;
@@ -50,40 +55,43 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
- Q_UNUSED(application)
- Q_UNUSED(launchOptions)
+ Q_UNUSED(application);
+ Q_UNUSED(launchOptions);
- return YES;
-}
+ self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
+ self.qiosViewController = [[[QIOSViewController alloc] init] autorelease];
+ self.window.rootViewController = self.qiosViewController;
-- (void)applicationWillResignActive:(UIApplication *)application
-{
- Q_UNUSED(application)
-}
+#ifdef QT_DEBUG
+ self.window.backgroundColor = [UIColor cyanColor];
+#endif
-- (void)applicationDidEnterBackground:(UIApplication *)application
-{
- Q_UNUSED(application)
-}
+ [self.window makeKeyAndVisible];
-- (void)applicationWillEnterForeground:(UIApplication *)application
-{
- Q_UNUSED(application)
- // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
-}
+ // We schedule the main-redirection for the next eventloop pass so that we
+ // can return from this function and let UIApplicationMain finish its job.
+ [NSTimer scheduledTimerWithTimeInterval:.01f target:self
+ selector:@selector(runUserMain) userInfo:nil repeats:NO];
-- (void)applicationDidBecomeActive:(UIApplication *)application
-{
- Q_UNUSED(application)
- // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+ return YES;
}
-- (void)applicationWillTerminate:(UIApplication *)application
+- (void)runUserMain
{
- Q_UNUSED(application)
- // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+ NSArray *arguments = [[NSProcessInfo processInfo] arguments];
+ int argc = arguments.count;
+ char **argv = new char*[argc];
+ for (int i = 0; i < argc; ++i) {
+ NSString *arg = [arguments objectAtIndex:i];
+ argv[i] = reinterpret_cast<char *>(malloc([arg lengthOfBytesUsingEncoding:[NSString defaultCStringEncoding]]));
+ strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]);
+ }
+
+ qt_user_main(argc, argv);
+ delete[] argv;
}
+
- (void)dealloc
{
[qiosViewController release];
@@ -93,4 +101,3 @@
@end
-
diff --git a/src/plugins/platforms/kms/qkmsudevhandler.cpp b/src/plugins/platforms/ios/qiosapplicationstate.h
index e32723e78f..e726ad895e 100644
--- a/src/plugins/platforms/kms/qkmsudevhandler.cpp
+++ b/src/plugins/platforms/ios/qiosapplicationstate.h
@@ -39,17 +39,22 @@
**
****************************************************************************/
-#include <qkmsudevhandler.h>
+#ifndef QIOSAPPLICATIONSTATE_H
+#define QIOSAPPLICATIONSTATE_H
QT_BEGIN_NAMESPACE
-QKmsUdevHandler::QKmsUdevHandler(QObject *parent)
- : QObject(parent)
-{
-}
+@class QIOSApplicationStateListener;
-QKmsUdevHandler::~QKmsUdevHandler()
+class QIOSApplicationState
{
-}
+public:
+ QIOSApplicationState();
+ ~QIOSApplicationState();
+private:
+ QIOSApplicationStateListener *m_listener;
+};
QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm
new file mode 100644
index 0000000000..df64edf465
--- /dev/null
+++ b/src/plugins/platforms/ios/qiosapplicationstate.mm
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+#include <qpa/qwindowsysteminterface.h>
+#include "qiosapplicationstate.h"
+
+@interface QIOSApplicationStateListener : NSObject
+@end
+
+@implementation QIOSApplicationStateListener
+
+- (id) init
+{
+ self = [super init];
+ if (self) {
+ // Listen for application state changes.
+ // Note: We use notifications rather than application delegate callbacks to
+ // also support hybrid applications were QIOSApplicationDelegate is not in use.
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(applicationDidBecomeActive)
+ name:UIApplicationDidBecomeActiveNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(applicationWillResignActive)
+ name:UIApplicationWillResignActiveNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(applicationDidEnterBackground)
+ name:UIApplicationDidEnterBackgroundNotification
+ object:nil];
+ }
+ return self;
+}
+
+- (void) dealloc
+{
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:UIApplicationDidBecomeActiveNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:UIApplicationWillResignActiveNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:UIApplicationDidEnterBackgroundNotification
+ object:nil];
+ [super dealloc];
+}
+
+- (void) applicationDidBecomeActive
+{
+ [self handleApplicationStateChanged:UIApplicationStateActive];
+}
+
+- (void) applicationWillResignActive
+{
+ // Note that UIApplication is still UIApplicationStateActive at this
+ // point, but since there is no separate notification for the inactive
+ // state, we report UIApplicationStateInactive now:
+ [self handleApplicationStateChanged:UIApplicationStateInactive];
+}
+
+- (void) applicationDidEnterBackground
+{
+ [self handleApplicationStateChanged:UIApplicationStateBackground];
+}
+
+- (void) handleApplicationStateChanged:(UIApplicationState) uiApplicationState
+{
+ Qt::ApplicationState state;
+ switch (uiApplicationState) {
+ case UIApplicationStateActive:
+ // The application is visible in front, and receiving events:
+ state = Qt::ApplicationActive;
+ break;
+ case UIApplicationStateInactive:
+ // The app is running in the foreground but is not receiving events. This
+ // typically happens while transitioning to/from active/background, like
+ // upon app launch or when receiving incoming calls:
+ state = Qt::ApplicationInactive;
+ break;
+ case UIApplicationStateBackground:
+ // Normally the app would enter this state briefly before it gets
+ // suspeded (you have five seconds, according to Apple).
+ // You can request more time and start a background task, which would
+ // normally map closer to Qt::ApplicationHidden. But since we have no
+ // API for doing that yet, we handle this state as "about to be suspended".
+ // Note: A screen-shot for the SpringBoard will also be taken after this
+ // call returns.
+ state = Qt::ApplicationSuspended;
+ break;
+ }
+ QWindowSystemInterface::handleApplicationStateChanged(state);
+}
+
+@end
+
+QT_BEGIN_NAMESPACE
+
+QIOSApplicationState::QIOSApplicationState()
+ : m_listener([[QIOSApplicationStateListener alloc] init])
+{
+ // Update the current state now, since we have missed all the updates
+ // posted from AppKit so far. But let QPA finish initialization first:
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIApplicationState state = [UIApplication sharedApplication].applicationState;
+ [m_listener handleApplicationStateChanged:state];
+ });
+}
+
+QIOSApplicationState::~QIOSApplicationState()
+{
+ [m_listener release];
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm
index 87bcc01d04..85f560a722 100644
--- a/src/plugins/platforms/ios/qioscontext.mm
+++ b/src/plugins/platforms/ios/qioscontext.mm
@@ -200,7 +200,7 @@ void QIOSContext::windowDestroyed(QObject *object)
QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName)
{
- return reinterpret_cast<QFunctionPointer>(dlsym(RTLD_NEXT, functionName.constData()));
+ return QFunctionPointer(dlsym(RTLD_DEFAULT, functionName.constData()));
}
#include "moc_qioscontext.cpp"
diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h
index 176ad05733..78c1b260e6 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.h
+++ b/src/plugins/platforms/ios/qiosinputcontext.h
@@ -66,6 +66,7 @@ public:
private:
QIOSKeyboardListener *m_keyboardListener;
UIView *m_focusView;
+ bool m_hasPendingHideRequest;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 1d3ab12de9..d430589037 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -99,6 +99,7 @@ QIOSInputContext::QIOSInputContext()
: QPlatformInputContext()
, m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this])
, m_focusView(0)
+ , m_hasPendingHideRequest(false)
{
}
@@ -120,12 +121,20 @@ void QIOSInputContext::showInputPanel()
// responder. Rather than searching for it from the top, we let the active QIOSWindow tell us which view to use.
// Note that Qt will forward keyevents to whichever QObject that needs it, regardless of which UIView the input
// actually came from. So in this respect, we're undermining iOS' responder chain.
+ m_hasPendingHideRequest = false;
[m_focusView becomeFirstResponder];
}
void QIOSInputContext::hideInputPanel()
{
- [m_focusView resignFirstResponder];
+ // Delay hiding the keyboard for cases where the user is transferring focus between
+ // 'line edits'. In that case the 'line edit' that lost focus will close the input
+ // panel, just to see that the new 'line edit' will open it again:
+ m_hasPendingHideRequest = true;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ if (m_hasPendingHideRequest)
+ [m_focusView resignFirstResponder];
+ });
}
bool QIOSInputContext::isInputPanelVisible() const
diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h
index c352e0f2d2..4aaf98f839 100644
--- a/src/plugins/platforms/ios/qiosintegration.h
+++ b/src/plugins/platforms/ios/qiosintegration.h
@@ -46,6 +46,8 @@
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qwindowsysteminterface.h>
+#include "qiosapplicationstate.h"
+
QT_BEGIN_NAMESPACE
class QIOSIntegration : public QPlatformIntegration, public QPlatformNativeInterface
@@ -79,6 +81,7 @@ private:
QPlatformInputContext *m_inputContext;
QPlatformScreen *m_screen;
QTouchDevice *m_touchDevice;
+ QIOSApplicationState m_applicationState;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index 61fd1c3d60..e31804f428 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -43,12 +43,13 @@
#include "qioswindow.h"
#include "qiosbackingstore.h"
#include "qiosscreen.h"
-#include "qioseventdispatcher.h"
#include "qioscontext.h"
#include "qiosinputcontext.h"
#include "qiostheme.h"
+#include <QtPlatformSupport/private/qioseventdispatcher_p.h>
#include <QtPlatformSupport/private/qcoretextfontdatabase_p.h>
+#include <QDir>
#include <QtDebug>
@@ -71,6 +72,9 @@ QIOSIntegration::QIOSIntegration()
exit(-1);
}
+ // Set current directory to app bundle folder
+ QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String]));
+
screenAdded(m_screen);
m_touchDevice = new QTouchDevice;
@@ -86,6 +90,8 @@ bool QIOSIntegration::hasCapability(Capability cap) const
return true;
case MultipleWindows:
return true;
+ case ApplicationState:
+ return true;
default:
return QPlatformIntegration::hasCapability(cap);
}
@@ -129,6 +135,8 @@ QVariant QIOSIntegration::styleHint(StyleHint hint) const
switch (hint) {
case ShowIsFullScreen:
return true;
+ case SetFocusOnTouchRelease:
+ return true;
default:
return QPlatformIntegration::styleHint(hint);
}
diff --git a/src/plugins/platforms/kms/qkmsudevhandler.h b/src/plugins/platforms/ios/qiosmain_dummy.mm
index e95960628a..28d7e59381 100644
--- a/src/plugins/platforms/kms/qkmsudevhandler.h
+++ b/src/plugins/platforms/ios/qiosmain_dummy.mm
@@ -39,26 +39,18 @@
**
****************************************************************************/
-#ifndef QKMSUDEVHANDLER_H
-#define QKMSUDEVHANDLER_H
+#include <QtCore/qglobal.h>
-#include <QObject>
+/*
+ This file provides a dummy implementation of qt_user_main, so that
+ we don't get an undefined symbol in the hybrid use-case, where we
+ don't rename main() to qt_user_main(). As long as the linker is not
+ passed -all_load, this translation unit is only picked up and used
+ if qt_user_main is not defined by the user's code.
+*/
-#include <libudev.h>
-
-QT_BEGIN_NAMESPACE
-
-class QKmsUdevHandler : public QObject
+int qt_user_main(int, char **)
{
- Q_OBJECT
-
-public:
- QKmsUdevHandler(QObject *parent = 0);
- virtual ~QKmsUdevHandler();
-
- virtual QObject *create(struct udev_device *) = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QKMSUDEVHANDLER_H
+ qFatal("Hit dummy qt_user_main, this should never happen!");
+ return 0;
+}
diff --git a/src/plugins/platforms/kms/qkmsudevdrmhandler.cpp b/src/plugins/platforms/ios/qiosmain_wrapper.mm
index 68a4aaacdb..d9b8c7311e 100644
--- a/src/plugins/platforms/kms/qkmsudevdrmhandler.cpp
+++ b/src/plugins/platforms/ios/qiosmain_wrapper.mm
@@ -39,28 +39,22 @@
**
****************************************************************************/
-#include <QtCore/QRegExp>
+#include "qiosapplicationdelegate.h"
-#include <qkmsintegration.h>
-#include <qkmsudevdrmhandler.h>
+/*
+ This file provides a wrapper implementation of main() for the non-
+ hybrid use-case. The user's main is renamed to qt_user_main by the
+ build rules, and we'll call out to that main at the appropriate time.
-QT_BEGIN_NAMESPACE
+ This file purposly only exports a single symbol, _main, so that
+ when the linker considers the translation unit for inclusion it
+ will discard it when main has already been defined in the user's
+ application for the hybrid use-case.
+*/
-QKmsUdevDRMHandler::QKmsUdevDRMHandler(QKmsIntegration *integration)
- : m_integration(integration)
+int main(int argc, char *argv[])
{
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSApplicationDelegate class]));
+ }
}
-
-QObject *QKmsUdevDRMHandler::create(struct udev_device *device)
-{
- if (strcmp(udev_device_get_subsystem(device), "drm"))
- return 0;
-
- QRegExp regexp("^card\\d+$");
- if (!regexp.exactMatch(udev_device_get_sysname(device)))
- return 0;
-
- return m_integration->createDevice(udev_device_get_devnode(device));
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 0c3ae8e834..4c8a16b0bc 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -247,6 +247,23 @@
return YES;
}
+- (BOOL)becomeFirstResponder
+{
+ // On iOS, a QWindow should only have input focus when the input panel is
+ // open. This is to stop cursors and focus rects from being drawn when the
+ // user cannot type. And since the keyboard will open when a view becomes
+ // the first responder, it's now a good time to inform QPA that the QWindow
+ // this view backs became active:
+ QWindowSystemInterface::handleWindowActivated(m_qioswindow->window());
+ return [super becomeFirstResponder];
+}
+
+- (BOOL)resignFirstResponder
+{
+ QWindowSystemInterface::handleWindowActivated(0);
+ return [super resignFirstResponder];
+}
+
- (BOOL)hasText
{
return YES;
@@ -416,7 +433,6 @@ void QIOSWindow::requestActivateWindow()
raise();
QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
static_cast<QIOSInputContext *>(context)->focusViewChanged(m_view);
- QPlatformWindow::requestActivateWindow();
}
void QIOSWindow::raiseOrLower(bool raise)
diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm
deleted file mode 100644
index 19c98f2c59..0000000000
--- a/src/plugins/platforms/ios/qtmain.mm
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qiosapplicationdelegate.h"
-#include "qiosviewcontroller.h"
-
-int main(int argc, char *argv[])
-{
- @autoreleasepool {
- return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSMainWrapperApplicationDelegate class]));
- }
-}
-
-extern int qt_main(int argc, char *argv[]);
-
-@implementation QIOSMainWrapperApplicationDelegate
-
-- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
-{
- self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
- self.qiosViewController = [[[QIOSViewController alloc] init] autorelease];
- self.window.rootViewController = self.qiosViewController;
-
-#ifdef QT_DEBUG
- self.window.backgroundColor = [UIColor cyanColor];
-#endif
-
- [self.window makeKeyAndVisible];
-
- // We schedule the main-redirection for the next eventloop pass so that we
- // can return from this function and let UIApplicationMain finish its job.
- [NSTimer scheduledTimerWithTimeInterval:.01f target:self
- selector:@selector(runUserMain) userInfo:nil repeats:NO];
-
- if ([QIOSApplicationDelegate instancesRespondToSelector:_cmd])
- return [super application:application didFinishLaunchingWithOptions:launchOptions];
- else
- return YES;
-}
-
-- (void)runUserMain
-{
- NSArray *arguments = [[NSProcessInfo processInfo] arguments];
- int argc = arguments.count;
- char **argv = new char*[argc];
- for (int i = 0; i < argc; ++i) {
- NSString *arg = [arguments objectAtIndex:i];
- argv[i] = reinterpret_cast<char *>(malloc([arg lengthOfBytesUsingEncoding:[NSString defaultCStringEncoding]]));
- strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- }
-
- qt_main(argc, argv);
- delete[] argv;
-}
-
-@end
diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro
deleted file mode 100644
index cbcb272217..0000000000
--- a/src/plugins/platforms/ios/qtmain.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-TARGET = qiosmain
-
-PLUGIN_TYPE = platforms
-load(qt_plugin)
-
-QT += gui-private
-
-OBJECTIVE_SOURCES = qtmain.mm
diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro
index 711cf9e5c7..612a878736 100644
--- a/src/plugins/platforms/kms/kms.pro
+++ b/src/plugins/platforms/kms/kms.pro
@@ -22,9 +22,6 @@ SOURCES = main.cpp \
qkmsdevice.cpp \
qkmsbackingstore.cpp \
qkmsnativeinterface.cpp \
- qkmsudevlistener.cpp \
- qkmsudevhandler.cpp \
- qkmsudevdrmhandler.cpp \
qkmsvthandler.cpp
HEADERS = qkmsintegration.h \
qkmsscreen.h \
@@ -34,9 +31,6 @@ HEADERS = qkmsintegration.h \
qkmsdevice.h \
qkmsbackingstore.h \
qkmsnativeinterface.h \
- qkmsudevlistener.h \
- qkmsudevhandler.h \
- qkmsudevdrmhandler.h \
qkmsvthandler.h
OTHER_FILES += \
diff --git a/src/plugins/platforms/kms/main.cpp b/src/plugins/platforms/kms/main.cpp
index 75f7ef5278..db0582e694 100644
--- a/src/plugins/platforms/kms/main.cpp
+++ b/src/plugins/platforms/kms/main.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QKmsIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "kms.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "kms.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/kms/qkmsintegration.cpp b/src/plugins/platforms/kms/qkmsintegration.cpp
index 8210b54535..539363722d 100644
--- a/src/plugins/platforms/kms/qkmsintegration.cpp
+++ b/src/plugins/platforms/kms/qkmsintegration.cpp
@@ -46,10 +46,14 @@
#include "qkmsbackingstore.h"
#include "qkmscontext.h"
#include "qkmsnativeinterface.h"
-#include "qkmsudevlistener.h"
-#include "qkmsudevdrmhandler.h"
#include "qkmsvthandler.h"
+#if !defined(QT_NO_EVDEV)
+#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
+#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
+#include <QtPlatformSupport/private/qevdevtouch_p.h>
+#endif
+
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
#include <QtGui/private/qguiapplication_p.h>
@@ -62,18 +66,32 @@ QKmsIntegration::QKmsIntegration()
: QPlatformIntegration(),
m_fontDatabase(new QGenericUnixFontDatabase()),
m_eventDispatcher(createUnixEventDispatcher()),
- m_nativeInterface(new QKmsNativeInterface),
- m_udevListener(new QKmsUdevListener)
+ m_nativeInterface(new QKmsNativeInterface)
{
QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
setenv("EGL_PLATFORM", "drm",1);
m_vtHandler = new QKmsVTHandler;
- m_drmHandler = new QKmsUdevDRMHandler(this);
- m_udevListener->addHandler(m_drmHandler);
+
+ m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_DRM | QDeviceDiscovery::Device_DRM_PrimaryGPU, 0);
+ if (m_deviceDiscovery) {
+ QStringList devices = m_deviceDiscovery->scanConnectedDevices();
+ foreach (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)));
+ }
+
+#if !defined(QT_NO_EVDEV)
+ new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
+ new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
+ new QEvdevTouchScreenHandlerThread(QString() /* spec */, this);
+#endif
}
QKmsIntegration::~QKmsIntegration()
{
+ delete m_deviceDiscovery;
foreach (QKmsDevice *device, m_devices) {
delete device;
}
@@ -81,15 +99,18 @@ QKmsIntegration::~QKmsIntegration()
delete screen;
}
delete m_fontDatabase;
- delete m_udevListener;
delete m_vtHandler;
}
-QObject *QKmsIntegration::createDevice(const char *path)
+void QKmsIntegration::addDevice(const QString &deviceNode)
+{
+ m_devices.append(new QKmsDevice(deviceNode, this));
+}
+
+void QKmsIntegration::removeDevice(const QString &deviceNode)
{
- QKmsDevice *device = new QKmsDevice(path, this);
- m_devices.append(device);
- return device;
+ // TODO: support hot-plugging some day?
+ Q_UNUSED(deviceNode);
}
bool QKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
diff --git a/src/plugins/platforms/kms/qkmsintegration.h b/src/plugins/platforms/kms/qkmsintegration.h
index c08396ba3f..5069753aa5 100644
--- a/src/plugins/platforms/kms/qkmsintegration.h
+++ b/src/plugins/platforms/kms/qkmsintegration.h
@@ -44,17 +44,18 @@
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformnativeinterface.h>
+#include <QtPlatformSupport/private/qdevicediscovery_p.h>
QT_BEGIN_NAMESPACE
class QKmsScreen;
class QKmsDevice;
-class QKmsUdevListener;
-class QKmsUdevDRMHandler;
class QKmsVTHandler;
-class QKmsIntegration : public QPlatformIntegration
+class QKmsIntegration : public QObject, public QPlatformIntegration
{
+ Q_OBJECT
+
public:
QKmsIntegration();
~QKmsIntegration();
@@ -73,6 +74,10 @@ public:
void addScreen(QKmsScreen *screen);
QObject *createDevice(const char *);
+private slots:
+ void addDevice(const QString &deviceNode);
+ void removeDevice(const QString &deviceNode);
+
private:
QStringList findDrmDevices();
@@ -81,9 +86,8 @@ private:
QPlatformFontDatabase *m_fontDatabase;
QAbstractEventDispatcher *m_eventDispatcher;
QPlatformNativeInterface *m_nativeInterface;
- QKmsUdevListener *m_udevListener;
- QKmsUdevDRMHandler *m_drmHandler;
QKmsVTHandler *m_vtHandler;
+ QDeviceDiscovery *m_deviceDiscovery;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/linuxfb/main.cpp b/src/plugins/platforms/linuxfb/main.cpp
index a1037c4feb..579984d2fc 100644
--- a/src/plugins/platforms/linuxfb/main.cpp
+++ b/src/plugins/platforms/linuxfb/main.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QLinuxFbIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "linuxfb.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "linuxfb.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/minimal/main.cpp b/src/plugins/platforms/minimal/main.cpp
index 811f1fe5ee..7846b5b387 100644
--- a/src/plugins/platforms/minimal/main.cpp
+++ b/src/plugins/platforms/minimal/main.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
class QMinimalIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "minimal.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "minimal.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/minimalegl/main.cpp b/src/plugins/platforms/minimalegl/main.cpp
index 414f45c745..c951bfb0dc 100644
--- a/src/plugins/platforms/minimalegl/main.cpp
+++ b/src/plugins/platforms/minimalegl/main.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QMinimalEglIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "minimalegl.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "minimalegl.json")
public:
QStringList keys() const;
QPlatformIntegration *create(const QString&, const QStringList&);
diff --git a/src/plugins/platforms/offscreen/main.cpp b/src/plugins/platforms/offscreen/main.cpp
index ca7dc1d18b..f48451d00d 100644
--- a/src/plugins/platforms/offscreen/main.cpp
+++ b/src/plugins/platforms/offscreen/main.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
class QOffscreenIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "offscreen.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "offscreen.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/openwfd/main.cpp b/src/plugins/platforms/openwfd/main.cpp
index 724c5cfa4b..cea3c50e56 100644
--- a/src/plugins/platforms/openwfd/main.cpp
+++ b/src/plugins/platforms/openwfd/main.cpp
@@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE
class QOpenWFDIntegrationPlugin : public QPlatformIntegrationPlugin
{
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/qnx/main.cpp b/src/plugins/platforms/qnx/main.cpp
index ea50b12cb3..fb81928625 100644
--- a/src/plugins/platforms/qnx/main.cpp
+++ b/src/plugins/platforms/qnx/main.cpp
@@ -46,9 +46,8 @@ QT_BEGIN_NAMESPACE
QPlatformIntegration *QQnxIntegrationPlugin::create(const QString& system, const QStringList& paramList)
{
- Q_UNUSED(paramList);
if (system.toLower() == QLatin1String("qnx"))
- return new QQnxIntegration;
+ return new QQnxIntegration(paramList);
return 0;
}
diff --git a/src/plugins/platforms/qnx/main.h b/src/plugins/platforms/qnx/main.h
index 0b5f6323c4..683b20efd2 100644
--- a/src/plugins/platforms/qnx/main.h
+++ b/src/plugins/platforms/qnx/main.h
@@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE
class QQnxIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "qnx.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "qnx.json")
public:
QPlatformIntegration *create(const QString&, const QStringList&);
};
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index 398b64640e..7c497b4434 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -11,11 +11,11 @@ QT += platformsupport-private core-private gui-private
CONFIG(blackberry) {
CONFIG += qqnx_pps
- # Unomment this to enable screen event handling
- # through a dedicated thread.
- # DEFINES += QQNX_SCREENEVENTTHREAD
+ # Uncomment following line to enable screen event
+ # handling through a dedicated thread.
+ # CONFIG += qqnx_screeneventthread
} else {
- DEFINES += QQNX_SCREENEVENTTHREAD
+ CONFIG += qqnx_screeneventthread
}
# Uncomment these to enable debugging output for various aspects of the plugin
@@ -40,11 +40,11 @@ CONFIG(blackberry) {
#DEFINES += QQNXVIRTUALKEYBOARD_DEBUG
#DEFINES += QQNXWINDOW_DEBUG
#DEFINES += QQNXCURSOR_DEBUG
+#DEFINES += QQNXFILEPICKER_DEBUG
SOURCES = main.cpp \
qqnxbuffer.cpp \
- qqnxscreeneventthread.cpp \
qqnxintegration.cpp \
qqnxscreen.cpp \
qqnxwindow.cpp \
@@ -60,7 +60,6 @@ SOURCES = main.cpp \
HEADERS = main.h \
qqnxbuffer.h \
- qqnxscreeneventthread.h \
qqnxkeytranslator.h \
qqnxintegration.h \
qqnxscreen.h \
@@ -75,6 +74,12 @@ HEADERS = main.h \
qqnxservices.h \
qqnxcursor.h
+CONFIG(qqnx_screeneventthread) {
+ DEFINES += QQNX_SCREENEVENTTHREAD
+ SOURCES += qqnxscreeneventthread.cpp
+ HEADERS += qqnxscreeneventthread.h
+}
+
LIBS += -lscreen
contains(QT_CONFIG, opengles2) {
@@ -91,8 +96,7 @@ CONFIG(blackberry) {
qqnxbpseventfilter.cpp \
qqnxvirtualkeyboardbps.cpp \
qqnxtheme.cpp \
- qqnxsystemsettings.cpp \
- qqnxfiledialoghelper.cpp
+ qqnxsystemsettings.cpp
HEADERS += qqnxnavigatorbps.h \
qqnxeventdispatcher_blackberry.h \
@@ -105,6 +109,17 @@ CONFIG(blackberry) {
LIBS += -lbps
}
+CONFIG(blackberry-playbook) {
+ SOURCES += qqnxfiledialoghelper_playbook.cpp
+} else {
+ CONFIG(blackberry) {
+ SOURCES += qqnxfiledialoghelper_bb10.cpp \
+ qqnxfilepicker.cpp
+
+ HEADERS += qqnxfilepicker.h
+ }
+}
+
CONFIG(qqnx_pps) {
DEFINES += QQNX_PPS
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
index d94d3c092a..133bf02fee 100644
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
+++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
@@ -41,11 +41,12 @@
#include "qqnxbpseventfilter.h"
#include "qqnxnavigatoreventhandler.h"
-#include "qqnxfiledialoghelper.h"
#include "qqnxscreen.h"
#include "qqnxscreeneventhandler.h"
#include "qqnxvirtualkeyboardbps.h"
+#include "qqnxfiledialoghelper.h"
+#include <QCoreApplication>
#include <QAbstractEventDispatcher>
#include <QDebug>
@@ -126,6 +127,7 @@ void QQnxBpsEventFilter::unregisterForScreenEvents(QQnxScreen *screen)
qWarning("QQNX: failed to unregister for screen events on screen %p", screen->nativeContext());
}
+#if defined(Q_OS_BLACKBERRY_TABLET)
void QQnxBpsEventFilter::registerForDialogEvents(QQnxFileDialogHelper *dialog)
{
if (dialog_request_events(0) != BPS_SUCCESS)
@@ -141,6 +143,7 @@ void QQnxBpsEventFilter::unregisterForDialogEvents(QQnxFileDialogHelper *dialog)
if (count == 0)
qWarning("QQNX: attempting to unregister dialog that was not registered");
}
+#endif // Q_OS_BLACKBERRY_TABLET
bool QQnxBpsEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
@@ -160,12 +163,14 @@ bool QQnxBpsEventFilter::nativeEventFilter(const QByteArray &eventType, void *me
return m_screenEventHandler->handleEvent(screenEvent);
}
+#if defined(Q_OS_BLACKBERRY_TABLET)
if (eventDomain == dialog_get_domain()) {
dialog_instance_t nativeDialog = dialog_event_get_dialog_instance(event);
QQnxFileDialogHelper *dialog = m_dialogMapper.value(nativeDialog, 0);
if (dialog)
return dialog->handleEvent(event);
}
+#endif
if (eventDomain == navigator_get_domain())
return handleNavigatorEvent(event);
@@ -244,6 +249,11 @@ bool QQnxBpsEventFilter::handleNavigatorEvent(bps_event_t *event)
break;
}
+ case NAVIGATOR_LOW_MEMORY:
+ qWarning() << "QGuiApplication based process" << QCoreApplication::applicationPid()
+ << "received \"NAVIGATOR_LOW_MEMORY\" event";
+ return false;
+
default:
qBpsEventFilterDebug() << Q_FUNC_INFO << "Unhandled navigator event. code=" << bps_event_get_code(event);
return false;
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.h b/src/plugins/platforms/qnx/qqnxbpseventfilter.h
index e897863efb..f8e36823d5 100644
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.h
+++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.h
@@ -73,8 +73,10 @@ public:
void registerForScreenEvents(QQnxScreen *screen);
void unregisterForScreenEvents(QQnxScreen *screen);
+#ifdef Q_OS_BLACKBERRY_TABLET
void registerForDialogEvents(QQnxFileDialogHelper *dialog);
void unregisterForDialogEvents(QQnxFileDialogHelper *dialog);
+#endif
private:
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
index e17ea80501..e7c68f6ff5 100644
--- a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
@@ -44,12 +44,19 @@
#include <qpa/qplatformdialoghelper.h>
-#include <bps/dialog.h>
QT_BEGIN_NAMESPACE
class QQnxIntegration;
+#if defined(Q_OS_BLACKBERRY_TABLET)
+#include <bps/dialog.h>
+#define NativeDialogPtr dialog_instance_t
+#else
+class QQnxFilePicker;
+#define NativeDialogPtr QQnxFilePicker *
+#endif
+
class QQnxFileDialogHelper : public QPlatformFileDialogHelper
{
Q_OBJECT
@@ -57,7 +64,9 @@ public:
explicit QQnxFileDialogHelper(const QQnxIntegration *);
~QQnxFileDialogHelper();
+#if defined(Q_OS_BLACKBERRY_TABLET)
bool handleEvent(bps_event_t *event);
+#endif
void exec();
@@ -65,29 +74,32 @@ public:
void hide();
bool defaultNameFilterDisables() const;
- void setDirectory(const QString &directory);
- QString directory() const;
- void selectFile(const QString &fileName);
- QStringList selectedFiles() 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;
- dialog_instance_t nativeDialog() const { return m_dialog; }
+ NativeDialogPtr nativeDialog() const { return m_dialog; }
Q_SIGNALS:
void dialogClosed();
private:
void setNameFilter(const QString &filter);
+ void setNameFilters(const QStringList &filters);
const QQnxIntegration *m_integration;
- dialog_instance_t m_dialog;
+ NativeDialogPtr m_dialog;
QFileDialogOptions::AcceptMode m_acceptMode;
QString m_selectedFilter;
QPlatformDialogHelper::DialogCode m_result;
- QStringList m_paths;
+#if defined(Q_OS_BLACKBERRY_TABLET)
+ QList<QUrl> m_paths;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp b/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp
new file mode 100644
index 0000000000..dc841eb1a9
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp
@@ -0,0 +1,217 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "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(),
+ m_result(QPlatformDialogHelper::Rejected)
+{
+}
+
+QQnxFileDialogHelper::~QQnxFileDialogHelper()
+{
+ delete m_dialog;
+}
+
+void QQnxFileDialogHelper::exec()
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+
+ // Clear any previous results
+ m_dialog->setDirectories(QStringList());
+
+ QEventLoop loop;
+ connect(m_dialog, SIGNAL(closed()), &loop, SLOT(quit()));
+ loop.exec();
+
+ if (m_dialog->selectedFiles().isEmpty())
+ Q_EMIT reject();
+ else
+ Q_EMIT accept();
+}
+
+bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
+{
+ Q_UNUSED(flags);
+ Q_UNUSED(parent);
+ Q_UNUSED(modality);
+
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+
+ // 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() << Q_FUNC_INFO;
+ m_dialog->close();
+}
+
+bool QQnxFileDialogHelper::defaultNameFilterDisables() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ return false;
+}
+
+void QQnxFileDialogHelper::setDirectory(const QUrl &directory)
+{
+ m_dialog->addDirectory(directory.toLocalFile());
+}
+
+QUrl QQnxFileDialogHelper::directory() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ 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() << Q_FUNC_INFO;
+ 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() << Q_FUNC_INFO;
+}
+
+void QQnxFileDialogHelper::selectNameFilter(const QString &filter)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "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() << Q_FUNC_INFO;
+ return m_selectedFilter;
+}
+
+void QQnxFileDialogHelper::setNameFilter(const QString &filter)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
+
+ setNameFilters(QPlatformFileDialogHelper::cleanFilterList(filter));
+}
+
+void QQnxFileDialogHelper::setNameFilters(const QStringList &filters)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filters =" << filters;
+
+ Q_ASSERT(!filters.isEmpty());
+
+ m_dialog->setFilters(filters);
+ m_selectedFilter = filters.first();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp b/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
index 0325a33268..2a743d03f7 100644
--- a/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
@@ -102,7 +102,7 @@ bool QQnxFileDialogHelper::handleEvent(bps_event_t *event)
for (int i = 0; i < pathCount; ++i) {
QString path = QFile::decodeName(filePaths[i]);
- m_paths.append(path);
+ m_paths.append(QUrl::fromLocalFile(path));
qFileDialogHelperDebug() << "path =" << path;
}
@@ -112,13 +112,13 @@ bool QQnxFileDialogHelper::handleEvent(bps_event_t *event)
const char *filePath = dialog_event_get_filesave_filepath(event);
QString path = QFile::decodeName(filePath);
qFileDialogHelperDebug() << "path =" << path;
- m_paths.append(path);
+ m_paths.append(QUrl::fromLocalFile(path));
}
} else { // Cancel
m_result = QPlatformDialogHelper::Rejected;
}
- emit dialogClosed();
+ Q_EMIT dialogClosed();
return true;
}
@@ -135,9 +135,9 @@ void QQnxFileDialogHelper::exec()
loop.exec();
if (m_result == QPlatformDialogHelper::Accepted)
- emit accept();
+ Q_EMIT accept();
else
- emit reject();
+ Q_EMIT reject();
}
bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
@@ -188,7 +188,7 @@ bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modali
// Maybe pre-select a filename
if (!opts->initiallySelectedFiles().isEmpty()) {
- QString fileName = opts->initiallySelectedFiles().first();
+ QString fileName = opts->initiallySelectedFiles().first().toLocalFile();
dialog_set_filesave_filename(m_dialog, QFile::encodeName(fileName).constData());
}
@@ -240,29 +240,29 @@ bool QQnxFileDialogHelper::defaultNameFilterDisables() const
return false;
}
-void QQnxFileDialogHelper::setDirectory(const QString &directory)
+void QQnxFileDialogHelper::setDirectory(const QUrl &directory)
{
qFileDialogHelperDebug() << Q_FUNC_INFO << "directory =" << directory;
// No native API for setting the directory(!). The best we can do is to
// set it as the file name but even then only with a file save dialog.
if (m_dialog && m_acceptMode == QFileDialogOptions::AcceptSave)
- dialog_set_filesave_filename(m_dialog, QFile::encodeName(directory).constData());
+ dialog_set_filesave_filename(m_dialog, QFile::encodeName(directory.toLocalFile()).constData());
}
-QString QQnxFileDialogHelper::directory() const
+QUrl QQnxFileDialogHelper::directory() const
{
qFileDialogHelperDebug() << Q_FUNC_INFO;
return m_paths.first();
}
-void QQnxFileDialogHelper::selectFile(const QString &fileName)
+void QQnxFileDialogHelper::selectFile(const QUrl &fileName)
{
qFileDialogHelperDebug() << Q_FUNC_INFO << "filename =" << fileName;
if (m_dialog && m_acceptMode == QFileDialogOptions::AcceptSave)
- dialog_set_filesave_filename(m_dialog, QFile::encodeName(fileName).constData());
+ dialog_set_filesave_filename(m_dialog, QFile::encodeName(fileName.toLocalFile()).constData());
}
-QStringList QQnxFileDialogHelper::selectedFiles() const
+QList<QUrl> QQnxFileDialogHelper::selectedFiles() const
{
qFileDialogHelperDebug() << Q_FUNC_INFO;
return m_paths;
@@ -291,9 +291,15 @@ QString QQnxFileDialogHelper::selectedNameFilter() const
void QQnxFileDialogHelper::setNameFilter(const QString &filter)
{
qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
+ setNameFilters(QPlatformFileDialogHelper::cleanFilterList(filter));
+}
+
+void QQnxFileDialogHelper::setNameFilters(const QStringList &filters)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filters =" << filters;
+
+ Q_ASSERT(!filters.isEmpty());
- // Extract the globbing expressions
- QStringList filters = QPlatformFileDialogHelper::cleanFilterList(filter);
char **globs = new char*[filters.size()];
for (int i = 0; i < filters.size(); ++i) {
QByteArray glob = filters.at(i).toLocal8Bit();
@@ -303,7 +309,7 @@ void QQnxFileDialogHelper::setNameFilter(const QString &filter)
// Set the filters
dialog_set_filebrowse_filter(m_dialog, const_cast<const char**>(globs), filters.size());
- m_selectedFilter = filter;
+ m_selectedFilter = filters.first();
// Cleanup
for (int i = 0; i < filters.size(); ++i)
diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.cpp b/src/plugins/platforms/qnx/qqnxfilepicker.cpp
new file mode 100644
index 0000000000..5229d1f1f5
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxfilepicker.cpp
@@ -0,0 +1,289 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqnxfilepicker.h"
+
+#include <QAbstractEventDispatcher>
+#include <QCoreApplication>
+#include <QDebug>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QJsonParseError>
+#include <QUrl>
+
+#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
+
+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;
+
+ 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")] = QStringLiteral("Other");
+ 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(",");
+ if (!m_filters.isEmpty())
+ map[QStringLiteral("Filter")] = m_filters.join(";");
+
+ QJsonDocument document;
+ document.setObject(QJsonObject::fromVariantMap(map));
+ const QByteArray jsonData = document.toJson(QJsonDocument::Compact);
+
+ errorCode = navigator_invoke_invocation_set_data(m_invocationHandle, jsonData.constData(), jsonData.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::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");
+}
diff --git a/src/plugins/platforms/kms/qkmsudevlistener.cpp b/src/plugins/platforms/qnx/qqnxfilepicker.h
index b2fb110479..5bb8f0969f 100644
--- a/src/plugins/platforms/kms/qkmsudevlistener.cpp
+++ b/src/plugins/platforms/qnx/qqnxfilepicker.h
@@ -1,6 +1,6 @@
-/****************************************************************************
+/***************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Research In Motion
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,63 +39,72 @@
**
****************************************************************************/
-#include <qkmsudevlistener.h>
+#ifndef QQNXFILEPICKER_H
+#define QQNXFILEPICKER_H
-QT_BEGIN_NAMESPACE
+#include <QAbstractNativeEventFilter>
+#include <QObject>
+#include <QStringList>
-QKmsUdevListener::QKmsUdevListener(QObject *parent)
- : QObject(parent)
-{
- m_udev = udev_new();
-}
+struct navigator_invoke_invocation_t;
-QKmsUdevListener::~QKmsUdevListener()
+class QQnxFilePicker : public QObject, public QAbstractNativeEventFilter
{
- udev_unref(m_udev);
-}
+ Q_OBJECT
-void QKmsUdevListener::addHandler(QKmsUdevHandler *handler)
-{
- m_handlers.removeAll((QKmsUdevHandler *) 0);
- m_handlers.removeAll(handler);
- m_handlers.prepend(handler);
+public:
+ explicit QQnxFilePicker(QObject *parent = 0);
+ ~QQnxFilePicker();
- scan();
-}
+ enum Mode {
+ Picker,
+ Saver,
+ PickerMultiple,
+ SaverMultiple
+ };
-bool QKmsUdevListener::create(struct udev_device *device)
-{
- foreach (QKmsUdevHandler *handler, m_handlers) {
- if (!handler)
- continue;
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
- QObject *obj = handler->create(device);
- if (obj) {
- m_devices[udev_device_get_syspath(device)] = obj;
- return true;
- }
- }
+ 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);
- return false;
-}
+ Mode mode() const;
-void QKmsUdevListener::scan()
-{
- struct udev_enumerate *e;
- struct udev_list_entry *entry;
-
- e = udev_enumerate_new(m_udev);
- udev_enumerate_scan_devices(e);
- udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
- const char *path = udev_list_entry_get_name(entry);
- if (m_devices.contains(path))
- continue;
-
- struct udev_device *device = udev_device_new_from_syspath(m_udev, path);
- create(device);
- udev_device_unref(device);
- }
- udev_enumerate_unref(e);
-}
-
-QT_END_NAMESPACE
+ 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 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;
+};
+
+#endif // QQNXFILEPICKER_H
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index ed959467ff..448509c69d 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -60,36 +60,10 @@ QT_BEGIN_NAMESPACE
EGLDisplay QQnxGLContext::ms_eglDisplay = EGL_NO_DISPLAY;
-static EGLenum checkEGLError(const char *msg)
-{
- static const char *errmsg[] =
- {
- "EGL function succeeded",
- "EGL is not initialized, or could not be initialized, for the specified display",
- "EGL cannot access a requested resource",
- "EGL failed to allocate resources for the requested operation",
- "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list",
- "EGLConfig argument does not name a valid EGLConfig",
- "EGLContext argument does not name a valid EGLContext",
- "EGL current surface of the calling thread is no longer valid",
- "EGLDisplay argument does not name a valid EGLDisplay",
- "EGL arguments are inconsistent",
- "EGLNativePixmapType argument does not refer to a valid native pixmap",
- "EGLNativeWindowType argument does not refer to a valid native window",
- "EGL one or more argument values are invalid",
- "EGLSurface argument does not name a valid surface configured for rendering",
- "EGL power management event has occurred",
- };
- EGLenum error = eglGetError();
- fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]);
- return error;
-}
-
QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext)
: QPlatformOpenGLContext(),
m_glContext(glContext),
- m_eglSurface(EGL_NO_SURFACE),
- m_newSurfaceRequested(true) // Create a surface the first time makeCurrent() is called
+ m_currentEglSurface(EGL_NO_SURFACE)
{
qGLContextDebug() << Q_FUNC_INFO;
QSurfaceFormat format = m_glContext->format();
@@ -168,9 +142,31 @@ QQnxGLContext::~QQnxGLContext()
// Cleanup EGL context if it exists
if (m_eglContext != EGL_NO_CONTEXT)
eglDestroyContext(ms_eglDisplay, m_eglContext);
+}
- // Cleanup EGL surface if it exists
- destroySurface();
+EGLenum QQnxGLContext::checkEGLError(const char *msg)
+{
+ static const char *errmsg[] =
+ {
+ "EGL function succeeded",
+ "EGL is not initialized, or could not be initialized, for the specified display",
+ "EGL cannot access a requested resource",
+ "EGL failed to allocate resources for the requested operation",
+ "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list",
+ "EGLConfig argument does not name a valid EGLConfig",
+ "EGLContext argument does not name a valid EGLContext",
+ "EGL current surface of the calling thread is no longer valid",
+ "EGLDisplay argument does not name a valid EGLDisplay",
+ "EGL arguments are inconsistent",
+ "EGLNativePixmapType argument does not refer to a valid native pixmap",
+ "EGLNativeWindowType argument does not refer to a valid native window",
+ "EGL one or more argument values are invalid",
+ "EGLSurface argument does not name a valid surface configured for rendering",
+ "EGL power management event has occurred",
+ };
+ EGLenum error = eglGetError();
+ fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]);
+ return error;
}
void QQnxGLContext::initialize()
@@ -199,12 +195,6 @@ void QQnxGLContext::shutdown()
eglTerminate(ms_eglDisplay);
}
-void QQnxGLContext::requestSurfaceChange()
-{
- qGLContextDebug() << Q_FUNC_INFO;
- m_newSurfaceRequested.testAndSetRelease(false, true);
-}
-
bool QQnxGLContext::makeCurrent(QPlatformSurface *surface)
{
qGLContextDebug() << Q_FUNC_INFO;
@@ -216,14 +206,18 @@ bool QQnxGLContext::makeCurrent(QPlatformSurface *surface)
if (eglResult != EGL_TRUE)
qFatal("QQnxGLContext: failed to set EGL API, err=%d", eglGetError());
- if (m_newSurfaceRequested.testAndSetOrdered(true, false)) {
- qGLContextDebug() << "New EGL surface requested";
+ QQnxWindow *platformWindow = dynamic_cast<QQnxWindow*>(surface);
+ if (!platformWindow)
+ return false;
+
+ platformWindow->setPlatformOpenGLContext(this);
+
+ if (m_currentEglSurface == EGL_NO_SURFACE || m_currentEglSurface != platformWindow->getSurface()) {
+ m_currentEglSurface = platformWindow->getSurface();
doneCurrent();
- destroySurface();
- createSurface(surface);
}
- eglResult = eglMakeCurrent(ms_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
+ eglResult = eglMakeCurrent(ms_eglDisplay, m_currentEglSurface, m_currentEglSurface, m_eglContext);
if (eglResult != EGL_TRUE) {
checkEGLError("eglMakeCurrent");
qFatal("QQNX: failed to set current EGL context, err=%d", eglGetError());
@@ -248,18 +242,12 @@ void QQnxGLContext::doneCurrent()
void QQnxGLContext::swapBuffers(QPlatformSurface *surface)
{
- Q_UNUSED(surface);
qGLContextDebug() << Q_FUNC_INFO;
+ QQnxWindow *platformWindow = dynamic_cast<QQnxWindow*>(surface);
+ if (!platformWindow)
+ return;
- // Set current rendering API
- EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (eglResult != EGL_TRUE)
- qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
-
- // Post EGL surface to window
- eglResult = eglSwapBuffers(ms_eglDisplay, m_eglSurface);
- if (eglResult != EGL_TRUE)
- qFatal("QQNX: failed to swap EGL buffers, err=%d", eglGetError());
+ platformWindow->swapEGLBuffers();
}
QFunctionPointer QQnxGLContext::getProcAddress(const QByteArray &procName)
@@ -275,6 +263,10 @@ QFunctionPointer QQnxGLContext::getProcAddress(const QByteArray &procName)
return static_cast<QFunctionPointer>(eglGetProcAddress(procName.constData()));
}
+EGLDisplay QQnxGLContext::getEglDisplay() {
+ return ms_eglDisplay;
+}
+
EGLint *QQnxGLContext::contextAttrs()
{
qGLContextDebug() << Q_FUNC_INFO;
@@ -288,66 +280,4 @@ EGLint *QQnxGLContext::contextAttrs()
#endif
}
-bool QQnxGLContext::isCurrent() const
-{
- qGLContextDebug() << Q_FUNC_INFO;
- return (eglGetCurrentContext() == m_eglContext);
-}
-
-void QQnxGLContext::createSurface(QPlatformSurface *surface)
-{
- qGLContextDebug() << Q_FUNC_INFO;
-
- // Get a pointer to the corresponding platform window
- QQnxWindow *platformWindow = dynamic_cast<QQnxWindow*>(surface);
- if (!platformWindow)
- qFatal("QQNX: unable to create EGLSurface without a QQnxWindow");
-
- // Link the window and context
- platformWindow->setPlatformOpenGLContext(this);
-
- // Fetch the surface size from the window and update
- // the window's buffers before we create the EGL surface
- const QSize surfaceSize = platformWindow->requestedBufferSize();
- if (!surfaceSize.isValid()) {
- qFatal("QQNX: Trying to create 0 size EGL surface. "
- "Please set a valid window size before calling QOpenGLContext::makeCurrent()");
- }
- platformWindow->setBufferSize(surfaceSize);
-
- // Post root window, in case it hasn't been posted yet, to make it appear.
- platformWindow->screen()->onWindowPost(platformWindow);
-
- // Obtain the native handle for our window
- screen_window_t handle = platformWindow->nativeHandle();
-
- const EGLint eglSurfaceAttrs[] =
- {
- EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
- EGL_NONE
- };
-
- // Create EGL surface
- m_eglSurface = eglCreateWindowSurface(ms_eglDisplay, m_eglConfig, (EGLNativeWindowType) handle, eglSurfaceAttrs);
- if (m_eglSurface == EGL_NO_SURFACE) {
- checkEGLError("eglCreateWindowSurface");
- qFatal("QQNX: failed to create EGL surface, err=%d", eglGetError());
- }
-}
-
-void QQnxGLContext::destroySurface()
-{
- qGLContextDebug() << Q_FUNC_INFO;
-
- // Destroy EGL surface if it exists
- if (m_eglSurface != EGL_NO_SURFACE) {
- EGLBoolean eglResult = eglDestroySurface(ms_eglDisplay, m_eglSurface);
- if (eglResult != EGL_TRUE) {
- qFatal("QQNX: failed to destroy EGL surface, err=%d", eglGetError());
- }
- }
-
- m_eglSurface = EGL_NO_SURFACE;
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h
index 6a7fca7df2..ff57861498 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.h
+++ b/src/plugins/platforms/qnx/qqnxglcontext.h
@@ -59,6 +59,8 @@ public:
QQnxGLContext(QOpenGLContext *glContext);
virtual ~QQnxGLContext();
+ static EGLenum checkEGLError(const char *msg);
+
static void initialize();
static void shutdown();
@@ -71,13 +73,10 @@ public:
virtual QSurfaceFormat format() const { return m_windowFormat; }
- bool isCurrent() const;
-
- void createSurface(QPlatformSurface *surface);
- void destroySurface();
-
+ static EGLDisplay getEglDisplay();
+ EGLConfig getEglConfig() const { return m_eglConfig;}
private:
- /** \todo Should this be non-static so we can use additional displays? */
+ //Can be static because different displays returne the same handle
static EGLDisplay ms_eglDisplay;
QSurfaceFormat m_windowFormat;
@@ -85,9 +84,7 @@ private:
EGLConfig m_eglConfig;
EGLContext m_eglContext;
- EGLSurface m_eglSurface;
-
- QAtomicInt m_newSurfaceRequested;
+ EGLSurface m_currentEglSurface;
static EGLint *contextAttrs();
};
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index feb05e3093..fa9961ccce 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -40,7 +40,9 @@
****************************************************************************/
#include "qqnxintegration.h"
+#if defined(QQNX_SCREENEVENTTHREAD)
#include "qqnxscreeneventthread.h"
+#endif
#include "qqnxnativeinterface.h"
#include "qqnxrasterbackingstore.h"
#include "qqnxscreen.h"
@@ -84,6 +86,8 @@
#include <qpa/qplatformwindow.h>
#include <qpa/qwindowsysteminterface.h>
+#include <QtGui/private/qguiapplication_p.h>
+
#if !defined(QT_NO_OPENGL)
#include "qqnxglcontext.h"
#include <QtGui/QOpenGLContext>
@@ -107,9 +111,20 @@ QT_BEGIN_NAMESPACE
QQnxWindowMapper QQnxIntegration::ms_windowMapper;
QMutex QQnxIntegration::ms_windowMapperMutex;
-QQnxIntegration::QQnxIntegration()
+static inline QQnxIntegration::Options parseOptions(const QStringList &paramList)
+{
+ QQnxIntegration::Options options = QQnxIntegration::NoOptions;
+ if (!paramList.contains(QLatin1String("no-fullscreen"))) {
+ options |= QQnxIntegration::FullScreenApplication;
+ }
+ return options;
+}
+
+QQnxIntegration::QQnxIntegration(const QStringList &paramList)
: QPlatformIntegration()
+#if defined(QQNX_SCREENEVENTTHREAD)
, m_screenEventThread(0)
+#endif
, m_navigatorEventHandler(new QQnxNavigatorEventHandler())
, m_virtualKeyboard(0)
#if defined(QQNX_PPS)
@@ -134,6 +149,7 @@ QQnxIntegration::QQnxIntegration()
#if !defined(QT_NO_DRAGANDDROP)
, m_drag(new QSimpleDrag())
#endif
+ , m_options(parseOptions(paramList))
{
qIntegrationDebug() << Q_FUNC_INFO;
// Open connection to QNX composition manager
@@ -185,8 +201,13 @@ QQnxIntegration::QQnxIntegration()
#if defined(Q_OS_BLACKBERRY)
QQnxVirtualKeyboardBps* virtualKeyboardBps = new QQnxVirtualKeyboardBps;
- m_bpsEventFilter = new QQnxBpsEventFilter(m_navigatorEventHandler,
- (m_screenEventThread ? 0 : m_screenEventHandler), virtualKeyboardBps);
+
+#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;
@@ -383,7 +404,7 @@ QPlatformDrag *QQnxIntegration::drag() const
QVariant QQnxIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
qIntegrationDebug() << Q_FUNC_INFO;
- if (hint == ShowIsFullScreen)
+ if ((hint == ShowIsFullScreen) && (m_options & FullScreenApplication))
return true;
return QPlatformIntegration::styleHint(hint);
@@ -526,6 +547,11 @@ QQnxScreen *QQnxIntegration::primaryDisplay() const
return m_screens.first();
}
+QQnxIntegration::Options QQnxIntegration::options() const
+{
+ return m_options;
+}
+
bool QQnxIntegration::supportsNavigatorEvents() const
{
// If QQNX_PPS or Q_OS_BLACKBERRY is defined then we have navigator
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index e3eb9e06ba..dd8973b767 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -51,7 +51,9 @@
QT_BEGIN_NAMESPACE
class QQnxBpsEventFilter;
+#if defined(QQNX_SCREENEVENTTHREAD)
class QQnxScreenEventThread;
+#endif
class QQnxFileDialogHelper;
class QQnxNativeInterface;
class QQnxWindow;
@@ -80,7 +82,12 @@ typedef QHash<screen_window_t, QWindow *> QQnxWindowMapper;
class QQnxIntegration : public QPlatformIntegration
{
public:
- QQnxIntegration();
+ enum Option { // Options to be passed on command line.
+ NoOptions = 0x0,
+ FullScreenApplication = 0x1
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+ explicit QQnxIntegration(const QStringList &paramList);
~QQnxIntegration();
bool hasCapability(QPlatformIntegration::Capability cap) const;
@@ -129,6 +136,8 @@ public:
void createDisplay(screen_display_t display, bool isPrimary);
void removeDisplay(QQnxScreen *screen);
QQnxScreen *primaryDisplay() const;
+ Options options() const;
+
private:
void createDisplays();
void destroyDisplays();
@@ -137,7 +146,9 @@ private:
static void removeWindow(screen_window_t qnxWindow);
screen_context_t m_screenContext;
+#if defined(QQNX_SCREENEVENTTHREAD)
QQnxScreenEventThread *m_screenEventThread;
+#endif
QQnxNavigatorEventHandler *m_navigatorEventHandler;
QQnxAbstractVirtualKeyboard *m_virtualKeyboard;
#if defined(QQNX_PPS)
@@ -164,6 +175,8 @@ private:
static QQnxWindowMapper ms_windowMapper;
static QMutex ms_windowMapperMutex;
+ const Options m_options;
+
friend class QQnxWindow;
};
diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
index 6a7a4d0944..1da3cd5446 100644
--- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
@@ -91,6 +91,11 @@ void QQnxRasterBackingStore::flush(QWindow *window, const QRegion &region, const
if (window)
targetWindow = static_cast<QQnxWindow *>(window->handle());
+ // we only need to flush the platformWindow backing store, since this is
+ // the buffer where all drawing operations of all windows, including the
+ // child windows, are performed; conceptually ,child windows have no buffers
+ // (actually they do have a 1x1 placeholder buffer due to libscreen limitations),
+ // since Qt will only draw to the backing store of the top-level window.
QQnxWindow *platformWindow = this->platformWindow();
if (!targetWindow || targetWindow == platformWindow) {
@@ -108,28 +113,6 @@ void QQnxRasterBackingStore::flush(QWindow *window, const QRegion &region, const
// update the display with newly rendered content
platformWindow->post(region);
- } else if (targetWindow) {
-
- // The contents of the backing store should be flushed to a different window than the
- // window which owns the buffer.
- // This typically happens for child windows, since child windows share a backing store with
- // their top-level window (TLW).
- // Simply copy the buffer over to the child window, to emulate a painting operation, and
- // then post the window.
- //
- // ### Note that because of the design in the QNX QPA plugin, each window has its own buffers,
- // even though they might share a backing store. This is unneeded overhead, but I don't think
- // libscreen allows to have windows without buffers, or does it?
-
- // We assume that the TLW has been flushed previously and that no changes were made to the
- // backing store inbetween (### does Qt guarantee this?)
-
- targetWindow->adjustBufferSize();
- targetWindow->blitFrom(platformWindow, offset, region);
- targetWindow->post(region);
-
- } else {
- qWarning() << Q_FUNC_INFO << "flush() called without a valid window!";
}
m_hasUnflushedPaintOperations = false;
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index 84721c9c2a..7959617443 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -85,7 +85,9 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
if (val[0] > 0 && val[1] > 0)
return QSize(val[0], val[1]);
- qWarning("QQnxScreen: screen_get_display_property_iv() reported an invalid physical screen size (%dx%d). Falling back to QQNX_PHYSICAL_SCREEN_SIZE environment variable.", val[0], val[1]);
+ qScreenDebug("QQnxScreen: screen_get_display_property_iv() reported an invalid "
+ "physical screen size (%dx%d). Falling back to QQNX_PHYSICAL_SCREEN_SIZE "
+ "environment variable.", val[0], val[1]);
const QString envPhySizeStr = qgetenv("QQNX_PHYSICAL_SCREEN_SIZE");
if (!envPhySizeStr.isEmpty()) {
@@ -94,7 +96,9 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
const int envHeight = envPhySizeStrList.size() == 2 ? envPhySizeStrList[1].toInt() : -1;
if (envWidth <= 0 || envHeight <= 0) {
- qFatal("QQnxScreen: The value of QQNX_PHYSICAL_SCREEN_SIZE must be in the format \"width,height\" in mm, with width, height > 0. Example: QQNX_PHYSICAL_SCREEN_SIZE=150,90");
+ qFatal("QQnxScreen: The value of QQNX_PHYSICAL_SCREEN_SIZE must be in the format "
+ "\"width,height\" in mm, with width, height > 0. "
+ "Example: QQNX_PHYSICAL_SCREEN_SIZE=150,90");
return QSize(150, 90);
}
@@ -103,11 +107,14 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
#if defined(QQNX_PHYSICAL_SCREEN_SIZE_DEFINED)
const QSize defSize(QQNX_PHYSICAL_SCREEN_WIDTH, QQNX_PHYSICAL_SCREEN_HEIGHT);
- qWarning("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. Falling back to defines QQNX_PHYSICAL_SCREEN_WIDTH/QQNX_PHYSICAL_SCREEN_HEIGHT (%dx%d)", defSize.width(), defSize.height());
+ qWarning("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. Falling back to defines "
+ "QQNX_PHYSICAL_SCREEN_WIDTH/QQNX_PHYSICAL_SCREEN_HEIGHT (%dx%d)",
+ defSize.width(), defSize.height());
return defSize;
#else
if (primaryScreen)
- qFatal("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. Could not determine physical screen size.");
+ qFatal("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. "
+ "Could not determine physical screen size.");
return QSize(150, 90);
#endif
}
@@ -119,7 +126,6 @@ QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display,
m_posted(false),
m_keyboardHeight(0),
m_nativeOrientation(Qt::PrimaryOrientation),
- m_platformContext(0),
m_cursor(new QQnxCursor())
{
qScreenDebug() << Q_FUNC_INFO;
@@ -475,9 +481,14 @@ void QQnxScreen::updateHierarchy()
int topZorder;
errno = 0;
- result = screen_get_window_property_iv(rootWindow()->nativeHandle(), SCREEN_PROPERTY_ZORDER, &topZorder);
- if (result != 0)
- qFatal("QQnxScreen: failed to query root window z-order, errno=%d", errno);
+ if (isPrimaryScreen()) {
+ result = screen_get_window_property_iv(rootWindow()->nativeHandle(), SCREEN_PROPERTY_ZORDER, &topZorder);
+ if (result != 0)
+ qFatal("QQnxScreen: failed to query root window z-order, errno=%d", errno);
+ } else {
+ topZorder = 0; //We do not need z ordering on the secondary screen, because only one window
+ //is supported there
+ }
topZorder++; // root window has the lowest z-order in the windowgroup
diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h
index 6e8c2c6a60..e498d27c14 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.h
+++ b/src/plugins/platforms/qnx/qqnxscreen.h
@@ -133,7 +133,6 @@ private:
Qt::ScreenOrientation m_nativeOrientation;
QRect m_initialGeometry;
QRect m_currentGeometry;
- QPlatformOpenGLContext *m_platformContext;
QList<QQnxWindow *> m_childWindows;
QList<screen_window_t> m_overlays;
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index c2d0e3e41c..c869d29c99 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -469,8 +469,14 @@ void QQnxScreenEventHandler::handleDisplayEvent(screen_event_t event)
qScreenEventDebug() << Q_FUNC_INFO << "display attachment is now:" << isAttached;
QQnxScreen *screen = m_qnxIntegration->screenForNative(nativeDisplay);
+
if (!screen) {
if (isAttached) {
+ int val[2];
+ screen_get_display_property_iv(nativeDisplay, SCREEN_PROPERTY_SIZE, val);
+ if (val[0] == 0 && val[1] == 0) //If screen size is invalid, wait for the next event
+ return;
+
qScreenEventDebug() << "creating new QQnxScreen for newly attached display";
m_qnxIntegration->createDisplay(nativeDisplay, false /* not primary, we assume */);
}
diff --git a/src/plugins/platforms/qnx/qqnxtheme.cpp b/src/plugins/platforms/qnx/qqnxtheme.cpp
index 733b7223b6..37c1079441 100644
--- a/src/plugins/platforms/qnx/qqnxtheme.cpp
+++ b/src/plugins/platforms/qnx/qqnxtheme.cpp
@@ -58,10 +58,8 @@ QQnxTheme::~QQnxTheme()
bool QQnxTheme::usePlatformNativeDialog(DialogType type) const
{
-#if defined(Q_OS_BLACKBERRY_TABLET)
if (type == QPlatformTheme::FileDialog)
return true;
-#endif
#if !defined(QT_NO_COLORDIALOG)
if (type == QPlatformTheme::ColorDialog)
return false;
@@ -76,10 +74,8 @@ bool QQnxTheme::usePlatformNativeDialog(DialogType type) const
QPlatformDialogHelper *QQnxTheme::createPlatformDialogHelper(DialogType type) const
{
switch (type) {
-#if defined(Q_OS_BLACKBERRY_TABLET)
case QPlatformTheme::FileDialog:
return new QQnxFileDialogHelper(m_integration);
-#endif
#if !defined(QT_NO_COLORDIALOG)
case QPlatformTheme::ColorDialog:
#endif
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 5aa1c970fd..45e565f24f 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -72,13 +72,15 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context)
m_window(0),
m_currentBufferIndex(-1),
m_previousBufferIndex(-1),
-#if !defined(QT_NO_OPENGL)
- m_platformOpenGLContext(0),
-#endif
m_screen(0),
m_parentWindow(0),
m_visible(false),
m_windowState(Qt::WindowNoState),
+#if !defined(QT_NO_OPENGL)
+ m_platformOpenGLContext(0),
+ m_newSurfaceRequested(true),
+ m_eglSurface(EGL_NO_SURFACE),
+#endif
m_requestedBufferSize(window->geometry().size())
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size();
@@ -86,7 +88,11 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context)
// Create child QNX window
errno = 0;
- result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW);
+ if (static_cast<QQnxScreen *>(window->screen()->handle())->isPrimaryScreen()) {
+ result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW);
+ } else {
+ result = screen_create_window(&m_window, m_screenContext);
+ }
if (result != 0)
qFatal("QQnxWindow: failed to create window, errno=%d", errno);
@@ -172,6 +178,11 @@ QQnxWindow::~QQnxWindow()
// Cleanup QNX window and its buffers
screen_destroy_window(m_window);
+
+#if !defined(QT_NO_OPENGL)
+ // Cleanup EGL surface if it exists
+ destroyEGLSurface();
+#endif
}
void QQnxWindow::setGeometry(const QRect &rect)
@@ -180,16 +191,16 @@ void QQnxWindow::setGeometry(const QRect &rect)
#if !defined(QT_NO_OPENGL)
// If this is an OpenGL window we need to request that the GL context updates
- // the EGLsurface on which it is rendering. The surface will be recreated the
- // next time QQnxGLContext::makeCurrent() is called.
+ // the EGLsurface on which it is rendering.
{
// We want the setting of the atomic bool in the GL context to be atomic with
// setting m_requestedBufferSize and therefore extended the scope to include
// that test.
const QMutexLocker locker(&m_mutex);
m_requestedBufferSize = rect.size();
- if (m_platformOpenGLContext != 0 && bufferSize() != rect.size())
- m_platformOpenGLContext->requestSurfaceChange();
+ if (m_platformOpenGLContext != 0 && bufferSize() != rect.size()) {
+ m_newSurfaceRequested.testAndSetRelease(false, true);
+ }
}
#endif
@@ -336,6 +347,9 @@ QSize QQnxWindow::requestedBufferSize() const
void QQnxWindow::adjustBufferSize()
{
+ if (m_parentWindow)
+ return;
+
const QSize windowSize = window()->size();
if (windowSize != bufferSize())
setBufferSize(windowSize);
@@ -514,8 +528,12 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
if (m_screen == platformScreen)
return;
- if (m_screen)
+ if (m_screen) {
+ qWindowDebug() << Q_FUNC_INFO << "Moving window to different screen";
m_screen->removeWindow(this);
+ screen_leave_window_group(m_window);
+ }
+
platformScreen->addWindow(this);
m_screen = platformScreen;
@@ -526,17 +544,20 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
if (result != 0)
qFatal("QQnxWindow: failed to set window display, errno=%d", errno);
- // Add window to display's window group
- errno = 0;
- result = screen_join_window_group(m_window, platformScreen->windowGroupName());
- if (result != 0)
- qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
- Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
- // Only subwindows and tooltips need necessarily be moved to another display with the window.
- if ((window()->type() & Qt::WindowType_Mask) == Qt::SubWindow ||
- (window()->type() & Qt::WindowType_Mask) == Qt::ToolTip)
- childWindow->setScreen(platformScreen);
+ if (m_screen->isPrimaryScreen()) {
+ // Add window to display's window group
+ errno = 0;
+ result = screen_join_window_group(m_window, platformScreen->windowGroupName());
+ if (result != 0)
+ qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
+
+ Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
+ // Only subwindows and tooltips need necessarily be moved to another display with the window.
+ if ((window()->type() & Qt::WindowType_Mask) == Qt::SubWindow ||
+ (window()->type() & Qt::WindowType_Mask) == Qt::ToolTip)
+ childWindow->setScreen(platformScreen);
+ }
}
m_screen->updateHierarchy();
@@ -574,8 +595,18 @@ void QQnxWindow::setParent(const QPlatformWindow *window)
setScreen(m_parentWindow->m_screen);
m_parentWindow->m_childWindows.push_back(this);
+
+ // we don't need any buffers, since
+ // Qt will draw to the parent TLW
+ // backing store.
+ setBufferSize(QSize(1, 1));
} else {
m_screen->addWindow(this);
+
+ // recreate buffers, in case the
+ // window has been reparented and
+ // becomes a TLW
+ adjustBufferSize();
}
m_screen->updateHierarchy();
@@ -634,6 +665,12 @@ void QQnxWindow::setWindowState(Qt::WindowState state)
applyWindowState();
}
+void QQnxWindow::propagateSizeHints()
+{
+ // nothing to do; silence base class warning
+ qWindowDebug() << Q_FUNC_INFO << ": ignored";
+}
+
void QQnxWindow::gainedFocus()
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window();
@@ -699,6 +736,79 @@ void QQnxWindow::minimize()
#endif
}
+#if !defined(QT_NO_OPENGL)
+void QQnxWindow::createEGLSurface()
+{
+ // Fetch the surface size from the window and update
+ // the window's buffers before we create the EGL surface
+ const QSize surfaceSize = requestedBufferSize();
+ if (!surfaceSize.isValid()) {
+ qFatal("QQNX: Trying to create 0 size EGL surface. "
+ "Please set a valid window size before calling QOpenGLContext::makeCurrent()");
+ }
+ setBufferSize(surfaceSize);
+
+ // Post root window, in case it hasn't been posted yet, to make it appear.
+ screen()->onWindowPost(0);
+
+ const EGLint eglSurfaceAttrs[] =
+ {
+ EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
+ EGL_NONE
+ };
+
+ qWindowDebug() << "Creating EGL surface" << platformOpenGLContext()->getEglDisplay()
+ << platformOpenGLContext()->getEglConfig();
+ // Create EGL surface
+ m_eglSurface = eglCreateWindowSurface(platformOpenGLContext()->getEglDisplay()
+ , platformOpenGLContext()->getEglConfig(),
+ (EGLNativeWindowType) m_window, eglSurfaceAttrs);
+ if (m_eglSurface == EGL_NO_SURFACE) {
+ QQnxGLContext::checkEGLError("eglCreateWindowSurface");
+ qFatal("QQNX: failed to create EGL surface, err=%d", eglGetError());
+ }
+}
+
+void QQnxWindow::destroyEGLSurface()
+{
+ // Destroy EGL surface if it exists
+ if (m_eglSurface != EGL_NO_SURFACE) {
+ EGLBoolean eglResult = eglDestroySurface(platformOpenGLContext()->getEglDisplay(), m_eglSurface);
+ if (eglResult != EGL_TRUE)
+ qFatal("QQNX: failed to destroy EGL surface, err=%d", eglGetError());
+ }
+
+ m_eglSurface = EGL_NO_SURFACE;
+}
+
+void QQnxWindow::swapEGLBuffers()
+{
+ qWindowDebug() << Q_FUNC_INFO;
+ // Set current rendering API
+ EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
+ if (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)
+ qFatal("QQNX: failed to swap EGL buffers, err=%d", eglGetError());
+}
+
+EGLSurface QQnxWindow::getSurface()
+{
+ if (m_newSurfaceRequested.testAndSetOrdered(true, false)) {
+ if (m_eglSurface != EGL_NO_SURFACE) {
+ platformOpenGLContext()->doneCurrent();
+ destroyEGLSurface();
+ }
+ createEGLSurface();
+ }
+
+ return m_eglSurface;
+}
+#endif
+
void QQnxWindow::updateZorder(int &topZorder)
{
errno = 0;
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index 63d5dc0979..4fabccf4cb 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -103,6 +103,8 @@ public:
void requestActivateWindow();
void setWindowState(Qt::WindowState state);
+ void propagateSizeHints();
+
void gainedFocus();
QQnxScreen *screen() const { return m_screen; }
@@ -118,6 +120,13 @@ public:
void blitFrom(QQnxWindow *sourceWindow, const QPoint &sourceOffset, const QRegion &targetRegion);
void minimize();
+#if !defined(QT_NO_OPENGL)
+ void createEGLSurface();
+ void destroyEGLSurface();
+ void swapEGLBuffers();
+ EGLSurface getSurface();
+#endif
+
private:
QRect setGeometryHelper(const QRect &rect);
void removeFromParent();
@@ -145,9 +154,6 @@ private:
QRegion m_previousDirty;
QRegion m_scrolled;
-#if !defined(QT_NO_OPENGL)
- QQnxGLContext *m_platformOpenGLContext;
-#endif
QQnxScreen *m_screen;
QList<QQnxWindow*> m_childWindows;
QQnxWindow *m_parentWindow;
@@ -162,6 +168,13 @@ private:
// EGL surface. All of this has to be done from the thread that is calling
// QQnxGLContext::makeCurrent()
mutable QMutex m_mutex;
+
+#if !defined(QT_NO_OPENGL)
+ QQnxGLContext *m_platformOpenGLContext;
+ QAtomicInt m_newSurfaceRequested;
+ EGLSurface m_eglSurface;
+#endif
+
QSize m_requestedBufferSize;
};
diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp
index e5c3269a6c..ffd87af193 100644
--- a/src/plugins/platforms/windows/main.cpp
+++ b/src/plugins/platforms/windows/main.cpp
@@ -105,12 +105,12 @@ QT_BEGIN_NAMESPACE
class QWindowsIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "windows.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "windows.json")
public:
- QPlatformIntegration *create(const QString&, const QStringList&);
+ QPlatformIntegration *create(const QString&, const QStringList&, int &, char **);
};
-QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList, int &, char **)
{
if (system.compare(system, QStringLiteral("windows"), Qt::CaseInsensitive) == 0)
return new QWindowsIntegration(paramList);
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index ae48887a80..dcd3db2d47 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -83,6 +83,7 @@ enum WindowsEventType // Simplify event types
CalculateSize = WindowEventFlag + 16,
FocusInEvent = WindowEventFlag + 17,
FocusOutEvent = WindowEventFlag + 18,
+ WhatsThisEvent = WindowEventFlag + 19,
MouseEvent = MouseEventFlag + 1,
MouseWheelEvent = MouseEventFlag + 2,
CursorEvent = MouseEventFlag + 3,
@@ -199,6 +200,12 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
case WM_CONTEXTMENU:
return QtWindows::ContextMenu;
#endif
+ case WM_SYSCOMMAND:
+#ifndef Q_OS_WINCE
+ if ((wParamIn & 0xfff0) == SC_CONTEXTHELP)
+ return QtWindows::WhatsThisEvent;
+#endif
+ break;
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 37a51e1fec..de0a583e58 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -47,6 +47,7 @@
#include "qtwindowsglobal.h"
#include "qwindowsmime.h"
#include "qwindowsinputcontext.h"
+#include "qwindowstabletsupport.h"
#ifndef QT_NO_ACCESSIBILITY
#include "accessible/qwindowsaccessibility.h"
#endif
@@ -83,6 +84,7 @@ int QWindowsContext::verboseOLE = 0;
int QWindowsContext::verboseInputMethods = 0;
int QWindowsContext::verboseDialogs = 0;
int QWindowsContext::verboseTheming = 0;
+int QWindowsContext::verboseTablet = 0;
// Get verbosity of components from "foo:2,bar:3"
static inline int componentVerbose(const char *v, const char *keyWord)
@@ -259,17 +261,20 @@ struct QWindowsContextPrivate {
QWindowsMimeConverter m_mimeConverter;
QWindowsScreenManager m_screenManager;
QSharedPointer<QWindowCreationContext> m_creationContext;
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+ QScopedPointer<QWindowsTabletSupport> m_tabletSupport;
+#endif
const HRESULT m_oleInitializeResult;
const QByteArray m_eventType;
QWindow *m_lastActiveWindow;
bool m_asyncExpose;
};
-QWindowsContextPrivate::QWindowsContextPrivate() :
- m_systemInfo(0),
- m_oleInitializeResult(OleInitialize(NULL)),
- m_eventType(QByteArrayLiteral("windows_generic_MSG")),
- m_lastActiveWindow(0), m_asyncExpose(0)
+QWindowsContextPrivate::QWindowsContextPrivate()
+ : m_systemInfo(0)
+ , m_oleInitializeResult(OleInitialize(NULL))
+ , m_eventType(QByteArrayLiteral("windows_generic_MSG"))
+ , m_lastActiveWindow(0), m_asyncExpose(0)
{
const QSysInfo::WinVersion ver = QSysInfo::windowsVersion();
#ifndef Q_OS_WINCE
@@ -310,7 +315,13 @@ QWindowsContext::QWindowsContext() :
QWindowsContext::verboseInputMethods = componentVerbose(v, "im");
QWindowsContext::verboseDialogs = componentVerbose(v, "dialogs");
QWindowsContext::verboseTheming = componentVerbose(v, "theming");
+ QWindowsContext::verboseTablet = componentVerbose(v, "tablet");
}
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+ d->m_tabletSupport.reset(QWindowsTabletSupport::create());
+ if (QWindowsContext::verboseTablet)
+ qDebug() << "Tablet support: " << (d->m_tabletSupport.isNull() ? QStringLiteral("None") : d->m_tabletSupport->description());
+#endif
}
QWindowsContext::~QWindowsContext()
@@ -631,6 +642,15 @@ QWindowsScreenManager &QWindowsContext::screenManager()
return d->m_screenManager;
}
+QWindowsTabletSupport *QWindowsContext::tabletSupport() const
+{
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+ return d->m_tabletSupport.data();
+#else
+ return 0;
+#endif
+}
+
/*!
\brief Convenience to create a non-visible, message-only dummy
window for example used as clipboard watcher or for GL.
@@ -864,6 +884,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
}
#ifndef Q_OS_WINCE
case QtWindows::ActivateWindowEvent:
+#ifndef QT_NO_TABLETEVENT
+ if (!d->m_tabletSupport.isNull())
+ d->m_tabletSupport->notifyActivate();
+#endif // !QT_NO_TABLETEVENT
if (platformWindow->testFlag(QWindowsWindow::BlockedByModal))
if (const QWindow *modalWindow = QGuiApplication::modalWindow())
QWindowsWindow::baseWindowOf(modalWindow)->alertWindow();
@@ -873,6 +897,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::ContextMenu:
return handleContextMenuEvent(platformWindow->window(), msg);
#endif
+ case QtWindows::WhatsThisEvent: {
+#ifndef QT_NO_WHATSTHIS
+ QWindowSystemInterface::handleEnterWhatsThisEvent();
+ return true;
+#endif
+ } break;
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 6b80075379..0d3476e00f 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE
class QWindow;
class QPlatformScreen;
class QWindowsScreenManager;
+class QWindowsTabletSupport;
class QWindowsWindow;
class QWindowsMimeConverter;
struct QWindowCreationContext;
@@ -135,6 +136,7 @@ public:
static int verboseInputMethods;
static int verboseDialogs;
static int verboseTheming;
+ static int verboseTablet;
explicit QWindowsContext();
~QWindowsContext();
@@ -185,6 +187,7 @@ public:
QWindowsMimeConverter &mimeConverter() const;
QWindowsScreenManager &screenManager();
+ QWindowsTabletSupport *tabletSupport() const;
#ifndef Q_OS_WINCE
static QWindowsUser32DLL user32dll;
static QWindowsShell32DLL shell32dll;
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 27a7044868..354f6700b3 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#define QT_NO_URL_CAST_FROM_STRING 1
+
#include "qwindowsdialoghelpers.h"
#include "qwindowscontext.h"
@@ -651,34 +653,34 @@ public:
QWindowsFileDialogSharedData() : m_data(new Data) {}
void fromOptions(const QSharedPointer<QFileDialogOptions> &o);
- QString directory() const;
- void setDirectory(const QString &);
+ QUrl directory() const;
+ void setDirectory(const QUrl &);
QString selectedNameFilter() const;
void setSelectedNameFilter(const QString &);
- QStringList selectedFiles() const;
- void setSelectedFiles(const QStringList &);
+ QList<QUrl> selectedFiles() const;
+ void setSelectedFiles(const QList<QUrl> &);
QString selectedFile() const;
private:
class Data : public QSharedData {
public:
- QString directory;
+ QUrl directory;
QString selectedNameFilter;
- QStringList selectedFiles;
+ QList<QUrl> selectedFiles;
QMutex mutex;
};
QExplicitlySharedDataPointer<Data> m_data;
};
-inline QString QWindowsFileDialogSharedData::directory() const
+inline QUrl QWindowsFileDialogSharedData::directory() const
{
m_data->mutex.lock();
- const QString result = m_data->directory;
+ const QUrl result = m_data->directory;
m_data->mutex.unlock();
return result;
}
-inline void QWindowsFileDialogSharedData::setDirectory(const QString &d)
+inline void QWindowsFileDialogSharedData::setDirectory(const QUrl &d)
{
QMutexLocker (&m_data->mutex);
m_data->directory = d;
@@ -698,24 +700,24 @@ inline void QWindowsFileDialogSharedData::setSelectedNameFilter(const QString &f
m_data->selectedNameFilter = f;
}
-inline QStringList QWindowsFileDialogSharedData::selectedFiles() const
+inline QList<QUrl> QWindowsFileDialogSharedData::selectedFiles() const
{
m_data->mutex.lock();
- const QStringList result = m_data->selectedFiles;
+ const QList<QUrl> result = m_data->selectedFiles;
m_data->mutex.unlock();
return result;
}
inline QString QWindowsFileDialogSharedData::selectedFile() const
{
- const QStringList files = selectedFiles();
- return files.isEmpty() ? QString() : files.front();
+ const QList<QUrl> files = selectedFiles();
+ return files.isEmpty() ? QString() : files.front().toLocalFile();
}
-inline void QWindowsFileDialogSharedData::setSelectedFiles(const QStringList &f)
+inline void QWindowsFileDialogSharedData::setSelectedFiles(const QList<QUrl> &urls)
{
QMutexLocker (&m_data->mutex);
- m_data->selectedFiles = f;
+ m_data->selectedFiles = urls;
}
inline void QWindowsFileDialogSharedData::fromOptions(const QSharedPointer<QFileDialogOptions> &o)
@@ -822,7 +824,7 @@ public:
virtual void setWindowTitle(const QString &title);
inline void setMode(QFileDialogOptions::FileMode mode, QFileDialogOptions::FileDialogOptions options);
inline void setDirectory(const QString &directory);
- inline void updateDirectory() { setDirectory(m_data.directory()); }
+ inline void updateDirectory() { setDirectory(m_data.directory().toLocalFile()); }
inline QString directory() const;
virtual void exec(HWND owner = 0);
virtual void setNameFilters(const QStringList &f);
@@ -837,10 +839,10 @@ public:
inline void setLabelText(QFileDialogOptions::DialogLabel l, const QString &text);
// Return the selected files for tracking in OnSelectionChanged().
- virtual QStringList selectedFiles() const = 0;
+ virtual QList<QUrl> selectedFiles() const = 0;
// Return the result for tracking in OnFileOk(). Differs from selection for
// example by appended default suffixes, etc.
- virtual QStringList dialogResult() const = 0;
+ virtual QList<QUrl> dialogResult() const = 0;
inline void onFolderChange(IShellItem *);
inline void onSelectionChange();
@@ -848,8 +850,8 @@ public:
inline bool onFileOk();
signals:
- void directoryEntered(const QString& directory);
- void currentChanged(const QString& file);
+ void directoryEntered(const QUrl &directory);
+ void currentChanged(const QUrl &file);
void filterSelected(const QString & filter);
public slots:
@@ -861,9 +863,9 @@ protected:
void setDefaultSuffixSys(const QString &s);
inline IFileDialog * fileDialog() const { return m_fileDialog; }
static QString itemPath(IShellItem *item);
- static QStringList libraryItemFolders(IShellItem *item);
+ static QList<QUrl> libraryItemFolders(IShellItem *item);
static QString libraryItemDefaultSaveFolder(IShellItem *item);
- static int itemPaths(IShellItemArray *items, QStringList *fileResult = 0);
+ static int itemPaths(IShellItemArray *items, QList<QUrl> *fileResult = 0);
static IShellItem *shellItem(const QString &path);
const QWindowsFileDialogSharedData &data() const { return m_data; }
@@ -1031,9 +1033,9 @@ static IShellLibrary *sHLoadLibraryFromItem(IShellItem *libraryItem, DWORD mode)
}
// Return all folders of a library-type item.
-QStringList QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *item)
+QList<QUrl> QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *item)
{
- QStringList result;
+ QList<QUrl> result;
if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) {
IShellItemArray *itemArray = 0;
if (SUCCEEDED(library->GetFolders(LFF_FORCEFILESYSTEM, IID_IShellItemArray, reinterpret_cast<void **>(&itemArray)))) {
@@ -1062,9 +1064,9 @@ QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *i
#else // !Q_OS_WINCE && __IShellLibrary_INTERFACE_DEFINED__
-QStringList QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *)
+QList<QUrl> QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *)
{
- return QStringList();
+ return QList<QUrl>();
}
QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *)
@@ -1096,7 +1098,7 @@ QString QWindowsNativeFileDialogBase::itemPath(IShellItem *item)
}
int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items,
- QStringList *result /* = 0 */)
+ QList<QUrl> *result /* = 0 */)
{
DWORD itemCount = 0;
if (result)
@@ -1108,7 +1110,7 @@ int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items,
for (DWORD i = 0; i < itemCount; ++i) {
IShellItem *item = 0;
if (SUCCEEDED(items->GetItemAt(i, &item)))
- result->push_back(QWindowsNativeFileDialogBase::itemPath(item));
+ result->push_back(QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item)));
}
}
return itemCount;
@@ -1270,7 +1272,7 @@ QString QWindowsNativeFileDialogBase::selectedNameFilter() const
void QWindowsNativeFileDialogBase::onFolderChange(IShellItem *item)
{
if (item) {
- const QString directory = QWindowsNativeFileDialogBase::itemPath(item);
+ const QUrl directory = QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item));
m_data.setDirectory(directory);
emit directoryEntered(directory);
}
@@ -1278,7 +1280,7 @@ void QWindowsNativeFileDialogBase::onFolderChange(IShellItem *item)
void QWindowsNativeFileDialogBase::onSelectionChange()
{
- const QStringList current = selectedFiles();
+ const QList<QUrl> current = selectedFiles();
m_data.setSelectedFiles(current);
if (current.size() == 1)
emit currentChanged(current.front());
@@ -1338,8 +1340,8 @@ public:
explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data)
: QWindowsNativeFileDialogBase(data) {}
virtual void setNameFilters(const QStringList &f);
- virtual QStringList selectedFiles() const;
- virtual QStringList dialogResult() const;
+ virtual QList<QUrl> selectedFiles() const;
+ virtual QList<QUrl> dialogResult() const;
};
// Return the first suffix from the name filter "Foo files (*.foo;*.bar)" -> "foo".
@@ -1374,22 +1376,22 @@ void QWindowsNativeSaveFileDialog::setNameFilters(const QStringList &f)
} // m_hasDefaultSuffix
}
-QStringList QWindowsNativeSaveFileDialog::dialogResult() const
+QList<QUrl> QWindowsNativeSaveFileDialog::dialogResult() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItem *item = 0;
if (SUCCEEDED(fileDialog()->GetResult(&item)) && item)
- result.push_back(QWindowsNativeFileDialogBase::itemPath(item));
+ result.push_back(QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item)));
return result;
}
-QStringList QWindowsNativeSaveFileDialog::selectedFiles() const
+QList<QUrl> QWindowsNativeSaveFileDialog::selectedFiles() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItem *item = 0;
const HRESULT hr = fileDialog()->GetCurrentSelection(&item);
if (SUCCEEDED(hr) && item)
- result.push_back(QWindowsNativeSaveFileDialog::itemPath(item));
+ result.push_back(QUrl::fromLocalFile(QWindowsNativeSaveFileDialog::itemPath(item)));
return result;
}
@@ -1408,26 +1410,26 @@ class QWindowsNativeOpenFileDialog : public QWindowsNativeFileDialogBase
public:
explicit QWindowsNativeOpenFileDialog(const QWindowsFileDialogSharedData &data) :
QWindowsNativeFileDialogBase(data) {}
- virtual QStringList selectedFiles() const;
- virtual QStringList dialogResult() const;
+ virtual QList<QUrl> selectedFiles() const;
+ virtual QList<QUrl> dialogResult() const;
private:
inline IFileOpenDialog *openFileDialog() const
{ return static_cast<IFileOpenDialog *>(fileDialog()); }
};
-QStringList QWindowsNativeOpenFileDialog::dialogResult() const
+QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItemArray *items = 0;
if (SUCCEEDED(openFileDialog()->GetResults(&items)) && items)
QWindowsNativeFileDialogBase::itemPaths(items, &result);
return result;
}
-QStringList QWindowsNativeOpenFileDialog::selectedFiles() const
+QList<QUrl> QWindowsNativeOpenFileDialog::selectedFiles() const
{
- QStringList result;
+ QList<QUrl> result;
IShellItemArray *items = 0;
const HRESULT hr = openFileDialog()->GetSelectedItems(&items);
if (SUCCEEDED(hr) && items)
@@ -1484,14 +1486,13 @@ public:
virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; }
virtual bool defaultNameFilterDisables() const
{ return true; }
- virtual void setDirectory(const QString &directory);
- virtual QString directory() const;
- virtual void selectFile(const QString &filename);
- virtual QStringList selectedFiles() const;
- virtual void setFilter();
- virtual void setNameFilters(const QStringList &filters);
- virtual void selectNameFilter(const QString &filter);
- virtual QString selectedNameFilter() const;
+ virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
+ virtual QUrl directory() const Q_DECL_OVERRIDE;
+ virtual void selectFile(const QUrl &filename) Q_DECL_OVERRIDE;
+ virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+ virtual void setFilter() Q_DECL_OVERRIDE;
+ virtual void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE;
+ virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
private:
virtual QWindowsNativeDialogBase *createNativeDialog();
@@ -1509,10 +1510,10 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
return 0;
QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept()));
QObject::connect(result, SIGNAL(rejected()), this, SIGNAL(reject()));
- QObject::connect(result, SIGNAL(directoryEntered(QString)),
- this, SIGNAL(directoryEntered(QString)));
- QObject::connect(result, SIGNAL(currentChanged(QString)),
- this, SIGNAL(currentChanged(QString)));
+ QObject::connect(result, SIGNAL(directoryEntered(QUrl)),
+ this, SIGNAL(directoryEntered(QUrl)));
+ QObject::connect(result, SIGNAL(currentChanged(QUrl)),
+ this, SIGNAL(currentChanged(QUrl)));
QObject::connect(result, SIGNAL(filterSelected(QString)),
this, SIGNAL(filterSelected(QString)));
@@ -1532,11 +1533,16 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
result->setLabelText(QFileDialogOptions::Accept, opts->labelText(QFileDialogOptions::Accept));
result->updateDirectory();
result->updateSelectedNameFilter();
- const QStringList initialSelection = opts->initiallySelectedFiles();
+ const QList<QUrl> initialSelection = opts->initiallySelectedFiles();
if (initialSelection.size() > 0) {
- QFileInfo info(initialSelection.front());
- if (!info.isDir())
- result->selectFile(info.fileName());
+ const QUrl url = initialSelection.front();
+ if (url.isLocalFile()) {
+ QFileInfo info(url.toLocalFile());
+ if (!info.isDir())
+ result->selectFile(info.fileName());
+ } else {
+ result->selectFile(url.path()); // TODO url.fileName() once it exists
+ }
}
// No need to select initialNameFilter if mode is Dir
if (mode != QFileDialogOptions::Directory && mode != QFileDialogOptions::DirectoryOnly) {
@@ -1550,31 +1556,31 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
return result;
}
-void QWindowsFileDialogHelper::setDirectory(const QString &directory)
+void QWindowsFileDialogHelper::setDirectory(const QUrl &directory)
{
if (QWindowsContext::verboseDialogs)
- qDebug("%s %s" , __FUNCTION__, qPrintable(directory));
+ qDebug("%s %s" , __FUNCTION__, qPrintable(directory.toString()));
m_data.setDirectory(directory);
if (hasNativeDialog())
nativeFileDialog()->updateDirectory();
}
-QString QWindowsFileDialogHelper::directory() const
+QUrl QWindowsFileDialogHelper::directory() const
{
return m_data.directory();
}
-void QWindowsFileDialogHelper::selectFile(const QString &fileName)
+void QWindowsFileDialogHelper::selectFile(const QUrl &fileName)
{
if (QWindowsContext::verboseDialogs)
- qDebug("%s %s" , __FUNCTION__, qPrintable(fileName));
+ qDebug("%s %s" , __FUNCTION__, qPrintable(fileName.toString()));
if (QWindowsNativeFileDialogBase *nfd = nativeFileDialog())
- nfd->selectFile(fileName);
+ nfd->selectFile(fileName.toLocalFile()); // ## should use QUrl::fileName() once it exists
}
-QStringList QWindowsFileDialogHelper::selectedFiles() const
+QList<QUrl> QWindowsFileDialogHelper::selectedFiles() const
{
return m_data.selectedFiles();
}
@@ -1585,14 +1591,6 @@ void QWindowsFileDialogHelper::setFilter()
qDebug("%s" , __FUNCTION__);
}
-void QWindowsFileDialogHelper::setNameFilters(const QStringList &filters)
-{
- if (QWindowsContext::verboseDialogs)
- qDebug("%s" , __FUNCTION__);
- if (QWindowsNativeFileDialogBase *nfd = nativeFileDialog())
- nfd->setNameFilters(filters);
-}
-
void QWindowsFileDialogHelper::selectNameFilter(const QString &filter)
{
m_data.setSelectedNameFilter(filter);
@@ -1643,8 +1641,8 @@ private:
explicit QWindowsXpNativeFileDialog(const OptionsPtr &options, const QWindowsFileDialogSharedData &data);
void populateOpenFileName(OPENFILENAME *ofn, HWND owner) const;
- QStringList execExistingDir(HWND owner);
- QStringList execFileNames(HWND owner, int *selectedFilterIndex) const;
+ QList<QUrl> execExistingDir(HWND owner);
+ QList<QUrl> execFileNames(HWND owner, int *selectedFilterIndex) const;
const OptionsPtr m_options;
QString m_title;
@@ -1683,7 +1681,7 @@ QWindowsXpNativeFileDialog::QWindowsXpNativeFileDialog(const OptionsPtr &options
void QWindowsXpNativeFileDialog::exec(HWND owner)
{
int selectedFilterIndex = -1;
- const QStringList selectedFiles =
+ const QList<QUrl> selectedFiles =
m_options->fileMode() == QFileDialogOptions::DirectoryOnly ?
execExistingDir(owner) : execFileNames(owner, &selectedFilterIndex);
m_data.setSelectedFiles(selectedFiles);
@@ -1695,7 +1693,8 @@ void QWindowsXpNativeFileDialog::exec(HWND owner)
const QStringList nameFilters = m_options->nameFilters();
if (selectedFilterIndex >= 0 && selectedFilterIndex < nameFilters.size())
m_data.setSelectedNameFilter(nameFilters.at(selectedFilterIndex));
- m_data.setDirectory(QFileInfo(selectedFiles.front()).absolutePath());
+ QUrl firstFile = selectedFiles.front();
+ m_data.setDirectory(firstFile.adjusted(QUrl::RemoveFilename));
m_result = QPlatformDialogHelper::Accepted;
emit accepted();
}
@@ -1722,7 +1721,7 @@ int QWindowsXpNativeFileDialog::existingDirCallback(HWND hwnd, UINT uMsg, LPARAM
case BFFM_INITIALIZED: {
if (!m_title.isEmpty())
SetWindowText(hwnd, (wchar_t *)m_title.utf16());
- const QString initialFile = QDir::toNativeSeparators(m_data.directory());
+ const QString initialFile = QDir::toNativeSeparators(m_data.directory().toLocalFile());
if (!initialFile.isEmpty())
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(initialFile.utf16()));
}
@@ -1738,7 +1737,7 @@ int QWindowsXpNativeFileDialog::existingDirCallback(HWND hwnd, UINT uMsg, LPARAM
return 0;
}
-QStringList QWindowsXpNativeFileDialog::execExistingDir(HWND owner)
+QList<QUrl> QWindowsXpNativeFileDialog::execExistingDir(HWND owner)
{
BROWSEINFO bi;
wchar_t initPath[MAX_PATH];
@@ -1750,12 +1749,12 @@ QStringList QWindowsXpNativeFileDialog::execExistingDir(HWND owner)
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE;
bi.lpfn = xpFileDialogGetExistingDirCallbackProc;
bi.lParam = LPARAM(this);
- QStringList selectedFiles;
+ QList<QUrl> selectedFiles;
if (qt_LpItemIdList pItemIDList = SHBrowseForFolder(&bi)) {
wchar_t path[MAX_PATH];
path[0] = 0;
if (SHGetPathFromIDList(pItemIDList, path) && path[0])
- selectedFiles.push_back(QDir::cleanPath(QString::fromWCharArray(path)));
+ selectedFiles.push_back(QUrl::fromLocalFile(QDir::cleanPath(QString::fromWCharArray(path))));
IMalloc *pMalloc;
if (SHGetMalloc(&pMalloc) == NOERROR) {
pMalloc->Free(pItemIDList);
@@ -1807,7 +1806,7 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow
QDir::toNativeSeparators(m_data.selectedFile()).remove(QLatin1Char('<')).
remove(QLatin1Char('>')).remove(QLatin1Char('"')).remove(QLatin1Char('|'));
ofn->lpstrFile = qStringToWCharArray(initiallySelectedFile, ofn->nMaxFile);
- ofn->lpstrInitialDir = qStringToWCharArray(QDir::toNativeSeparators(m_data.directory()));
+ ofn->lpstrInitialDir = qStringToWCharArray(QDir::toNativeSeparators(m_data.directory().toLocalFile()));
ofn->lpstrTitle = (wchar_t*)m_title.utf16();
// Determine lpstrDefExt. Note that the current MSDN docs document this
// member wrong. It should rather be documented as "the default extension
@@ -1832,25 +1831,27 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow
ofn->Flags |= OFN_OVERWRITEPROMPT;
}
-QStringList QWindowsXpNativeFileDialog::execFileNames(HWND owner, int *selectedFilterIndex) const
+QList<QUrl> QWindowsXpNativeFileDialog::execFileNames(HWND owner, int *selectedFilterIndex) const
{
*selectedFilterIndex = -1;
OPENFILENAME ofn;
populateOpenFileName(&ofn, owner);
- QStringList result;
+ QList<QUrl> result;
const bool isSave = m_options->acceptMode() == QFileDialogOptions::AcceptSave;
if (isSave ? m_getSaveFileNameW(&ofn) : m_getOpenFileNameW(&ofn)) {
*selectedFilterIndex = ofn.nFilterIndex - 1;
- result.push_back(QDir::cleanPath(QString::fromWCharArray(ofn.lpstrFile)));
+ const QString dir = QDir::cleanPath(QString::fromWCharArray(ofn.lpstrFile));
+ result.push_back(QUrl::fromLocalFile(dir));
// For multiselection, the first item is the path followed
// by "\0<file1>\0<file2>\0\0".
if (ofn.Flags & (OFN_ALLOWMULTISELECT)) {
- wchar_t *ptr = ofn.lpstrFile + result.front().size() + 1;
+ wchar_t *ptr = ofn.lpstrFile + dir.size() + 1;
if (*ptr) {
- const QString path = result.takeAt(0) + QLatin1Char('/');
+ result.pop_front();
+ const QString path = dir + QLatin1Char('/');
while (*ptr) {
const QString fileName = QString::fromWCharArray(ptr);
- result.push_back(path + fileName);
+ result.push_back(QUrl::fromLocalFile(path + fileName));
ptr += fileName.size() + 1;
} // extract multiple files
} // has multiple files
@@ -1879,14 +1880,13 @@ public:
virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; }
virtual bool defaultNameFilterDisables() const
{ return true; }
- virtual void setDirectory(const QString &directory);
- virtual QString directory() const;
- virtual void selectFile(const QString &filename);
- virtual QStringList selectedFiles() const;
- virtual void setFilter() {}
- virtual void setNameFilters(const QStringList &);
- virtual void selectNameFilter(const QString &);
- virtual QString selectedNameFilter() const;
+ virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
+ virtual QUrl directory() const Q_DECL_OVERRIDE;
+ virtual void selectFile(const QUrl &url) Q_DECL_OVERRIDE;
+ virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+ virtual void setFilter() Q_DECL_OVERRIDE {}
+ virtual void selectNameFilter(const QString &) Q_DECL_OVERRIDE;
+ virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
private:
virtual QWindowsNativeDialogBase *createNativeDialog();
@@ -1907,31 +1907,26 @@ QWindowsNativeDialogBase *QWindowsXpFileDialogHelper::createNativeDialog()
return 0;
}
-void QWindowsXpFileDialogHelper::setDirectory(const QString &directory)
+void QWindowsXpFileDialogHelper::setDirectory(const QUrl &directory)
{
m_data.setDirectory(directory); // Dialog cannot be updated at run-time.
}
-QString QWindowsXpFileDialogHelper::directory() const
+QUrl QWindowsXpFileDialogHelper::directory() const
{
return m_data.directory();
}
-void QWindowsXpFileDialogHelper::selectFile(const QString &filename)
+void QWindowsXpFileDialogHelper::selectFile(const QUrl &url)
{
- m_data.setSelectedFiles(QStringList(filename)); // Dialog cannot be updated at run-time.
+ m_data.setSelectedFiles(QList<QUrl>() << url); // Dialog cannot be updated at run-time.
}
-QStringList QWindowsXpFileDialogHelper::selectedFiles() const
+QList<QUrl> QWindowsXpFileDialogHelper::selectedFiles() const
{
return m_data.selectedFiles();
}
-void QWindowsXpFileDialogHelper::setNameFilters(const QStringList &)
-{
- // Dialog cannot be updated at run-time.
-}
-
void QWindowsXpFileDialogHelper::selectNameFilter(const QString &f)
{
m_data.setSelectedNameFilter(f); // Dialog cannot be updated at run-time.
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index b7ccb5767e..a6bce6502b 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -838,8 +838,6 @@ error:
return i18n_name;
}
-Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
-
static bool addFontToDatabase(const QString &familyName, uchar charSet,
const TEXTMETRIC *textmetric,
const FONTSIGNATURE *signature,
@@ -932,7 +930,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, 0);
if (!englishName.isEmpty())
- qt_registerAliasToFontFamily(familyName, englishName);
+ QPlatformFontDatabase::registerAliasToFontFamily(familyName, englishName);
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
index 7f97d58be4..6037c201ac 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
@@ -122,8 +122,6 @@ static FontFile * createFontFile(const QString &fileName, int index)
extern bool localizedName(const QString &name);
extern QString getEnglishName(const QString &familyName);
-Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
-
static bool addFontToDatabase(const QString &familyName, uchar charSet,
const TEXTMETRIC *textmetric,
const FONTSIGNATURE *signature,
@@ -304,7 +302,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
if (!englishName.isEmpty())
- qt_registerAliasToFontFamily(faceName, englishName);
+ QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName);
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
index c0f1b3a000..7407d88f8b 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
@@ -215,7 +215,9 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di
if (QWindowsContext::verboseFonts)
qDebug("%s %g", __FUNCTION__, pixelSize);
- d->directWriteFactory->AddRef();
+ Q_ASSERT(m_directWriteFontFace);
+
+ m_fontEngineData->directWriteFactory->AddRef();
m_directWriteFontFace->AddRef();
fontDef.pixelSize = pixelSize;
@@ -237,19 +239,17 @@ QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
void QWindowsFontEngineDirectWrite::collectMetrics()
{
- if (m_directWriteFontFace != 0) {
- DWRITE_FONT_METRICS metrics;
-
- m_directWriteFontFace->GetMetrics(&metrics);
- m_unitsPerEm = metrics.designUnitsPerEm;
-
- m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
- m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
- m_descent = DESIGN_TO_LOGICAL(metrics.descent);
- m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
- m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
- m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
- }
+ DWRITE_FONT_METRICS metrics;
+
+ m_directWriteFontFace->GetMetrics(&metrics);
+ m_unitsPerEm = metrics.designUnitsPerEm;
+
+ m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
+ m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
+ m_descent = DESIGN_TO_LOGICAL(metrics.descent);
+ m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
+ m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
+ m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
}
QFixed QWindowsFontEngineDirectWrite::underlinePosition() const
@@ -272,31 +272,24 @@ bool QWindowsFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, ui
{
bool ret = false;
- if (m_directWriteFontFace) {
- DWORD t = qbswap<quint32>(tag);
-
- const void *tableData = 0;
- void *tableContext = 0;
- UINT32 tableSize;
- BOOL exists;
- HRESULT hr = m_directWriteFontFace->TryGetFontTable(
- t, &tableData, &tableSize, &tableContext, &exists
- );
-
- if (SUCCEEDED(hr)) {
- if (exists) {
- if (!buffer) {
- *length = tableSize;
- ret = true;
- } else if (*length >= tableSize) {
- memcpy(buffer, tableData, tableSize);
- ret = true;
- }
- }
- m_directWriteFontFace->ReleaseFontTable(tableContext);
- } else {
- qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
+ const void *tableData = 0;
+ UINT32 tableSize;
+ void *tableContext = 0;
+ BOOL exists;
+ HRESULT hr = m_directWriteFontFace->TryGetFontTable(qbswap<quint32>(tag)
+ &tableData, &tableSize,
+ &tableContext, &exists);
+ if (SUCCEEDED(hr)) {
+ if (exists) {
+ ret = true;
+ if (buffer && *length >= tableSize)
+ memcpy(buffer, tableData, tableSize);
+ else
+ *length = tableSize;
}
+ m_directWriteFontFace->ReleaseFontTable(tableContext);
+ } else {
+ qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
}
return ret;
@@ -327,43 +320,43 @@ inline unsigned int getChar(const QChar *str, int &i, const int len)
bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
int *nglyphs, QFontEngine::ShaperFlags flags) const
{
- if (m_directWriteFontFace != 0) {
- QVarLengthArray<UINT32> codePoints(len);
- for (int i=0; i<len; ++i) {
- codePoints[i] = getChar(str, i, len);
- if (flags & QFontEngine::RightToLeft)
- codePoints[i] = QChar::mirroredChar(codePoints[i]);
- }
+ if (*nglyphs < len) {
+ *nglyphs = len;
+ return false;
+ }
- QVarLengthArray<UINT16> glyphIndices(len);
- HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(),
- len,
- glyphIndices.data());
+ QVarLengthArray<UINT32> codePoints(len);
+ int actualLength = 0;
+ if (flags & QFontEngine::RightToLeft) {
+ for (int i = 0; i < len; ++i)
+ codePoints[actualLength++] = QChar::mirroredChar(getChar(str, i, len));
+ } else {
+ for (int i = 0; i < len; ++i)
+ codePoints[actualLength++] = getChar(str, i, len);
+ }
- if (SUCCEEDED(hr)) {
- for (int i=0; i<len; ++i)
- glyphs->glyphs[i] = glyphIndices[i];
+ QVarLengthArray<UINT16> glyphIndices(actualLength);
+ HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), actualLength,
+ glyphIndices.data());
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
+ return false;
+ }
- *nglyphs = len;
- glyphs->numGlyphs = len;
+ for (int i = 0; i < actualLength; ++i)
+ glyphs->glyphs[i] = glyphIndices.at(i);
- if (!(flags & GlyphIndicesOnly))
- recalcAdvances(glyphs, 0);
+ *nglyphs = actualLength;
+ glyphs->numGlyphs = actualLength;
- return true;
- } else {
- qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
- }
- }
+ if (!(flags & GlyphIndicesOnly))
+ recalcAdvances(glyphs, 0);
- return false;
+ return true;
}
void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const
{
- if (m_directWriteFontFace == 0)
- return;
-
QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs);
// ### Caching?
@@ -391,9 +384,6 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn
void QWindowsFontEngineDirectWrite::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
QPainterPath *path, QTextItem::RenderFlags flags)
{
- if (m_directWriteFontFace == 0)
- return;
-
QVarLengthArray<UINT16> glyphIndices(nglyphs);
QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(nglyphs);
QVarLengthArray<FLOAT> glyphAdvances(nglyphs);
@@ -439,9 +429,6 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(const QGlyphLayout &g
glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(glyph_t g)
{
- if (m_directWriteFontFace == 0)
- return glyph_metrics_t();
-
UINT16 glyphIndex = g;
DWRITE_GLYPH_METRICS glyphMetrics;
@@ -668,14 +655,14 @@ bool QWindowsFontEngineDirectWrite::canRender(const QChar *string, int len)
if (FAILED(hr)) {
qErrnoWarning("%s: GetGlyphIndices failed", __FUNCTION__);
return false;
- } else {
- for (int i=0; i<glyphIndices.size(); ++i) {
- if (glyphIndices.at(i) == 0)
- return false;
- }
+ }
- return true;
+ for (int i = 0; i < actualLength; ++i) {
+ if (glyphIndices.at(i) == 0)
+ return false;
}
+
+ return true;
}
QFontEngine::Type QWindowsFontEngineDirectWrite::type() const
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
index 106087f757..ab14cb49eb 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
@@ -107,8 +107,6 @@ public:
static QString fontNameSubstitute(const QString &familyName);
private:
- friend class QRawFontPrivate;
-
QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
void collectMetrics();
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
new file mode 100644
index 0000000000..4a5d7b5a78
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -0,0 +1,473 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowstabletsupport.h"
+
+#ifndef QT_NO_TABLETEVENT
+
+#include "qwindowscontext.h"
+#include "qwindowskeymapper.h"
+#include "qwindowswindow.h"
+
+#include <qpa/qwindowsysteminterface.h>
+
+#include <QtGui/QTabletEvent>
+#include <QtGui/QScreen>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QWindow>
+#include <QtCore/QDebug>
+#include <QtCore/QScopedArrayPointer>
+#include <QtCore/QtMath>
+
+#include <private/qguiapplication_p.h>
+#include <QtCore/private/qsystemlibrary_p.h>
+
+// Note: The definition of the PACKET structure in pktdef.h depends on this define.
+#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_Z)
+#include <pktdef.h>
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ PacketMode = 0,
+ TabletPacketQSize = 128,
+ DeviceIdMask = 0xFF6, // device type mask && device color mask
+ CursorTypeBitMask = 0x0F06 // bitmask to find the specific cursor type (see Wacom FAQ)
+};
+
+extern "C" LRESULT QT_WIN_CALLBACK qWindowsTabletSupportWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message) {
+ case WT_PROXIMITY:
+ if (QWindowsContext::instance()->tabletSupport()->translateTabletProximityEvent(wParam, lParam))
+ return 0;
+ break;
+ case WT_PACKET:
+ if (QWindowsContext::instance()->tabletSupport()->translateTabletPacketEvent())
+ return 0;
+ break;
+ }
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+
+// Scale tablet coordinates to screen coordinates.
+
+static inline int sign(int x)
+{
+ return x >= 0 ? 1 : -1;
+}
+
+inline QPointF QWindowsTabletDeviceData::scaleCoordinates(int coordX, int coordY, const QRect &targetArea) const
+{
+ const int targetX = targetArea.x();
+ const int targetY = targetArea.y();
+ const int targetWidth = targetArea.width();
+ const int targetHeight = targetArea.height();
+
+ const qreal x = sign(targetWidth) == sign(maxX) ?
+ ((coordX - minX) * qAbs(targetWidth) / qAbs(qreal(maxX - minX))) + targetX :
+ ((qAbs(maxX) - (coordX - minX)) * qAbs(targetWidth) / qAbs(qreal(maxX - minX))) + targetX;
+
+ const qreal y = sign(targetHeight) == sign(maxY) ?
+ ((coordY - minY) * qAbs(targetHeight) / qAbs(qreal(maxY - minY))) + targetY :
+ ((qAbs(maxY) - (coordY - minY)) * qAbs(targetHeight) / qAbs(qreal(maxY - minY))) + targetY;
+
+ return QPointF(x, y);
+}
+
+QWindowsWinTab32DLL QWindowsTabletSupport::m_winTab32DLL;
+
+/*!
+ \class QWindowsWinTab32DLL QWindowsTabletSupport
+ \brief Functions from wintabl32.dll shipped with WACOM tablets used by QWindowsTabletSupport.
+
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+
+bool QWindowsWinTab32DLL::init()
+{
+ if (wTInfo)
+ return true;
+ QSystemLibrary library(QStringLiteral("wintab32"));
+ if (!library.load())
+ return false;
+ wTOpen = (PtrWTOpen)library.resolve("WTOpenW");
+ wTClose = (PtrWTClose)library.resolve("WTClose");
+ wTInfo = (PtrWTInfo)library.resolve("WTInfoW");
+ wTEnable = (PtrWTEnable)library.resolve("WTEnable");
+ wTOverlap = (PtrWTEnable)library.resolve("WTOverlap");
+ wTPacketsGet = (PtrWTPacketsGet)library.resolve("WTPacketsGet");
+ wTGet = (PtrWTGet)library.resolve("WTGetW");
+ wTQueueSizeGet = (PtrWTQueueSizeGet)library.resolve("WTQueueSizeGet");
+ wTQueueSizeSet = (PtrWTQueueSizeSet)library.resolve("WTQueueSizeSet");
+ return wTOpen && wTClose && wTInfo && wTEnable && wTOverlap && wTPacketsGet && wTQueueSizeGet && wTQueueSizeSet;
+}
+
+/*!
+ \class QWindowsTabletSupport
+ \brief Tablet support for Windows.
+
+ Support for WACOM tablets.
+
+ \sa http://www.wacomeng.com/windows/docs/Wintab_v140.htm
+
+ \internal
+ \since 5.2
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsTabletSupport::QWindowsTabletSupport(HWND window, HCTX context)
+ : m_window(window)
+ , m_context(context)
+ , m_tiltSupport(false)
+ , m_currentDevice(-1)
+{
+ AXIS orientation[3];
+ // Some tablets don't support tilt, check if it is possible,
+ if (QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES, DVC_ORIENTATION, &orientation))
+ m_tiltSupport = orientation[0].axResolution && orientation[1].axResolution;
+}
+
+QWindowsTabletSupport::~QWindowsTabletSupport()
+{
+ QWindowsTabletSupport::m_winTab32DLL.wTClose(m_context);
+ DestroyWindow(m_window);
+}
+
+QWindowsTabletSupport *QWindowsTabletSupport::create()
+{
+ if (!m_winTab32DLL.init())
+ return 0;
+ const HWND window = QWindowsContext::instance()->createDummyWindow(QStringLiteral("TabletDummyWindow"),
+ L"TabletDummyWindow",
+ qWindowsTabletSupportWndProc);
+ if (!window) {
+ if (QWindowsContext::verboseTablet)
+ qWarning() << __FUNCTION__ << "Unable to create window for tablet.";
+ return 0;
+ }
+ LOGCONTEXT lcMine;
+ // build our context from the default context
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEFSYSCTX, 0, &lcMine);
+ // Go for the raw coordinates, the tablet event will return good stuff
+ lcMine.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
+ lcMine.lcPktData = lcMine.lcMoveMask = PACKETDATA;
+ lcMine.lcPktMode = PacketMode;
+ lcMine.lcOutOrgX = 0;
+ lcMine.lcOutExtX = lcMine.lcInExtX;
+ lcMine.lcOutOrgY = 0;
+ lcMine.lcOutExtY = -lcMine.lcInExtY;
+ const HCTX context = QWindowsTabletSupport::m_winTab32DLL.wTOpen(window, &lcMine, true);
+ if (!context) {
+ if (QWindowsContext::verboseTablet)
+ qWarning() << __FUNCTION__ << "Unable to open tablet.";
+ DestroyWindow(window);
+ return 0;
+
+ }
+ // Set the size of the Packet Queue to the correct size
+ const int currentQueueSize = QWindowsTabletSupport::m_winTab32DLL.wTQueueSizeGet(context);
+ if (currentQueueSize != TabletPacketQSize) {
+ if (!QWindowsTabletSupport::m_winTab32DLL.wTQueueSizeSet(context, TabletPacketQSize)) {
+ if (!QWindowsTabletSupport::m_winTab32DLL.wTQueueSizeSet(context, currentQueueSize)) {
+ qWarning() << "Unable to set queue size on tablet. The tablet will not work.";
+ QWindowsTabletSupport::m_winTab32DLL.wTClose(context);
+ DestroyWindow(window);
+ return 0;
+ } // cannot restore old size
+ } // cannot set
+ } // mismatch
+ if (QWindowsContext::verboseTablet)
+ qDebug("Opened tablet context %p on window %p, changed packet queue size %d -> %d",
+ context, window, currentQueueSize, TabletPacketQSize);
+ return new QWindowsTabletSupport(window, context);
+}
+
+unsigned QWindowsTabletSupport::options() const
+{
+ UINT result = 0;
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_CTXOPTIONS, &result);
+ return result;
+}
+
+QString QWindowsTabletSupport::description() const
+{
+ const unsigned size = m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, 0);
+ if (!size)
+ return QString();
+ QScopedPointer<TCHAR> winTabId(new TCHAR[size + 1]);
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, winTabId.data());
+ WORD implementationVersion = 0;
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_IMPLVERSION, &implementationVersion);
+ WORD specificationVersion = 0;
+ m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_SPECVERSION, &specificationVersion);
+ const unsigned opts = options();
+ QString result = QString::fromLatin1("%1 specification: v%2.%3 implementation: v%4.%5 options: 0x%6")
+ .arg(QString::fromWCharArray(winTabId.data()))
+ .arg(specificationVersion >> 8).arg(specificationVersion & 0xFF)
+ .arg(implementationVersion >> 8).arg(implementationVersion & 0xFF)
+ .arg(opts, 0, 16);
+ if (opts & CXO_MESSAGES)
+ result += QStringLiteral(" CXO_MESSAGES");
+ if (opts & CXO_CSRMESSAGES)
+ result += QStringLiteral(" CXO_CSRMESSAGES");
+ if (m_tiltSupport)
+ result += QStringLiteral(" tilt");
+ return result;
+}
+
+void QWindowsTabletSupport::notifyActivate()
+{
+ // Cooperate with other tablet applications, but when we get focus, I want to use the tablet.
+ const bool result = QWindowsTabletSupport::m_winTab32DLL.wTEnable(m_context, true)
+ && QWindowsTabletSupport::m_winTab32DLL.wTOverlap(m_context, true);
+ if (QWindowsContext::verboseTablet)
+ qDebug() << __FUNCTION__ << result;
+}
+
+static inline int indexOfDevice(const QVector<QWindowsTabletDeviceData> &devices, qint64 uniqueId)
+{
+ for (int i = 0; i < devices.size(); ++i)
+ if (devices.at(i).uniqueId == uniqueId)
+ return i;
+ return -1;
+}
+
+static inline QTabletEvent::TabletDevice deviceType(const UINT cursorType)
+{
+ if (((cursorType & 0x0006) == 0x0002) && ((cursorType & CursorTypeBitMask) != 0x0902))
+ return QTabletEvent::Stylus;
+ switch (cursorType & CursorTypeBitMask) {
+ case 0x0802:
+ return QTabletEvent::Stylus;
+ case 0x0902:
+ return QTabletEvent::Airbrush;
+ case 0x0004:
+ return QTabletEvent::FourDMouse;
+ case 0x0006:
+ return QTabletEvent::Puck;
+ case 0x0804:
+ return QTabletEvent::RotationStylus;
+ default:
+ break;
+ }
+ return QTabletEvent::NoDevice;
+}
+
+static inline QTabletEvent::PointerType pointerType(unsigned currentCursor)
+{
+ switch (currentCursor % 3) { // %3 for dual track
+ case 0:
+ return QTabletEvent::Cursor;
+ case 1:
+ return QTabletEvent::Pen;
+ case 2:
+ return QTabletEvent::Eraser;
+ default:
+ break;
+ }
+ return QTabletEvent::UnknownPointer;
+}
+
+QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t)
+{
+ d << "TabletDevice id:" << t.uniqueId << " pressure: " << t.minPressure
+ << ".." << t.maxPressure << " tan pressure: " << t.minTanPressure << ".."
+ << t.maxTanPressure << " area:" << t.minX << t.minY <<t.minZ
+ << ".." << t.maxX << t.maxY << t.maxZ << " device " << t.currentDevice
+ << " pointer " << t.currentPointerType;
+ return d;
+}
+
+QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(const quint64 uniqueId, const UINT cursorType) const
+{
+ QWindowsTabletDeviceData result;
+ result.uniqueId = uniqueId;
+ /* browse WinTab's many info items to discover pressure handling. */
+ AXIS axis;
+ LOGCONTEXT lc;
+ /* get the current context for its device variable. */
+ QWindowsTabletSupport::m_winTab32DLL.wTGet(m_context, &lc);
+ /* get the size of the pressure axis. */
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &axis);
+ result.minPressure = int(axis.axMin);
+ result.maxPressure = int(axis.axMax);
+
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES + lc.lcDevice, DVC_TPRESSURE, &axis);
+ result.minTanPressure = int(axis.axMin);
+ result.maxTanPressure = int(axis.axMax);
+
+ LOGCONTEXT defaultLc;
+ /* get default region */
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEFCONTEXT, 0, &defaultLc);
+ result.maxX = int(defaultLc.lcInExtX) - int(defaultLc.lcInOrgX);
+ result.maxY = int(defaultLc.lcInExtY) - int(defaultLc.lcInOrgY);
+ result.maxZ = int(defaultLc.lcInExtZ) - int(defaultLc.lcInOrgZ);
+ result.currentDevice = deviceType(cursorType);
+ return result;
+}
+
+bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, LPARAM lParam)
+{
+ const bool enteredProximity = LOWORD(lParam) != 0;
+ PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
+ const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
+ if (!totalPacks)
+ return false;
+ const UINT currentCursor = proximityBuffer[0].pkCursor;
+ UINT physicalCursorId;
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &physicalCursorId);
+ UINT cursorType;
+ QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_TYPE, &cursorType);
+ const qint64 uniqueId = (qint64(cursorType & DeviceIdMask) << 32L) | qint64(physicalCursorId);
+ // initializing and updating the cursor should be done in response to
+ // WT_CSRCHANGE. We do it in WT_PROXIMITY because some wintab never send
+ // the event WT_CSRCHANGE even if asked with CXO_CSRMESSAGES
+ m_currentDevice = indexOfDevice(m_devices, uniqueId);
+ if (m_currentDevice < 0) {
+ m_currentDevice = m_devices.size();
+ m_devices.push_back(tabletInit(uniqueId, cursorType));
+ }
+ m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor);
+ if (QWindowsContext::verboseTablet)
+ qDebug() << __FUNCTION__ << (enteredProximity ? "enter" : "leave")
+ << " proximity for device #"
+ << m_currentDevice << m_devices.at(m_currentDevice);
+ if (enteredProximity) {
+ QWindowSystemInterface::handleTabletEnterProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ m_devices.at(m_currentDevice).currentPointerType,
+ m_devices.at(m_currentDevice).uniqueId);
+ } else {
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ m_devices.at(m_currentDevice).currentPointerType,
+ m_devices.at(m_currentDevice).uniqueId);
+ }
+ return true;
+}
+
+bool QWindowsTabletSupport::translateTabletPacketEvent()
+{
+ static PACKET localPacketBuf[TabletPacketQSize]; // our own tablet packet queue.
+ const int packetCount = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, TabletPacketQSize, &localPacketBuf);
+ if (!packetCount || m_currentDevice < 0)
+ return false;
+
+ const int currentDevice = m_devices.at(m_currentDevice).currentDevice;
+ const int currentPointer = m_devices.at(m_currentDevice).currentPointerType;
+
+ // When entering proximity, the tablet driver snaps the mouse pointer to the
+ // tablet position scaled to the virtual desktop and keeps it in sync.
+ const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
+
+ if (QWindowsContext::verboseTablet)
+ qDebug() << __FUNCTION__ << "processing " << packetCount
+ << "target:" << QGuiApplicationPrivate::tabletPressTarget;
+
+ const Qt::KeyboardModifiers keyboardModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
+
+ for (int i = 0; i < packetCount ; ++i) {
+ const PACKET &packet = localPacketBuf[i];
+
+ const int z = currentDevice == QTabletEvent::FourDMouse ? int(packet.pkZ) : 0;
+ const QPointF globalPosF = m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea);
+
+ QWindow *target = QGuiApplicationPrivate::tabletPressTarget; // Pass to window that grabbed it.
+ const QPoint globalPos = globalPosF.toPoint();
+ if (!target)
+ if (QPlatformWindow *pw = QWindowsContext::instance()->findPlatformWindowAt(GetDesktopWindow(), globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT))
+ target = pw->window();
+ if (!target)
+ continue;
+
+ const QPoint localPos = target->mapFromGlobal(globalPos);
+
+ const qreal pressureNew = packet.pkButtons && (currentPointer == QTabletEvent::Pen || currentPointer == QTabletEvent::Eraser) ?
+ m_devices.at(m_currentDevice).scalePressure(packet.pkNormalPressure) :
+ qreal(0);
+ const qreal tangentialPressure = currentDevice == QTabletEvent::Airbrush ?
+ m_devices.at(m_currentDevice).scaleTangentialPressure(packet.pkTangentPressure) :
+ qreal(0);
+
+ int tiltX = 0;
+ int tiltY = 0;
+ qreal rotation = 0;
+ if (m_tiltSupport) {
+ // Convert from azimuth and altitude to x tilt and y tilt. What
+ // follows is the optimized version. Here are the equations used:
+ // X = sin(azimuth) * cos(altitude)
+ // Y = cos(azimuth) * cos(altitude)
+ // Z = sin(altitude)
+ // X Tilt = arctan(X / Z)
+ // Y Tilt = arctan(Y / Z)
+ const double radAzim = (packet.pkOrientation.orAzimuth / 10) * (M_PI / 180);
+ const double tanAlt = tan((abs(packet.pkOrientation.orAltitude / 10)) * (M_PI / 180));
+
+ const double degX = atan(sin(radAzim) / tanAlt);
+ const double degY = atan(cos(radAzim) / tanAlt);
+ tiltX = int(degX * (180 / M_PI));
+ tiltY = int(-degY * (180 / M_PI));
+ rotation = packet.pkOrientation.orTwist;
+ }
+
+ if (QWindowsContext::verboseTablet > 1) {
+ qDebug()
+ << "Packet #" << i << '/' << packetCount << "button:" << packet.pkButtons
+ << globalPosF << z << "to:" << target << localPos << "(packet" << packet.pkX
+ << packet.pkY << ") dev:" << currentDevice << "pointer:"
+ << currentPointer << "P:" << pressureNew << "tilt:" << tiltX << ','
+ << tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation;
+ }
+
+ QWindowSystemInterface::handleTabletEvent(target, packet.pkButtons, localPos, globalPosF,
+ currentDevice, currentPointer,
+ pressureNew, tiltX, tiltY,
+ tangentialPressure, rotation, z,
+ m_devices.at(m_currentDevice).uniqueId,
+ keyboardModifiers);
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_TABLETEVENT
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h
new file mode 100644
index 0000000000..12f96b618d
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSTABLETSUPPORT_H
+#define QWINDOWSTABLETSUPPORT_H
+
+#include "qtwindowsglobal.h"
+
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+
+#include <QtCore/QVector>
+#include <QtCore/QPointF>
+
+#include <wintab.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDebug;
+class QWindow;
+class QRect;
+
+struct QWindowsWinTab32DLL
+{
+ QWindowsWinTab32DLL() : wTOpen(0), wTClose(0), wTInfo(0), wTEnable(0), wTOverlap(0), wTPacketsGet(0), wTGet(0),
+ wTQueueSizeGet(0), wTQueueSizeSet(0) {}
+
+ bool init();
+
+ typedef HCTX (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL);
+ typedef BOOL (API *PtrWTClose)(HCTX);
+ typedef UINT (API *PtrWTInfo)(UINT, UINT, LPVOID);
+ typedef BOOL (API *PtrWTEnable)(HCTX, BOOL);
+ typedef BOOL (API *PtrWTOverlap)(HCTX, BOOL);
+ typedef int (API *PtrWTPacketsGet)(HCTX, int, LPVOID);
+ typedef BOOL (API *PtrWTGet)(HCTX, LPLOGCONTEXT);
+ typedef int (API *PtrWTQueueSizeGet)(HCTX);
+ typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int);
+
+ PtrWTOpen wTOpen;
+ PtrWTClose wTClose;
+ PtrWTInfo wTInfo;
+ PtrWTEnable wTEnable;
+ PtrWTOverlap wTOverlap;
+ PtrWTPacketsGet wTPacketsGet;
+ PtrWTGet wTGet;
+ PtrWTQueueSizeGet wTQueueSizeGet;
+ PtrWTQueueSizeSet wTQueueSizeSet;
+};
+
+struct QWindowsTabletDeviceData
+{
+ QWindowsTabletDeviceData() : minPressure(0), maxPressure(0), minTanPressure(0),
+ maxTanPressure(0), minX(0), maxX(0), minY(0), maxY(0), minZ(0), maxZ(0),
+ uniqueId(0), currentDevice(0), currentPointerType(0) {}
+
+ QPointF scaleCoordinates(int coordX, int coordY,const QRect &targetArea) const;
+ qreal scalePressure(qreal p) const { return p / qreal(maxPressure - minPressure); }
+ qreal scaleTangentialPressure(qreal p) const { return p / qreal(maxTanPressure - minTanPressure); }
+
+ int minPressure;
+ int maxPressure;
+ int minTanPressure;
+ int maxTanPressure;
+ int minX, maxX, minY, maxY, minZ, maxZ;
+ qint64 uniqueId;
+ int currentDevice;
+ int currentPointerType;
+};
+
+QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t);
+
+class QWindowsTabletSupport
+{
+ Q_DISABLE_COPY(QWindowsTabletSupport)
+
+ explicit QWindowsTabletSupport(HWND window, HCTX context);
+
+public:
+ ~QWindowsTabletSupport();
+
+ static QWindowsTabletSupport *create();
+
+ void notifyActivate();
+ QString description() const;
+
+ bool translateTabletProximityEvent(WPARAM wParam, LPARAM lParam);
+ bool translateTabletPacketEvent();
+
+private:
+ unsigned options() const;
+ QWindowsTabletDeviceData tabletInit(const quint64 uniqueId, const UINT cursorType) const;
+
+ static QWindowsWinTab32DLL m_winTab32DLL;
+ const HWND m_window;
+ const HCTX m_context;
+ bool m_tiltSupport;
+ QVector<QWindowsTabletDeviceData> m_devices;
+ int m_currentDevice;
+};
+
+QT_END_NAMESPACE
+
+#endif // !QT_NO_TABLETEVENT && !Q_OS_WINCE
+#endif // QWINDOWSTABLETSUPPORT_H
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 0fcd20f7bb..882967d22c 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -404,6 +404,8 @@ void QWindowsTheme::refreshFonts()
const QFont messageBoxFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont);
const QFont statusFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfStatusFont);
const QFont titleFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfCaptionFont);
+ QFont fixedFont(QStringLiteral("Courier New"), messageBoxFont.pointSize());
+ fixedFont.setStyleHint(QFont::TypeWriter);
LOGFONT lfIconTitleFont;
SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
@@ -418,6 +420,7 @@ void QWindowsTheme::refreshFonts()
m_fonts[MdiSubWindowTitleFont] = new QFont(titleFont);
m_fonts[DockWidgetTitleFont] = new QFont(titleFont);
m_fonts[ItemViewFont] = new QFont(iconTitleFont);
+ m_fonts[FixedFont] = new QFont(fixedFont);
if (QWindowsContext::verboseTheming)
qDebug() << __FUNCTION__ << '\n'
@@ -595,7 +598,8 @@ public:
void operator delete (void *) {}
};
-QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const
+QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions) const
{
/* We don't use the variable, but by storing it statically, we
* ensure CoInitialize is only called once. */
@@ -604,6 +608,8 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
static QCache<QString, FakePointer<int> > dirIconEntryCache(1000);
static QMutex mx;
+ static int defaultFolderIIcon = 0;
+ const bool useDefaultFolderIcon = iconOptions & QPlatformTheme::DontUseCustomDirectoryIcons;
QPixmap pixmap;
const QString filePath = QDir::toNativeSeparators(fileInfo.filePath());
@@ -612,7 +618,8 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
bool cacheableDirIcon = fileInfo.isDir() && !fileInfo.isRoot();
if (cacheableDirIcon) {
QMutexLocker locker(&mx);
- int iIcon = **dirIconEntryCache.object(filePath);
+ int iIcon = (useDefaultFolderIcon && defaultFolderIIcon) ? defaultFolderIIcon
+ : **dirIconEntryCache.object(filePath);
if (iIcon) {
QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize), pixmap);
if (pixmap.isNull()) // Let's keep both caches in sync
@@ -629,13 +636,24 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
#else
iconSize|SHGFI_SYSICONINDEX;
#endif // Q_OS_WINCE
- unsigned long val = SHGetFileInfo((const wchar_t *)filePath.utf16(), 0,
- &info, sizeof(SHFILEINFO), flags);
+ unsigned long val = 0;
+ if (cacheableDirIcon && useDefaultFolderIcon) {
+ flags |= SHGFI_USEFILEATTRIBUTES;
+ val = SHGetFileInfo(L"dummy",
+ FILE_ATTRIBUTE_DIRECTORY,
+ &info, sizeof(SHFILEINFO), flags);
+ } else {
+ val = SHGetFileInfo(reinterpret_cast<const wchar_t *>(filePath.utf16()), 0,
+ &info, sizeof(SHFILEINFO), flags);
+ }
// Even if GetFileInfo returns a valid result, hIcon can be empty in some cases
if (val && info.hIcon) {
QString key;
if (cacheableDirIcon) {
+ if (useDefaultFolderIcon && !defaultFolderIIcon)
+ defaultFolderIIcon = info.iIcon;
+
//using the unique icon index provided by windows save us from duplicate keys
key = dirIconPixmapCacheKey(info.iIcon, iconSize);
QPixmapCache::find(key, pixmap);
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index bbd7f4623f..9346621d59 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -68,7 +68,8 @@ public:
{ return m_fonts[type]; }
virtual QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const;
- virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const;
+ virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
+ QPlatformTheme::IconOptions iconOptions = 0) const;
void windowsThemeChanged(QWindow *window);
diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro
index 3aa9caaa0f..d4e6e558ed 100644
--- a/src/plugins/platforms/windows/windows.pro
+++ b/src/plugins/platforms/windows/windows.pro
@@ -102,6 +102,12 @@ contains(QT_CONFIG, opengles2) {
}
}
+!wince*:!contains( DEFINES, QT_NO_TABLETEVENT ) {
+ INCLUDEPATH += ../../../3rdparty/wintab
+ HEADERS += qwindowstabletsupport.h
+ SOURCES += qwindowstabletsupport.cpp
+}
+
contains(QT_CONFIG, freetype) {
DEFINES *= QT_NO_FONTCONFIG
QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype
diff --git a/src/plugins/platforms/xcb/main.cpp b/src/plugins/platforms/xcb/main.cpp
index be5a0e3501..e114827703 100644
--- a/src/plugins/platforms/xcb/main.cpp
+++ b/src/plugins/platforms/xcb/main.cpp
@@ -47,15 +47,15 @@ QT_BEGIN_NAMESPACE
class QXcbIntegrationPlugin : public QPlatformIntegrationPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "xcb.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "xcb.json")
public:
- QPlatformIntegration *create(const QString&, const QStringList&);
+ QPlatformIntegration *create(const QString&, const QStringList&, int &, char **);
};
-QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters)
+QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters, int &argc, char **argv)
{
if (system.toLower() == "xcb")
- return new QXcbIntegration(parameters);
+ return new QXcbIntegration(parameters, argc, argv);
return 0;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 01af23377e..3f717ae2df 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -51,6 +51,7 @@
#include "qxcbwmsupport.h"
#include "qxcbnativeinterface.h"
#include "qxcbintegration.h"
+#include "qxcbsystemtraytracker.h"
#include <QtAlgorithms>
#include <QSocketNotifier>
@@ -262,6 +263,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
, has_xkb(false)
, m_buttons(0)
, m_focusWindow(0)
+ , m_systemTrayTracker(0)
{
#ifdef XCB_USE_XLIB
Display *dpy = XOpenDisplay(m_displayName.constData());
@@ -656,6 +658,11 @@ void QXcbConnection::log(const char *file, int line, int sequence)
void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
{
+ long result = 0;
+ QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance();
+ if (dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->genericEventFilterType(), error, &result))
+ return;
+
uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
@@ -813,6 +820,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
case XCB_UNMAP_NOTIFY:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
+ case XCB_DESTROY_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_destroy_notify_event_t, event, handleDestroyNotifyEvent);
case XCB_CLIENT_MESSAGE:
handleClientMessageEvent((xcb_client_message_event_t *)event);
break;
@@ -1193,6 +1202,8 @@ void QXcbConnection::handleClientMessageEvent(const xcb_client_message_event_t *
drag()->handleFinished(event);
}
#endif
+ if (m_systemTrayTracker && event->type == atom(QXcbAtom::MANAGER))
+ m_systemTrayTracker->notifyManagerClientMessageEvent(event);
QXcbWindow *window = platformWindowFromId(event->window);
if (!window)
@@ -1228,6 +1239,8 @@ static const char * xcb_atomnames = {
"_NET_WM_CONTEXT_HELP\0"
"_NET_WM_SYNC_REQUEST\0"
"_NET_WM_SYNC_REQUEST_COUNTER\0"
+ "MANAGER\0"
+ "_NET_SYSTEM_TRAY_OPCODE\0"
// ICCCM window state
"WM_STATE\0"
@@ -1385,6 +1398,8 @@ static const char * xcb_atomnames = {
"Abs MT Pressure\0"
"Abs MT Tracking ID\0"
"Max Contacts\0"
+ "Rel X\0"
+ "Rel Y\0"
// XInput2 tablet
"Abs X\0"
"Abs Y\0"
@@ -1401,11 +1416,16 @@ static const char * xcb_atomnames = {
"_XSETTINGS_SETTINGS\0" // \0\0 terminates loop.
};
-xcb_atom_t QXcbConnection::atom(QXcbAtom::Atom atom)
+xcb_atom_t QXcbConnection::atom(QXcbAtom::Atom atom) const
{
return m_allAtoms[atom];
}
+QXcbAtom::Atom QXcbConnection::qatom(xcb_atom_t xatom) const
+{
+ return static_cast<QXcbAtom::Atom>(qFind(m_allAtoms, m_allAtoms + QXcbAtom::NAtoms, xatom) - m_allAtoms);
+}
+
void QXcbConnection::initializeAllAtoms() {
const char *names[QXcbAtom::NAtoms];
const char *ptr = xcb_atomnames;
@@ -1721,6 +1741,17 @@ bool QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int o
}
#endif // defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
+QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker()
+{
+ if (!m_systemTrayTracker) {
+ if ( (m_systemTrayTracker = QXcbSystemTrayTracker::create(this)) ) {
+ connect(m_systemTrayTracker, SIGNAL(systemTrayWindowChanged(QScreen*)),
+ QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)));
+ }
+ }
+ return m_systemTrayTracker;
+}
+
QXcbConnectionGrabber::QXcbConnectionGrabber(QXcbConnection *connection)
:m_connection(connection)
{
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 2a5ff0b1cb..aa0e070061 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -87,6 +87,7 @@ class QXcbKeyboard;
class QXcbClipboard;
class QXcbWMSupport;
class QXcbNativeInterface;
+class QXcbSystemTrayTracker;
namespace QXcbAtom {
enum Atom {
@@ -98,6 +99,8 @@ namespace QXcbAtom {
_NET_WM_CONTEXT_HELP,
_NET_WM_SYNC_REQUEST,
_NET_WM_SYNC_REQUEST_COUNTER,
+ MANAGER, // System tray notification
+ _NET_SYSTEM_TRAY_OPCODE, // System tray operation
// ICCCM window state
WM_STATE,
@@ -256,6 +259,8 @@ namespace QXcbAtom {
AbsMTPressure,
AbsMTTrackingID,
MaxContacts,
+ RelX,
+ RelY,
// XInput2 tablet
AbsX,
AbsY,
@@ -319,6 +324,7 @@ public:
virtual void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *) {}
virtual void handleMapNotifyEvent(const xcb_map_notify_event_t *) {}
virtual void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *) {}
+ virtual void handleDestroyNotifyEvent(const xcb_destroy_notify_event_t *) {}
virtual void handleButtonPressEvent(const xcb_button_press_event_t *) {}
virtual void handleButtonReleaseEvent(const xcb_button_release_event_t *) {}
virtual void handleMotionNotifyEvent(const xcb_motion_notify_event_t *) {}
@@ -346,7 +352,8 @@ public:
const QList<QXcbScreen *> &screens() const { return m_screens; }
int primaryScreen() const { return m_primaryScreen; }
- xcb_atom_t atom(QXcbAtom::Atom atom);
+ xcb_atom_t atom(QXcbAtom::Atom atom) const;
+ QXcbAtom::Atom qatom(xcb_atom_t atom) const;
xcb_atom_t internAtom(const char *name);
QByteArray atomName(xcb_atom_t atom);
@@ -430,6 +437,9 @@ public:
void ungrabServer();
QXcbNativeInterface *nativeInterface() const { return m_nativeInterface; }
+
+ QXcbSystemTrayTracker *systemTrayTracker();
+
private slots:
void processXcbEvents();
@@ -478,8 +488,6 @@ private:
};
QHash<int, ValuatorClassInfo> valuatorInfo;
};
- void xi2QueryTabletData(void *dev, TabletData *tabletData); // use no XI stuff in headers
- void xi2SetupTabletDevices();
bool xi2HandleTabletEvent(void *event, TabletData *tabletData);
void xi2ReportTabletEvent(const TabletData &tabletData, void *event);
QVector<TabletData> m_tabletData;
@@ -565,6 +573,7 @@ private:
QXcbWindow *m_focusWindow;
QByteArray m_startupId;
+ QXcbSystemTrayTracker *m_systemTrayTracker;
};
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 991c82eaaa..466193b7a1 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -44,8 +44,8 @@
#include "qxcbwindow.h"
#include "qtouchdevice.h"
#include <qpa/qwindowsysteminterface.h>
-//#define XI2_TOUCH_DEBUG
-#ifdef XI2_TOUCH_DEBUG
+//#define XI2_DEBUG
+#ifdef XI2_DEBUG
#include <QDebug>
#endif
@@ -63,20 +63,19 @@ struct XInput2DeviceData {
}
XIDeviceInfo *xiDeviceInfo;
QTouchDevice *qtTouchDevice;
-};
-#ifndef QT_NO_TABLETEVENT
-static inline bool q_xi2_is_tablet(XIDeviceInfo *dev)
-{
- QByteArray name(dev->name);
- name = name.toLower();
- // Cannot just check for "wacom" because that would also pick up the touch and tablet-button devices.
- return name.contains("stylus") || name.contains("eraser");
-}
-#endif // QT_NO_TABLETEVENT
+ // Stuff that is relevant only for touchpads
+ QHash<int, QPointF> pointPressedPosition; // in screen coordinates where each point was pressed
+ QPointF firstPressedPosition; // in screen coordinates where the first point was pressed
+ QPointF firstPressedNormalPosition; // device coordinates (0 to 1, 0 to 1) where the first point was pressed
+ QSizeF size; // device size in mm
+};
void QXcbConnection::initializeXInput2()
{
+#ifndef QT_NO_TABLETEVENT
+ m_tabletData.clear();
+#endif
Display *xDisplay = static_cast<Display *>(m_xlib_display);
if (XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
int xiMajor = 2;
@@ -88,13 +87,76 @@ void QXcbConnection::initializeXInput2()
m_xi2Enabled = true;
}
if (m_xi2Enabled) {
+#ifdef XI2_DEBUG
+ qDebug("XInput version %d.%d is supported", xiMajor, m_xi2Minor);
+#endif
+ int deviceCount = 0;
+ XIDeviceInfo *devices = XIQueryDevice(xDisplay, XIAllDevices, &deviceCount);
+ for (int i = 0; i < deviceCount; ++i) {
+ // Only non-master pointing devices are relevant here.
+ if (devices[i].use != XISlavePointer)
+ continue;
+#ifdef XI2_DEBUG
+ qDebug() << "input device "<< devices[i].name;
+#endif
#ifndef QT_NO_TABLETEVENT
- // Tablet support: Find the stylus-related devices.
- xi2SetupTabletDevices();
+ TabletData tabletData;
+#endif
+ for (int c = 0; c < devices[i].num_classes; ++c) {
+ switch (devices[i].classes[c]->type) {
+ case XIValuatorClass: {
+ XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(devices[i].classes[c]);
+ const int valuatorAtom = qatom(vci->label);
+#ifdef XI2_DEBUG
+ qDebug() << " has valuator" << atomName(vci->label) << "recognized?" << (valuatorAtom < QXcbAtom::NAtoms);
+#endif
+#ifndef QT_NO_TABLETEVENT
+ if (valuatorAtom < QXcbAtom::NAtoms) {
+ TabletData::ValuatorClassInfo info;
+ info.minVal = vci->min;
+ info.maxVal = vci->max;
+ info.number = vci->number;
+ tabletData.valuatorInfo[valuatorAtom] = info;
+ }
#endif // QT_NO_TABLETEVENT
-#ifdef XI2_TOUCH_DEBUG
- qDebug("XInput version %d.%d is supported", xiMajor, m_xi2Minor);
+ } break;
+ default:
+ break;
+ }
+ }
+ bool isTablet = false;
+#ifndef QT_NO_TABLETEVENT
+ // If we have found the valuators which we expect a tablet to have, assume it's a tablet.
+ if (tabletData.valuatorInfo.contains(QXcbAtom::AbsX) &&
+ tabletData.valuatorInfo.contains(QXcbAtom::AbsY) &&
+ tabletData.valuatorInfo.contains(QXcbAtom::AbsPressure)) {
+ tabletData.deviceId = devices[i].deviceid;
+ tabletData.pointerType = QTabletEvent::Pen;
+ if (QByteArray(devices[i].name).toLower().contains("eraser"))
+ tabletData.pointerType = QTabletEvent::Eraser;
+ m_tabletData.append(tabletData);
+ isTablet = true;
+#ifdef XI2_DEBUG
+ qDebug() << " it's a tablet with pointer type" << tabletData.pointerType;
#endif
+ }
+#endif // QT_NO_TABLETEVENT
+#ifdef XI2_DEBUG
+ if (!isTablet) {
+ XInput2DeviceData *dev = deviceForId(devices[i].deviceid);
+ if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchScreen)
+ qDebug(" it's a touchscreen with type %d capabilities 0x%X max touch points %d",
+ dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
+ dev->qtTouchDevice->maximumTouchPoints());
+ else if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchPad)
+ qDebug(" it's a touchpad with type %d capabilities 0x%X max touch points %d size %f x %f",
+ dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
+ dev->qtTouchDevice->maximumTouchPoints(),
+ dev->size.width(), dev->size.height());
+ }
+#endif // XI2_DEBUG
+ }
+ XIFreeDeviceInfo(devices);
}
}
}
@@ -113,25 +175,24 @@ void QXcbConnection::xi2Select(xcb_window_t window)
unsigned char *xiBitMask = reinterpret_cast<unsigned char *>(&bitMask);
#ifdef XCB_USE_XINPUT22
- // Select touch events on all master devices indiscriminately.
bitMask |= XI_TouchBeginMask;
bitMask |= XI_TouchUpdateMask;
bitMask |= XI_TouchEndMask;
XIEventMask mask;
- mask.deviceid = XIAllMasterDevices;
mask.mask_len = sizeof(bitMask);
mask.mask = xiBitMask;
- Status result = XISelectEvents(xDisplay, window, &mask, 1);
- // If we have XInput 2.2 and successfully enable touch on the master
- // devices, then evdev touchscreens will provide touch only. In most other
- // cases, there will be emulated mouse events, because true X11 touch
- // support is so new that for the older drivers, mouse emulation was the
- // only way; and it's still the fallback even with the modern evdev driver.
- // But if neither Qt nor X11 does mouse emulation, it will not be possible
- // to interact with mouse-oriented QWidgets; so we have to let Qt do it.
- if (m_xi2Minor >= 2 && result == Success)
- has_touch_without_mouse_emulation = true;
-#endif
+ // Enable each touchscreen
+ foreach (XInput2DeviceData *dev, m_touchDevices.values()) {
+ mask.deviceid = dev->xiDeviceInfo->deviceid;
+ Status result = XISelectEvents(xDisplay, window, &mask, 1);
+ // If we have XInput >= 2.2 and successfully enable a touchscreen, then
+ // it will provide touch only. In most other cases, there will be
+ // emulated mouse events from the driver. If not, then Qt must do its
+ // own mouse emulation to enable interaction with mouse-oriented QWidgets.
+ if (m_xi2Minor >= 2 && result == Success)
+ has_touch_without_mouse_emulation = true;
+ }
+#endif // XCB_USE_XINPUT22
#ifndef QT_NO_TABLETEVENT
// For each tablet, select some additional event types.
@@ -163,23 +224,29 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
QTouchDevice::Capabilities caps = 0;
dev = new XInput2DeviceData;
dev->xiDeviceInfo = XIQueryDevice(static_cast<Display *>(m_xlib_display), id, &unused);
- dev->qtTouchDevice = new QTouchDevice;
+ int type = -1;
+ int maxTouchPoints = 1;
+ bool hasRelativeCoords = false;
for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) {
XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i];
switch (classinfo->type) {
#ifdef XCB_USE_XINPUT22
case XITouchClass: {
XITouchClassInfo *tci = reinterpret_cast<XITouchClassInfo *>(classinfo);
+ maxTouchPoints = tci->num_touches;
+#ifdef XI2_DEBUG
+ qDebug(" has touch class with mode %d", tci->mode);
+#endif
switch (tci->mode) {
case XIModeRelative:
- dev->qtTouchDevice->setType(QTouchDevice::TouchPad);
+ type = QTouchDevice::TouchPad;
break;
case XIModeAbsolute:
- dev->qtTouchDevice->setType(QTouchDevice::TouchScreen);
+ type = QTouchDevice::TouchScreen;
break;
}
} break;
-#endif
+#endif // XCB_USE_XINPUT22
case XIValuatorClass: {
XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classinfo);
if (vci->label == atom(QXcbAtom::AbsMTPositionX))
@@ -188,18 +255,36 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
caps |= QTouchDevice::Area;
else if (vci->label == atom(QXcbAtom::AbsMTPressure) || vci->label == atom(QXcbAtom::AbsPressure))
caps |= QTouchDevice::Pressure;
+ else if (vci->label == atom(QXcbAtom::RelX)) {
+ hasRelativeCoords = true;
+ dev->size.setWidth((vci->max - vci->min) * 1000.0 / vci->resolution);
+ } else if (vci->label == atom(QXcbAtom::RelY)) {
+ hasRelativeCoords = true;
+ dev->size.setHeight((vci->max - vci->min) * 1000.0 / vci->resolution);
+ }
} break;
}
}
- dev->qtTouchDevice->setCapabilities(caps);
- dev->qtTouchDevice->setName(dev->xiDeviceInfo->name);
- if (caps != 0)
- QWindowSystemInterface::registerTouchDevice(dev->qtTouchDevice);
-#ifdef XI2_TOUCH_DEBUG
- qDebug("registered new device %s with %d classes and %d max touch points",
- dev->xiDeviceInfo->name, dev->xiDeviceInfo->num_classes, dev->qtTouchDevice->maxTouchPoints());
-#endif
- m_touchDevices[id] = dev;
+ if (type < 0 && caps && hasRelativeCoords) {
+ type = QTouchDevice::TouchPad;
+ if (dev->size.width() < 10 || dev->size.height() < 10 ||
+ dev->size.width() > 10000 || dev->size.height() > 10000)
+ dev->size = QSizeF(130, 110);
+ }
+ if (type >= QTouchDevice::TouchScreen && type <= QTouchDevice::TouchPad) {
+ dev->qtTouchDevice = new QTouchDevice;
+ dev->qtTouchDevice->setName(dev->xiDeviceInfo->name);
+ dev->qtTouchDevice->setType((QTouchDevice::DeviceType)type);
+ dev->qtTouchDevice->setCapabilities(caps);
+ dev->qtTouchDevice->setMaximumTouchPoints(maxTouchPoints);
+ if (caps != 0)
+ QWindowSystemInterface::registerTouchDevice(dev->qtTouchDevice);
+ m_touchDevices[id] = dev;
+ } else {
+ m_touchDevices.remove(id);
+ delete dev;
+ dev = 0;
+ }
}
return dev;
}
@@ -218,7 +303,7 @@ static qreal valuatorNormalized(double value, XIValuatorClassInfo *vci)
value = vci->min;
return (value - vci->min) / (vci->max - vci->min);
}
-#endif
+#endif // XCB_USE_XINPUT22
void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
{
@@ -237,7 +322,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
#ifdef XCB_USE_XINPUT22
if (xiEvent->evtype == XI_TouchBegin || xiEvent->evtype == XI_TouchUpdate || xiEvent->evtype == XI_TouchEnd) {
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
-#ifdef XI2_TOUCH_DEBUG
+#ifdef XI2_DEBUG
qDebug("XI2 event type %d seq %d detail %d pos 0x%X,0x%X %f,%f root pos %f,%f",
event->event_type, xiEvent->sequenceNumber, xiDeviceEvent->detail,
xiDeviceEvent->event_x, xiDeviceEvent->event_y,
@@ -247,6 +332,8 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
XInput2DeviceData *dev = deviceForId(xiEvent->deviceid);
+ Q_ASSERT(dev);
+ const bool firstTouch = m_touchPoints.isEmpty();
if (xiEvent->evtype == XI_TouchBegin) {
QWindowSystemInterface::TouchPoint tp;
tp.id = xiDeviceEvent->detail % INT_MAX;
@@ -267,11 +354,15 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
double value;
if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value))
continue;
-#ifdef XI2_TOUCH_DEBUG
- qDebug(" valuator class label %d value %lf from range %lf -> %lf name %s",
- vci->label, value, vci->min, vci->max, XGetAtomName(static_cast<Display *>(m_xlib_display), vci->label) );
+#ifdef XI2_DEBUG
+ qDebug(" valuator %20s value %lf from range %lf -> %lf",
+ atomName(vci->label).constData(), value, vci->min, vci->max );
#endif
- if (vci->label == atom(QXcbAtom::AbsMTPositionX)) {
+ if (vci->label == atom(QXcbAtom::RelX)) {
+ nx = valuatorNormalized(value, vci);
+ } else if (vci->label == atom(QXcbAtom::RelY)) {
+ ny = valuatorNormalized(value, vci);
+ } else if (vci->label == atom(QXcbAtom::AbsMTPositionX)) {
nx = valuatorNormalized(value, vci);
} else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) {
ny = valuatorNormalized(value, vci);
@@ -306,19 +397,45 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
switch (xiEvent->evtype) {
+ case XI_TouchBegin:
+ if (firstTouch) {
+ dev->firstPressedPosition = QPointF(x, y);
+ dev->firstPressedNormalPosition = QPointF(nx, ny);
+ }
+ dev->pointPressedPosition.insert(touchPoint.id, QPointF(x, y));
+ break;
case XI_TouchUpdate:
- if (touchPoint.area.center() != QPoint(x, y))
+ if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) {
+ qreal dx = (nx - dev->firstPressedNormalPosition.x()) *
+ dev->size.width() * screen->geometry().width() / screen->physicalSize().width();
+ qreal dy = (ny - dev->firstPressedNormalPosition.y()) *
+ dev->size.height() * screen->geometry().height() / screen->physicalSize().height();
+ x = dev->firstPressedPosition.x() + dx;
+ y = dev->firstPressedPosition.y() + dy;
+ touchPoint.state = Qt::TouchPointMoved;
+ } else if (touchPoint.area.center() != QPoint(x, y)) {
touchPoint.state = Qt::TouchPointMoved;
+ dev->pointPressedPosition[touchPoint.id] = QPointF(x, y);
+ }
else
touchPoint.state = Qt::TouchPointStationary;
break;
case XI_TouchEnd:
touchPoint.state = Qt::TouchPointReleased;
+ if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) {
+ qreal dx = (nx - dev->firstPressedNormalPosition.x()) *
+ dev->size.width() * screen->geometry().width() / screen->physicalSize().width();
+ qreal dy = (ny - dev->firstPressedNormalPosition.y()) *
+ dev->size.width() * screen->geometry().width() / screen->physicalSize().width();
+ x = dev->firstPressedPosition.x() + dx;
+ y = dev->firstPressedPosition.y() + dy;
+ }
+ dev->pointPressedPosition.remove(touchPoint.id);
}
touchPoint.area = QRectF(x - w/2, y - h/2, w, h);
touchPoint.normalPosition = QPointF(nx, ny);
-#ifdef XI2_TOUCH_DEBUG
+#ifdef XI2_DEBUG
qDebug() << " tp " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition <<
" area " << touchPoint.area << " pressure " << touchPoint.pressure;
#endif
@@ -328,80 +445,11 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
m_touchPoints.remove(touchPoint.id);
}
}
-#endif
+#endif // XCB_USE_XINPUT22
}
}
#ifndef QT_NO_TABLETEVENT
-void QXcbConnection::xi2QueryTabletData(void *dev, TabletData *tabletData)
-{
- XIDeviceInfo *device = static_cast<XIDeviceInfo *>(dev);
- tabletData->deviceId = device->deviceid;
-
- tabletData->pointerType = QTabletEvent::Pen;
- if (QByteArray(device->name).toLower().contains("eraser"))
- tabletData->pointerType = QTabletEvent::Eraser;
-
- for (int i = 0; i < device->num_classes; ++i) {
- switch (device->classes[i]->type) {
- case XIValuatorClass: {
- XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(device->classes[i]);
- int val = 0;
- if (vci->label == atom(QXcbAtom::AbsX))
- val = QXcbAtom::AbsX;
- else if (vci->label == atom(QXcbAtom::AbsY))
- val = QXcbAtom::AbsY;
- else if (vci->label == atom(QXcbAtom::AbsPressure))
- val = QXcbAtom::AbsPressure;
- else if (vci->label == atom(QXcbAtom::AbsTiltX))
- val = QXcbAtom::AbsTiltX;
- else if (vci->label == atom(QXcbAtom::AbsTiltY))
- val = QXcbAtom::AbsTiltY;
- else if (vci->label == atom(QXcbAtom::AbsWheel))
- val = QXcbAtom::AbsWheel;
- else if (vci->label == atom(QXcbAtom::AbsDistance))
- val = QXcbAtom::AbsDistance;
- if (val) {
- TabletData::ValuatorClassInfo info;
- info.minVal = vci->min;
- info.maxVal = vci->max;
- info.number = vci->number;
- tabletData->valuatorInfo[val] = info;
- }
- }
- break;
- default:
- break;
- }
- }
-}
-
-void QXcbConnection::xi2SetupTabletDevices()
-{
- Display *xDisplay = static_cast<Display *>(m_xlib_display);
- m_tabletData.clear();
- int deviceCount = 0;
- XIDeviceInfo *devices = XIQueryDevice(xDisplay, XIAllDevices, &deviceCount);
- if (devices) {
- for (int i = 0; i < deviceCount; ++i) {
- int unused = 0;
- XIDeviceInfo *dev = XIQueryDevice(xDisplay, devices[i].deviceid, &unused);
- if (dev) {
- if (q_xi2_is_tablet(dev)) {
- TabletData tabletData;
- xi2QueryTabletData(dev, &tabletData);
-#ifdef XI2_TOUCH_DEBUG
- qDebug() << "found tablet" << dev->name;
-#endif
- m_tabletData.append(tabletData);
- }
- XIFreeDeviceInfo(dev);
- }
- }
- XIFreeDeviceInfo(devices);
- }
-}
-
bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
{
bool handled = true;
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index cf7e99023a..68ad93143b 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -119,9 +119,10 @@ static bool runningUnderDebugger()
}
#endif
-QXcbIntegration::QXcbIntegration(const QStringList &parameters)
+QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char **argv)
: m_eventDispatcher(createUnixEventDispatcher())
, m_services(new QGenericUnixServices)
+ , m_instanceName(0)
{
QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
@@ -138,7 +139,28 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters)
if (canNotGrabEnv)
canGrab = false;
- m_connections << new QXcbConnection(m_nativeInterface.data(), canGrab);
+ // Parse arguments
+ const char *displayName = 0;
+ if (argc) {
+ int j = 1;
+ for (int i = 1; i < argc; i++) {
+ char *arg = argv[i];
+ if (arg) {
+ if (!strcmp(arg, "-display") && i < argc - 1) {
+ displayName = argv[++i];
+ arg = 0;
+ } else if (!strcmp(arg, "-name") && i < argc - 1) {
+ m_instanceName = argv[++i];
+ arg = 0;
+ }
+ }
+ if (arg)
+ argv[j++] = arg;
+ }
+ argc = j;
+ } // argc
+
+ m_connections << new QXcbConnection(m_nativeInterface.data(), canGrab, displayName);
for (int i = 0; i < parameters.size() - 1; i += 2) {
#ifdef Q_XCB_DEBUG
@@ -365,6 +387,8 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
case QPlatformIntegration::SynthesizeMouseFromTouchEvents:
// We do not want Qt to synthesize mouse events if X11 already does it.
return m_connections.at(0)->hasTouchWithoutMouseEmulation();
+ default:
+ break;
}
return QPlatformIntegration::styleHint(hint);
}
@@ -389,6 +413,8 @@ QByteArray QXcbIntegration::wmClass() const
if (m_wmClass.isEmpty()) {
// Instance name according to ICCCM 4.1.2.5
QString name;
+ if (m_instanceName)
+ name = QString::fromLocal8Bit(m_instanceName);
if (name.isEmpty() && qEnvironmentVariableIsSet(resourceNameVar))
name = QString::fromLocal8Bit(qgetenv(resourceNameVar));
if (name.isEmpty())
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 07b6b8d678..09fc0d32b5 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -55,7 +55,7 @@ class QXcbScreen;
class QXcbIntegration : public QPlatformIntegration
{
public:
- QXcbIntegration(const QStringList &parameters);
+ QXcbIntegration(const QStringList &parameters, int &argc, char **argv);
~QXcbIntegration();
QPlatformWindow *createPlatformWindow(QWindow *window) const;
@@ -119,6 +119,7 @@ private:
friend class QXcbConnection; // access QPlatformIntegration::screenAdded()
mutable QByteArray m_wmClass;
+ const char *m_instanceName;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index d1729ed168..2529fb8a83 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -243,6 +243,10 @@
#define XF86XK_Select 0x1008FFA0
#define XF86XK_View 0x1008FFA1
#define XF86XK_TopMenu 0x1008FFA2
+#define XF86XK_Red 0x1008FFA3
+#define XF86XK_Green 0x1008FFA4
+#define XF86XK_Yellow 0x1008FFA5
+#define XF86XK_Blue 0x1008FFA6
#define XF86XK_Suspend 0x1008FFA7
#define XF86XK_Hibernate 0x1008FFA8
#define XF86XK_TouchpadToggle 0x1008FFA9
@@ -538,6 +542,10 @@ static const unsigned int KeyTbl[] = {
XF86XK_Select, Qt::Key_Select,
XF86XK_View, Qt::Key_View,
XF86XK_TopMenu, Qt::Key_TopMenu,
+ XF86XK_Red, Qt::Key_Red,
+ XF86XK_Green, Qt::Key_Green,
+ XF86XK_Yellow, Qt::Key_Yellow,
+ XF86XK_Blue, Qt::Key_Blue,
XF86XK_Bluetooth, Qt::Key_Bluetooth,
XF86XK_Suspend, Qt::Key_Suspend,
XF86XK_Hibernate, Qt::Key_Hibernate,
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 9e9fd2914f..99e9932847 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -42,7 +42,9 @@
#include "qxcbnativeinterface.h"
#include "qxcbscreen.h"
+#include "qxcbwindow.h"
#include "qxcbintegration.h"
+#include "qxcbsystemtraytracker.h"
#include <private/qguiapplication_p.h>
#include <QtCore/QMap>
@@ -82,6 +84,8 @@ public:
insert("appusertime",QXcbNativeInterface::AppUserTime);
insert("hintstyle", QXcbNativeInterface::ScreenHintStyle);
insert("startupid", QXcbNativeInterface::StartupId);
+ insert(QByteArrayLiteral("traywindow"), QXcbNativeInterface::TrayWindow);
+ insert(QByteArrayLiteral("gettimestamp"), QXcbNativeInterface::GetTimestamp);
}
};
@@ -100,6 +104,36 @@ void QXcbNativeInterface::beep() // For QApplication::beep()
xcb_bell(connection, 0);
}
+static inline QXcbSystemTrayTracker *systemTrayTracker(const QScreen *s)
+{
+ return static_cast<const QXcbScreen *>(s->handle())->connection()->systemTrayTracker();
+}
+
+bool QXcbNativeInterface::systemTrayAvailable(const QScreen *screen) const
+{
+ return systemTrayTracker(screen);
+}
+
+bool QXcbNativeInterface::requestSystemTrayWindowDock(const QWindow *window)
+{
+ const QPlatformWindow *platformWindow = window->handle();
+ if (!platformWindow)
+ return false;
+ QXcbSystemTrayTracker *trayTracker = systemTrayTracker(window->screen());
+ if (!trayTracker)
+ return false;
+ trayTracker->requestSystemTrayWindowDock(static_cast<const QXcbWindow *>(platformWindow)->xcb_window());
+ return true;
+}
+
+QRect QXcbNativeInterface::systemTrayWindowGlobalGeometry(const QWindow *window)
+{
+ if (const QPlatformWindow *platformWindow = window->handle())
+ if (const QXcbSystemTrayTracker *trayTracker = systemTrayTracker(window->screen()))
+ return trayTracker->systemTrayWindowGlobalGeometry(static_cast<const QXcbWindow *>(platformWindow)->xcb_window());
+ return QRect();
+}
+
void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString)
{
QByteArray lowerCaseResource = resourceString.toLower();
@@ -162,6 +196,14 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q
break;
case ScreenHintStyle:
result = reinterpret_cast<void *>(xcbScreen->hintStyle() + 1);
+ break;
+ case TrayWindow:
+ if (QXcbSystemTrayTracker *s = systemTrayTracker(screen))
+ result = (void *)quintptr(s->trayWindow());
+ break;
+ case GetTimestamp:
+ result = getTimestamp(xcbScreen);
+ break;
default:
break;
}
@@ -216,6 +258,11 @@ void *QXcbNativeInterface::appUserTime(const QXcbScreen *screen)
return reinterpret_cast<void *>(quintptr(screen->connection()->netWmUserTime()));
}
+void *QXcbNativeInterface::getTimestamp(const QXcbScreen *screen)
+{
+ return reinterpret_cast<void *>(quintptr(screen->connection()->getTimestamp()));
+}
+
void *QXcbNativeInterface::startupId()
{
QXcbIntegration* integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index e27bfa5a46..86b94e62e4 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -45,6 +45,8 @@
#include <qpa/qplatformnativeinterface.h>
#include <xcb/xcb.h>
+#include <QtCore/QRect>
+
QT_BEGIN_NAMESPACE
class QWidget;
@@ -66,7 +68,9 @@ public:
AppTime,
AppUserTime,
ScreenHintStyle,
- StartupId
+ StartupId,
+ TrayWindow,
+ GetTimestamp
};
QXcbNativeInterface();
@@ -88,6 +92,7 @@ public:
void *graphicsDeviceForWindow(QWindow *window);
void *appTime(const QXcbScreen *screen);
void *appUserTime(const QXcbScreen *screen);
+ void *getTimestamp(const QXcbScreen *screen);
void *startupId();
static void setAppTime(QScreen *screen, xcb_timestamp_t time);
static void setAppUserTime(QScreen *screen, xcb_timestamp_t time);
@@ -95,6 +100,12 @@ public:
static void *glxContextForContext(QOpenGLContext *context);
Q_INVOKABLE void beep();
+ Q_INVOKABLE bool systemTrayAvailable(const QScreen *screen) const;
+ Q_INVOKABLE bool requestSystemTrayWindowDock(const QWindow *window);
+ Q_INVOKABLE QRect systemTrayWindowGlobalGeometry(const QWindow *window);
+
+signals:
+ void systemTrayWindowChanged(QScreen *screen);
private:
const QByteArray m_genericEventFilterType;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 37c6c97bc4..0971b6ca8e 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -112,6 +112,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
XCB_EVENT_MASK_ENTER_WINDOW
| XCB_EVENT_MASK_LEAVE_WINDOW
| XCB_EVENT_MASK_PROPERTY_CHANGE
+ | XCB_EVENT_MASK_STRUCTURE_NOTIFY // for the "MANAGER" atom (system tray notification).
};
xcb_change_window_attributes(xcb_connection(), screen()->root, mask, values);
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
new file mode 100644
index 0000000000..24d2feb106
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbsystemtraytracker.h"
+#include "qxcbconnection.h"
+#include "qxcbscreen.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QRect>
+#include <QtGui/QScreen>
+
+#include <qpa/qplatformnativeinterface.h>
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ SystemTrayRequestDock = 0,
+ SystemTrayBeginMessage = 1,
+ SystemTrayCancelMessage = 2
+};
+
+// QXcbSystemTrayTracker provides API for accessing the tray window and tracks
+// its lifecyle by listening for its destruction and recreation.
+// See http://standards.freedesktop.org/systemtray-spec/systemtray-spec-latest.html
+
+QXcbSystemTrayTracker *QXcbSystemTrayTracker::create(QXcbConnection *connection)
+{
+ // Selection, tray atoms for GNOME, NET WM Specification
+ const xcb_atom_t trayAtom = connection->atom(QXcbAtom::_NET_SYSTEM_TRAY_OPCODE);
+ if (!trayAtom)
+ return 0;
+ const QByteArray netSysTray = QByteArrayLiteral("_NET_SYSTEM_TRAY_S") + QByteArray::number(connection->primaryScreen());
+ const xcb_atom_t selection = connection->internAtom(netSysTray.constData());
+ if (!selection)
+ return 0;
+ return new QXcbSystemTrayTracker(connection, trayAtom, selection, connection);
+}
+
+QXcbSystemTrayTracker::QXcbSystemTrayTracker(QXcbConnection *connection,
+ xcb_atom_t trayAtom,
+ xcb_atom_t selection,
+ QObject *parent)
+ : QObject(parent)
+ , m_selection(selection)
+ , m_trayAtom(trayAtom)
+ , m_connection(connection)
+ , m_trayWindow(0)
+{
+}
+
+xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *connection, xcb_atom_t selection)
+{
+ xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(connection->xcb_connection(), selection);
+ xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(connection->xcb_connection(), cookie, 0);
+ if (!reply)
+ return 0;
+ const xcb_window_t result = reply->owner;
+ free(reply);
+ return result;
+}
+
+// API for QPlatformNativeInterface/QPlatformSystemTrayIcon: Request a window
+// to be docked on the tray.
+void QXcbSystemTrayTracker::requestSystemTrayWindowDock(xcb_window_t window) const
+{
+ xcb_client_message_event_t trayRequest;
+ memset(&trayRequest, 0, sizeof(trayRequest));
+ trayRequest.response_type = XCB_CLIENT_MESSAGE;
+ trayRequest.format = 32;
+ trayRequest.window = m_trayWindow;
+ trayRequest.type = m_trayAtom;
+ trayRequest.data.data32[0] = XCB_CURRENT_TIME;
+ trayRequest.data.data32[1] = SystemTrayRequestDock;
+ trayRequest.data.data32[2] = window;
+ xcb_send_event(m_connection->xcb_connection(), 0, m_trayWindow, XCB_EVENT_MASK_NO_EVENT, (const char *)&trayRequest);
+}
+
+// API for QPlatformNativeInterface/QPlatformSystemTrayIcon: Return tray window.
+xcb_window_t QXcbSystemTrayTracker::trayWindow()
+{
+ if (!m_trayWindow) {
+ m_trayWindow = QXcbSystemTrayTracker::locateTrayWindow(m_connection, m_selection);
+ if (m_trayWindow) { // Listen for DestroyNotify on tray.
+ m_connection->addWindowEventListener(m_trayWindow, this);
+ const quint32 mask = XCB_CW_EVENT_MASK;
+ const quint32 value = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
+ Q_XCB_CALL(xcb_change_window_attributes(m_connection->xcb_connection(), m_trayWindow, mask, &value));
+ }
+ }
+ return m_trayWindow;
+}
+
+// API for QPlatformNativeInterface/QPlatformSystemTrayIcon: Return the geometry of a
+// a window parented on the tray. Determines the global geometry via XCB since mapToGlobal
+// does not work for the QWindow parented on the tray.
+QRect QXcbSystemTrayTracker::systemTrayWindowGlobalGeometry(xcb_window_t window) const
+{
+ xcb_connection_t *conn = m_connection->xcb_connection();
+ xcb_get_geometry_reply_t *geomReply =
+ xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), 0);
+ if (!geomReply)
+ return QRect();
+
+ xcb_translate_coordinates_reply_t *translateReply =
+ xcb_translate_coordinates_reply(conn, xcb_translate_coordinates(conn, window, m_connection->rootWindow(), 0, 0), 0);
+ if (!translateReply) {
+ free(geomReply);
+ return QRect();
+ }
+
+ const QRect result(QPoint(translateReply->dst_x, translateReply->dst_y), QSize(geomReply->width, geomReply->height));
+ free(translateReply);
+ return result;
+}
+
+inline void QXcbSystemTrayTracker::emitSystemTrayWindowChanged()
+{
+ const int screen = m_connection->primaryScreen();
+ if (screen >= 0 && screen < m_connection->screens().size()) {
+ const QPlatformScreen *ps = m_connection->screens().at(screen);
+ emit systemTrayWindowChanged(ps->screen());
+ }
+}
+
+// Client messages with the "MANAGER" atom on the root window indicate creation of a new tray.
+void QXcbSystemTrayTracker::notifyManagerClientMessageEvent(const xcb_client_message_event_t *t)
+{
+ if (t->data.data32[1] == m_selection)
+ emitSystemTrayWindowChanged();
+}
+
+// Listen for destruction of the tray.
+void QXcbSystemTrayTracker::handleDestroyNotifyEvent(const xcb_destroy_notify_event_t *event)
+{
+ if (event->window == m_trayWindow) {
+ m_connection->removeWindowEventListener(m_trayWindow);
+ m_trayWindow = 0;
+ emitSystemTrayWindowChanged();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.h b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
new file mode 100644
index 0000000000..c6b0a0659e
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBSYSTEMTRAYTRACKER_H
+#define QXCBSYSTEMTRAYTRACKER_H
+
+#include "qxcbconnection.h"
+
+#include <xcb/xcb.h>
+
+QT_BEGIN_NAMESPACE
+
+class QXcbConnection;
+class QScreen;
+
+class QXcbSystemTrayTracker : public QObject, public QXcbWindowEventListener
+{
+ Q_OBJECT
+public:
+ static QXcbSystemTrayTracker *create(QXcbConnection *connection);
+
+ xcb_window_t trayWindow();
+ void requestSystemTrayWindowDock(xcb_window_t window) const;
+ QRect systemTrayWindowGlobalGeometry(xcb_window_t window) const;
+
+ void notifyManagerClientMessageEvent(const xcb_client_message_event_t *);
+
+ void handleDestroyNotifyEvent(const xcb_destroy_notify_event_t *);
+
+signals:
+ void systemTrayWindowChanged(QScreen *screen);
+
+private:
+ explicit QXcbSystemTrayTracker(QXcbConnection *connection,
+ xcb_atom_t trayAtom,
+ xcb_atom_t selection,
+ QObject *parent = 0);
+ static xcb_window_t locateTrayWindow(const QXcbConnection *connection, xcb_atom_t selection);
+ void emitSystemTrayWindowChanged();
+
+ const xcb_atom_t m_selection;
+ const xcb_atom_t m_trayAtom;
+ QXcbConnection *m_connection;
+ xcb_window_t m_trayWindow;
+};
+
+QT_END_NAMESPACE
+
+#endif // QXCBSYSTEMTRAYTRACKER_H
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 028cd9ab72..35b95b84a1 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1515,8 +1515,7 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
m_syncValue.hi = event->data.data32[3];
#ifndef QT_NO_WHATSTHIS
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_CONTEXT_HELP)) {
- QEvent *e = new QEvent(QEvent::EnterWhatsThisMode);
- QGuiApplication::postEvent(QGuiApplication::instance(), e);
+ QWindowSystemInterface::handleEnterWhatsThisEvent();
#endif
} else {
qWarning() << "QXcbWindow: Unhandled WM_PROTOCOLS message:" << connection()->atomName(event->data.data32[0]);
@@ -1533,6 +1532,9 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
#endif
} else if (event->type == atom(QXcbAtom::_XEMBED)) {
handleXEmbedMessage(event);
+ } else if (event->type == atom(QXcbAtom::MANAGER) || event->type == atom(QXcbAtom::_NET_ACTIVE_WINDOW)) {
+ // Ignore _NET_ACTIVE_WINDOW which is received when the user clicks on a system tray icon and
+ // MANAGER which indicates the creation of a system tray.
} else {
qWarning() << "QXcbWindow: Unhandled client message:" << connection()->atomName(event->type);
}
diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro
index 82995286c4..b198ab1717 100644
--- a/src/plugins/platforms/xcb/xcb-plugin.pro
+++ b/src/plugins/platforms/xcb/xcb-plugin.pro
@@ -21,7 +21,8 @@ SOURCES = \
qxcbnativeinterface.cpp \
qxcbcursor.cpp \
qxcbimage.cpp \
- qxcbxsettings.cpp
+ qxcbxsettings.cpp \
+ qxcbsystemtraytracker.cpp
HEADERS = \
qxcbclipboard.h \
@@ -38,7 +39,8 @@ HEADERS = \
qxcbnativeinterface.h \
qxcbcursor.h \
qxcbimage.h \
- qxcbxsettings.h
+ qxcbxsettings.h \
+ qxcbsystemtraytracker.h
LIBS += -ldl
diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp
index 91a23afac5..e8758da1c7 100644
--- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp
+++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp
@@ -282,13 +282,13 @@ bool QGtk2FileDialogHelper::defaultNameFilterDisables() const
return false;
}
-void QGtk2FileDialogHelper::setDirectory(const QString &directory)
+void QGtk2FileDialogHelper::setDirectory(const QUrl &directory)
{
GtkDialog *gtkDialog = d->gtkDialog();
- gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(gtkDialog), directory.toUtf8());
+ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(gtkDialog), directory.toLocalFile().toUtf8());
}
-QString QGtk2FileDialogHelper::directory() const
+QUrl QGtk2FileDialogHelper::directory() const
{
// While GtkFileChooserDialog is hidden, gtk_file_chooser_get_current_folder()
// returns a bogus value -> return the cached value before hiding
@@ -302,27 +302,27 @@ QString QGtk2FileDialogHelper::directory() const
ret = QString::fromUtf8(folder);
g_free(folder);
}
- return ret;
+ return QUrl::fromLocalFile(ret);
}
-void QGtk2FileDialogHelper::selectFile(const QString &filename)
+void QGtk2FileDialogHelper::selectFile(const QUrl &filename)
{
GtkDialog *gtkDialog = d->gtkDialog();
- gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(gtkDialog), filename.toUtf8());
+ gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(gtkDialog), filename.toLocalFile().toUtf8());
}
-QStringList QGtk2FileDialogHelper::selectedFiles() const
+QList<QUrl> QGtk2FileDialogHelper::selectedFiles() const
{
// While GtkFileChooserDialog is hidden, gtk_file_chooser_get_filenames()
// returns a bogus value -> return the cached value before hiding
if (!_selection.isEmpty())
return _selection;
- QStringList selection;
+ QList<QUrl> selection;
GtkDialog *gtkDialog = d->gtkDialog();
GSList *filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(gtkDialog));
for (GSList *it = filenames; it; it = it->next)
- selection += QString::fromUtf8((const char*)it->data);
+ selection += QUrl::fromLocalFile(QString::fromUtf8((const char*)it->data));
g_slist_free(filenames);
return selection;
}
@@ -356,7 +356,7 @@ void QGtk2FileDialogHelper::onAccepted()
if (filter.isEmpty())
emit filterSelected(filter);
- QStringList files = selectedFiles();
+ QList<QUrl> files = selectedFiles();
emit filesSelected(files);
if (files.count() == 1)
emit fileSelected(files.first());
@@ -370,7 +370,7 @@ void QGtk2FileDialogHelper::onSelectionChanged(GtkDialog *gtkDialog, QGtk2FileDi
selection = QString::fromUtf8(filename);
g_free(filename);
}
- emit helper->currentChanged(selection);
+ emit helper->currentChanged(QUrl::fromLocalFile(selection));
}
void QGtk2FileDialogHelper::onCurrentFolderChanged(QGtk2FileDialogHelper *dialog)
@@ -419,12 +419,12 @@ void QGtk2FileDialogHelper::applyOptions()
if (!nameFilters.isEmpty())
setNameFilters(nameFilters);
- const QString initialDirectory = opts->initialDirectory();
+ const QString initialDirectory = opts->initialDirectory().toLocalFile();
if (!initialDirectory.isEmpty())
setDirectory(initialDirectory);
- foreach (const QString &filename, opts->initiallySelectedFiles())
- selectFile(filename);
+ foreach (const QUrl &filename, opts->initiallySelectedFiles())
+ selectFile(filename.toLocalFile());
const QString initialNameFilter = opts->initiallySelectedNameFilter();
if (!initialNameFilter.isEmpty())
diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h
index c2d12625f5..47a6153fbc 100644
--- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h
+++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h
@@ -90,10 +90,10 @@ public:
void hide();
bool defaultNameFilterDisables() const;
- void setDirectory(const QString &directory);
- QString directory() const;
- void selectFile(const QString &filename);
- QStringList selectedFiles() 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;
@@ -107,8 +107,8 @@ private:
void applyOptions();
void setNameFilters(const QStringList &filters);
- QString _dir;
- QStringList _selection;
+ QUrl _dir;
+ QList<QUrl> _selection;
QHash<QString, GtkFileFilter*> _filters;
QHash<GtkFileFilter*, QString> _filterNames;
QScopedPointer<QGtk2Dialog> d;
diff --git a/src/printsupport/doc/qtprintsupport.qdocconf b/src/printsupport/doc/qtprintsupport.qdocconf
index c7b14e16c1..d5015fa46a 100644
--- a/src/printsupport/doc/qtprintsupport.qdocconf
+++ b/src/printsupport/doc/qtprintsupport.qdocconf
@@ -40,3 +40,6 @@ excludedirs += ../../../examples/widgets/doc
imagedirs += images \
../../widgets/doc/images \
+
+navigation.landingpage = "Qt Print Support"
+navigation.cppclassespage = "Qt Print Support C++ Classes"
diff --git a/src/printsupport/doc/src/qtprintsupport-module.qdoc b/src/printsupport/doc/src/qtprintsupport-module.qdoc
index aaff476bc5..20ff11d8cb 100644
--- a/src/printsupport/doc/src/qtprintsupport-module.qdoc
+++ b/src/printsupport/doc/src/qtprintsupport-module.qdoc
@@ -31,6 +31,7 @@
\brief The Qt PrintSupport module provides classes to make printing easier and portable.
\ingroup modules
+ \qtvariable printsupport
To include the definitions of the module's classes, use the
following directive:
diff --git a/src/sql/doc/qtsql.qdocconf b/src/sql/doc/qtsql.qdocconf
index c2686079d5..a2a05d7c8a 100644
--- a/src/sql/doc/qtsql.qdocconf
+++ b/src/sql/doc/qtsql.qdocconf
@@ -39,3 +39,6 @@ exampledirs += ../../../examples/sql \
imagedirs += images \
../../../examples/sql/doc/images
+
+navigation.landingpage = "Qt SQL"
+navigation.cppclassespage = "Qt SQL C++ Classes"
diff --git a/src/sql/doc/src/qtsql.qdoc b/src/sql/doc/src/qtsql.qdoc
index 8ce981756a..2f806b4b45 100644
--- a/src/sql/doc/src/qtsql.qdoc
+++ b/src/sql/doc/src/qtsql.qdoc
@@ -62,6 +62,7 @@
\module QtSql
\title Qt SQL C++ Classes
\ingroup modules
+ \qtvariable sql
\brief Provides a driver layer, SQL API layer, and a user
interface layer for SQL databases.
diff --git a/src/src.pro b/src/src.pro
index b4c96025c1..6815fe4a75 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -102,12 +102,14 @@ src_android.subdir = $$PWD/android
# this order is important
SUBDIRS += src_tools_bootstrap src_tools_moc src_tools_rcc src_corelib
+TOOLS = src_tools_moc src_tools_rcc
win32:SUBDIRS += src_winmain
SUBDIRS += src_network src_sql src_xml src_testlib
contains(QT_CONFIG, dbus) {
SUBDIRS += src_dbus
force_bootstrap: SUBDIRS += src_tools_bootstrap_dbus
SUBDIRS += src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml
+ TOOLS += src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml
contains(QT_CONFIG, accessibility-atspi-bridge): \
src_platformsupport.depends += src_dbus src_tools_qdbusxml2cpp
src_plugins.depends += src_dbus src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml
@@ -123,6 +125,7 @@ contains(QT_CONFIG, concurrent):SUBDIRS += src_concurrent
src_plugins.depends += src_gui src_platformsupport
!contains(QT_CONFIG, no-widgets) {
SUBDIRS += src_tools_uic src_widgets
+ TOOLS += src_tools_uic
src_plugins.depends += src_widgets
contains(QT_CONFIG, opengl(es1|es2)?) {
SUBDIRS += src_opengl
@@ -139,3 +142,6 @@ SUBDIRS += src_plugins src_tools_qdoc
nacl: SUBDIRS -= src_network src_testlib
android:!android-no-sdk: SUBDIRS += src_android
+
+sub-tools.depends = $$TOOLS
+QMAKE_EXTRA_TARGETS = sub-tools
diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf
index 2eea4f246a..ab2bdc1948 100644
--- a/src/testlib/doc/qttestlib.qdocconf
+++ b/src/testlib/doc/qttestlib.qdocconf
@@ -40,3 +40,6 @@ exampledirs += ../../../examples/qtestlib \
excludedirs += ../../../examples/widgets/doc
imagedirs += images
+
+navigation.landingpage = "Qt Test"
+navigation.cppclassespage = "Qt Test C++ Classes"
diff --git a/src/testlib/doc/src/qttest.qdoc b/src/testlib/doc/src/qttest.qdoc
index 6e0bd3c070..c9e1683f83 100644
--- a/src/testlib/doc/src/qttest.qdoc
+++ b/src/testlib/doc/src/qttest.qdoc
@@ -29,6 +29,7 @@
\module QtTest
\title Qt Test C++ Classes
\ingroup modules
+ \qtvariable testlib
\keyword QtTest
diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc
index c44bb49ae3..613d2c220c 100644
--- a/src/testlib/doc/src/qttestlib-manual.qdoc
+++ b/src/testlib/doc/src/qttestlib-manual.qdoc
@@ -247,6 +247,9 @@
2000.
\li \c -nocrashhandler \br
Disables the crash handler on Unix platforms.
+ On Windows, it re-enables the Windows Error Reporting dialog, which is
+ turned off by default.
+
\li \c -platform \e name \br
This command line argument applies to all Qt applications, but might be
especially useful in the context of auto-testing. By using the "offscreen"
diff --git a/src/testlib/qabstracttestlogger.cpp b/src/testlib/qabstracttestlogger.cpp
index d039c3c342..41f8f37872 100644
--- a/src/testlib/qabstracttestlogger.cpp
+++ b/src/testlib/qabstracttestlogger.cpp
@@ -52,6 +52,10 @@
#include <unistd.h>
#endif
+#ifdef Q_OS_ANDROID
+#include <sys/stat.h>
+#endif
+
QT_BEGIN_NAMESPACE
QAbstractTestLogger::QAbstractTestLogger(const char *filename)
@@ -69,6 +73,12 @@ QAbstractTestLogger::QAbstractTestLogger(const char *filename)
fprintf(stderr, "Unable to open file for logging: %s\n", filename);
::exit(1);
}
+#ifdef Q_OS_ANDROID
+ else {
+ // Make sure output is world-readable on Android
+ ::chmod(filename, 0666);
+ }
+#endif
}
QAbstractTestLogger::~QAbstractTestLogger()
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 77a59d0cf0..5d5a976201 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -1130,9 +1130,7 @@ namespace QTest
static int keyDelay = -1;
static int mouseDelay = -1;
static int eventDelay = -1;
-#if defined(Q_OS_UNIX)
static bool noCrashHandler = false;
-#endif
/*! \internal
Invoke a method of the object without generating warning if the method does not exist
@@ -1335,9 +1333,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
" -mousedelay ms : Set default delay for mouse simulation to ms milliseconds\n"
" -maxwarnings n : Sets the maximum amount of messages to output.\n"
" 0 means unlimited, default: 2000\n"
-#if defined(Q_OS_UNIX)
" -nocrashhandler : Disables the crash handler\n"
-#endif
"\n"
" Benchmarking options:\n"
#ifdef QTESTLIB_USE_VALGRIND
@@ -1468,10 +1464,8 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
} else {
QTestLog::setMaxWarnings(qToInt(argv[++i]));
}
-#if defined(Q_OS_UNIX)
} else if (strcmp(argv[i], "-nocrashhandler") == 0) {
QTest::noCrashHandler = true;
-#endif
#ifdef QTESTLIB_USE_VALGRIND
} else if (strcmp(argv[i], "-callgrind") == 0) {
if (QBenchmarkValgrindUtils::haveValgrind())
@@ -2083,6 +2077,18 @@ FatalSignalHandler::~FatalSignalHandler()
} // namespace
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+static LONG WINAPI windowsFaultHandler(struct _EXCEPTION_POINTERS *exInfo)
+{
+ char appName[MAX_PATH];
+ if (!GetModuleFileNameA(NULL, appName, MAX_PATH))
+ appName[0] = 0;
+ fprintf(stderr, "A crash occurred in %s (exception code 0x%lx).",
+ appName, exInfo->ExceptionRecord->ExceptionCode);
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+#endif // Q_OS_WIN) && !Q_OS_WINCE
+
/*!
Executes tests declared in \a testObject. In addition, the private slots
\c{initTestCase()}, \c{cleanupTestCase()}, \c{init()} and \c{cleanup()}
@@ -2138,13 +2144,6 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
try {
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
-# if !defined(Q_CC_MINGW)
- _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
-# endif
- SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
-#endif
-
#if defined(Q_OS_MACX)
if (macNeedsActivate) {
CFStringRef reasonForActivity= CFSTR("No Display Sleep");
@@ -2170,6 +2169,16 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
qtest_qParseArgs(argc, argv, false);
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ if (!noCrashHandler) {
+# ifndef Q_CC_MINGW
+ _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
+# endif
+ SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
+ SetUnhandledExceptionFilter(windowsFaultHandler);
+ } // !noCrashHandler
+#endif // Q_OS_WIN) && !Q_OS_WINCE
+
#ifdef QTESTLIB_USE_VALGRIND
if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) {
const QStringList origAppArgs(QCoreApplication::arguments());
diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp
index a6a8ee0cc1..7ab317f209 100644
--- a/src/testlib/qtestresult.cpp
+++ b/src/testlib/qtestresult.cpp
@@ -268,10 +268,12 @@ bool QTestResult::compare(bool success, const char *failureMsg,
if (success && QTest::expectFailMode) {
qsnprintf(msg, 1024, "QCOMPARE(%s, %s) returned TRUE unexpectedly.", actual, expected);
} else if (val1 || val2) {
- qsnprintf(msg, 1024, "%s\n Actual (%s): %s\n Expected (%s): %s",
+ size_t len1 = strlen(actual);
+ size_t len2 = strlen(expected);
+ qsnprintf(msg, 1024, "%s\n Actual (%s)%*s %s\n Expected (%s)%*s %s",
failureMsg,
- actual, val1 ? val1 : "<null>",
- expected, val2 ? val2 : "<null>");
+ actual, qMax(len1, len2) - len1 + 1, ":", val1 ? val1 : "<null>",
+ expected, qMax(len1, len2) - len2 + 1, ":", val2 ? val2 : "<null>");
} else
qsnprintf(msg, 1024, "%s", failureMsg);
diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
index a66757907d..0e1fa59b90 100644
--- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
+++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
@@ -47,6 +47,7 @@
#include <qbuffer.h>
#include <qregexp.h>
#include <qvector.h>
+#include <qdebug.h>
#include <stdio.h>
#include <stdlib.h>
@@ -95,14 +96,14 @@ static const char help[] =
"\n";
-int qDBusParametersForMethod(const FunctionDef &mm, QVector<int>& metaTypes)
+int qDBusParametersForMethod(const FunctionDef &mm, QVector<int>& metaTypes, QString &errorMsg)
{
QList<QByteArray> parameterTypes;
foreach (const ArgumentDef &arg, mm.arguments)
parameterTypes.append(arg.normalizedType);
- return qDBusParametersForMethod(parameterTypes, metaTypes);
+ return qDBusParametersForMethod(parameterTypes, metaTypes, errorMsg);
}
@@ -140,9 +141,12 @@ static QString addFunction(const FunctionDef &mm, bool isSignal = false) {
}
QList<ArgumentDef> names = mm.arguments;
QVector<int> types;
- int inputCount = qDBusParametersForMethod(mm, types);
- if (inputCount == -1)
+ QString errorMsg;
+ int inputCount = qDBusParametersForMethod(mm, types, errorMsg);
+ if (inputCount == -1) {
+ qWarning() << qPrintable(errorMsg);
return QString(); // invalid form
+ }
if (isSignal && inputCount + 1 != types.count())
return QString(); // signal with output arguments?
if (isSignal && types.at(inputCount) == QDBusMetaTypeId::message())
diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
index e6d77643de..f2b9441ea4 100644
--- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -401,6 +401,8 @@ static QStringList makeArgNames(const QDBusIntrospection::Arguments &inputArgs,
QString name = arg.name;
if (name.isEmpty())
name = QString( QLatin1String("in%1") ).arg(i);
+ else
+ name.replace(QLatin1Char('-'), QLatin1Char('_'));
while (retval.contains(name))
name += QLatin1String("_");
retval << name;
@@ -410,6 +412,8 @@ static QStringList makeArgNames(const QDBusIntrospection::Arguments &inputArgs,
QString name = arg.name;
if (name.isEmpty())
name = QString( QLatin1String("out%1") ).arg(i);
+ else
+ name.replace(QLatin1Char('-'), QLatin1Char('_'));
while (retval.contains(name))
name += QLatin1String("_");
retval << name;
diff --git a/src/tools/qdoc/codemarker.cpp b/src/tools/qdoc/codemarker.cpp
index c7d9c5b339..8faac66b1b 100644
--- a/src/tools/qdoc/codemarker.cpp
+++ b/src/tools/qdoc/codemarker.cpp
@@ -398,7 +398,7 @@ void CodeMarker::insert(FastSection &fastSection,
bool inheritedMember = false;
if (!node->relates()) {
InnerNode* p = node->parent();
- if (p->subType() == Node::QmlPropertyGroup)
+ if (p->type() == Node::QmlPropertyGroup)
p = p->parent();
if (p != fastSection.parent_) { // && !node->parent()->isAbstract()) {
if (p->subType() != Node::QmlClass || !p->isAbstract()) {
diff --git a/src/tools/qdoc/codeparser.cpp b/src/tools/qdoc/codeparser.cpp
index 7b534a6c95..1be67894cc 100644
--- a/src/tools/qdoc/codeparser.cpp
+++ b/src/tools/qdoc/codeparser.cpp
@@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE
#define COMMAND_PAGEKEYWORDS Doc::alias(QLatin1String("pagekeywords"))
#define COMMAND_PRELIMINARY Doc::alias(QLatin1String("preliminary"))
#define COMMAND_INPUBLICGROUP Doc::alias(QLatin1String("inpublicgroup"))
+#define COMMAND_QTVARIABLE Doc::alias(QLatin1String("qtvariable"))
#define COMMAND_REENTRANT Doc::alias(QLatin1String("reentrant"))
#define COMMAND_SINCE Doc::alias(QLatin1String("since"))
#define COMMAND_SUBTITLE Doc::alias(QLatin1String("subtitle"))
@@ -199,29 +200,34 @@ CodeParser *CodeParser::parserForSourceFile(const QString &filePath)
return 0;
}
+static QSet<QString> commonMetaCommands_;
/*!
Returns the set of strings representing the common metacommands.
*/
-QSet<QString> CodeParser::commonMetaCommands()
+const QSet<QString>& CodeParser::commonMetaCommands()
{
- return QSet<QString>() << COMMAND_COMPAT
- << COMMAND_DEPRECATED
- << COMMAND_INGROUP
- << COMMAND_INMODULE
- << COMMAND_INQMLMODULE
- << COMMAND_INTERNAL
- << COMMAND_MAINCLASS
- << COMMAND_NONREENTRANT
- << COMMAND_OBSOLETE
- << COMMAND_PAGEKEYWORDS
- << COMMAND_PRELIMINARY
- << COMMAND_INPUBLICGROUP
- << COMMAND_REENTRANT
- << COMMAND_SINCE
- << COMMAND_SUBTITLE
- << COMMAND_THREADSAFE
- << COMMAND_TITLE
- << COMMAND_WRAPPER;
+ if (commonMetaCommands_.isEmpty()) {
+ commonMetaCommands_ << COMMAND_COMPAT
+ << COMMAND_DEPRECATED
+ << COMMAND_INGROUP
+ << COMMAND_INMODULE
+ << COMMAND_INQMLMODULE
+ << COMMAND_INTERNAL
+ << COMMAND_MAINCLASS
+ << COMMAND_NONREENTRANT
+ << COMMAND_OBSOLETE
+ << COMMAND_PAGEKEYWORDS
+ << COMMAND_PRELIMINARY
+ << COMMAND_INPUBLICGROUP
+ << COMMAND_QTVARIABLE
+ << COMMAND_REENTRANT
+ << COMMAND_SINCE
+ << COMMAND_SUBTITLE
+ << COMMAND_THREADSAFE
+ << COMMAND_TITLE
+ << COMMAND_WRAPPER;
+ }
+ return commonMetaCommands_;
}
/*!
@@ -269,8 +275,8 @@ void CodeParser::processCommonMetaCommand(const Location& location,
if (!showInternal) {
node->setAccess(Node::Private);
node->setStatus(Node::Internal);
- if (node->subType() == Node::QmlPropertyGroup) {
- const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
+ if (node->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
@@ -317,6 +323,15 @@ void CodeParser::processCommonMetaCommand(const Location& location,
else
location.warning(tr("Ignored '\\%1'").arg(COMMAND_TITLE));
}
+ else if (command == COMMAND_QTVARIABLE) {
+ if (node->subType() == Node::Module) {
+ DocNode *dn = static_cast<DocNode *>(node);
+ dn->setQtVariable(arg.first);
+ }
+ else
+ location.warning(tr("Command '\\%1' found outside of '\\module'. It can only be used within a module page.")
+ .arg(COMMAND_QTVARIABLE));
+ }
}
/*!
diff --git a/src/tools/qdoc/codeparser.h b/src/tools/qdoc/codeparser.h
index 8c398aeb05..89f661abeb 100644
--- a/src/tools/qdoc/codeparser.h
+++ b/src/tools/qdoc/codeparser.h
@@ -86,7 +86,7 @@ public:
static const QString& currentOutputSubdirectory() { return currentSubDir_; }
protected:
- QSet<QString> commonMetaCommands();
+ const QSet<QString>& commonMetaCommands();
void processCommonMetaCommand(const Location& location,
const QString& command,
const ArgLocPair& arg,
diff --git a/src/tools/qdoc/config.cpp b/src/tools/qdoc/config.cpp
index a475ccbfb6..8729bf387f 100644
--- a/src/tools/qdoc/config.cpp
+++ b/src/tools/qdoc/config.cpp
@@ -279,10 +279,19 @@ int Config::getInt(const QString& var) const
*/
QString Config::getOutputDir() const
{
+ QString t;
if (overrideOutputDir.isNull())
- return getString(QLatin1String(CONFIG_OUTPUTDIR));
+ t = getString(QLatin1String(CONFIG_OUTPUTDIR));
else
- return overrideOutputDir;
+ t = overrideOutputDir;
+ if (!Generator::useOutputSubdirs()) {
+ t = t.left(t.lastIndexOf('/'));
+ QString singleOutputSubdir = getString("HTML.outputsubdir");
+ if (singleOutputSubdir.isEmpty())
+ singleOutputSubdir = "html";
+ t += QLatin1Char('/') + singleOutputSubdir;
+ }
+ return t;
}
/*!
diff --git a/src/tools/qdoc/config.h b/src/tools/qdoc/config.h
index 8787d27eb3..948f31c01a 100644
--- a/src/tools/qdoc/config.h
+++ b/src/tools/qdoc/config.h
@@ -165,7 +165,9 @@ private:
#define CONFIG_ALIAS "alias"
#define CONFIG_BASE "base"
#define CONFIG_BASEDIR "basedir"
+#define CONFIG_BUILDVERSION "buildversion"
#define CONFIG_CODEINDENT "codeindent"
+#define CONFIG_CPPCLASSESPAGE "cppclassespage"
#define CONFIG_DEFINES "defines"
#define CONFIG_DEPENDS "depends"
#define CONFIG_DESCRIPTION "description"
@@ -184,15 +186,18 @@ private:
#define CONFIG_HEADERS "headers"
#define CONFIG_HEADERSCRIPTS "headerscripts"
#define CONFIG_HEADERSTYLES "headerstyles"
+#define CONFIG_HOMEPAGE "homepage"
#define CONFIG_IGNOREDIRECTIVES "ignoredirectives"
#define CONFIG_IGNORETOKENS "ignoretokens"
#define CONFIG_IMAGEDIRS "imagedirs"
#define CONFIG_IMAGES "images"
#define CONFIG_INDEXES "indexes"
#define CONFIG_LANGUAGE "language"
+#define CONFIG_LANDINGPAGE "landingpage"
#define CONFIG_MACRO "macro"
#define CONFIG_MANIFESTMETA "manifestmeta"
#define CONFIG_NATURALLANGUAGE "naturallanguage"
+#define CONFIG_NAVIGATION "navigation"
#define CONFIG_NOLINKERRORS "nolinkerrors"
#define CONFIG_OBSOLETELINKS "obsoletelinks"
#define CONFIG_OUTPUTDIR "outputdir"
@@ -201,7 +206,9 @@ private:
#define CONFIG_OUTPUTFORMATS "outputformats"
#define CONFIG_OUTPUTPREFIXES "outputprefixes"
#define CONFIG_PROJECT "project"
+#define CONFIG_REDIRECTDOCUMENTATIONTODEVNULL "redirectdocumentationtodevnull"
#define CONFIG_QHP "qhp"
+#define CONFIG_QMLTYPESPAGE "qmltypespage"
#define CONFIG_QUOTINGINFORMATION "quotinginformation"
#define CONFIG_SCRIPTDIRS "scriptdirs"
#define CONFIG_SCRIPTS "scripts"
diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp
index 75e49f288a..ad3c5cba47 100644
--- a/src/tools/qdoc/cppcodemarker.cpp
+++ b/src/tools/qdoc/cppcodemarker.cpp
@@ -1110,40 +1110,15 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno
while (qcn != 0) {
NodeList::ConstIterator c = qcn->childNodes().constBegin();
while (c != qcn->childNodes().constEnd()) {
- if ((*c)->subType() == Node::QmlPropertyGroup) {
- const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
- NodeList::ConstIterator p = qpgn->childNodes().constBegin();
- while (p != qpgn->childNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*p);
- if (pn->isAttached())
- insert(qmlattachedproperties,*p,style,Okay);
- else
- insert(qmlproperties,*p,style,Okay);
- }
- ++p;
- }
+ if ((*c)->type() == Node::QmlPropertyGroup) {
+ insert(qmlproperties, *c, style, Okay);
}
else if ((*c)->type() == Node::QmlProperty) {
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*c);
- if (pn->qmlPropNodes().isEmpty()) {
- if (pn->isAttached())
- insert(qmlattachedproperties,*c,style,Okay);
- else
- insert(qmlproperties,*c,style,Okay);
- }
+ if (pn->isAttached())
+ insert(qmlattachedproperties,*c,style,Okay);
else {
- NodeList::ConstIterator p = pn->qmlPropNodes().constBegin();
- while (p != pn->qmlPropNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*p);
- if (pn->isAttached())
- insert(qmlattachedproperties,*p,style,Okay);
- else
- insert(qmlproperties,*p,style,Okay);
- }
- ++p;
- }
+ insert(qmlproperties,*c,style,Okay);
}
}
else if ((*c)->type() == Node::QmlSignal) {
@@ -1196,24 +1171,8 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno
while (qcn != 0) {
NodeList::ConstIterator c = qcn->childNodes().constBegin();
while (c != qcn->childNodes().constEnd()) {
- if ((*c)->subType() == Node::QmlPropertyGroup) {
- bool attached = false;
- const QmlPropGroupNode* pgn = static_cast<const QmlPropGroupNode*>(*c);
- NodeList::ConstIterator C = pgn->childNodes().constBegin();
- while (C != pgn->childNodes().constEnd()) {
- if ((*C)->type() == Node::QmlProperty) {
- const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*C);
- if (pn->isAttached()) {
- attached = true;
- break;
- }
- }
- ++C;
- }
- if (attached)
- insert(qmlattachedproperties,*c,style,Okay);
- else
- insert(qmlproperties,*c,style,Okay);
+ if ((*c)->type() == Node::QmlPropertyGroup) {
+ insert(qmlproperties,*c,style,Okay);
}
else if ((*c)->type() == Node::QmlProperty) {
const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*c);
@@ -1278,8 +1237,8 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, Syno
}
NodeList::ConstIterator c = current->childNodes().constBegin();
while (c != current->childNodes().constEnd()) {
- if ((*c)->subType() == Node::QmlPropertyGroup) {
- const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
+ if ((*c)->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(*c);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp
index 5c25eeedc4..3e63432047 100644
--- a/src/tools/qdoc/cppcodeparser.cpp
+++ b/src/tools/qdoc/cppcodeparser.cpp
@@ -272,37 +272,42 @@ void CppCodeParser::doneParsingSourceFiles()
qdb_->treeRoot()->makeUndocumentedChildrenInternal();
}
+static QSet<QString> topicCommands_;
/*!
Returns the set of strings reopresenting the topic commands.
*/
-QSet<QString> CppCodeParser::topicCommands()
+const QSet<QString>& CppCodeParser::topicCommands()
{
- return QSet<QString>() << COMMAND_CLASS
- << COMMAND_DITAMAP
- << COMMAND_ENUM
- << COMMAND_EXAMPLE
- << COMMAND_EXTERNALPAGE
- << COMMAND_FILE
- << COMMAND_FN
- << COMMAND_GROUP
- << COMMAND_HEADERFILE
- << COMMAND_MACRO
- << COMMAND_MODULE
- << COMMAND_NAMESPACE
- << COMMAND_PAGE
- << COMMAND_PROPERTY
- << COMMAND_TYPEDEF
- << COMMAND_VARIABLE
- << COMMAND_QMLCLASS
- << COMMAND_QMLTYPE
- << COMMAND_QMLPROPERTY
- << COMMAND_QMLATTACHEDPROPERTY
- << COMMAND_QMLSIGNAL
- << COMMAND_QMLATTACHEDSIGNAL
- << COMMAND_QMLMETHOD
- << COMMAND_QMLATTACHEDMETHOD
- << COMMAND_QMLBASICTYPE
- << COMMAND_QMLMODULE;
+ if (topicCommands_.isEmpty()) {
+ topicCommands_ << COMMAND_CLASS
+ << COMMAND_DITAMAP
+ << COMMAND_ENUM
+ << COMMAND_EXAMPLE
+ << COMMAND_EXTERNALPAGE
+ << COMMAND_FILE
+ << COMMAND_FN
+ << COMMAND_GROUP
+ << COMMAND_HEADERFILE
+ << COMMAND_MACRO
+ << COMMAND_MODULE
+ << COMMAND_NAMESPACE
+ << COMMAND_PAGE
+ << COMMAND_PROPERTY
+ << COMMAND_TYPEDEF
+ << COMMAND_VARIABLE
+ << COMMAND_QMLCLASS
+ << COMMAND_QMLTYPE
+ << COMMAND_QMLPROPERTY
+ << COMMAND_QMLPROPERTYGROUP
+ << COMMAND_QMLATTACHEDPROPERTY
+ << COMMAND_QMLSIGNAL
+ << COMMAND_QMLATTACHEDSIGNAL
+ << COMMAND_QMLMETHOD
+ << COMMAND_QMLATTACHEDMETHOD
+ << COMMAND_QMLBASICTYPE
+ << COMMAND_QMLMODULE;
+ }
+ return topicCommands_;
}
/*!
@@ -607,10 +612,10 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
(command == COMMAND_QMLATTACHEDSIGNAL) ||
(command == COMMAND_QMLATTACHEDMETHOD)) {
QString module;
- QString element;
+ QString qmlType;
QString type;
- if (splitQmlMethodArg(arg.first,type,module,element)) {
- QmlClassNode* qmlClass = qdb_->findQmlType(module,element);
+ if (splitQmlMethodArg(arg.first,type,module,qmlType)) {
+ QmlClassNode* qmlClass = qdb_->findQmlType(module,qmlType);
if (qmlClass) {
bool attached = false;
Node::Type nodeType = Node::QmlMethod;
@@ -643,28 +648,57 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
}
/*!
+ A QML property group argument has the form...
+
+ <QML-module>::<QML-type>::<name>
+
+ This function splits the argument into those parts.
+ A <QML-module> is the QML equivalent of a C++ namespace.
+ So this function splits \a arg on "::" and stores the
+ parts in \a module, \a qmlType, and \a name, and returns
+ true. If any part is not found, a qdoc warning is emitted
+ and false is returned.
+ */
+bool CppCodeParser::splitQmlPropertyGroupArg(const QString& arg,
+ QString& module,
+ QString& qmlType,
+ QString& name)
+{
+ QStringList colonSplit = arg.split("::");
+ if (colonSplit.size() == 3) {
+ module = colonSplit[0];
+ qmlType = colonSplit[1];
+ name = colonSplit[2];
+ return true;
+ }
+ QString msg = "Unrecognizable QML module/component qualifier for " + arg;
+ location().warning(tr(msg.toLatin1().data()));
+ return false;
+}
+
+/*!
A QML property argument has the form...
- <type> <element>::<name>
- <type> <QML-module>::<element>::<name>
+ <type> <QML-type>::<name>
+ <type> <QML-module>::<QML-type>::<name>
This function splits the argument into one of those
two forms. The three part form is the old form, which
was used before the creation of Qt Quick 2 and Qt
Components. A <QML-module> is the QML equivalent of a
C++ namespace. So this function splits \a arg on "::"
- and stores the parts in \a type, \a module, \a element,
+ and stores the parts in \a type, \a module, \a qmlType,
and \a name, and returns true. If any part other than
\a module is not found, a qdoc warning is emitted and
false is returned.
- \note The two elements \e{Component} and \e{QtObject} never
- have a module qualifier.
+ \note The two QML types \e{Component} and \e{QtObject}
+ never have a module qualifier.
*/
bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
QString& type,
QString& module,
- QString& element,
+ QString& qmlType,
QString& name)
{
QStringList blankSplit = arg.split(QLatin1Char(' '));
@@ -673,13 +707,13 @@ bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
QStringList colonSplit(blankSplit[1].split("::"));
if (colonSplit.size() == 3) {
module = colonSplit[0];
- element = colonSplit[1];
+ qmlType = colonSplit[1];
name = colonSplit[2];
return true;
}
if (colonSplit.size() == 2) {
module.clear();
- element = colonSplit[0];
+ qmlType = colonSplit[0];
name = colonSplit[1];
return true;
}
@@ -696,21 +730,21 @@ bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
/*!
A QML signal or method argument has the form...
- <type> <element>::<name>(<param>, <param>, ...)
- <type> <QML-module>::<element>::<name>(<param>, <param>, ...)
+ <type> <QML-type>::<name>(<param>, <param>, ...)
+ <type> <QML-module>::<QML-type>::<name>(<param>, <param>, ...)
This function splits the argument into one of those two
- forms, sets \a module, \a element, and \a name, and returns
+ forms, sets \a module, \a qmlType, and \a name, and returns
true. If the argument doesn't match either form, an error
message is emitted and false is returned.
- \note The two elements \e{Component} and \e{QtObject} never
+ \note The two QML types \e{Component} and \e{QtObject} never
have a module qualifier.
*/
bool CppCodeParser::splitQmlMethodArg(const QString& arg,
QString& type,
QString& module,
- QString& element)
+ QString& qmlType)
{
QStringList colonSplit(arg.split("::"));
if (colonSplit.size() > 1) {
@@ -719,22 +753,22 @@ bool CppCodeParser::splitQmlMethodArg(const QString& arg,
type = blankSplit[0];
if (colonSplit.size() > 2) {
module = blankSplit[1];
- element = colonSplit[1];
+ qmlType = colonSplit[1];
}
else {
module.clear();
- element = blankSplit[1];
+ qmlType = blankSplit[1];
}
}
else {
type.clear();
if (colonSplit.size() > 2) {
module = colonSplit[0];
- element = colonSplit[1];
+ qmlType = colonSplit[1];
}
else {
module.clear();
- element = colonSplit[0];
+ qmlType = colonSplit[0];
}
}
return true;
@@ -750,79 +784,118 @@ bool CppCodeParser::splitQmlMethodArg(const QString& arg,
Currently, this function is called only for \e{qmlproperty}
and \e{qmlattachedproperty}.
*/
-Node* CppCodeParser::processTopicCommandGroup(const Doc& doc,
- const QString& command,
- const ArgList& args)
+void CppCodeParser::processQmlProperties(const Doc& doc, NodeList& nodes, DocList& docs)
{
- QmlPropGroupNode* qmlPropGroup = 0;
- if ((command == COMMAND_QMLPROPERTY) ||
- (command == COMMAND_QMLATTACHEDPROPERTY)) {
- QString arg;
- QString type;
- QString module;
- QString element;
- QString property;
- QmlClassNode* qmlClass = 0;
- bool attached = (command == COMMAND_QMLATTACHEDPROPERTY);
- ArgList::ConstIterator argsIter = args.constBegin();
- arg = argsIter->first;
- if (splitQmlPropertyArg(arg,type,module,element,property)) {
- qmlClass = qdb_->findQmlType(module,element);
- if (qmlClass) {
- qmlPropGroup = new QmlPropGroupNode(qmlClass,property); //,attached);
- qmlPropGroup->setLocation(doc.startLocation());
- }
+ QString arg;
+ QString type;
+ QString topic;
+ QString module;
+ QString qmlType;
+ QString property;
+ QmlPropertyNode* qpn = 0;
+ QmlClassNode* qmlClass = 0;
+ QmlPropertyGroupNode* qpgn = 0;
+
+ Topic qmlPropertyGroupTopic;
+ const TopicList& topics = doc.topicsUsed();
+ for (int i=0; i<topics.size(); ++i) {
+ if (topics.at(i).topic == COMMAND_QMLPROPERTYGROUP) {
+ qmlPropertyGroupTopic = topics.at(i);
+ break;
}
- if (qmlPropGroup) {
- if (qmlClass->hasProperty(property)) {
- doc.startLocation().warning(tr("QML property documented multiple times: '%1'").arg(arg));
+ }
+ if (qmlPropertyGroupTopic.isEmpty() && topics.size() > 1) {
+ qmlPropertyGroupTopic = topics.at(0);
+ qmlPropertyGroupTopic.topic = COMMAND_QMLPROPERTYGROUP;
+ arg = qmlPropertyGroupTopic.args;
+ if (splitQmlPropertyArg(arg, type, module, qmlType, property)) {
+ int i = property.indexOf('.');
+ if (i != -1) {
+ property = property.left(i);
+ qmlPropertyGroupTopic.args = module + "::" + qmlType + "::" + property;
+ doc.location().warning(tr("No QML property group command found; using \\%1 %2")
+ .arg(COMMAND_QMLPROPERTYGROUP).arg(qmlPropertyGroupTopic.args));
}
else {
- QmlPropertyNode *qmlPropNode = new QmlPropertyNode(qmlPropGroup,property,type,attached);
- qmlPropNode->setLocation(doc.startLocation());
+ /*
+ Assumption: No '.' in the property name
+ means there is no property group.
+ */
+ qmlPropertyGroupTopic.clear();
+ }
+ }
+ }
+
+ if (!qmlPropertyGroupTopic.isEmpty()) {
+ arg = qmlPropertyGroupTopic.args;
+ if (splitQmlPropertyGroupArg(arg, module, qmlType, property)) {
+ qmlClass = qdb_->findQmlType(module, qmlType);
+ if (qmlClass) {
+ qpgn = new QmlPropertyGroupNode(qmlClass, property);
+ qpgn->setLocation(doc.startLocation());
}
- ++argsIter;
- while (argsIter != args.constEnd()) {
- arg = argsIter->first;
- if (splitQmlPropertyArg(arg,type,module,element,property)) {
- if (qmlClass->hasProperty(property)) {
- doc.startLocation().warning(tr("QML property documented multiple times: '%1'").arg(arg));
+ }
+ if (topics.size() == 1) {
+ nodes.append(qpgn);
+ docs.append(doc);
+ return;
+ }
+ }
+ for (int i=0; i<topics.size(); ++i) {
+ if (topics.at(i).topic == COMMAND_QMLPROPERTYGROUP)
+ continue;
+ topic = topics.at(i).topic;
+ arg = topics.at(i).args;
+ if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ bool attached = (topic == COMMAND_QMLATTACHEDPROPERTY);
+ if (splitQmlPropertyArg(arg, type, module, qmlType, property)) {
+ qmlClass = qdb_->findQmlType(module, qmlType);
+ if (qmlClass) {
+ if (qmlClass->hasQmlProperty(property) != 0) {
+ QString msg = tr("QML property documented multiple times: '%1'").arg(arg);
+ doc.startLocation().warning(msg);
+ }
+ else if (qpgn) {
+ qpn = new QmlPropertyNode(qpgn, property, type, attached);
+ qpn->setLocation(doc.startLocation());
}
else {
- QmlPropertyNode* qmlPropNode = new QmlPropertyNode(qmlPropGroup,
- property,
- type,
- attached);
- qmlPropNode->setLocation(doc.startLocation());
+ qpn = new QmlPropertyNode(qmlClass, property, type, attached);
+ qpn->setLocation(doc.startLocation());
+ nodes.append(qpn);
+ docs.append(doc);
}
}
- ++argsIter;
}
}
}
- return qmlPropGroup;
}
+static QSet<QString> otherMetaCommands_;
/*!
Returns the set of strings representing the common metacommands
plus some other metacommands.
*/
-QSet<QString> CppCodeParser::otherMetaCommands()
+const QSet<QString>& CppCodeParser::otherMetaCommands()
{
- return commonMetaCommands() << COMMAND_INHEADERFILE
- << COMMAND_OVERLOAD
- << COMMAND_REIMP
- << COMMAND_RELATES
- << COMMAND_CONTENTSPAGE
- << COMMAND_NEXTPAGE
- << COMMAND_PREVIOUSPAGE
- << COMMAND_INDEXPAGE
- << COMMAND_STARTPAGE
- << COMMAND_QMLINHERITS
- << COMMAND_QMLINSTANTIATES
- << COMMAND_QMLDEFAULT
- << COMMAND_QMLREADONLY
- << COMMAND_QMLABSTRACT;
+ if (otherMetaCommands_.isEmpty()) {
+ otherMetaCommands_ = commonMetaCommands();
+ otherMetaCommands_ << COMMAND_INHEADERFILE
+ << COMMAND_OVERLOAD
+ << COMMAND_REIMP
+ << COMMAND_RELATES
+ << COMMAND_CONTENTSPAGE
+ << COMMAND_NEXTPAGE
+ << COMMAND_PREVIOUSPAGE
+ << COMMAND_INDEXPAGE
+ << COMMAND_STARTPAGE
+ << COMMAND_QMLINHERITS
+ << COMMAND_QMLINSTANTIATES
+ << COMMAND_QMLDEFAULT
+ << COMMAND_QMLREADONLY
+ << COMMAND_QMLABSTRACT;
+ }
+ return otherMetaCommands_;
}
/*!
@@ -855,8 +928,8 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
}
}
else if (command == COMMAND_REIMP) {
- if (node->parent() && !node->parent()->isInternal()) {
- if (node != 0 && node->type() == Node::Function) {
+ if (node != 0 && node->parent() && !node->parent()->isInternal()) {
+ if (node->type() == Node::Function) {
FunctionNode *func = (FunctionNode *) node;
const FunctionNode *from = func->reimplementedFrom();
if (from == 0) {
@@ -961,8 +1034,8 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
qpn->setDefault();
}
- else if (node->type() == Node::Document && node->subType() == Node::QmlPropertyGroup) {
- QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node);
+ else if (node->type() == Node::QmlPropertyGroup) {
+ QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
@@ -978,8 +1051,8 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
qpn->setReadOnly(1);
}
- else if (node->type() == Node::Document && node->subType() == Node::QmlPropertyGroup) {
- QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node);
+ else if (node->type() == Node::QmlPropertyGroup) {
+ QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
@@ -2067,10 +2140,9 @@ bool CppCodeParser::matchDeclList(InnerNode *parent)
bool CppCodeParser::matchDocsAndStuff()
{
ExtraFuncData extra;
- QSet<QString> topicCommandsAllowed = topicCommands();
- QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
- QSet<QString> metacommandsAllowed = topicCommandsAllowed +
- otherMetacommandsAllowed;
+ const QSet<QString>& topicCommandsAllowed = topicCommands();
+ const QSet<QString>& otherMetacommandsAllowed = otherMetaCommands();
+ const QSet<QString>& metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
while (tok != Tok_Eoi) {
if (tok == Tok_Doc) {
@@ -2087,25 +2159,22 @@ bool CppCodeParser::matchDocsAndStuff()
/*
Doc parses the comment.
*/
- Doc doc(start_loc,end_loc,comment,metacommandsAllowed);
-
+ Doc doc(start_loc,end_loc,comment,metacommandsAllowed, topicCommandsAllowed);
QString topic;
- ArgList args;
-
- QSet<QString> topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
+ bool isQmlPropertyTopic = false;
- /*
- There should be one topic command in the set,
- or none. If the set is empty, then the comment
- should be a function description.
- */
- if (topicCommandsUsed.count() > 0) {
- topic = *topicCommandsUsed.constBegin();
- args = doc.metaCommandArgs(topic);
+ const TopicList& topics = doc.topicsUsed();
+ if (!topics.isEmpty()) {
+ topic = topics[0].topic;
+ if ((topic == COMMAND_QMLPROPERTY) ||
+ (topic == COMMAND_QMLPROPERTYGROUP) ||
+ (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ isQmlPropertyTopic = true;
+ }
}
-
+ // if (isQmlPropertyTopic && doc.location().fileName().endsWith("qquickitem.cpp")) {
NodeList nodes;
- QList<Doc> docs;
+ DocList docs;
if (topic.isEmpty()) {
QStringList parentPath;
@@ -2133,43 +2202,39 @@ bool CppCodeParser::matchDocsAndStuff()
.arg(COMMAND_FN).arg(COMMAND_PAGE));
}
}
+ else if (isQmlPropertyTopic) {
+ Doc nodeDoc = doc;
+ processQmlProperties(nodeDoc, nodes, docs);
+ }
else {
- /*
- There is a topic command. Process it.
- */
- if ((topic == COMMAND_QMLPROPERTY) ||
- (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ ArgList args;
+ const QSet<QString>& topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
+ if (topicCommandsUsed.count() > 0) {
+ topic = *topicCommandsUsed.constBegin();
+ args = doc.metaCommandArgs(topic);
+ }
+ if (topicCommandsUsed.count() > 1) {
+ QString topics;
+ QSet<QString>::ConstIterator t = topicCommandsUsed.constBegin();
+ while (t != topicCommandsUsed.constEnd()) {
+ topics += " \\" + *t + ",";
+ ++t;
+ }
+ topics[topics.lastIndexOf(',')] = '.';
+ int i = topics.lastIndexOf(',');
+ topics[i] = ' ';
+ topics.insert(i+1,"and");
+ doc.location().warning(tr("Multiple topic commands found in comment: %1").arg(topics));
+ }
+ ArgList::ConstIterator a = args.constBegin();
+ while (a != args.constEnd()) {
Doc nodeDoc = doc;
- Node *node = processTopicCommandGroup(nodeDoc, topic,args);
+ Node *node = processTopicCommand(nodeDoc,topic,*a);
if (node != 0) {
nodes.append(node);
docs.append(nodeDoc);
}
- }
- else {
- if (topicCommandsUsed.count() > 1) {
- QString topics;
- QSet<QString>::ConstIterator t = topicCommandsUsed.constBegin();
- while (t != topicCommandsUsed.constEnd()) {
- topics += " \\" + *t + ",";
- ++t;
- }
- topics[topics.lastIndexOf(',')] = '.';
- int i = topics.lastIndexOf(',');
- topics[i] = ' ';
- topics.insert(i+1,"and");
- doc.location().warning(tr("Multiple topic commands found in comment: %1").arg(topics));
- }
- ArgList::ConstIterator a = args.constBegin();
- while (a != args.constEnd()) {
- Doc nodeDoc = doc;
- Node *node = processTopicCommand(nodeDoc,topic,*a);
- if (node != 0) {
- nodes.append(node);
- docs.append(nodeDoc);
- }
- ++a;
- }
+ ++a;
}
}
@@ -2262,7 +2327,7 @@ bool CppCodeParser::makeFunctionNode(const QString& signature,
the \a type.
\a parent is the QML class node. The QML module and QML
- element names have already been consumed to find \a parent.
+ type names have already been consumed to find \a parent.
What remains in \a sig is the method signature. The method
must be a child of \a parent.
*/
diff --git a/src/tools/qdoc/cppcodeparser.h b/src/tools/qdoc/cppcodeparser.h
index 957142712b..5ab72f7f54 100644
--- a/src/tools/qdoc/cppcodeparser.h
+++ b/src/tools/qdoc/cppcodeparser.h
@@ -84,13 +84,16 @@ public:
virtual void doneParsingSourceFiles();
protected:
- virtual QSet<QString> topicCommands();
+ const QSet<QString>& topicCommands();
+ const QSet<QString>& otherMetaCommands();
virtual Node* processTopicCommand(const Doc& doc,
const QString& command,
const ArgLocPair& arg);
- virtual Node *processTopicCommandGroup(const Doc& doc,
- const QString& command,
- const ArgList& args);
+ void processQmlProperties(const Doc& doc, NodeList& nodes, DocList& docs);
+ bool splitQmlPropertyGroupArg(const QString& arg,
+ QString& module,
+ QString& element,
+ QString& name);
bool splitQmlPropertyArg(const QString& arg,
QString& type,
QString& module,
@@ -100,7 +103,6 @@ protected:
QString& type,
QString& module,
QString& element);
- virtual QSet<QString> otherMetaCommands();
virtual void processOtherMetaCommand(const Doc& doc,
const QString& command,
const ArgLocPair& argLocPair,
@@ -212,6 +214,7 @@ protected:
#define COMMAND_QMLCLASS Doc::alias("qmlclass")
#define COMMAND_QMLTYPE Doc::alias("qmltype")
#define COMMAND_QMLPROPERTY Doc::alias("qmlproperty")
+#define COMMAND_QMLPROPERTYGROUP Doc::alias("qmlpropertygroup")
#define COMMAND_QMLATTACHEDPROPERTY Doc::alias("qmlattachedproperty")
#define COMMAND_QMLINHERITS Doc::alias("inherits")
#define COMMAND_QMLINSTANTIATES Doc::alias("instantiates")
@@ -238,6 +241,7 @@ protected:
#define COMMAND_LICENSENAME Doc::alias("licensename")
#define COMMAND_LICENSEDESCRIPTION Doc::alias("licensedescription")
#define COMMAND_RELEASEDATE Doc::alias("releasedate")
+#define COMMAND_QTVARIABLE Doc::alias("qtvariable")
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp
index 96f5519be4..241fcbba43 100644
--- a/src/tools/qdoc/ditaxmlgenerator.cpp
+++ b/src/tools/qdoc/ditaxmlgenerator.cpp
@@ -3677,8 +3677,8 @@ QString DitaXmlGenerator::guidForNode(const Node* node)
return fn->guid();
}
case Node::Document:
- if (node->subType() != Node::QmlPropertyGroup)
- break;
+ break;
+ case Node::QmlPropertyGroup:
case Node::QmlProperty:
case Node::Property:
return node->guid();
@@ -3743,7 +3743,7 @@ QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative)
}
QString link = fn;
- if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) {
+ if (!node->isInnerNode() || node->type() == Node::QmlPropertyGroup) {
QString guid = guidForNode(node);
if (relative && fn == fileName(relative) && guid == guidForNode(relative)) {
return QString();
@@ -3758,7 +3758,7 @@ QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative)
back down into the other subdirectory.
*/
if (node && relative && (node != relative)) {
- if (node->outputSubdirectory() != relative->outputSubdirectory())
+ if (useOutputSubdirs() && node->outputSubdirectory() != relative->outputSubdirectory())
link.prepend(QString("../" + node->outputSubdirectory() + QLatin1Char('/')));
}
return link;
@@ -4079,8 +4079,8 @@ void DitaXmlGenerator::generateDetailedQmlMember(Node* node,
QString marked;
QmlPropertyNode* qpn = 0;
- if (node->subType() == Node::QmlPropertyGroup) {
- const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
+ if (node->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
if (qpgn->childNodes().size() == 1) {
qpn = static_cast<QmlPropertyNode*>(*p);
@@ -4114,50 +4114,10 @@ void DitaXmlGenerator::generateDetailedQmlMember(Node* node,
}
else if (node->type() == Node::QmlProperty) {
qpn = static_cast<QmlPropertyNode*>(node);
- if (qpn->qmlPropNodes().isEmpty()) {
- startQmlProperty(qpn,relative,marker);
- writeApiDesc(node, marker, node->title());
- writeEndTag(); // </qmlPropertyDetail>
- writeEndTag(); // </qmlProperty>
- }
- else if (qpn->qmlPropNodes().size() == 1) {
- Node* n = qpn->qmlPropNodes().at(0);
- if (n->type() == Node::QmlProperty) {
- qpn = static_cast<QmlPropertyNode*>(n);
- startQmlProperty(qpn,relative,marker);
- writeApiDesc(node, marker, node->title());
- writeEndTag(); // </qmlPropertyDetail>
- writeEndTag(); // </qmlProperty>
- }
- }
- else {
- /*
- The QML property node has multiple override nodes.
- Process the whole list as we would for a QML property
- group.
- */
- writeStartTag(DT_qmlPropertyGroup);
- QString id = "id-qml-propertygroup-" + node->name();
- id.replace('.','-');
- xmlWriter().writeAttribute("id",id);
- writeStartTag(DT_apiName);
- //writeCharacters("...");
- writeEndTag(); // </apiName>
- writeStartTag(DT_qmlPropertyGroupDetail);
- writeApiDesc(node, marker, node->title());
- writeEndTag(); // </qmlPropertyGroupDetail>
- NodeList::ConstIterator p = qpn->qmlPropNodes().constBegin();
- while (p != qpn->qmlPropNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- QmlPropertyNode* q = static_cast<QmlPropertyNode*>(*p);
- startQmlProperty(q,relative,marker);
- writeEndTag(); // </qmlPropertyDetail>
- writeEndTag(); // </qmlProperty>
- }
- ++p;
- }
- writeEndTag(); // </qmlPropertyGroup
- }
+ startQmlProperty(qpn,relative,marker);
+ writeApiDesc(node, marker, node->title());
+ writeEndTag(); // </qmlPropertyDetail>
+ writeEndTag(); // </qmlProperty>
}
else if (node->type() == Node::QmlSignal)
writeQmlRef(DT_qmlSignal,node,relative,marker);
@@ -5326,13 +5286,13 @@ DitaXmlGenerator::generateInnerNode(InnerNode* node)
return;
if (docNode->subType() == Node::Image)
return;
- if (docNode->subType() == Node::QmlPropertyGroup)
- return;
if (docNode->subType() == Node::Page) {
if (node->count() > 0)
qDebug("PAGE %s HAS CHILDREN", qPrintable(docNode->title()));
}
}
+ else if (node->type() == Node::QmlPropertyGroup)
+ return;
/*
Obtain a code marker for the source file.
@@ -5487,8 +5447,6 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent)
if (!isDuplicate(nodeSubtypeMaps[Node::QmlClass],child->title(),child))
nodeSubtypeMaps[Node::QmlClass]->insert(child->title(),child);
break;
- case Node::QmlPropertyGroup:
- break;
case Node::QmlBasicType:
if (!isDuplicate(nodeSubtypeMaps[Node::QmlBasicType],child->title(),child))
nodeSubtypeMaps[Node::QmlBasicType]->insert(child->title(),child);
@@ -5517,6 +5475,8 @@ Node* DitaXmlGenerator::collectNodesByTypeAndSubtype(const InnerNode* parent)
break;
case Node::QmlProperty:
break;
+ case Node::QmlPropertyGroup:
+ break;
case Node::QmlSignal:
break;
case Node::QmlSignalHandler:
diff --git a/src/tools/qdoc/doc.cpp b/src/tools/qdoc/doc.cpp
index 42b98502e0..4d6b0b1a2c 100644
--- a/src/tools/qdoc/doc.cpp
+++ b/src/tools/qdoc/doc.cpp
@@ -80,7 +80,6 @@ enum {
CMD_ANNOTATEDLIST,
CMD_B,
CMD_BADCODE,
- CMD_BASENAME,
CMD_BOLD,
CMD_BR,
CMD_BRIEF,
@@ -198,7 +197,6 @@ static struct {
{ "annotatedlist", CMD_ANNOTATEDLIST, 0 },
{ "b", CMD_B, 0 },
{ "badcode", CMD_BADCODE, 0 },
- { "basename", CMD_BASENAME, 0 }, // ### don't document for now
{ "bold", CMD_BOLD, 0 },
{ "br", CMD_BR, 0 },
{ "brief", CMD_BRIEF, 0 },
@@ -316,7 +314,6 @@ Q_GLOBAL_STATIC(QHash_QString_Macro, macroHash)
class DocPrivateExtra
{
public:
- QString baseName;
Doc::Sections granularity;
Doc::Sections section; // ###
QList<Atom*> tableOfContents;
@@ -376,7 +373,7 @@ public:
bool hasLegalese : 1;
bool hasSectioningUnits : 1;
DocPrivateExtra *extra;
- TopicList topics;
+ TopicList topics_;
DitaRefList ditamap_;
};
@@ -466,7 +463,6 @@ private:
Location& location();
QString detailsUnknownCommand(const QSet<QString>& metaCommandSet,
const QString& str);
- void insertBaseName(const QString &baseName);
void insertTarget(const QString& target, bool keyword);
void include(const QString& fileName, const QString& identifier);
void startFormat(const QString& format, int cmd);
@@ -571,7 +567,7 @@ void DocParser::parse(const QString& source,
cachedPos = 0;
priv = docPrivate;
priv->text << Atom::Nop;
- priv->topics.clear();
+ priv->topics_.clear();
paraState = OutsideParagraph;
inTableHeader = false;
@@ -644,10 +640,6 @@ void DocParser::parse(const QString& source,
leavePara();
append(Atom::CodeBad,getCode(CMD_BADCODE, marker));
break;
- case CMD_BASENAME:
- leavePara();
- insertBaseName(getArgument());
- break;
case CMD_BR:
leavePara();
append(Atom::BR);
@@ -1404,7 +1396,7 @@ void DocParser::parse(const QString& source,
QString arg = getMetaCommandArgument(cmdStr);
priv->metaCommandMap[cmdStr].append(ArgLocPair(arg,location()));
if (possibleTopics.contains(cmdStr)) {
- priv->topics.append(Topic(cmdStr,arg));
+ priv->topics_.append(Topic(cmdStr,arg));
}
}
else if (macroHash()->contains(cmdStr)) {
@@ -1669,29 +1661,6 @@ QString DocParser::detailsUnknownCommand(const QSet<QString> &metaCommandSet,
return tr("Maybe you meant '\\%1'?").arg(best);
}
-void DocParser::insertBaseName(const QString &baseName)
-{
- priv->constructExtra();
- if (currentSection == priv->extra->section) {
- priv->extra->baseName = baseName;
- }
- else {
- Atom *atom = priv->text.firstAtom();
- Atom *sectionLeft = 0;
-
- int delta = currentSection - priv->extra->section;
-
- while (atom != 0) {
- if (atom->type() == Atom::SectionLeft &&
- atom->string().toInt() == delta)
- sectionLeft = atom;
- atom = atom->next();
- }
- if (sectionLeft != 0)
- (void) new Atom(sectionLeft, Atom::BaseName, baseName);
- }
-}
-
void DocParser::insertTarget(const QString &target, bool keyword)
{
if (targetMap.contains(target)) {
@@ -2751,6 +2720,7 @@ QString DocParser::slashed(const QString& str)
#define COMMAND_BRIEF Doc::alias("brief")
#define COMMAND_QMLBRIEF Doc::alias("qmlbrief")
+#if 0
Doc::Doc(const Location& start_loc,
const Location& end_loc,
const QString& source,
@@ -2760,6 +2730,7 @@ Doc::Doc(const Location& start_loc,
DocParser parser;
parser.parse(source,priv,metaCommandSet,QSet<QString>());
}
+#endif
/*!
Parse the qdoc comment \a source. Build up a list of all the topic
@@ -2978,17 +2949,6 @@ Text Doc::legaleseText() const
return body().subText(Atom::LegaleseLeft, Atom::LegaleseRight);
}
-const QString& Doc::baseName() const
-{
- static QString null;
- if (priv == 0 || priv->extra == 0) {
- return null;
- }
- else {
- return priv->extra->baseName;
- }
-}
-
Doc::Sections Doc::granularity() const
{
if (priv == 0 || priv->extra == 0) {
@@ -3026,7 +2986,7 @@ const QSet<QString> &Doc::metaCommandsUsed() const
*/
const TopicList& Doc::topicsUsed() const
{
- return priv == 0 ? *nullTopicList() : priv->topics;
+ return priv == 0 ? *nullTopicList() : priv->topics_;
}
ArgList Doc::metaCommandArgs(const QString& metacommand) const
diff --git a/src/tools/qdoc/doc.h b/src/tools/qdoc/doc.h
index ca9787595f..bd3d623a05 100644
--- a/src/tools/qdoc/doc.h
+++ b/src/tools/qdoc/doc.h
@@ -71,7 +71,10 @@ struct Topic
{
QString topic;
QString args;
+ Topic() { }
Topic(QString& t, QString a) : topic(t), args(a) { }
+ bool isEmpty() const { return topic.isEmpty(); }
+ void clear() { topic.clear(); args.clear(); }
};
typedef QList<Topic> TopicList;
@@ -136,10 +139,6 @@ public:
};
Doc() : priv(0) {}
- Doc(const Location &start_loc,
- const Location &end_loc,
- const QString &source,
- const QSet<QString> &metaCommandSet);
Doc(const Location& start_loc,
const Location& end_loc,
const QString& source,
@@ -165,7 +164,6 @@ public:
Text briefText(bool inclusive = false) const;
Text trimmedBriefText(const QString &className) const;
Text legaleseText() const;
- const QString& baseName() const;
Sections granularity() const;
const QSet<QString> &parameterNames() const;
const QStringList &enumItemNames() const;
@@ -196,6 +194,7 @@ private:
void detach();
DocPrivate *priv;
};
+typedef QList<Doc> DocList;
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/doc/config/qdoc.qdocconf b/src/tools/qdoc/doc/config/qdoc.qdocconf
index a7fbb38463..a6ae18a675 100644
--- a/src/tools/qdoc/doc/config/qdoc.qdocconf
+++ b/src/tools/qdoc/doc/config/qdoc.qdocconf
@@ -70,3 +70,5 @@ depends += \
qtwebkitexamples \
qtxml \
qtxmlpatterns
+
+navigation.landingpage = "QDoc Manual"
diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp
index 889f0f55ca..f8d4910c28 100644
--- a/src/tools/qdoc/generator.cpp
+++ b/src/tools/qdoc/generator.cpp
@@ -97,7 +97,9 @@ QStringList Generator::styleDirs;
QStringList Generator::styleFiles;
bool Generator::debugging_ = false;
bool Generator::noLinkErrors_ = false;
+bool Generator::redirectDocumentationToDevNull_ = false;
Generator::Passes Generator::qdocPass_ = Both;
+bool Generator::useOutputSubdirs_ = true;
void Generator::setDebugSegfaultFlag(bool b)
{
@@ -263,14 +265,17 @@ void Generator::writeOutFileNames()
void Generator::beginSubPage(const InnerNode* node, const QString& fileName)
{
QString path = outputDir() + QLatin1Char('/');
- if (!node->outputSubdirectory().isEmpty())
+ if (Generator::useOutputSubdirs() && !node->outputSubdirectory().isEmpty())
path += node->outputSubdirectory() + QLatin1Char('/');
path += fileName;
- Generator::debugSegfault("Writing: " + path);
- outFileNames.insert(fileName,fileName);
- QFile* outFile = new QFile(path);
+
+ QFile* outFile = new QFile(redirectDocumentationToDevNull_ ? QStringLiteral("/dev/null") : path);
+ if (outFile->exists())
+ node->location().error(tr("HTML file already exists; overwriting %1").arg(outFile->fileName()));
if (!outFile->open(QFile::WriteOnly))
node->location().fatal(tr("Cannot open output file '%1'").arg(outFile->fileName()));
+ Generator::debugSegfault("Writing: " + path);
+ outFileNames.insert(fileName,fileName);
QTextStream* out = new QTextStream(outFile);
#ifndef QT_NO_TEXTCODEC
@@ -299,14 +304,22 @@ QString Generator::fileBase(const Node *node) const
node = node->relates();
else if (!node->isInnerNode())
node = node->parent();
- if (node->subType() == Node::QmlPropertyGroup) {
+ if (node->type() == Node::QmlPropertyGroup) {
node = node->parent();
}
- QString base = node->doc().baseName();
- if (!base.isEmpty())
- return base;
+ if (node->type() == Node::Document && node->subType() == Node::Collision) {
+ const NameCollisionNode* ncn = static_cast<const NameCollisionNode*>(node);
+ if (ncn->currentChild())
+ return fileBase(ncn->currentChild());
+ }
+
+ if (node->hasBaseName()) {
+ //qDebug() << "RETURNING:" << node->baseName();
+ return node->baseName();
+ }
+ QString base;
const Node *p = node;
forever {
@@ -375,6 +388,8 @@ QString Generator::fileBase(const Node *node) const
}
while (res.endsWith(QLatin1Char('-')))
res.chop(1);
+ Node* n = const_cast<Node*>(node);
+ n->setBaseName(res);
return res;
}
@@ -407,7 +422,7 @@ QMap<QString, QString>& Generator::formattingRightMap()
/*!
Returns the full document location.
*/
-QString Generator::fullDocumentLocation(const Node *node, bool subdir)
+QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
{
if (!node)
return QString();
@@ -419,11 +434,11 @@ QString Generator::fullDocumentLocation(const Node *node, bool subdir)
QString fdl;
/*
- If the output is being sent to subdirectories of the
- output directory, and if the subdir parameter is set,
- prepend the subdirectory name + '/' to the result.
+ If the useSubdir parameter is set, then the output is
+ being sent to subdirectories of the output directory.
+ Prepend the subdirectory name + '/' to the result.
*/
- if (subdir) {
+ if (useSubdir) {
fdl = node->outputSubdirectory();
if (!fdl.isEmpty())
fdl.append(QLatin1Char('/'));
@@ -467,7 +482,7 @@ QString Generator::fullDocumentLocation(const Node *node, bool subdir)
parentName = fullDocumentLocation(node->relates());
}
else if ((parentNode = node->parent())) {
- if (parentNode->subType() == Node::QmlPropertyGroup) {
+ if (parentNode->type() == Node::QmlPropertyGroup) {
parentNode = parentNode->parent();
parentName = fullDocumentLocation(parentNode);
}
@@ -933,6 +948,8 @@ void Generator::generateInnerNode(InnerNode* node)
{
if (!node->url().isNull())
return;
+ if (node->isIndexNode())
+ return;
if (node->type() == Node::Document) {
DocNode* docNode = static_cast<DocNode*>(node);
@@ -940,13 +957,13 @@ void Generator::generateInnerNode(InnerNode* node)
return;
if (docNode->subType() == Node::Image)
return;
- if (docNode->subType() == Node::QmlPropertyGroup)
- return;
if (docNode->subType() == Node::Page) {
if (node->count() > 0)
qDebug("PAGE %s HAS CHILDREN", qPrintable(docNode->title()));
}
}
+ else if (node->type() == Node::QmlPropertyGroup)
+ return;
/*
Obtain a code marker for the source file.
@@ -1099,7 +1116,10 @@ void Generator::generateSince(const Node *node, CodeMarker *marker)
if (project.isEmpty())
text << "version";
else
- text << project;
+ text << Atom(Atom::Link, project)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, project)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
text << " " << since[0];
} else {
// Reconstruct the <project> <version> string.
@@ -1474,7 +1494,12 @@ QString Generator::indent(int level, const QString& markedCode)
void Generator::initialize(const Config &config)
{
+
+ if (config.getBool(QString("HTML.nosubdirs")))
+ resetUseOutputSubdirs();
+
outputFormats = config.getOutputFormats();
+ redirectDocumentationToDevNull_ = config.getBool(CONFIG_REDIRECTDOCUMENTATIONTODEVNULL);
if (!outputFormats.isEmpty()) {
outDir_ = config.getOutputDir();
if (outDir_.isEmpty()) {
@@ -1487,7 +1512,7 @@ void Generator::initialize(const Config &config)
QDir dirInfo;
if (dirInfo.exists(outDir_)) {
- if (!runGenerateOnly()) {
+ if (!runGenerateOnly() && Generator::useOutputSubdirs()) {
if (!Config::removeDirContents(outDir_))
config.lastLocation().error(tr("Cannot empty output directory '%1'").arg(outDir_));
}
@@ -1907,8 +1932,6 @@ QString Generator::typeString(const Node *node)
switch (node->subType()) {
case Node::QmlClass:
return "type";
- case Node::QmlPropertyGroup:
- return "property group";
case Node::QmlBasicType:
return "type";
default:
@@ -1923,6 +1946,16 @@ QString Generator::typeString(const Node *node)
return "function";
case Node::Property:
return "property";
+ case Node::QmlPropertyGroup:
+ return "property group";
+ case Node::QmlProperty:
+ return "QML property";
+ case Node::QmlSignal:
+ return "QML signal";
+ case Node::QmlSignalHandler:
+ return "QML signal handler";
+ case Node::QmlMethod:
+ return "QML method";
default:
return "documentation";
}
diff --git a/src/tools/qdoc/generator.h b/src/tools/qdoc/generator.h
index 58e9073922..52d73e8dea 100644
--- a/src/tools/qdoc/generator.h
+++ b/src/tools/qdoc/generator.h
@@ -81,7 +81,7 @@ public:
virtual void initializeGenerator(const Config &config);
virtual void terminateGenerator();
- QString fullDocumentLocation(const Node *node, bool subdir = false);
+ QString fullDocumentLocation(const Node *node, bool useSubdir = false);
const Config* config() { return config_; }
static Generator *currentGenerator() { return currentGenerator_; }
@@ -100,6 +100,8 @@ public:
static bool runPrepareOnly() { return (qdocPass_ == Prepare); }
static bool runGenerateOnly() { return (qdocPass_ == Generate); }
static QString defaultModuleName() { return project; }
+ static void resetUseOutputSubdirs() { useOutputSubdirs_ = false; }
+ static bool useOutputSubdirs() { return useOutputSubdirs_; }
protected:
virtual void beginSubPage(const InnerNode* node, const QString& fileName);
@@ -185,6 +187,17 @@ protected:
QString tagFile_;
QStack<QTextStream*> outStreamStack;
+ void appendFullName(Text& text,
+ const Node *apparentNode,
+ const Node *relative,
+ const Node *actualNode = 0);
+ void appendFullName(Text& text,
+ const Node *apparentNode,
+ const QString& fullName,
+ const Node *actualNode);
+ void appendFullNames(Text& text, const NodeList& nodes, const Node* relative);
+ void appendSortedNames(Text& text, const ClassNode *classe, const QList<RelatedClass> &classes);
+
private:
static Generator* currentGenerator_;
static QStringList exampleDirs;
@@ -206,18 +219,10 @@ private:
static QStringList styleFiles;
static bool debugging_;
static bool noLinkErrors_;
+ static bool redirectDocumentationToDevNull_;
static Passes qdocPass_;
+ static bool useOutputSubdirs_;
- void appendFullName(Text& text,
- const Node *apparentNode,
- const Node *relative,
- const Node *actualNode = 0);
- void appendFullName(Text& text,
- const Node *apparentNode,
- const QString& fullName,
- const Node *actualNode);
- void appendFullNames(Text& text, const NodeList& nodes, const Node* relative);
- void appendSortedNames(Text& text, const ClassNode *classe, const QList<RelatedClass> &classes);
void generateReimplementedFrom(const FunctionNode *func, CodeMarker *marker);
QString amp;
diff --git a/src/tools/qdoc/helpprojectwriter.cpp b/src/tools/qdoc/helpprojectwriter.cpp
index 0cdb2de776..44292f84bb 100644
--- a/src/tools/qdoc/helpprojectwriter.cpp
+++ b/src/tools/qdoc/helpprojectwriter.cpp
@@ -135,6 +135,7 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
typeHash["qmlsignal"] = Node::QmlSignal;
typeHash["qmlsignalhandler"] = Node::QmlSignalHandler;
typeHash["qmlmethod"] = Node::QmlMethod;
+ typeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
QHash<QString, Node::SubType> subTypeHash;
subTypeHash["example"] = Node::Example;
@@ -145,7 +146,6 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
subTypeHash["page"] = Node::Page;
subTypeHash["externalpage"] = Node::ExternalPage;
subTypeHash["qmlclass"] = Node::QmlClass;
- subTypeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
subTypeHash["qmlbasictype"] = Node::QmlBasicType;
QSet<Node::SubType> allSubTypes = QSet<Node::SubType>::fromList(subTypeHash.values());
@@ -225,7 +225,7 @@ QStringList HelpProjectWriter::keywordDetails(const Node *node) const
details << node->name();
details << node->name();
}
- details << gen_->fullDocumentLocation(node,true);
+ details << gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
return details;
}
@@ -285,12 +285,12 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
case Node::Class:
project.keywords.append(keywordDetails(node));
- project.files.insert(gen_->fullDocumentLocation(node,true));
+ project.files.insert(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
break;
case Node::Namespace:
project.keywords.append(keywordDetails(node));
- project.files.insert(gen_->fullDocumentLocation(node,true));
+ project.files.insert(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
break;
case Node::Enum:
@@ -310,7 +310,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
details << item.name(); // "name"
details << item.name(); // "id"
}
- details << gen_->fullDocumentLocation(node,true);
+ details << gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
project.keywords.append(details);
}
}
@@ -342,7 +342,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
if (node->relates()) {
project.memberStatus[node->relates()].insert(node->status());
- project.files.insert(gen_->fullDocumentLocation(node->relates(),true));
+ project.files.insert(gen_->fullDocumentLocation(node->relates(),Generator::useOutputSubdirs()));
} else if (node->parent())
project.memberStatus[node->parent()].insert(node->status());
}
@@ -356,7 +356,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
// Use the location of any associated enum node in preference
// to that of the typedef.
if (enumNode)
- typedefDetails[2] = gen_->fullDocumentLocation(enumNode,true);
+ typedefDetails[2] = gen_->fullDocumentLocation(enumNode,Generator::useOutputSubdirs());
project.keywords.append(typedefDetails);
}
@@ -364,7 +364,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
case Node::Variable:
{
- QString location = gen_->fullDocumentLocation(node,true);
+ QString location = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
project.files.insert(location.left(location.lastIndexOf(QLatin1Char('#'))));
project.keywords.append(keywordDetails(node));
}
@@ -385,18 +385,18 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
QStringList details;
details << keyword->string()
<< keyword->string()
- << gen_->fullDocumentLocation(node,true) +
+ << gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()) +
QLatin1Char('#') + Doc::canonicalTitle(keyword->string());
project.keywords.append(details);
} else
docNode->doc().location().warning(
- tr("Bad keyword in %1").arg(gen_->fullDocumentLocation(node,true))
+ tr("Bad keyword in %1").arg(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()))
);
}
}
project.keywords.append(keywordDetails(node));
}
- project.files.insert(gen_->fullDocumentLocation(node,true));
+ project.files.insert(gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
}
break;
}
@@ -422,6 +422,11 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
void HelpProjectWriter::generateSections(HelpProject &project,
QXmlStreamWriter &writer, const Node *node)
{
+ /*
+ Don't include index nodes in the help file. Or DITA map nodes.
+ */
+ if (node->isIndexNode() || node->subType() == Node::DitaMap)
+ return;
if (!generateSection(project, writer, node))
return;
@@ -431,29 +436,40 @@ void HelpProjectWriter::generateSections(HelpProject &project,
// Ensure that we don't visit nodes more than once.
QMap<QString, const Node*> childMap;
foreach (const Node *childNode, inner->childNodes()) {
+ if (childNode->isIndexNode())
+ continue;
+
if (childNode->access() == Node::Private)
continue;
if (childNode->type() == Node::Document) {
+ childMap[static_cast<const DocNode *>(childNode)->fullTitle()] = childNode;
+ }
+ else if (childNode->type() == Node::QmlPropertyGroup) {
/*
Don't visit QML property group nodes,
but visit their children, which are all
QML property nodes.
+
+ This is probably not correct anymore,
+ because The Qml Property Group is an
+ actual documented thing.
*/
- if (childNode->subType() == Node::QmlPropertyGroup) {
- const InnerNode* inner = static_cast<const InnerNode*>(childNode);
- foreach (const Node* n, inner->childNodes()) {
- if (n->access() == Node::Private)
- continue;
- childMap[n->fullDocumentName()] = n;
- }
+ const InnerNode* inner = static_cast<const InnerNode*>(childNode);
+ foreach (const Node* n, inner->childNodes()) {
+ if (n->access() == Node::Private)
+ continue;
+ childMap[n->fullDocumentName()] = n;
}
- else
- childMap[static_cast<const DocNode *>(childNode)->fullTitle()] = childNode;
}
else {
// Store member status of children
project.memberStatus[node].insert(childNode->status());
+ if (childNode->relates()) {
+ project.memberStatus[childNode->relates()].insert(childNode->status());
+ project.files.insert(gen_->fullDocumentLocation(childNode->relates(),
+ Generator::useOutputSubdirs()));
+ }
if (childNode->type() == Node::Function) {
const FunctionNode *funcNode = static_cast<const FunctionNode *>(childNode);
@@ -508,7 +524,7 @@ void HelpProjectWriter::writeSection(QXmlStreamWriter &writer, const QString &pa
void HelpProjectWriter::addMembers(HelpProject &project, QXmlStreamWriter &writer,
const Node *node, bool writeSections)
{
- QString href = gen_->fullDocumentLocation(node,true);
+ QString href = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
href = href.left(href.size()-5);
if (href.isEmpty())
return;
@@ -546,7 +562,7 @@ void HelpProjectWriter::addMembers(HelpProject &project, QXmlStreamWriter &write
void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer,
const Node *node)
{
- QString href = gen_->fullDocumentLocation(node,true);
+ QString href = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
QString objName = node->name();
switch (node->type()) {
@@ -642,7 +658,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
node = qdb_->findNode(QStringList("index.html"));
QString indexPath;
if (node)
- indexPath = gen_->fullDocumentLocation(node,true);
+ indexPath = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs());
else
indexPath = "index.html";
writer.writeAttribute("ref", indexPath);
@@ -685,7 +701,8 @@ void HelpProjectWriter::generateProject(HelpProject &project)
const DocNode *page = qdb_->findDocNodeByTitle(atom->string());
writer.writeStartElement("section");
- QString indexPath = gen_->fullDocumentLocation(page,true);
+ QString indexPath = gen_->fullDocumentLocation(page,
+ Generator::useOutputSubdirs());
writer.writeAttribute("ref", indexPath);
writer.writeAttribute("title", atom->string());
project.files.insert(indexPath);
@@ -710,7 +727,7 @@ void HelpProjectWriter::generateProject(HelpProject &project)
if (!name.isEmpty()) {
writer.writeStartElement("section");
- QString indexPath = gen_->fullDocumentLocation(qdb_->findDocNodeByTitle(subproject.indexTitle),true);
+ QString indexPath = gen_->fullDocumentLocation(qdb_->findDocNodeByTitle(subproject.indexTitle),Generator::useOutputSubdirs());
writer.writeAttribute("ref", indexPath);
writer.writeAttribute("title", subproject.title);
project.files.insert(indexPath);
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp
index 7cb56974d5..f17e3adde8 100644
--- a/src/tools/qdoc/htmlgenerator.cpp
+++ b/src/tools/qdoc/htmlgenerator.cpp
@@ -166,9 +166,9 @@ void HtmlGenerator::initializeGenerator(const Config &config)
pleaseGenerateMacRef = config.getBool(HtmlGenerator::format() +
Config::dot +
HTMLGENERATOR_GENERATEMACREFS);
- noBreadCrumbs = config.getBool(HtmlGenerator::format() +
+ noNavigationBar = config.getBool(HtmlGenerator::format() +
Config::dot +
- HTMLGENERATOR_NOBREADCRUMBS);
+ HTMLGENERATOR_NONAVIGATIONBAR);
project = config.getString(CONFIG_PROJECT);
@@ -229,6 +229,25 @@ void HtmlGenerator::initializeGenerator(const Config &config)
examplesPath = config.getString(CONFIG_EXAMPLESINSTALLPATH);
if (!examplesPath.isEmpty())
examplesPath += QLatin1Char('/');
+
+ //retrieve the config for the navigation bar
+ homepage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_HOMEPAGE);
+
+ landingpage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_LANDINGPAGE);
+
+ cppclassespage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_CPPCLASSESPAGE);
+
+ qmltypespage = config.getString(CONFIG_NAVIGATION
+ + Config::dot
+ + CONFIG_QMLTYPESPAGE);
+
+ buildversion = config.getString(CONFIG_BUILDVERSION);
}
/*!
@@ -1095,8 +1114,6 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
QList<Section> sections;
QList<Section>::ConstIterator s;
- ClassNode* classe = 0;
-
QString title;
QString rawTitle;
QString fullTitle;
@@ -1106,7 +1123,6 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
title = rawTitle + " Namespace";
}
else if (inner->type() == Node::Class) {
- classe = static_cast<ClassNode*>(inner);
rawTitle = inner->plainName();
fullTitle = inner->plainFullName();
title = rawTitle + " Class";
@@ -1121,16 +1137,9 @@ void HtmlGenerator::generateClassLikeNode(InnerNode* inner, CodeMarker* marker)
generateTableOfContents(inner,marker,&sections);
generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
generateBrief(inner, marker);
- generateIncludes(inner, marker);
+ generateRequisites(inner, marker);
generateStatus(inner, marker);
- if (classe) {
- generateInherits(classe, marker);
- generateInheritedBy(classe, marker);
- if (classe->qmlElement() != 0)
- generateInstantiatedBy(classe,marker);
- }
generateThreadSafeness(inner, marker);
- generateSince(inner, marker);
out() << "<ul>\n";
@@ -1511,10 +1520,7 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker)
const_cast<DocNode*>(dn)->setCurrentChild();
ClassNode* cn = qml_cn->classNode();
generateBrief(qml_cn, marker);
- generateQmlInherits(qml_cn, marker);
- generateQmlInheritedBy(qml_cn, marker);
- generateQmlInstantiates(qml_cn, marker);
- generateSince(qml_cn, marker);
+ generateQmlRequisites(qml_cn, marker);
QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker);
if (!allQmlMembersLink.isEmpty()) {
@@ -1616,129 +1622,67 @@ QString HtmlGenerator::fileExtension() const
}
/*!
- Output breadcrumb list in the html file.
+ Output navigation list in the html file.
*/
-void HtmlGenerator::generateBreadCrumbs(const QString &title,
+void HtmlGenerator::generateNavigationBar(const QString &title,
const Node *node,
CodeMarker *marker)
{
- if (noBreadCrumbs)
+ if (noNavigationBar)
return;
- Text breadcrumbs;
+ Text navigationbar;
+
+ if (homepage == title)
+ return;
+ if (!homepage.isEmpty())
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::AutoLink, homepage)
+ << Atom(Atom::ListItemRight);
+ if (!landingpage.isEmpty() && landingpage != title)
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::AutoLink, landingpage)
+ << Atom(Atom::ListItemRight);
+
if (node->type() == Node::Class) {
const ClassNode *cn = static_cast<const ClassNode *>(node);
QString name = node->moduleName();
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("All Modules"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Modules"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- if (!name.isEmpty())
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, name)
+
+ if (!cppclassespage.isEmpty())
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::Link, cppclassespage)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, QLatin1String("C++ Classes"))
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
<< Atom(Atom::ListItemRight);
+
if (!cn->name().isEmpty())
- breadcrumbs << Atom(Atom::ListItemLeft)
+ navigationbar << Atom(Atom::ListItemLeft)
<< Atom(Atom::String, protectEnc(cn->name()))
<< Atom(Atom::ListItemRight);
}
else if (node->type() == Node::Document) {
- const DocNode* fn = static_cast<const DocNode*>(node);
- if (node->subType() == Node::Module) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("All Modules"))
+ if (node->subType() == Node::QmlClass || node->subType() == Node::QmlBasicType) {
+ if (!qmltypespage.isEmpty())
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::Link, qmltypespage)
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Modules"))
+ << Atom(Atom::String, QLatin1String("QML Types"))
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
<< Atom(Atom::ListItemRight);
- QString name = node->name();
- if (!name.isEmpty())
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(name))
- << Atom(Atom::ListItemRight);
- }
- else if (node->subType() == Node::Group) {
- if (fn->name() == QString("modules"))
- breadcrumbs << Atom(Atom::String, QLatin1String("Modules"));
- else
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- else if (node->subType() == Node::Page) {
- if (fn->name() == QString("qdeclarativeexamples.html")) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("Qt Examples"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Examples"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, QLatin1String("QML Examples & Demos"))
- << Atom(Atom::ListItemRight);
- }
- else if (fn->name().startsWith("examples-")) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("Qt Examples"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Examples"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- else if (fn->name() == QString("namespaces.html"))
- breadcrumbs << Atom(Atom::String, QLatin1String("Namespaces"));
- else
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- else if (node->subType() == Node::QmlClass) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, QLatin1String("Basic QML Types"))
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
+
+ navigationbar << Atom(Atom::ListItemLeft)
<< Atom(Atom::String, protectEnc(title))
<< Atom(Atom::ListItemRight);
}
- else if (node->subType() == Node::Example) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("Qt Examples"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Examples"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- QStringList sl = fn->name().split('/');
- if (sl.contains("declarative"))
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::AutoLink, QLatin1String("QML Examples & Demos"))
- << Atom(Atom::ListItemRight);
- else {
- QString name = protectEnc("examples-" + sl.at(0) + ".html"); // this generates an empty link
- QString t = CodeParser::titleFromName(name);
- }
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
+ else {
+ navigationbar << Atom(Atom::ListItemLeft)
+ << Atom(Atom::String, protectEnc(title))
+ << Atom(Atom::ListItemRight);
}
}
- else if (node->type() == Node::Namespace) {
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::Link, QLatin1String("All Namespaces"))
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, QLatin1String("Namespaces"))
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
- << Atom(Atom::ListItemRight);
- breadcrumbs << Atom(Atom::ListItemLeft)
- << Atom(Atom::String, protectEnc(title))
- << Atom(Atom::ListItemRight);
- }
- generateText(breadcrumbs, node, marker);
+ generateText(navigationbar, node, marker);
}
void HtmlGenerator::generateHeader(const QString& title,
@@ -1782,7 +1726,8 @@ void HtmlGenerator::generateHeader(const QString& title,
#endif
out() << QString(postHeader).replace("\\" + COMMAND_VERSION, qdb_->version());
- generateBreadCrumbs(title,node,marker);
+ generateNavigationBar(title,node,marker);
+ out() << "<li id=\"buildversion\">\n" << buildversion << "</li>\n";
out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, qdb_->version());
navigationLinks.clear();
@@ -1881,6 +1826,271 @@ void HtmlGenerator::generateFooter(const Node *node)
out() << "</html>\n";
}
+/*!
+Lists the required imports and includes in a table.
+The number of rows is known, so this path is simpler than the generateSection() path.
+*/
+void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker)
+{
+ QMap<QString, Text> requisites;
+ Text text;
+
+ const QString headerText = "Header";
+ const QString sinceText = "Since";
+ const QString inheritedBytext = "Inherited By";
+ const QString inheritsText = "Inherits";
+ const QString instantiatedByText = "Instantiated By";
+ const QString qtVariableText = "qmake";
+
+ //add the includes to the map
+ if (!inner->includes().isEmpty()) {
+ text.clear();
+ text << formattingRightMap()[ATOM_FORMATTING_BOLD]
+ << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]
+ << highlightedCode(indent(codeIndent,
+ marker->markedUpIncludes(inner->includes())),
+ inner)
+ << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
+ requisites.insert(headerText, text);
+ }
+
+ //The order of the requisites matter
+ QStringList requisiteorder;
+ requisiteorder << headerText
+ << qtVariableText
+ << sinceText
+ << instantiatedByText
+ << inheritsText
+ << inheritedBytext;
+
+ //add the since and project into the map
+ if (!inner->since().isEmpty()) {
+ text.clear();
+ QStringList since = inner->since().split(QLatin1Char(' '));
+ if (since.count() == 1) {
+ // Handle legacy use of \since <version>.
+ if (project.isEmpty())
+ text << "version";
+ else
+ text << Atom(Atom::Link, project)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, project)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << " " << since[0];
+ }
+ else {
+ // Reconstruct the <project> <version> string.
+ text << " " << since.join(' ');
+ }
+ text << Atom::ParaRight;
+ requisites.insert(sinceText, text);
+ }
+
+ //add the instantiated-by to the map if the class node is not internal
+ if (inner->type() == Node::Class) {
+ ClassNode* classe = static_cast<ClassNode*>(inner);
+ if (classe->qmlElement() != 0 && classe->status() != Node::Internal) {
+ text.clear();
+ text << Atom(Atom::LinkNode, CodeMarker::stringForNode(classe->qmlElement()))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, classe->qmlElement()->name())
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ requisites.insert(instantiatedByText, text);
+
+ }
+
+ //add the inherits to the map
+ QList<RelatedClass>::ConstIterator r;
+ int index;
+ if (!classe->baseClasses().isEmpty()) {
+ text.clear();
+ r = classe->baseClasses().constBegin();
+ index = 0;
+ while (r != classe->baseClasses().constEnd()) {
+ text << Atom(Atom::LinkNode, CodeMarker::stringForNode((*r).node))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, (*r).dataTypeWithTemplateArgs)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+
+ if ((*r).access == Node::Protected) {
+ text << " (protected)";
+ }
+ else if ((*r).access == Node::Private) {
+ text << " (private)";
+ }
+ text << separator(index++, classe->baseClasses().count());
+ ++r;
+ }
+ text << Atom::ParaRight;
+ requisites.insert(inheritsText, text);
+ }
+
+ //add the inherited-by to the map
+ if (!classe->derivedClasses().isEmpty()) {
+ text.clear();
+ text << Atom::ParaLeft;
+ appendSortedNames(text, classe, classe->derivedClasses());
+ text << Atom::ParaRight;
+ requisites.insert(inheritedBytext, text);
+ }
+
+ //add the QT variable to the map
+ DocNode * moduleNode = qdb_->findModule(classe->moduleName());
+ if (moduleNode && !moduleNode->qtVariable().isEmpty()) {
+ text.clear();
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_TELETYPE)
+ << "QT += " + moduleNode->qtVariable()
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_TELETYPE);
+ requisites.insert(qtVariableText, text);
+ }
+
+ }
+
+ if (!requisites.isEmpty()) {
+ //generate the table
+ out() << "<table class=\"alignedsummary\">\n";
+
+ QStringList::ConstIterator i;
+ for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) {
+
+ if (requisites.contains(*i)) {
+ out() << "<tr>"
+ << "<td class=\"memItemLeft rightAlign topAlign\"> "
+ << *i << ":"
+ << "</td><td class=\"memItemRight bottomAlign\"> ";
+
+ if (*i == headerText)
+ out() << requisites.value(*i).toString();
+ else
+ generateText(requisites.value(*i), inner, marker);
+ out() << "</td></tr>";
+ }
+ }
+ out() << "</table>";
+ }
+}
+
+/*!
+Lists the required imports and includes in a table.
+The number of rows is known, so this path is simpler than the generateSection() path.
+*/
+void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker)
+{
+ if (!qcn)
+ return;
+ QMap<QString, Text> requisites;
+ Text text;
+
+ const QString importText = "Import Statement:";
+ const QString sinceText = "Since:";
+ const QString inheritedBytext = "Inherited By:";
+ const QString inheritsText = "Inherits:";
+ const QString instantiatesText = "Instantiates:";
+
+ //The order of the requisites matter
+ QStringList requisiteorder;
+ requisiteorder << importText
+ << sinceText
+ << instantiatesText
+ << inheritsText
+ << inheritedBytext;
+
+ //add the module name and version to the map
+ text.clear();
+ text << formattingRightMap()[ATOM_FORMATTING_BOLD]
+ << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]
+ << "import " + qcn->qmlModuleName() + " " + qcn->qmlModuleVersion()
+ << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
+ requisites.insert(importText, text);
+
+ //add the since and project into the map
+ if (!qcn->since().isEmpty()) {
+ text.clear();
+ QStringList since = qcn->since().split(QLatin1Char(' '));
+ if (since.count() == 1) {
+ // Handle legacy use of \since <version>.
+ if (project.isEmpty())
+ text << "version";
+ else
+ text << Atom(Atom::Link, project)
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, project)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+
+ text << " " << since[0];
+ }
+ else {
+ // Reconstruct the <project> <version> string.
+ text << " " << since.join(' ');
+ }
+ text << Atom::ParaRight;
+ requisites.insert(sinceText, text);
+ }
+
+ //add the instantiates to the map
+ ClassNode* cn = qcn->classNode();
+ if (cn && (cn->status() != Node::Internal)) {
+ text.clear();
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, cn->name());
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ requisites.insert(instantiatesText, text);
+ }
+
+ //add the inherits to the map
+ const QmlClassNode* base = qcn->qmlBaseNode();
+ while (base && base->isInternal()) {
+ base = base->qmlBaseNode();
+ }
+ if (base) {
+ text.clear();
+ text << Atom::ParaLeft
+ << Atom(Atom::LinkNode,CodeMarker::stringForNode(base))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, base->name())
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
+ << Atom::ParaRight;
+ requisites.insert(inheritsText, text);
+ }
+
+ //add the inherited-by to the map
+ NodeList subs;
+ QmlClassNode::subclasses(qcn->name(), subs);
+ if (!subs.isEmpty()) {
+ text.clear();
+ text << Atom::ParaLeft;
+ appendSortedQmlNames(text, qcn, subs);
+ text << Atom::ParaRight;
+ requisites.insert(inheritedBytext, text);
+ }
+
+ if (!requisites.isEmpty()) {
+ //generate the table
+ out() << "<table class=\"alignedsummary\">\n";
+
+ QStringList::ConstIterator i;
+ for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) {
+
+ if (requisites.contains(*i)) {
+ out() << "<tr>"
+ << "<td class=\"memItemLeft rightAlign topAlign\"> "
+ << *i
+ << "</td><td class=\"memItemRight bottomAlign\"> ";
+
+ if (*i == importText)
+ out()<<requisites.value(*i).toString();
+ else
+ generateText(requisites.value(*i), qcn, marker);
+ out() << "</td></tr>";
+ }
+ }
+ out() << "</table>";
+ }
+}
+
void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
const Node *relative)
{
@@ -2151,7 +2361,10 @@ QString HtmlGenerator::generateLowStatusMemberFile(InnerNode *inner,
fileName = fileBase(inner) + "-obsolete." + fileExtension();
}
if (status == CodeMarker::Obsolete) {
- QString link = QString("../" + Generator::outputSubdir() + QLatin1Char('/')) + fileName;
+ QString link;
+ if (useOutputSubdirs() && !Generator::outputSubdir().isEmpty())
+ link = QString("../" + Generator::outputSubdir() + QLatin1Char('/'));
+ link += fileName;
inner->setObsoleteLink(link);
}
@@ -2160,21 +2373,22 @@ QString HtmlGenerator::generateLowStatusMemberFile(InnerNode *inner,
generateTitle(title, Text(), SmallSubTitle, inner, marker);
if (status == CodeMarker::Compat) {
- out() << "<p><b>The following class members are part of the "
+ out() << "<p><b>The following members of class "
+ << "<a href=\"" << linkForNode(inner, 0) << "\">"
+ << protectEnc(inner->name()) << "</a>"
+ << "are part of the "
"Qt compatibility layer.</b> We advise against "
"using them in new code.</p>\n";
}
else {
- out() << "<p><b>The following class members are obsolete.</b> "
+ out() << "<p><b>The following members of class "
+ << "<a href=\"" << linkForNode(inner, 0) << "\">"
+ << protectEnc(inner->name()) << "</a>"
+ << " are obsolete.</b> "
<< "They are provided to keep old source code working. "
<< "We strongly advise against using them in new code.</p>\n";
}
- out() << "<p><ul><li><a href=\""
- << linkForNode(inner, 0) << "\">"
- << protectEnc(inner->name())
- << " class reference</a></li></ul></p>\n";
-
for (i = 0; i < sections.size(); ++i) {
out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
@@ -2492,8 +2706,10 @@ void HtmlGenerator::generateCompactList(ListType listType,
}
else if (listType == Obsolete) {
QString fileName = fileBase(it.value()) + "-obsolete." + fileExtension();
- QString link = QString("../" + it.value()->outputSubdirectory() +
- QLatin1Char('/')) + fileName;
+ QString link;
+ if (useOutputSubdirs())
+ link = QString("../" + it.value()->outputSubdirectory() + QLatin1Char('/'));
+ link += fileName;
out() << "<a href=\"" << link << "\">";
}
@@ -3308,8 +3524,8 @@ QString HtmlGenerator::refForNode(const Node *node)
}
break;
case Node::Document:
- if (node->subType() != Node::QmlPropertyGroup)
- break;
+ break;
+ case Node::QmlPropertyGroup:
case Node::QmlProperty:
case Node::Property:
ref = node->name() + "-prop";
@@ -3372,7 +3588,7 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
}
QString link = fn;
- if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) {
+ if (!node->isInnerNode() || node->type() == Node::QmlPropertyGroup) {
QString ref = refForNode(node);
if (relative && fn == fileName(relative) && ref == refForNode(relative))
return QString();
@@ -3387,7 +3603,7 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
back down into the other subdirectory.
*/
if (node && relative && (node != relative)) {
- if (node->outputSubdirectory() != relative->outputSubdirectory())
+ if (useOutputSubdirs() && node->outputSubdirectory() != relative->outputSubdirectory())
link.prepend(QString("../" + node->outputSubdirectory() + QLatin1Char('/')));
}
return link;
@@ -3778,6 +3994,22 @@ void HtmlGenerator::generateQmlSummary(const Section& section,
while (m != section.members.constEnd()) {
out() << "<li class=\"fn\">";
generateQmlItem(*m,relative,marker,true);
+ if ((*m)->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(*m);
+ if (!qpgn->childNodes().isEmpty()) {
+ NodeList::ConstIterator p = qpgn->childNodes().constBegin();
+ out() << "<ul>\n";
+ while (p != qpgn->childNodes().constEnd()) {
+ if ((*p)->type() == Node::QmlProperty) {
+ out() << "<li class=\"fn\">";
+ generateQmlItem(*p, relative, marker, true);
+ out() << "</li>\n";
+ }
+ ++p;
+ }
+ out() << "</ul>\n";
+ }
+ }
out() << "</li>\n";
++m;
}
@@ -3799,11 +4031,18 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
#endif
generateExtractionMark(node, MemberMark);
out() << "<div class=\"qmlitem\">";
- if (node->subType() == Node::QmlPropertyGroup) {
- const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
+ if (node->type() == Node::QmlPropertyGroup) {
+ const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
out() << "<div class=\"qmlproto\">";
out() << "<table class=\"qmlname\">";
+
+ QString heading = qpgn->name() + " group";
+ out() << "<tr valign=\"top\" class=\"even\">";
+ out() << "<th class=\"centerAlign\"><p>";
+ out() << "<a name=\"" + refForNode(qpgn) + "\"></a>";
+ out() << "<b>" << heading << "</b>";
+ out() << "</p></th></tr>";
while (p != qpgn->childNodes().constEnd()) {
if ((*p)->type() == Node::QmlProperty) {
qpn = static_cast<QmlPropertyNode*>(*p);
@@ -3825,68 +4064,23 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
}
else if (node->type() == Node::QmlProperty) {
qpn = static_cast<QmlPropertyNode*>(node);
- /*
- If the QML property node has a single subproperty,
- override, replace qpn with that override node and
- proceed as normal.
- */
- if (qpn->qmlPropNodes().size() == 1) {
- Node* n = qpn->qmlPropNodes().at(0);
- if (n->type() == Node::QmlProperty)
- qpn = static_cast<QmlPropertyNode*>(n);
- }
- /*
- Now qpn either has no overrides, or it has more
- than 1. If it has none, proceed to output as nortmal.
- */
- if (qpn->qmlPropNodes().isEmpty()) {
- out() << "<div class=\"qmlproto\">";
- out() << "<table class=\"qmlname\">";
- out() << "<tr valign=\"top\" class=\"odd\">";
- out() << "<td class=\"tblQmlPropNode\"><p>";
- out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
- if (!qpn->isReadOnlySet()) {
- if (qpn->declarativeCppNode())
- qpn->setReadOnly(!qpn->isWritable(qdb_));
- }
- if (qpn->isReadOnly())
- out() << "<span class=\"qmlreadonly\">read-only</span>";
- if (qpn->isDefault())
- out() << "<span class=\"qmldefault\">default</span>";
- generateQmlItem(qpn, relative, marker, false);
- out() << "</p></td></tr>";
- out() << "</table>";
- out() << "</div>";
- }
- else {
- /*
- The QML property node has multiple override nodes.
- Process the whole list as we would for a QML property
- group.
- */
- NodeList::ConstIterator p = qpn->qmlPropNodes().constBegin();
- out() << "<div class=\"qmlproto\">";
- out() << "<table class=\"qmlname\">";
- while (p != qpn->qmlPropNodes().constEnd()) {
- if ((*p)->type() == Node::QmlProperty) {
- QmlPropertyNode* q = static_cast<QmlPropertyNode*>(*p);
- out() << "<tr valign=\"top\" class=\"odd\">";
- out() << "<td class=\"tblQmlPropNode\"><p>";
- out() << "<a name=\"" + refForNode(q) + "\"></a>";
- if (!qpn->isReadOnlySet())
- qpn->setReadOnly(!qpn->isWritable(qdb_));
- if (qpn->isReadOnly())
- out() << "<span class=\"qmlreadonly\">read-only</span>";
- if (qpn->isDefault())
- out() << "<span class=\"qmldefault\">default</span>";
- generateQmlItem(q, relative, marker, false);
- out() << "</p></td></tr>";
- }
- ++p;
- }
- out() << "</table>";
- out() << "</div>";
- }
+ out() << "<div class=\"qmlproto\">";
+ out() << "<table class=\"qmlname\">";
+ out() << "<tr valign=\"top\" class=\"odd\">";
+ out() << "<td class=\"tblQmlPropNode\"><p>";
+ out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
+ if (!qpn->isReadOnlySet()) {
+ if (qpn->declarativeCppNode())
+ qpn->setReadOnly(!qpn->isWritable(qdb_));
+ }
+ if (qpn->isReadOnly())
+ out() << "<span class=\"qmlreadonly\">read-only</span>";
+ if (qpn->isDefault())
+ out() << "<span class=\"qmldefault\">default</span>";
+ generateQmlItem(qpn, relative, marker, false);
+ out() << "</p></td></tr>";
+ out() << "</table>";
+ out() << "</div>";
}
else if (node->type() == Node::QmlSignal) {
const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
@@ -4359,8 +4553,6 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent)
break;
case Node::QmlClass:
break;
- case Node::QmlPropertyGroup:
- break;
case Node::QmlBasicType:
break;
case Node::QmlModule:
@@ -4394,6 +4586,8 @@ void HtmlGenerator::reportOrphans(const InnerNode* parent)
if (!related)
child->location().warning(tr("Global variable, %1, %2").arg(child->name()).arg(message));
break;
+ case Node::QmlPropertyGroup:
+ break;
case Node::QmlProperty:
if (!related)
child->location().warning(tr("Global QML property, %1, %2").arg(child->name()).arg(message));
diff --git a/src/tools/qdoc/htmlgenerator.h b/src/tools/qdoc/htmlgenerator.h
index 0a6717461e..8cd8664dfc 100644
--- a/src/tools/qdoc/htmlgenerator.h
+++ b/src/tools/qdoc/htmlgenerator.h
@@ -127,7 +127,7 @@ private:
};
const QPair<QString,QString> anchorForNode(const Node *node);
- void generateBreadCrumbs(const QString& title,
+ void generateNavigationBar(const QString& title,
const Node *node,
CodeMarker *marker);
void generateHeader(const QString& title,
@@ -139,6 +139,10 @@ private:
const Node *relative,
CodeMarker *marker);
void generateFooter(const Node *node = 0);
+ void generateRequisites(InnerNode *inner,
+ CodeMarker *marker);
+ void generateQmlRequisites(QmlClassNode *qcn,
+ CodeMarker *marker);
void generateBrief(const Node *node,
CodeMarker *marker,
const Node *relative = 0);
@@ -182,6 +186,7 @@ private:
void generateQmlInstantiates(QmlClassNode* qcn, CodeMarker* marker);
void generateInstantiatedBy(ClassNode* cn, CodeMarker* marker);
+ void generateRequisitesTable(const QStringList& requisitesOrder, QMap<QString, Text>& requisites);
void generateSection(const NodeList& nl,
const Node *relative,
CodeMarker *marker,
@@ -239,7 +244,7 @@ private:
QString footer;
QString address;
bool pleaseGenerateMacRef;
- bool noBreadCrumbs;
+ bool noNavigationBar;
QString project;
QString projectDescription;
QString projectUrl;
@@ -252,6 +257,12 @@ private:
QStack<QXmlStreamWriter*> xmlWriterStack;
static int id;
QList<ManifestMetaFilter> manifestMetaContent;
+ QString homepage;
+ QString landingpage;
+ QString cppclassespage;
+ QString qmltypespage;
+ QString buildversion;
+
public:
static bool debugging_on;
static QString divNavTop;
@@ -262,9 +273,10 @@ public:
#define HTMLGENERATOR_GENERATEMACREFS "generatemacrefs" // ### document me
#define HTMLGENERATOR_POSTHEADER "postheader"
#define HTMLGENERATOR_POSTPOSTHEADER "postpostheader"
-#define HTMLGENERATOR_NOBREADCRUMBS "nobreadcrumbs"
+#define HTMLGENERATOR_NONAVIGATIONBAR "nonavigationbar"
+#define HTMLGENERATOR_NOSUBDIRS "nosubdirs"
+
QT_END_NAMESPACE
#endif
-
diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp
index 3ec121f795..912cdad7eb 100644
--- a/src/tools/qdoc/main.cpp
+++ b/src/tools/qdoc/main.cpp
@@ -95,6 +95,7 @@ bool creationTimeBefore(const QFileInfo &fi1, const QFileInfo &fi2)
static bool highlighting = false;
static bool showInternal = false;
+static bool redirectDocumentationToDevNull = false;
static bool noLinkErrors = false;
static bool obsoleteLinks = false;
static QStringList defines;
@@ -139,6 +140,8 @@ static void printHelp()
"Run qdoc to read the index files and generate the docs\n"
" -showinternal "
"Include content marked internal\n"
+ " -redirect-documentation-to-dev-null "
+ "Save all documentation content to /dev/null. Useful if someone is interested in qdoc errors only.\n"
" -version "
"Display version of qdoc and exit\n") );
}
@@ -162,6 +165,15 @@ static void loadIndexFiles(Config& config)
dependModules += config.getStringList(CONFIG_DEPENDS);
+ bool noOutputSubdirs = false;
+ QString singleOutputSubdir;
+ if (config.getBool(QString("HTML.nosubdirs"))) {
+ noOutputSubdirs = true;
+ singleOutputSubdir = config.getString("HTML.outputsubdir");
+ if (singleOutputSubdir.isEmpty())
+ singleOutputSubdir = "html";
+ }
+
// Allow modules and third-party application/libraries to link
// to the Qt docs without having to explicitly pass --indexdir.
if (!indexDirs.contains(documentationPath))
@@ -196,8 +208,12 @@ static void loadIndexFiles(Config& config)
QString indexToAdd;
QList<QFileInfo> foundIndices;
for (int j = 0; j < indexDirs.size(); j++) {
- QString fileToLookFor = indexDirs[j] + QLatin1Char('/') + dependModules[i] +
- QLatin1Char('/') + dependModules[i] + QLatin1String(".index");
+ QString fileToLookFor = indexDirs[j] + QLatin1Char('/');
+ if (noOutputSubdirs)
+ fileToLookFor += singleOutputSubdir + QLatin1Char('/');
+ else
+ fileToLookFor += dependModules[i] + QLatin1Char('/');
+ fileToLookFor += dependModules[i] + QLatin1String(".index");
if (QFile::exists(fileToLookFor)) {
QFileInfo tempFileInfo(fileToLookFor);
if (!foundIndices.contains(tempFileInfo))
@@ -257,6 +273,7 @@ static void processQdocconfFile(const QString &fileName)
}
config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(highlighting ? "true" : "false"));
config.setStringList(CONFIG_SHOWINTERNAL, QStringList(showInternal ? "true" : "false"));
+ config.setStringList(CONFIG_REDIRECTDOCUMENTATIONTODEVNULL, QStringList(redirectDocumentationToDevNull ? "true" : "false"));
config.setStringList(CONFIG_NOLINKERRORS, QStringList(noLinkErrors ? "true" : "false"));
config.setStringList(CONFIG_OBSOLETELINKS, QStringList(obsoleteLinks ? "true" : "false"));
@@ -573,6 +590,9 @@ int main(int argc, char **argv)
else if (opt == "-showinternal") {
showInternal = true;
}
+ else if (opt == "-redirect-documentation-to-dev-null") {
+ redirectDocumentationToDevNull = true;
+ }
else if (opt == "-no-examples") {
Config::generateExamples = false;
}
diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp
index 2184e302ae..fd56c77742 100644
--- a/src/tools/qdoc/node.cpp
+++ b/src/tools/qdoc/node.cpp
@@ -151,11 +151,11 @@ QString Node::fullName(const Node* relative) const
*/
void Node::setDoc(const Doc& doc, bool replace)
{
- if (!d.isEmpty() && !replace) {
+ if (!doc_.isEmpty() && !replace) {
doc.location().warning(tr("Overrides a previous doc"));
- d.location().warning(tr("(The previous doc is here)"));
+ doc_.location().warning(tr("(The previous doc is here)"));
}
- d = doc;
+ doc_ = doc;
}
/*!
@@ -311,6 +311,8 @@ QString Node::nodeTypeString(unsigned t)
return "variable";
case QmlProperty:
return "QML property";
+ case QmlPropertyGroup:
+ return "QML property group";
case QmlSignal:
return "QML signal";
case QmlSignalHandler:
@@ -359,8 +361,6 @@ QString Node::nodeSubtypeString(unsigned t)
return "external page";
case QmlClass:
return "QML type";
- case QmlPropertyGroup:
- return "QML property group";
case QmlBasicType:
return "QML basic type";
case QmlModule:
@@ -742,12 +742,12 @@ void InnerNode::getMemberClasses(NodeMap& out)
Node *InnerNode::findChildNodeByName(const QString& name)
{
Node *node = childMap.value(name);
- if (node && node->subType() != QmlPropertyGroup)
+ if (node && node->type() != QmlPropertyGroup)
return node;
if ((type() == Document) && (subType() == QmlClass)) {
for (int i=0; i<children_.size(); ++i) {
Node* n = children_.at(i);
- if (n->subType() == QmlPropertyGroup) {
+ if (n->type() == QmlPropertyGroup) {
node = static_cast<InnerNode*>(n)->findChildNodeByName(name);
if (node)
return node;
@@ -771,7 +771,7 @@ void InnerNode::findNodes(const QString& name, QList<Node*>& n)
if ((type() == Document) && (subType() == QmlClass)) {
for (int i=0; i<children_.size(); ++i) {
node = children_.at(i);
- if (node->subType() == QmlPropertyGroup) {
+ if (node->type() == QmlPropertyGroup) {
node = static_cast<InnerNode*>(node)->findChildNodeByName(name);
if (node) {
n.append(node);
@@ -793,7 +793,7 @@ void InnerNode::findNodes(const QString& name, QList<Node*>& n)
*/
for (int i=0; i<nodes.size(); ++i) {
node = nodes.at(i);
- if (node->subType() != QmlPropertyGroup)
+ if (node->type() != QmlPropertyGroup)
n.append(node);
else {
node = static_cast<InnerNode*>(node)->findChildNodeByName(name);
@@ -829,14 +829,14 @@ Node* InnerNode::findChildNodeByName(const QString& name, bool qml)
if (!node->isQmlNode())
return node;
}
- else if (node->isQmlNode() && (node->subType() != QmlPropertyGroup))
+ else if (node->isQmlNode() && (node->type() != QmlPropertyGroup))
return node;
}
}
if (qml && (type() == Document) && (subType() == QmlClass)) {
for (int i=0; i<children_.size(); ++i) {
Node* node = children_.at(i);
- if (node->subType() == QmlPropertyGroup) {
+ if (node->type() == QmlPropertyGroup) {
node = static_cast<InnerNode*>(node)->findChildNodeByName(name);
if (node)
return node;
@@ -1371,6 +1371,26 @@ void InnerNode::removeRelated(Node *pseudoChild)
}
/*!
+ If this node has a child that is a QML property named \a n,
+ return the pointer to that child.
+ */
+QmlPropertyNode* InnerNode::hasQmlProperty(const QString& n) const
+{
+ foreach (Node* child, childNodes()) {
+ if (child->type() == Node::QmlProperty) {
+ if (child->name() == n)
+ return static_cast<QmlPropertyNode*>(child);
+ }
+ else if (child->type() == Node::QmlPropertyGroup) {
+ QmlPropertyNode* t = child->hasQmlProperty(n);
+ if (t)
+ return t;
+ }
+ }
+ return 0;
+}
+
+/*!
\class LeafNode
*/
@@ -1673,25 +1693,6 @@ QString DocNode::subTitle() const
}
/*!
- Returns true if this QML type or property group contains a
- property named \a name.
- */
-bool DocNode::hasProperty(const QString& name) const
-{
- foreach (Node* child, childNodes()) {
- if (child->type() == Node::Document && child->subType() == Node::QmlPropertyGroup) {
- if (child->hasProperty(name))
- return true;
- }
- else if (child->type() == Node::QmlProperty) {
- if (child->hasProperty(name))
- return true;
- }
- }
- return false;
-}
-
-/*!
The constructor calls the DocNode constructor with
\a parent, \a name, and Node::Example.
*/
@@ -2273,8 +2274,8 @@ QmlBasicTypeNode::QmlBasicTypeNode(InnerNode *parent,
Constructor for the Qml property group node. \a parent is
always a QmlClassNode.
*/
-QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent, const QString& name)
- : DocNode(parent, name, QmlPropertyGroup, Node::ApiPage)
+QmlPropertyGroupNode::QmlPropertyGroupNode(QmlClassNode* parent, const QString& name)
+ : InnerNode(QmlPropertyGroup, parent, name)
{
idNumber_ = -1;
}
@@ -2286,24 +2287,17 @@ QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent, const QString& name)
property group count and set the id number to the new
value.
*/
-QString QmlPropGroupNode::idNumber()
+QString QmlPropertyGroupNode::idNumber()
{
if (idNumber_ == -1)
idNumber_ = incPropertyGroupCount();
return QString().setNum(idNumber_);
}
-
/*!
- Constructor for the QML property node, when the \a parent
- is QML property group node. This constructor is only used
- for creating QML property nodes for QML elements, i.e.
- not for creating QML property nodes for QML components.
- Hopefully, this constructor will become obsolete, so don't
- use it unless one of the other two constructors can't be
- used.
+ Constructor for the QML property node.
*/
-QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent,
+QmlPropertyNode::QmlPropertyNode(InnerNode* parent,
const QString& name,
const QString& type,
bool attached)
@@ -2311,56 +2305,14 @@ QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent,
type_(type),
stored_(FlagValueDefault),
designable_(FlagValueDefault),
+ isAlias_(false),
isdefault_(false),
attached_(attached),
readOnly_(FlagValueDefault)
{
setPageType(ApiPage);
-}
-
-/*!
- Constructor for the QML property node, when the \a parent
- is a QML class node.
- */
-QmlPropertyNode::QmlPropertyNode(QmlClassNode *parent,
- const QString& name,
- const QString& type,
- bool attached)
- : LeafNode(QmlProperty, parent, name),
- type_(type),
- stored_(FlagValueDefault),
- designable_(FlagValueDefault),
- isdefault_(false),
- attached_(attached),
- readOnly_(FlagValueDefault)
-{
- setPageType(ApiPage);
-}
-
-/*!
- Constructor for the QML property node, when the \a parent
- is a QML property node. Strictly speaking, this is not the
- way QML property nodes were originally meant to be built,
- because this constructor has another QML property node as
- its parent. But this constructor is useful for documenting
- QML properties in QML components, i.e., when you override
- the definition of a property with the \e{qmlproperty}
- command. It actually uses the parent of \a parent as the
- parent.
- */
-QmlPropertyNode::QmlPropertyNode(QmlPropertyNode* parent,
- const QString& name,
- const QString& type,
- bool attached)
- : LeafNode(parent->parent(), QmlProperty, name),
- type_(type),
- stored_(FlagValueDefault),
- designable_(FlagValueDefault),
- isdefault_(false),
- attached_(attached),
- readOnly_(FlagValueDefault)
-{
- setPageType(ApiPage);
+ if (type_ == QString("alias"))
+ isAlias_ = true;
}
/*!
@@ -2450,23 +2402,6 @@ PropertyNode* QmlPropertyNode::correspondingProperty(QDocDatabase* qdb)
return 0;
}
-/*!
- Returns true if this QML type or property group contains a
- property named \a name.
- */
-bool QmlPropertyNode::hasProperty(const QString& n) const
-{
- if (name() == n)
- return true;
- foreach (Node* child, qmlPropNodes()) {
- if (child->type() == Node::QmlProperty) {
- if (child->name() == n)
- return true;
- }
- }
- return false;
-}
-
/*! \class NameCollisionNode
An instance of this node is inserted in the tree
@@ -2586,11 +2521,10 @@ QString Node::fullDocumentName() const
const Node* n = this;
do {
- if (!n->name().isEmpty() &&
- ((n->type() != Node::Document) || (n->subType() != Node::QmlPropertyGroup)))
+ if (!n->name().isEmpty() && n->type() != Node::QmlPropertyGroup)
pieces.insert(0, n->name());
- if ((n->type() == Node::Document) && (n->subType() != Node::QmlPropertyGroup)) {
+ if (n->type() == Node::Document) {
if ((n->subType() == Node::QmlClass) && !n->qmlModuleName().isEmpty())
pieces.insert(0, n->qmlModuleIdentifier());
break;
@@ -2806,12 +2740,6 @@ QString Node::idForNode() const
case Node::QmlClass:
str = "qml-class-" + name();
break;
- case Node::QmlPropertyGroup:
- {
- Node* n = const_cast<Node*>(this);
- str = "qml-propertygroup-" + n->name();
- }
- break;
case Node::Page:
case Node::Group:
case Node::Module:
@@ -2852,6 +2780,12 @@ QString Node::idForNode() const
case Node::QmlProperty:
str = "qml-property-" + name();
break;
+ case Node::QmlPropertyGroup:
+ {
+ Node* n = const_cast<Node*>(this);
+ str = "qml-propertygroup-" + n->name();
+ }
+ break;
case Node::Property:
str = "property-" + name();
break;
diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h
index bc75df2992..9c8950d185 100644
--- a/src/tools/qdoc/node.h
+++ b/src/tools/qdoc/node.h
@@ -60,6 +60,7 @@ class InnerNode;
class ExampleNode;
class QmlClassNode;
class QDocDatabase;
+class QmlPropertyNode;
typedef QList<Node*> NodeList;
typedef QMap<QString, Node*> NodeMap;
@@ -80,6 +81,7 @@ public:
Function,
Property,
Variable,
+ QmlPropertyGroup,
QmlProperty,
QmlSignal,
QmlSignalHandler,
@@ -98,7 +100,6 @@ public:
Page,
ExternalPage,
QmlClass,
- QmlPropertyGroup,
QmlBasicType,
QmlModule,
DitaMap,
@@ -163,7 +164,10 @@ public:
QString plainName() const;
QString plainFullName(const Node* relative = 0) const;
QString fullName(const Node* relative=0) const;
+ const QString& baseName() const { return baseName_; }
+ bool hasBaseName() const { return !baseName_.isEmpty(); }
+ void setBaseName(const QString& bn) { baseName_ = bn; }
void setAccess(Access access) { access_ = access; }
void setLocation(const Location& location) { loc = location; }
void setDoc(const Doc& doc, bool replace = false);
@@ -200,8 +204,11 @@ public:
virtual bool isQmlPropertyGroup() const { return false; }
virtual bool isCollisionNode() const { return false; }
virtual bool isAttached() const { return false; }
+ virtual bool isAlias() const { return false; }
virtual bool isGroup() const { return false; }
virtual bool isWrapper() const;
+ virtual bool isReadOnly() const { return false; }
+ virtual bool isDefault() const { return false; }
virtual void addMember(Node* ) { }
virtual bool hasMembers() const { return false; }
virtual bool hasNamespaces() const { return false; }
@@ -209,10 +216,12 @@ public:
virtual void setAbstract(bool ) { }
virtual void setWrapper() { }
virtual QString title() const { return QString(); }
- virtual bool hasProperty(const QString& ) const { return false; }
+ virtual QmlPropertyNode* hasQmlProperty(const QString& ) const { return 0; }
virtual void getMemberNamespaces(NodeMap& ) { }
virtual void getMemberClasses(NodeMap& ) { }
virtual bool isInternal() const;
+ virtual void setDataType(const QString& ) { }
+ virtual void setReadOnly(bool ) { }
bool isIndexNode() const { return indexNodeFlag_; }
bool wasSeen() const { return seen_; }
Type type() const { return nodeType_; }
@@ -231,7 +240,7 @@ public:
Access access() const { return access_; }
QString accessString() const;
const Location& location() const { return loc; }
- const Doc& doc() const { return d; }
+ const Doc& doc() const { return doc_; }
Status status() const { return status_; }
Status inheritedStatus() const;
ThreadSafeness threadSafeness() const;
@@ -294,8 +303,9 @@ private:
InnerNode* relatesTo_;
QString name_;
Location loc;
- Doc d;
+ Doc doc_;
QMap<LinkType, QPair<QString, QString> > linkMap_;
+ QString baseName_;
QString moduleName_;
QString url_;
QString since_;
@@ -366,6 +376,7 @@ public:
virtual void setCurrentChild(InnerNode* ) { }
virtual void setOutputFileName(const QString& f) { outputFileName_ = f; }
virtual QString outputFileName() const { return outputFileName_; }
+ virtual QmlPropertyNode* hasQmlProperty(const QString& ) const;
void printChildren(const QString& title);
void printMembers(const QString& title);
@@ -444,7 +455,7 @@ public:
virtual bool isClass() const { return true; }
virtual bool isWrapper() const { return wrapper_; }
virtual QString obsoleteLink() const { return obsoleteLink_; }
- virtual void setObsoleteLink(const QString& t) { obsoleteLink_ = t; };
+ virtual void setObsoleteLink(const QString& t) { obsoleteLink_ = t; }
virtual void setWrapper() { wrapper_ = true; }
void addBaseClass(Access access,
@@ -486,9 +497,11 @@ public:
PageType ptype);
virtual ~DocNode() { }
+ void setQtVariable(const QString &variable) { qtVariable_ = variable; }
void setTitle(const QString &title) { title_ = title; }
void setSubTitle(const QString &subTitle) { subtitle_ = subTitle; }
+ QString qtVariable() const { return qtVariable_; }
SubType subType() const { return nodeSubtype_; }
virtual QString title() const;
virtual QString fullTitle() const;
@@ -497,13 +510,14 @@ public:
virtual QString nameForLists() const { return title(); }
virtual void setImageFileName(const QString& ) { }
virtual bool isGroup() const { return (subType() == Node::Group); }
- virtual bool isQmlPropertyGroup() const { return (nodeSubtype_ == QmlPropertyGroup); }
- virtual bool hasProperty(const QString& ) const;
protected:
SubType nodeSubtype_;
QString title_;
QString subtitle_;
+
+private:
+ QString qtVariable_;
};
class NameCollisionNode : public DocNode
@@ -619,11 +633,11 @@ public:
virtual bool isQmlNode() const { return true; }
};
-class QmlPropGroupNode : public DocNode
+class QmlPropertyGroupNode : public InnerNode
{
public:
- QmlPropGroupNode(QmlClassNode* parent, const QString& name);
- virtual ~QmlPropGroupNode() { }
+ QmlPropertyGroupNode(QmlClassNode* parent, const QString& name);
+ virtual ~QmlPropertyGroupNode() { }
virtual bool isQmlNode() const { return true; }
virtual bool isQtQuickNode() const { return parent()->isQtQuickNode(); }
virtual QString qmlTypeName() const { return parent()->qmlTypeName(); }
@@ -631,6 +645,7 @@ public:
virtual QString qmlModuleVersion() const { return parent()->qmlModuleVersion(); }
virtual QString qmlModuleIdentifier() const { return parent()->qmlModuleIdentifier(); }
virtual QString idNumber();
+ virtual bool isQmlPropertyGroup() const { return true; }
const QString& element() const { return parent()->name(); }
@@ -645,34 +660,27 @@ class QmlPropertyNode : public LeafNode
Q_DECLARE_TR_FUNCTIONS(QDoc::QmlPropertyNode)
public:
- QmlPropertyNode(QmlClassNode *parent,
- const QString& name,
- const QString& type,
- bool attached);
- QmlPropertyNode(QmlPropGroupNode* parent,
- const QString& name,
- const QString& type,
- bool attached);
- QmlPropertyNode(QmlPropertyNode* parent,
+ QmlPropertyNode(InnerNode *parent,
const QString& name,
const QString& type,
bool attached);
virtual ~QmlPropertyNode() { }
- void setDataType(const QString& dataType) { type_ = dataType; }
+ virtual void setDataType(const QString& dataType) { type_ = dataType; }
void setStored(bool stored) { stored_ = toFlagValue(stored); }
void setDesignable(bool designable) { designable_ = toFlagValue(designable); }
- void setReadOnly(bool ro) { readOnly_ = toFlagValue(ro); }
+ virtual void setReadOnly(bool ro) { readOnly_ = toFlagValue(ro); }
void setDefault() { isdefault_ = true; }
const QString &dataType() const { return type_; }
QString qualifiedDataType() const { return type_; }
bool isReadOnlySet() const { return (readOnly_ != FlagValueDefault); }
- bool isDefault() const { return isdefault_; }
bool isStored() const { return fromFlagValue(stored_,true); }
bool isDesignable() const { return fromFlagValue(designable_,false); }
bool isWritable(QDocDatabase* qdb);
- bool isReadOnly() const { return fromFlagValue(readOnly_,false); }
+ virtual bool isDefault() const { return isdefault_; }
+ virtual bool isReadOnly() const { return fromFlagValue(readOnly_,false); }
+ virtual bool isAlias() const { return isAlias_; }
virtual bool isAttached() const { return attached_; }
virtual bool isQmlNode() const { return true; }
virtual bool isQtQuickNode() const { return parent()->isQtQuickNode(); }
@@ -680,22 +688,19 @@ public:
virtual QString qmlModuleName() const { return parent()->qmlModuleName(); }
virtual QString qmlModuleVersion() const { return parent()->qmlModuleVersion(); }
virtual QString qmlModuleIdentifier() const { return parent()->qmlModuleIdentifier(); }
- virtual bool hasProperty(const QString& name) const;
PropertyNode* correspondingProperty(QDocDatabase* qdb);
- const QString& element() const { return static_cast<QmlPropGroupNode*>(parent())->element(); }
- void appendQmlPropNode(QmlPropertyNode* p) { qmlPropNodes_.append(p); }
- const NodeList& qmlPropNodes() const { return qmlPropNodes_; }
+ const QString& element() const { return static_cast<QmlPropertyGroupNode*>(parent())->element(); }
private:
QString type_;
FlagValue stored_;
FlagValue designable_;
+ bool isAlias_;
bool isdefault_;
bool attached_;
FlagValue readOnly_;
- NodeList qmlPropNodes_;
};
class EnumItem
@@ -892,7 +897,7 @@ public:
PropertyNode(InnerNode* parent, const QString& name);
virtual ~PropertyNode() { }
- void setDataType(const QString& dataType) { type_ = dataType; }
+ virtual void setDataType(const QString& dataType) { type_ = dataType; }
void addFunction(FunctionNode* function, FunctionRole role);
void addSignal(FunctionNode* function, FunctionRole role);
void setStored(bool stored) { stored_ = toFlagValue(stored); }
diff --git a/src/tools/qdoc/puredocparser.cpp b/src/tools/qdoc/puredocparser.cpp
index d11ef3a3c7..644fe05438 100644
--- a/src/tools/qdoc/puredocparser.cpp
+++ b/src/tools/qdoc/puredocparser.cpp
@@ -118,9 +118,9 @@ void PureDocParser::parseSourceFile(const Location& location, const QString& fil
*/
bool PureDocParser::processQdocComments()
{
- QSet<QString> topicCommandsAllowed = topicCommands();
- QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
- QSet<QString> metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
+ const QSet<QString>& topicCommandsAllowed = topicCommands();
+ const QSet<QString>& otherMetacommandsAllowed = otherMetaCommands();
+ const QSet<QString>& metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
while (tok != Tok_Eoi) {
if (tok == Tok_Doc) {
@@ -137,55 +137,68 @@ bool PureDocParser::processQdocComments()
/*
Doc parses the comment.
*/
- Doc doc(start_loc,end_loc,comment,metacommandsAllowed);
+ Doc doc(start_loc, end_loc, comment, metacommandsAllowed, topicCommandsAllowed);
QString topic;
- ArgList args;
+ bool isQmlPropertyTopic = false;
- QSet<QString> topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
-
- /*
- There should be one topic command in the set,
- or none. If the set is empty, then the comment
- should be a function description.
- */
- if (topicCommandsUsed.count() > 0) {
- topic = *topicCommandsUsed.begin();
- args = doc.metaCommandArgs(topic);
+ const TopicList& topics = doc.topicsUsed();
+ if (!topics.isEmpty()) {
+ topic = topics[0].topic;
+ if ((topic == COMMAND_QMLPROPERTY) ||
+ (topic == COMMAND_QMLPROPERTYGROUP) ||
+ (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ isQmlPropertyTopic = true;
+ }
+ }
+ if (isQmlPropertyTopic && topics.size() > 1) {
+ qDebug() << "MULTIPLE TOPICS:" << doc.location().fileName() << doc.location().lineNo();
+ for (int i=0; i<topics.size(); ++i) {
+ qDebug() << " " << topics[i].topic << topics[i].args;
+ }
}
NodeList nodes;
- QList<Doc> docs;
+ DocList docs;
if (topic.isEmpty()) {
doc.location().warning(tr("This qdoc comment contains no topic command "
"(e.g., '\\%1', '\\%2').")
.arg(COMMAND_MODULE).arg(COMMAND_PAGE));
}
+ else if (isQmlPropertyTopic) {
+ Doc nodeDoc = doc;
+ processQmlProperties(nodeDoc, nodes, docs);
+ }
else {
- /*
- There is a topic command. Process it.
- */
- if ((topic == COMMAND_QMLPROPERTY) ||
- (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ ArgList args;
+ QSet<QString> topicCommandsUsed = topicCommandsAllowed & doc.metaCommandsUsed();
+ if (topicCommandsUsed.count() > 0) {
+ topic = *topicCommandsUsed.begin();
+ args = doc.metaCommandArgs(topic);
+ }
+ if (topicCommandsUsed.count() > 1) {
+ QString topics;
+ QSet<QString>::ConstIterator t = topicCommandsUsed.constBegin();
+ while (t != topicCommandsUsed.constEnd()) {
+ topics += " \\" + *t + ",";
+ ++t;
+ }
+ topics[topics.lastIndexOf(',')] = '.';
+ int i = topics.lastIndexOf(',');
+ topics[i] = ' ';
+ topics.insert(i+1,"and");
+ doc.location().warning(tr("Multiple topic commands found in comment: %1").arg(topics));
+ }
+ ArgList::ConstIterator a = args.begin();
+ while (a != args.end()) {
Doc nodeDoc = doc;
- Node* node = processTopicCommandGroup(nodeDoc,topic,args);
+ Node* node = processTopicCommand(nodeDoc,topic,*a);
if (node != 0) {
nodes.append(node);
docs.append(nodeDoc);
}
- }
- else {
- ArgList::ConstIterator a = args.begin();
- while (a != args.end()) {
- Doc nodeDoc = doc;
- Node* node = processTopicCommand(nodeDoc,topic,*a);
- if (node != 0) {
- nodes.append(node);
- docs.append(nodeDoc);
- }
- ++a;
- }
+ ++a;
}
}
diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp
index 7a3df4e4f2..a1e06c8020 100644
--- a/src/tools/qdoc/qdocdatabase.cpp
+++ b/src/tools/qdoc/qdocdatabase.cpp
@@ -612,7 +612,7 @@ void QDocDatabase::findAllObsoleteThings(const InnerNode* node)
case Node::QmlMethod:
if ((*c)->parent()) {
Node* parent = (*c)->parent();
- if (parent->subType() == Node::QmlPropertyGroup && parent->parent())
+ if (parent->type() == Node::QmlPropertyGroup && parent->parent())
parent = parent->parent();
if (parent && parent->subType() == Node::QmlClass && !parent->name().isEmpty())
name = parent->name() + "::" + name;
diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp
index 5f2ebdfd07..aab5e4f9ae 100644
--- a/src/tools/qdoc/qdocindexfiles.cpp
+++ b/src/tools/qdoc/qdocindexfiles.cpp
@@ -217,8 +217,18 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
location = Location(name);
node = qbtn;
}
- else if (element.nodeName() == "qmlproperty") {
+ else if (element.nodeName() == "qmlpropertygroup") {
QmlClassNode* qcn = static_cast<QmlClassNode*>(parent);
+ QmlPropertyGroupNode* qpgn = new QmlPropertyGroupNode(qcn, name);
+ if (element.hasAttribute("location"))
+ name = element.attribute("location", QString());
+ if (!indexUrl.isEmpty())
+ location = Location(indexUrl + QLatin1Char('/') + name);
+ else if (!indexUrl.isNull())
+ location = Location(name);
+ node = qpgn;
+ }
+ else if (element.nodeName() == "qmlproperty") {
QString type = element.attribute("type");
bool attached = false;
if (element.attribute("attached") == "true")
@@ -226,7 +236,15 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
bool readonly = false;
if (element.attribute("writable") == "false")
readonly = true;
- QmlPropertyNode* qpn = new QmlPropertyNode(qcn, name, type, attached);
+ QmlPropertyNode* qpn = 0;
+ if (parent->type() == Node::Document) {
+ QmlClassNode* qcn = static_cast<QmlClassNode*>(parent);
+ qpn = new QmlPropertyNode(qcn, name, type, attached);
+ }
+ else if (parent->type() == Node::QmlPropertyGroup) {
+ QmlPropertyGroupNode* qpgn = static_cast<QmlPropertyGroupNode*>(parent);
+ qpn = new QmlPropertyNode(qpgn, name, type, attached);
+ }
qpn->setReadOnly(readonly);
node = qpn;
}
@@ -281,10 +299,6 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
subtype = Node::QmlClass;
ptype = Node::ApiPage;
}
- else if (element.attribute("subtype") == "qmlpropertygroup") {
- subtype = Node::QmlPropertyGroup;
- ptype = Node::ApiPage;
- }
else if (element.attribute("subtype") == "qmlbasictype") {
subtype = Node::QmlBasicType;
ptype = Node::ApiPage;
@@ -501,7 +515,7 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element,
// Create some content for the node.
QSet<QString> emptySet;
- Doc doc(location, location, " ", emptySet); // placeholder
+ Doc doc(location, location, " ", emptySet, emptySet); // placeholder
node->setDoc(doc);
node->setIndexNodeFlag();
node->setOutputSubdirectory(project_.toLower());
@@ -644,6 +658,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
case Node::QmlProperty:
nodeName = "qmlproperty";
break;
+ case Node::QmlPropertyGroup:
+ nodeName = "qmlpropertygroup";
+ break;
case Node::QmlSignal:
nodeName = "qmlsignal";
break;
@@ -746,7 +763,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
QString fullName = node->fullDocumentName();
if (fullName != objName)
writer.writeAttribute("fullname", fullName);
- QString href = node->outputSubdirectory();
+ QString href;
+ if (Generator::useOutputSubdirs())
+ href = node->outputSubdirectory();
if (!href.isEmpty())
href.append(QLatin1Char('/'));
href.append(gen_->fullDocumentLocation(node));
@@ -927,6 +946,12 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
writer.writeAttribute("brief", brief);
}
break;
+ case Node::QmlPropertyGroup:
+ {
+ if (!brief.isEmpty())
+ writer.writeAttribute("brief", brief);
+ }
+ break;
case Node::Property:
{
const PropertyNode* propertyNode = static_cast<const PropertyNode*>(node);
@@ -1179,17 +1204,12 @@ void QDocIndexFiles::generateIndexSections(QXmlStreamWriter& writer,
foreach (Node* child, cnodes) {
/*
- Don't generate anything for a QML property group node.
- It is just a place holder for a collection of QML property
- nodes. Recurse to its children, which are the QML property
- nodes.
-
- Do the same thing for collision nodes - we want children
- of collision nodes in the index, but leaving out the
- parent collision page will make searching for nodes easier.
+ Don't generate anything for a collision node. We want
+ children of collision nodes in the index, but leaving
+ out the parent collision page will make searching for
+ nodes easier.
*/
- if (child->subType() == Node::QmlPropertyGroup ||
- child->subType() == Node::Collision) {
+ if (child->subType() == Node::Collision) {
const InnerNode* pgn = static_cast<const InnerNode*>(child);
foreach (Node* c, pgn->childNodes()) {
generateIndexSections(writer, c, generateInternalNodes);
diff --git a/src/tools/qdoc/qdoctagfiles.cpp b/src/tools/qdoc/qdoctagfiles.cpp
index 1f6020fc09..a0054ea229 100644
--- a/src/tools/qdoc/qdoctagfiles.cpp
+++ b/src/tools/qdoc/qdoctagfiles.cpp
@@ -156,7 +156,7 @@ void QDocTagFiles::generateTagFileCompounds(QXmlStreamWriter& writer, const Inne
if (node->type() == Node::Class) {
writer.writeTextElement("name", node->fullDocumentName());
- writer.writeTextElement("filename", gen_->fullDocumentLocation(node,true));
+ writer.writeTextElement("filename", gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
// Classes contain information about their base classes.
const ClassNode* classNode = static_cast<const ClassNode*>(node);
@@ -175,7 +175,7 @@ void QDocTagFiles::generateTagFileCompounds(QXmlStreamWriter& writer, const Inne
}
else {
writer.writeTextElement("name", node->fullDocumentName());
- writer.writeTextElement("filename", gen_->fullDocumentLocation(node,true));
+ writer.writeTextElement("filename", gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()));
// Recurse to write all members.
generateTagFileMembers(writer, static_cast<const InnerNode*>(node));
@@ -291,7 +291,7 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter& writer, const InnerN
writer.writeTextElement("type", "virtual " + functionNode->returnType());
writer.writeTextElement("name", objName);
- QStringList pieces = gen_->fullDocumentLocation(node,true).split(QLatin1Char('#'));
+ QStringList pieces = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()).split(QLatin1Char('#'));
writer.writeTextElement("anchorfile", pieces[0]);
writer.writeTextElement("anchor", pieces[1]);
@@ -332,7 +332,7 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter& writer, const InnerN
const PropertyNode* propertyNode = static_cast<const PropertyNode*>(node);
writer.writeAttribute("type", propertyNode->dataType());
writer.writeTextElement("name", objName);
- QStringList pieces = gen_->fullDocumentLocation(node,true).split(QLatin1Char('#'));
+ QStringList pieces = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()).split(QLatin1Char('#'));
writer.writeTextElement("anchorfile", pieces[0]);
writer.writeTextElement("anchor", pieces[1]);
writer.writeTextElement("arglist", QString());
@@ -366,7 +366,7 @@ void QDocTagFiles::generateTagFileMembers(QXmlStreamWriter& writer, const InnerN
else
writer.writeAttribute("type", QString());
writer.writeTextElement("name", objName);
- QStringList pieces = gen_->fullDocumentLocation(node,true).split(QLatin1Char('#'));
+ QStringList pieces = gen_->fullDocumentLocation(node,Generator::useOutputSubdirs()).split(QLatin1Char('#'));
writer.writeTextElement("anchorfile", pieces[0]);
writer.writeTextElement("anchor", pieces[1]);
writer.writeTextElement("arglist", QString());
diff --git a/src/tools/qdoc/qmlcodeparser.cpp b/src/tools/qdoc/qmlcodeparser.cpp
index b9c0ad9218..28b9c3ec9b 100644
--- a/src/tools/qdoc/qmlcodeparser.cpp
+++ b/src/tools/qdoc/qmlcodeparser.cpp
@@ -70,6 +70,7 @@ QT_BEGIN_NAMESPACE
#define COMMAND_QMLTYPE Doc::alias("qmltype")
#define COMMAND_QMLMODULE Doc::alias("qmlmodule")
#define COMMAND_QMLPROPERTY Doc::alias("qmlproperty")
+#define COMMAND_QMLPROPERTYGROUP Doc::alias("qmlpropertygroup")
#define COMMAND_QMLATTACHEDPROPERTY Doc::alias("qmlattachedproperty")
#define COMMAND_QMLINHERITS Doc::alias("inherits")
#define COMMAND_QMLINSTANTIATES Doc::alias("instantiates")
@@ -166,9 +167,9 @@ void QmlCodeParser::parseSourceFile(const Location& location, const QString& fil
extractPragmas(newCode);
lexer->setCode(newCode, 1);
- QSet<QString> topicCommandsAllowed = topicCommands();
- QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
- QSet<QString> metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
+ const QSet<QString>& topicCommandsAllowed = topicCommands();
+ const QSet<QString>& otherMetacommandsAllowed = otherMetaCommands();
+ const QSet<QString>& metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
if (parser->parse()) {
QQmlJS::AST::UiProgram *ast = parser->ast();
@@ -195,42 +196,52 @@ void QmlCodeParser::doneParsingSourceFiles()
{
}
+static QSet<QString> topicCommands_;
/*!
Returns the set of strings representing the topic commands.
*/
-QSet<QString> QmlCodeParser::topicCommands()
+const QSet<QString>& QmlCodeParser::topicCommands()
{
- return QSet<QString>() << COMMAND_VARIABLE
- << COMMAND_QMLCLASS
- << COMMAND_QMLTYPE
- << COMMAND_QMLPROPERTY
- << COMMAND_QMLATTACHEDPROPERTY
- << COMMAND_QMLSIGNAL
- << COMMAND_QMLATTACHEDSIGNAL
- << COMMAND_QMLMETHOD
- << COMMAND_QMLATTACHEDMETHOD
- << COMMAND_QMLBASICTYPE;
+ if (topicCommands_.isEmpty()) {
+ topicCommands_ << COMMAND_VARIABLE
+ << COMMAND_QMLCLASS
+ << COMMAND_QMLTYPE
+ << COMMAND_QMLPROPERTY
+ << COMMAND_QMLPROPERTYGROUP
+ << COMMAND_QMLATTACHEDPROPERTY
+ << COMMAND_QMLSIGNAL
+ << COMMAND_QMLATTACHEDSIGNAL
+ << COMMAND_QMLMETHOD
+ << COMMAND_QMLATTACHEDMETHOD
+ << COMMAND_QMLBASICTYPE;
+ }
+ return topicCommands_;
}
+static QSet<QString> otherMetaCommands_;
/*!
Returns the set of strings representing the common metacommands
plus some other metacommands.
*/
-QSet<QString> QmlCodeParser::otherMetaCommands()
+const QSet<QString>& QmlCodeParser::otherMetaCommands()
{
- return commonMetaCommands() << COMMAND_STARTPAGE
- << COMMAND_QMLINHERITS
- << COMMAND_QMLDEFAULT
- << COMMAND_QMLREADONLY
- << COMMAND_DEPRECATED
- << COMMAND_INGROUP
- << COMMAND_INTERNAL
- << COMMAND_OBSOLETE
- << COMMAND_PRELIMINARY
- << COMMAND_SINCE
- << COMMAND_QMLABSTRACT
- << COMMAND_INQMLMODULE
- << COMMAND_WRAPPER;
+ if (otherMetaCommands_.isEmpty()) {
+ otherMetaCommands_ = commonMetaCommands();
+ otherMetaCommands_ << COMMAND_STARTPAGE
+ << COMMAND_QMLINHERITS
+ << COMMAND_QMLDEFAULT
+ << COMMAND_QMLREADONLY
+ << COMMAND_DEPRECATED
+ << COMMAND_INGROUP
+ << COMMAND_INTERNAL
+ << COMMAND_OBSOLETE
+ << COMMAND_PRELIMINARY
+ << COMMAND_SINCE
+ << COMMAND_QMLABSTRACT
+ << COMMAND_INQMLMODULE
+ << COMMAND_WRAPPER;
+ }
+ return otherMetaCommands_;
}
/*!
diff --git a/src/tools/qdoc/qmlcodeparser.h b/src/tools/qdoc/qmlcodeparser.h
index 5bdcfbfbbf..71b4660fe7 100644
--- a/src/tools/qdoc/qmlcodeparser.h
+++ b/src/tools/qdoc/qmlcodeparser.h
@@ -79,8 +79,8 @@ public:
void extractPragmas(QString &script);
protected:
- virtual QSet<QString> topicCommands();
- virtual QSet<QString> otherMetaCommands();
+ const QSet<QString>& topicCommands();
+ const QSet<QString>& otherMetaCommands();
private:
QQmlJS::Engine engine;
diff --git a/src/tools/qdoc/qmlvisitor.cpp b/src/tools/qdoc/qmlvisitor.cpp
index 86b86c8f34..c049857717 100644
--- a/src/tools/qdoc/qmlvisitor.cpp
+++ b/src/tools/qdoc/qmlvisitor.cpp
@@ -67,6 +67,7 @@ QT_BEGIN_NAMESPACE
#define COMMAND_QMLTYPE Doc::alias(QLatin1String("qmltype"))
#define COMMAND_QMLMODULE Doc::alias(QLatin1String("qmlmodule"))
#define COMMAND_QMLPROPERTY Doc::alias(QLatin1String("qmlproperty"))
+#define COMMAND_QMLPROPERTYGROUP Doc::alias(QLatin1String("qmlpropertygroup"))
#define COMMAND_QMLATTACHEDPROPERTY Doc::alias(QLatin1String("qmlattachedproperty"))
#define COMMAND_QMLINHERITS Doc::alias(QLatin1String("inherits"))
#define COMMAND_QMLINSTANTIATES Doc::alias(QLatin1String("instantiates"))
@@ -85,17 +86,17 @@ QT_BEGIN_NAMESPACE
QmlDocVisitor::QmlDocVisitor(const QString &filePath,
const QString &code,
QQmlJS::Engine *engine,
- QSet<QString> &commands,
- QSet<QString> &topics)
+ const QSet<QString> &commands,
+ const QSet<QString> &topics)
: nestingLevel(0)
{
lastEndOffset = 0;
- this->filePath = filePath;
+ this->filePath_ = filePath;
this->name = QFileInfo(filePath).baseName();
document = code;
this->engine = engine;
- this->commands = commands;
- this->topics = topics;
+ this->commands_ = commands;
+ this->topics_ = topics;
current = QDocDatabase::qdocDB()->treeRoot();
}
@@ -141,13 +142,89 @@ QQmlJS::AST::SourceLocation QmlDocVisitor::precedingComment(quint32 offset) cons
return QQmlJS::AST::SourceLocation();
}
+#if 0
+ ArgList args;
+ QSet<QString>::iterator i = metacommands.begin();
+ while (i != metacommands.end()) {
+ if (topics_.contains(*i)) {
+ topic = *i;
+ break;
+ }
+ ++i;
+ }
+ if (!topic.isEmpty()) {
+ args = doc.metaCommandArgs(topic);
+ if ((topic == COMMAND_QMLCLASS) || (topic == COMMAND_QMLTYPE)) {
+ // do nothing.
+ }
+ else if (topic == COMMAND_QMLPROPERTY) {
+ if (node->type() == Node::QmlProperty) {
+ QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
+ qpn->setReadOnly(0);
+ if (qpn->dataType() == "alias") {
+ QStringList part = args[0].first.split(QLatin1Char(' '));
+ qpn->setDataType(part[0]);
+ }
+ }
+ }
+ else if (topic == COMMAND_QMLPROPERTYGROUP) {
+ // zzz ?
+ }
+ else if (topic == COMMAND_QMLMODULE) {
+ }
+ else if (topic == COMMAND_QMLATTACHEDPROPERTY) {
+ if (node->type() == Node::QmlProperty) {
+ QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
+ qpn->setReadOnly(0);
+ }
+ }
+ else if (topic == COMMAND_QMLSIGNAL) {
+ }
+ else if (topic == COMMAND_QMLATTACHEDSIGNAL) {
+ }
+ else if (topic == COMMAND_QMLMETHOD) {
+ }
+ else if (topic == COMMAND_QMLATTACHEDMETHOD) {
+ }
+ else if (topic == COMMAND_QMLBASICTYPE) {
+ }
+ }
+
+ if (node->type() == Node::QmlProperty) {
+ QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
+ for (int i=0; i<topicsUsed.size(); ++i) {
+ if (topicsUsed.at(i).topic == "qmlproperty") {
+ /*
+ A \qmlproperty command would be used in a QML file
+ to document the underlying property for a property
+ alias.
+ */
+ QmlPropArgs qpa;
+ if (splitQmlPropertyArg(doc, topicsUsed.at(i).args, qpa)) {
+ QmlPropertyNode* n = parent->hasQmlPropertyNode(qpa.name_);
+ if (n == 0)
+ n = new QmlPropertyNode(qpn, qpa.name_, qpa.type_, false);
+ n->setLocation(doc.location());
+ n->setReadOnly(qpn->isReadOnly());
+ if (qpn->isDefault())
+ n->setDefault();
+ }
+ else
+ qDebug() << " FAILED TO PARSE QML PROPERTY:"
+ << topicsUsed.at(i).topic << topicsUsed.at(i).args;
+ }
+ }
+ }
+
+#endif
+
/*!
Finds the nearest unused qdoc comment above the QML entity
represented by the \a node and processes the qdoc commands
- in that comment. The proceesed documentation is stored in
+ in that comment. The processed documentation is stored in
the \a node.
- If a qdoc comment is found about \a location, true is returned.
+ If a qdoc comment is found for \a location, true is returned.
If a comment is not found there, false is returned.
*/
bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Node* node)
@@ -156,23 +233,66 @@ bool QmlDocVisitor::applyDocumentation(QQmlJS::AST::SourceLocation location, Nod
if (loc.isValid()) {
QString source = document.mid(loc.offset, loc.length);
- Location start(filePath);
+ Location start(filePath_);
start.setLineNo(loc.startLine);
start.setColumnNo(loc.startColumn);
- Location finish(filePath);
+ Location finish(filePath_);
finish.setLineNo(loc.startLine);
finish.setColumnNo(loc.startColumn);
- Doc doc(start, finish, source.mid(1), commands, topics);
+ Doc doc(start, finish, source.mid(1), commands_, topics_);
+ const TopicList& topicsUsed = doc.topicsUsed();
+ NodeList nodes;
+ Node* nodePassedIn = node;
+ InnerNode* parent = nodePassedIn->parent();
node->setDoc(doc);
- applyMetacommands(loc, node, doc);
+ nodes.append(node);
+ if (topicsUsed.size() > 0) {
+ for (int i=0; i<topicsUsed.size(); ++i) {
+ if (topicsUsed.at(i).topic == QString("qmlpropertygroup")) {
+ qDebug() << "PROPERTY GROUP COMMAND SEEN:" << topicsUsed.at(i).args << filePath_;
+ break;
+ }
+ }
+ for (int i=0; i<topicsUsed.size(); ++i) {
+ QString topic = topicsUsed.at(i).topic;
+ QString args = topicsUsed.at(i).args;
+ if ((topic == COMMAND_QMLPROPERTY) || (topic == COMMAND_QMLATTACHEDPROPERTY)) {
+ QmlPropArgs qpa;
+ if (splitQmlPropertyArg(doc, args, qpa)) {
+ if (qpa.name_ == nodePassedIn->name()) {
+ if (nodePassedIn->isAlias())
+ nodePassedIn->setDataType(qpa.type_);
+ }
+ else {
+ bool isAttached = (topic == COMMAND_QMLATTACHEDPROPERTY);
+ QmlPropertyNode* n = parent->hasQmlProperty(qpa.name_);
+ if (n == 0)
+ n = new QmlPropertyNode(parent, qpa.name_, qpa.type_, isAttached);
+ n->setLocation(doc.location());
+ n->setDoc(doc);
+ n->setReadOnly(nodePassedIn->isReadOnly());
+ if (nodePassedIn->isDefault())
+ n->setDefault();
+ if (isAttached)
+ n->setReadOnly(0);
+ nodes.append(n);
+ }
+ }
+ else
+ qDebug() << " FAILED TO PARSE QML PROPERTY:" << topic << args;
+ }
+ }
+ }
+ for (int i=0; i<nodes.size(); ++i)
+ applyMetacommands(loc, nodes.at(i), doc);
usedComments.insert(loc.offset);
if (doc.isEmpty()) {
return false;
}
return true;
}
- Location codeLoc(filePath);
+ Location codeLoc(filePath_);
codeLoc.setLineNo(location.startLine);
node->setLocation(codeLoc);
return false;
@@ -237,80 +357,13 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation,
Doc& doc)
{
QDocDatabase* qdb = QDocDatabase::qdocDB();
-
- const TopicList& topicsUsed = doc.topicsUsed();
- if (topicsUsed.size() > 0) {
- if (node->type() == Node::QmlProperty) {
- QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
- for (int i=0; i<topicsUsed.size(); ++i) {
- if (topicsUsed.at(i).topic == "qmlproperty") {
- QmlPropArgs qpa;
- if (splitQmlPropertyArg(doc, topicsUsed.at(i).args, qpa)) {
- QmlPropertyNode* n = new QmlPropertyNode(qpn, qpa.name_, qpa.type_, false);
- n->setLocation(doc.location());
- qpn->appendQmlPropNode(n);
- n->setReadOnly(qpn->isReadOnly());
- if (qpn->isDefault())
- n->setDefault();
- }
- else
- qDebug() << " FAILED TO PARSE QML PROPERTY:"
- << topicsUsed.at(i).topic << topicsUsed.at(i).args;
- }
- }
- }
- }
QSet<QString> metacommands = doc.metaCommandsUsed();
if (metacommands.count() > 0) {
- QString topic;
- ArgList args;
+ metacommands.subtract(topics_);
QSet<QString>::iterator i = metacommands.begin();
while (i != metacommands.end()) {
- if (topics.contains(*i)) {
- topic = *i;
- break;
- }
- ++i;
- }
- if (!topic.isEmpty()) {
- args = doc.metaCommandArgs(topic);
- if ((topic == COMMAND_QMLCLASS) || (topic == COMMAND_QMLTYPE)) {
- // do nothing.
- }
- else if (topic == COMMAND_QMLPROPERTY) {
- if (node->type() == Node::QmlProperty) {
- QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
- qpn->setReadOnly(0);
- if (qpn->dataType() == "alias") {
- QStringList part = args[0].first.split(QLatin1Char(' '));
- qpn->setDataType(part[0]);
- }
- }
- }
- else if (topic == COMMAND_QMLMODULE) {
- }
- else if (topic == COMMAND_QMLATTACHEDPROPERTY) {
- if (node->type() == Node::QmlProperty) {
- QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
- qpn->setReadOnly(0);
- }
- }
- else if (topic == COMMAND_QMLSIGNAL) {
- }
- else if (topic == COMMAND_QMLATTACHEDSIGNAL) {
- }
- else if (topic == COMMAND_QMLMETHOD) {
- }
- else if (topic == COMMAND_QMLATTACHEDMETHOD) {
- }
- else if (topic == COMMAND_QMLBASICTYPE) {
- }
- }
- metacommands.subtract(topics);
- i = metacommands.begin();
- while (i != metacommands.end()) {
QString command = *i;
- args = doc.metaCommandArgs(command);
+ ArgList args = doc.metaCommandArgs(command);
if (command == COMMAND_QMLABSTRACT) {
if ((node->type() == Node::Document) && (node->subType() == Node::QmlClass)) {
node->setAbstract(true);
@@ -528,7 +581,9 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
QmlClassNode *qmlClass = static_cast<QmlClassNode *>(current);
if (qmlClass) {
QString name = member->name.toString();
- QmlPropertyNode *qmlPropNode = new QmlPropertyNode(qmlClass, name, type, false);
+ QmlPropertyNode* qmlPropNode = qmlClass->hasQmlProperty(name);
+ if (qmlPropNode == 0)
+ qmlPropNode = new QmlPropertyNode(qmlClass, name, type, false);
qmlPropNode->setReadOnly(member->isReadonlyMember);
if (member->isDefaultMember)
qmlPropNode->setDefault();
diff --git a/src/tools/qdoc/qmlvisitor.h b/src/tools/qdoc/qmlvisitor.h
index 2c3ff341d6..cdb7ae7391 100644
--- a/src/tools/qdoc/qmlvisitor.h
+++ b/src/tools/qdoc/qmlvisitor.h
@@ -45,7 +45,6 @@
#include <qstring.h>
#include "qqmljsastvisitor_p.h"
#include "node.h"
-#include "tree.h"
QT_BEGIN_NAMESPACE
@@ -72,8 +71,8 @@ public:
QmlDocVisitor(const QString &filePath,
const QString &code,
QQmlJS::Engine *engine,
- QSet<QString> &commands,
- QSet<QString> &topics);
+ const QSet<QString> &commands,
+ const QSet<QString> &topics);
virtual ~QmlDocVisitor();
bool visit(QQmlJS::AST::UiImportList *imports);
@@ -113,12 +112,12 @@ private:
QQmlJS::Engine *engine;
quint32 lastEndOffset;
quint32 nestingLevel;
- QString filePath;
+ QString filePath_;
QString name;
QString document;
ImportList importList;
- QSet<QString> commands;
- QSet<QString> topics;
+ QSet<QString> commands_;
+ QSet<QString> topics_;
QSet<quint32> usedComments;
InnerNode *current;
};
diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp
index 553c569ae9..8c5ecdcfe9 100644
--- a/src/tools/qdoc/tree.cpp
+++ b/src/tools/qdoc/tree.cpp
@@ -169,7 +169,7 @@ const Node* Tree::findNode(const QStringList& path,
if (node && i == path.size()
&& (!(findFlags & NonFunction) || node->type() != Node::Function
|| ((FunctionNode*)node)->metaness() == FunctionNode::MacroWithoutParams)) {
- if ((node != self) && (node->subType() != Node::QmlPropertyGroup)) {
+ if ((node != self) && (node->type() != Node::QmlPropertyGroup)) {
if (node->subType() == Node::Collision) {
node = node->applyModuleIdentifier(start);
}
diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp
index f5a1301666..baafb8ec92 100644
--- a/src/tools/uic/main.cpp
+++ b/src/tools/uic/main.cpp
@@ -106,13 +106,6 @@ int runUic(int argc, char *argv[])
return 1;
}
driver.option().postfix = QLatin1String(argv[arg]);
- } else if (opt == QLatin1String("-3")) {
- ++arg;
- if (!argv[arg]) {
- showHelp(argv[0]);
- return 1;
- }
- driver.option().uic3 = QFile::decodeName(argv[arg]);
} else if (opt == QLatin1String("-tr") || opt == QLatin1String("-translate")) {
++arg;
if (!argv[arg]) {
diff --git a/src/tools/uic/option.h b/src/tools/uic/option.h
index 141eb4806a..14ed422d63 100644
--- a/src/tools/uic/option.h
+++ b/src/tools/uic/option.h
@@ -73,7 +73,6 @@ struct Option
QString prefix;
QString postfix;
QString translateFunction;
- QString uic3;
#ifdef QT_UIC_JAVA_GENERATOR
QString javaPackage;
QString javaOutputDirectory;
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index c08a034d9e..5da41aa0a5 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -63,6 +63,8 @@
#include "qmimedata.h"
#include "qspinbox.h"
#include "qdialogbuttonbox.h"
+#include "qscreen.h"
+#include "qcursor.h"
QT_BEGIN_NAMESPACE
@@ -920,6 +922,8 @@ signals:
private slots:
void rgbEd();
void hsvEd();
+ void htmlEd();
+
private:
void showCurrentColor();
int hue, sat, val;
@@ -931,6 +935,7 @@ private:
QLabel *lblRed;
QLabel *lblGreen;
QLabel *lblBlue;
+ QLabel *lblHtml;
QColSpinBox *hEd;
QColSpinBox *sEd;
QColSpinBox *vEd;
@@ -939,6 +944,7 @@ private:
QColSpinBox *bEd;
QColSpinBox *alphaEd;
QLabel *alphaLab;
+ QLineEdit *htEd;
QColorShowLabel *lab;
bool rgbOriginal;
QColorDialog *colorDialog;
@@ -1230,6 +1236,19 @@ QColorShower::QColorShower(QColorDialog *parent)
#endif
alphaEd->hide();
alphaLab->hide();
+ lblHtml = new QLabel(this);
+ htEd = new QLineEdit(this);
+#ifndef QT_NO_SHORTCUT
+ lblHtml->setBuddy(htEd);
+#endif
+
+ QRegularExpression regExp(QStringLiteral("#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})"));
+ QRegularExpressionValidator *validator = new QRegularExpressionValidator(regExp, this);
+ htEd->setValidator(validator);
+
+ lblHtml->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+ gl->addWidget(lblHtml, 5, 1);
+ gl->addWidget(htEd, 5, 2);
connect(hEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
connect(sEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
@@ -1239,6 +1258,7 @@ QColorShower::QColorShower(QColorDialog *parent)
connect(gEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
connect(bEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
connect(alphaEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
+ connect(htEd, SIGNAL(textEdited(QString)), this, SLOT(htmlEd()));
retranslateStrings();
}
@@ -1251,7 +1271,7 @@ inline bool QColorDialogPrivate::isAlphaVisible() const { return cs->isAlphaVisi
QColor QColorDialogPrivate::currentQColor() const
{
- if (!options->testOption(QColorDialogOptions::DontUseNativeDialog) && nativeDialogInUse)
+ if (nativeDialogInUse)
return platformColorDialogHelper()->currentColor();
return cs->currentQColor();
}
@@ -1273,6 +1293,8 @@ void QColorShower::rgbEd()
sEd->setValue(sat);
vEd->setValue(val);
+ htEd->setText(QColor(curCol).name());
+
showCurrentColor();
emit newCol(currentColor());
updateQColor();
@@ -1293,6 +1315,31 @@ void QColorShower::hsvEd()
gEd->setValue(qGreen(currentColor()));
bEd->setValue(qBlue(currentColor()));
+ htEd->setText(c.name());
+
+ showCurrentColor();
+ emit newCol(currentColor());
+ updateQColor();
+}
+
+void QColorShower::htmlEd()
+{
+ QColor c;
+ QString t = htEd->text();
+ c.setNamedColor(t);
+ if (!c.isValid())
+ return;
+ curCol = qRgba(c.red(), c.green(), c.blue(), currentAlpha());
+ rgb2hsv(curCol, hue, sat, val);
+
+ hEd->setValue(hue);
+ sEd->setValue(sat);
+ vEd->setValue(val);
+
+ rEd->setValue(qRed(currentColor()));
+ gEd->setValue(qGreen(currentColor()));
+ bEd->setValue(qBlue(currentColor()));
+
showCurrentColor();
emit newCol(currentColor());
updateQColor();
@@ -1313,6 +1360,8 @@ void QColorShower::setRgb(QRgb rgb)
gEd->setValue(qGreen(currentColor()));
bEd->setValue(qBlue(currentColor()));
+ htEd->setText(QColor(rgb).name());
+
showCurrentColor();
updateQColor();
}
@@ -1336,6 +1385,8 @@ void QColorShower::setHsv(int h, int s, int v)
gEd->setValue(qGreen(currentColor()));
bEd->setValue(qBlue(currentColor()));
+ htEd->setText(c.name());
+
showCurrentColor();
updateQColor();
}
@@ -1349,6 +1400,7 @@ void QColorShower::retranslateStrings()
lblGreen->setText(QColorDialog::tr("&Green:"));
lblBlue->setText(QColorDialog::tr("Bl&ue:"));
alphaLab->setText(QColorDialog::tr("A&lpha channel:"));
+ lblHtml->setText(QColorDialog::tr("&HTML:"));
}
void QColorShower::updateQColor()
@@ -1362,16 +1414,20 @@ void QColorShower::updateQColor()
//sets all widgets to display h,s,v
void QColorDialogPrivate::_q_newHsv(int h, int s, int v)
{
- cs->setHsv(h, s, v);
- cp->setCol(h, s);
- lp->setCol(h, s, v);
+ if (!nativeDialogInUse) {
+ cs->setHsv(h, s, v);
+ cp->setCol(h, s);
+ lp->setCol(h, s, v);
+ }
}
//sets all widgets to display rgb
void QColorDialogPrivate::setCurrentColor(QRgb rgb)
{
- cs->setRgb(rgb);
- _q_newColorTypedIn(rgb);
+ if (!nativeDialogInUse) {
+ cs->setRgb(rgb);
+ _q_newColorTypedIn(rgb);
+ }
}
// hack; doesn't keep curCol in sync, so use with care
@@ -1421,13 +1477,24 @@ bool QColorDialogPrivate::selectColor(const QColor &col)
return false;
}
+QColor QColorDialogPrivate::grabScreenColor(const QPoint &p)
+{
+ const QDesktopWidget *desktop = QApplication::desktop();
+ const QPixmap pixmap = QGuiApplication::screens().at(desktop->screenNumber())->grabWindow(desktop->winId(),
+ p.x(), p.y(), 1, 1);
+ QImage i = pixmap.toImage();
+ return i.pixel(0, 0);
+}
+
//sets all widgets except cs to display rgb
void QColorDialogPrivate::_q_newColorTypedIn(QRgb rgb)
{
- int h, s, v;
- rgb2hsv(rgb, h, s, v);
- cp->setCol(h, s);
- lp->setCol(h, s, v);
+ if (!nativeDialogInUse) {
+ int h, s, v;
+ rgb2hsv(rgb, h, s, v);
+ cp->setCol(h, s);
+ lp->setCol(h, s, v);
+ }
}
void QColorDialogPrivate::_q_nextCustom(int r, int c)
@@ -1450,6 +1517,48 @@ void QColorDialogPrivate::_q_newStandard(int r, int c)
custom->setSelected(-1,-1);
}
+void QColorDialogPrivate::_q_pickScreenColor()
+{
+ Q_Q(QColorDialog);
+ screenColorPicking = true;
+ // If user pushes Escape, the last color before picking will be restored.
+ beforeScreenColorPicking = cs->currentColor();
+ /*For some reason, q->grabMouse(Qt::CrossCursor) doesn't change
+ * the cursor, and therefore I have to change it manually.
+ */
+ q->grabMouse();
+ q->setCursor(Qt::CrossCursor);
+ q->grabKeyboard();
+ /* With setMouseTracking(true) the desired color can be more precisedly picked up,
+ * and continuously pushing the mouse button is not necessary.
+ */
+ q->setMouseTracking(true);
+
+ addCusBt->setDisabled(true);
+ buttons->setDisabled(true);
+ screenColorPickerButton->setDisabled(true);
+
+ q->setCurrentColor(grabScreenColor(QCursor::pos()));
+ lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2, color: %3\nPress ESC to cancel")
+ .arg(QCursor::pos().x())
+ .arg(QCursor::pos().y())
+ .arg(q->currentColor().name()));
+}
+
+void QColorDialogPrivate::releaseColorPicking()
+{
+ Q_Q(QColorDialog);
+ screenColorPicking = false;
+ q->releaseMouse();
+ q->releaseKeyboard();
+ q->setCursor(Qt::ArrowCursor);
+ q->setMouseTracking(false);
+ lblScreenColorInfo->setText(QLatin1String("\n"));
+ addCusBt->setDisabled(false);
+ buttons->setDisabled(false);
+ screenColorPickerButton->setDisabled(false);
+}
+
void QColorDialogPrivate::init(const QColor &initial)
{
Q_Q(QColorDialog);
@@ -1457,9 +1566,24 @@ void QColorDialogPrivate::init(const QColor &initial)
q->setSizeGripEnabled(false);
q->setWindowTitle(QColorDialog::tr("Select Color"));
+ // default: use the native dialog if possible. Can be overridden in setOptions()
nativeDialogInUse = (platformColorDialogHelper() != 0);
-
+ screenColorPicking = false;
nextCust = 0;
+
+ if (!nativeDialogInUse)
+ initWidgets();
+
+#ifdef Q_WS_MAC
+ delegate = 0;
+#endif
+
+ q->setCurrentColor(initial);
+}
+
+void QColorDialogPrivate::initWidgets()
+{
+ Q_Q(QColorDialog);
QVBoxLayout *mainLay = new QVBoxLayout(q);
// there's nothing in this dialog that benefits from sizing up
mainLay->setSizeConstraint(QLayout::SetFixedSize);
@@ -1494,6 +1618,15 @@ void QColorDialogPrivate::init(const QColor &initial)
leftLay->addWidget(lblBasicColors);
leftLay->addWidget(standard);
+#if !defined(Q_OS_WINCE) && !defined(QT_SMALL_COLORDIALOG)
+ // The screen color picker button
+ screenColorPickerButton = new QPushButton(QColorDialog::tr("Pick Screen Color"));
+ leftLay->addWidget(screenColorPickerButton);
+ lblScreenColorInfo = new QLabel(QLatin1String("\n"));
+ leftLay->addWidget(lblScreenColorInfo);
+ q->connect(screenColorPickerButton, SIGNAL(clicked()), SLOT(_q_pickScreenColor()));
+#endif
+
#if !defined(Q_OS_WINCE)
leftLay->addStretch();
#endif
@@ -1597,12 +1730,6 @@ void QColorDialogPrivate::init(const QColor &initial)
QObject::connect(cancel, SIGNAL(clicked()), q, SLOT(reject()));
retranslateStrings();
-
-#ifdef Q_WS_MAC
- delegate = 0;
-#endif
-
- q->setCurrentColor(initial);
}
void QColorDialogPrivate::initHelper(QPlatformDialogHelper *h)
@@ -1667,6 +1794,11 @@ static const Qt::WindowFlags DefaultWindowFlags =
during the execution of the program. Use setCustomColor() to set
the custom colors, and use customColor() to get them.
+ When pressing the "Pick Screen Color" button, the cursor changes to a haircross
+ and the colors on the screen are scanned. The user can pick up one by clicking
+ the mouse or the Enter button. Pressing Escape restores the last color selected
+ before entering this mode.
+
The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
how to use QColorDialog as well as other built-in Qt dialogs.
@@ -1708,12 +1840,13 @@ QColorDialog::QColorDialog(const QColor &initial, QWidget *parent)
void QColorDialog::setCurrentColor(const QColor &color)
{
Q_D(QColorDialog);
- d->setCurrentColor(color.rgb());
- d->selectColor(color);
- d->setCurrentAlpha(color.alpha());
-
- if (!testOption(QColorDialog::DontUseNativeDialog) && d->nativeDialogInUse)
+ if (d->nativeDialogInUse)
d->platformColorDialogHelper()->setCurrentColor(color);
+ else {
+ d->setCurrentColor(color.rgb());
+ d->selectColor(color);
+ d->setCurrentAlpha(color.alpha());
+ }
}
QColor QColorDialog::currentColor() const
@@ -1783,10 +1916,14 @@ void QColorDialog::setOptions(ColorDialogOptions options)
return;
d->options->setOptions(QColorDialogOptions::ColorDialogOptions(int(options)));
- d->buttons->setVisible(!(options & NoButtons));
- d->showAlpha(options & ShowAlphaChannel);
- if (options & DontUseNativeDialog)
+ if ((options & DontUseNativeDialog) && d->nativeDialogInUse) {
d->nativeDialogInUse = false;
+ d->initWidgets();
+ }
+ if (!d->nativeDialogInUse) {
+ d->buttons->setVisible(!(options & NoButtons));
+ d->showAlpha(options & ShowAlphaChannel);
+ }
}
QColorDialog::ColorDialogOptions QColorDialog::options() const
@@ -1868,7 +2005,7 @@ void QColorDialog::setVisible(bool visible)
}
#else
- if (!(options() & DontUseNativeDialog) && d->nativeDialogInUse) {
+ if (d->nativeDialogInUse) {
d->setNativeDialogVisible(visible);
// Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
// updates the state correctly, but skips showing the non-native version:
@@ -1983,6 +2120,57 @@ void QColorDialog::changeEvent(QEvent *e)
}
/*!
+ \reimp
+*/
+void QColorDialog::mouseMoveEvent(QMouseEvent *e)
+{
+ Q_D(QColorDialog);
+ if (d->screenColorPicking) {
+ setCurrentColor(d->grabScreenColor(e->globalPos()));
+ d->lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2, color: %3\nPress ESC to cancel")
+ .arg(e->globalPos().x())
+ .arg(e->globalPos().y())
+ .arg(currentColor().name()));
+ return;
+ }
+ QDialog::mouseMoveEvent(e);
+}
+
+/*!
+ \reimp
+*/
+void QColorDialog::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_D(QColorDialog);
+ if (d->screenColorPicking) {
+ setCurrentColor(d->grabScreenColor(e->globalPos()));
+ d->releaseColorPicking();
+ return;
+ }
+ QDialog::mouseReleaseEvent(e);
+}
+
+/*!
+ \reimp
+*/
+void QColorDialog::keyPressEvent(QKeyEvent *e)
+{
+ Q_D(QColorDialog);
+ if (d->screenColorPicking) {
+ if (e->key() == Qt::Key_Escape) {
+ d->releaseColorPicking();
+ d->setCurrentColor(d->beforeScreenColorPicking);
+ } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
+ setCurrentColor(d->grabScreenColor(QCursor::pos()));
+ d->releaseColorPicking();
+ }
+ e->accept();
+ return;
+ }
+ QDialog::keyPressEvent(e);
+}
+
+/*!
Closes the dialog and sets its result code to \a result. If this dialog
is shown with exec(), done() causes the local event loop to finish,
and exec() to return \a result.
diff --git a/src/widgets/dialogs/qcolordialog.h b/src/widgets/dialogs/qcolordialog.h
index f6dc627a05..c7a1d6f400 100644
--- a/src/widgets/dialogs/qcolordialog.h
+++ b/src/widgets/dialogs/qcolordialog.h
@@ -112,6 +112,9 @@ Q_SIGNALS:
protected:
void changeEvent(QEvent *event);
+ virtual void mouseMoveEvent(QMouseEvent *);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void keyPressEvent(QKeyEvent *);
void done(int result);
private:
@@ -123,6 +126,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_nextCustom(int, int))
Q_PRIVATE_SLOT(d_func(), void _q_newCustom(int, int))
Q_PRIVATE_SLOT(d_func(), void _q_newStandard(int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_pickScreenColor())
friend class QColorShower;
};
diff --git a/src/widgets/dialogs/qcolordialog_p.h b/src/widgets/dialogs/qcolordialog_p.h
index 695e95d26c..08199cc7c1 100644
--- a/src/widgets/dialogs/qcolordialog_p.h
+++ b/src/widgets/dialogs/qcolordialog_p.h
@@ -82,11 +82,13 @@ public:
{ return static_cast<QPlatformColorDialogHelper *>(platformHelper()); }
void init(const QColor &initial);
+ void initWidgets();
QRgb currentColor() const;
QColor currentQColor() const;
void setCurrentColor(QRgb rgb);
void setCurrentQColor(const QColor &color);
bool selectColor(const QColor &color);
+ QColor grabScreenColor(const QPoint &p);
int currentAlpha() const;
void setCurrentAlpha(int a);
@@ -101,6 +103,8 @@ public:
void _q_nextCustom(int, int);
void _q_newCustom(int, int);
void _q_newStandard(int, int);
+ void _q_pickScreenColor();
+ void releaseColorPicking();
QWellArray *custom;
QWellArray *standard;
@@ -112,12 +116,16 @@ public:
QColorShower *cs;
QLabel *lblBasicColors;
QLabel *lblCustomColors;
+ QLabel *lblScreenColorInfo;
QPushButton *ok;
QPushButton *cancel;
QPushButton *addCusBt;
+ QPushButton *screenColorPickerButton;
QColor selectedQColor;
int nextCust;
bool smallDisplay;
+ bool screenColorPicking;
+ QRgb beforeScreenColorPicking;
QSharedPointer<QColorDialogOptions> options;
QPointer<QObject> receiverToDisconnectOnClose;
diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h
index eb0cb2372b..5064efa35d 100644
--- a/src/widgets/dialogs/qdialog_p.h
+++ b/src/widgets/dialogs/qdialog_p.h
@@ -111,7 +111,7 @@ public:
QPointer<QEventLoop> eventLoop;
- bool nativeDialogInUse; // Assigned in setVisible_sys() in derived classes.
+ bool nativeDialogInUse;
QPlatformDialogHelper *platformHelper() const;
private:
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index c42752311f..9c4b99253a 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -86,15 +86,27 @@ Q_GLOBAL_STATIC(QString, lastVisitedDir)
typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
Q_WIDGETS_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook = 0;
+typedef QUrl (*_qt_filedialog_existing_directory_url_hook)(QWidget *parent, const QString &caption, const QUrl &dir, QFileDialog::Options options, const QStringList &supportedSchemes);
+Q_WIDGETS_EXPORT _qt_filedialog_existing_directory_url_hook qt_filedialog_existing_directory_url_hook = 0;
+
typedef QString (*_qt_filedialog_open_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
Q_WIDGETS_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook = 0;
+typedef QUrl (*_qt_filedialog_open_file_url_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
+Q_WIDGETS_EXPORT _qt_filedialog_open_file_url_hook qt_filedialog_open_file_url_hook = 0;
+
typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
Q_WIDGETS_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook = 0;
+typedef QList<QUrl> (*_qt_filedialog_open_file_urls_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
+Q_WIDGETS_EXPORT _qt_filedialog_open_file_urls_hook qt_filedialog_open_file_urls_hook = 0;
+
typedef QString (*_qt_filedialog_save_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
Q_WIDGETS_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook = 0;
+typedef QUrl (*_qt_filedialog_save_file_url_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
+Q_WIDGETS_EXPORT _qt_filedialog_save_file_url_hook qt_filedialog_save_file_url_hook = 0;
+
/*!
\class QFileDialog
\brief The QFileDialog class provides a dialog that allow users to select files or directories.
@@ -243,6 +255,11 @@ Q_WIDGETS_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_h
static functions will always be an application modal dialog. If
you want to use sheets, use QFileDialog::open() instead.
+ \value DontUseCustomDirectoryIcons Always use the default directory icon.
+ Some platforms allow the user to set a different icon. Custom icon lookup
+ cause a big performance impact over network or removable drives.
+ Setting this will enable the QFileIconProvider::DontUseCustomDirectoryIcons
+ option in the icon provider. This enum value was added in Qt 5.2.
*/
/*!
@@ -258,37 +275,76 @@ Q_WIDGETS_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_h
/*!
\fn void QFileDialog::filesSelected(const QStringList &selected)
- When the selection changes and the dialog is accepted, this signal is
- emitted with the (possibly empty) list of \a selected files.
+ When the selection changes for local operations and the dialog is
+ accepted, this signal is emitted with the (possibly empty) list
+ of \a selected files.
\sa currentChanged(), QDialog::Accepted
*/
+/*!
+ \fn void QFileDialog::urlsSelected(const QList<QUrl> &urls)
+
+ When the selection changes and the dialog is accepted, this signal is
+ emitted with the (possibly empty) list of selected \a urls.
+
+ \sa currentUrlChanged(), QDialog::Accepted
+ \since 5.2
+*/
/*!
\fn void QFileDialog::fileSelected(const QString &file)
- When the selection changes and the dialog is accepted, this signal is
- emitted with the (possibly empty) selected \a file.
+ When the selection changes for local operations and the dialog is
+ accepted, this signal is emitted with the (possibly empty)
+ selected \a file.
\sa currentChanged(), QDialog::Accepted
*/
+/*!
+ \fn void QFileDialog::urlSelected(const QUrl &url)
+
+ When the selection changes and the dialog is accepted, this signal is
+ emitted with the (possibly empty) selected \a url.
+
+ \sa currentUrlChanged(), QDialog::Accepted
+ \since 5.2
+*/
/*!
\fn void QFileDialog::currentChanged(const QString &path)
- When the current file changes, this signal is emitted with the
- new file name as the \a path parameter.
+ When the current file changes for local operations, this signal is
+ emitted with the new file name as the \a path parameter.
\sa filesSelected()
*/
/*!
+ \fn void QFileDialog::currentUrlChanged(const QUrl &url)
+
+ When the current file changes, this signal is emitted with the
+ new file URL as the \a url parameter.
+
+ \sa urlsSelected()
+ \since 5.2
+*/
+
+/*!
\fn void QFileDialog::directoryEntered(const QString &directory)
\since 4.3
+ This signal is emitted for local operations when the user enters
+ a \a directory.
+*/
+
+/*!
+ \fn void QFileDialog::directoryUrlEntered(const QUrl &directory)
+
This signal is emitted when the user enters a \a directory.
+
+ \since 5.2
*/
/*!
@@ -532,11 +588,10 @@ QFileDialogPrivate::~QFileDialogPrivate()
void QFileDialogPrivate::initHelper(QPlatformDialogHelper *h)
{
QFileDialog *d = q_func();
- QObject::connect(h, SIGNAL(fileSelected(QString)), d, SIGNAL(fileSelected(QString)));
- QObject::connect(h, SIGNAL(filesSelected(QStringList)), d, SIGNAL(filesSelected(QStringList)));
- QObject::connect(h, SIGNAL(currentChanged(QString)), d, SIGNAL(currentChanged(QString)));
- QObject::connect(h, SIGNAL(directoryEntered(QString)), d, SIGNAL(directoryEntered(QString)));
- QObject::connect(h, SIGNAL(directoryEntered(QString)), d, SLOT(_q_nativeEnterDirectory(QString)));
+ QObject::connect(h, SIGNAL(fileSelected(QUrl)), d, SLOT(_q_nativeFileSelected(QUrl)));
+ QObject::connect(h, SIGNAL(filesSelected(QList<QUrl>)), d, SLOT(_q_nativeFilesSelected(QList<QUrl>)));
+ QObject::connect(h, SIGNAL(currentChanged(QUrl)), d, SLOT(_q_nativeCurrentChanged(QUrl)));
+ QObject::connect(h, SIGNAL(directoryEntered(QUrl)), d, SLOT(_q_nativeEnterDirectory(QUrl)));
QObject::connect(h, SIGNAL(filterSelected(QString)), d, SIGNAL(filterSelected(QString)));
static_cast<QPlatformFileDialogHelper *>(h)->setOptions(options);
}
@@ -550,8 +605,8 @@ void QFileDialogPrivate::helperPrepareShow(QPlatformDialogHelper *)
options->setSidebarUrls(qFileDialogUi->sidebar->urls());
const QDir directory = q->directory();
options->setInitialDirectory(directory.exists() ?
- directory.absolutePath() :
- QString());
+ QUrl::fromLocalFile(directory.absolutePath()) :
+ QUrl());
options->setInitiallySelectedNameFilter(q->selectedNameFilter());
options->setInitiallySelectedFiles(userSelectedFiles());
}
@@ -742,6 +797,15 @@ void QFileDialog::setOptions(Options options)
if (changed & ShowDirsOnly)
setFilter((options & ShowDirsOnly) ? filter() & ~QDir::Files : filter() | QDir::Files);
+
+ if (changed & DontUseCustomDirectoryIcons) {
+ QFileIconProvider::Options providerOptions = iconProvider()->options();
+ if (options & DontUseCustomDirectoryIcons)
+ providerOptions |= QFileIconProvider::DontUseCustomDirectoryIcons;
+ else
+ providerOptions &= ~QFileIconProvider::DontUseCustomDirectoryIcons;
+ iconProvider()->setOptions(providerOptions);
+ }
}
QFileDialog::Options QFileDialog::options() const
@@ -850,7 +914,7 @@ void QFileDialog::setDirectory(const QString &directory)
d->setLastVisitedDirectory(newDirectory);
if (d->nativeDialogInUse){
- d->setDirectory_sys(newDirectory);
+ d->setDirectory_sys(QUrl::fromLocalFile(newDirectory));
return;
}
if (d->rootPath() == newDirectory)
@@ -875,7 +939,42 @@ void QFileDialog::setDirectory(const QString &directory)
QDir QFileDialog::directory() const
{
Q_D(const QFileDialog);
- return QDir(d->nativeDialogInUse ? d->directory_sys() : d->rootPath());
+ return QDir(d->nativeDialogInUse ? d->directory_sys().toLocalFile() : d->rootPath());
+}
+
+/*!
+ Sets the file dialog's current \a directory url.
+
+ \note The non-native QFileDialog supports only local files.
+
+ \since 5.2
+*/
+void QFileDialog::setDirectoryUrl(const QUrl &directory)
+{
+ Q_D(QFileDialog);
+ if (!directory.isValid())
+ return;
+
+ if (d->nativeDialogInUse)
+ d->setDirectory_sys(directory);
+ else if (directory.isLocalFile())
+ setDirectory(directory.toLocalFile());
+ else
+ qWarning() << "Non-native QFileDialog supports only local files";
+}
+
+/*!
+ Returns the url of the directory currently being displayed in the dialog.
+
+ \since 5.2
+*/
+QUrl QFileDialog::directoryUrl() const
+{
+ Q_D(const QFileDialog);
+ if (d->nativeDialogInUse)
+ return d->directory_sys();
+ else
+ return QUrl::fromLocalFile(directory().absolutePath());
}
/*!
@@ -890,7 +989,7 @@ void QFileDialog::selectFile(const QString &filename)
return;
if (d->nativeDialogInUse){
- d->selectFile_sys(filename);
+ d->selectFile_sys(QUrl::fromLocalFile(filename));
return;
}
@@ -927,6 +1026,28 @@ void QFileDialog::selectFile(const QString &filename)
d->lineEdit()->setText(file);
}
+/*!
+ Selects the given \a url in the file dialog.
+
+ \note The non-native QFileDialog supports only local files.
+
+ \sa selectedUrls()
+ \since 5.2
+*/
+void QFileDialog::selectUrl(const QUrl &url)
+{
+ Q_D(QFileDialog);
+ if (!url.isValid())
+ return;
+
+ if (d->nativeDialogInUse)
+ d->selectFile_sys(url);
+ else if (url.isLocalFile())
+ selectFile(url.toLocalFile());
+ else
+ qWarning() << "Non-native QFileDialog supports only local files";
+}
+
#ifdef Q_OS_UNIX
Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0)
{
@@ -1015,17 +1136,19 @@ QStringList QFileDialogPrivate::typedFiles() const
// Return selected files without defaulting to the root of the file system model
// used for initializing QFileDialogOptions for native dialogs. The default is
// not suitable for native dialogs since it mostly equals directory().
-QStringList QFileDialogPrivate::userSelectedFiles() const
+QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
{
+ QList<QUrl> files;
+
if (nativeDialogInUse)
- return addDefaultSuffixToFiles(selectedFiles_sys());
+ return addDefaultSuffixToUrls(selectedFiles_sys());
- QStringList files;
foreach (const QModelIndex &index, qFileDialogUi->listView->selectionModel()->selectedRows())
- files.append(index.data(QFileSystemModel::FilePathRole).toString());
+ files.append(QUrl::fromLocalFile(index.data(QFileSystemModel::FilePathRole).toString()));
if (files.isEmpty() && !lineEdit()->text().isEmpty())
- files = typedFiles();
+ foreach (const QString &path, typedFiles())
+ files.append(QUrl::fromLocalFile(path));
return files;
}
@@ -1056,6 +1179,20 @@ QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList filesT
return files;
}
+QList<QUrl> QFileDialogPrivate::addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const
+{
+ QList<QUrl> urls;
+ for (int i=0; i<urlsToFix.size(); ++i) {
+ QUrl url = urlsToFix.at(i);
+ // if the filename has no suffix, add the default suffix
+ const QString defaultSuffix = options->defaultSuffix();
+ if (!defaultSuffix.isEmpty() && !url.path().endsWith(QLatin1Char('/')) && url.path().lastIndexOf(QLatin1Char('.')) == -1)
+ url.setPath(url.path() + QLatin1Char('.') + defaultSuffix);
+ urls.append(url);
+ }
+ return urls;
+}
+
/*!
Returns a list of strings containing the absolute paths of the
@@ -1068,7 +1205,9 @@ QStringList QFileDialog::selectedFiles() const
{
Q_D(const QFileDialog);
- QStringList files = d->userSelectedFiles();
+ QStringList files;
+ foreach (const QUrl &file, d->userSelectedFiles())
+ files.append(file.toLocalFile());
if (files.isEmpty()) {
const FileMode fm = fileMode();
if (fm != ExistingFile && fm != ExistingFiles)
@@ -1077,6 +1216,27 @@ QStringList QFileDialog::selectedFiles() const
return files;
}
+/*!
+ Returns a list of urls containing the selected files in the dialog.
+ If no files are selected, or the mode is not ExistingFiles or
+ ExistingFile, selectedUrls() contains the current path in the viewport.
+
+ \sa selectedNameFilter(), selectUrl()
+ \since 5.2
+*/
+QList<QUrl> QFileDialog::selectedUrls() const
+{
+ Q_D(const QFileDialog);
+ if (d->nativeDialogInUse) {
+ return d->userSelectedFiles();
+ } else {
+ QList<QUrl> urls;
+ foreach (const QString &file, selectedFiles())
+ urls.append(QUrl::fromLocalFile(file));
+ return urls;
+ }
+}
+
/*
Makes a list of filters from ;;-separated text.
Used by the mac and windows implementations
@@ -1526,6 +1686,8 @@ bool QFileDialog::confirmOverwrite() const
filename if it has no suffix already. The suffix is typically
used to indicate the file type (e.g. "txt" indicates a text
file).
+
+ If the first character is a dot ('.'), it is removed.
*/
void QFileDialog::setDefaultSuffix(const QString &suffix)
{
@@ -1798,6 +1960,48 @@ QString QFileDialog::getOpenFileName(QWidget *parent,
}
/*!
+ This is a convenience static function that returns an existing file
+ selected by the user. If the user presses Cancel, it returns an
+ empty url.
+
+ The function is used similarly to QFileDialog::getOpenFileName(). In
+ particular \a parent, \a caption, \a dir, \a filter, \a selectedFilter
+ and \a options are used in the exact same way.
+
+ The main difference with QFileDialog::getOpenFileName() comes from
+ the ability offered to the user to select a remote file. That's why
+ the return type and the type of \a dir is QUrl.
+
+ The \a supportedSchemes argument allows to restrict the type of URLs the
+ user will be able to select. It is a way for the application to declare
+ the protocols it will support to fetch the file content. An empty list
+ means that no restriction is applied (the default).
+ Supported for local files ("file" scheme) is implicit and always enabled.
+ it is not necessary to include in the restriction.
+
+ When possible, this static function will use the native file dialog and
+ not a QFileDialog. On platforms which don't support selecting remote
+ files, Qt will allow to select only local files.
+
+ \sa getOpenFileName(), getOpenFileUrls(), getSaveFileUrl(), getExistingDirectoryUrl()
+ \since 5.2
+*/
+QUrl QFileDialog::getOpenFileUrl(QWidget *parent,
+ const QString &caption,
+ const QUrl &dir,
+ const QString &filter,
+ QString *selectedFilter,
+ Options options,
+ const QStringList &supportedSchemes)
+{
+ if (qt_filedialog_open_file_url_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_open_file_url_hook(parent, caption, dir, filter, selectedFilter, options, supportedSchemes);
+
+ // Falls back to local file
+ return QUrl::fromLocalFile(getOpenFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
+}
+
+/*!
This is a convenience static function that will return one or more existing
files selected by the user.
@@ -1883,6 +2087,55 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent,
}
/*!
+ This is a convenience static function that will return or or more existing
+ files selected by the user. If the user presses Cancel, it returns an
+ empty list.
+
+ The function is used similarly to QFileDialog::getOpenFileNames(). In
+ particular \a parent, \a caption, \a dir, \a filter, \a selectedFilter
+ and \a options are used in the exact same way.
+
+ The main difference with QFileDialog::getOpenFileNames() comes from
+ the ability offered to the user to select remote files. That's why
+ the return type and the type of \a dir are respectively QList<QUrl>
+ and QUrl.
+
+ The \a supportedSchemes argument allows to restrict the type of URLs the
+ user will be able to select. It is a way for the application to declare
+ the protocols it will support to fetch the file content. An empty list
+ means that no restriction is applied (the default).
+ Supported for local files ("file" scheme) is implicit and always enabled.
+ it is not necessary to include in the restriction.
+
+ When possible, this static function will use the native file dialog and
+ not a QFileDialog. On platforms which don't support selecting remote
+ files, Qt will allow to select only local files.
+
+ \sa getOpenFileNames(), getOpenFileUrl(), getSaveFileUrl(), getExistingDirectoryUrl()
+ \since 5.2
+*/
+QList<QUrl> QFileDialog::getOpenFileUrls(QWidget *parent,
+ const QString &caption,
+ const QUrl &dir,
+ const QString &filter,
+ QString *selectedFilter,
+ Options options,
+ const QStringList &supportedSchemes)
+{
+ if (qt_filedialog_open_file_urls_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_open_file_urls_hook(parent, caption, dir, filter, selectedFilter, options, supportedSchemes);
+
+ // Falls back to local files
+ QList<QUrl> urls;
+
+ const QStringList fileNames = getOpenFileNames(parent, caption, dir.toLocalFile(), filter, selectedFilter, options);
+ foreach (const QString &fileName, fileNames)
+ urls << QUrl::fromLocalFile(fileName);
+
+ return urls;
+}
+
+/*!
This is a convenience static function that will return a file name selected
by the user. The file does not have to exist.
@@ -1971,6 +2224,48 @@ QString QFileDialog::getSaveFileName(QWidget *parent,
}
/*!
+ This is a convenience static function that returns a file selected by
+ the user. The file does not have to exist. If the user presses Cancel,
+ it returns an empty url.
+
+ The function is used similarly to QFileDialog::getSaveFileName(). In
+ particular \a parent, \a caption, \a dir, \a filter, \a selectedFilter
+ and \a options are used in the exact same way.
+
+ The main difference with QFileDialog::getSaveFileName() comes from
+ the ability offered to the user to select a remote file. That's why
+ the return type and the type of \a dir is QUrl.
+
+ The \a supportedSchemes argument allows to restrict the type of URLs the
+ user will be able to select. It is a way for the application to declare
+ the protocols it will support to save the file content. An empty list
+ means that no restriction is applied (the default).
+ Supported for local files ("file" scheme) is implicit and always enabled.
+ it is not necessary to include in the restriction.
+
+ When possible, this static function will use the native file dialog and
+ not a QFileDialog. On platforms which don't support selecting remote
+ files, Qt will allow to select only local files.
+
+ \sa getSaveFileName(), getOpenFileUrl(), getOpenFileUrls(), getExistingDirectoryUrl()
+ \since 5.2
+*/
+QUrl QFileDialog::getSaveFileUrl(QWidget *parent,
+ const QString &caption,
+ const QUrl &dir,
+ const QString &filter,
+ QString *selectedFilter,
+ Options options,
+ const QStringList &supportedSchemes)
+{
+ if (qt_filedialog_save_file_url_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_save_file_url_hook(parent, caption, dir, filter, selectedFilter, options, supportedSchemes);
+
+ // Falls back to local file
+ return QUrl::fromLocalFile(getSaveFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
+}
+
+/*!
This is a convenience static function that will return an existing
directory selected by the user.
@@ -2041,6 +2336,46 @@ QString QFileDialog::getExistingDirectory(QWidget *parent,
return QString();
}
+/*!
+ This is a convenience static function that will return an existing
+ directory selected by the user. If the user presses Cancel, it
+ returns an empty url.
+
+ The function is used similarly to QFileDialog::getExistingDirectory().
+ In particular \a parent, \a caption, \a dir and \a options are used
+ in the exact same way.
+
+ The main difference with QFileDialog::getExistingDirectory() comes from
+ the ability offered to the user to select a remote directory. That's why
+ the return type and the type of \a dir is QUrl.
+
+ The \a supportedSchemes argument allows to restrict the type of URLs the
+ user will be able to select. It is a way for the application to declare
+ the protocols it will support to fetch the file content. An empty list
+ means that no restriction is applied (the default).
+ Supported for local files ("file" scheme) is implicit and always enabled.
+ it is not necessary to include in the restriction.
+
+ When possible, this static function will use the native file dialog and
+ not a QFileDialog. On platforms which don't support selecting remote
+ files, Qt will allow to select only local files.
+
+ \sa getExistingDirectory(), getOpenFileUrl(), getOpenFileUrls(), getSaveFileUrl()
+ \since 5.2
+*/
+QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent,
+ const QString &caption,
+ const QUrl &dir,
+ Options options,
+ const QStringList &supportedSchemes)
+{
+ if (qt_filedialog_existing_directory_url_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_existing_directory_url_hook(parent, caption, dir, options, supportedSchemes);
+
+ // Falls back to local file
+ return QUrl::fromLocalFile(getExistingDirectory(parent, caption, dir.toLocalFile(), options));
+}
+
inline static QString _qt_get_directory(const QString &path)
{
QFileInfo info = QFileInfo(QDir::current(), path);
@@ -3119,10 +3454,42 @@ void QFileDialogPrivate::_q_fileRenamed(const QString &path, const QString oldNa
}
}
-void QFileDialogPrivate::_q_nativeEnterDirectory(const QString &directory)
+void QFileDialogPrivate::_q_nativeFileSelected(const QUrl &file)
+{
+ Q_Q(QFileDialog);
+ emit q->urlSelected(file);
+ if (file.isLocalFile())
+ emit q->fileSelected(file.toLocalFile());
+}
+
+void QFileDialogPrivate::_q_nativeFilesSelected(const QList<QUrl> &files)
+{
+ Q_Q(QFileDialog);
+ emit q->urlsSelected(files);
+ QStringList localFiles;
+ foreach (const QUrl &file, files)
+ if (file.isLocalFile())
+ localFiles.append(file.toLocalFile());
+ if (!localFiles.isEmpty())
+ emit q->filesSelected(localFiles);
+}
+
+void QFileDialogPrivate::_q_nativeCurrentChanged(const QUrl &file)
{
- if (!directory.isEmpty()) // Windows native dialogs occasionally emit signals with empty strings.
- *lastVisitedDir() = directory;
+ Q_Q(QFileDialog);
+ emit q->currentUrlChanged(file);
+ if (file.isLocalFile())
+ emit q->currentChanged(file.toLocalFile());
+}
+
+void QFileDialogPrivate::_q_nativeEnterDirectory(const QUrl &directory)
+{
+ Q_Q(QFileDialog);
+ emit q->directoryUrlEntered(directory);
+ if (!directory.isEmpty() && directory.isLocalFile()) { // Windows native dialogs occasionally emit signals with empty strings.
+ *lastVisitedDir() = directory.toLocalFile();
+ emit q->directoryEntered(directory.toLocalFile());
+ }
}
/*!
diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h
index 98d1fd5695..5413a42ea9 100644
--- a/src/widgets/dialogs/qfiledialog.h
+++ b/src/widgets/dialogs/qfiledialog.h
@@ -44,6 +44,7 @@
#include <QtCore/qdir.h>
#include <QtCore/qstring.h>
+#include <QtCore/qurl.h>
#include <QtWidgets/qdialog.h>
QT_BEGIN_NAMESPACE
@@ -58,7 +59,6 @@ class QFileIconProvider;
class QFileDialogPrivate;
class QAbstractItemDelegate;
class QAbstractProxyModel;
-class QUrl;
class Q_WIDGETS_EXPORT QFileDialog : public QDialog
{
@@ -84,13 +84,14 @@ public:
enum Option
{
- ShowDirsOnly = 0x00000001,
- DontResolveSymlinks = 0x00000002,
- DontConfirmOverwrite = 0x00000004,
- DontUseSheet = 0x00000008,
- DontUseNativeDialog = 0x00000010,
- ReadOnly = 0x00000020,
- HideNameFilterDetails = 0x00000040
+ ShowDirsOnly = 0x00000001,
+ DontResolveSymlinks = 0x00000002,
+ DontConfirmOverwrite = 0x00000004,
+ DontUseSheet = 0x00000008,
+ DontUseNativeDialog = 0x00000010,
+ ReadOnly = 0x00000020,
+ HideNameFilterDetails = 0x00000040,
+ DontUseCustomDirectoryIcons = 0x00000080
};
Q_DECLARE_FLAGS(Options, Option)
@@ -105,9 +106,15 @@ public:
inline void setDirectory(const QDir &directory);
QDir directory() const;
+ void setDirectoryUrl(const QUrl &directory);
+ QUrl directoryUrl() const;
+
void selectFile(const QString &filename);
QStringList selectedFiles() const;
+ void selectUrl(const QUrl &url);
+ QList<QUrl> selectedUrls() const;
+
void setNameFilterDetailsVisible(bool enabled);
bool isNameFilterDetailsVisible() const;
@@ -184,6 +191,12 @@ Q_SIGNALS:
void filesSelected(const QStringList &files);
void currentChanged(const QString &path);
void directoryEntered(const QString &directory);
+
+ void urlSelected(const QUrl &url);
+ void urlsSelected(const QList<QUrl> &urls);
+ void currentUrlChanged(const QUrl &url);
+ void directoryUrlEntered(const QUrl &directory);
+
void filterSelected(const QString &filter);
public:
@@ -195,6 +208,14 @@ public:
QString *selectedFilter = 0,
Options options = 0);
+ static QUrl getOpenFileUrl(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QUrl &dir = QUrl(),
+ const QString &filter = QString(),
+ QString *selectedFilter = 0,
+ Options options = 0,
+ const QStringList &supportedSchemes = QStringList());
+
static QString getSaveFileName(QWidget *parent = 0,
const QString &caption = QString(),
const QString &dir = QString(),
@@ -202,11 +223,25 @@ public:
QString *selectedFilter = 0,
Options options = 0);
+ static QUrl getSaveFileUrl(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QUrl &dir = QUrl(),
+ const QString &filter = QString(),
+ QString *selectedFilter = 0,
+ Options options = 0,
+ const QStringList &supportedSchemes = QStringList());
+
static QString getExistingDirectory(QWidget *parent = 0,
const QString &caption = QString(),
const QString &dir = QString(),
Options options = ShowDirsOnly);
+ static QUrl getExistingDirectoryUrl(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QUrl &dir = QUrl(),
+ Options options = ShowDirsOnly,
+ const QStringList &supportedSchemes = QStringList());
+
static QStringList getOpenFileNames(QWidget *parent = 0,
const QString &caption = QString(),
const QString &dir = QString(),
@@ -214,6 +249,14 @@ public:
QString *selectedFilter = 0,
Options options = 0);
+ static QList<QUrl> getOpenFileUrls(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QUrl &dir = QUrl(),
+ const QString &filter = QString(),
+ QString *selectedFilter = 0,
+ Options options = 0,
+ const QStringList &supportedSchemes = QStringList());
+
protected:
QFileDialog(const QFileDialogArgs &args);
@@ -240,7 +283,10 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_updateOkButton())
Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex &index))
Q_PRIVATE_SLOT(d_func(), void _q_enterDirectory(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_nativeEnterDirectory(const QString&))
+ Q_PRIVATE_SLOT(d_func(), void _q_nativeFileSelected(const QUrl &))
+ Q_PRIVATE_SLOT(d_func(), void _q_nativeFilesSelected(const QList<QUrl> &))
+ Q_PRIVATE_SLOT(d_func(), void _q_nativeCurrentChanged(const QUrl &))
+ Q_PRIVATE_SLOT(d_func(), void _q_nativeEnterDirectory(const QUrl&))
Q_PRIVATE_SLOT(d_func(), void _q_goToDirectory(const QString &path))
Q_PRIVATE_SLOT(d_func(), void _q_useNameFilter(int index))
Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index f8f33eb18d..e5a558bb91 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -130,8 +130,9 @@ public:
static QString workingDirectory(const QString &path);
static QString initialSelection(const QString &path);
QStringList typedFiles() const;
- QStringList userSelectedFiles() const;
+ QList<QUrl> userSelectedFiles() const;
QStringList addDefaultSuffixToFiles(const QStringList filesToFix) const;
+ QList<QUrl> addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const;
bool removeDirectory(const QString &path);
void setLabelTextControl(QFileDialog::DialogLabel label, const QString &text);
inline void updateFileNameLabel();
@@ -206,7 +207,10 @@ public:
void _q_updateOkButton();
void _q_currentChanged(const QModelIndex &index);
void _q_enterDirectory(const QModelIndex &index);
- void _q_nativeEnterDirectory(const QString &directory);
+ void _q_nativeFileSelected(const QUrl &file);
+ void _q_nativeFilesSelected(const QList<QUrl> &files);
+ void _q_nativeCurrentChanged(const QUrl &file);
+ void _q_nativeEnterDirectory(const QUrl &directory);
void _q_goToDirectory(const QString &);
void _q_useNameFilter(int index);
void _q_selectionChanged();
@@ -246,10 +250,10 @@ public:
// used instead.
bool canBeNativeDialog();
- void setDirectory_sys(const QString &directory);
- QString directory_sys() const;
- void selectFile_sys(const QString &filename);
- QStringList selectedFiles_sys() const;
+ void setDirectory_sys(const QUrl &directory);
+ QUrl directory_sys() const;
+ void selectFile_sys(const QUrl &filename);
+ QList<QUrl> selectedFiles_sys() const;
void setFilter_sys();
void selectNameFilter_sys(const QString &filter);
QString selectedNameFilter_sys() const;
@@ -346,30 +350,40 @@ inline QString QFileDialogPrivate::rootPath() const {
return model->rootPath();
}
-inline void QFileDialogPrivate::setDirectory_sys(const QString &directory)
+inline void QFileDialogPrivate::setDirectory_sys(const QUrl &directory)
{
- if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
+ QPlatformFileDialogHelper *helper = platformFileDialogHelper();
+
+ if (!helper)
+ return;
+
+ if (helper->isSupportedUrl(directory))
helper->setDirectory(directory);
}
-inline QString QFileDialogPrivate::directory_sys() const
+inline QUrl QFileDialogPrivate::directory_sys() const
{
if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
return helper->directory();
return QString();
}
-inline void QFileDialogPrivate::selectFile_sys(const QString &filename)
+inline void QFileDialogPrivate::selectFile_sys(const QUrl &filename)
{
- if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
+ QPlatformFileDialogHelper *helper = platformFileDialogHelper();
+
+ if (!helper)
+ return;
+
+ if (helper->isSupportedUrl(filename))
helper->selectFile(filename);
}
-inline QStringList QFileDialogPrivate::selectedFiles_sys() const
+inline QList<QUrl> QFileDialogPrivate::selectedFiles_sys() const
{
if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
return helper->selectedFiles();
- return QStringList();
+ return QList<QUrl>();
}
inline void QFileDialogPrivate::setFilter_sys()
diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp
index 213aefe5f5..0f12c2b80e 100644
--- a/src/widgets/dialogs/qfileinfogatherer.cpp
+++ b/src/widgets/dialogs/qfileinfogatherer.cpp
@@ -238,7 +238,7 @@ QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const
#endif
#ifdef Q_OS_WIN
- if (m_resolveSymlinks && fileInfo.isSymLink()) {
+ if (m_resolveSymlinks && info.isSymLink(/* ignoreNtfsSymLinks = */ true)) {
QFileInfo resolvedInfo(fileInfo.symLinkTarget());
resolvedInfo = resolvedInfo.canonicalFilePath();
if (resolvedInfo.exists()) {
diff --git a/src/widgets/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h
index 0c4e644e40..447ee78edc 100644
--- a/src/widgets/dialogs/qfileinfogatherer_p.h
+++ b/src/widgets/dialogs/qfileinfogatherer_p.h
@@ -108,7 +108,13 @@ public:
return QExtendedInformation::System;
}
- bool isSymLink() const {
+ bool isSymLink(bool ignoreNtfsSymLinks = false) const
+ {
+ if (ignoreNtfsSymLinks) {
+#ifdef Q_OS_WIN
+ return !mFileInfo.suffix().compare(QLatin1String("lnk"), Qt::CaseInsensitive);
+#endif
+ }
return mFileInfo.isSymLink();
}
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index 8e3ecc3e0e..519c158f81 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -800,7 +800,7 @@ QString QFileSystemModelPrivate::name(const QModelIndex &index) const
if (!index.isValid())
return QString();
QFileSystemNode *dirNode = node(index);
- if (fileInfoGatherer.resolveSymlinks() && !resolvedSymLinks.isEmpty() && dirNode->isSymLink()) {
+ if (fileInfoGatherer.resolveSymlinks() && !resolvedSymLinks.isEmpty() && dirNode->isSymLink(/* ignoreNtfsSymLinks = */ true)) {
QString fullPath = QDir::fromNativeSeparators(filePath(index));
if (resolvedSymLinks.contains(fullPath))
return resolvedSymLinks[fullPath];
diff --git a/src/widgets/dialogs/qfilesystemmodel_p.h b/src/widgets/dialogs/qfilesystemmodel_p.h
index d61936d545..663be3d933 100644
--- a/src/widgets/dialogs/qfilesystemmodel_p.h
+++ b/src/widgets/dialogs/qfilesystemmodel_p.h
@@ -116,7 +116,7 @@ public:
inline bool isFile() const { if (info) return info->isFile(); return true; }
inline bool isSystem() const { if (info) return info->isSystem(); return true; }
inline bool isHidden() const { if (info) return info->isHidden(); return false; }
- inline bool isSymLink() const { if (info) return info->isSymLink(); return false; }
+ inline bool isSymLink(bool ignoreNtfsSymLinks = false) const { return info && info->isSymLink(ignoreNtfsSymLinks); }
inline bool caseSensitive() const { if (info) return info->isCaseSensitive(); return false; }
inline QIcon icon() const { if (info) return info->icon; return QIcon(); }
diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp
index 313b475f1f..b989ea7c86 100644
--- a/src/widgets/dialogs/qfontdialog.cpp
+++ b/src/widgets/dialogs/qfontdialog.cpp
@@ -479,7 +479,22 @@ void QFontDialogPrivate::updateFamilies()
enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 };
- QStringList familyNames = fdb.families(writingSystem);
+ const QFontDialog::FontDialogOptions scalableMask = (QFontDialog::ScalableFonts | QFontDialog::NonScalableFonts);
+ const QFontDialog::FontDialogOptions spacingMask = (QFontDialog::ProportionalFonts | QFontDialog::MonospacedFonts);
+ const QFontDialog::FontDialogOptions options = q->options();
+
+ QStringList familyNames;
+ foreach (const QString &family, fdb.families(writingSystem)) {
+ if ((options & scalableMask) && (options & scalableMask) != scalableMask) {
+ if (bool(options & QFontDialog::ScalableFonts) != fdb.isSmoothlyScalable(family))
+ continue;
+ }
+ if ((options & spacingMask) && (options & spacingMask) != spacingMask) {
+ if (bool(options & QFontDialog::MonospacedFonts) != fdb.isFixedPitch(family))
+ continue;
+ }
+ familyNames << family;
+ }
familyList->model()->setStringList(familyNames);
@@ -837,10 +852,21 @@ QFont QFontDialog::selectedFont() const
This enum specifies various options that affect the look and feel
of a font dialog.
+ For instance, it allows to specify which type of font should be
+ displayed. If none are specified all fonts available will be listed.
+
+ Note that the font filtering options might not be supported on some
+ platforms (e.g. Mac). They are always supported by the non native
+ dialog (used on Windows or Linux).
+
\value NoButtons Don't display \uicontrol{OK} and \uicontrol{Cancel} buttons. (Useful for "live dialogs".)
\value DontUseNativeDialog Use Qt's standard font dialog on the Mac instead of Apple's
native font panel. (Currently, the native dialog is never used,
but this is likely to change in future Qt releases.)
+ \value ScalableFonts Show scalable fonts
+ \value NonScalableFonts Show non scalable fonts
+ \value MonospacedFonts Show monospaced fonts
+ \value ProportionalFonts Show proportional fonts
\sa options, setOption(), testOption()
*/
diff --git a/src/widgets/dialogs/qfontdialog.h b/src/widgets/dialogs/qfontdialog.h
index c2d930bc1e..9956987cfe 100644
--- a/src/widgets/dialogs/qfontdialog.h
+++ b/src/widgets/dialogs/qfontdialog.h
@@ -64,7 +64,11 @@ class Q_WIDGETS_EXPORT QFontDialog : public QDialog
public:
enum FontDialogOption {
NoButtons = 0x00000001,
- DontUseNativeDialog = 0x00000002
+ DontUseNativeDialog = 0x00000002,
+ ScalableFonts = 0x00000004,
+ NonScalableFonts = 0x00000008,
+ MonospacedFonts = 0x00000010,
+ ProportionalFonts = 0x00000020
};
Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption)
diff --git a/src/widgets/dialogs/qinputdialog.cpp b/src/widgets/dialogs/qinputdialog.cpp
index 45aa49d552..c1f8deb4eb 100644
--- a/src/widgets/dialogs/qinputdialog.cpp
+++ b/src/widgets/dialogs/qinputdialog.cpp
@@ -49,6 +49,7 @@
#include "qlabel.h"
#include "qlayout.h"
#include "qlineedit.h"
+#include "qplaintextedit.h"
#include "qlistwidget.h"
#include "qpushbutton.h"
#include "qspinbox.h"
@@ -167,6 +168,7 @@ public:
void ensureLayout();
void ensureLineEdit();
+ void ensurePlainTextEdit();
void ensureComboBox();
void ensureListView();
void ensureIntSpinBox();
@@ -180,11 +182,13 @@ public:
void ensureLayout() const { const_cast<QInputDialogPrivate *>(this)->ensureLayout(); }
bool useComboBoxOrListView() const { return comboBox && comboBox->count() > 0; }
void _q_textChanged(const QString &text);
+ void _q_plainTextEditTextChanged();
void _q_currentRowChanged(const QModelIndex &newIndex, const QModelIndex &oldIndex);
mutable QLabel *label;
mutable QDialogButtonBox *buttonBox;
mutable QLineEdit *lineEdit;
+ mutable QPlainTextEdit *plainTextEdit;
mutable QSpinBox *intSpinBox;
mutable QDoubleSpinBox *doubleSpinBox;
mutable QComboBox *comboBox;
@@ -198,8 +202,8 @@ public:
};
QInputDialogPrivate::QInputDialogPrivate()
- : label(0), buttonBox(0), lineEdit(0), intSpinBox(0), doubleSpinBox(0), comboBox(0), listView(0),
- inputWidget(0), mainLayout(0)
+ : label(0), buttonBox(0), lineEdit(0), plainTextEdit(0), intSpinBox(0), doubleSpinBox(0),
+ comboBox(0), listView(0), inputWidget(0), mainLayout(0)
{
}
@@ -250,6 +254,21 @@ void QInputDialogPrivate::ensureLineEdit()
}
}
+void QInputDialogPrivate::ensurePlainTextEdit()
+{
+ Q_Q(QInputDialog);
+ if (!plainTextEdit) {
+ plainTextEdit = new QPlainTextEdit(q);
+ plainTextEdit->setLineWrapMode(QPlainTextEdit::NoWrap);
+#ifndef QT_NO_IM
+ qt_widget_private(plainTextEdit)->inheritsInputMethodHints = 1;
+#endif
+ plainTextEdit->hide();
+ QObject::connect(plainTextEdit, SIGNAL(textChanged()),
+ q, SLOT(_q_plainTextEditTextChanged()));
+ }
+}
+
void QInputDialogPrivate::ensureComboBox()
{
Q_Q(QInputDialog);
@@ -344,6 +363,8 @@ void QInputDialogPrivate::setInputWidget(QWidget *widget)
// textValue
if (widget == lineEdit) {
lineEdit->setText(textValue);
+ } else if (widget == plainTextEdit) {
+ plainTextEdit->setPlainText(textValue);
} else if (widget == comboBox) {
setComboBoxText(textValue);
} else if (widget == listView) {
@@ -364,6 +385,9 @@ void QInputDialogPrivate::chooseRightTextInputWidget()
} else {
widget = comboBox;
}
+ } else if (opts & QInputDialog::UsePlainTextEditForTextInput) {
+ ensurePlainTextEdit();
+ widget = plainTextEdit;
} else {
ensureLineEdit();
widget = lineEdit;
@@ -417,6 +441,16 @@ void QInputDialogPrivate::_q_textChanged(const QString &text)
}
}
+void QInputDialogPrivate::_q_plainTextEditTextChanged()
+{
+ Q_Q(QInputDialog);
+ QString text = plainTextEdit->toPlainText();
+ if (textValue != text) {
+ textValue = text;
+ emit q->textValueChanged(text);
+ }
+}
+
void QInputDialogPrivate::_q_currentRowChanged(const QModelIndex &newIndex,
const QModelIndex & /* oldIndex */)
{
@@ -434,8 +468,8 @@ void QInputDialogPrivate::_q_currentRowChanged(const QModelIndex &newIndex,
The input value can be a string, a number or an item from a list. A label
must be set to tell the user what they should enter.
- Four static convenience functions are provided: getText(), getInt(),
- getDouble(), and getItem(). All the functions can be used in a similar way,
+ Five static convenience functions are provided: getText(), getMultiLineText(),
+ getInt(), getDouble(), and getItem(). All the functions can be used in a similar way,
for example:
\snippet dialogs/standarddialogs/dialog.cpp 3
@@ -575,6 +609,8 @@ QString QInputDialog::labelText() const
\value NoButtons Don't display \uicontrol{OK} and \uicontrol{Cancel} buttons (useful for "live dialogs").
\value UseListViewForComboBoxItems Use a QListView rather than a non-editable QComboBox for
displaying the items set with setComboBoxItems().
+ \value UsePlainTextEditForTextInput Use a QPlainTextEdit for multiline text input. This value was
+ introduced in 5.2.
\sa options, setOption(), testOption()
*/
@@ -628,6 +664,8 @@ void QInputDialog::setOptions(InputDialogOptions options)
d->buttonBox->setVisible(!(options & NoButtons));
if ((changed & UseListViewForComboBoxItems) && inputMode() == TextInput)
d->chooseRightTextInputWidget();
+ if ((changed & UsePlainTextEditForTextInput) && inputMode() == TextInput)
+ d->chooseRightTextInputWidget();
}
QInputDialog::InputDialogOptions QInputDialog::options() const
@@ -653,6 +691,8 @@ void QInputDialog::setTextValue(const QString &text)
setInputMode(TextInput);
if (d->inputWidget == d->lineEdit) {
d->lineEdit->setText(text);
+ } else if (d->inputWidget == d->plainTextEdit) {
+ d->plainTextEdit->setPlainText(text);
} else if (d->inputWidget == d->comboBox) {
d->setComboBoxText(text);
} else {
@@ -1075,6 +1115,8 @@ void QInputDialog::setVisible(bool visible)
d->inputWidget->setFocus();
if (d->inputWidget == d->lineEdit) {
d->lineEdit->selectAll();
+ } else if (d->inputWidget == d->plainTextEdit) {
+ d->plainTextEdit->selectAll();
} else if (d->inputWidget == d->intSpinBox) {
d->intSpinBox->selectAll();
} else if (d->inputWidget == d->doubleSpinBox) {
@@ -1144,7 +1186,7 @@ void QInputDialog::done(int result)
want to do this, you should create the dialog yourself using one of the
QInputDialog constructors.
- \sa getInt(), getDouble(), getItem()
+ \sa getInt(), getDouble(), getItem(), getMultiLineText()
*/
QString QInputDialog::getText(QWidget *parent, const QString &title, const QString &label,
@@ -1169,6 +1211,58 @@ QString QInputDialog::getText(QWidget *parent, const QString &title, const QStri
}
/*!
+ \since 5.2
+
+ Static convenience function to get a multiline string from the user.
+
+ \a title is the text which is displayed in the title bar of the dialog.
+ \a label is the text which is shown to the user (it should say what should
+ be entered).
+ \a text is the default text which is placed in the plain text edit.
+ \a inputMethodHints is the input method hints that will be used in the
+ edit widget if an input method is active.
+
+ If \a ok is nonnull \e *\a ok will be set to true if the user pressed
+ \uicontrol OK and to false if the user pressed \uicontrol Cancel. The dialog's parent
+ is \a parent. The dialog will be modal and uses the specified widget
+ \a flags.
+
+ If the dialog is accepted, this function returns the text in the dialog's
+ plain text edit. If the dialog is rejected, a null QString is returned.
+
+ Use this static function like this:
+
+ \snippet dialogs/standarddialogs/dialog.cpp 4
+
+ \warning Do not delete \a parent during the execution of the dialog. If you
+ want to do this, you should create the dialog yourself using one of the
+ QInputDialog constructors.
+
+ \sa getInt(), getDouble(), getItem(), getText()
+*/
+
+QString QInputDialog::getMultiLineText(QWidget *parent, const QString &title, const QString &label,
+ const QString &text, bool *ok, Qt::WindowFlags flags,
+ Qt::InputMethodHints inputMethodHints)
+{
+ QInputDialog dialog(parent, flags);
+ dialog.setOptions(QInputDialog::UsePlainTextEditForTextInput);
+ dialog.setWindowTitle(title);
+ dialog.setLabelText(label);
+ dialog.setTextValue(text);
+ dialog.setInputMethodHints(inputMethodHints);
+
+ int ret = dialog.exec();
+ if (ok)
+ *ok = !!ret;
+ if (ret) {
+ return dialog.textValue();
+ } else {
+ return QString();
+ }
+}
+
+/*!
\since 4.5
Static convenience function to get an integer input from the user.
@@ -1196,7 +1290,7 @@ QString QInputDialog::getText(QWidget *parent, const QString &title, const QStri
want to do this, you should create the dialog yourself using one of the
QInputDialog constructors.
- \sa getText(), getDouble(), getItem()
+ \sa getText(), getDouble(), getItem(), getMultiLineText()
*/
int QInputDialog::getInt(QWidget *parent, const QString &title, const QString &label, int value,
@@ -1248,7 +1342,7 @@ int QInputDialog::getInt(QWidget *parent, const QString &title, const QString &l
want to do this, you should create the dialog yourself using one of the
QInputDialog constructors.
- \sa getText(), getDouble(), getItem()
+ \sa getText(), getDouble(), getItem(), getMultiLineText()
*/
/*!
@@ -1277,7 +1371,7 @@ int QInputDialog::getInt(QWidget *parent, const QString &title, const QString &l
want to do this, you should create the dialog yourself using one of the
QInputDialog constructors.
- \sa getText(), getInt(), getItem()
+ \sa getText(), getInt(), getItem(), getMultiLineText()
*/
double QInputDialog::getDouble(QWidget *parent, const QString &title, const QString &label,
@@ -1331,7 +1425,7 @@ double QInputDialog::getDouble(QWidget *parent, const QString &title, const QStr
want to do this, you should create the dialog yourself using one of the
QInputDialog constructors.
- \sa getText(), getInt(), getDouble()
+ \sa getText(), getInt(), getDouble(), getMultiLineText()
*/
QString QInputDialog::getItem(QWidget *parent, const QString &title, const QString &label,
diff --git a/src/widgets/dialogs/qinputdialog.h b/src/widgets/dialogs/qinputdialog.h
index 41dca1f94f..c2c85835c8 100644
--- a/src/widgets/dialogs/qinputdialog.h
+++ b/src/widgets/dialogs/qinputdialog.h
@@ -78,8 +78,9 @@ class Q_WIDGETS_EXPORT QInputDialog : public QDialog
public:
enum InputDialogOption {
- NoButtons = 0x00000001,
- UseListViewForComboBoxItems = 0x00000002
+ NoButtons = 0x00000001,
+ UseListViewForComboBoxItems = 0x00000002,
+ UsePlainTextEditForTextInput = 0x00000004
};
Q_DECLARE_FLAGS(InputDialogOptions, InputDialogOption)
@@ -168,6 +169,9 @@ public:
QLineEdit::EchoMode echo = QLineEdit::Normal,
const QString &text = QString(), bool *ok = 0, Qt::WindowFlags flags = 0,
Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
+ static QString getMultiLineText(QWidget *parent, const QString &title, const QString &label,
+ const QString &text = QString(), bool *ok = 0, Qt::WindowFlags flags = 0,
+ Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
static QString getItem(QWidget *parent, const QString &title, const QString &label,
const QStringList &items, int current = 0, bool editable = true,
bool *ok = 0, Qt::WindowFlags flags = 0,
@@ -204,6 +208,7 @@ public:
private:
Q_DISABLE_COPY(QInputDialog)
Q_PRIVATE_SLOT(d_func(), void _q_textChanged(const QString&))
+ Q_PRIVATE_SLOT(d_func(), void _q_plainTextEditTextChanged())
Q_PRIVATE_SLOT(d_func(), void _q_currentRowChanged(const QModelIndex&, const QModelIndex&))
};
diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf
index a989ef9363..d3c7825bc0 100644
--- a/src/widgets/doc/qtwidgets.qdocconf
+++ b/src/widgets/doc/qtwidgets.qdocconf
@@ -54,3 +54,6 @@ imagedirs += images \
../../../doc/src/images \
../../../examples/widgets/doc/images \
../../../examples/widgets
+
+navigation.landingpage = "Qt Widgets"
+navigation.cppclassespage = "Qt Widgets C++ Classes"
diff --git a/src/widgets/doc/src/qtwidgets.qdoc b/src/widgets/doc/src/qtwidgets.qdoc
index 2e3403e9d9..e6145ea17e 100644
--- a/src/widgets/doc/src/qtwidgets.qdoc
+++ b/src/widgets/doc/src/qtwidgets.qdoc
@@ -29,6 +29,7 @@
\module QtWidgets
\title Qt Widgets C++ Classes
\ingroup modules
+ \qtvariable widgets
\brief The Qt Widgets module extends Qt GUI with C++ widget functionality.
diff --git a/src/widgets/graphicsview/qgridlayoutengine.cpp b/src/widgets/graphicsview/qgridlayoutengine.cpp
index 4f43a0a4ac..f741962264 100644
--- a/src/widgets/graphicsview/qgridlayoutengine.cpp
+++ b/src/widgets/graphicsview/qgridlayoutengine.cpp
@@ -432,6 +432,8 @@ QGridLayoutBox QGridLayoutRowData::totalBox(int start, int end) const
result.q_maximumSize = 0.0;
qreal nextSpacing = 0.0;
for (int i = start; i < end; ++i) {
+ if (ignore.testBit(i))
+ continue;
result.add(boxes.at(i), stretches.at(i), nextSpacing);
nextSpacing = spacings.at(i);
}
@@ -1475,7 +1477,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt
int effectiveRowSpan = 1;
for (int i = 1; i < itemRowSpan; ++i) {
- if (!rowData->ignore.testBit(i))
+ if (!rowData->ignore.testBit(i + itemRow))
++effectiveRowSpan;
}
@@ -1713,7 +1715,8 @@ void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo,
q_descents.resize(rowCount());
if (constraintOrientation() != Qt::Horizontal) {
- //We might have items whose width depends on their height
+ // We might have items whose height depends on their width,
+ // or none of the items has a dynamic constraint.
ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal);
//Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as
//constraints to find the row heights
@@ -1724,7 +1727,7 @@ void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo,
q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(),
q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]);
} else {
- //We have items whose height depends on their width
+ // We have items whose width depends on their height
ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical);
//Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as
//constraints to find the column widths
diff --git a/src/widgets/itemviews/itemviews.pri b/src/widgets/itemviews/itemviews.pri
index 0bc0309271..4e152d18bb 100644
--- a/src/widgets/itemviews/itemviews.pri
+++ b/src/widgets/itemviews/itemviews.pri
@@ -26,6 +26,7 @@ HEADERS += \
itemviews/qtreewidgetitemiterator.h \
itemviews/qdatawidgetmapper.h \
itemviews/qfileiconprovider.h \
+ itemviews/qfileiconprovider_p.h \
itemviews/qcolumnviewgrip_p.h \
itemviews/qcolumnview.h \
itemviews/qcolumnview_p.h \
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 70c8f44a73..b79525b9df 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -1108,6 +1108,7 @@ void QAbstractItemView::reset()
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ d->updateGeometry();
}
/*!
@@ -1124,6 +1125,7 @@ void QAbstractItemView::setRootIndex(const QModelIndex &index)
}
d->root = index;
d->doDelayedItemsLayout();
+ d->updateGeometry();
}
/*!
@@ -2668,8 +2670,10 @@ void QAbstractItemView::updateEditorGeometries()
*/
void QAbstractItemView::updateGeometries()
{
+ Q_D(QAbstractItemView);
updateEditorGeometries();
- d_func()->fetchMoreTimer.start(0, this); //fetch more later
+ d->fetchMoreTimer.start(0, this); //fetch more later
+ d->updateGeometry();
}
/*!
@@ -3231,6 +3235,7 @@ void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelInde
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ d->updateGeometry();
}
/*!
@@ -3332,6 +3337,7 @@ void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int star
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
/*!
@@ -3412,6 +3418,7 @@ void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int s
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
@@ -3435,6 +3442,7 @@ void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int sta
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
/*!
@@ -3459,6 +3467,7 @@ void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
/*!
@@ -4084,7 +4093,14 @@ void QAbstractItemViewPrivate::interruptDelayedItemsLayout() const
delayedPendingLayout = false;
}
-
+void QAbstractItemViewPrivate::updateGeometry()
+{
+ Q_Q(QAbstractItemView);
+ if (sizeAdjustPolicy == QAbstractScrollArea::AdjustIgnored)
+ return;
+ if (sizeAdjustPolicy == QAbstractScrollArea::AdjustToContents || !shownOnce)
+ q->updateGeometry();
+}
QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
const QStyleOptionViewItem &options)
diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h
index 86eab174ed..5da22615e2 100644
--- a/src/widgets/itemviews/qabstractitemview_p.h
+++ b/src/widgets/itemviews/qabstractitemview_p.h
@@ -127,6 +127,8 @@ public:
void doDelayedItemsLayout(int delay = 0);
void interruptDelayedItemsLayout() const;
+ void updateGeometry();
+
void startAutoScroll()
{ // ### it would be nice to make this into a style hint one day
int scrollInterval = (verticalScrollMode == QAbstractItemView::ScrollPerItem) ? 150 : 50;
diff --git a/src/widgets/itemviews/qcolumnview.cpp b/src/widgets/itemviews/qcolumnview.cpp
index 5aee78fab4..32a3dddca1 100644
--- a/src/widgets/itemviews/qcolumnview.cpp
+++ b/src/widgets/itemviews/qcolumnview.cpp
@@ -332,11 +332,14 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint)
}
#ifndef QT_NO_ANIMATION
- d->currentAnimation.setEndValue(newScrollbarValue);
- d->currentAnimation.start();
-#else
- horizontalScrollBar()->setValue(newScrollbarValue);
+ if (style()->styleHint(QStyle::SH_Widget_Animate, 0, this)) {
+ d->currentAnimation.setEndValue(newScrollbarValue);
+ d->currentAnimation.start();
+ } else
#endif //QT_NO_ANIMATION
+ {
+ horizontalScrollBar()->setValue(newScrollbarValue);
+ }
}
/*!
diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp
index 8a0736ec70..71697ddc40 100644
--- a/src/widgets/itemviews/qfileiconprovider.cpp
+++ b/src/widgets/itemviews/qfileiconprovider.cpp
@@ -40,9 +40,8 @@
****************************************************************************/
#include "qfileiconprovider.h"
+#include "qfileiconprovider_p.h"
-#ifndef QT_NO_FILEICONPROVIDER
-#include <qstyle.h>
#include <qapplication.h>
#include <qdir.h>
#include <qpixmapcache.h>
@@ -83,34 +82,15 @@ QT_BEGIN_NAMESPACE
\value File
*/
-class QFileIconProviderPrivate
-{
- Q_DECLARE_PUBLIC(QFileIconProvider)
-
-public:
- QFileIconProviderPrivate();
- QIcon getIcon(QStyle::StandardPixmap name) const;
- QIcon getIcon(const QFileInfo &fi) const;
-
- QFileIconProvider *q_ptr;
- const QString homePath;
-
-private:
- mutable QIcon file;
- mutable QIcon fileLink;
- mutable QIcon directory;
- mutable QIcon directoryLink;
- mutable QIcon harddisk;
- mutable QIcon floppy;
- mutable QIcon cdrom;
- mutable QIcon ram;
- mutable QIcon network;
- mutable QIcon computer;
- mutable QIcon desktop;
- mutable QIcon trashcan;
- mutable QIcon generic;
- mutable QIcon home;
-};
+
+/*!
+ \enum QFileIconProvider::Option
+ \since 5.2
+
+ \value DontUseCustomDirectoryIcons Always use the default directory icon.
+ Some platforms allow the user to set a different icon. Custom icon lookup
+ cause a big performance impact over network or removable drives.
+*/
QFileIconProviderPrivate::QFileIconProviderPrivate() :
homePath(QDir::home().absolutePath())
@@ -193,6 +173,31 @@ QFileIconProvider::~QFileIconProvider()
}
/*!
+ \since 5.2
+ Sets \a options that affect the icon provider.
+ \sa options()
+*/
+
+void QFileIconProvider::setOptions(QFileIconProvider::Options options)
+{
+ Q_D(QFileIconProvider);
+ d->options = options;
+}
+
+/*!
+ \since 5.2
+ Returns all the options that affect the icon provider.
+ By default, all options are disabled.
+ \sa setOptions()
+*/
+
+QFileIconProvider::Options QFileIconProvider::options() const
+{
+ Q_D(const QFileIconProvider);
+ return d->options;
+}
+
+/*!
Returns an icon set for the given \a type.
*/
@@ -220,6 +225,23 @@ QIcon QFileIconProvider::icon(IconType type) const
return QIcon();
}
+static bool isCacheable(const QFileInfo &fi)
+{
+ if (!fi.isFile())
+ return false;
+
+#ifdef Q_OS_WIN
+ // On windows it's faster to just look at the file extensions. QTBUG-13182
+ const QString fileExtension = fi.suffix();
+ // Will return false for .exe, .lnk and .ico extensions
+ return fileExtension.compare(QLatin1String("exe"), Qt::CaseInsensitive) &&
+ fileExtension.compare(QLatin1String("lnk"), Qt::CaseInsensitive) &&
+ fileExtension.compare(QLatin1String("ico"), Qt::CaseInsensitive);
+#else
+ return !fi.isExecutable() && !fi.isSymLink();
+#endif
+}
+
QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const
{
QIcon retIcon;
@@ -231,10 +253,9 @@ QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const
if (sizes.isEmpty())
return retIcon;
- const QString fileExtension = fi.suffix().toUpper();
const QString keyBase = QLatin1String("qt_.") + fi.suffix().toUpper();
- bool cacheable = fi.isFile() && !fi.isExecutable() && !fi.isSymLink() && fileExtension != QLatin1String("ICO");
+ bool cacheable = isCacheable(fi);
if (cacheable) {
QPixmap pixmap;
QPixmapCache::find(keyBase + QString::number(sizes.at(0)), pixmap);
@@ -253,8 +274,12 @@ QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const
}
}
+ QPlatformTheme::IconOptions iconOptions;
+ if (options & QFileIconProvider::DontUseCustomDirectoryIcons)
+ iconOptions |= QPlatformTheme::DontUseCustomDirectoryIcons;
+
Q_FOREACH (int size, sizes) {
- QPixmap pixmap = theme->fileIconPixmap(fi, QSizeF(size, size));
+ QPixmap pixmap = theme->fileIconPixmap(fi, QSizeF(size, size), iconOptions);
if (!pixmap.isNull()) {
retIcon.addPixmap(pixmap);
if (cacheable)
@@ -372,5 +397,3 @@ QString QFileIconProvider::type(const QFileInfo &info) const
}
QT_END_NAMESPACE
-
-#endif
diff --git a/src/widgets/itemviews/qfileiconprovider.h b/src/widgets/itemviews/qfileiconprovider.h
index cac135fe71..6f7e28395b 100644
--- a/src/widgets/itemviews/qfileiconprovider.h
+++ b/src/widgets/itemviews/qfileiconprovider.h
@@ -49,8 +49,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_FILEICONPROVIDER
-
class QFileIconProviderPrivate;
class Q_WIDGETS_EXPORT QFileIconProvider
@@ -59,19 +57,27 @@ public:
QFileIconProvider();
virtual ~QFileIconProvider();
enum IconType { Computer, Desktop, Trashcan, Network, Drive, Folder, File };
+
+ enum Option {
+ DontUseCustomDirectoryIcons = 0x00000001
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+
virtual QIcon icon(IconType type) const;
virtual QIcon icon(const QFileInfo &info) const;
virtual QString type(const QFileInfo &info) const;
+ void setOptions(Options options);
+ Options options() const;
+
private:
Q_DECLARE_PRIVATE(QFileIconProvider)
QScopedPointer<QFileIconProviderPrivate> d_ptr;
Q_DISABLE_COPY(QFileIconProvider)
};
-#endif // QT_NO_FILEICONPROVIDER
+Q_DECLARE_OPERATORS_FOR_FLAGS(QFileIconProvider::Options)
QT_END_NAMESPACE
#endif // QFILEICONPROVIDER_H
-
diff --git a/src/widgets/itemviews/qfileiconprovider_p.h b/src/widgets/itemviews/qfileiconprovider_p.h
new file mode 100644
index 0000000000..9b2d536258
--- /dev/null
+++ b/src/widgets/itemviews/qfileiconprovider_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFILEICONPROVIDER_P_H
+#define QFILEICONPROVIDER_P_H
+
+#include "qfileiconprovider.h"
+
+#include <QtCore/qstring.h>
+#include <QtGui/qicon.h>
+#include <QtWidgets/qstyle.h>
+
+QT_BEGIN_NAMESPACE
+
+class QFileInfo;
+
+class QFileIconProviderPrivate
+{
+ Q_DECLARE_PUBLIC(QFileIconProvider)
+
+public:
+ QFileIconProviderPrivate();
+ QIcon getIcon(QStyle::StandardPixmap name) const;
+ QIcon getIcon(const QFileInfo &fi) const;
+
+ QFileIconProvider *q_ptr;
+ const QString homePath;
+ QFileIconProvider::Options options;
+
+private:
+ mutable QIcon file;
+ mutable QIcon fileLink;
+ mutable QIcon directory;
+ mutable QIcon directoryLink;
+ mutable QIcon harddisk;
+ mutable QIcon floppy;
+ mutable QIcon cdrom;
+ mutable QIcon ram;
+ mutable QIcon network;
+ mutable QIcon computer;
+ mutable QIcon desktop;
+ mutable QIcon trashcan;
+ mutable QIcon generic;
+ mutable QIcon home;
+};
+
+QT_END_NAMESPACE
+
+#endif // QFILEICONPROVIDER_P_H
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index edfbc5c8f1..c9a845fc7b 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -550,6 +550,22 @@ QSize QHeaderView::sizeHint() const
}
/*!
+ \reimp
+*/
+
+void QHeaderView::setVisible(bool v)
+{
+ bool actualChange = (v != isVisible());
+ QAbstractItemView::setVisible(v);
+ if (actualChange) {
+ QAbstractScrollArea *parent = qobject_cast<QAbstractScrollArea*>(parentWidget());
+ if (parent)
+ parent->updateGeometry();
+ }
+}
+
+
+/*!
Returns a suitable size hint for the section specified by \a logicalIndex.
\sa sizeHint(), defaultSectionSize(), minimumSectionSize(),
@@ -918,6 +934,18 @@ void QHeaderView::resizeSection(int logical, int size)
d->doDelayedResizeSections();
r = d->viewport->rect();
}
+
+ // If the parent is a QAbstractScrollArea with QAbstractScrollArea::AdjustToContents
+ // then we want to change the geometry on that widget. Not doing it at once can/will
+ // cause scrollbars flicker as they would be shown at first but then removed.
+ // In the same situation it will also allow shrinking the whole view when stretchLastSection is set
+ // (It is default on QTreeViews - and it wouldn't shrink since the last stretch was made before the
+ // viewport was resized)
+
+ QAbstractScrollArea *parent = qobject_cast<QAbstractScrollArea *>(parentWidget());
+ if (parent && parent->sizeAdjustPolicy() == QAbstractScrollArea::AdjustToContents)
+ parent->updateGeometry();
+
d->viewport->update(r.normalized());
emit sectionResized(logical, oldSize, size);
}
@@ -1225,7 +1253,7 @@ void QHeaderView::setSectionResizeMode(ResizeMode mode)
property is set to true. This is the default for the horizontal headers provided
by QTreeView.
- \sa setStretchLastSection()
+ \sa setStretchLastSection(), resizeContentsPrecision()
*/
void QHeaderView::setSectionResizeMode(int logicalIndex, ResizeMode mode)
@@ -1288,6 +1316,53 @@ QHeaderView::ResizeMode QHeaderView::sectionResizeMode(int logicalIndex) const
return d->headerSectionResizeMode(visual);
}
+/*!
+ \since 5.2
+ Sets how precise QHeaderView should calculate the size when ResizeToContents is used.
+ A low value will provide a less accurate but fast auto resize while a higher
+ value will provide a more accurate resize that however can be slow.
+
+ The number \a precision specifies how many sections that should be consider
+ when calculating the preferred size.
+
+ The default value is 1000 meaning that a horizontal column with auto-resize will look
+ at maximum 1000 rows on calculating when doing an auto resize.
+
+ Special value 0 means that it will look at only the visible area.
+ Special value -1 will imply looking at all elements.
+
+ This value is used in QTableView::sizeHintForColumn(), QTableView::sizeHintForRow()
+ and QTreeView::sizeHintForColumn(). Reimplementing these functions can make this
+ function not having an effect.
+
+ If \a resizeSectionsNow is set to true (default) it will do adjustment of sections by calling
+ resizeSections(). (regardless if the precision was changed).
+
+ \sa resizeContentsPrecision(), setSectionResizeMode(), resizeSections(), QTableView::sizeHintForColumn(), QTableView::sizeHintForRow(), QTreeView::sizeHintForColumn()
+*/
+
+void QHeaderView::setResizeContentsPrecision(int precision, bool resizeSectionsNow)
+{
+ Q_D(QHeaderView);
+ d->resizeContentsPrecision = precision;
+ if (resizeSectionsNow)
+ resizeSections();
+}
+
+/*!
+ \since 5.2
+ Returns how precise QHeaderView will calculate on ResizeToContents.
+
+ \sa setResizeContentsPrecision(), setSectionResizeMode()
+
+*/
+
+int QHeaderView::resizeContentsPrecision() const
+{
+ Q_D(const QHeaderView);
+ return d->resizeContentsPrecision;
+}
+
// ### Qt 6 - remove this obsolete function
/*!
\obsolete
@@ -3512,6 +3587,19 @@ int QHeaderViewPrivate::adjustedVisualIndex(int visualIndex) const
return visualIndex;
}
+void QHeaderViewPrivate::setScrollOffset(const QScrollBar *scrollBar, QAbstractItemView::ScrollMode scrollMode)
+{
+ Q_Q(QHeaderView);
+ if (scrollMode == QAbstractItemView::ScrollPerItem) {
+ if (scrollBar->maximum() > 0 && scrollBar->value() == scrollBar->maximum())
+ q->setOffsetToLastSection();
+ else
+ q->setOffsetToSectionPosition(scrollBar->value());
+ } else {
+ q->setOffset(scrollBar->value());
+ }
+}
+
#ifndef QT_NO_DATASTREAM
void QHeaderViewPrivate::write(QDataStream &out) const
{
@@ -3542,6 +3630,8 @@ void QHeaderViewPrivate::write(QDataStream &out) const
out << int(globalResizeMode);
out << sectionItems;
+ if (out.version() >= QDataStream::Qt_5_2)
+ out << resizeContentsPrecision;
}
bool QHeaderViewPrivate::read(QDataStream &in)
@@ -3593,6 +3683,10 @@ bool QHeaderViewPrivate::read(QDataStream &in)
}
sectionItems = newSectionItems;
recalcSectionStartPos();
+
+ if (in.version() >= QDataStream::Qt_5_2)
+ in >> resizeContentsPrecision;
+
return true;
}
diff --git a/src/widgets/itemviews/qheaderview.h b/src/widgets/itemviews/qheaderview.h
index 8fcd8d7a36..3de3d320bf 100644
--- a/src/widgets/itemviews/qheaderview.h
+++ b/src/widgets/itemviews/qheaderview.h
@@ -84,6 +84,7 @@ public:
int offset() const;
int length() const;
QSize sizeHint() const;
+ void setVisible(bool v);
int sectionSizeHint(int logicalIndex) const;
int visualIndexAt(int position) const;
@@ -132,6 +133,10 @@ public:
ResizeMode sectionResizeMode(int logicalIndex) const;
void setSectionResizeMode(ResizeMode mode);
void setSectionResizeMode(int logicalIndex, ResizeMode mode);
+
+ void setResizeContentsPrecision(int precision, bool resizeNow = true);
+ int resizeContentsPrecision() const;
+
#if QT_DEPRECATED_SINCE(5, 0)
inline QT_DEPRECATED void setResizeMode(ResizeMode mode)
{ setSectionResizeMode(mode); }
diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h
index 7fda0c8873..c56e0d6196 100644
--- a/src/widgets/itemviews/qheaderview_p.h
+++ b/src/widgets/itemviews/qheaderview_p.h
@@ -99,7 +99,8 @@ public:
sectionIndicatorOffset(0),
sectionIndicator(0),
globalResizeMode(QHeaderView::Interactive),
- sectionStartposRecalc(true)
+ sectionStartposRecalc(true),
+ resizeContentsPrecision(1000)
{}
@@ -291,6 +292,7 @@ public:
QHeaderView::ResizeMode globalResizeMode;
QList<QPersistentModelIndex> persistentHiddenSections;
mutable bool sectionStartposRecalc;
+ int resizeContentsPrecision;
// header sections
struct SectionItem {
@@ -341,6 +343,7 @@ public:
// other
int viewSectionSizeHint(int logical) const;
int adjustedVisualIndex(int visualIndex) const;
+ void setScrollOffset(const QScrollBar *scrollBar, QAbstractItemView::ScrollMode scrollMode);
#ifndef QT_NO_DATASTREAM
void write(QDataStream &out) const;
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index 39d03124ce..1573e97981 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -347,7 +347,11 @@ void QListModel::ensureSorted(int column, Qt::SortOrder order, int start, int en
bool changed = false;
for (int i = 0; i < count; ++i) {
int oldRow = sorting.at(i).second;
+ int tmpitepos = lit - tmp.begin();
QListWidgetItem *item = tmp.takeAt(oldRow);
+ if (tmpitepos > tmp.size())
+ --tmpitepos;
+ lit = tmp.begin() + tmpitepos;
lit = sortedInsertionIterator(lit, tmp.end(), order, item);
int newRow = qMax(lit - tmp.begin(), 0);
lit = tmp.insert(lit, item);
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index a6623b9462..d282397c1b 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -931,6 +931,59 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &
}
/*!
+ \internal
+ Get sizeHint width for single Index (providing existing hint and style option)
+*/
+int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const
+{
+ Q_Q(const QTableView);
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().width());
+ int min = editor->minimumSize().width();
+ int max = editor->maximumSize().width();
+ hint = qBound(min, hint, max);
+ }
+ hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).width());
+ return hint;
+}
+
+/*!
+ \internal
+ Get sizeHint height for single Index (providing existing hint and style option)
+*/
+int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QStyleOptionViewItem &option) const
+{
+ Q_Q(const QTableView);
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().height());
+ int min = editor->minimumSize().height();
+ int max = editor->maximumSize().height();
+ hint = qBound(min, hint, max);
+ }
+
+ if (wrapItemText) {// for wrapping boundaries
+ option.rect.setY(q->rowViewportPosition(index.row()));
+ int height = q->rowHeight(index.row());
+ // if the option.height == 0 then q->itemDelegate(index)->sizeHint(option, index) will be wrong.
+ // The option.height == 0 is used to conclude that the text is not wrapped, and hence it will
+ // (exactly like widthHintForIndex) return a QSize with a long width (that we don't use) -
+ // and the height of the text if it was/is on one line.
+ // What we want is a height hint for the current width (and we know that this section is not hidden)
+ // Therefore we catch this special situation with:
+ if (height == 0)
+ height = 1;
+ option.rect.setHeight(height);
+ option.rect.setX(q->columnViewportPosition(index.column()));
+ option.rect.setWidth(q->columnWidth(index.column()));
+ }
+ hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).height());
+ return hint;
+}
+
+
+/*!
\class QTableView
\brief The QTableView class provides a default model/view
@@ -1056,6 +1109,19 @@ QTableView::~QTableView()
/*!
\reimp
*/
+QSize QTableView::viewportSizeHint() const
+{
+ Q_D(const QTableView);
+ QSize result( (d->verticalHeader->isHidden() ? 0 : d->verticalHeader->width()) + d->horizontalHeader->length(),
+ (d->horizontalHeader->isHidden() ? 0 : d->horizontalHeader->height()) + d->verticalHeader->length());
+ result += QSize(verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0,
+ horizontalScrollBar()->isVisible() ? horizontalScrollBar()->height() : 0);
+ return result;
+}
+
+/*!
+ \reimp
+*/
void QTableView::setModel(QAbstractItemModel *model)
{
Q_D(QTableView);
@@ -1113,15 +1179,7 @@ void QTableView::doItemsLayout()
{
Q_D(QTableView);
QAbstractItemView::doItemsLayout();
- if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
- const int max = verticalScrollBar()->maximum();
- if (max > 0 && verticalScrollBar()->value() == max)
- d->verticalHeader->setOffsetToLastSection();
- else
- d->verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value());
- } else {
- d->verticalHeader->setOffset(verticalScrollBar()->value());
- }
+ d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());
if (!d->verticalHeader->updatesEnabled())
d->verticalHeader->setUpdatesEnabled(true);
}
@@ -1258,29 +1316,19 @@ void QTableView::scrollContentsBy(int dx, int dy)
dx = isRightToLeft() ? -dx : dx;
if (dx) {
+ int oldOffset = d->horizontalHeader->offset();
+ d->horizontalHeader->d_func()->setScrollOffset(horizontalScrollBar(), horizontalScrollMode());
if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
- int oldOffset = d->horizontalHeader->offset();
- if (horizontalScrollBar()->value() == horizontalScrollBar()->maximum())
- d->horizontalHeader->setOffsetToLastSection();
- else
- d->horizontalHeader->setOffsetToSectionPosition(horizontalScrollBar()->value());
int newOffset = d->horizontalHeader->offset();
dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset;
- } else {
- d->horizontalHeader->setOffset(horizontalScrollBar()->value());
}
}
if (dy) {
+ int oldOffset = d->verticalHeader->offset();
+ d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());
if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
- int oldOffset = d->verticalHeader->offset();
- if (verticalScrollBar()->value() == verticalScrollBar()->maximum())
- d->verticalHeader->setOffsetToLastSection();
- else
- d->verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value());
int newOffset = d->verticalHeader->offset();
dy = oldOffset - newOffset;
- } else {
- d->verticalHeader->setOffset(verticalScrollBar()->value());
}
}
d->scrollContentsBy(dx, dy);
@@ -1760,13 +1808,13 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi
visualRow = bottom;
break;
case MovePageUp: {
- int newRow = rowAt(visualRect(current).top() - d->viewport->height());
+ int newRow = rowAt(visualRect(current).bottom() - d->viewport->height());
if (newRow == -1)
newRow = d->logicalRow(0);
return d->model->index(newRow, current.column(), d->root);
}
case MovePageDown: {
- int newRow = rowAt(visualRect(current).bottom() + d->viewport->height());
+ int newRow = rowAt(visualRect(current).top() + d->viewport->height());
if (newRow == -1)
newRow = d->logicalRow(bottom);
return d->model->index(newRow, current.column(), d->root);
@@ -2175,7 +2223,7 @@ void QTableView::updateGeometries()
if a larger row height is required by either the vertical header or
the item delegate, that width will be used instead.
- \sa QWidget::sizeHint, verticalHeader()
+ \sa QWidget::sizeHint, verticalHeader(), QHeaderView::resizeContentsPrecision()
*/
int QTableView::sizeHintForRow(int row) const
{
@@ -2185,6 +2233,8 @@ int QTableView::sizeHintForRow(int row) const
return -1;
ensurePolished();
+ const int maximumProcessCols = d->verticalHeader->resizeContentsPrecision();
+
int left = qMax(0, d->horizontalHeader->visualIndexAt(0));
int right = d->horizontalHeader->visualIndexAt(d->viewport->width());
@@ -2195,27 +2245,55 @@ int QTableView::sizeHintForRow(int row) const
int hint = 0;
QModelIndex index;
- for (int column = left; column <= right; ++column) {
+ int columnsProcessed = 0;
+ int column = left;
+ for (; column <= right; ++column) {
int logicalColumn = d->horizontalHeader->logicalIndex(column);
if (d->horizontalHeader->isSectionHidden(logicalColumn))
continue;
index = d->model->index(row, logicalColumn, d->root);
- if (d->wrapItemText) {// for wrapping boundaries
- option.rect.setY(rowViewportPosition(index.row()));
- option.rect.setHeight(rowHeight(index.row()));
- option.rect.setX(columnViewportPosition(index.column()));
- option.rect.setWidth(columnWidth(index.column()));
- }
+ hint = d->heightHintForIndex(index, hint, option);
+
+ ++columnsProcessed;
+ if (columnsProcessed == maximumProcessCols)
+ break;
+ }
- QWidget *editor = d->editorForIndex(index).widget.data();
- if (editor && d->persistent.contains(editor)) {
- hint = qMax(hint, editor->sizeHint().height());
- int min = editor->minimumSize().height();
- int max = editor->maximumSize().height();
- hint = qBound(min, hint, max);
+ int actualRight = d->model->columnCount(d->root) - 1;
+ int idxLeft = left;
+ int idxRight = column - 1;
+
+ if (maximumProcessCols == 0)
+ columnsProcessed = 0; // skip the while loop
+
+ while (columnsProcessed != maximumProcessCols && (idxLeft > 0 || idxRight < actualRight)) {
+ int logicalIdx = -1;
+
+ if ((columnsProcessed % 2 && idxLeft > 0) || idxRight == actualRight) {
+ while (idxLeft > 0) {
+ --idxLeft;
+ int logcol = d->horizontalHeader->logicalIndex(idxLeft);
+ if (d->horizontalHeader->isSectionHidden(logcol))
+ continue;
+ logicalIdx = logcol;
+ break;
+ }
+ } else {
+ while (idxRight < actualRight) {
+ ++idxRight;
+ int logcol = d->horizontalHeader->logicalIndex(idxRight);
+ if (d->horizontalHeader->isSectionHidden(logcol))
+ continue;
+ logicalIdx = logcol;
+ break;
+ }
}
+ if (logicalIdx < 0)
+ continue;
- hint = qMax(hint, itemDelegate(index)->sizeHint(option, index).height());
+ index = d->model->index(row, logicalIdx, d->root);
+ hint = d->heightHintForIndex(index, hint, option);
+ ++columnsProcessed;
}
return d->showGrid ? hint + 1 : hint;
@@ -2234,7 +2312,7 @@ int QTableView::sizeHintForRow(int row) const
required by either the horizontal header or the item delegate, the larger
width will be used instead.
- \sa QWidget::sizeHint, horizontalHeader()
+ \sa QWidget::sizeHint, horizontalHeader(), QHeaderView::resizeContentsPrecision()
*/
int QTableView::sizeHintForColumn(int column) const
{
@@ -2244,6 +2322,7 @@ int QTableView::sizeHintForColumn(int column) const
return -1;
ensurePolished();
+ const int maximumProcessRows = d->horizontalHeader->resizeContentsPrecision();
int top = qMax(0, d->verticalHeader->visualIndexAt(0));
int bottom = d->verticalHeader->visualIndexAt(d->viewport->height());
@@ -2253,22 +2332,56 @@ int QTableView::sizeHintForColumn(int column) const
QStyleOptionViewItem option = d->viewOptions();
int hint = 0;
+ int rowsProcessed = 0;
QModelIndex index;
- for (int row = top; row <= bottom; ++row) {
+ int row = top;
+ for (; row <= bottom; ++row) {
int logicalRow = d->verticalHeader->logicalIndex(row);
if (d->verticalHeader->isSectionHidden(logicalRow))
continue;
index = d->model->index(logicalRow, column, d->root);
- QWidget *editor = d->editorForIndex(index).widget.data();
- if (editor && d->persistent.contains(editor)) {
- hint = qMax(hint, editor->sizeHint().width());
- int min = editor->minimumSize().width();
- int max = editor->maximumSize().width();
- hint = qBound(min, hint, max);
+ hint = d->widthHintForIndex(index, hint, option);
+ ++rowsProcessed;
+ if (rowsProcessed == maximumProcessRows)
+ break;
+ }
+
+ int actualBottom = d->model->rowCount(d->root) - 1;
+ int idxTop = top;
+ int idxBottom = row - 1;
+
+ if (maximumProcessRows == 0)
+ rowsProcessed = 0; // skip the while loop
+
+ while (rowsProcessed != maximumProcessRows && (idxTop > 0 || idxBottom < actualBottom)) {
+ int logicalIdx = -1;
+
+ if ((rowsProcessed % 2 && idxTop > 0) || idxBottom == actualBottom) {
+ while (idxTop > 0) {
+ --idxTop;
+ int logrow = d->verticalHeader->logicalIndex(idxTop);
+ if (d->verticalHeader->isSectionHidden(logrow))
+ continue;
+ logicalIdx = logrow;
+ break;
+ }
+ } else {
+ while (idxBottom < actualBottom) {
+ ++idxBottom;
+ int logrow = d->verticalHeader->logicalIndex(idxBottom);
+ if (d->verticalHeader->isSectionHidden(logrow))
+ continue;
+ logicalIdx = logrow;
+ break;
+ }
}
+ if (logicalIdx < 0)
+ continue;
- hint = qMax(hint, itemDelegate(index)->sizeHint(option, index).width());
+ index = d->model->index(logicalIdx, column, d->root);
+ hint = d->widthHintForIndex(index, hint, option);
+ ++rowsProcessed;
}
return d->showGrid ? hint + 1 : hint;
@@ -2934,6 +3047,8 @@ void QTableView::showColumn(int column)
/*!
Resizes the given \a row based on the size hints of the delegate
used to render each item in the row.
+
+ \sa resizeRowsToContents(), sizeHintForRow(), QHeaderView::resizeContentsPrecision()
*/
void QTableView::resizeRowToContents(int row)
{
@@ -2946,6 +3061,8 @@ void QTableView::resizeRowToContents(int row)
/*!
Resizes all rows based on the size hints of the delegate
used to render each item in the rows.
+
+ \sa resizeRowToContents(), sizeHintForRow(), QHeaderView::resizeContentsPrecision()
*/
void QTableView::resizeRowsToContents()
{
@@ -2959,6 +3076,8 @@ void QTableView::resizeRowsToContents()
\note Only visible columns will be resized. Reimplement sizeHintForColumn()
to resize hidden columns as well.
+
+ \sa resizeColumnsToContents(), sizeHintForColumn(), QHeaderView::resizeContentsPrecision()
*/
void QTableView::resizeColumnToContents(int column)
{
@@ -2971,6 +3090,8 @@ void QTableView::resizeColumnToContents(int column)
/*!
Resizes all columns based on the size hints of the delegate
used to render each item in the columns.
+
+ \sa resizeColumnToContents(), sizeHintForColumn(), QHeaderView::resizeContentsPrecision()
*/
void QTableView::resizeColumnsToContents()
{
diff --git a/src/widgets/itemviews/qtableview.h b/src/widgets/itemviews/qtableview.h
index 824348dbe8..db956480d6 100644
--- a/src/widgets/itemviews/qtableview.h
+++ b/src/widgets/itemviews/qtableview.h
@@ -118,6 +118,8 @@ public:
void sortByColumn(int column, Qt::SortOrder order);
+ QSize viewportSizeHint() const;
+
public Q_SLOTS:
void selectRow(int row);
void selectColumn(int column);
diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h
index 923beec253..d36dcd2c3a 100644
--- a/src/widgets/itemviews/qtableview_p.h
+++ b/src/widgets/itemviews/qtableview_p.h
@@ -181,6 +181,8 @@ public:
const QStyleOptionViewItem &option, QBitArray *drawn,
int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn);
void drawCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index);
+ int widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const;
+ int heightHintForIndex(const QModelIndex &index, int hint, QStyleOptionViewItem &option) const;
bool showGrid;
Qt::PenStyle gridStyle;
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 6aefbb5367..b1ac4eba7b 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -335,6 +335,7 @@ void QTreeView::setHeader(QHeaderView *header)
this, SLOT(updateGeometries()));
setSortingEnabled(d->sortingEnabled);
+ d->updateGeometry();
}
/*!
@@ -952,6 +953,36 @@ bool QTreeView::wordWrap() const
return d->wrapItemText;
}
+/*!
+ \since 5.2
+
+ This specifies that the tree structure should be placed at logical index \a index.
+ If \index is set to -1 then the tree will always follow visual index 0.
+
+ \sa treePosition(), QHeaderView::swapSections(), QHeaderView::moveSection()
+*/
+
+void QTreeView::setTreePosition(int index)
+{
+ Q_D(QTreeView);
+ d->treePosition = index;
+ update();
+}
+
+/*!
+ \since 5.2
+
+ Return the logical index the tree is set on. If the return value is -1 then the
+ tree is placed on the visual index 0.
+
+ \sa setTreePosition()
+*/
+
+int QTreeView::treePosition() const
+{
+ Q_D(const QTreeView);
+ return d->treePosition;
+}
/*!
\reimp
@@ -1067,7 +1098,7 @@ QRect QTreeView::visualRect(const QModelIndex &index) const
int x = (spanning ? 0 : columnViewportPosition(index.column()));
int w = (spanning ? d->header->length() : columnWidth(index.column()));
// handle indentation
- if (index.column() == 0) {
+ if (d->isTreePosition(index.column())) {
int i = d->indentationForItem(vi);
w -= i;
if (!isRightToLeft())
@@ -1284,6 +1315,14 @@ void QTreeView::paintEvent(QPaintEvent *event)
}
}
+int QTreeViewPrivate::logicalIndexForTree() const
+{
+ int index = treePosition;
+ if (index < 0)
+ index = header->logicalIndex(0);
+ return index;
+}
+
void QTreeViewPrivate::paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItem *option, int y, int bottom) const
{
Q_Q(const QTreeView);
@@ -1516,7 +1555,7 @@ void QTreeViewPrivate::calcLogicalIndices(QVector<int> *logicalIndices, QVector<
if (columnCount == 1 || (nextLogicalSection == 0 && prevLogicalSection == -1)
|| (headerSection == 0 && nextLogicalSection == -1) || spanning)
pos = QStyleOptionViewItem::OnlyOne;
- else if (headerSection == 0 || (nextLogicalSection != 0 && prevLogicalSection == -1))
+ else if (isTreePosition(headerSection) || (nextLogicalSection != 0 && prevLogicalSection == -1))
pos = QStyleOptionViewItem::Beginning;
else if (nextLogicalSection == 0 || nextLogicalSection == -1)
pos = QStyleOptionViewItem::End;
@@ -1526,6 +1565,23 @@ void QTreeViewPrivate::calcLogicalIndices(QVector<int> *logicalIndices, QVector<
}
}
+/*!
+ \internal
+ Get sizeHint width for single index (providing existing hint and style option) and index in viewIndex i.
+*/
+int QTreeViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option, int i) const
+{
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().width());
+ int min = editor->minimumSize().width();
+ int max = editor->maximumSize().width();
+ hint = qBound(min, hint, max);
+ }
+ int xhint = delegateForIndex(index)->sizeHint(option, index).width();
+ hint = qMax(hint, xhint + (isTreePosition(index.column()) ? indentationForItem(i) : 0));
+ return hint;
+}
/*!
Draws the row in the tree view that contains the model item \a index,
@@ -1668,7 +1724,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
alternate row color was provided by the view. For backward compatibility,
this is now delegated to the style using PE_PanelViewItemRow which
does the appropriate fill */
- if (headerSection == 0) {
+ if (d->isTreePosition(headerSection)) {
const int i = d->indentationForItem(d->current);
QRect branches(reverse ? position + width - i : position, y, i, height);
const bool setClipRect = branches.width() > width;
@@ -2400,16 +2456,11 @@ void QTreeView::scrollContentsBy(int dx, int dy)
dx = isRightToLeft() ? -dx : dx;
if (dx) {
+ int oldOffset = d->header->offset();
+ d->header->d_func()->setScrollOffset(horizontalScrollBar(), horizontalScrollMode());
if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
- int oldOffset = d->header->offset();
- if (horizontalScrollBar()->value() == horizontalScrollBar()->maximum())
- d->header->setOffsetToLastSection();
- else
- d->header->setOffsetToSectionPosition(horizontalScrollBar()->value());
int newOffset = d->header->offset();
dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset;
- } else {
- d->header->setOffset(horizontalScrollBar()->value());
}
}
@@ -2552,7 +2603,7 @@ void QTreeView::columnCountChanged(int oldCount, int newCount)
/*!
Resizes the \a column given to the size of its contents.
- \sa columnWidth(), setColumnWidth()
+ \sa columnWidth(), setColumnWidth(), sizeHintForColumn(), QHeaderView::resizeContentsPrecision()
*/
void QTreeView::resizeColumnToContents(int column)
{
@@ -2619,6 +2670,35 @@ void QTreeView::selectAll()
}
/*!
+ \reimp
+*/
+QSize QTreeView::viewportSizeHint() const
+{
+ Q_D(const QTreeView);
+ d->executePostedLayout(); // Make sure that viewItems are up to date.
+
+ if (d->viewItems.size() == 0)
+ return QAbstractItemView::viewportSizeHint();
+
+ // Get rect for last item
+ const QRect deepestRect = visualRect(d->viewItems.last().index);
+
+ if (!deepestRect.isValid())
+ return QAbstractItemView::viewportSizeHint();
+
+ QSize result = QSize(d->header->length(), deepestRect.bottom() + 1);
+
+ // add size for header
+ result += QSize(0, d->header->isVisible() ? d->header->height() : 0);
+
+ // add size for scrollbars
+ result += QSize(verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0,
+ horizontalScrollBar()->isVisible() ? horizontalScrollBar()->height() : 0);
+
+ return result;
+}
+
+/*!
\since 4.2
Expands all expandable items.
@@ -2740,7 +2820,6 @@ void QTreeView::updateGeometries()
QRect vg = d->viewport->geometry();
QRect geometryRect(vg.left(), vg.top() - hint.height(), vg.width(), hint.height());
d->header->setGeometry(geometryRect);
- //d->header->setOffset(horizontalScrollBar()->value()); // ### bug ???
QMetaObject::invokeMethod(d->header, "updateGeometries");
d->updateScrollBars();
d->geometryRecursionBlock = false;
@@ -2760,7 +2839,7 @@ void QTreeView::updateGeometries()
if a larger column width is required by either the view's header or
the item delegate, that width will be used instead.
- \sa QWidget::sizeHint, header()
+ \sa QWidget::sizeHint, header(), QHeaderView::resizeContentsPrecision()
*/
int QTreeView::sizeHintForColumn(int column) const
{
@@ -2773,28 +2852,58 @@ int QTreeView::sizeHintForColumn(int column) const
QStyleOptionViewItem option = d->viewOptions();
const QVector<QTreeViewItem> viewItems = d->viewItems;
- int start = 0;
- int end = viewItems.count();
- if(end > 1000) { //if we have too many item this function would be too slow.
- //we get a good approximation by only iterate over 1000 items.
- start = qMax(0, d->firstVisibleItem() - 100);
- end = qMin(end, start + 900);
- }
+ const int maximumProcessRows = d->header->resizeContentsPrecision(); // To avoid this to take forever.
+
+ int offset = 0;
+ int start = d->firstVisibleItem(&offset);
+ int end = d->lastVisibleItem(start, offset);
- for (int i = start; i < end; ++i) {
+ int rowsProcessed = 0;
+
+ for (int i = start; i <= end; ++i) {
if (viewItems.at(i).spanning)
continue; // we have no good size hint
QModelIndex index = viewItems.at(i).index;
index = index.sibling(index.row(), column);
- QWidget *editor = d->editorForIndex(index).widget.data();
- if (editor && d->persistent.contains(editor)) {
- w = qMax(w, editor->sizeHint().width());
- int min = editor->minimumSize().width();
- int max = editor->maximumSize().width();
- w = qBound(min, w, max);
+ w = d->widthHintForIndex(index, w, option, i);
+ ++rowsProcessed;
+ if (rowsProcessed == maximumProcessRows)
+ break;
+ }
+
+ --end;
+ int actualBottom = viewItems.size() - 1;
+
+ if (maximumProcessRows == 0)
+ rowsProcessed = 0; // skip the while loop
+
+ while (rowsProcessed != maximumProcessRows && (start > 0 || end < actualBottom)) {
+ int idx = -1;
+
+ if ((rowsProcessed % 2 && start > 0) || end == actualBottom) {
+ while (start > 0) {
+ --start;
+ if (viewItems.at(start).spanning)
+ continue;
+ idx = start;
+ break;
+ }
+ } else {
+ while (end < actualBottom) {
+ ++end;
+ if (viewItems.at(end).spanning)
+ continue;
+ idx = end;
+ break;
+ }
}
- int hint = d->delegateForIndex(index)->sizeHint(option, index).width();
- w = qMax(w, hint + (column == 0 ? d->indentationForItem(i) : 0));
+ if (idx < 0)
+ continue;
+
+ QModelIndex index = viewItems.at(idx).index;
+ index = index.sibling(index.row(), column);
+ w = d->widthHintForIndex(index, w, option, idx);
+ ++rowsProcessed;
}
return w;
}
@@ -2915,6 +3024,7 @@ void QTreeViewPrivate::initialize()
header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter);
q->setHeader(header);
#ifndef QT_NO_ANIMATION
+ animationsEnabled = q->style()->styleHint(QStyle::SH_Widget_Animate, 0, q);
QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()));
#endif //QT_NO_ANIMATION
}
@@ -3314,7 +3424,7 @@ int QTreeViewPrivate::coordinateForItem(int item) const
if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) {
if (uniformRowHeights)
return (item * defaultItemHeight) - vbar->value();
- // ### optimize (spans or caching)
+ // ### optimize (maybe do like QHeaderView by letting items have startposition)
int y = 0;
for (int i = 0; i < viewItems.count(); ++i) {
if (i == item)
@@ -3481,7 +3591,7 @@ int QTreeViewPrivate::firstVisibleItem(int *offset) const
*offset = -(value % defaultItemHeight);
return value / defaultItemHeight;
}
- int y = 0; // ### optimize (use spans ?)
+ int y = 0; // ### (maybe do like QHeaderView by letting items have startposition)
for (int i = 0; i < viewItems.count(); ++i) {
y += itemHeight(i); // the height value is cached
if (y > value) {
@@ -3493,6 +3603,21 @@ int QTreeViewPrivate::firstVisibleItem(int *offset) const
return -1;
}
+int QTreeViewPrivate::lastVisibleItem(int firstVisual, int offset) const
+{
+ if (firstVisual < 0 || offset < 0)
+ firstVisual = firstVisibleItem(&offset);
+ int y = - offset;
+ int value = viewport->height();
+
+ for (int i = firstVisual; i < viewItems.count(); ++i) {
+ y += itemHeight(i); // the height value is cached
+ if (y > value)
+ return i;
+ }
+ return viewItems.size() - 1;
+}
+
int QTreeViewPrivate::columnAt(int x) const
{
return header->logicalIndexAt(x);
@@ -3535,7 +3660,7 @@ void QTreeViewPrivate::updateScrollBars()
int contentsHeight = 0;
if (uniformRowHeights) {
contentsHeight = defaultItemHeight * viewItems.count();
- } else { // ### optimize (spans or caching)
+ } else { // ### (maybe do like QHeaderView by letting items have startposition)
for (int i = 0; i < viewItems.count(); ++i)
contentsHeight += itemHeight(i);
}
@@ -3576,7 +3701,7 @@ int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const
executePostedLayout();
int x = pos.x();
int column = header->logicalIndexAt(x);
- if (column != 0)
+ if (!isTreePosition(column))
return -1; // no logical index at x
int viewItemIndex = itemAtCoordinate(pos.y());
@@ -3598,8 +3723,8 @@ QRect QTreeViewPrivate::itemDecorationRect(const QModelIndex &index) const
return QRect();
int itemIndentation = indentationForItem(viewItemIndex);
- int position = header->sectionViewportPosition(0);
- int size = header->sectionSize(0);
+ int position = header->sectionViewportPosition(logicalIndexForTree());
+ int size = header->sectionSize(logicalIndexForTree());
QRect rect;
if (q->isRightToLeft())
diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h
index 73f11f1a48..d9c6cd9269 100644
--- a/src/widgets/itemviews/qtreeview.h
+++ b/src/widgets/itemviews/qtreeview.h
@@ -128,6 +128,9 @@ public:
void setWordWrap(bool on);
bool wordWrap() const;
+ void setTreePosition(int logicalIndex);
+ int treePosition() const;
+
void keyboardSearch(const QString &search);
QRect visualRect(const QModelIndex &index) const;
@@ -144,6 +147,8 @@ public:
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>());
void selectAll();
+ QSize viewportSizeHint() const;
+
Q_SIGNALS:
void expanded(const QModelIndex &index);
void collapsed(const QModelIndex &index);
diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h
index 90e83cb58c..89de435606 100644
--- a/src/widgets/itemviews/qtreeview_p.h
+++ b/src/widgets/itemviews/qtreeview_p.h
@@ -91,10 +91,16 @@ public:
expandsOnDoubleClick(true),
allColumnsShowFocus(false), current(0), spanning(false),
animationsEnabled(false), columnResizeTimerID(0),
- autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false), hasRemovedItems(false) {}
+ autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false), hasRemovedItems(false),
+ treePosition(0) {}
~QTreeViewPrivate() {}
void initialize();
+ int logicalIndexForTree() const;
+ inline bool isTreePosition(int logicalIndex) const
+ {
+ return logicalIndex == logicalIndexForTree();
+ }
QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
void adjustViewOptionsForIndex(QStyleOptionViewItem *option, const QModelIndex &current) const;
@@ -148,6 +154,7 @@ public:
#endif
int firstVisibleItem(int *offset = 0) const;
+ int lastVisibleItem(int firstVisual = -1, int offset = -1) const;
int columnAt(int x) const;
bool hasVisibleChildren( const QModelIndex& parent) const;
@@ -171,7 +178,7 @@ public:
// logicalIndices: vector of currently visibly logical indices
// itemPositions: vector of view item positions (beginning/middle/end/onlyone)
void calcLogicalIndices(QVector<int> *logicalIndices, QVector<QStyleOptionViewItem::ViewItemPosition> *itemPositions, int left, int right) const;
-
+ int widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option, int i) const;
QHeaderView *header;
int indent;
@@ -251,6 +258,9 @@ public:
// If we should clean the set
bool hasRemovedItems;
+
+ // tree position
+ int treePosition;
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index f72abd20ab..2de7830c6a 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -623,7 +623,13 @@ void QTreeModel::ensureSorted(int column, Qt::SortOrder order,
for (int i = 0; i < count; ++i) {
int oldRow = sorting.at(i).second;
+
+ int tmpitepos = lit - lst.begin();
QTreeWidgetItem *item = lst.takeAt(oldRow);
+ if (tmpitepos > lst.size())
+ --tmpitepos;
+ lit = lst.begin() + tmpitepos;
+
lit = sortedInsertionIterator(lit, lst.end(), order, item);
int newRow = qMax(lit - lst.begin(), 0);
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index b918bdb9e9..af3d134a5a 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -1852,8 +1852,11 @@ bool QApplication::event(QEvent *e)
if (showToolTip) {
QHelpEvent e(QEvent::ToolTip, d->toolTipPos, d->toolTipGlobalPos);
QApplication::sendEvent(d->toolTipWidget, &e);
- if (e.isAccepted())
- d->toolTipFallAsleep.start(2000, this);
+ if (e.isAccepted()) {
+ QStyle *s = d->toolTipWidget->style();
+ int sleepDelay = s->styleHint(QStyle::SH_ToolTip_FallAsleepDelay, 0, d->toolTipWidget, 0);
+ d->toolTipFallAsleep.start(sleepDelay, this);
+ }
}
}
} else if (te->timerId() == d->toolTipFallAsleep.timerId()) {
@@ -2949,12 +2952,8 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QPoint relpos = mouse->pos();
if (e->spontaneous()) {
-
- if (e->type() == QEvent::MouseButtonPress) {
- QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
- Qt::ClickFocus,
- Qt::MouseFocusReason);
- }
+ if (e->type() != QEvent::MouseMove)
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos);
// ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms
// like Mac OS X (probably others too), can optimize their views by not
@@ -2967,7 +2966,9 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
d->toolTipWidget = w;
d->toolTipPos = relpos;
d->toolTipGlobalPos = mouse->globalPos();
- d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this);
+ QStyle *s = d->toolTipWidget->style();
+ int wakeDelay = s->styleHint(QStyle::SH_ToolTip_WakeUpDelay, 0, d->toolTipWidget, 0);
+ d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive() ? 20 : wakeDelay, this);
}
}
@@ -3042,11 +3043,8 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QPoint relpos = wheel->pos();
bool eventAccepted = wheel->isAccepted();
- if (e->spontaneous()) {
- QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
- Qt::WheelFocus,
- Qt::MouseFocusReason);
- }
+ if (e->spontaneous())
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos);
while (w) {
QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(),
@@ -3234,6 +3232,11 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
const bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
+ if (e->type() != QEvent::TouchUpdate && acceptTouchEvents && e->spontaneous()) {
+ const QPoint localPos = touchEvent->touchPoints()[0].pos().toPoint();
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget, e, localPos);
+ }
+
touchEvent->setTarget(widget);
touchEvent->setAccepted(acceptTouchEvents);
@@ -3251,16 +3254,16 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QWidget *widget = static_cast<QWidget *>(receiver);
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
bool eventAccepted = touchEvent->isAccepted();
- if (widget->testAttribute(Qt::WA_AcceptTouchEvents) && e->spontaneous()) {
- // give the widget focus if the focus policy allows it
- QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget,
- Qt::ClickFocus,
- Qt::MouseFocusReason);
+ bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
+
+ if (acceptTouchEvents && e->spontaneous()) {
+ const QPoint localPos = touchEvent->touchPoints()[0].pos().toPoint();
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget, e, localPos);
}
while (widget) {
// first, try to deliver the touch event
- bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
+ acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
touchEvent->setTarget(widget);
touchEvent->setAccepted(acceptTouchEvents);
QPointer<QWidget> p = widget;
@@ -3725,20 +3728,40 @@ bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event)
return QGuiApplication::sendSpontaneousEvent(receiver, event);
}
-
-void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget,
- Qt::FocusPolicy focusPolicy,
- Qt::FocusReason focusReason)
+void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget, QEvent *event, QPoint localPos)
{
+ const bool setFocusOnRelease = QGuiApplication::styleHints()->setFocusOnTouchRelease();
+ Qt::FocusPolicy focusPolicy = Qt::ClickFocus;
+
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::TouchBegin:
+ if (setFocusOnRelease)
+ return;
+ break;
+ case QEvent::MouseButtonRelease:
+ case QEvent::TouchEnd:
+ if (!setFocusOnRelease)
+ return;
+ break;
+ case QEvent::Wheel:
+ focusPolicy = Qt::WheelFocus;
+ break;
+ default:
+ return;
+ }
+
QWidget *focusWidget = widget;
while (focusWidget) {
if (focusWidget->isEnabled()
+ && focusWidget->rect().contains(localPos)
&& QApplicationPrivate::shouldSetFocus(focusWidget, focusPolicy)) {
- focusWidget->setFocus(focusReason);
+ focusWidget->setFocus(Qt::MouseFocusReason);
break;
}
if (focusWidget->isWindow())
break;
+ localPos += focusWidget->pos();
focusWidget = focusWidget->parentWidget();
}
}
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 87cf259ba5..29c6902c78 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -294,9 +294,7 @@ public:
private:
static QApplicationPrivate *self;
- static void giveFocusAccordingToFocusPolicy(QWidget *w,
- Qt::FocusPolicy focusPolicy,
- Qt::FocusReason focusReason);
+ static void giveFocusAccordingToFocusPolicy(QWidget *w, QEvent *event, QPoint localPos);
static bool shouldSetFocus(QWidget *w, Qt::FocusPolicy policy);
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
index 852b6b9697..0fc065e74b 100644
--- a/src/widgets/kernel/qapplication_qpa.cpp
+++ b/src/widgets/kernel/qapplication_qpa.cpp
@@ -198,7 +198,6 @@ void QApplicationPrivate::closePopup(QWidget *popup)
// mouse release event or inside
qt_replay_popup_mouse_event = false;
} else { // mouse press event
- QGuiApplicationPrivate::mousePressTime -= 10000; // avoid double click
qt_replay_popup_mouse_event = true;
}
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index a65c34adf5..8541dd984d 100644
--- a/src/widgets/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
@@ -1443,7 +1443,7 @@ QDataStream &operator<<(QDataStream &stream, const QSizePolicy &policy)
policy.bits.hfw << 8 | // [8]
policy.bits.ctype << 9 | // [9, 13]
policy.bits.wfh << 14 | // [14]
- //policy.bits.padding << 15 | // [15]
+ policy.bits.retainSizeWhenHidden << 15 | // [15]
policy.bits.verStretch << 16 | // [16, 23]
policy.bits.horStretch << 24); // [24, 31]
return stream << data;
@@ -1468,7 +1468,7 @@ QDataStream &operator>>(QDataStream &stream, QSizePolicy &policy)
policy.bits.hfw = VALUE_OF_BITS(data, 8, 1);
policy.bits.ctype = VALUE_OF_BITS(data, 9, 5);
policy.bits.wfh = VALUE_OF_BITS(data, 14, 1);
- policy.bits.padding = 0;
+ policy.bits.retainSizeWhenHidden = VALUE_OF_BITS(data, 15, 1);
policy.bits.verStretch = VALUE_OF_BITS(data, 16, 8);
policy.bits.horStretch = VALUE_OF_BITS(data, 24, 8);
return stream;
diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp
index 223bcf1d9b..a99ea77ce2 100644
--- a/src/widgets/kernel/qlayoutitem.cpp
+++ b/src/widgets/kernel/qlayoutitem.cpp
@@ -682,7 +682,7 @@ bool QSpacerItem::isEmpty() const
*/
bool QWidgetItem::isEmpty() const
{
- return wid->isHidden() || wid->isWindow();
+ return (wid->isHidden() && !wid->sizePolicy().retainSizeWhenHidden()) || wid->isWindow();
}
/*!
diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h
index 2fe85cbe0c..9c6d67410a 100644
--- a/src/widgets/kernel/qsizepolicy.h
+++ b/src/widgets/kernel/qsizepolicy.h
@@ -131,6 +131,9 @@ public:
void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
+ bool retainSizeWhenHidden() const { return bits.retainSizeWhenHidden; }
+ void setRetainSizeWhenHidden(bool retainSize) { bits.retainSizeWhenHidden = retainSize; }
+
void transpose();
@@ -150,7 +153,7 @@ private:
quint32 ctype : 5;
quint32 hfw : 1;
quint32 wfh : 1;
- quint32 padding : 1; // feel free to use
+ quint32 retainSizeWhenHidden : 1;
} bits;
quint32 data;
};
diff --git a/src/widgets/kernel/qsizepolicy.qdoc b/src/widgets/kernel/qsizepolicy.qdoc
index 6af694d999..2c088113e1 100644
--- a/src/widgets/kernel/qsizepolicy.qdoc
+++ b/src/widgets/kernel/qsizepolicy.qdoc
@@ -341,6 +341,23 @@
*/
/*!
+ \fn void QSizePolicy::retainSizeWhenHidden() const
+
+ Returns if the layout should retain the widgets size when it is hidden. This is by default false.
+
+ \sa setRetainSizeWhenHidden()
+*/
+
+/*!
+ \fn void QSizePolicy::setRetainSizeWhenHidden(bool retainSize)
+
+ Set if a layout should retain the widgets size when it is hidden.
+ If \a retainSize is true the layout will not be changed by hiding the widget.
+
+ \sa retainSizeWhenHidden()
+*/
+
+/*!
\enum QSizePolicy::ControlType
\since 4.3
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index 864ed6a555..8399f94976 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -120,7 +120,7 @@ class QTipLabel : public QLabel
{
Q_OBJECT
public:
- QTipLabel(const QString &text, QWidget *w);
+ QTipLabel(const QString &text, QWidget *w, int msecDisplayTime);
~QTipLabel();
static QTipLabel *instance;
@@ -130,11 +130,11 @@ public:
bool fadingOut;
- void reuseTip(const QString &text);
+ void reuseTip(const QString &text, int msecDisplayTime);
void hideTip();
void hideTipImmediately();
void setTipRect(QWidget *w, const QRect &r);
- void restartExpireTimer();
+ void restartExpireTimer(int msecDisplayTime);
bool tipChanged(const QPoint &pos, const QString &text, QObject *o);
void placeTip(const QPoint &pos, QWidget *w);
@@ -166,7 +166,7 @@ private:
QTipLabel *QTipLabel::instance = 0;
-QTipLabel::QTipLabel(const QString &text, QWidget *w)
+QTipLabel::QTipLabel(const QString &text, QWidget *w, int msecDisplayTime)
#ifndef QT_NO_STYLE_STYLESHEET
: QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget), styleSheetParent(0), widget(0)
#else
@@ -187,17 +187,19 @@ QTipLabel::QTipLabel(const QString &text, QWidget *w)
setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0);
setMouseTracking(true);
fadingOut = false;
- reuseTip(text);
+ reuseTip(text, msecDisplayTime);
}
-void QTipLabel::restartExpireTimer()
+void QTipLabel::restartExpireTimer(int msecDisplayTime)
{
int time = 10000 + 40 * qMax(0, text().length()-100);
+ if (msecDisplayTime > 0)
+ time = msecDisplayTime;
expireTimer.start(time, this);
hideTimer.stop();
}
-void QTipLabel::reuseTip(const QString &text)
+void QTipLabel::reuseTip(const QString &text, int msecDisplayTime)
{
#ifndef QT_NO_STYLE_STYLESHEET
if (styleSheetParent){
@@ -215,7 +217,7 @@ void QTipLabel::reuseTip(const QString &text)
if (fm.descent() == 2 && fm.ascent() >= 11)
++extra.rheight();
resize(sizeHint() + extra);
- restartExpireTimer();
+ restartExpireTimer(msecDisplayTime);
}
void QTipLabel::paintEvent(QPaintEvent *ev)
@@ -440,6 +442,18 @@ bool QTipLabel::tipChanged(const QPoint &pos, const QString &text, QObject *o)
void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect)
{
+ showText(pos, text, w, rect, -1);
+}
+
+/*!
+ \since 5.2
+ \overload
+ This is similar to QToolTip::showText(\a pos, \a text, \a w, \a rect) but with an extra parameter \a msecDisplayTime
+ that specifies how long the tool tip will be displayed, in milliseconds.
+*/
+
+void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect, int msecDisplayTime)
+{
if (QTipLabel::instance && QTipLabel::instance->isVisible()){ // a tip does already exist
if (text.isEmpty()){ // empty text means hide current tip
QTipLabel::instance->hideTip();
@@ -452,7 +466,7 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons
if (w)
localPos = w->mapFromGlobal(pos);
if (QTipLabel::instance->tipChanged(localPos, text, w)){
- QTipLabel::instance->reuseTip(text);
+ QTipLabel::instance->reuseTip(text, msecDisplayTime);
QTipLabel::instance->setTipRect(w, rect);
QTipLabel::instance->placeTip(pos, w);
}
@@ -462,11 +476,11 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons
if (!text.isEmpty()){ // no tip can be reused, create new tip:
#ifndef Q_WS_WIN
- new QTipLabel(text, w); // sets QTipLabel::instance to itself
+ new QTipLabel(text, w, msecDisplayTime); // sets QTipLabel::instance to itself
#else
// On windows, we can't use the widget as parent otherwise the window will be
// raised when the tooltip will be shown
- new QTipLabel(text, QApplication::desktop()->screen(QTipLabel::getTipScreen(pos, w)));
+ new QTipLabel(text, QApplication::desktop()->screen(QTipLabel::getTipScreen(pos, w)), msecDisplayTime);
#endif
QTipLabel::instance->setTipRect(w, rect);
QTipLabel::instance->placeTip(pos, w);
diff --git a/src/widgets/kernel/qtooltip.h b/src/widgets/kernel/qtooltip.h
index 25b138b855..ccde405342 100644
--- a/src/widgets/kernel/qtooltip.h
+++ b/src/widgets/kernel/qtooltip.h
@@ -53,8 +53,10 @@ class Q_WIDGETS_EXPORT QToolTip
{
QToolTip() Q_DECL_EQ_DELETE;
public:
+ // ### Qt 6 - merge the three showText functions below
static void showText(const QPoint &pos, const QString &text, QWidget *w = 0);
static void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect);
+ static void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect, int msecShowTime);
static inline void hideText() { showText(QPoint(), QString()); }
static bool isVisible();
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 49d64c5cd8..5532b04b22 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -245,6 +245,9 @@ QWidgetPrivate::QWidgetPrivate(int version)
#if !defined(QT_NO_IM)
, imHints(Qt::ImhNone)
#endif
+#ifndef QT_NO_TOOLTIP
+ , toolTipDuration(-1)
+#endif
, inheritedFontResolveMask(0)
, inheritedPaletteResolveMask(0)
, leftmargin(0)
@@ -261,6 +264,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
, bg_role(QPalette::NoRole)
, dirtyOpaqueChildren(1)
, isOpaque(0)
+ , retainSizeWhenHiddenChanged(0)
, inDirtyList(0)
, isScrolled(0)
, isMoved(0)
@@ -7264,10 +7268,19 @@ void QWidget::setVisible(bool visible)
create();
}
-#if defined(Q_WS_X11)
- if (windowType() == Qt::Window)
- QApplicationPrivate::applyX11SpecificCommandLineArguments(this);
-#endif
+ // Handling of the -qwindowgeometry, -geometry command line arguments
+ if (windowType() == Qt::Window && windowHandle()) {
+ static bool done = false;
+ if (!done) {
+ done = true;
+ const QRect oldGeometry = frameGeometry();
+ const QRect geometry = QGuiApplicationPrivate::applyWindowGeometrySpecification(oldGeometry, windowHandle());
+ if (oldGeometry.size() != geometry.size())
+ resize(geometry.size());
+ if (geometry.topLeft() != oldGeometry.topLeft())
+ move(geometry.topLeft());
+ } // done
+ }
bool wasResized = testAttribute(Qt::WA_Resized);
Qt::WindowStates initialWindowState = windowState();
@@ -8207,7 +8220,7 @@ bool QWidget::event(QEvent *event)
#ifndef QT_NO_TOOLTIP
case QEvent::ToolTip:
if (!d->toolTip.isEmpty())
- QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), d->toolTip, this);
+ QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), d->toolTip, this, QRect(), d->toolTipDuration);
else
event->ignore();
break;
@@ -9251,6 +9264,10 @@ void QWidget::setSizePolicy(QSizePolicy policy)
setAttribute(Qt::WA_WState_OwnSizePolicy);
if (policy == d->size_policy)
return;
+
+ if (d->size_policy.retainSizeWhenHidden() != policy.retainSizeWhenHidden())
+ d->retainSizeWhenHiddenChanged = 1;
+
d->size_policy = policy;
#ifndef QT_NO_GRAPHICSVIEW
@@ -9261,6 +9278,7 @@ void QWidget::setSizePolicy(QSizePolicy policy)
#endif
updateGeometry();
+ d->retainSizeWhenHiddenChanged = 0;
if (isWindow() && d->maybeTopData())
d->topData()->sizeAdjusted = false;
@@ -9389,7 +9407,9 @@ void QWidgetPrivate::updateGeometry_helper(bool forceUpdate)
widgetItem->invalidateSizeCache();
QWidget *parent;
if (forceUpdate || !extra || extra->minw != extra->maxw || extra->minh != extra->maxh) {
- if (!q->isWindow() && !q->isHidden() && (parent = q->parentWidget())) {
+ const int isHidden = q->isHidden() && !size_policy.retainSizeWhenHidden() && !retainSizeWhenHiddenChanged;
+
+ if (!q->isWindow() && !isHidden && (parent = q->parentWidget())) {
if (parent->d_func()->layout)
parent->d_func()->layout->invalidate();
else if (parent->isVisible())
@@ -10019,6 +10039,13 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
}
#endif
+ // Don't set WA_NativeWindow on platforms that don't support it
+ if (attribute == Qt::WA_NativeWindow) {
+ QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
+ if (!platformIntegration->hasCapability(QPlatformIntegration::NativeWidgets))
+ return;
+ }
+
setAttribute_internal(attribute, on, data, d);
switch (attribute) {
@@ -10426,6 +10453,30 @@ QString QWidget::toolTip() const
Q_D(const QWidget);
return d->toolTip;
}
+
+/*!
+ \property QWidget::toolTipDuration
+ \brief the widget's tooltip duration
+ \since 5.2
+
+ Specifies how long time the tooltip will be displayed, in milliseconds.
+ If the value is -1 (default) the duration is calculated depending on the length of the tooltip.
+
+ \sa toolTip
+*/
+
+void QWidget::setToolTipDuration(int msec)
+{
+ Q_D(QWidget);
+ d->toolTipDuration = msec;
+}
+
+int QWidget::toolTipDuration() const
+{
+ Q_D(const QWidget);
+ return d->toolTipDuration;
+}
+
#endif // QT_NO_TOOLTIP
diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h
index f90f2ee5f5..f579dbb9cd 100644
--- a/src/widgets/kernel/qwidget.h
+++ b/src/widgets/kernel/qwidget.h
@@ -178,6 +178,7 @@ class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice
Q_PROPERTY(bool windowModified READ isWindowModified WRITE setWindowModified DESIGNABLE isWindow)
#ifndef QT_NO_TOOLTIP
Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip)
+ Q_PROPERTY(int toolTipDuration READ toolTipDuration WRITE setToolTipDuration)
#endif
#ifndef QT_NO_STATUSTIP
Q_PROPERTY(QString statusTip READ statusTip WRITE setStatusTip)
@@ -376,6 +377,8 @@ public:
#ifndef QT_NO_TOOLTIP
void setToolTip(const QString &);
QString toolTip() const;
+ void setToolTipDuration(int msec);
+ int toolTipDuration() const;
#endif
#ifndef QT_NO_STATUSTIP
void setStatusTip(const QString &);
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 50f32af8b0..0580f72e11 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -644,6 +644,7 @@ public:
QRegion dirty;
#ifndef QT_NO_TOOLTIP
QString toolTip;
+ int toolTipDuration;
#endif
#ifndef QT_NO_STATUSTIP
QString statusTip;
@@ -687,6 +688,7 @@ public:
QPalette::ColorRole bg_role : 8;
uint dirtyOpaqueChildren : 1;
uint isOpaque : 1;
+ uint retainSizeWhenHiddenChanged : 1;
uint inDirtyList : 1;
uint isScrolled : 1;
uint isMoved : 1;
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 675ea77b30..f2bd389769 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -559,7 +559,7 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event)
QPoint mapped = widget->mapFrom(m_widget, event->pos());
- QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers());
+ QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers(), event->phase());
QGuiApplication::sendSpontaneousEvent(widget, &translated);
}
diff --git a/src/widgets/styles/images/cleartext-16.png b/src/widgets/styles/images/cleartext-16.png
new file mode 100644
index 0000000000..74133bafff
--- /dev/null
+++ b/src/widgets/styles/images/cleartext-16.png
Binary files differ
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 936eb76dad..f5b61ea6f3 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -65,6 +65,7 @@
#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <qrubberband.h>
+#include "qtreeview.h"
#include <private/qcommonstylepixmaps_p.h>
#include <private/qmath_p.h>
#include <qdebug.h>
@@ -5097,11 +5098,7 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
ret = theme->themeHint(QPlatformTheme::ToolButtonStyle).toInt();
break;
case SH_RequestSoftwareInputPanel:
-#ifdef Q_OS_ANDROID
ret = RSIP_OnMouseClick;
-#else
- ret = RSIP_OnMouseClickAndAlreadyFocused;
-#endif
break;
case SH_ScrollBar_Transient:
ret = false;
@@ -5109,6 +5106,24 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
case SH_Menu_SupportsSections:
ret = false;
break;
+#ifndef QT_NO_TOOLTIP
+ case SH_ToolTip_WakeUpDelay:
+ ret = 700;
+ break;
+ case SH_ToolTip_FallAsleepDelay:
+ ret = 2000;
+ break;
+#endif
+ case SH_Widget_Animate:
+#ifndef QT_NO_TREEVIEW
+ if (qobject_cast<const QTreeView*>(widget)) {
+ ret = false;
+ } else
+#endif
+ {
+ ret = true;
+ }
+ break;
default:
ret = 0;
break;
@@ -5289,6 +5304,13 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti
}
}
break;
+ case SP_LineEditClearButton: {
+ QString themeName = rtl ? QStringLiteral("edit-clear-locationbar-ltr") : QStringLiteral("edit-clear-locationbar-rtl");
+ if (!QIcon::hasThemeIcon(themeName))
+ themeName = QStringLiteral("edit-clear");
+ pixmap = QIcon::fromTheme(themeName).pixmap(16);
+ }
+ break;
default:
break;
}
@@ -5417,6 +5439,8 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti
return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-16.png"));
case SP_MediaVolumeMuted:
return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png"));
+ case SP_LineEditClearButton:
+ return QPixmap(QStringLiteral(":/qt-project.org/styles/commonstyle/images/cleartext-16.png"));
#endif // QT_NO_IMAGEFORMAT_PNG
default:
break;
diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp
index 769d822108..c53a21e59a 100644
--- a/src/widgets/styles/qgtkstyle_p.cpp
+++ b/src/widgets/styles/qgtkstyle_p.cpp
@@ -756,8 +756,9 @@ void QGtkStylePrivate::removeWidgetFromMap(const QHashableLatin1Literal &path)
WidgetMap *map = gtkWidgetMap();
WidgetMap::iterator it = map->find(path);
if (it != map->end()) {
- free(const_cast<char *>(it.key().data()));
+ char* keyData = const_cast<char *>(it.key().data());
map->erase(it);
+ free(keyData);
}
}
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index dccc9ff3ce..8d8eb3aa46 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1894,6 +1894,16 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SH_Menu_SupportsSections Determines if the style displays sections in menus or treat them as
plain separators. Sections are separators with a text and icon hint.
+ \value SH_ToolTip_WakeUpDelay Determines the delay before a tooltip is shown, in milliseconds.
+
+ \value SH_ToolTip_FallAsleepDelay Determines the delay (in milliseconds) before a new wake time is needed when
+ a tooltip is shown (notice: shown, not hidden). When a new wake isn't needed, a user-requested tooltip
+ will be shown nearly instantly.
+
+ \value SH_Widget_Animate Determines if the widget should show animations or not, for example
+ a transition between checked and unchecked statuses in a checkbox.
+ This enum value has been introduced in Qt 5.2.
+
\sa styleHint()
*/
@@ -1986,6 +1996,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SP_MediaSeekBackward Icon indicating that media should seek backward.
\value SP_MediaVolume Icon indicating a volume control.
\value SP_MediaVolumeMuted Icon indicating a muted volume control.
+ \value SP_LineEditClearButton Icon for a standard clear button in a QLineEdit. This enum value was added in Qt 5.2.
\value SP_CustomBase Base value for custom standard pixmaps;
custom values must be greater than this value.
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index beafad326e..fffd423c8a 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -698,6 +698,9 @@ public:
SH_RequestSoftwareInputPanel,
SH_ScrollBar_Transient,
SH_Menu_SupportsSections,
+ SH_ToolTip_WakeUpDelay,
+ SH_ToolTip_FallAsleepDelay,
+ SH_Widget_Animate,
// Add new style hint values here
SH_CustomBase = 0xf0000000
@@ -777,6 +780,7 @@ public:
SP_MediaSeekBackward,
SP_MediaVolume,
SP_MediaVolumeMuted,
+ SP_LineEditClearButton,
// do not add any values below/greater than this
SP_CustomBase = 0xf0000000
};
diff --git a/src/widgets/styles/qstyle.qrc b/src/widgets/styles/qstyle.qrc
index 28ad484032..c063ec5036 100644
--- a/src/widgets/styles/qstyle.qrc
+++ b/src/widgets/styles/qstyle.qrc
@@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/qt-project.org/styles/commonstyle">
+ <file>images/cleartext-16.png</file>
<file>images/filelink-16.png</file>
<file>images/filelink-32.png</file>
<file>images/filelink-128.png</file>
diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp
index 5204b85a9a..347e5701c0 100644
--- a/src/widgets/util/qsystemtrayicon_x11.cpp
+++ b/src/widgets/util/qsystemtrayicon_x11.cpp
@@ -57,84 +57,19 @@
#include <qpa/qplatformnativeinterface.h>
#include <qdebug.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xos.h>
-#include <X11/Xatom.h>
-
#ifndef QT_NO_SYSTEMTRAYICON
QT_BEGIN_NAMESPACE
-enum {
- SYSTEM_TRAY_REQUEST_DOCK = 0,
- SYSTEM_TRAY_BEGIN_MESSAGE = 1,
- SYSTEM_TRAY_CANCEL_MESSAGE =2
-};
-
-// ### fixme (15.3.2012): The following issues need to be resolved:
-// - Tracking of the actual tray window for DestroyNotify and re-creation
-// of the icons on the new window should it change (see Qt 4.X).
-
-// Global context for the X11 system tray containing a display for the primary
-// screen and a selection atom from which the tray window can be determined.
-class QX11SystemTrayContext
-{
-public:
- QX11SystemTrayContext();
- ~QX11SystemTrayContext();
-
- bool isValid() const { return m_systemTraySelection != 0; }
-
- inline Display *display() const { return m_display; }
- inline int screenNumber() const { return m_screenNumber; }
- Window locateSystemTray() const;
-
-private:
- Display *m_display;
- int m_screenNumber;
- Atom m_systemTraySelection;
-};
-
-QX11SystemTrayContext::QX11SystemTrayContext() : m_display(0), m_screenNumber(0), m_systemTraySelection(0)
-{
- QScreen *screen = QGuiApplication::primaryScreen();
- if (!screen) {
- qWarning("%s: No screen.", Q_FUNC_INFO);
- return;
- }
- void *displayV = QGuiApplication::platformNativeInterface()->nativeResourceForScreen(QByteArrayLiteral("display"), screen);
- if (!displayV) {
- qWarning("%s: Unable to obtain X11 display of primary screen.", Q_FUNC_INFO);
- return;
- }
-
- m_display = static_cast<Display *>(displayV);
-
- const QByteArray netSysTray = "_NET_SYSTEM_TRAY_S" + QByteArray::number(m_screenNumber);
- m_systemTraySelection = XInternAtom(m_display, netSysTray.constData(), False);
- if (!m_systemTraySelection) {
- qWarning("%s: Unable to retrieve atom '%s'.", Q_FUNC_INFO, netSysTray.constData());
- return;
- }
-}
-
-Window QX11SystemTrayContext::locateSystemTray() const
+static inline unsigned long locateSystemTray()
{
- if (isValid())
- return XGetSelectionOwner(m_display, m_systemTraySelection);
- return 0;
+ return (unsigned long)QGuiApplication::platformNativeInterface()->nativeResourceForScreen(QByteArrayLiteral("traywindow"), QGuiApplication::primaryScreen());
}
-QX11SystemTrayContext::~QX11SystemTrayContext()
-{
-}
-
-Q_GLOBAL_STATIC(QX11SystemTrayContext, qX11SystemTrayContext)
-
// System tray widget. Could be replaced by a QWindow with
// a backing store if it did not need tooltip handling.
class QSystemTrayIconSys : public QWidget
{
+ Q_OBJECT
public:
explicit QSystemTrayIconSys(QSystemTrayIcon *q);
@@ -149,7 +84,12 @@ protected:
virtual bool event(QEvent *);
virtual void paintEvent(QPaintEvent *);
+private slots:
+ void systemTrayWindowChanged(QScreen *screen);
+
private:
+ bool addToTray();
+
QSystemTrayIcon *q;
};
@@ -159,47 +99,59 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn)
{
setObjectName(QStringLiteral("QSystemTrayIconSys"));
setToolTip(q->toolTip());
- QX11SystemTrayContext *context = qX11SystemTrayContext();
- Q_ASSERT(context->isValid());
setAttribute(Qt::WA_AlwaysShowToolTips, true);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_QuitOnClose, false);
const QSize size(22, 22); // Gnome, standard size
setGeometry(QRect(QPoint(0, 0), size));
setMinimumSize(size);
+ addToTray();
+}
+
+bool QSystemTrayIconSys::addToTray()
+{
+ if (!locateSystemTray())
+ return false;
+
createWinId();
setMouseTracking(true);
- Display *display = context->display();
-
- // Request to be a tray window according to GNOME, NET WM Specification
- static Atom netwm_tray_atom = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", False);
- long l[5] = { CurrentTime, SYSTEM_TRAY_REQUEST_DOCK, static_cast<long>(winId()), 0, 0 };
- XEvent ev;
- memset(&ev, 0, sizeof(ev));
- ev.xclient.type = ClientMessage;
- ev.xclient.window = context->locateSystemTray();
- ev.xclient.message_type = netwm_tray_atom;
- ev.xclient.format = 32;
- memcpy((char *)&ev.xclient.data, (const char *) l, sizeof(l));
- XSendEvent(display, ev.xclient.window, False, 0, &ev);
+ bool requestResult = false;
+ if (!QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(),
+ "requestSystemTrayWindowDock", Qt::DirectConnection,
+ Q_RETURN_ARG(bool, requestResult),
+ Q_ARG(const QWindow *, windowHandle()))
+ || !requestResult) {
+ qWarning("requestSystemTrayWindowDock failed.");
+ return false;
+ }
show();
+ return true;
}
-QRect QSystemTrayIconSys::globalGeometry() const
+void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *)
{
- QX11SystemTrayContext *context = qX11SystemTrayContext();
- ::Window dummy;
- int x, y, rootX, rootY;
- unsigned int width, height, border, depth;
- // Use X11 API since we are parented on the tray, about which the QWindow does not know.
- XGetGeometry(context->display(), winId(), &dummy, &x, &y, &width, &height, &border, &depth);
- XTranslateCoordinates(context->display(), winId(),
- XRootWindow(context->display(), context->screenNumber()),
- x, y, &rootX, &rootY, &dummy);
- return QRect(QPoint(rootX, rootY), QSize(width, height));
+ if (locateSystemTray()) {
+ addToTray();
+ } else {
+ QBalloonTip::hideBalloon();
+ hide(); // still no luck
+ destroy();
+ }
}
+QRect QSystemTrayIconSys::globalGeometry() const
+{
+ QRect result;
+ if (!QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(),
+ "systemTrayWindowGlobalGeometry", Qt::DirectConnection,
+ Q_RETURN_ARG(QRect, result),
+ Q_ARG(const QWindow *, windowHandle()))
+ || !result.isValid()) {
+ qWarning("systemTrayWindowGlobalGeometry failed.");
+ }
+ return result;
+}
void QSystemTrayIconSys::mousePressEvent(QMouseEvent *ev)
{
@@ -268,8 +220,11 @@ QSystemTrayIconPrivate::~QSystemTrayIconPrivate()
void QSystemTrayIconPrivate::install_sys()
{
Q_Q(QSystemTrayIcon);
- if (!sys && qX11SystemTrayContext()->isValid())
+ if (!sys && locateSystemTray()) {
sys = new QSystemTrayIconSys(q);
+ QObject::connect(QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),
+ sys, SLOT(systemTrayWindowChanged(QScreen*)));
+ }
}
QRect QSystemTrayIconPrivate::geometry_sys() const
@@ -313,7 +268,7 @@ bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
{
const QString platform = QGuiApplication::platformName();
if (platform.compare(QStringLiteral("xcb"), Qt::CaseInsensitive) == 0)
- return qX11SystemTrayContext()->locateSystemTray() != None;
+ return locateSystemTray();
return false;
}
@@ -334,4 +289,7 @@ void QSystemTrayIconPrivate::showMessage_sys(const QString &message, const QStri
}
QT_END_NAMESPACE
+
+#include "qsystemtrayicon_x11.moc"
+
#endif //QT_NO_SYSTEMTRAYICON
diff --git a/src/widgets/util/util.pri b/src/widgets/util/util.pri
index 598a3082c0..072c736f71 100644
--- a/src/widgets/util/util.pri
+++ b/src/widgets/util/util.pri
@@ -31,7 +31,6 @@ win32:!wince* {
SOURCES += util/qsystemtrayicon_win.cpp
} else:contains(QT_CONFIG, xcb) {
SOURCES += util/qsystemtrayicon_x11.cpp
- CONFIG += x11
} else {
SOURCES += util/qsystemtrayicon_qpa.cpp
}
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 900e95f4da..e7827055fb 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -167,6 +167,7 @@ QT_BEGIN_NAMESPACE
QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()
:hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded),
+ shownOnce(false), sizeAdjustPolicy(QAbstractScrollArea::AdjustIgnored),
viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0),
xoffset(0), yoffset(0), viewportFilter(0)
#ifdef Q_WS_WIN
@@ -527,6 +528,19 @@ void QAbstractScrollAreaPrivate::layoutChildren()
}
/*!
+ \enum QAbstractScrollArea::SizeAdjustPolicy
+ \since 5.2
+
+ This enum specifies how the size hint of the QAbstractScrollArea should
+ adjust when the size of the viewport changes.
+
+ \value AdjustIgnored The scroll area will behave like before - and not do any adjust.
+ \value AdjustToContents The scroll area will always adjust to the viewport
+ \value AdjustToContentsOnFirstShow The scroll area will adjust to its viewport the first time it is shown.
+*/
+
+
+/*!
\internal
Creates a new QAbstractScrollAreaPrivate, \a dd with the given \a parent.
@@ -983,6 +997,13 @@ bool QAbstractScrollArea::event(QEvent *e)
case QEvent::Resize:
d->layoutChildren();
break;
+ case QEvent::Show:
+ if (!d->shownOnce && d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContentsOnFirstShow) {
+ d->sizeHint = QSize();
+ updateGeometry();
+ }
+ d->shownOnce = true;
+ return QFrame::event(e);
case QEvent::Paint: {
QStyleOption option;
option.initFrom(this);
@@ -1533,17 +1554,70 @@ QSize QAbstractScrollArea::minimumSizeHint() const
}
/*!
+ Returns the sizeHint property of the scroll area. The size is determined by using
+ viewportSizeHint() plus some extra space for scroll bars, if needed.
\reimp
*/
QSize QAbstractScrollArea::sizeHint() const
{
- return QSize(256, 192);
-#if 0
Q_D(const QAbstractScrollArea);
- int h = qMax(10, fontMetrics().height());
- int f = 2 * d->frameWidth;
- return QSize((6 * h) + f, (4 * h) + f);
-#endif
+ if (d->sizeAdjustPolicy == QAbstractScrollArea::AdjustIgnored)
+ return QSize(256, 192);
+
+ if (!d->sizeHint.isValid() || d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContents) {
+ const int f = 2 * d->frameWidth;
+ const QSize frame( f, f );
+ const QSize scrollbars(d->vbarpolicy == Qt::ScrollBarAlwaysOn ? d->vbar->sizeHint().width() : 0,
+ d->hbarpolicy == Qt::ScrollBarAlwaysOn ? d->hbar->sizeHint().height() : 0);
+ d->sizeHint = frame + scrollbars + viewportSizeHint();
+ }
+ return d->sizeHint;
+}
+
+/*!
+ \since 5.2
+ Returns the recommended size for the viewport.
+ The default implementation returns viewport()->sizeHint().
+ Note that the size is just the viewport's size, without any scroll bars visible.
+ */
+QSize QAbstractScrollArea::viewportSizeHint() const
+{
+ Q_D(const QAbstractScrollArea);
+ if (d->viewport) {
+ const QSize sh = d->viewport->sizeHint();
+ if (sh.isValid()) {
+ return sh;
+ }
+ }
+ const int h = qMax(10, fontMetrics().height());
+ return QSize(6 * h, 4 * h);
+}
+
+/*!
+ \since 5.2
+ \property QAbstractScrollArea::sizeAdjustPolicy
+ This property holds the policy describing how the size of the scroll area changes when the
+ size of the viewport changes.
+
+ The default policy is QAbstractScrollArea::AdjustIgnored.
+ Changing this property might actually resize the scrollarea.
+*/
+
+QAbstractScrollArea::SizeAdjustPolicy QAbstractScrollArea::sizeAdjustPolicy() const
+{
+ Q_D(const QAbstractScrollArea);
+ return d->sizeAdjustPolicy;
+}
+
+void QAbstractScrollArea::setSizeAdjustPolicy(SizeAdjustPolicy policy)
+{
+ Q_D(QAbstractScrollArea);
+ if (d->sizeAdjustPolicy == policy)
+ return;
+
+ d->sizeAdjustPolicy = policy;
+ d->sizeHint = QSize();
+ updateGeometry();
}
/*!
@@ -1559,16 +1633,6 @@ void QAbstractScrollArea::setupViewport(QWidget *viewport)
Q_UNUSED(viewport);
}
-/*!
- \internal
-
- This method is reserved for future use.
-*/
-QSize QAbstractScrollArea::viewportSizeHint() const
-{
- return QSize();
-}
-
QT_END_NAMESPACE
#include "moc_qabstractscrollarea.cpp"
diff --git a/src/widgets/widgets/qabstractscrollarea.h b/src/widgets/widgets/qabstractscrollarea.h
index ccf16b5e5c..fb9562db1b 100644
--- a/src/widgets/widgets/qabstractscrollarea.h
+++ b/src/widgets/widgets/qabstractscrollarea.h
@@ -56,13 +56,22 @@ class QAbstractScrollAreaPrivate;
class Q_WIDGETS_EXPORT QAbstractScrollArea : public QFrame
{
Q_OBJECT
+
+ Q_ENUMS(SizeAdjustPolicy)
Q_PROPERTY(Qt::ScrollBarPolicy verticalScrollBarPolicy READ verticalScrollBarPolicy WRITE setVerticalScrollBarPolicy)
Q_PROPERTY(Qt::ScrollBarPolicy horizontalScrollBarPolicy READ horizontalScrollBarPolicy WRITE setHorizontalScrollBarPolicy)
+ Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy)
public:
explicit QAbstractScrollArea(QWidget* parent=0);
~QAbstractScrollArea();
+ enum SizeAdjustPolicy {
+ AdjustIgnored,
+ AdjustToContentsOnFirstShow,
+ AdjustToContents
+ };
+
Qt::ScrollBarPolicy verticalScrollBarPolicy() const;
void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy);
QScrollBar *verticalScrollBar() const;
@@ -89,6 +98,9 @@ public:
virtual void setupViewport(QWidget *viewport);
+ SizeAdjustPolicy sizeAdjustPolicy() const;
+ void setSizeAdjustPolicy(SizeAdjustPolicy policy);
+
protected:
QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent = 0);
void setViewportMargins(int left, int top, int right, int bottom);
diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h
index 34d767fe29..3093c2f812 100644
--- a/src/widgets/widgets/qabstractscrollarea_p.h
+++ b/src/widgets/widgets/qabstractscrollarea_p.h
@@ -75,6 +75,10 @@ public:
QScrollBar *hbar, *vbar;
Qt::ScrollBarPolicy vbarpolicy, hbarpolicy;
+ bool shownOnce;
+ mutable QSize sizeHint;
+ QAbstractScrollArea::SizeAdjustPolicy sizeAdjustPolicy;
+
QWidget *viewport;
QWidget *cornerWidget;
QRect cornerPaintingRect;
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index afe8f1c3f4..bdd06da7fc 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -2086,6 +2086,20 @@ QString QComboBox::currentText() const
}
/*!
+ \property QComboBox::currentData
+ \brief the data for the current item
+ \since 5.2
+
+ By default, for an empty combo box or a combo box in which no current
+ item is set, this property contains an invalid QVariant.
+*/
+QVariant QComboBox::currentData(int role) const
+{
+ Q_D(const QComboBox);
+ return d->currentIndex.data(role);
+}
+
+/*!
Returns the text for the given \a index in the combobox.
*/
QString QComboBox::itemText(int index) const
diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h
index 2fafe79f7a..0002cd08cb 100644
--- a/src/widgets/widgets/qcombobox.h
+++ b/src/widgets/widgets/qcombobox.h
@@ -66,6 +66,7 @@ class Q_WIDGETS_EXPORT QComboBox : public QWidget
Q_PROPERTY(int count READ count)
Q_PROPERTY(QString currentText READ currentText WRITE setCurrentText NOTIFY currentTextChanged USER true)
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+ Q_PROPERTY(QVariant currentData READ currentData)
Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems)
Q_PROPERTY(int maxCount READ maxCount WRITE setMaxCount)
Q_PROPERTY(InsertPolicy insertPolicy READ insertPolicy WRITE setInsertPolicy)
@@ -167,8 +168,8 @@ public:
void setModelColumn(int visibleColumn);
int currentIndex() const;
-
QString currentText() const;
+ QVariant currentData(int role = Qt::UserRole) const;
QString itemText(int index) const;
QIcon itemIcon(int index) const;
diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp
index bc5d84e259..226969cdd1 100644
--- a/src/widgets/widgets/qdialogbuttonbox.cpp
+++ b/src/widgets/widgets/qdialogbuttonbox.cpp
@@ -669,6 +669,21 @@ QDialogButtonBox::QDialogButtonBox(Qt::Orientation orientation, QWidget *parent)
}
/*!
+ \since 5.2
+
+ Constructs a horizontal button box with the given \a parent, containing
+ the standard buttons specified by \a buttons.
+
+ \sa orientation, addButton()
+*/
+QDialogButtonBox::QDialogButtonBox(StandardButtons buttons, QWidget *parent)
+ : QWidget(*new QDialogButtonBoxPrivate(Qt::Horizontal), parent, 0)
+{
+ d_func()->initLayout();
+ d_func()->createStandardButtons(buttons);
+}
+
+/*!
Constructs a button box with the given \a orientation and \a parent, containing
the standard buttons specified by \a buttons.
diff --git a/src/widgets/widgets/qdialogbuttonbox.h b/src/widgets/widgets/qdialogbuttonbox.h
index 6715c590e2..d8e1a997d4 100644
--- a/src/widgets/widgets/qdialogbuttonbox.h
+++ b/src/widgets/widgets/qdialogbuttonbox.h
@@ -115,7 +115,8 @@ public:
QDialogButtonBox(QWidget *parent = 0);
QDialogButtonBox(Qt::Orientation orientation, QWidget *parent = 0);
- QDialogButtonBox(StandardButtons buttons, Qt::Orientation orientation = Qt::Horizontal,
+ explicit QDialogButtonBox(StandardButtons buttons, QWidget *parent = 0);
+ QDialogButtonBox(StandardButtons buttons, Qt::Orientation orientation,
QWidget *parent = 0);
~QDialogButtonBox();
diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp
index 5f929caf03..0b0efa2bdf 100644
--- a/src/widgets/widgets/qfontcombobox.cpp
+++ b/src/widgets/widgets/qfontcombobox.cpp
@@ -54,6 +54,88 @@
QT_BEGIN_NAMESPACE
+static QFontDatabase::WritingSystem writingSystemFromScript(QLocale::Script script)
+{
+ switch (script) {
+ case QLocale::ArabicScript:
+ return QFontDatabase::Arabic;
+ case QLocale::CyrillicScript:
+ return QFontDatabase::Cyrillic;
+ case QLocale::GurmukhiScript:
+ return QFontDatabase::Gurmukhi;
+ case QLocale::SimplifiedHanScript:
+ return QFontDatabase::SimplifiedChinese;
+ case QLocale::TraditionalHanScript:
+ return QFontDatabase::TraditionalChinese;
+ case QLocale::LatinScript:
+ return QFontDatabase::Latin;
+ case QLocale::ArmenianScript:
+ return QFontDatabase::Armenian;
+ case QLocale::BengaliScript:
+ return QFontDatabase::Bengali;
+ case QLocale::DevanagariScript:
+ return QFontDatabase::Devanagari;
+ case QLocale::GeorgianScript:
+ return QFontDatabase::Georgian;
+ case QLocale::GreekScript:
+ return QFontDatabase::Greek;
+ case QLocale::GujaratiScript:
+ return QFontDatabase::Gujarati;
+ case QLocale::HebrewScript:
+ return QFontDatabase::Hebrew;
+ case QLocale::JapaneseScript:
+ return QFontDatabase::Japanese;
+ case QLocale::KhmerScript:
+ return QFontDatabase::Khmer;
+ case QLocale::KannadaScript:
+ return QFontDatabase::Kannada;
+ case QLocale::KoreanScript:
+ return QFontDatabase::Korean;
+ case QLocale::LaoScript:
+ return QFontDatabase::Lao;
+ case QLocale::MalayalamScript:
+ return QFontDatabase::Malayalam;
+ case QLocale::MyanmarScript:
+ return QFontDatabase::Myanmar;
+ case QLocale::TamilScript:
+ return QFontDatabase::Tamil;
+ case QLocale::TeluguScript:
+ return QFontDatabase::Telugu;
+ case QLocale::ThaanaScript:
+ return QFontDatabase::Thaana;
+ case QLocale::ThaiScript:
+ return QFontDatabase::Thai;
+ case QLocale::TibetanScript:
+ return QFontDatabase::Tibetan;
+ case QLocale::SinhalaScript:
+ return QFontDatabase::Sinhala;
+ case QLocale::SyriacScript:
+ return QFontDatabase::Syriac;
+ case QLocale::OriyaScript:
+ return QFontDatabase::Oriya;
+ case QLocale::OghamScript:
+ return QFontDatabase::Ogham;
+ case QLocale::RunicScript:
+ return QFontDatabase::Runic;
+ case QLocale::NkoScript:
+ return QFontDatabase::Nko;
+ default:
+ return QFontDatabase::Any;
+ }
+}
+
+static QFontDatabase::WritingSystem writingSystemFromLocale()
+{
+ QStringList uiLanguages = QLocale::system().uiLanguages();
+ QLocale::Script script;
+ if (!uiLanguages.isEmpty())
+ script = QLocale(uiLanguages.at(0)).script();
+ else
+ script = QLocale::system().script();
+
+ return writingSystemFromScript(script);
+}
+
static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool *hasLatin)
{
QList<QFontDatabase::WritingSystem> writingSystems = QFontDatabase().writingSystems(font.family());
@@ -66,7 +148,22 @@ static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool
if (writingSystems.isEmpty())
return QFontDatabase::Any;
- QFontDatabase::WritingSystem system = writingSystems.last();
+ QFontDatabase::WritingSystem system = writingSystemFromLocale();
+
+ if (writingSystems.contains(system))
+ return system;
+
+ if (system == QFontDatabase::TraditionalChinese
+ && writingSystems.contains(QFontDatabase::SimplifiedChinese)) {
+ return QFontDatabase::SimplifiedChinese;
+ }
+
+ if (system == QFontDatabase::SimplifiedChinese
+ && writingSystems.contains(QFontDatabase::TraditionalChinese)) {
+ return QFontDatabase::TraditionalChinese;
+ }
+
+ system = writingSystems.last();
if (!*hasLatin) {
// we need to show something
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 70083d7267..a8b6b1a10c 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -351,7 +351,7 @@ void QLineEdit::setPlaceholderText(const QString& placeholderText)
Q_D(QLineEdit);
if (d->placeholderText != placeholderText) {
d->placeholderText = placeholderText;
- if (!hasFocus())
+ if (d->control->text().isEmpty())
update();
}
}
@@ -420,6 +420,96 @@ bool QLineEdit::hasFrame() const
return d->frame;
}
+/*!
+ \enum QLineEdit::ActionPosition
+
+ This enum type describes how a line edit should display the action widgets to be
+ added.
+
+ \value LeadingPosition The widget is displayed to the left of the text
+ when using layout direction \c Qt::LeftToRight or to
+ the right when using \c Qt::RightToLeft, respectively.
+
+ \value TrailingPosition The widget is displayed to the right of the text
+ when using layout direction \c Qt::LeftToRight or to
+ the left when using \c Qt::RightToLeft, respectively.
+
+ \sa addAction(), removeAction(), QWidget::layoutDirection
+
+ \since 5.2
+*/
+
+/*!
+ \fn void QLineEdit::addAction(QAction *action)
+ \overload
+ \internal
+*/
+
+/*!
+ \overload
+
+ Adds the \a action to the list of actions at the \a position.
+
+ \since 5.2
+*/
+
+void QLineEdit::addAction(QAction *action, ActionPosition position)
+{
+ Q_D(QLineEdit);
+ QWidget::addAction(action);
+ d->addAction(action, 0, position);
+}
+
+/*!
+ \overload
+
+ Creates a new action with the given \a icon at the \a position.
+
+ \since 5.2
+*/
+
+QAction *QLineEdit::addAction(const QIcon &icon, ActionPosition position)
+{
+ QAction *result = new QAction(icon, QString(), this);
+ addAction(result, position);
+ return result;
+}
+
+/*!
+ \property QLineEdit::clearButtonEnabled
+ \brief Whether the line edit displays a clear button when it is not empty.
+
+ If enabled, the line edit displays a trailing \e clear button when it contains
+ some text, otherwise the line edit does not show a clear button (the
+ default).
+
+ \sa addAction(), removeAction()
+ \since 5.2
+*/
+
+static const char clearButtonActionNameC[] = "_q_qlineeditclearaction";
+
+void QLineEdit::setClearButtonEnabled(bool enable)
+{
+ Q_D(QLineEdit);
+ if (enable == isClearButtonEnabled())
+ return;
+ if (enable) {
+ QAction *clearAction = new QAction(d->clearButtonIcon(), QString(), this);
+ clearAction->setObjectName(QLatin1String(clearButtonActionNameC));
+ d->addAction(clearAction, 0, QLineEdit::TrailingPosition, QLineEditPrivate::SideWidgetClearButton | QLineEditPrivate::SideWidgetFadeInWithText);
+ } else {
+ QAction *clearAction = findChild<QAction *>(QLatin1String(clearButtonActionNameC));
+ Q_ASSERT(clearAction);
+ removeAction(clearAction);
+ delete clearAction;
+ }
+}
+
+bool QLineEdit::isClearButtonEnabled() const
+{
+ return findChild<QAction *>(QLatin1String(clearButtonActionNameC));
+}
void QLineEdit::setFrame(bool enable)
{
@@ -606,7 +696,7 @@ QSize QLineEdit::sizeHint() const
+ d->topTextMargin + d->bottomTextMargin
+ d->topmargin + d->bottommargin;
int w = fm.width(QLatin1Char('x')) * 17 + 2*d->horizontalMargin
- + d->leftTextMargin + d->rightTextMargin
+ + d->effectiveLeftTextMargin() + d->effectiveRightTextMargin()
+ d->leftmargin + d->rightmargin; // "some"
QStyleOptionFrameV2 opt;
initStyleOption(&opt);
@@ -967,7 +1057,6 @@ void QLineEdit::setDragEnabled(bool b)
d->dragEnabled = b;
}
-
/*!
\property QLineEdit::cursorMoveStyle
\brief the movement style of cursor in this line edit
@@ -1350,8 +1439,11 @@ bool QLineEdit::event(QEvent * e)
|| style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
d->setCursorVisible(true);
}
+ } else if (e->type() == QEvent::ActionRemoved) {
+ d->removeAction(static_cast<QActionEvent *>(e));
+ } else if (e->type() == QEvent::Resize) {
+ d->positionSideWidgets();
}
-
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled()) {
if (e->type() == QEvent::EnterEditFocus) {
@@ -1777,9 +1869,9 @@ void QLineEdit::paintEvent(QPaintEvent *)
initStyleOption(&panel);
style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
- r.setX(r.x() + d->leftTextMargin);
+ r.setX(r.x() + d->effectiveLeftTextMargin());
r.setY(r.y() + d->topTextMargin);
- r.setRight(r.right() - d->rightTextMargin);
+ r.setRight(r.right() - d->effectiveRightTextMargin());
r.setBottom(r.bottom() - d->bottomTextMargin);
p.setClipRect(r);
@@ -1983,6 +2075,13 @@ void QLineEdit::contextMenuEvent(QContextMenuEvent *event)
}
}
+static inline void setActionIcon(QAction *action, const QString &name)
+{
+ const QIcon icon = QIcon::fromTheme(name);
+ if (!icon.isNull())
+ action->setIcon(icon);
+}
+
/*! This function creates the standard context menu which is shown
when the user clicks on the line edit with the right mouse
button. It is called from the default contextMenuEvent() handler.
@@ -1999,10 +2098,12 @@ QMenu *QLineEdit::createStandardContextMenu()
if (!isReadOnly()) {
action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo));
action->setEnabled(d->control->isUndoAvailable());
+ setActionIcon(action, QStringLiteral("edit-undo"));
connect(action, SIGNAL(triggered()), SLOT(undo()));
action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo));
action->setEnabled(d->control->isRedoAvailable());
+ setActionIcon(action, QStringLiteral("edit-redo"));
connect(action, SIGNAL(triggered()), SLOT(redo()));
popup->addSeparator();
@@ -2013,17 +2114,20 @@ QMenu *QLineEdit::createStandardContextMenu()
action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut));
action->setEnabled(!d->control->isReadOnly() && d->control->hasSelectedText()
&& d->control->echoMode() == QLineEdit::Normal);
+ setActionIcon(action, QStringLiteral("edit-cut"));
connect(action, SIGNAL(triggered()), SLOT(cut()));
}
action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy));
action->setEnabled(d->control->hasSelectedText()
&& d->control->echoMode() == QLineEdit::Normal);
+ setActionIcon(action, QStringLiteral("edit-copy"));
connect(action, SIGNAL(triggered()), SLOT(copy()));
if (!isReadOnly()) {
action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste));
action->setEnabled(!d->control->isReadOnly() && !QApplication::clipboard()->text().isEmpty());
+ setActionIcon(action, QStringLiteral("edit-paste"));
connect(action, SIGNAL(triggered()), SLOT(paste()));
}
#endif
@@ -2031,6 +2135,7 @@ QMenu *QLineEdit::createStandardContextMenu()
if (!isReadOnly()) {
action = popup->addAction(QLineEdit::tr("Delete"));
action->setEnabled(!d->control->isReadOnly() && !d->control->text().isEmpty() && d->control->hasSelectedText());
+ setActionIcon(action, QStringLiteral("edit-delete"));
connect(action, SIGNAL(triggered()), d->control, SLOT(_q_deleteSelected()));
}
@@ -2070,8 +2175,15 @@ void QLineEdit::changeEvent(QEvent *ev)
initStyleOption(&opt);
d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
}
+ d->m_iconSize = QSize();
update();
break;
+ case QEvent::LayoutDirectionChange:
+ foreach (const QLineEditPrivate::SideWidgetEntry &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:
break;
}
diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h
index e2b944314b..3d52863db2 100644
--- a/src/widgets/widgets/qlineedit.h
+++ b/src/widgets/widgets/qlineedit.h
@@ -59,12 +59,14 @@ class QCompleter;
class QStyleOptionFrame;
class QAbstractSpinBox;
class QDateTimeEdit;
+class QIcon;
+class QToolButton;
class Q_WIDGETS_EXPORT QLineEdit : public QWidget
{
Q_OBJECT
- Q_ENUMS(EchoMode)
+ Q_ENUMS(ActionPosition EchoMode)
Q_PROPERTY(QString inputMask READ inputMask WRITE setInputMask)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged USER true)
Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength)
@@ -83,8 +85,13 @@ class Q_WIDGETS_EXPORT QLineEdit : public QWidget
Q_PROPERTY(bool acceptableInput READ hasAcceptableInput)
Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
Q_PROPERTY(Qt::CursorMoveStyle cursorMoveStyle READ cursorMoveStyle WRITE setCursorMoveStyle)
-
+ Q_PROPERTY(bool clearButtonEnabled READ isClearButtonEnabled WRITE setClearButtonEnabled)
public:
+ enum ActionPosition {
+ LeadingPosition,
+ TrailingPosition
+ };
+
explicit QLineEdit(QWidget* parent=0);
explicit QLineEdit(const QString &, QWidget* parent=0);
~QLineEdit();
@@ -102,6 +109,9 @@ public:
void setFrame(bool);
bool hasFrame() const;
+ void setClearButtonEnabled(bool enable);
+ bool isClearButtonEnabled() const;
+
enum EchoMode { Normal, NoEcho, Password, PasswordEchoOnEdit };
EchoMode echoMode() const;
void setEchoMode(EchoMode);
@@ -164,6 +174,16 @@ public:
void getTextMargins(int *left, int *top, int *right, int *bottom) const;
QMargins textMargins() const;
+#ifdef Q_NO_USING_KEYWORD
+ inline void addAction(QAction *action)
+ { QWidget::addAction(action); }
+#else
+ using QWidget::addAction;
+#endif
+
+ void addAction(QAction *action, ActionPosition position);
+ QAction *addAction(const QIcon &icon, ActionPosition position);
+
public Q_SLOTS:
void setText(const QString &);
void clear();
@@ -240,6 +260,7 @@ private:
#endif
Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
Q_PRIVATE_SLOT(d_func(), void _q_updateNeeded(const QRect &))
+ Q_PRIVATE_SLOT(d_func(), void _q_textChanged(const QString &))
};
#endif // QT_NO_LINEEDIT
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 1999216e65..99d6d0b8d9 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -44,8 +44,10 @@
#ifndef QT_NO_LINEEDIT
+#include "qvariant.h"
#include "qabstractitemview.h"
#include "qdrag.h"
+#include "qwidgetaction.h"
#include "qclipboard.h"
#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible.h"
@@ -53,6 +55,7 @@
#ifndef QT_NO_IM
#include "qinputmethod.h"
#include "qlist.h"
+#include <qpropertyanimation.h>
#endif
QT_BEGIN_NAMESPACE
@@ -219,9 +222,9 @@ QRect QLineEditPrivate::adjustedContentsRect() const
QStyleOptionFrameV2 opt;
q->initStyleOption(&opt);
QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q);
- r.setX(r.x() + leftTextMargin);
+ r.setX(r.x() + effectiveLeftTextMargin());
r.setY(r.y() + topTextMargin);
- r.setRight(r.right() - rightTextMargin);
+ r.setRight(r.right() - effectiveRightTextMargin());
r.setBottom(r.bottom() - bottomTextMargin);
return r;
}
@@ -297,6 +300,170 @@ void QLineEditPrivate::drag()
#endif // QT_NO_DRAGANDDROP
+QLineEditIconButton::QLineEditIconButton(QWidget *parent)
+ : QToolButton(parent)
+ , m_opacity(0)
+{
+#ifndef QT_NO_CURSOR
+ setCursor(Qt::ArrowCursor);
+#endif
+ setFocusPolicy(Qt::NoFocus);
+}
+
+void QLineEditIconButton::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ // Note isDown should really use the active state but in most styles
+ // this has no proper feedback
+ QIcon::Mode state = QIcon::Disabled;
+ if (isEnabled())
+ state = isDown() ? QIcon::Selected : QIcon::Normal;
+ const QPixmap iconPixmap = icon().pixmap(QSize(IconButtonSize, IconButtonSize),
+ state, QIcon::Off);
+ QRect pixmapRect = QRect(0, 0, iconPixmap.width(), iconPixmap.height());
+ pixmapRect.moveCenter(rect().center());
+ painter.setOpacity(m_opacity);
+ painter.drawPixmap(pixmapRect, iconPixmap);
+}
+
+void QLineEditIconButton::setOpacity(qreal value)
+{
+ if (!qFuzzyCompare(m_opacity, value)) {
+ m_opacity = value;
+ update();
+ }
+}
+
+void QLineEditIconButton::startOpacityAnimation(qreal endValue)
+{
+ QPropertyAnimation *animation = new QPropertyAnimation(this, QByteArrayLiteral("opacity"));
+ animation->setDuration(160);
+ animation->setEndValue(endValue);
+ animation->start(QAbstractAnimation::DeleteWhenStopped);
+}
+
+void QLineEditPrivate::_q_textChanged(const QString &text)
+{
+ if (hasSideWidgets()) {
+ const int newTextSize = text.size();
+ if (!newTextSize || !lastTextSize) {
+ lastTextSize = newTextSize;
+ const bool fadeIn = newTextSize > 0;
+ foreach (const SideWidgetEntry &e, leadingSideWidgets) {
+ if (e.flags & SideWidgetFadeInWithText)
+ static_cast<QLineEditIconButton *>(e.widget)->animateShow(fadeIn);
+ }
+ foreach (const SideWidgetEntry &e, trailingSideWidgets) {
+ if (e.flags & SideWidgetFadeInWithText)
+ static_cast<QLineEditIconButton *>(e.widget)->animateShow(fadeIn);
+ }
+ }
+ }
+}
+
+QSize QLineEditPrivate::iconSize() const
+{
+ if (!m_iconSize.isValid()) // This might require style-specific handling (pixel metric).
+ m_iconSize = QSize(QLineEditIconButton::IconButtonSize + 6, QLineEditIconButton::IconButtonSize + 2);
+ return m_iconSize;
+}
+
+QIcon QLineEditPrivate::clearButtonIcon() const
+{
+ Q_Q(const QLineEdit);
+ QStyleOptionFrameV2 styleOption;
+ q->initStyleOption(&styleOption);
+ return QIcon(q->style()->standardPixmap(QStyle::SP_LineEditClearButton, &styleOption, q));
+}
+
+void QLineEditPrivate::positionSideWidgets()
+{
+ Q_Q(QLineEdit);
+ if (hasSideWidgets()) {
+ const QRect contentRect = q->rect();
+ const QSize iconSize = QLineEditPrivate::iconSize();
+ const int delta = QLineEditIconButton::IconMargin + iconSize.width();
+ QRect widgetGeometry(QPoint(QLineEditIconButton::IconMargin, (contentRect.height() - iconSize.height()) / 2), iconSize);
+ foreach (const SideWidgetEntry &e, leftSideWidgetList()) {
+ e.widget->setGeometry(widgetGeometry);
+ widgetGeometry.moveLeft(widgetGeometry.left() + delta);
+ }
+ widgetGeometry.moveLeft(contentRect.width() - iconSize.width() - QLineEditIconButton::IconMargin);
+ foreach (const SideWidgetEntry &e, rightSideWidgetList()) {
+ e.widget->setGeometry(widgetGeometry);
+ widgetGeometry.moveLeft(widgetGeometry.left() - delta);
+ }
+ }
+}
+
+QLineEditPrivate::PositionIndexPair QLineEditPrivate::findSideWidget(const QAction *a) const
+{
+ for (int i = 0; i < leadingSideWidgets.size(); ++i) {
+ if (a == leadingSideWidgets.at(i).action)
+ return PositionIndexPair(QLineEdit::LeadingPosition, i);
+ }
+ for (int i = 0; i < trailingSideWidgets.size(); ++i) {
+ if (a == trailingSideWidgets.at(i).action)
+ return PositionIndexPair(QLineEdit::TrailingPosition, i);
+ }
+ return PositionIndexPair(QLineEdit::LeadingPosition, -1);
+}
+
+QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineEdit::ActionPosition position, int flags)
+{
+ Q_Q(QLineEdit);
+ if (!newAction)
+ return 0;
+ QWidget *w = 0;
+ // Store flags about QWidgetAction here since removeAction() may be called from ~QAction,
+ // in which a qobject_cast<> no longer works.
+ if (QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(newAction)) {
+ if ((w = widgetAction->requestWidget(q)))
+ flags |= SideWidgetCreatedByWidgetAction;
+ }
+ if (!w) {
+ QLineEditIconButton *toolButton = new QLineEditIconButton(q);
+ toolButton->setIcon(newAction->icon());
+ toolButton->setOpacity(lastTextSize > 0 || !(flags & SideWidgetFadeInWithText) ? 1 : 0);
+ if (flags & SideWidgetClearButton)
+ QObject::connect(toolButton, SIGNAL(clicked()), q, SLOT(clear()));
+ toolButton->setDefaultAction(newAction);
+ w = toolButton;
+ }
+ if (!hasSideWidgets()) { // initial setup.
+ QObject::connect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString)));
+ lastTextSize = q->text().size();
+ }
+ // If there is a 'before' action, it takes preference
+ 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));
+ positionSideWidgets();
+ w->show();
+ return w;
+}
+
+void QLineEditPrivate::removeAction(const QActionEvent *e)
+{
+ Q_Q(QLineEdit);
+ QAction *action = e->action();
+ const PositionIndexPair positionIndex = findSideWidget(action);
+ if (positionIndex.second == -1)
+ return;
+ SideWidgetEntryList &list = positionIndex.first == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets;
+ SideWidgetEntry entry = list.takeAt(positionIndex.second);
+ if (entry.flags & SideWidgetCreatedByWidgetAction)
+ static_cast<QWidgetAction *>(entry.action)->releaseWidget(entry.widget);
+ else
+ delete entry.widget;
+ positionSideWidgets();
+ if (!hasSideWidgets()) // Last widget, remove connection
+ QObject::disconnect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString)));
+ q->update();
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h
index 4eb35b7dc6..8fe45972ff 100644
--- a/src/widgets/widgets/qlineedit_p.h
+++ b/src/widgets/widgets/qlineedit_p.h
@@ -58,7 +58,9 @@
#ifndef QT_NO_LINEEDIT
#include "private/qwidget_p.h"
#include "QtWidgets/qlineedit.h"
+#include "QtWidgets/qtoolbutton.h"
#include "QtGui/qtextlayout.h"
+#include "QtGui/qicon.h"
#include "QtWidgets/qstyleoption.h"
#include "QtCore/qbasictimer.h"
#include "QtWidgets/qcompleter.h"
@@ -69,16 +71,55 @@
QT_BEGIN_NAMESPACE
+// QLineEditIconButton: This is a simple helper class that represents clickable icons that fade in with text
+
+class QLineEditIconButton : public QToolButton
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
+public:
+ enum { IconMargin = 4, IconButtonSize = 16 };
+
+ explicit QLineEditIconButton(QWidget *parent = 0);
+
+ qreal opacity() const { return m_opacity; }
+ void setOpacity(qreal value);
+ void animateShow(bool visible) { startOpacityAnimation(visible ? 1.0 : 0.0); }
+
+protected:
+ void paintEvent(QPaintEvent *event);
+
+private:
+ void startOpacityAnimation(qreal endValue);
+
+ qreal m_opacity;
+};
+
class Q_AUTOTEST_EXPORT QLineEditPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QLineEdit)
public:
+ enum SideWidgetFlag {
+ SideWidgetFadeInWithText = 0x1,
+ SideWidgetCreatedByWidgetAction = 0x2,
+ SideWidgetClearButton = 0x4
+ };
+
+ struct SideWidgetEntry {
+ SideWidgetEntry(QWidget *w = 0, QAction *a = 0, int _flags = 0) : widget(w), action(a), flags(_flags) {}
+
+ QWidget *widget;
+ QAction *action;
+ int flags;
+ };
+ typedef QList<SideWidgetEntry> SideWidgetEntryList;
QLineEditPrivate()
: control(0), frame(1), contextMenuEnabled(1), cursorVisible(0),
dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0),
alignment(Qt::AlignLeading | Qt::AlignVCenter),
- leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0)
+ leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0),
+ lastTextSize(0)
{
}
@@ -145,15 +186,50 @@ public:
QBasicTimer dndTimer;
void drag();
#endif
+ void _q_textChanged(const QString &);
- int leftTextMargin;
+ int leftTextMargin; // use effectiveLeftTextMargin() in case of icon.
int topTextMargin;
- int rightTextMargin;
+ int rightTextMargin; // use effectiveRightTextMargin() in case of icon.
int bottomTextMargin;
QString placeholderText;
+
+ QWidget *addAction(QAction *newAction, QAction *before, QLineEdit::ActionPosition, int flags = 0);
+ void removeAction(const QActionEvent *e);
+ QSize iconSize() const;
+ QIcon clearButtonIcon() const;
+ void positionSideWidgets();
+ inline bool hasSideWidgets() const { return !leadingSideWidgets.isEmpty() || !trailingSideWidgets.isEmpty(); }
+ inline const SideWidgetEntryList &leftSideWidgetList() const
+ { return q_func()->layoutDirection() == Qt::LeftToRight ? leadingSideWidgets : trailingSideWidgets; }
+ inline const SideWidgetEntryList &rightSideWidgetList() const
+ { return q_func()->layoutDirection() == Qt::LeftToRight ? trailingSideWidgets : leadingSideWidgets; }
+
+ int effectiveLeftTextMargin() const;
+ int effectiveRightTextMargin() const;
+
+private:
+ typedef QPair<QLineEdit::ActionPosition, int> PositionIndexPair;
+
+ PositionIndexPair findSideWidget(const QAction *a) const;
+
+ SideWidgetEntryList leadingSideWidgets;
+ SideWidgetEntryList trailingSideWidgets;
+ int lastTextSize;
+ mutable QSize m_iconSize;
};
+inline int QLineEditPrivate::effectiveLeftTextMargin() const
+{
+ return leftTextMargin + leftSideWidgetList().size() * (QLineEditIconButton::IconMargin + iconSize().width());
+}
+
+inline int QLineEditPrivate::effectiveRightTextMargin() const
+{
+ return rightTextMargin + rightSideWidgetList().size() * (QLineEditIconButton::IconMargin + iconSize().width());
+}
+
#endif // QT_NO_LINEEDIT
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp
index 93c335c56b..2a6d4620d7 100644
--- a/src/widgets/widgets/qscrollarea.cpp
+++ b/src/widgets/widgets/qscrollarea.cpp
@@ -407,6 +407,18 @@ QSize QScrollArea::sizeHint() const
return sz.boundedTo(QSize(36 * h, 24 * h));
}
+/*!
+ \reimp
+ */
+QSize QScrollArea::viewportSizeHint() const
+{
+ Q_D(const QScrollArea);
+ if (d->widget) {
+ return d->resizable ? d->widget->sizeHint() : d->widget->size();
+ }
+ const int h = fontMetrics().height();
+ return QSize(6 * h, 4 * h);
+}
/*!
diff --git a/src/widgets/widgets/qscrollarea.h b/src/widgets/widgets/qscrollarea.h
index 576c9bc9e0..70af5fbbd7 100644
--- a/src/widgets/widgets/qscrollarea.h
+++ b/src/widgets/widgets/qscrollarea.h
@@ -69,6 +69,8 @@ public:
void setWidgetResizable(bool resizable);
QSize sizeHint() const;
+ QSize viewportSizeHint() const;
+
bool focusNextPrevChild(bool next);
Qt::Alignment alignment() const;
diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp
index e1e2723a2d..4ed91204cd 100644
--- a/src/widgets/widgets/qscrollbar.cpp
+++ b/src/widgets/widgets/qscrollbar.cpp
@@ -510,6 +510,11 @@ void QScrollBar::wheelEvent(QWheelEvent *event)
Q_D(QScrollBar);
if (d->scrollByDelta(event->orientation(), event->modifiers(), delta))
event->accept();
+
+ if (event->phase() == QWheelEvent::Started)
+ d->setTransient(false);
+ else if (event->phase() == QWheelEvent::Ended)
+ d->setTransient(true);
}
#endif
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 0ce5473ad8..bf4e130d4e 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -78,6 +78,8 @@ public:
q->setInputMethodHints(Qt::ImhDigitsOnly);
setLayoutItemMargins(QStyle::SE_SpinBoxLayoutItem);
}
+
+ int displayIntegerBase;
};
class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate
@@ -425,6 +427,38 @@ void QSpinBox::setRange(int minimum, int maximum)
}
/*!
+ \property QSpinBox::displayIntegerBase
+
+ \brief the base used to display the value of the spin box
+
+ The default displayIntegerBase value is 10.
+
+ \sa textFromValue(), valueFromText()
+ \since 5.2
+*/
+
+int QSpinBox::displayIntegerBase() const
+{
+ Q_D(const QSpinBox);
+ return d->displayIntegerBase;
+}
+
+void QSpinBox::setDisplayIntegerBase(int base)
+{
+ Q_D(QSpinBox);
+ // Falls back to base 10 on invalid bases (like QString)
+ if (base < 2 || base > 36) {
+ qWarning("QSpinBox::setDisplayIntegerBase: Invalid base (%d)", base);
+ base = 10;
+ }
+
+ if (base != d->displayIntegerBase) {
+ d->displayIntegerBase = base;
+ d->updateEdit();
+ }
+}
+
+/*!
This virtual function is used by the spin box whenever it needs to
display the given \a value. The default implementation returns a
string containing \a value printed in the standard way using
@@ -444,9 +478,18 @@ void QSpinBox::setRange(int minimum, int maximum)
QString QSpinBox::textFromValue(int value) const
{
- QString str = locale().toString(value);
- if (qAbs(value) >= 1000 || value == INT_MIN) {
- str.remove(locale().groupSeparator());
+ Q_D(const QSpinBox);
+ QString str;
+
+ if (d->displayIntegerBase != 10) {
+ str = QString::number(qAbs(value), d->displayIntegerBase);
+ if (value < 0)
+ str.prepend('-');
+ } else {
+ str = locale().toString(value);
+ if (qAbs(value) >= 1000 || value == INT_MIN) {
+ str.remove(locale().groupSeparator());
+ }
}
return str;
@@ -926,6 +969,7 @@ QSpinBoxPrivate::QSpinBoxPrivate()
minimum = QVariant((int)0);
maximum = QVariant((int)99);
value = minimum;
+ displayIntegerBase = 10;
singleStep = QVariant((int)1);
type = QVariant::Int;
}
@@ -1003,11 +1047,15 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100
} else {
bool ok = false;
- num = locale.toInt(copy, &ok);
- if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) {
- QString copy2 = copy;
- copy2.remove(locale.groupSeparator());
- num = locale.toInt(copy2, &ok);
+ if (displayIntegerBase != 10) {
+ num = copy.toInt(&ok, displayIntegerBase);
+ } else {
+ num = locale.toInt(copy, &ok);
+ if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) {
+ QString copy2 = copy;
+ copy2.remove(locale.groupSeparator());
+ num = locale.toInt(copy2, &ok);
+ }
}
QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num;
if (!ok) {
diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h
index 4963f87a1a..98e809e141 100644
--- a/src/widgets/widgets/qspinbox.h
+++ b/src/widgets/widgets/qspinbox.h
@@ -61,6 +61,7 @@ class Q_WIDGETS_EXPORT QSpinBox : public QAbstractSpinBox
Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
+ Q_PROPERTY(int displayIntegerBase READ displayIntegerBase WRITE setDisplayIntegerBase)
public:
explicit QSpinBox(QWidget *parent = 0);
@@ -87,6 +88,8 @@ public:
void setRange(int min, int max);
+ int displayIntegerBase() const;
+ void setDisplayIntegerBase(int base);
protected:
bool event(QEvent *event);
diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index 746c02e4e2..b2a0d3f8b8 100644
--- a/src/widgets/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
@@ -200,7 +200,7 @@ void QSplashScreen::repaint()
is kept up to date with what your application is doing (e.g.,
loading files).
- \sa Qt::Alignment, clearMessage()
+ \sa Qt::Alignment, clearMessage(), message()
*/
void QSplashScreen::showMessage(const QString &message, int alignment,
const QColor &color)
@@ -214,6 +214,20 @@ void QSplashScreen::showMessage(const QString &message, int alignment,
}
/*!
+ \since 5.2
+
+ Returns the message that is currently displayed on the splash screen.
+
+ \sa showMessage(), clearMessage()
+*/
+
+QString QSplashScreen::message() const
+{
+ Q_D(const QSplashScreen);
+ return d->currStatus;
+}
+
+/*!
Removes the message being displayed on the splash screen
\sa showMessage()
diff --git a/src/widgets/widgets/qsplashscreen.h b/src/widgets/widgets/qsplashscreen.h
index a1af8e45ef..e675c2e7af 100644
--- a/src/widgets/widgets/qsplashscreen.h
+++ b/src/widgets/widgets/qsplashscreen.h
@@ -63,6 +63,7 @@ public:
const QPixmap pixmap() const;
void finish(QWidget *w);
void repaint();
+ QString message() const;
public Q_SLOTS:
void showMessage(const QString &message, int alignment = Qt::AlignLeft,
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index b975035dcf..aa7677869c 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -329,6 +329,26 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const
\sa moveTab()
*/
+/*!
+ \fn void QTabBar::tabBarClicked(int index)
+
+ This signal is emitted when user clicks on a tab at an \a index.
+
+ \a index is the index of a clicked tab, or -1 if no tab is under the cursor.
+
+ \since 5.2
+*/
+
+/*!
+ \fn void QTabBar::tabBarDoubleClicked(int index)
+
+ This signal is emitted when the user double clicks on a tab at \a index.
+
+ \a index refers to the tab clicked, or -1 if no tab is under the cursor.
+
+ \since 5.2
+*/
+
int QTabBarPrivate::extraWidth() const
{
Q_Q(const QTabBar);
@@ -1703,11 +1723,37 @@ void QTabBarPrivate::moveTab(int index, int offset)
q_func()->update();
}
+
+/*!
+ \reimp
+*/
+void QTabBar::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ Q_D(QTabBar);
+
+ const QPoint pos = event->pos();
+ const bool isEventInCornerButtons = (!d->leftB->isHidden() && d->leftB->geometry().contains(pos))
+ || (!d->rightB->isHidden() && d->rightB->geometry().contains(pos));
+ if (!isEventInCornerButtons) {
+ const int index = tabAt(pos);
+ emit tabBarDoubleClicked(index);
+ }
+}
+
/*!\reimp
*/
void QTabBar::mousePressEvent(QMouseEvent *event)
{
Q_D(QTabBar);
+
+ const QPoint pos = event->pos();
+ const bool isEventInCornerButtons = (!d->leftB->isHidden() && d->leftB->geometry().contains(pos))
+ || (!d->rightB->isHidden() && d->rightB->geometry().contains(pos));
+ if (!isEventInCornerButtons) {
+ const int index = d->indexAtPos(pos);
+ emit tabBarClicked(index);
+ }
+
if (event->button() != Qt::LeftButton) {
event->ignore();
return;
diff --git a/src/widgets/widgets/qtabbar.h b/src/widgets/widgets/qtabbar.h
index 72c19ab520..1f7b8f6b03 100644
--- a/src/widgets/widgets/qtabbar.h
+++ b/src/widgets/widgets/qtabbar.h
@@ -173,6 +173,8 @@ Q_SIGNALS:
void currentChanged(int index);
void tabCloseRequested(int index);
void tabMoved(int from, int to);
+ void tabBarClicked(int index);
+ void tabBarDoubleClicked(int index);
protected:
virtual QSize tabSizeHint(int index) const;
@@ -186,6 +188,7 @@ protected:
void showEvent(QShowEvent *);
void hideEvent(QHideEvent *);
void paintEvent(QPaintEvent *);
+ void mouseDoubleClickEvent(QMouseEvent *);
void mousePressEvent (QMouseEvent *);
void mouseMoveEvent (QMouseEvent *);
void mouseReleaseEvent (QMouseEvent *);
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index 7468144146..8c6e70b8d7 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -138,6 +138,10 @@ public:
} *animation;
void startAnimation(QTabBarPrivate *priv, int duration) {
+ if (!priv->isAnimated()) {
+ priv->moveTabFinished(priv->tabList.indexOf(*this));
+ return;
+ }
if (!animation)
animation = new TabBarAnimation(this, priv);
animation->setStartValue(dragOffset);
@@ -162,6 +166,7 @@ public:
int indexAtPos(const QPoint &p) const;
+ inline bool isAnimated() const { Q_Q(const QTabBar); return q->style()->styleHint(QStyle::SH_Widget_Animate, 0, q); }
inline bool validIndex(int index) const { return index >= 0 && index < tabList.count(); }
void setCurrentNextEnabledIndex(int offset);
diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp
index 4df55e2537..9d14c01490 100644
--- a/src/widgets/widgets/qtabwidget.cpp
+++ b/src/widgets/widgets/qtabwidget.cpp
@@ -172,6 +172,26 @@ QT_BEGIN_NAMESPACE
\sa setTabsClosable()
*/
+/*!
+ \fn void QTabWidget::tabBarClicked(int index)
+
+ This signal is emitted when user clicks on a tab at an \a index.
+
+ \a index refers to the tab clicked, or -1 if no tab is under the cursor.
+
+ \since 5.2
+*/
+
+/*!
+ \fn void QTabWidget::tabBarDoubleClicked(int index)
+
+ This signal is emitted when the user double clicks on a tab at an \a index.
+
+ \a index is the index of a clicked tab, or -1 if no tab is under the cursor.
+
+ \since 5.2
+*/
+
class QTabWidgetPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QTabWidget)
@@ -693,6 +713,10 @@ void QTabWidget::setTabBar(QTabBar* tb)
this, SLOT(_q_showTab(int)));
connect(d->tabs, SIGNAL(tabMoved(int,int)),
this, SLOT(_q_tabMoved(int,int)));
+ connect(d->tabs, SIGNAL(tabBarClicked(int)),
+ this, SIGNAL(tabBarClicked(int)));
+ connect(d->tabs, SIGNAL(tabBarDoubleClicked(int)),
+ this, SIGNAL(tabBarDoubleClicked(int)));
if (d->tabs->tabsClosable())
connect(d->tabs, SIGNAL(tabCloseRequested(int)),
this, SIGNAL(tabCloseRequested(int)));
diff --git a/src/widgets/widgets/qtabwidget.h b/src/widgets/widgets/qtabwidget.h
index 1a1eb2ef2b..83c2e31d28 100644
--- a/src/widgets/widgets/qtabwidget.h
+++ b/src/widgets/widgets/qtabwidget.h
@@ -151,6 +151,8 @@ public Q_SLOTS:
Q_SIGNALS:
void currentChanged(int index);
void tabCloseRequested(int index);
+ void tabBarClicked(int index);
+ void tabBarDoubleClicked(int index);
protected:
virtual void tabInserted(int index);
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index 4b3bf6de65..4e0c682493 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -773,6 +773,35 @@ QTextDocument *QTextEdit::document() const
}
/*!
+ \since 5.2
+
+ \property QTextEdit::placeholderText
+ \brief the editor placeholder text
+
+ Setting this property makes the editor display a grayed-out
+ placeholder text as long as the document() is empty.
+
+ By default, this property contains an empty string.
+
+ \sa document()
+*/
+QString QTextEdit::placeholderText() const
+{
+ Q_D(const QTextEdit);
+ return d->placeholderText;
+}
+
+void QTextEdit::setPlaceholderText(const QString &placeholderText)
+{
+ Q_D(QTextEdit);
+ if (d->placeholderText != placeholderText) {
+ d->placeholderText = placeholderText;
+ if (d->control->document()->isEmpty())
+ d->viewport->update();
+ }
+}
+
+/*!
Sets the visible \a cursor.
*/
void QTextEdit::setTextCursor(const QTextCursor &cursor)
@@ -1499,6 +1528,13 @@ void QTextEdit::paintEvent(QPaintEvent *e)
Q_D(QTextEdit);
QPainter p(d->viewport);
d->paint(&p, e);
+ if (!d->placeholderText.isEmpty() && d->control->document()->isEmpty()) {
+ QColor col = palette().text().color();
+ col.setAlpha(128);
+ p.setPen(col);
+ const int margin = int(document()->documentMargin());
+ p.drawText(d->viewport->rect().adjusted(margin, margin, -margin, -margin), Qt::AlignTop | Qt::TextWordWrap, d->placeholderText);
+ }
}
void QTextEditPrivate::_q_currentCharFormatChanged(const QTextCharFormat &fmt)
diff --git a/src/widgets/widgets/qtextedit.h b/src/widgets/widgets/qtextedit.h
index e1471848e7..06ec5fb889 100644
--- a/src/widgets/widgets/qtextedit.h
+++ b/src/widgets/widgets/qtextedit.h
@@ -85,6 +85,7 @@ class Q_WIDGETS_EXPORT QTextEdit : public QAbstractScrollArea
Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
Q_PROPERTY(QTextDocument *document READ document WRITE setDocument DESIGNABLE false)
+ Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
public:
enum LineWrapMode {
NoWrap,
@@ -108,6 +109,9 @@ public:
void setDocument(QTextDocument *document);
QTextDocument *document() const;
+ void setPlaceholderText(const QString &placeholderText);
+ QString placeholderText() const;
+
void setTextCursor(const QTextCursor &cursor);
QTextCursor textCursor() const;
diff --git a/src/widgets/widgets/qtextedit_p.h b/src/widgets/widgets/qtextedit_p.h
index 1ce68dc23e..daa6eb5ed0 100644
--- a/src/widgets/widgets/qtextedit_p.h
+++ b/src/widgets/widgets/qtextedit_p.h
@@ -130,6 +130,8 @@ public:
QString anchorToScrollToWhenVisible;
+ QString placeholderText;
+
#ifdef QT_KEYPAD_NAVIGATION
QBasicTimer deleteAllTimer;
#endif
diff --git a/src/widgets/widgets/qwidgetanimator.cpp b/src/widgets/widgets/qwidgetanimator.cpp
index bbd96ca29a..1209ade536 100644
--- a/src/widgets/widgets/qwidgetanimator.cpp
+++ b/src/widgets/widgets/qwidgetanimator.cpp
@@ -91,24 +91,28 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo
QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size());
#ifndef QT_NO_ANIMATION
- AnimationMap::const_iterator it = m_animation_map.constFind(widget);
- if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
- return;
+ //If the QStyle has animations, animate
+ if (widget->style()->styleHint(QStyle::SH_Widget_Animate, 0, widget)) {
+ AnimationMap::const_iterator it = m_animation_map.constFind(widget);
+ if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
+ return;
- QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry", widget);
- anim->setDuration(animate ? 200 : 0);
- anim->setEasingCurve(QEasingCurve::InOutQuad);
- anim->setEndValue(final_geometry);
- m_animation_map[widget] = anim;
- connect(anim, SIGNAL(finished()), SLOT(animationFinished()));
- anim->start(QPropertyAnimation::DeleteWhenStopped);
-#else
+ QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry", widget);
+ anim->setDuration(animate ? 200 : 0);
+ anim->setEasingCurve(QEasingCurve::InOutQuad);
+ anim->setEndValue(final_geometry);
+ m_animation_map[widget] = anim;
+ connect(anim, SIGNAL(finished()), SLOT(animationFinished()));
+ anim->start(QPropertyAnimation::DeleteWhenStopped);
+ } else
+#endif //QT_NO_ANIMATION
+ {
//we do it in one shot
widget->setGeometry(final_geometry);
#ifndef QT_NO_MAINWINDOW
m_mainWindowLayout->animationFinished(widget);
#endif //QT_NO_MAINWINDOW
-#endif //QT_NO_ANIMATION
+ }
}
bool QWidgetAnimator::animating() const
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 9212f942c5..d10001a305 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -427,7 +427,7 @@ bool QWidgetLineControl::fixup() // this function assumes that validate currentl
m_validator->fixup(textCopy);
if (m_validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) {
if (textCopy != m_text || cursorCopy != m_cursor)
- internalSetText(textCopy, cursorCopy);
+ internalSetText(textCopy, cursorCopy, false);
return true;
}
}
@@ -672,7 +672,7 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e
m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
if (m_validInput) {
if (m_text != textCopy) {
- internalSetText(textCopy, cursorCopy);
+ internalSetText(textCopy, cursorCopy, false);
return true;
}
m_cursor = cursorCopy;
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index de06d4454a..0255183c87 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -2126,6 +2126,13 @@ void QWidgetTextControlPrivate::editFocusEvent(QEvent *e)
#endif
#ifndef QT_NO_CONTEXTMENU
+static inline void setActionIcon(QAction *action, const QString &name)
+{
+ const QIcon icon = QIcon::fromTheme(name);
+ if (!icon.isNull())
+ action->setIcon(icon);
+}
+
QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget *parent)
{
Q_D(QWidgetTextControl);
@@ -2145,17 +2152,21 @@ QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget
if (d->interactionFlags & Qt::TextEditable) {
a = menu->addAction(tr("&Undo") + ACCEL_KEY(QKeySequence::Undo), this, SLOT(undo()));
a->setEnabled(d->doc->isUndoAvailable());
+ setActionIcon(a, QStringLiteral("edit-undo"));
a = menu->addAction(tr("&Redo") + ACCEL_KEY(QKeySequence::Redo), this, SLOT(redo()));
a->setEnabled(d->doc->isRedoAvailable());
+ setActionIcon(a, QStringLiteral("edit-redo"));
menu->addSeparator();
a = menu->addAction(tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut), this, SLOT(cut()));
a->setEnabled(d->cursor.hasSelection());
+ setActionIcon(a, QStringLiteral("edit-cut"));
}
if (showTextSelectionActions) {
a = menu->addAction(tr("&Copy") + ACCEL_KEY(QKeySequence::Copy), this, SLOT(copy()));
a->setEnabled(d->cursor.hasSelection());
+ setActionIcon(a, QStringLiteral("edit-copy"));
}
if ((d->interactionFlags & Qt::LinksAccessibleByKeyboard)
@@ -2169,9 +2180,11 @@ QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget
#if !defined(QT_NO_CLIPBOARD)
a = menu->addAction(tr("&Paste") + ACCEL_KEY(QKeySequence::Paste), this, SLOT(paste()));
a->setEnabled(canPaste());
+ setActionIcon(a, QStringLiteral("edit-paste"));
#endif
a = menu->addAction(tr("Delete"), this, SLOT(_q_deleteSelected()));
a->setEnabled(d->cursor.hasSelection());
+ setActionIcon(a, QStringLiteral("edit-delete"));
}
diff --git a/src/xml/doc/qtxml.qdocconf b/src/xml/doc/qtxml.qdocconf
index 4e8cf34b0c..f9c847e022 100644
--- a/src/xml/doc/qtxml.qdocconf
+++ b/src/xml/doc/qtxml.qdocconf
@@ -40,3 +40,6 @@ exampledirs += ../../../examples/xml \
imagedirs += images \
../../../examples/xml/images
+
+navigation.landingpage = "Qt XML"
+navigation.cppclassespage = "Qt XML C++ Classes"
diff --git a/src/xml/doc/src/qtxml.qdoc b/src/xml/doc/src/qtxml.qdoc
index 5ffa0f7330..925e492880 100644
--- a/src/xml/doc/src/qtxml.qdoc
+++ b/src/xml/doc/src/qtxml.qdoc
@@ -29,6 +29,7 @@
\module QtXml
\title Qt XML C++ Classes
\ingroup modules
+ \qtvariable xml
\brief The Qt XML module provides C++ implementations of the SAX and DOM standards for XML.
diff --git a/tests/auto/android/runtests.pl b/tests/auto/android/runtests.pl
index 7bb6833859..55e1a224d8 100755
--- a/tests/auto/android/runtests.pl
+++ b/tests/auto/android/runtests.pl
@@ -79,6 +79,7 @@ GetOptions('h|help' => \$help
, 'ant=s' => \$ant_tool
, 'strip=s' => \$strip_tool
, 'readelf=s' => \$readelf_tool
+ , 'testcase=s' => \$testcase
) or pod2usage(2);
pod2usage(1) if $help;
pod2usage(-verbose => 2) if $man;
@@ -232,6 +233,7 @@ if ($deploy_qt)
print ("cp -L $_ $temp_dir/lib\n");
system("cp -L $_ $temp_dir/lib");
}
+ system("cp -L $android_ndk_dir/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/libgnustl_shared.so $temp_dir/lib");
system("cp -a plugins $temp_dir");
system("cp -a imports $temp_dir");
system("cp -a qml $temp_dir");
@@ -252,7 +254,14 @@ print "Building $tests_dir \n";
system("make distclean") if ($make_clean);
system("$qmake_path CONFIG-=QTDIR_build -r") == 0 or die "Can't run qmake\n"; #exec qmake
system("make -j$jobs") == 0 or warn "Can't build all tests\n"; #exec make
-my $testsFiles=`find . -name libtst_*.so`; # only tests
+
+my $testsFiles = "";
+if ($testcase) {
+ $testsFiles=`find . -name libtst_$testcase.so`; # only tests
+} else {
+ $testsFiles=`find . -name libtst_*.so`; # only tests
+}
+
foreach (split("\n",$testsFiles))
{
chomp; #remove white spaces
diff --git a/tests/auto/android/src/org/qtproject/qt5/android/QtActivity.java b/tests/auto/android/src/org/qtproject/qt5/android/QtActivity.java
index 6242f55488..ed190fdc1b 100644
--- a/tests/auto/android/src/org/qtproject/qt5/android/QtActivity.java
+++ b/tests/auto/android/src/org/qtproject/qt5/android/QtActivity.java
@@ -62,9 +62,9 @@ public class QtActivity extends Activity {
QtNative.loadQtLibraries(libs);
// start application
- final String envPaths = "NECESSITAS_API_LEVEL=2\tHOME=" + getDir("files", MODE_WORLD_WRITEABLE).getAbsolutePath() +
- "\tTMPDIR=" + getDir("files", MODE_WORLD_WRITEABLE).getAbsolutePath() +
- "\tCACHE_PATH=" + getDir("files", MODE_WORLD_WRITEABLE).getAbsolutePath();
+ final String envPaths = "NECESSITAS_API_LEVEL=2\tHOME=" + getDir("files", MODE_WORLD_WRITEABLE | MODE_WORLD_READABLE).getAbsolutePath() +
+ "\tTMPDIR=" + getDir("files", MODE_WORLD_WRITEABLE | MODE_WORLD_READABLE).getAbsolutePath() +
+ "\tCACHE_PATH=" + getDir("files", MODE_WORLD_WRITEABLE | MODE_WORLD_READABLE).getAbsolutePath();
if (environment != null && environment.length() > 0)
environment = envPaths + "\t" + environment;
else
@@ -102,6 +102,7 @@ public class QtActivity extends Activity {
}
if (getIntent().getExtras().containsKey("lib_name")) {
mainLib = getIntent().getExtras().getString("lib_name");
+ libraryList.add(mainLib);
int slash = mainLib.lastIndexOf("/");
if (slash >= 0) {
nativeLibDir = mainLib.substring(0, slash+1);
@@ -120,6 +121,7 @@ public class QtActivity extends Activity {
// TODO Auto-generated catch block
e.printStackTrace();
}
+ finish();
System.exit(0);
}
String[] libs = new String[libraryList.size()];
@@ -136,7 +138,7 @@ public class QtActivity extends Activity {
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
- getDir("files", MODE_WORLD_WRITEABLE);
+ getDir("files", MODE_WORLD_WRITEABLE | MODE_WORLD_READABLE);
requestWindowFeature(Window.FEATURE_NO_TITLE);
m_quitApp = true;
QtNative.setMainActivity(this);
diff --git a/tests/auto/android/src/org/qtproject/qt5/android/QtNative.java b/tests/auto/android/src/org/qtproject/qt5/android/QtNative.java
index d9995e3178..a61543d31a 100644
--- a/tests/auto/android/src/org/qtproject/qt5/android/QtNative.java
+++ b/tests/auto/android/src/org/qtproject/qt5/android/QtNative.java
@@ -164,7 +164,8 @@ public class QtNative extends Application
m_displayMetricsDesktopWidthPixels,
m_displayMetricsDesktopHeightPixels,
m_displayMetricsXDpi,
- m_displayMetricsYDpi);
+ m_displayMetricsYDpi,
+ 1.0);
startQtApplication(f.getAbsolutePath()+"\t"+params, environment);
m_started = true;
}
@@ -183,7 +184,7 @@ public class QtNative extends Application
synchronized (m_mainActivityMutex) {
if (m_started) {
- setDisplayMetrics(screenWidthPixels, screenHeightPixels, desktopWidthPixels, desktopHeightPixels, XDpi, YDpi);
+ setDisplayMetrics(screenWidthPixels, screenHeightPixels, desktopWidthPixels, desktopHeightPixels, XDpi, YDpi, 1.0);
} else {
m_displayMetricsScreenWidthPixels = screenWidthPixels;
m_displayMetricsScreenHeightPixels = screenHeightPixels;
@@ -379,8 +380,12 @@ public class QtNative extends Application
// screen methods
public static native void setDisplayMetrics(int screenWidthPixels,
- int screenHeightPixels, int desktopWidthPixels,
- int desktopHeightPixels, double XDpi, double YDpi);
+ int screenHeightPixels,
+ int desktopWidthPixels,
+ int desktopHeightPixels,
+ double XDpi,
+ double YDpi,
+ double scaledDensity);
public static native void handleOrientationChanged(int newOrientation);
// screen methods
diff --git a/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp
index 1f57e38b44..4fcc46efab 100644
--- a/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp
+++ b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp
@@ -361,7 +361,7 @@ void tst_QIpAddress::parseIp6()
#endif
Ip6 result;
- bool ok = QIPAddressUtils::parseIp6(result.u8, address.constBegin(), address.constEnd());
+ bool ok = QIPAddressUtils::parseIp6(result.u8, address.constBegin(), address.constEnd()) == 0;
QVERIFY(ok);
QCOMPARE(result, expected);
}
@@ -441,7 +441,7 @@ void tst_QIpAddress::invalidParseIp6()
#endif
Ip6 result;
- bool ok = QIPAddressUtils::parseIp6(result.u8, address.constBegin(), address.constEnd());
+ bool ok = QIPAddressUtils::parseIp6(result.u8, address.constBegin(), address.constEnd()) == 0;
QVERIFY(!ok);
}
diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
index f94c8eac4f..501dde1ba5 100644
--- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
+++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
@@ -166,7 +166,7 @@ void tst_qstandardpaths::testCustomLocations()
void tst_qstandardpaths::enableTestMode()
{
QVERIFY(!QStandardPaths::isTestModeEnabled());
- QStandardPaths::enableTestMode(true);
+ QStandardPaths::setTestModeEnabled(true);
QVERIFY(QStandardPaths::isTestModeEnabled());
#ifdef Q_XDG_PLATFORM
@@ -204,7 +204,7 @@ void tst_qstandardpaths::enableTestMode()
// On Windows, what should "Program Files" become, in test mode?
//testLocations.insert(QStandardPaths::ApplicationsLocation, QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation));
- QStandardPaths::enableTestMode(false);
+ QStandardPaths::setTestModeEnabled(false);
for (LocationHash::const_iterator it = testLocations.constBegin(); it != testLocations.constEnd(); ++it)
QVERIFY2(QStandardPaths::writableLocation(it.key()) != it.value(), qPrintable(it.value()));
diff --git a/tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp b/tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp
index 40621957ce..db2a5b53fd 100644
--- a/tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp
+++ b/tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp
@@ -40,13 +40,11 @@
****************************************************************************/
-#include <QtCore/QCoreApplication>
#include <QtCore/QTextStream>
-#include <QtCore/QDebug>
+#include <stdio.h>
-int main(int argc, char **argv)
+int main(int, char**)
{
- QCoreApplication a(argc, argv);
- qDebug() << QTextStream(stdin).readAll();
+ fprintf(stderr, "%s\n", QTextStream(stdin).readAll().toLatin1().constData());
return 0;
}
diff --git a/tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp b/tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp
index e36a2aeda8..cb4e75c6a2 100644
--- a/tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp
+++ b/tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp
@@ -40,17 +40,16 @@
****************************************************************************/
-#include <QtCore/QCoreApplication>
#include <QtCore/QTextStream>
+#include <stdio.h>
-int main(int argc, char **argv)
+int main(int, char**)
{
- QCoreApplication a(argc, argv);
QTextStream qin(stdin);
if (!qin.atEnd()) {
- int a, b, c;
- qin >> a >> b >> c;
- qDebug("%d %d %d", a, b, c);
+ int a, b, c;
+ qin >> a >> b >> c;
+ fprintf(stderr, "%d %d %d\n", a, b, c);
}
return 0;
}
diff --git a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp
index 56c07f1590..c19e80bff3 100644
--- a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp
@@ -1425,8 +1425,7 @@ void tst_QTextStream::readAllFromStdin()
stdinProcess.closeWriteChannel();
QVERIFY(stdinProcess.waitForFinished(5000));
- QChar quoteChar('"');
- QCOMPARE(stream.readAll(), QString::fromLatin1("%1hello world%2 \n").arg(quoteChar).arg(quoteChar));
+ QCOMPARE(stream.readAll(), QString::fromLatin1("hello world\n"));
}
// ------------------------------------------------------------------------------
diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp
index 2a506ef8e2..2817e6d22c 100644
--- a/tests/auto/corelib/io/qurl/tst_qurl.cpp
+++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp
@@ -111,6 +111,8 @@ private slots:
void percentEncoding();
void swap();
void symmetry();
+ void ipvfuture_data();
+ void ipvfuture();
void ipv6_data();
void ipv6();
void ipv6_2_data();
@@ -160,6 +162,8 @@ private slots:
void binaryData();
void fromUserInput_data();
void fromUserInput();
+ void fileName_data();
+ void fileName();
void isEmptyForEncodedUrl();
void toEncodedNotUsingUninitializedPath();
void emptyAuthorityRemovesExistingAuthority();
@@ -291,6 +295,8 @@ void tst_QUrl::comparison()
QVERIFY(url1 == url2);
QVERIFY(!(url1 < url2));
QVERIFY(!(url2 < url1));
+ QVERIFY(url1.matches(url2, QUrl::None));
+ QVERIFY(url1.matches(url2, QUrl::StripTrailingSlash));
// 6.2.2 Syntax-based Normalization
QUrl url3 = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D");
@@ -298,6 +304,20 @@ void tst_QUrl::comparison()
QEXPECT_FAIL("", "Normalization not implemented, will probably not be implemented like this", Continue);
QCOMPARE(url3, url4);
+ QUrl url3bis = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D/");
+ QUrl url3bisNoSlash = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D");
+ QUrl url4bis = QUrl::fromEncoded("example://a/.//b/../b/c//%7Bfoo%7D/");
+ QCOMPARE(url4bis.adjusted(QUrl::NormalizePathSegments), url3bis);
+ QCOMPARE(url4bis.adjusted(QUrl::NormalizePathSegments | QUrl::StripTrailingSlash), url3bisNoSlash);
+ QVERIFY(url3bis.matches(url4bis, QUrl::NormalizePathSegments));
+ QVERIFY(!url3bisNoSlash.matches(url4bis, QUrl::NormalizePathSegments));
+ QVERIFY(url3bisNoSlash.matches(url4bis, QUrl::NormalizePathSegments | QUrl::StripTrailingSlash));
+
+ QUrl url4EncodedDots = QUrl("example://a/.//b/%2E%2E%2F/b/c/");
+ QCOMPARE(QString::fromLatin1(url4EncodedDots.toEncoded()), QString::fromLatin1("example://a/.//b/..%2F/b/c/"));
+ QCOMPARE(url4EncodedDots.toString(), QString("example://a/.//b/..%2F/b/c/"));
+ QCOMPARE(url4EncodedDots.adjusted(QUrl::NormalizePathSegments).toString(), QString("example://a/b/..%2F/b/c/"));
+
// 6.2.2.1 Make sure hexdecimal characters in percent encoding are
// treated case-insensitively
QUrl url5;
@@ -312,6 +332,59 @@ void tst_QUrl::comparison()
url8.setEncodedQuery("a=c");
QVERIFY(url7 != url8);
QVERIFY(url7 < url8);
+
+ // Trailing slash difference
+ QUrl url9("http://qt-project.org/path/");
+ QUrl url9NoSlash("http://qt-project.org/path");
+ QVERIFY(!(url9 == url9NoSlash));
+ QVERIFY(!url9.matches(url9NoSlash, QUrl::None));
+ QVERIFY(url9.matches(url9NoSlash, QUrl::StripTrailingSlash));
+
+ // RemoveFilename
+ QUrl url10("http://qt-project.org/file");
+ QUrl url10bis("http://qt-project.org/otherfile");
+ QVERIFY(!(url10 == url10bis));
+ QVERIFY(!url10.matches(url10bis, QUrl::None));
+ QVERIFY(!url10.matches(url10bis, QUrl::StripTrailingSlash));
+ QVERIFY(url10.matches(url10bis, QUrl::RemoveFilename));
+
+ // RemoveAuthority
+ QUrl authUrl1("x://host/a/b");
+ QUrl authUrl2("x://host/a/");
+ QUrl authUrl3("x:/a/b");
+ QVERIFY(authUrl1.matches(authUrl2, QUrl::RemoveFilename));
+ QCOMPARE(authUrl1.adjusted(QUrl::RemoveAuthority), authUrl3.adjusted(QUrl::RemoveAuthority));
+ QVERIFY(authUrl1.matches(authUrl3, QUrl::RemoveAuthority));
+ QCOMPARE(authUrl2.adjusted(QUrl::RemoveAuthority | QUrl::RemoveFilename), authUrl3.adjusted(QUrl::RemoveAuthority | QUrl::RemoveFilename));
+ QVERIFY(authUrl2.matches(authUrl3, QUrl::RemoveAuthority | QUrl::RemoveFilename));
+ QVERIFY(authUrl3.matches(authUrl2, QUrl::RemoveAuthority | QUrl::RemoveFilename));
+
+ QUrl hostUrl1("file:/foo");
+ QUrl hostUrl2("file:///foo");
+ QVERIFY(hostUrl1 == hostUrl2);
+ QVERIFY(hostUrl1.matches(hostUrl2, QUrl::None));
+ QVERIFY(hostUrl1.matches(hostUrl2, QUrl::RemoveAuthority));
+
+ // RemovePassword
+ QUrl passUrl1("http://user:pass@host/");
+ QUrl passUrl2("http://user:PASS@host/");
+ QVERIFY(!(passUrl1 == passUrl2));
+ QVERIFY(passUrl1 != passUrl2);
+ QVERIFY(!passUrl1.matches(passUrl2, QUrl::None));
+ QVERIFY(passUrl1.matches(passUrl2, QUrl::RemovePassword));
+
+ // RemoveQuery, RemoveFragment
+ QUrl queryFragUrl1("http://host/file?query#fragment");
+ QUrl queryFragUrl2("http://host/file?q2#f2");
+ QUrl queryFragUrl3("http://host/file");
+ QVERIFY(!(queryFragUrl1 == queryFragUrl2));
+ QVERIFY(queryFragUrl1 != queryFragUrl2);
+ QVERIFY(!queryFragUrl1.matches(queryFragUrl2, QUrl::None));
+ QVERIFY(!queryFragUrl1.matches(queryFragUrl2, QUrl::RemoveQuery));
+ QVERIFY(!queryFragUrl1.matches(queryFragUrl2, QUrl::RemoveFragment));
+ QVERIFY(queryFragUrl1.matches(queryFragUrl2, QUrl::RemoveQuery | QUrl::RemoveFragment));
+ QVERIFY(queryFragUrl1.matches(queryFragUrl3, QUrl::RemoveQuery | QUrl::RemoveFragment));
+ QVERIFY(queryFragUrl3.matches(queryFragUrl1, QUrl::RemoveQuery | QUrl::RemoveFragment));
}
void tst_QUrl::comparison2_data()
@@ -685,8 +758,8 @@ void tst_QUrl::setUrl()
QVERIFY(url.isValid());
QCOMPARE(url.scheme(), QString("data"));
QCOMPARE(url.host(), QString());
- QCOMPARE(url.path(), QString("text/javascript,d5 = 'five\\u0027s';"));
- QCOMPARE(url.encodedPath().constData(), "text/javascript,d5%20=%20'five%5Cu0027s';");
+ QCOMPARE(url.path(), QString("text/javascript,d5 %3D 'five\\u0027s'%3B"));
+ QCOMPARE(url.encodedPath().constData(), "text/javascript,d5%20%3D%20'five%5Cu0027s'%3B");
}
{
@@ -946,8 +1019,12 @@ void tst_QUrl::toString()
QFETCH(uint, options);
QFETCH(QString, string);
+ QUrl::FormattingOptions opt(options);
+
QUrl url(urlString);
- QCOMPARE(url.toString(QUrl::FormattingOptions(options)), string);
+ QCOMPARE(url.toString(opt), string);
+
+ QCOMPARE(url.adjusted(opt).toString(), string);
}
void tst_QUrl::toAndFromStringList_data()
@@ -1498,17 +1575,17 @@ void tst_QUrl::relative()
void tst_QUrl::percentEncoding_data()
{
+ // This test is limited. It's superseded by componentEncodings below
QTest::addColumn<QString>("original");
QTest::addColumn<QByteArray>("encoded");
QTest::newRow("test_01") << QString::fromLatin1("sdfsdf") << QByteArray("sdfsdf");
QTest::newRow("test_02") << QString::fromUtf8("æss") << QByteArray("%C3%A6ss");
- // not unreserved or reserved
- QTest::newRow("test_03") << QString::fromLatin1("{}") << QByteArray("%7B%7D");
}
void tst_QUrl::percentEncoding()
{
+ // This test is limited. It's superseded by componentEncodings below
QFETCH(QString, original);
QFETCH(QByteArray, encoded);
@@ -1583,21 +1660,83 @@ void tst_QUrl::symmetry()
{
QString urlString = QString::fromLatin1("http://desktop:33326/upnp/{32f525a6-6f31-426e-91ca-01c2e6c2c57e}");
+ QString encodedUrlString = QString("http://desktop:33326/upnp/%7B32f525a6-6f31-426e-91ca-01c2e6c2c57e%7D");
QUrl urlPreviewList(urlString);
- QCOMPARE(urlPreviewList.toString(), urlString);
+ QCOMPARE(urlPreviewList.toString(), encodedUrlString);
QByteArray b = urlPreviewList.toEncoded();
- QCOMPARE(b.constData(), "http://desktop:33326/upnp/%7B32f525a6-6f31-426e-91ca-01c2e6c2c57e%7D");
- QCOMPARE(QUrl::fromEncoded(b).toString(), urlString);
- QCOMPARE(QUrl(b).toString(), urlString);
+ QCOMPARE(b.constData(), encodedUrlString.toLatin1().constData());
+ QCOMPARE(QUrl::fromEncoded(b).toString(), encodedUrlString);
+ QCOMPARE(QUrl(b).toString(), encodedUrlString);
}
{
QString urlString = QString::fromLatin1("http://desktop:53423/deviceDescription?uuid={7977c17b-00bf-4af9-894e-fed28573c3a9}");
+ QString encodedUrlString = QString("http://desktop:53423/deviceDescription?uuid=%7B7977c17b-00bf-4af9-894e-fed28573c3a9%7D");
QUrl urlPreviewList(urlString);
- QCOMPARE(urlPreviewList.toString(), urlString);
+ QCOMPARE(urlPreviewList.toString(), encodedUrlString);
QByteArray b = urlPreviewList.toEncoded();
- QCOMPARE(b.constData(), "http://desktop:53423/deviceDescription?uuid=%7B7977c17b-00bf-4af9-894e-fed28573c3a9%7D");
- QCOMPARE(QUrl::fromEncoded(b).toString(), urlString);
- QCOMPARE(QUrl(b).toString(), urlString);
+ QCOMPARE(b.constData(), encodedUrlString.toLatin1().constData());
+ QCOMPARE(QUrl::fromEncoded(b).toString(), encodedUrlString);
+ QCOMPARE(QUrl(b).toString(), encodedUrlString);
+ }
+}
+
+void tst_QUrl::ipvfuture_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<bool>("isValid");
+ QTest::addColumn<QString>("output");
+
+ // No one uses IPvFuture yet, so we have no clue what it might contain
+ // We're just testing that it can hold what the RFC says it should hold:
+ // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
+ QTest::newRow("missing-version-dot") << "x://[v]" << false;
+ QTest::newRow("missing-version") << "x://[v.]" << false;
+ QTest::newRow("missing-version-2") << "x://[v.1234]" << false;
+ QTest::newRow("missing-dot") << "x://[v7]" << false;
+ QTest::newRow("missing-dot-2") << "x://[v71234]" << false;
+ QTest::newRow("missing-data") << "x://[v7.]" << false;
+ QTest::newRow("non-hex-version") << "x://[vz.1234]" << false;
+
+ QTest::newRow("digit-ver") << "x://[v7.1]" << true << "x://[v7.1]";
+ QTest::newRow("lowercase-hex-ver") << "x://[va.1]" << true << "x://[vA.1]";
+ QTest::newRow("lowercase-hex-ver") << "x://[vA.1]" << true << "x://[vA.1]";
+
+ QTest::newRow("data-digits") << "x://[v7.1234]" << true << "x://[v7.1234]";
+ QTest::newRow("data-unreserved") << "x://[v7.hello~-WORLD_.com]" << true << "x://[v7.hello~-WORLD_.com]";
+ QTest::newRow("data-sub-delims-colon") << "x://[v7.!$&'()*+,;=:]" << true << "x://[v7.!$&'()*+,;=:]";
+
+ // we're using the tolerant parser
+ QTest::newRow("data-encoded-digits") << "x://[v7.%31%32%33%34]" << true << "x://[v7.1234]";
+ QTest::newRow("data-encoded-unreserved") << "x://[v7.%7E%2D%54%5f%2E]" << true << "x://[v7.~-T_.]";
+ QTest::newRow("data-encoded-sub-delims-colon") << "x://[v7.%21%24%26%27%28%29%2A%2B%2C%3B%3D%3A]" << true << "x://[v7.!$&'()*+,;=:]";
+
+ // should we test "[%76%37%2ex]" -> "[v7.x]" ?
+
+ QTest::newRow("data-invalid-space") << "x://[v7.%20]" << false;
+ QTest::newRow("data-invalid-control") << "x://[v7.\x7f]" << false;
+ QTest::newRow("data-invalid-other-1") << "x://[v7.{1234}]" << false;
+ QTest::newRow("data-invalid-other-2") << "x://[v7.<hello>]" << false;
+ QTest::newRow("data-invalid-unicode") << "x://[v7.æøå]" << false;
+ QTest::newRow("data-invalid-percent") << "x://[v7.%]" << false;
+ QTest::newRow("data-invalid-percent-percent") << "x://[v7.%25]" << false;
+}
+
+void tst_QUrl::ipvfuture()
+{
+ QFETCH(QString, input);
+ QFETCH(bool, isValid);
+
+ QUrl url(input);
+ if (isValid) {
+ QVERIFY2(url.isValid(), qPrintable(url.errorString()));
+
+ QFETCH(QString, output);
+ QCOMPARE(url.toString(), output);
+
+ QUrl url2(output);
+ QCOMPARE(url2, url);
+ } else {
+ QVERIFY(!url.isValid());
}
}
@@ -1641,6 +1780,9 @@ void tst_QUrl::ipv6_data()
QTest::newRow("case :,") << QString::fromLatin1("//[:,]") << false << "";
QTest::newRow("case ::bla") << QString::fromLatin1("//[::bla]") << false << "";
QTest::newRow("case v4-mapped") << "//[0:0:0:0:0:ffff:7f00:1]" << true << "//[::ffff:127.0.0.1]";
+
+ QTest::newRow("encoded-digit") << "//[::%31]" << true << "//[::1]";
+ QTest::newRow("encoded-colon") << "//[%3A%3A]" << true << "//[::]";
}
void tst_QUrl::ipv6()
@@ -1932,9 +2074,14 @@ void tst_QUrl::strictParser_data()
QTest::newRow("invalid-regname") << "http://bad<hostname>" << "Invalid hostname (contains invalid characters)";
QTest::newRow("invalid-regname-2") << "http://b%61d" << "Invalid hostname (contains invalid characters)";
QTest::newRow("invalid-ipv6") << "http://[:::]" << "Invalid IPv6 address";
+ QTest::newRow("invalid-ipv6-char1") << "http://[::g]" << "Invalid IPv6 address (character 'g' not permitted)";
+ QTest::newRow("invalid-ipv6-char2") << "http://[z::]" << "Invalid IPv6 address (character 'z' not permitted)";
QTest::newRow("invalid-ipvfuture-1") << "http://[v7]" << "Invalid IPvFuture address";
QTest::newRow("invalid-ipvfuture-2") << "http://[v7.]" << "Invalid IPvFuture address";
QTest::newRow("invalid-ipvfuture-3") << "http://[v789]" << "Invalid IPvFuture address";
+ QTest::newRow("invalid-ipvfuture-char1") << "http://[v7.^]" << "Invalid IPvFuture address";
+ QTest::newRow("invalid-encoded-ipv6") << "x://[%3a%3a%31]" << "Invalid IPv6 address";
+ QTest::newRow("invalid-encoded-ipvfuture") << "x://[v7.%7E%2D%54%5f%2E]" << "Invalid IPvFuture address";
QTest::newRow("unbalanced-brackets") << "http://[ff02::1" << "Expected ']' to match '[' in hostname";
// invalid hostnames happen in TolerantMode too
@@ -2035,35 +2182,22 @@ void tst_QUrl::tolerantParser()
url.setUrl("http://foo.bar/[image][1].jpg");
QVERIFY(url.isValid());
QVERIFY(!url.toString().isEmpty());
- QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
- QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
+ QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/[image][1].jpg"));
+ QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/[image][1].jpg"));
QCOMPARE(url.toString(), QString("http://foo.bar/[image][1].jpg"));
- url.setUrl("[].jpg");
- QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%5B%5D.jpg"));
- QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg"));
- QCOMPARE(url.toString(), QString("[].jpg"));
-
- url.setUrl("/some/[path]/[]");
- QCOMPARE(url.toString(QUrl::FullyEncoded), QString("/some/%5Bpath%5D/%5B%5D"));
- QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D"));
- QCOMPARE(url.toString(), QString("/some/[path]/[]"));
+ url.setUrl("http://foo.bar/%5Bimage%5D%5B1%5D.jpg");
+ QVERIFY(url.isValid());
+ QVERIFY(!url.toString().isEmpty());
+ QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
+ QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
+ QCOMPARE(url.toString(), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
url.setUrl("//[::56:56:56:56:56:56:56]");
QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]"));
QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]"));
QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]"));
- url.setUrl("//[::56:56:56:56:56:56:56]#[]");
- QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]#%5B%5D"));
- QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]#%5B%5D"));
- QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]#[]"));
-
- url.setUrl("//[::56:56:56:56:56:56:56]?[]");
- QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?[]"));
- QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]?[]"));
- QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]?[]"));
-
// invoke the tolerant parser's error correction
url.setUrl("%hello.com/f%");
QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%25hello.com/f%25"));
@@ -2076,38 +2210,24 @@ void tst_QUrl::tolerantParser()
url.setEncodedUrl("http://foo.bar/[image][1].jpg");
QVERIFY(url.isValid());
- QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
- QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
+ QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/[image][1].jpg"));
+ QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/[image][1].jpg"));
QCOMPARE(url.toString(), QString("http://foo.bar/[image][1].jpg"));
- url.setEncodedUrl("[].jpg");
- QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%5B%5D.jpg"));
- QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg"));
- QCOMPARE(url.toString(), QString("[].jpg"));
-
- url.setEncodedUrl("/some/[path]/[]");
- QCOMPARE(url.toString(QUrl::FullyEncoded), QString("/some/%5Bpath%5D/%5B%5D"));
- QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D"));
- QCOMPARE(url.toString(), QString("/some/[path]/[]"));
+ url.setEncodedUrl("http://foo.bar/%5Bimage%5D%5B1%5D.jpg");
+ QVERIFY(url.isValid());
+ QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
+ QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
+ QCOMPARE(url.toString(), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
url.setEncodedUrl("//[::56:56:56:56:56:56:56]");
QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]"));
QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]"));
- url.setEncodedUrl("//[::56:56:56:56:56:56:56]#[]");
- QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]#%5B%5D"));
- QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]#%5B%5D"));
- QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]#[]"));
-
- url.setEncodedUrl("//[::56:56:56:56:56:56:56]?[]");
- QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?[]"));
- QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]?[]"));
- QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]?[]"));
-
url.setEncodedUrl("data:text/css,div%20{%20border-right:%20solid;%20}");
QCOMPARE(url.toString(QUrl::FullyEncoded), QString("data:text/css,div%20%7B%20border-right:%20solid;%20%7D"));
QCOMPARE(url.toEncoded(), QByteArray("data:text/css,div%20%7B%20border-right:%20solid;%20%7D"));
- QCOMPARE(url.toString(), QString("data:text/css,div { border-right: solid; }"));
+ QCOMPARE(url.toString(), QString("data:text/css,div %7B border-right: solid; %7D"));
}
{
@@ -2386,7 +2506,7 @@ void tst_QUrl::setEncodedFragment_data()
QTest::newRow("basic test") << BA("http://www.kde.org") << BA("abc") << BA("http://www.kde.org#abc");
QTest::newRow("initial url has fragment") << BA("http://www.kde.org#old") << BA("new") << BA("http://www.kde.org#new");
QTest::newRow("encoded fragment") << BA("http://www.kde.org") << BA("a%20c") << BA("http://www.kde.org#a%20c");
- QTest::newRow("with #") << BA("http://www.kde.org") << BA("a#b") << BA("http://www.kde.org#a#b");
+ QTest::newRow("with #") << BA("http://www.kde.org") << BA("a#b") << BA("http://www.kde.org#a%23b"); // toString uses "a#b"
QTest::newRow("unicode") << BA("http://www.kde.org") << BA("\xc3\xa9") << BA("http://www.kde.org#%C3%A9");
QTest::newRow("binary") << BA("http://www.kde.org") << BA("\x00\xc0\x80", 3) << BA("http://www.kde.org#%00%C0%80");
}
@@ -2427,23 +2547,37 @@ void tst_QUrl::fromEncoded()
void tst_QUrl::stripTrailingSlash_data()
{
QTest::addColumn<QString>("url");
- QTest::addColumn<QString>("expected");
+ QTest::addColumn<QString>("expectedStrip"); // toString(Strip)
+ QTest::addColumn<QString>("expectedDir"); // toString(RemoveFilename)
+ QTest::addColumn<QString>("expectedDirStrip"); // toString(RemoveFilename|Strip)
- QTest::newRow("ftp no slash") << "ftp://ftp.de.kde.org/dir" << "ftp://ftp.de.kde.org/dir";
- QTest::newRow("ftp slash") << "ftp://ftp.de.kde.org/dir/" << "ftp://ftp.de.kde.org/dir";
- QTest::newRow("file slash") << "file:///dir/" << "file:///dir";
- QTest::newRow("file no slash") << "file:///dir/" << "file:///dir";
- QTest::newRow("file root") << "file:///" << "file:///";
- QTest::newRow("no path") << "remote://" << "remote://";
+ QTest::newRow("subdir no slash") << "ftp://kde.org/dir/subdir" << "ftp://kde.org/dir/subdir" << "ftp://kde.org/dir/" << "ftp://kde.org/dir";
+ QTest::newRow("ftp no slash") << "ftp://kde.org/dir" << "ftp://kde.org/dir" << "ftp://kde.org/" << "ftp://kde.org/";
+ QTest::newRow("ftp slash") << "ftp://kde.org/dir/" << "ftp://kde.org/dir" << "ftp://kde.org/dir/" << "ftp://kde.org/dir";
+ QTest::newRow("ftp_two_slashes") << "ftp://kde.org/dir//" << "ftp://kde.org/dir" << "ftp://kde.org/dir//" << "ftp://kde.org/dir";
+ QTest::newRow("file slash") << "file:///dir/" << "file:///dir" << "file:///dir/" << "file:///dir";
+ QTest::newRow("file no slash") << "file:///dir" << "file:///dir" << "file:///" << "file:///";
+ QTest::newRow("file root") << "file:///" << "file:///" << "file:///" << "file:///";
+ QTest::newRow("file_root_manyslashes") << "file://///" << "file:///" << "file://///" << "file:///";
+ QTest::newRow("no path") << "remote://" << "remote://" << "remote://" << "remote://";
}
void tst_QUrl::stripTrailingSlash()
{
QFETCH(QString, url);
- QFETCH(QString, expected);
+ QFETCH(QString, expectedStrip);
+ QFETCH(QString, expectedDir);
+ QFETCH(QString, expectedDirStrip);
QUrl u(url);
- QCOMPARE(u.toString(QUrl::StripTrailingSlash), expected);
+ QCOMPARE(u.toString(QUrl::StripTrailingSlash), expectedStrip);
+ QCOMPARE(u.toString(QUrl::RemoveFilename), expectedDir);
+ QCOMPARE(u.toString(QUrl::RemoveFilename | QUrl::StripTrailingSlash), expectedDirStrip);
+
+ // Same thing, using QUrl::adjusted()
+ QCOMPARE(u.adjusted(QUrl::StripTrailingSlash).toString(), expectedStrip);
+ QCOMPARE(u.adjusted(QUrl::RemoveFilename).toString(), expectedDir);
+ QCOMPARE(u.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).toString(), expectedDirStrip);
}
void tst_QUrl::hosts_data()
@@ -2729,6 +2863,43 @@ void tst_QUrl::fromUserInput()
QCOMPARE(url, guessUrlFromString);
}
+void tst_QUrl::fileName_data()
+{
+ QTest::addColumn<QString>("urlStr");
+ QTest::addColumn<QString>("expectedDirPath");
+ QTest::addColumn<QString>("expectedPrettyDecodedFileName");
+ QTest::addColumn<QString>("expectedFullyDecodedFileName");
+
+ QTest::newRow("fromDocu") << "http://qt-project.org/support/file.html"
+ << "/support/" << "file.html" << "file.html";
+ QTest::newRow("absoluteFile") << "file:///temp/tmp.txt"
+ << "/temp/" << "tmp.txt" << "tmp.txt";
+ QTest::newRow("absoluteDir") << "file:///temp/"
+ << "/temp/" << QString() << QString();
+ QTest::newRow("absoluteInRoot") << "file:///temp"
+ << "/" << "temp" << "temp";
+ QTest::newRow("relative") << "temp/tmp.txt"
+ << "temp/" << "tmp.txt" << "tmp.txt";
+ QTest::newRow("relativeNoSlash") << "tmp.txt"
+ << QString() << "tmp.txt" << "tmp.txt";
+ QTest::newRow("encoded") << "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)"
+ << "/specials/" << "Print To File (PDF%252FAcrobat)" << "Print To File (PDF%2FAcrobat)";
+}
+
+void tst_QUrl::fileName()
+{
+ QFETCH(QString, urlStr);
+ QFETCH(QString, expectedDirPath);
+ QFETCH(QString, expectedPrettyDecodedFileName);
+ QFETCH(QString, expectedFullyDecodedFileName);
+
+ QUrl url(urlStr);
+ QVERIFY(url.isValid());
+ QCOMPARE(url.adjusted(QUrl::RemoveFilename).path(), expectedDirPath);
+ QCOMPARE(url.fileName(QUrl::PrettyDecoded), expectedPrettyDecodedFileName);
+ QCOMPARE(url.fileName(QUrl::FullyDecoded), expectedFullyDecodedFileName);
+}
+
// This is a regression test for a previously fixed bug where isEmpty didn't
// work for an encoded URL that was yet to be decoded. The test checks that
// isEmpty works for an encoded URL both after and before decoding.
@@ -2866,7 +3037,8 @@ void tst_QUrl::effectiveTLDs()
{
QFETCH(QUrl, domain);
QFETCH(QString, TLD);
- QCOMPARE(domain.topLevelDomain(), TLD);
+ QCOMPARE(domain.topLevelDomain(QUrl::PrettyDecoded), TLD);
+ QCOMPARE(domain.topLevelDomain(QUrl::FullyDecoded), TLD);
}
void tst_QUrl::lowercasesScheme()
@@ -2950,19 +3122,25 @@ void tst_QUrl::componentEncodings_data()
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
// / "*" / "+" / "," / ";" / "="
- // like the unreserved, these are decoded everywhere
- // don't test in query because they might remain encoded
- QTest::newRow("decoded-subdelims") << QUrl("x://%21%24%26:%27%28%29@host/%2a%2b%2c#%3b%3d")
+ // these are always left alone
+ QTest::newRow("decoded-subdelims") << QUrl("x://!$&:'()@host/*+,?$=(+)#;=")
<< int(QUrl::FullyEncoded)
<< "!$&" << "'()" << "!$&:'()"
<< "host" << "!$&:'()@host"
- << "/*+," << "" << ";="
- << "x://!$&:'()@host/*+,#;=";
+ << "/*+," << "$=(+)" << ";="
+ << "x://!$&:'()@host/*+,?$=(+)#;=";
+ QTest::newRow("encoded-subdelims") << QUrl("x://%21%24%26:%27%28%29@host/%2a%2b%2c?%26=%26&%3d=%3d#%3b%3d")
+ << MostDecoded
+ << "%21%24%26" << "%27%28%29" << "%21%24%26:%27%28%29"
+ << "host" << "%21%24%26:%27%28%29@host"
+ << "/%2A%2B%2C" << "%26=%26&%3D=%3D" << "%3B%3D"
+ << "x://%21%24%26:%27%28%29@host/%2A%2B%2C?%26=%26&%3D=%3D#%3B%3D";
// gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
// these are the separators between fields
- // they must appear encoded in certain positions, no exceptions
- // in other positions, they can appear decoded, so they always do
+ // they must appear encoded in certain positions in the full URL, no exceptions
+ // when in those positions, they appear decoded in the isolated parts
+ // in other positions and the other delimiters are always left untransformed
// 1) test the delimiters that must appear encoded
// (if they were decoded, they'd would change the URL parsing)
QTest::newRow("encoded-gendelims-changing") << QUrl("x://%5b%3a%2f%3f%23%40%5d:%5b%2f%3f%23%40%5d@host/%2f%3f%23?%23")
@@ -2972,32 +3150,21 @@ void tst_QUrl::componentEncodings_data()
<< "/%2F?#" << "#" << ""
<< "x://%5B%3A%2F%3F%23%40%5D:%5B%2F%3F%23%40%5D@host/%2F%3F%23?%23";
- // 2) test the delimiters that may appear decoded and would not change the meaning
- // and test that %2f is *not* decoded to a slash in the path
- // don't test the query because in this mode it doesn't transform anything
- QTest::newRow("decoded-gendelims-unchanging") << QUrl("x://:%3a@host/%2f%3a%40#%23%3a%2f%3f%40")
+ // 2) test that the other delimiters remain decoded
+ QTest::newRow("decoded-gendelims-unchanging") << QUrl("x://::@host/:@/[]?:/?@[]?#:/?@[]")
<< int(QUrl::FullyEncoded)
<< "" << ":" << "::"
<< "host" << "::@host"
- << "/%2F:@" << "" << "#:/?@"
- << "x://::@host/%2F:@##:/?@";
-
- // 3) test "[" and "]". Even though they are not ambiguous in the path, query or fragment
- // the RFC does not allow them to appear there decoded. QUrl adheres strictly in FullyEncoded mode
- QTest::newRow("encoded-square-brackets") << QUrl("x:/[]#[]")
- << int(QUrl::FullyEncoded)
- << "" << "" << ""
- << "" << ""
- << "/%5B%5D" << "" << "%5B%5D"
- << "x:/%5B%5D#%5B%5D";
-
- // 4) like above, but now decode them, which is allowed
- QTest::newRow("decoded-square-brackets") << QUrl("x:/%5B%5D#%5B%5D")
- << MostDecoded
- << "" << "" << ""
- << "" << ""
- << "/[]" << "" << "[]"
- << "x:/[]#[]";
+ << "/:@/[]" << ":/?@[]?" << ":/?@[]"
+ << "x://::@host/:@/[]?:/?@[]?#:/?@[]";
+
+ // 3) and test that the same encoded sequences remain encoded
+ QTest::newRow("encoded-gendelims-unchanging") << QUrl("x://:%3A@host/%3A%40%5B%5D?%3A%2F%3F%40%5B%5D#%23%3A%2F%3F%40%5B%5D")
+ << MostDecoded
+ << "" << "%3A" << ":%3A"
+ << "host" << ":%3A@host"
+ << "/%3A%40%5B%5D" << "%3A%2F%3F%40%5B%5D" << "%23%3A%2F%3F%40%5B%5D"
+ << "x://:%3A@host/%3A%40%5B%5D?%3A%2F%3F%40%5B%5D#%23%3A%2F%3F%40%5B%5D";
// test the query
// since QUrl doesn't know what chars the user wants to use for the pair and value delimiters,
@@ -3051,23 +3218,13 @@ void tst_QUrl::componentEncodings_data()
<< QString::fromUtf8("é ")
<< QString::fromUtf8("x:// é:é @smørbrød.example.no/é ? é#é ");
- // the pretty form re-encodes the subdelims (except in the query, where they are left alone)
- QTest::newRow("pretty-subdelims") << QUrl("x://%21%24%26:%27%28%29@host/%2a%2b%2c?%26=%26&%3d=%3d#%3b%3d")
- << int(QUrl::PrettyDecoded)
- << "!$&" << "'()" << "!$&:'()"
- << "host" << "!$&:'()@host"
- << "/*+," << "%26=%26&%3D=%3D" << ";="
- << "x://!$&:'()@host/*+,?%26=%26&%3D=%3D#;=";
-
- // the pretty form decodes all unambiguous gen-delims
- // (except in query, where they are left alone)
- QTest::newRow("pretty-gendelims") << QUrl("x://%5b%3a%40%2f%5d:%5b%3a%40%2f%5d@host"
- "/%3a%40%5b%3f%23%5d?[?%3f%23]%5b:%3a@%40%5d#%23")
+ // the pretty form decodes all unambiguous gen-delims in the individual parts
+ QTest::newRow("pretty-gendelims") << QUrl("x://%5b%3a%40%2f%3f%23%5d:%5b%40%2f%3f%23%5d@host/%3f%23?%23")
<< int(QUrl::PrettyDecoded)
- << "[:@/]" << "[:@/]" << "[%3A@/]:[:@/]"
- << "host" << "%5B%3A%40/%5D:%5B:%40/%5D@host"
- << "/:@[?#]" << "[?%3F#]%5B:%3A@%40%5D" << "#"
- << "x://%5B%3A%40%2F%5D:%5B:%40%2F%5D@host/:@[%3F%23]?[?%3F%23]%5B:%3A@%40%5D##";
+ << "[:@/?#]" << "[@/?#]" << "[%3A@/?#]:[@/?#]"
+ << "host" << "%5B%3A%40/?#%5D:%5B%40/?#%5D@host"
+ << "/?#" << "#" << ""
+ << "x://%5B%3A%40%2F%3F%23%5D:%5B%40%2F%3F%23%5D@host/%3F%23?%23";
// the pretty form keeps the other characters decoded everywhere
// except when rebuilding the full URL, when we only allow "{}" to remain decoded
@@ -3076,8 +3233,8 @@ void tst_QUrl::componentEncodings_data()
<< "\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}:\"<>^\\{|}"
<< "host" << "\"<>^\\{|}:\"<>^\\{|}@host"
<< "/\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}"
- << "x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host/%22%3C%3E%5E%5C{%7C}"
- "?%22%3C%3E%5E%5C{%7C}#%22%3C%3E%5E%5C%7B%7C%7D";
+ << "x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host/%22%3C%3E%5E%5C%7B%7C%7D"
+ "?%22%3C%3E%5E%5C%7B%7C%7D#%22%3C%3E%5E%5C%7B%7C%7D";
}
void tst_QUrl::componentEncodings()
@@ -3346,9 +3503,6 @@ void tst_QUrl::setComponents_data()
QTest::newRow("invalid-scheme-encode") << QUrl("http://example.com")
<< int(Scheme) << "http%61" << Decoded << false
<< PrettyDecoded << "" << "";
- QTest::newRow("userinfo-encode") << QUrl("http://example.com")
- << int(UserInfo) << "h%61llo:world@" << Decoded << true
- << PrettyDecoded << "h%2561llo:world@" << "http://h%2561llo:world%40@example.com";
QTest::newRow("username-encode") << QUrl("http://example.com")
<< int(UserName) << "h%61llo:world" << Decoded << true
<< PrettyDecoded << "h%2561llo:world" << "http://h%2561llo%3Aworld@example.com";
@@ -3359,9 +3513,6 @@ void tst_QUrl::setComponents_data()
QTest::newRow("invalid-host-encode") << QUrl("http://example.com")
<< int(Host) << "ex%61mple.com" << Decoded << false
<< PrettyDecoded << "" << "";
- QTest::newRow("invalid-authority-encode") << QUrl("http://example.com")
- << int(Authority) << "ex%61mple.com" << Decoded << false
- << PrettyDecoded << "" << "";
QTest::newRow("path-encode") << QUrl("http://example.com/foo")
<< int(Path) << "/bar%23" << Decoded << true
<< PrettyDecoded << "/bar%2523" << "http://example.com/bar%2523";
@@ -3371,11 +3522,7 @@ void tst_QUrl::setComponents_data()
QTest::newRow("fragment-encode") << QUrl("http://example.com/foo#z")
<< int(Fragment) << "bar%23" << Decoded << true
<< PrettyDecoded << "bar%2523" << "http://example.com/foo#bar%2523";
- // force decoding; note how the userinfo becomes ambiguous
- QTest::newRow("userinfo-decode") << QUrl("http://example.com")
- << int(UserInfo) << "hello%3Aworld:}}>b9o%25kR(" << Tolerant << true
- << FullyDecoded << "hello:world:}}>b9o%kR("
- << "http://hello%3Aworld:%7D%7D%3Eb9o%25kR(@example.com";
+ // force decoding
QTest::newRow("username-decode") << QUrl("http://example.com")
<< int(UserName) << "hello%3Aworld%25" << Tolerant << true
<< FullyDecoded << "hello:world%" << "http://hello%3Aworld%25@example.com";
diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
index 2014045171..05d5f94e3d 100644
--- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
+++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
@@ -824,12 +824,20 @@ void tst_QUrlInternal::correctEncodedMistakes()
QFETCH(QString, expected);
// prepend some data to be sure that it remains there
- QString output = QTest::currentDataTag();
- expected.prepend(output);
+ QString dataTag = QTest::currentDataTag();
+ QString output = dataTag;
if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), 0))
output += input;
- QCOMPARE(output, expected);
+ QCOMPARE(output, dataTag + expected);
+
+ // now try the full decode mode
+ output = dataTag;
+ QString expected2 = QUrl::fromPercentEncoding(expected.toLatin1());
+
+ if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyDecoded))
+ output += input;
+ QCOMPARE(output, dataTag + expected2);
}
static void addUtf8Data(const char *name, const char *data)
@@ -1027,6 +1035,15 @@ void tst_QUrlInternal::encodingRecodeInvalidUtf8()
if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyEncoded))
output += input;
QCOMPARE(output, QTest::currentDataTag() + input);
+
+ // verify for security reasons that all bad UTF-8 data got replaced by QChar::ReplacementCharacter
+ output = QTest::currentDataTag();
+ if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyEncoded))
+ output += input;
+ for (int i = strlen(QTest::currentDataTag()); i < output.length(); ++i) {
+ QVERIFY2(output.at(i).unicode() < 0x80 || output.at(i) == QChar::ReplacementCharacter,
+ qPrintable(QString("Character at i == %1 was U+%2").arg(i).arg(output.at(i).unicode(), 4, 16, QLatin1Char('0'))));
+ }
}
void tst_QUrlInternal::recodeByteArray_data()
diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp
index 94e6e1129e..9111c59408 100644
--- a/tests/auto/corelib/json/tst_qtjson.cpp
+++ b/tests/auto/corelib/json/tst_qtjson.cpp
@@ -45,6 +45,7 @@
#include "qjsonobject.h"
#include "qjsonvalue.h"
#include "qjsondocument.h"
+#include <limits>
#define INVALID_UNICODE "\357\277\277" // "\uffff"
#define UNICODE_DJE "\320\202" // Character from the Serbian Cyrillic alphabet
@@ -97,6 +98,8 @@ private Q_SLOTS:
void toVariantList();
void toJson();
+ void toJsonSillyNumericValues();
+ void toJsonLargeNumericValues();
void fromJson();
void fromJsonErrors();
void fromBinary();
@@ -1201,6 +1204,89 @@ void tst_QtJson::toJson()
}
}
+void tst_QtJson::toJsonSillyNumericValues()
+{
+ QJsonObject object;
+ QJsonArray array;
+ array.append(QJsonValue(std::numeric_limits<double>::infinity())); // encode to: null
+ array.append(QJsonValue(-std::numeric_limits<double>::infinity())); // encode to: null
+ array.append(QJsonValue(std::numeric_limits<double>::quiet_NaN())); // encode to: null
+ object.insert("Array", array);
+
+ QByteArray json = QJsonDocument(object).toJson();
+
+ QByteArray expected =
+ "{\n"
+ " \"Array\": [\n"
+ " null,\n"
+ " null,\n"
+ " null\n"
+ " ]\n"
+ "}\n";
+
+ QCOMPARE(json, expected);
+
+ QJsonDocument doc;
+ doc.setObject(object);
+ json = doc.toJson();
+ QCOMPARE(json, expected);
+}
+
+void tst_QtJson::toJsonLargeNumericValues()
+{
+ QJsonObject object;
+ QJsonArray array;
+ array.append(QJsonValue(1.234567)); // actual precision bug in Qt 5.0.0
+ array.append(QJsonValue(1.7976931348623157e+308)); // JS Number.MAX_VALUE
+ array.append(QJsonValue(5e-324)); // JS Number.MIN_VALUE
+ array.append(QJsonValue(std::numeric_limits<double>::min()));
+ array.append(QJsonValue(std::numeric_limits<double>::max()));
+ array.append(QJsonValue(std::numeric_limits<double>::epsilon()));
+ array.append(QJsonValue(std::numeric_limits<double>::denorm_min()));
+ array.append(QJsonValue(0.0));
+ array.append(QJsonValue(-std::numeric_limits<double>::min()));
+ array.append(QJsonValue(-std::numeric_limits<double>::max()));
+ array.append(QJsonValue(-std::numeric_limits<double>::epsilon()));
+ array.append(QJsonValue(-std::numeric_limits<double>::denorm_min()));
+ array.append(QJsonValue(-0.0));
+ array.append(QJsonValue(9007199254740992LL)); // JS Number max integer
+ array.append(QJsonValue(-9007199254740992LL)); // JS Number min integer
+ object.insert("Array", array);
+
+ QByteArray json = QJsonDocument(object).toJson();
+
+ QByteArray expected =
+ "{\n"
+ " \"Array\": [\n"
+ " 1.234567,\n"
+ " 1.7976931348623157e+308,\n"
+ // ((4.9406564584124654e-324 == 5e-324) == true)
+ // I can only think JavaScript has a special formatter to
+ // emit this value for this IEEE754 bit pattern.
+ " 4.9406564584124654e-324,\n"
+ " 2.2250738585072014e-308,\n"
+ " 1.7976931348623157e+308,\n"
+ " 2.2204460492503131e-16,\n"
+ " 4.9406564584124654e-324,\n"
+ " 0,\n"
+ " -2.2250738585072014e-308,\n"
+ " -1.7976931348623157e+308,\n"
+ " -2.2204460492503131e-16,\n"
+ " -4.9406564584124654e-324,\n"
+ " 0,\n"
+ " 9007199254740992,\n"
+ " -9007199254740992\n"
+ " ]\n"
+ "}\n";
+
+ QCOMPARE(json, expected);
+
+ QJsonDocument doc;
+ doc.setObject(object);
+ json = doc.toJson();
+ QCOMPARE(json, expected);
+}
+
void tst_QtJson::fromJson()
{
{
diff --git a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
index df374ffc23..c6d04e64db 100644
--- a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
+++ b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
@@ -195,11 +195,11 @@ protected:
void tst_QEventLoop::processEvents()
{
- QSignalSpy spy1(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()));
- QSignalSpy spy2(QAbstractEventDispatcher::instance(), SIGNAL(awake()));
+ QSignalSpy aboutToBlockSpy(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()));
+ QSignalSpy awakeSpy(QAbstractEventDispatcher::instance(), SIGNAL(awake()));
- QVERIFY(spy1.isValid());
- QVERIFY(spy2.isValid());
+ QVERIFY(aboutToBlockSpy.isValid());
+ QVERIFY(awakeSpy.isValid());
QEventLoop eventLoop;
@@ -208,8 +208,8 @@ void tst_QEventLoop::processEvents()
// process posted events, QEventLoop::processEvents() should return
// true
QVERIFY(eventLoop.processEvents());
- QCOMPARE(spy1.count(), 0);
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(aboutToBlockSpy.count(), 0);
+ QCOMPARE(awakeSpy.count(), 1);
// allow any session manager to complete its handshake, so that
// there are no pending events left.
@@ -222,28 +222,28 @@ void tst_QEventLoop::processEvents()
// no events to process, QEventLoop::processEvents() should return
// false
- spy1.clear();
- spy2.clear();
+ aboutToBlockSpy.clear();
+ awakeSpy.clear();
QVERIFY(!eventLoop.processEvents());
- QCOMPARE(spy1.count(), 0);
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(aboutToBlockSpy.count(), 0);
+ QCOMPARE(awakeSpy.count(), 1);
// make sure the test doesn't block forever
int timerId = startTimer(100);
// wait for more events to process, QEventLoop::processEvents()
// should return true
- spy1.clear();
- spy2.clear();
+ aboutToBlockSpy.clear();
+ awakeSpy.clear();
QVERIFY(eventLoop.processEvents(QEventLoop::WaitForMoreEvents));
// Verify that the eventloop has blocked and woken up. Some eventloops
// may block and wake up multiple times.
- QVERIFY(spy1.count() > 0);
- QVERIFY(spy2.count() > 0);
+ QVERIFY(aboutToBlockSpy.count() > 0);
+ QVERIFY(awakeSpy.count() > 0);
// We should get one awake for each aboutToBlock, plus one awake when
// processEvents is entered.
- QVERIFY(spy2.count() >= spy1.count());
+ QVERIFY(awakeSpy.count() >= aboutToBlockSpy.count());
killTimer(timerId);
}
diff --git a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro
index 5009fedc4f..23a8e6d23a 100644
--- a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro
+++ b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro
@@ -1,6 +1,7 @@
CONFIG += testcase parallel_test
TARGET = tst_qmetatype
QT = core testlib
+INCLUDEPATH += $$PWD/../../../other/qvariant_common
SOURCES = tst_qmetatype.cpp
TESTDATA=./typeFlags.bin
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index 77ea39da53..47900204e7 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -43,6 +43,8 @@
#include <QtCore>
#include <QtTest/QtTest>
+#include "tst_qvariant_common.h"
+
#ifdef Q_OS_LINUX
# include <pthread.h>
#endif
@@ -111,6 +113,11 @@ private slots:
void metaObject();
void constexprMetaTypeIds();
void constRefs();
+ void convertCustomType_data();
+ void convertCustomType();
+ void compareCustomType_data();
+ void compareCustomType();
+ void customDebugStream();
};
struct Foo { int i; };
@@ -1302,15 +1309,20 @@ Q_DECLARE_METATYPE(MyObjectPtr)
void tst_QMetaType::automaticTemplateRegistration()
{
- {
- QList<int> intList;
- intList << 42;
- QVERIFY(QVariant::fromValue(intList).value<QList<int> >().first() == 42);
- QVector<QList<int> > vectorList;
- vectorList << intList;
- QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<int> > >().first().first() == 42);
+#define TEST_SEQUENTIAL_CONTAINER(CONTAINER, VALUE_TYPE) \
+ { \
+ CONTAINER<VALUE_TYPE> innerContainer; \
+ innerContainer.push_back(42); \
+ QVERIFY(*QVariant::fromValue(innerContainer).value<CONTAINER<VALUE_TYPE> >().begin() == 42); \
+ QVector<CONTAINER<VALUE_TYPE> > outerContainer; \
+ outerContainer << innerContainer; \
+ QVERIFY(*QVariant::fromValue(outerContainer).value<QVector<CONTAINER<VALUE_TYPE> > >().first().begin() == 42); \
}
+ TEST_SEQUENTIAL_CONTAINER(QList, int)
+ TEST_SEQUENTIAL_CONTAINER(std::vector, int)
+ TEST_SEQUENTIAL_CONTAINER(std::list, int)
+
{
QList<QByteArray> bytearrayList;
bytearrayList << QByteArray("foo");
@@ -1323,14 +1335,9 @@ void tst_QMetaType::automaticTemplateRegistration()
QCOMPARE(::qMetaTypeId<QVariantList>(), (int)QMetaType::QVariantList);
QCOMPARE(::qMetaTypeId<QList<QVariant> >(), (int)QMetaType::QVariantList);
- {
- QList<QVariant> variantList;
- variantList << 42;
- QVERIFY(QVariant::fromValue(variantList).value<QList<QVariant> >().first() == 42);
- QVector<QList<QVariant> > vectorList;
- vectorList << variantList;
- QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QVariant> > >().first().first() == 42);
- }
+ TEST_SEQUENTIAL_CONTAINER(QList, QVariant)
+ TEST_SEQUENTIAL_CONTAINER(std::vector, QVariant)
+ TEST_SEQUENTIAL_CONTAINER(std::list, QVariant)
{
QList<QSharedPointer<QObject> > sharedPointerList;
@@ -1395,6 +1402,31 @@ void tst_QMetaType::automaticTemplateRegistration()
QCOMPARE(QVariant::fromValue(variantMap).value<QVariantMap>().value(QStringLiteral("4")), QVariant(2));
}
{
+ typedef std::map<int, int> IntIntMap;
+ IntIntMap intIntMap;
+ intIntMap[4] = 2;
+ QCOMPARE(QVariant::fromValue(intIntMap).value<IntIntMap>()[4], 2);
+ }
+ {
+ typedef std::map<int, uint> StdIntUIntMap;
+ StdIntUIntMap intUIntMap;
+ intUIntMap[4] = 2;
+ QCOMPARE(QVariant::fromValue(intUIntMap).value<StdIntUIntMap>()[4], (uint)2);
+ }
+ {
+ typedef std::map<int, CustomObject*> StdMapIntCustomObject ;
+ StdMapIntCustomObject intComparableMap;
+ CustomObject *o = 0;
+ intComparableMap[4] = o;
+ QCOMPARE(QVariant::fromValue(intComparableMap).value<StdMapIntCustomObject >()[4], o);
+ }
+ {
+ typedef std::map<QString, QVariant> StdMapStringVariant;
+ StdMapStringVariant variantMap;
+ variantMap[QStringLiteral("4")] = 2;
+ QCOMPARE(QVariant::fromValue(variantMap).value<StdMapStringVariant>()[QStringLiteral("4")], QVariant(2));
+ }
+ {
typedef QPair<int, int> IntIntPair;
IntIntPair intIntPair = qMakePair(4, 2);
QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().first, 4);
@@ -1412,6 +1444,25 @@ void tst_QMetaType::automaticTemplateRegistration()
QCOMPARE(QVariant::fromValue(intComparablePair).value<IntComparablePair>().second, m);
}
{
+ typedef std::pair<int, int> IntIntPair;
+ IntIntPair intIntPair = std::make_pair(4, 2);
+ QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().first, 4);
+ QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().second, 2);
+ }
+ {
+ typedef std::pair<int, uint> StdIntUIntPair;
+ StdIntUIntPair intUIntPair = std::make_pair<int, uint>(4, 2);
+ QCOMPARE(QVariant::fromValue(intUIntPair).value<StdIntUIntPair>().first, 4);
+ QCOMPARE(QVariant::fromValue(intUIntPair).value<StdIntUIntPair>().second, (uint)2);
+ }
+ {
+ typedef std::pair<int, CustomQObject*> StdIntComparablePair;
+ CustomQObject* o = 0;
+ StdIntComparablePair intComparablePair = std::make_pair(4, o);
+ QCOMPARE(QVariant::fromValue(intComparablePair).value<StdIntComparablePair>().first, 4);
+ QCOMPARE(QVariant::fromValue(intComparablePair).value<StdIntComparablePair>().second, o);
+ }
+ {
typedef QHash<int, UnregisteredType> IntUnregisteredTypeHash;
QVERIFY(qRegisterMetaType<IntUnregisteredTypeHash>("IntUnregisteredTypeHash") > 0);
}
@@ -1446,17 +1497,14 @@ void tst_QMetaType::automaticTemplateRegistration()
F(uint, __VA_ARGS__) \
F(qlonglong, __VA_ARGS__) \
F(qulonglong, __VA_ARGS__) \
- F(double, __VA_ARGS__) \
F(long, __VA_ARGS__) \
F(short, __VA_ARGS__) \
F(char, __VA_ARGS__) \
F(ulong, __VA_ARGS__) \
F(ushort, __VA_ARGS__) \
F(uchar, __VA_ARGS__) \
- F(float, __VA_ARGS__) \
F(QObject*, __VA_ARGS__) \
- F(QString, __VA_ARGS__) \
- F(CustomMovable, __VA_ARGS__)
+ F(QString, __VA_ARGS__)
#define CREATE_AND_VERIFY_CONTAINER(CONTAINER, ...) \
@@ -1774,6 +1822,366 @@ void tst_QMetaType::constRefs()
#endif
}
+struct CustomConvertibleType
+{
+ explicit CustomConvertibleType(const QVariant &foo = QVariant()) : m_foo(foo) {}
+ virtual ~CustomConvertibleType() {}
+ QString toString() const { return m_foo.toString(); }
+ operator QPoint() const { return QPoint(12, 34); }
+ template<typename To>
+ To convert() const { return s_value.value<To>();}
+ template<typename To>
+ To convertOk(bool *ok) const { *ok = s_ok; return s_value.value<To>();}
+
+ QVariant m_foo;
+ static QVariant s_value;
+ static bool s_ok;
+};
+
+bool operator<(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
+{ return lhs.m_foo < rhs.m_foo; }
+bool operator==(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
+{ return lhs.m_foo == rhs.m_foo; }
+bool operator!=(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
+{ return !operator==(lhs, rhs); }
+
+QVariant CustomConvertibleType::s_value;
+bool CustomConvertibleType::s_ok = true;
+
+struct CustomConvertibleType2
+{
+ // implicit
+ CustomConvertibleType2(const CustomConvertibleType &t = CustomConvertibleType())
+ : m_foo(t.m_foo) {}
+ virtual ~CustomConvertibleType2() {}
+
+ QVariant m_foo;
+};
+
+struct CustomDebugStreamableType
+{
+ QString toString() const { return "test"; }
+};
+
+QDebug operator<<(QDebug dbg, const CustomDebugStreamableType&)
+{
+ return dbg << "string-content";
+}
+
+bool operator==(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs)
+{ return lhs.m_foo == rhs.m_foo; }
+bool operator!=(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs)
+{ return !operator==(lhs, rhs); }
+
+Q_DECLARE_METATYPE(CustomConvertibleType);
+Q_DECLARE_METATYPE(CustomConvertibleType2);
+Q_DECLARE_METATYPE(CustomDebugStreamableType);
+
+template<typename T, typename U>
+U convert(const T &t)
+{
+ return t;
+}
+
+template<typename From>
+struct ConvertFunctor
+{
+ CustomConvertibleType operator()(const From& f) const
+ {
+ return CustomConvertibleType(QVariant::fromValue(f));
+ }
+};
+
+template<typename From, typename To>
+bool hasRegisteredConverterFunction()
+{
+ return QMetaType::hasRegisteredConverterFunction<From, To>();
+}
+
+template<typename From, typename To>
+void testCustomTypeNotYetConvertible()
+{
+ QVERIFY((!hasRegisteredConverterFunction<From, To>()));
+ QVERIFY((!QVariant::fromValue<From>(From()).canConvert(qMetaTypeId<To>())));
+}
+
+template<typename From, typename To>
+void testCustomTypeConvertible()
+{
+ QVERIFY((hasRegisteredConverterFunction<From, To>()));
+ QVERIFY((QVariant::fromValue<From>(From()).canConvert(qMetaTypeId<To>())));
+}
+
+void customTypeNotYetConvertible()
+{
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QString>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, bool>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, int>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, double>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, float>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QRect>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QRectF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QPoint>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QPointF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QSize>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QSizeF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QLine>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QLineF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QChar>();
+ testCustomTypeNotYetConvertible<QString, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<bool, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<int, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<double, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<float, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QRect, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QRectF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QPoint, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QPointF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QSize, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QSizeF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QLine, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QLineF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QChar, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, CustomConvertibleType2>();
+}
+
+void registerCustomTypeConversions()
+{
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QString>(&CustomConvertibleType::convertOk<QString>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, bool>(&CustomConvertibleType::convert<bool>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, int>(&CustomConvertibleType::convertOk<int>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, double>(&CustomConvertibleType::convert<double>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, float>(&CustomConvertibleType::convertOk<float>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRect>(&CustomConvertibleType::convert<QRect>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRectF>(&CustomConvertibleType::convertOk<QRectF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPoint>(convert<CustomConvertibleType,QPoint>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPointF>(&CustomConvertibleType::convertOk<QPointF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSize>(&CustomConvertibleType::convert<QSize>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSizeF>(&CustomConvertibleType::convertOk<QSizeF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLine>(&CustomConvertibleType::convert<QLine>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLineF>(&CustomConvertibleType::convertOk<QLineF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QChar>(&CustomConvertibleType::convert<QChar>)));
+ QVERIFY((QMetaType::registerConverter<QString, CustomConvertibleType>(ConvertFunctor<QString>())));
+ QVERIFY((QMetaType::registerConverter<bool, CustomConvertibleType>(ConvertFunctor<bool>())));
+ QVERIFY((QMetaType::registerConverter<int, CustomConvertibleType>(ConvertFunctor<int>())));
+ QVERIFY((QMetaType::registerConverter<double, CustomConvertibleType>(ConvertFunctor<double>())));
+ QVERIFY((QMetaType::registerConverter<float, CustomConvertibleType>(ConvertFunctor<float>())));
+ QVERIFY((QMetaType::registerConverter<QRect, CustomConvertibleType>(ConvertFunctor<QRect>())));
+ QVERIFY((QMetaType::registerConverter<QRectF, CustomConvertibleType>(ConvertFunctor<QRectF>())));
+ QVERIFY((QMetaType::registerConverter<QPoint, CustomConvertibleType>(ConvertFunctor<QPoint>())));
+ QVERIFY((QMetaType::registerConverter<QPointF, CustomConvertibleType>(ConvertFunctor<QPointF>())));
+ QVERIFY((QMetaType::registerConverter<QSize, CustomConvertibleType>(ConvertFunctor<QSize>())));
+ QVERIFY((QMetaType::registerConverter<QSizeF, CustomConvertibleType>(ConvertFunctor<QSizeF>())));
+ QVERIFY((QMetaType::registerConverter<QLine, CustomConvertibleType>(ConvertFunctor<QLine>())));
+ QVERIFY((QMetaType::registerConverter<QLineF, CustomConvertibleType>(ConvertFunctor<QLineF>())));
+ QVERIFY((QMetaType::registerConverter<QChar, CustomConvertibleType>(ConvertFunctor<QChar>())));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
+ QTest::ignoreMessage(QtWarningMsg, "Type conversion already registered from type CustomConvertibleType to type CustomConvertibleType2");
+ QVERIFY((!QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
+}
+
+void tst_QMetaType::convertCustomType_data()
+{
+ customTypeNotYetConvertible();
+ registerCustomTypeConversions();
+
+ QTest::addColumn<bool>("ok");
+ QTest::addColumn<QString>("testQString");
+ QTest::addColumn<bool>("testBool");
+ QTest::addColumn<int>("testInt");
+ QTest::addColumn<double>("testDouble");
+ QTest::addColumn<float>("testFloat");
+ QTest::addColumn<QRect>("testQRect");
+ QTest::addColumn<QRectF>("testQRectF");
+ QTest::addColumn<QPoint>("testQPoint");
+ QTest::addColumn<QPointF>("testQPointF");
+ QTest::addColumn<QSize>("testQSize");
+ QTest::addColumn<QSizeF>("testQSizeF");
+ QTest::addColumn<QLine>("testQLine");
+ QTest::addColumn<QLineF>("testQLineF");
+ QTest::addColumn<QChar>("testQChar");
+ QTest::addColumn<CustomConvertibleType>("testCustom");
+
+ QTest::newRow("default") << true
+ << QString::fromLatin1("string") << true << 15
+ << double(3.14) << float(3.6) << QRect(1, 2, 3, 4)
+ << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34)
+ << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8)
+ << QLine(3, 9, 29, 4) << QLineF(38.9, 28.9, 102.3, 0.0)
+ << QChar('Q') << CustomConvertibleType(QString::fromLatin1("test"));
+ QTest::newRow("not ok") << false
+ << QString::fromLatin1("string") << true << 15
+ << double(3.14) << float(3.6) << QRect(1, 2, 3, 4)
+ << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34)
+ << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8)
+ << QLine(3, 9, 29, 4) << QLineF()
+ << QChar('Q') << CustomConvertibleType(42);
+}
+
+void tst_QMetaType::convertCustomType()
+{
+ QFETCH(bool, ok);
+ CustomConvertibleType::s_ok = ok;
+
+ CustomConvertibleType t;
+ QVariant v = QVariant::fromValue(t);
+ QFETCH(QString, testQString);
+ CustomConvertibleType::s_value = testQString;
+ QCOMPARE(v.toString(), ok ? testQString : QString());
+ QCOMPARE(v.value<QString>(), ok ? testQString : QString());
+ QVERIFY(CustomConvertibleType::s_value.canConvert<CustomConvertibleType>());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toString()), testQString);
+
+ QFETCH(bool, testBool);
+ CustomConvertibleType::s_value = testBool;
+ QCOMPARE(v.toBool(), testBool);
+ QCOMPARE(v.value<bool>(), testBool);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toBool()), testBool);
+
+ QFETCH(int, testInt);
+ CustomConvertibleType::s_value = testInt;
+ QCOMPARE(v.toInt(), ok ? testInt : 0);
+ QCOMPARE(v.value<int>(), ok ? testInt : 0);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toInt()), testInt);
+
+ QFETCH(double, testDouble);
+ CustomConvertibleType::s_value = testDouble;
+ QCOMPARE(v.toDouble(), testDouble);
+ QCOMPARE(v.value<double>(), testDouble);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toDouble()), testDouble);
+
+ QFETCH(float, testFloat);
+ CustomConvertibleType::s_value = testFloat;
+ QCOMPARE(v.toFloat(), ok ? testFloat : 0.0);
+ QCOMPARE(v.value<float>(), ok ? testFloat : 0.0);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toFloat()), testFloat);
+
+ QFETCH(QRect, testQRect);
+ CustomConvertibleType::s_value = testQRect;
+ QCOMPARE(v.toRect(), testQRect);
+ QCOMPARE(v.value<QRect>(), testQRect);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRect()), testQRect);
+
+ QFETCH(QRectF, testQRectF);
+ CustomConvertibleType::s_value = testQRectF;
+ QCOMPARE(v.toRectF(), ok ? testQRectF : QRectF());
+ QCOMPARE(v.value<QRectF>(), ok ? testQRectF : QRectF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRectF()), testQRectF);
+
+ QFETCH(QPoint, testQPoint);
+ CustomConvertibleType::s_value = testQPoint;
+ QCOMPARE(v.toPoint(), testQPoint);
+ QCOMPARE(v.value<QPoint>(), testQPoint);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPoint()), testQPoint);
+
+ QFETCH(QPointF, testQPointF);
+ CustomConvertibleType::s_value = testQPointF;
+ QCOMPARE(v.toPointF(), ok ? testQPointF : QPointF());
+ QCOMPARE(v.value<QPointF>(), ok ? testQPointF : QPointF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPointF()), testQPointF);
+
+ QFETCH(QSize, testQSize);
+ CustomConvertibleType::s_value = testQSize;
+ QCOMPARE(v.toSize(), testQSize);
+ QCOMPARE(v.value<QSize>(), testQSize);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSize()), testQSize);
+
+ QFETCH(QSizeF, testQSizeF);
+ CustomConvertibleType::s_value = testQSizeF;
+ QCOMPARE(v.toSizeF(), ok ? testQSizeF : QSizeF());
+ QCOMPARE(v.value<QSizeF>(), ok ? testQSizeF : QSizeF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSizeF()), testQSizeF);
+
+ QFETCH(QLine, testQLine);
+ CustomConvertibleType::s_value = testQLine;
+ QCOMPARE(v.toLine(), testQLine);
+ QCOMPARE(v.value<QLine>(), testQLine);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLine()), testQLine);
+
+ QFETCH(QLineF, testQLineF);
+ CustomConvertibleType::s_value = testQLineF;
+ QCOMPARE(v.toLineF(), ok ? testQLineF : QLineF());
+ QCOMPARE(v.value<QLineF>(), ok ? testQLineF : QLineF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLineF()), testQLineF);
+
+ QFETCH(QChar, testQChar);
+ CustomConvertibleType::s_value = testQChar;
+ QCOMPARE(v.toChar(), testQChar);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toChar()), testQChar);
+
+ QFETCH(CustomConvertibleType, testCustom);
+ v = QVariant::fromValue(testCustom);
+ QVERIFY(v.canConvert(::qMetaTypeId<CustomConvertibleType2>()));
+ QCOMPARE(v.value<CustomConvertibleType2>().m_foo, testCustom.m_foo);
+}
+
+void tst_QMetaType::compareCustomType_data()
+{
+ QMetaType::registerComparators<CustomConvertibleType>();
+
+ QTest::addColumn<QVariantList>("unsorted");
+ QTest::addColumn<QVariantList>("sorted");
+
+ QTest::newRow("int") << (QVariantList() << 37 << 458 << 1 << 243 << -4 << 383)
+ << (QVariantList() << -4 << 1 << 37 << 243 << 383 << 458);
+
+ QTest::newRow("dobule") << (QVariantList() << 4934.93 << 0.0 << 302.39 << -39.0)
+ << (QVariantList() << -39.0 << 0.0 << 302.39 << 4934.93);
+
+ QTest::newRow("QString") << (QVariantList() << "Hello" << "World" << "this" << "is" << "a" << "test")
+ << (QVariantList() << "a" << "Hello" << "is" << "test" << "this" << "World");
+
+ QTest::newRow("QTime") << (QVariantList() << QTime(14, 39) << QTime(0, 0) << QTime(18, 18) << QTime(9, 27))
+ << (QVariantList() << QTime(0, 0) << QTime(9, 27) << QTime(14, 39) << QTime(18, 18));
+
+ QTest::newRow("QDate") << (QVariantList() << QDate(2013, 3, 23) << QDate(1900, 12, 1) << QDate(2001, 2, 2) << QDate(1982, 12, 16))
+ << (QVariantList() << QDate(1900, 12, 1) << QDate(1982, 12, 16) << QDate(2001, 2, 2) << QDate(2013, 3, 23));
+
+ QTest::newRow("mixed") << (QVariantList() << "Hello" << "World" << QChar('a') << 38 << QChar('z') << -39 << 4.6)
+ << (QVariantList() << -39 << 4.6 << 38 << QChar('a') << "Hello" << "World" << QChar('z'));
+
+ QTest::newRow("custom") << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(100)) << QVariant::fromValue(CustomConvertibleType(50)))
+ << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(50)) << QVariant::fromValue(CustomConvertibleType(100)));
+}
+
+void tst_QMetaType::compareCustomType()
+{
+ QFETCH(QVariantList, unsorted);
+ QFETCH(QVariantList, sorted);
+ qSort(unsorted);
+ QCOMPARE(unsorted, sorted);
+}
+
+struct MessageHandlerCustom : public MessageHandler
+{
+ MessageHandlerCustom(const int typeId)
+ : MessageHandler(typeId, handler)
+ {}
+ static void handler(QtMsgType, const QMessageLogContext &, const QString &msg)
+ {
+ QCOMPARE(msg.trimmed(), expectedMessage.trimmed());
+ }
+ static QString expectedMessage;
+};
+
+QString MessageHandlerCustom::expectedMessage;
+
+void tst_QMetaType::customDebugStream()
+{
+ MessageHandlerCustom handler(::qMetaTypeId<CustomDebugStreamableType>());
+ QVariant v1 = QVariant::fromValue(CustomDebugStreamableType());
+ handler.expectedMessage = "QVariant(CustomDebugStreamableType, )";
+ qDebug() << v1;
+
+ QMetaType::registerConverter<CustomDebugStreamableType, QString>(&CustomDebugStreamableType::toString);
+ handler.expectedMessage = "QVariant(CustomDebugStreamableType, \"test\")";
+ qDebug() << v1;
+
+ QMetaType::registerDebugStreamOperator<CustomDebugStreamableType>();
+ handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)";
+ qDebug() << v1;
+}
+
// Compile-time test, it should be possible to register function pointer types
class Undefined;
@@ -1781,11 +2189,15 @@ typedef Undefined (*UndefinedFunction0)();
typedef Undefined (*UndefinedFunction1)(Undefined);
typedef Undefined (*UndefinedFunction2)(Undefined, Undefined);
typedef Undefined (*UndefinedFunction3)(Undefined, Undefined, Undefined);
+typedef Undefined (*UndefinedFunction4)(Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined);
Q_DECLARE_METATYPE(UndefinedFunction0);
Q_DECLARE_METATYPE(UndefinedFunction1);
Q_DECLARE_METATYPE(UndefinedFunction2);
Q_DECLARE_METATYPE(UndefinedFunction3);
+#ifdef Q_COMPILER_VARIADIC_TEMPLATES
+Q_DECLARE_METATYPE(UndefinedFunction4);
+#endif
QTEST_MAIN(tst_QMetaType)
#include "tst_qmetatype.moc"
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index 1cdf39018b..8d1ea3b510 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -146,6 +146,7 @@ private slots:
void connectFunctorOverloads();
void disconnectDoesNotLeakFunctor();
void connectBase();
+ void qmlConnect();
};
struct QObjectCreatedOnShutdown
@@ -5879,6 +5880,56 @@ void tst_QObject::connectBase()
QCOMPARE( r1.count_slot3, 1 );
}
+struct QmlReceiver : public QtPrivate::QSlotObjectBase
+{
+ int callCount;
+ void *magic;
+
+ QmlReceiver()
+ : QtPrivate::QSlotObjectBase(&impl)
+ , callCount(0)
+ , magic(0)
+ {}
+
+ static void impl(int which, QSlotObjectBase *this_, QObject *, void **metaArgs, bool *ret)
+ {
+ switch (which) {
+ case Destroy: delete static_cast<QmlReceiver*>(this_); return;
+ case Call: static_cast<QmlReceiver*>(this_)->callCount++; return;
+ case Compare: *ret = static_cast<QmlReceiver*>(this_)->magic == metaArgs[0]; return;
+ case NumOperations: break;
+ }
+ }
+};
+
+void tst_QObject::qmlConnect()
+{
+#ifdef QT_BUILD_INTERNAL
+ SenderObject sender;
+ QmlReceiver *receiver = new QmlReceiver;
+ receiver->magic = receiver;
+ receiver->ref();
+
+ QVERIFY(QObjectPrivate::connect(&sender, sender.metaObject()->indexOfSignal("signal1()"),
+ receiver, Qt::AutoConnection));
+
+ QCOMPARE(receiver->callCount, 0);
+ sender.emitSignal1();
+ QCOMPARE(receiver->callCount, 1);
+
+ void *a[] = {
+ receiver
+ };
+ QVERIFY(QObjectPrivate::disconnect(&sender, sender.metaObject()->indexOfSignal("signal1()"), reinterpret_cast<void**>(&a)));
+
+ sender.emitSignal1();
+ QCOMPARE(receiver->callCount, 1);
+
+ receiver->destroyIfLastRef();
+#else
+ QSKIP("Needs QT_BUILD_INTERNAL");
+#endif
+}
QTEST_MAIN(tst_QObject)
#include "tst_qobject.moc"
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index 4d862f4fc5..dab40db0ec 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -242,6 +242,9 @@ private slots:
void saveNewBuiltinWithOldStream();
void implicitConstruction();
+
+ void iterateContainerElements();
+ void pairElements();
private:
void dataStream_data(QDataStream::Version version);
void loadQVariantFromDataStream(QDataStream::Version version);
@@ -990,8 +993,8 @@ void tst_QVariant::toString_data()
QTest::newRow( "float" ) << QVariant( 123.456f ) << QString( "123.456" );
QTest::newRow( "bool" ) << QVariant( true ) << QString( "true" );
QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 1, 1 ) ) << QString( "2002-01-01" );
- QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56" );
- QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56 ) ) ) << QString( "2002-01-01T12:34:56" );
+ QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56.000" );
+ QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56 ) ) ) << QString( "2002-01-01T12:34:56.000" );
QTest::newRow( "llong" ) << QVariant( (qlonglong)Q_INT64_C(123456789012) ) <<
QString( "123456789012" );
QTest::newRow("QJsonValue") << QVariant(QJsonValue(QString("hello"))) << QString("hello");
@@ -3392,5 +3395,312 @@ void tst_QVariant::saveNewBuiltinWithOldStream()
QCOMPARE(int(data.constData()[3]), 0);
}
+template<typename Container, typename Value_Type = typename Container::value_type>
+struct ContainerAPI
+{
+ static void insert(Container &container, typename Container::value_type value)
+ {
+ container.push_back(value);
+ }
+
+ static bool compare(const QVariant &variant, typename Container::value_type value)
+ {
+ return variant.value<typename Container::value_type>() == value;
+ }
+ static bool compare(QVariant variant, const QVariant &value)
+ {
+ return variant == value;
+ }
+};
+
+template<typename Container>
+struct ContainerAPI<Container, QVariant>
+{
+ static void insert(Container &container, int value)
+ {
+ container.push_back(QVariant::fromValue(value));
+ }
+
+ static bool compare(QVariant variant, const QVariant &value)
+ {
+ return variant == value;
+ }
+};
+
+template<typename Container>
+struct ContainerAPI<Container, QString>
+{
+ static void insert(Container &container, int value)
+ {
+ container.push_back(QString::number(value));
+ }
+
+ static bool compare(const QVariant &variant, QString value)
+ {
+ return variant.value<QString>() == value;
+ }
+ static bool compare(QVariant variant, const QVariant &value)
+ {
+ return variant == value;
+ }
+};
+
+// We have no built-in defines to check the stdlib features.
+// #define TEST_FORWARD_LIST
+
+#ifdef TEST_FORWARD_LIST
+#include <forward_list>
+Q_DECLARE_METATYPE(std::forward_list<int>)
+Q_DECLARE_METATYPE(std::forward_list<QVariant>)
+Q_DECLARE_METATYPE(std::forward_list<QString>)
+
+template<typename Value_Type>
+struct ContainerAPI<std::forward_list<Value_Type> >
+{
+ static void insert(std::forward_list<Value_Type> &container, Value_Type value)
+ {
+ container.push_front(value);
+ }
+ static bool compare(const QVariant &variant, Value_Type value)
+ {
+ return variant.value<Value_Type>() == value;
+ }
+ static bool compare(QVariant variant, const QVariant &value)
+ {
+ return variant == value;
+ }
+};
+
+template<>
+struct ContainerAPI<std::forward_list<QVariant> >
+{
+ static void insert(std::forward_list<QVariant> &container, int value)
+ {
+ container.push_front(QVariant::fromValue(value));
+ }
+
+ static bool compare(QVariant variant, const QVariant &value)
+ {
+ return variant == value;
+ }
+};
+
+template<>
+struct ContainerAPI<std::forward_list<QString> >
+{
+ static void insert(std::forward_list<QString> &container, int value)
+ {
+ container.push_front(QString::number(value));
+ }
+ static bool compare(const QVariant &variant, QString value)
+ {
+ return variant.value<QString>() == value;
+ }
+ static bool compare(QVariant variant, const QVariant &value)
+ {
+ return variant == value;
+ }
+};
+#endif
+
+template<typename Container>
+struct KeyGetter
+{
+ static const typename Container::key_type & get(const typename Container::const_iterator &it)
+ {
+ return it.key();
+ }
+ static const typename Container::mapped_type & value(const typename Container::const_iterator &it)
+ {
+ return it.value();
+ }
+};
+
+template<typename T, typename U>
+struct KeyGetter<std::map<T, U> >
+{
+ static const T & get(const typename std::map<T, U>::const_iterator &it)
+ {
+ return it->first;
+ }
+ static const U & value(const typename std::map<T, U>::const_iterator &it)
+ {
+ return it->second;
+ }
+};
+
+
+// We have no built-in defines to check the stdlib features.
+// #define TEST_UNORDERED_MAP
+
+#ifdef TEST_UNORDERED_MAP
+#include <unordered_map>
+typedef std::unordered_map<int, bool> StdUnorderedMap_int_bool;
+Q_DECLARE_METATYPE(StdUnorderedMap_int_bool)
+
+template<typename T, typename U>
+struct KeyGetter<std::unordered_map<T, U> >
+{
+ static const T & get(const typename std::unordered_map<T, U>::const_iterator &it)
+ {
+ return it->first;
+ }
+ static const U & value(const typename std::unordered_map<T, U>::const_iterator &it)
+ {
+ return it->second;
+ }
+};
+#endif
+
+void tst_QVariant::iterateContainerElements()
+{
+#ifdef Q_COMPILER_RANGE_FOR
+
+#define TEST_RANGE_FOR(CONTAINER, VALUE_TYPE) \
+ numSeen = 0; \
+ containerIter = intList.begin(); \
+ for (QVariant v : listIter) { \
+ QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, *containerIter)); \
+ QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, varList.at(numSeen))); \
+ ++containerIter; \
+ ++numSeen; \
+ } \
+ QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end()));
+
+#else
+
+#define TEST_RANGE_FOR(CONTAINER, VALUE_TYPE)
+
+#endif
+
+#define TEST_SEQUENTIAL_ITERATION(CONTAINER, VALUE_TYPE) \
+ { \
+ int numSeen = 0; \
+ CONTAINER<VALUE_TYPE > intList; \
+ ContainerAPI<CONTAINER<VALUE_TYPE > >::insert(intList, 1); \
+ ContainerAPI<CONTAINER<VALUE_TYPE > >::insert(intList, 2); \
+ ContainerAPI<CONTAINER<VALUE_TYPE > >::insert(intList, 3); \
+ \
+ QVariant listVariant = QVariant::fromValue(intList); \
+ QVERIFY(listVariant.canConvert<QVariantList>()); \
+ QVariantList varList = listVariant.value<QVariantList>(); \
+ QCOMPARE(varList.size(), (int)std::distance(intList.begin(), intList.end())); \
+ QSequentialIterable listIter = listVariant.value<QSequentialIterable>(); \
+ QCOMPARE(varList.size(), listIter.size()); \
+ \
+ CONTAINER<VALUE_TYPE >::iterator containerIter = intList.begin(); \
+ const CONTAINER<VALUE_TYPE >::iterator containerEnd = intList.end(); \
+ for (int i = 0; i < listIter.size(); ++i, ++containerIter, ++numSeen) \
+ { \
+ QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(listIter.at(i), *containerIter)); \
+ QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(listIter.at(i), varList.at(i))); \
+ } \
+ QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); \
+ QCOMPARE(containerIter, containerEnd); \
+ \
+ containerIter = intList.begin(); \
+ numSeen = 0; \
+ Q_FOREACH (const QVariant &v, listIter) { \
+ QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, *containerIter)); \
+ QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, varList.at(numSeen))); \
+ ++containerIter; \
+ ++numSeen; \
+ } \
+ QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); \
+ TEST_RANGE_FOR(CONTAINER, VALUE_TYPE) \
+ }
+
+ TEST_SEQUENTIAL_ITERATION(QVector, int)
+ TEST_SEQUENTIAL_ITERATION(QVector, QVariant)
+ TEST_SEQUENTIAL_ITERATION(QVector, QString)
+ TEST_SEQUENTIAL_ITERATION(QQueue, int)
+ TEST_SEQUENTIAL_ITERATION(QQueue, QVariant)
+ TEST_SEQUENTIAL_ITERATION(QQueue, QString)
+ TEST_SEQUENTIAL_ITERATION(QList, int)
+ TEST_SEQUENTIAL_ITERATION(QList, QVariant)
+ TEST_SEQUENTIAL_ITERATION(QList, QString)
+ TEST_SEQUENTIAL_ITERATION(QStack, int)
+ TEST_SEQUENTIAL_ITERATION(QStack, QVariant)
+ TEST_SEQUENTIAL_ITERATION(QStack, QString)
+ TEST_SEQUENTIAL_ITERATION(std::vector, int)
+ TEST_SEQUENTIAL_ITERATION(std::vector, QVariant)
+ TEST_SEQUENTIAL_ITERATION(std::vector, QString)
+ TEST_SEQUENTIAL_ITERATION(std::list, int)
+ TEST_SEQUENTIAL_ITERATION(std::list, QVariant)
+ TEST_SEQUENTIAL_ITERATION(std::list, QString)
+
+#ifdef TEST_FORWARD_LIST
+ qRegisterSequentialConverter<std::forward_list<int> >();
+ qRegisterSequentialConverter<std::forward_list<QVariant> >();
+ qRegisterSequentialConverter<std::forward_list<QString> >();
+ TEST_SEQUENTIAL_ITERATION(std::forward_list, int)
+ TEST_SEQUENTIAL_ITERATION(std::forward_list, QVariant)
+ TEST_SEQUENTIAL_ITERATION(std::forward_list, QString)
+#endif
+
+#define TEST_ASSOCIATIVE_ITERATION(CONTAINER, KEY_TYPE, MAPPED_TYPE) \
+ { \
+ int numSeen = 0; \
+ CONTAINER<KEY_TYPE, MAPPED_TYPE> mapping; \
+ mapping[5] = true; \
+ mapping[15] = false; \
+ \
+ QVariant mappingVariant = QVariant::fromValue(mapping); \
+ QVariantMap varMap = mappingVariant.value<QVariantMap>(); \
+ QVariantMap varHash = mappingVariant.value<QVariantMap>(); \
+ QAssociativeIterable mappingIter = mappingVariant.value<QAssociativeIterable>(); \
+ \
+ CONTAINER<KEY_TYPE, MAPPED_TYPE>::const_iterator containerIter = mapping.begin(); \
+ const CONTAINER<KEY_TYPE, MAPPED_TYPE>::const_iterator containerEnd = mapping.end(); \
+ for ( ; containerIter != containerEnd; ++containerIter, ++numSeen) \
+ { \
+ MAPPED_TYPE expected = KeyGetter<CONTAINER<KEY_TYPE, MAPPED_TYPE> >::value(containerIter); \
+ KEY_TYPE key = KeyGetter<CONTAINER<KEY_TYPE, MAPPED_TYPE> >::get(containerIter); \
+ MAPPED_TYPE actual = mappingIter.value(key).value<MAPPED_TYPE >(); \
+ QCOMPARE(varMap.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \
+ QCOMPARE(varHash.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \
+ QCOMPARE(actual, expected); \
+ } \
+ QCOMPARE(numSeen, (int)std::distance(mapping.begin(), mapping.end())); \
+ QCOMPARE(containerIter, containerEnd); \
+ \
+ }
+
+ TEST_ASSOCIATIVE_ITERATION(QHash, int, bool)
+ TEST_ASSOCIATIVE_ITERATION(QMap, int, bool)
+ TEST_ASSOCIATIVE_ITERATION(std::map, int, bool)
+#ifdef TEST_UNORDERED_MAP
+ qRegisterAssociativeConverter<StdUnorderedMap_int_bool>();
+ TEST_ASSOCIATIVE_ITERATION(std::unordered_map, int, bool)
+#endif
+}
+
+void tst_QVariant::pairElements()
+{
+ typedef QPair<QVariant, QVariant> QVariantPair;
+
+#define TEST_PAIR_ELEMENT_ACCESS(PAIR, T1, T2, VALUE1, VALUE2) \
+ { \
+ PAIR<T1, T2> p(VALUE1, VALUE2); \
+ QVariant v = QVariant::fromValue(p); \
+ \
+ QVERIFY(v.canConvert<QVariantPair>()); \
+ QVariantPair pi = v.value<QVariantPair>(); \
+ QCOMPARE(pi.first, QVariant::fromValue(VALUE1)); \
+ QCOMPARE(pi.second, QVariant::fromValue(VALUE2)); \
+ }
+
+ TEST_PAIR_ELEMENT_ACCESS(QPair, int, int, 4, 5)
+ TEST_PAIR_ELEMENT_ACCESS(std::pair, int, int, 4, 5)
+ TEST_PAIR_ELEMENT_ACCESS(QPair, QString, QString, QStringLiteral("one"), QStringLiteral("two"))
+ TEST_PAIR_ELEMENT_ACCESS(std::pair, QString, QString, QStringLiteral("one"), QStringLiteral("two"))
+ TEST_PAIR_ELEMENT_ACCESS(QPair, QVariant, QVariant, 4, 5)
+ TEST_PAIR_ELEMENT_ACCESS(std::pair, QVariant, QVariant, 4, 5)
+ TEST_PAIR_ELEMENT_ACCESS(QPair, QVariant, int, 41, 15)
+ TEST_PAIR_ELEMENT_ACCESS(std::pair, QVariant, int, 34, 65)
+ TEST_PAIR_ELEMENT_ACCESS(QPair, int, QVariant, 24, 25)
+ TEST_PAIR_ELEMENT_ACCESS(std::pair, int, QVariant, 44, 15)
+}
+
QTEST_MAIN(tst_QVariant)
#include "tst_qvariant.moc"
diff --git a/mkspecs/macx-clang-libc++-32/qplatformdefs.h b/tests/auto/corelib/plugin/qpluginloader/fakeplugin.cpp
index 2c3a8b1c09..d5c933e3af 100644
--- a/mkspecs/macx-clang-libc++-32/qplatformdefs.h
+++ b/tests/auto/corelib/plugin/qpluginloader/fakeplugin.cpp
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the qmake spec of the Qt Toolkit.
+** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,5 +39,11 @@
**
****************************************************************************/
-#include "../common/mac/qplatformdefs.h"
+#include <QtCore/qplugin.h>
+#if QT_POINTER_SIZE == 8
+QT_PLUGIN_METADATA_SECTION void *const pluginSection = (void*)(0xc0ffeec0ffeeL);
+#else
+QT_PLUGIN_METADATA_SECTION void *const pluginSection = (void*)0xc0ffee;
+#endif
+QT_PLUGIN_METADATA_SECTION const char message[] = "QTMETADATA";
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl b/tests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl
new file mode 100755
index 0000000000..ec0dd980a9
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl
@@ -0,0 +1,209 @@
+#!/usr/bin/perl
+#############################################################################
+##
+## Copyright (C) 2013 Intel Corporation.
+## Contact: http://www.qt-project.org/legal
+##
+## This file is the build configuration utility of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and Digia. For licensing terms and
+## conditions see http://qt.digia.com/licensing. For further information
+## use the contact form at http://qt.digia.com/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Digia gives you certain additional
+## rights. These rights are described in the Digia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3.0 as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU General Public License version 3.0 requirements will be
+## met: http://www.gnu.org/copyleft/gpl.html.
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+use strict;
+use constant FAT_MAGIC => 0xcafebabe;
+use constant MH_MAGIC => 0xfeedface;
+use constant MH_MAGIC_64 => 0xfeedfacf;
+use constant CPU_TYPE_X86 => 7;
+use constant CPU_TYPE_X86_64 => CPU_TYPE_X86 | 0x01000000;
+use constant CPU_SUBTYPE_I386_ALL => 3;
+use constant MH_DYLIB => 6;
+use constant LC_SEGMENT => 1;
+use constant LC_SEGMENT_64 => 0x19;
+
+my $good = pack("(L7 L2 Z16 L8 Z16 Z16 L9 . L)>",
+ MH_MAGIC, CPU_TYPE_X86, CPU_SUBTYPE_I386_ALL, MH_DYLIB, # 0-3
+ 1, # 4: ncmds
+ 4 * (37 - 6), # 5: sizeofcmds
+ 0, # 6: flags
+
+ LC_SEGMENT, # 7: cmd
+ 4 * (37 - 6), # 8: cmdsize
+ '__TEXT', # 9-12: segname
+ 0, # 13: vmaddr
+ 0x1000, # 14: vmsize
+ 0, # 15: fileoff
+ 0x204, # 16: filesize
+ 7, # 17: maxprot (rwx)
+ 5, # 18: initprot (r-x)
+ 1, # 19: nsects
+ 0, # 20: flags
+
+ 'qtmetadata', # 21-24: sectname
+ '__TEXT', # 25-28: segname
+ 0x200, # 29: addr
+ 4, # 30: size
+ 0x200, # 31: offset
+ 2, # 32: align (2^2)
+ 0, # 33: reloff
+ 0, # 34: nreloc
+ 0, # 35: flags
+ 0, # 36: reserved1
+ 0, # 37: reserved2
+
+ 0x200,
+ 0xc0ffee # data
+);
+
+my $good64 = pack("(L8 L2 Z16 Q4 L4 Z16 Z16 Q2 L8 . Q)>",
+ MH_MAGIC_64, CPU_TYPE_X86_64, CPU_SUBTYPE_I386_ALL, MH_DYLIB, # 0-3
+ 1, # 4: ncmds
+ 4 * (45 - 7), # 5: sizeofcmds
+ 0, # 6: flags
+ 0, # 7: reserved
+
+ LC_SEGMENT_64, # 8: cmd
+ 4 * (45 - 7), # 9: cmdsize
+ '__TEXT', # 10-13: segname
+ 0, # 14-15: vmaddr
+ 0x1000, # 16-17: vmsize
+ 0, # 18-19: fileoff
+ 0x208, # 20-21: filesize
+ 7, # 22: maxprot (rwx)
+ 5, # 23: initprot (r-x)
+ 1, # 24: nsects
+ 0, # 25: flags
+
+ 'qtmetadata', # 26-29: sectname
+ '__TEXT', # 30-33: segname
+ 0x200, # 34-35: addr
+ 4, # 36-37: size
+ 0x200, # 38: offset
+ 3, # 39: align (2^3)
+ 0, # 40: reloff
+ 0, # 41: nreloc
+ 0, # 42: flags
+ 0, # 43: reserved1
+ 0, # 44: reserved2
+ 0, # 45: reserved3
+
+ 0x200,
+ 0xc0ffeec0ffee # data
+);
+
+my $fat = pack("L>*",
+ FAT_MAGIC, # 1: magic
+ 2, # 2: nfat_arch
+
+ CPU_TYPE_X86, # 3: cputype
+ CPU_SUBTYPE_I386_ALL, # 4: cpusubtype
+ 0x1000, # 5: offset
+ 0x1000, # 6: size
+ 12, # 7: align (2^12)
+
+ CPU_TYPE_X86_64, # 8: cputype
+ CPU_SUBTYPE_I386_ALL, # 9: cpusubtype
+ 0x2000, # 10: offset
+ 0x1000, # 11: size
+ 12, # 12: align (2^12)
+);
+
+my $buffer;
+
+our $badcount = 1;
+sub generate($) {
+ open OUT, ">", "bad$badcount.dylib" or die("Could not open file bad$badcount.dylib: $!\n");
+ binmode OUT;
+ print OUT $_[0];
+ close OUT;
+ ++$badcount;
+}
+
+# Bad file 1-2
+# Except that the cmdsize fields are null
+$buffer = $good;
+vec($buffer, 5, 32) = 0;
+generate $buffer;
+
+$buffer = $good;
+vec($buffer, 8, 32) = 0;
+generate $buffer;
+
+# Bad file 3-4: same as above but 64-bit
+$buffer = $good64;
+vec($buffer, 5, 32) = 0;
+generate $buffer;
+
+$buffer = $good64;
+vec($buffer, 9, 32) = 0;
+generate $buffer;
+
+# Bad file 5-8: same as 1-4, but set cmdsize to bigger than file
+$buffer = $good;
+vec($buffer, 5, 32) = 0x1000;
+generate $buffer;
+
+$buffer = $good;
+vec($buffer, 8, 32) = 0x1000;
+generate $buffer;
+
+$buffer = $good64;
+vec($buffer, 5, 32) = 0x1000;
+generate $buffer;
+
+$buffer = $good64;
+vec($buffer, 9, 32) = 0x1000;
+generate $buffer;
+
+# Bad file 9-10: overflow size+offset
+$buffer = $good;
+vec($buffer, 30, 32) = 0xffffffe0;
+generate $buffer;
+
+$buffer = $good64;
+vec($buffer, 36, 32) = 0xffffffff;
+vec($buffer, 37, 32) = 0xffffffe0;
+generate $buffer;
+
+# Bad file 11: FAT binary with just the header
+generate $fat;
+
+# Bad file 12: FAT binary where the Mach contents don't match the FAT directory
+$buffer = pack("a4096 a4096 a4096", $fat, $good64, $good);
+generate $buffer;
+
+# Bad file 13: FAT binary with overflowing size
+$buffer = pack("a4096 a4096 a4096", $fat, $good, $good64);
+vec($buffer, 5, 32) = 0xfffffffe0;
+vec($buffer, 10, 32) = 0xfffffffe0;
+generate $buffer;
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro
new file mode 100644
index 0000000000..7acddc22ce
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro
@@ -0,0 +1,56 @@
+TEMPLATE = aux
+OTHER_FILES += \
+ ppcconverter.pl \
+ generate-bad.pl
+
+i386.target = good.i386.dylib
+i386.commands = $(CXX) $(CXXFLAGS) -shared -arch i386 -o $@ -I$$[QT_INSTALL_HEADERS/get] $<
+i386.depends += $$PWD/../fakeplugin.cpp
+x86_64.target = good.x86_64.dylib
+x86_64.commands = $(CXX) $(CXXFLAGS) -shared -arch x86_64 -o $@ -I$$[QT_INSTALL_HEADERS/get] $<
+x86_64.depends += $$PWD/../fakeplugin.cpp
+
+# Current Mac OS X toolchains have no compiler for PPC anymore
+# So we fake it by converting an x86-64 binary to (little-endian!) PPC64
+ppc64.target = good.ppc64.dylib
+ppc64.commands = $$PWD/ppcconverter.pl $< $@
+ppc64.depends = x86_64 $$PWD/ppcconverter.pl
+
+# Generate a fat binary with three architectures
+fat_all.target = good.fat.all.dylib
+fat_all.commands = lipo -create -output $@ \
+ -arch ppc64 $$ppc64.target \
+ -arch i386 $$i386.target \
+ -arch x86_64 $$x86_64.target
+fat_all.depends += i386 x86_64 ppc64
+
+fat_no_i386.target = good.fat.no-i386.dylib
+fat_no_i386.commands = lipo -create -output $@ -arch x86_64 $$x86_64.target -arch ppc64 $$ppc64.target
+fat_no_i386.depends += x86_64 ppc64
+
+fat_no_x86_64.target = good.fat.no-x86_64.dylib
+fat_no_x86_64.commands = lipo -create -output $@ -arch i386 $$i386.target -arch ppc64 $$ppc64.target
+fat_no_x86_64.depends += i386 ppc64
+
+fat_stub_i386.target = good.fat.stub-i386.dylib
+fat_stub_i386.commands = lipo -create -output $@ -arch ppc64 $$ppc64.target -arch_blank i386
+fat_stub_i386.depends += x86_64 ppc64
+
+fat_stub_x86_64.target = good.fat.stub-x86_64.dylib
+fat_stub_x86_64.commands = lipo -create -output $@ -arch ppc64 $$ppc64.target -arch_blank x86_64
+fat_stub_x86_64.depends += i386 ppc64
+
+bad.commands = $$PWD/generate-bad.pl
+bad.depends += $$PWD/generate-bad.pl
+
+MYTARGETS = $$fat_all.depends fat_all fat_no_x86_64 fat_no_i386 \
+ fat_stub_i386 fat_stub_x86_64 bad
+all.depends += $$MYTARGETS
+QMAKE_EXTRA_TARGETS += $$MYTARGETS all
+
+QMAKE_CLEAN += $$i386.target $$x86_64.target $$ppc64.target $$fat_all.target \
+ $$fat_no_i386.target $$fat_no_x86_64.target \
+ $$fat_stub_i386.target $$fat_stub_x86_64.target \
+ "bad*.dylib"
+
+
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/ppcconverter.pl b/tests/auto/corelib/plugin/qpluginloader/machtest/ppcconverter.pl
new file mode 100755
index 0000000000..86943161b7
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/ppcconverter.pl
@@ -0,0 +1,112 @@
+#!/usr/bin/perl
+#############################################################################
+##
+## Copyright (C) 2013 Intel Corporation.
+## Contact: http://www.qt-project.org/legal
+##
+## This file is the build configuration utility of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and Digia. For licensing terms and
+## conditions see http://qt.digia.com/licensing. For further information
+## use the contact form at http://qt.digia.com/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Digia gives you certain additional
+## rights. These rights are described in the Digia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3.0 as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU General Public License version 3.0 requirements will be
+## met: http://www.gnu.org/copyleft/gpl.html.
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+# Changes the Mach-O file type header to PowerPC.
+#
+# The header is (from mach-o/loader.h):
+# struct mach_header {
+# uint32_t magic; /* mach magic number identifier */
+# cpu_type_t cputype; /* cpu specifier */
+# cpu_subtype_t cpusubtype; /* machine specifier */
+# uint32_t filetype; /* type of file */
+# uint32_t ncmds; /* number of load commands */
+# uint32_t sizeofcmds; /* the size of all the load commands */
+# uint32_t flags; /* flags */
+# };
+#
+# The 64-bit header is identical in the first three fields, except for a different
+# magic number. We will not touch the magic number, we'll just reset the cputype
+# field to the PowerPC type and the subtype field to zero.
+#
+# We will not change the file's endianness. That means we might create a little-endian
+# PowerPC binary, which could not be run in real life.
+#
+# We will also not change the 64-bit ABI flag, which is found in the cputype's high
+# byte. That means we'll create a PPC64 binary if fed a 64-bit input.
+#
+use strict;
+use constant MH_MAGIC => 0xfeedface;
+use constant MH_CIGAM => 0xcefaedfe;
+use constant MH_MAGIC_64 => 0xfeedfacf;
+use constant MH_CIGAM_64 => 0xcffaedfe;
+use constant CPU_TYPE_POWERPC => 18;
+use constant CPU_SUBTYPE_POWERPC_ALL => 0;
+
+my $infile = shift @ARGV or die("Missing input filename");
+my $outfile = shift @ARGV or die("Missing output filename");
+
+open IN, "<$infile" or die("Can't open $infile for reading: $!\n");
+open OUT, ">$outfile" or die("Can't open $outfile for writing: $!\n");
+
+binmode IN;
+binmode OUT;
+
+# Read the first 12 bytes, which includes the interesting fields of the header
+my $buffer;
+read(IN, $buffer, 12);
+
+my $magic = vec($buffer, 0, 32);
+if ($magic == MH_MAGIC || $magic == MH_MAGIC_64) {
+ # Big endian
+ # The low byte of cputype is at offset 7
+ vec($buffer, 7, 8) = CPU_TYPE_POWERPC;
+} elsif ($magic == MH_CIGAM || $magic == MH_CIGAM_64) {
+ # Little endian
+ # The low byte of cpytype is at offset 4
+ vec($buffer, 4, 8) = CPU_TYPE_POWERPC;
+} else {
+ $magic = '';
+ $magic .= sprintf("%02X ", $_) for unpack("CCCC", $buffer);
+ die("Invalid input. Unknown magic $magic\n");
+}
+vec($buffer, 2, 32) = CPU_SUBTYPE_POWERPC_ALL;
+
+print OUT $buffer;
+
+# Copy the rest
+while (!eof(IN)) {
+ read(IN, $buffer, 4096) and
+ print OUT $buffer or
+ die("Problem copying: $!\n");
+}
+close(IN);
+close(OUT);
diff --git a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
index 0cba19887e..8d117793bf 100644
--- a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
+++ b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
@@ -5,6 +5,7 @@ SUBDIRS = lib \
theplugin \
tst
!win32: !mac: SUBDIRS += almostplugin
+macx-*: SUBDIRS += machtest
TARGET = tst_qpluginloader
# no special install rule for subdir
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro b/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro
index a7a9661a54..3894c90ae3 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro
+++ b/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro
@@ -2,7 +2,8 @@ CONFIG += testcase
CONFIG += parallel_test
TARGET = ../tst_qpluginloader
QT = core testlib
-SOURCES = ../tst_qpluginloader.cpp
+contains(QT_CONFIG, private_tests): QT += core-private
+SOURCES = ../tst_qpluginloader.cpp ../fakeplugin.cpp
HEADERS = ../theplugin/plugininterface.h
CONFIG -= app_bundle
@@ -14,5 +15,5 @@ win32 {
}
}
-TESTDATA += ../elftest
+TESTDATA += ../elftest ../machtest
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
index cef4f53101..351e3a23e0 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
@@ -44,6 +44,10 @@
#include <qpluginloader.h>
#include "theplugin/plugininterface.h"
+#if defined(QT_BUILD_INTERNAL) && defined(Q_OF_MACH_O)
+# include <QtCore/private/qmachparser_p.h>
+#endif
+
// Helper macros to let us know if some suffixes are valid
#define bundle_VALID false
#define dylib_VALID false
@@ -118,6 +122,8 @@ private slots:
void deleteinstanceOnUnload();
void loadDebugObj();
void loadCorruptElf();
+ void loadMachO_data();
+ void loadMachO();
#if defined (Q_OS_UNIX)
void loadGarbage();
#endif
@@ -311,6 +317,78 @@ void tst_QPluginLoader::loadCorruptElf()
#endif
}
+void tst_QPluginLoader::loadMachO_data()
+{
+#ifdef Q_OF_MACH_O
+ QTest::addColumn<int>("parseResult");
+
+ QTest::newRow("/dev/null") << int(QMachOParser::NotSuitable);
+ QTest::newRow("elftest/debugobj.so") << int(QMachOParser::NotSuitable);
+ QTest::newRow("tst_qpluginloader.cpp") << int(QMachOParser::NotSuitable);
+ QTest::newRow("tst_qpluginloader") << int(QMachOParser::NotSuitable);
+
+# ifdef Q_PROCESSOR_X86_64
+ QTest::newRow("machtest/good.x86_64.dylib") << int(QMachOParser::QtMetaDataSection);
+ QTest::newRow("machtest/good.i386.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.fat.no-x86_64.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.fat.no-i386.dylib") << int(QMachOParser::QtMetaDataSection);
+# elif defined(Q_PROCESSOR_X86_32)
+ QTest::newRow("machtest/good.i386.dylib") << int(QMachOParser::QtMetaDataSection);
+ QTest::newRow("machtest/good.x86_64.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.fat.no-i386.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.fat.no-x86_64.dylib") << int(QMachOParser::QtMetaDataSection);
+# endif
+# ifndef Q_PROCESSOR_POWER_64
+ QTest::newRow("machtest/good.ppc64.dylib") << int(QMachOParser::NotSuitable);
+# endif
+
+ QTest::newRow("machtest/good.fat.all.dylib") << int(QMachOParser::QtMetaDataSection);
+ QTest::newRow("machtest/good.fat.stub-x86_64.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.fat.stub-i386.dylib") << int(QMachOParser::NotSuitable);
+
+ QDir d(QFINDTESTDATA("machtest"));
+ QStringList badlist = d.entryList(QStringList() << "bad*.dylib");
+ foreach (const QString &bad, badlist)
+ QTest::newRow(qPrintable("machtest/" + bad)) << int(QMachOParser::NotSuitable);
+#endif
+}
+
+void tst_QPluginLoader::loadMachO()
+{
+#ifdef Q_OF_MACH_O
+ QFile f(QFINDTESTDATA(QTest::currentDataTag()));
+ QVERIFY(f.open(QIODevice::ReadOnly));
+ QByteArray data = f.readAll();
+
+ long pos;
+ ulong len;
+ QString errorString;
+ int r = QMachOParser::parse(data.constData(), data.size(), f.fileName(), &errorString, &pos, &len);
+
+ QFETCH(int, parseResult);
+ QCOMPARE(r, parseResult);
+
+ if (r == QMachOParser::NotSuitable)
+ return;
+
+ QVERIFY(pos > 0);
+ QVERIFY(len >= sizeof(void*));
+ QVERIFY(pos + long(len) < data.size());
+ QCOMPARE(pos & (sizeof(void*) - 1), 0UL);
+
+ void *value = *(void**)(data.constData() + pos);
+ QCOMPARE(value, sizeof(void*) > 4 ? (void*)(0xc0ffeec0ffeeL) : (void*)0xc0ffee);
+
+ // now that we know it's valid, let's try to make it invalid
+ ulong offeredlen = pos;
+ do {
+ --offeredlen;
+ r = QMachOParser::parse(data.constData(), offeredlen, f.fileName(), &errorString, &pos, &len);
+ QVERIFY2(r == QMachOParser::NotSuitable, qPrintable(QString("Failed at size 0x%1").arg(offeredlen, 0, 16)));
+ } while (offeredlen);
+#endif
+}
+
#if defined (Q_OS_UNIX)
void tst_QPluginLoader::loadGarbage()
{
diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
index 3c0e132a0a..fb34afb880 100644
--- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
+++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
@@ -214,22 +214,22 @@ void tst_QThreadPool::waitcomplete()
QCOMPARE(testFunctionCount, runs);
}
-volatile bool ran;
+QAtomicInt ran; // bool
class TestTask : public QRunnable
{
public:
void run()
{
- ran = true;
+ ran.store(true);
}
};
void tst_QThreadPool::runTask()
{
QThreadPool manager;
- ran = false;
+ ran.store(false);
manager.start(new TestTask());
- QTRY_VERIFY(ran);
+ QTRY_VERIFY(ran.load());
}
/*
@@ -237,19 +237,19 @@ void tst_QThreadPool::runTask()
*/
void tst_QThreadPool::singleton()
{
- ran = false;
+ ran.store(false);
QThreadPool::globalInstance()->start(new TestTask());
- QTRY_VERIFY(ran);
+ QTRY_VERIFY(ran.load());
}
-int *value = 0;
+QAtomicInt *value = 0;
class IntAccessor : public QRunnable
{
public:
void run()
{
for (int i = 0; i < 100; ++i) {
- ++(*value);
+ value->ref();
QTest::qSleep(1);
}
}
@@ -261,7 +261,7 @@ public:
*/
void tst_QThreadPool::destruction()
{
- value = new int;
+ value = new QAtomicInt;
QThreadPool *threadManager = new QThreadPool();
threadManager->start(new IntAccessor());
threadManager->start(new IntAccessor());
@@ -681,8 +681,8 @@ void tst_QThreadPool::tryStart()
}
QMutex mutex;
-int activeThreads = 0;
-int peakActiveThreads = 0;
+QAtomicInt activeThreads;
+QAtomicInt peakActiveThreads;
void tst_QThreadPool::tryStartPeakThreadCount()
{
class CounterTask : public QRunnable
@@ -694,14 +694,14 @@ void tst_QThreadPool::tryStartPeakThreadCount()
{
{
QMutexLocker lock(&mutex);
- ++activeThreads;
- peakActiveThreads = qMax(peakActiveThreads, activeThreads);
+ activeThreads.ref();
+ peakActiveThreads.store(qMax(peakActiveThreads.load(), activeThreads.load()));
}
QTest::qWait(100);
{
QMutexLocker lock(&mutex);
- --activeThreads;
+ activeThreads.deref();
}
}
};
@@ -713,13 +713,13 @@ void tst_QThreadPool::tryStartPeakThreadCount()
if (threadPool.tryStart(&task) == false)
QTest::qWait(10);
}
- QCOMPARE(peakActiveThreads, QThread::idealThreadCount());
+ QCOMPARE(peakActiveThreads.load(), QThread::idealThreadCount());
for (int i = 0; i < 20; ++i) {
if (threadPool.tryStart(&task) == false)
QTest::qWait(10);
}
- QCOMPARE(peakActiveThreads, QThread::idealThreadCount());
+ QCOMPARE(peakActiveThreads.load(), QThread::idealThreadCount());
}
void tst_QThreadPool::tryStartCount()
diff --git a/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp b/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp
index 72bf5c58ca..c18ba4d05c 100644
--- a/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp
+++ b/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp
@@ -78,10 +78,22 @@ private slots:
void qCountContainer() const;
void binaryFindOnLargeContainer() const;
-#if Q_TEST_PERFORMANCE
+ void popCount08_data() { popCount_data_impl(sizeof(quint8 )); }
+ void popCount16_data() { popCount_data_impl(sizeof(quint16)); }
+ void popCount32_data() { popCount_data_impl(sizeof(quint32)); }
+ void popCount64_data() { popCount_data_impl(sizeof(quint64)); }
+ void popCount08() { popCount_impl<quint8 >(); }
+ void popCount16() { popCount_impl<quint16>(); }
+ void popCount32() { popCount_impl<quint32>(); }
+ void popCount64() { popCount_impl<quint64>(); }
+
private:
+#if Q_TEST_PERFORMANCE
void performance();
#endif
+ void popCount_data_impl(size_t sizeof_T_Int);
+ template <typename T_Int>
+ void popCount_impl();
};
class TestInt
@@ -1007,6 +1019,72 @@ void tst_QAlgorithms::binaryFindOnLargeContainer() const
QCOMPARE(foundIt.pos(), 1073987655);
}
+// alternative implementation of qPopulationCount for comparison:
+static const uint bitsSetInNibble[] = {
+ 0, 1, 1, 2, 1, 2, 2, 3,
+ 1, 2, 2, 3, 2, 3, 3, 4,
+};
+Q_STATIC_ASSERT(sizeof bitsSetInNibble / sizeof *bitsSetInNibble == 16);
+
+static Q_DECL_CONSTEXPR uint bitsSetInByte(quint8 byte)
+{
+ return bitsSetInNibble[byte & 0xF] + bitsSetInNibble[byte >> 4];
+}
+static Q_DECL_CONSTEXPR uint bitsSetInShort(quint16 word)
+{
+ return bitsSetInByte(word & 0xFF) + bitsSetInByte(word >> 8);
+}
+static Q_DECL_CONSTEXPR uint bitsSetInInt(quint32 word)
+{
+ return bitsSetInShort(word & 0xFFFF) + bitsSetInShort(word >> 16);
+}
+static Q_DECL_CONSTEXPR uint bitsSetInInt64(quint64 word)
+{
+ return bitsSetInInt(word & 0xFFFFFFFF) + bitsSetInInt(word >> 32);
+}
+
+
+void tst_QAlgorithms::popCount_data_impl(size_t sizeof_T_Int)
+{
+ using namespace QTest;
+ addColumn<quint64>("input");
+ addColumn<uint>("expected");
+
+ for (uint i = 0; i < UCHAR_MAX; ++i) {
+ const uchar byte = static_cast<uchar>(i);
+ const uint bits = bitsSetInByte(byte);
+ const quint64 value = static_cast<quint64>(byte);
+ const quint64 input = value << ((i % sizeof_T_Int) * 8U);
+ newRow(qPrintable(QString().sprintf("0x%016llx", input))) << input << bits;
+ }
+
+ // and some random ones:
+ if (sizeof_T_Int >= 8)
+ for (size_t i = 0; i < 1000; ++i) {
+ const quint64 input = quint64(qrand()) << 32 | quint32(qrand());
+ newRow(qPrintable(QString().sprintf("0x%016llx", input))) << input << bitsSetInInt64(input);
+ }
+ else if (sizeof_T_Int >= 2)
+ for (size_t i = 0; i < 1000 ; ++i) {
+ const quint32 input = qrand();
+ if (sizeof_T_Int >= 4)
+ newRow(qPrintable(QString().sprintf("0x%08x", input))) << quint64(input) << bitsSetInInt(input);
+ else
+ newRow(qPrintable(QString().sprintf("0x%04x", quint16(input & 0xFFFF)))) << quint64(input & 0xFFFF) << bitsSetInShort(input & 0xFFFF);
+ }
+}
+
+template <typename T_Int>
+void tst_QAlgorithms::popCount_impl()
+{
+ QFETCH(quint64, input);
+ QFETCH(uint, expected);
+
+ const T_Int value = static_cast<T_Int>(input);
+
+ QCOMPARE(qPopulationCount(value), expected);
+}
+
QTEST_APPLESS_MAIN(tst_QAlgorithms)
#include "tst_qalgorithms.moc"
diff --git a/tests/auto/corelib/tools/qdate/tst_qdate.cpp b/tests/auto/corelib/tools/qdate/tst_qdate.cpp
index 310528ba27..728a4244a1 100644
--- a/tests/auto/corelib/tools/qdate/tst_qdate.cpp
+++ b/tests/auto/corelib/tools/qdate/tst_qdate.cpp
@@ -944,6 +944,61 @@ void tst_QDate::fromStringDateFormat_data()
QTest::newRow("iso2") << QDate(1999, 11, 14).toString(Qt::ISODate) << Qt::ISODate << QDate(1999, 11, 14);
QTest::newRow("iso3") << QString("0999-01-01") << Qt::ISODate << QDate(999, 1, 1);
QTest::newRow("iso3b") << QString("0999-01-01") << Qt::ISODate << QDate(999, 1, 1);
+
+ // Test Qt::RFC2822Date format (RFC 2822).
+ QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDate(1987, 2, 13);
+ QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QDate(1970, 1, 1);
+ // No timezone
+ QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
+ << Qt::RFC2822Date << QDate(1970, 1, 1);
+ // No time specified
+ QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002")
+ << Qt::RFC2822Date << QDate(2002, 11, 1);
+ QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002")
+ << Qt::RFC2822Date << QDate(2002, 11, 1);
+ // Test invalid month, day, year
+ QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Fev 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100")
+ << Qt::RFC2822Date << QDate();
+ // Test invalid characters (should ignore invalid characters at end of string).
+ QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
+ << Qt::RFC2822Date << QDate(2012, 1, 1);
+ QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000")
+ << Qt::RFC2822Date << QDate();
+
+ // Test Qt::RFC2822Date format (RFC 850 and 1036).
+ QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QDate(1987, 2, 13);
+ // No timezone
+ QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
+ << Qt::RFC2822Date << QDate(1970, 1, 1);
+ // No time specified
+ QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002")
+ << Qt::RFC2822Date << QDate(2002, 11, 1);
+ // Test invalid characters (should ignore invalid characters at end of string).
+ QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
+ << Qt::RFC2822Date << QDate(2012, 1, 1);
+ QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 850 and 1036 invalid character 2 at front") << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0000")
+ << Qt::RFC2822Date << QDate();
+
+ QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << QDate();
}
void tst_QDate::fromStringDateFormat()
@@ -1072,6 +1127,7 @@ void tst_QDate::toStringDateFormat_data()
QTest::newRow("data3") << QDate(1974,12,1) << Qt::ISODate << QString("1974-12-01");
QTest::newRow("year < 0") << QDate(-1,1,1) << Qt::ISODate << QString();
QTest::newRow("year > 9999") << QDate(-1,1,1) << Qt::ISODate << QString();
+ QTest::newRow("RFC2822Date") << QDate(1974,12,1) << Qt::RFC2822Date << QString("01 Dec 1974");
}
void tst_QDate::toStringDateFormat()
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index 0ec3f64020..a0e55e9ae1 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -85,6 +85,8 @@ private slots:
void fromMSecsSinceEpoch();
void toString_isoDate_data();
void toString_isoDate();
+ void toString_rfcDate_data();
+ void toString_rfcDate();
void toString_enumformat();
void toString_strformat_data();
void toString_strformat();
@@ -556,22 +558,25 @@ void tst_QDateTime::toString_isoDate_data()
QTest::newRow("localtime")
<< QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34))
- << QString("1978-11-09T13:28:34");
+ << QString("1978-11-09T13:28:34.000");
QTest::newRow("UTC")
<< QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), Qt::UTC)
- << QString("1978-11-09T13:28:34Z");
+ << QString("1978-11-09T13:28:34.000Z");
QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34));
dt.setUtcOffset(19800);
QTest::newRow("positive OffsetFromUTC")
<< dt
- << QString("1978-11-09T13:28:34+05:30");
+ << QString("1978-11-09T13:28:34.000+05:30");
dt.setUtcOffset(-7200);
QTest::newRow("negative OffsetFromUTC")
<< dt
- << QString("1978-11-09T13:28:34-02:00");
+ << QString("1978-11-09T13:28:34.000-02:00");
QTest::newRow("invalid")
<< QDateTime(QDate(-1, 11, 9), QTime(13, 28, 34), Qt::UTC)
<< QString();
+ QTest::newRow("999 milliseconds UTC")
+ << QDateTime(QDate(2000, 1, 1), QTime(13, 28, 34, 999), Qt::UTC)
+ << QString("2000-01-01T13:28:34.999Z");
}
void tst_QDateTime::toString_isoDate()
@@ -582,6 +587,44 @@ void tst_QDateTime::toString_isoDate()
QCOMPARE(dt.toString(Qt::ISODate), formatted);
}
+void tst_QDateTime::toString_rfcDate_data()
+{
+ QTest::addColumn<QDateTime>("dt");
+ QTest::addColumn<QString>("formatted");
+
+ if (europeanTimeZone) {
+ QTest::newRow("localtime")
+ << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34))
+ << QString("09 Nov 1978 13:28:34 +0100");
+ }
+ QTest::newRow("UTC")
+ << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), Qt::UTC)
+ << QString("09 Nov 1978 13:28:34 +0000");
+ QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34));
+ dt.setUtcOffset(19800);
+ QTest::newRow("positive OffsetFromUTC")
+ << dt
+ << QString("09 Nov 1978 13:28:34 +0530");
+ dt.setUtcOffset(-7200);
+ QTest::newRow("negative OffsetFromUTC")
+ << dt
+ << QString("09 Nov 1978 13:28:34 -0200");
+ QTest::newRow("invalid")
+ << QDateTime(QDate(1978, 13, 9), QTime(13, 28, 34), Qt::UTC)
+ << QString();
+ QTest::newRow("999 milliseconds UTC")
+ << QDateTime(QDate(2000, 1, 1), QTime(13, 28, 34, 999), Qt::UTC)
+ << QString("01 Jan 2000 13:28:34 +0000");
+}
+
+void tst_QDateTime::toString_rfcDate()
+{
+ QFETCH(QDateTime, dt);
+ QFETCH(QString, formatted);
+
+ QCOMPARE(dt.toString(Qt::RFC2822Date), formatted);
+}
+
void tst_QDateTime::toString_enumformat()
{
QDateTime dt1(QDate(1995, 5, 20), QTime(12, 34, 56));
@@ -591,7 +634,7 @@ void tst_QDateTime::toString_enumformat()
QVERIFY(!str1.isEmpty()); // It's locale dependent everywhere
QString str2 = dt1.toString(Qt::ISODate);
- QCOMPARE(str2, QString("1995-05-20T12:34:56"));
+ QCOMPARE(str2, QString("1995-05-20T12:34:56.000"));
QString str3 = dt1.toString(Qt::LocalDate);
QVERIFY(!str3.isEmpty());
@@ -1611,6 +1654,8 @@ void tst_QDateTime::fromStringDateFormat_data()
<< Qt::TextDate << invalidDateTime();
QTest::newRow("text invalid gmt minute") << QString::fromLatin1("Thu 1. Jan 1970 00:00:00 GMT+000X")
<< Qt::TextDate << invalidDateTime();
+ QTest::newRow("text second fraction") << QString::fromLatin1("Mon 6. May 2013 01:02:03.456")
+ << Qt::TextDate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 3, 456));
// Test Qt::ISODate format.
QTest::newRow("ISO +01:00") << QString::fromLatin1("1987-02-13T13:24:51+01:00")
@@ -1697,6 +1742,79 @@ void tst_QDateTime::fromStringDateFormat_data()
QTest::newRow("ISO .99999 of a minute (comma)") << QString::fromLatin1("2012-01-01T08:00,99999")
<< Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 59, 999), Qt::LocalTime);
QTest::newRow("ISO empty") << QString::fromLatin1("") << Qt::ISODate << invalidDateTime();
+
+ // Test Qt::RFC2822Date format (RFC 2822).
+ QTest::newRow("RFC 2822 +0100") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
+ QTest::newRow("RFC 2822 with day +0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
+ QTest::newRow("RFC 2822 -0100") << QString::fromLatin1("13 Feb 1987 13:24:51 -0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC);
+ QTest::newRow("RFC 2822 with day -0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 -0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC);
+ QTest::newRow("RFC 2822 +0000") << QString::fromLatin1("01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
+ QTest::newRow("RFC 2822 with day +0000") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
+ QTest::newRow("RFC 2822 +0000") << QString::fromLatin1("01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
+ QTest::newRow("RFC 2822 with day +0000") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
+ // No timezone assume UTC
+ QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
+ // No time specified
+ QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002")
+ << Qt::RFC2822Date << invalidDateTime();
+ QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002")
+ << Qt::RFC2822Date << invalidDateTime();
+ // Test invalid month, day, year
+ QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << invalidDateTime();
+ QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Fev 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << invalidDateTime();
+ QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100")
+ << Qt::RFC2822Date << invalidDateTime();
+ // Test invalid characters (should ignore invalid characters at end of string).
+ QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
+ << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC);
+ QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000")
+ << Qt::RFC2822Date << invalidDateTime();
+ QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!")
+ << Qt::RFC2822Date << invalidDateTime();
+ QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..")
+ << Qt::RFC2822Date << invalidDateTime();
+ QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000")
+ << Qt::RFC2822Date << invalidDateTime();
+
+ // Test Qt::RFC2822Date format (RFC 850 and 1036).
+ QTest::newRow("RFC 850 and 1036 +0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
+ QTest::newRow("RFC 850 and 1036 -0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 -0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC);
+ QTest::newRow("RFC 850 and 1036 +0000") << QString::fromLatin1("Thu Jan 01 00:12:34 1970 +0000")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
+ QTest::newRow("RFC 850 and 1036 +0000") << QString::fromLatin1("Thu Jan 01 00:12:34 1970 +0000")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
+ // No timezone assume UTC
+ QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
+ // No time specified
+ QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002")
+ << Qt::RFC2822Date << invalidDateTime();
+ // Test invalid characters (should ignore invalid characters at end of string).
+ QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
+ << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC);
+ QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000")
+ << Qt::RFC2822Date << invalidDateTime();
+ QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!")
+ << Qt::RFC2822Date << invalidDateTime();
+ QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..")
+ << Qt::RFC2822Date << invalidDateTime();
+ QTest::newRow("RFC 850 and 1036 invalid character 2 at front") << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0000")
+ << Qt::RFC2822Date << invalidDateTime();
+
+ QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << invalidDateTime();
}
void tst_QDateTime::fromStringDateFormat()
diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
index fa747b3c18..3348b49110 100644
--- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
+++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
@@ -730,14 +730,16 @@ double static inline _fast_cbrt(double d)
void tst_QEasingCurve::testCbrtDouble()
{
- const qreal errorBound = 0.0001;
+ const double errorBound = 0.0001;
for (int i = 0; i < 100000; i++) {
double d = double(i) / 1000.0;
double t = _fast_cbrt(d);
const double t_cubic = t * t * t;
- t = t * (t_cubic + d + d) / (t_cubic + t_cubic + d);
+ const double f = t_cubic + t_cubic + d;
+ if (f != 0.0)
+ t = t * (t_cubic + d + d) / f;
double expected = pow(d, 1.0/3.0);
@@ -754,14 +756,16 @@ void tst_QEasingCurve::testCbrtDouble()
void tst_QEasingCurve::testCbrtFloat()
{
- const qreal errorBound = 0.0005;
+ const float errorBound = 0.0005;
- for (int i = 1; i < 100000; i++) {
+ for (int i = 0; i < 100000; i++) {
float f = float(i) / 1000.0f;
float t = _fast_cbrt(f);
const float t_cubic = t * t * t;
- t = t * (t_cubic + f + f) / (t_cubic + t_cubic + f);
+ const float fac = t_cubic + t_cubic + f;
+ if (fac != 0.0f)
+ t = t * (t_cubic + f + f) / fac;
float expected = pow(f, float(1.0/3.0));
diff --git a/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro b/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro
index 5fa529e175..48a3b9ee9c 100644
--- a/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro
+++ b/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro
@@ -1,4 +1,5 @@
CONFIG += testcase parallel_test
+contains(QT_CONFIG, c++11):CONFIG += c++11
TARGET = tst_qscopedpointer
QT = core testlib
SOURCES = tst_qscopedpointer.cpp
diff --git a/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp b/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp
index 66ea3e940c..cb0382eb66 100644
--- a/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp
+++ b/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp
@@ -42,6 +42,8 @@
#include <QtTest/QtTest>
#include <QtCore/QScopedPointer>
+#include <utility>
+
/*!
\class tst_QScopedPointer
\internal
@@ -73,6 +75,7 @@ private Q_SLOTS:
void objectSize();
void comparison();
void array();
+ void move();
// TODO instanciate on const object
};
@@ -458,6 +461,158 @@ void tst_QScopedPointer::array()
QCOMPARE(instCount, RefCounted::instanceCount.load());
}
+#ifdef Q_COMPILER_RVALUE_REFS
+struct CountedInteger
+{
+ CountedInteger(int i) : i(i)
+ {
+ ++instanceCount;
+ }
+ ~CountedInteger()
+ {
+ --instanceCount;
+ }
+ CountedInteger(const CountedInteger &c)
+ : i(c.i)
+ {
+ ++instanceCount;
+ }
+
+ static int instanceCount;
+ int i;
+};
+
+int CountedInteger::instanceCount = 0;
+
+QScopedPointer<CountedInteger> returnScopedPointer(int i)
+{
+ return QScopedPointer<CountedInteger>(new CountedInteger(i));
+}
+#endif
+
+void tst_QScopedPointer::move()
+{
+#ifndef Q_COMPILER_RVALUE_REFS
+ QSKIP("This test requires rvalues refs");
+#else
+ QCOMPARE(CountedInteger::instanceCount, 0);
+
+ {
+ QScopedPointer<CountedInteger> p = returnScopedPointer(42);
+ QVERIFY(!p.isNull());
+ QCOMPARE(p->i, 42);
+ QCOMPARE(CountedInteger::instanceCount, 1);
+
+ QScopedPointer<CountedInteger> q = returnScopedPointer(51);
+ QVERIFY(!q.isNull());
+ QCOMPARE(q->i, 51);
+ QCOMPARE(CountedInteger::instanceCount, 2);
+
+ q = returnScopedPointer(123);
+ QVERIFY(!q.isNull());
+ QCOMPARE(q->i, 123);
+ QCOMPARE(CountedInteger::instanceCount, 2);
+
+ p = std::move(q);
+ QVERIFY(!p.isNull());
+ QCOMPARE(p->i, 123);
+ QVERIFY(q.isNull());
+ QCOMPARE(CountedInteger::instanceCount, 1);
+
+ p = std::move(q);
+ QVERIFY(p.isNull());
+ QVERIFY(q.isNull());
+ QCOMPARE(CountedInteger::instanceCount, 0);
+ }
+
+ QCOMPARE(CountedInteger::instanceCount, 0);
+
+ {
+ QScopedPointer<CountedInteger> p = returnScopedPointer(1024);
+ QVERIFY(!p.isNull());
+ QCOMPARE(p->i, 1024);
+ QCOMPARE(CountedInteger::instanceCount, 1);
+
+ p.reset();
+ QVERIFY(p.isNull());
+ QCOMPARE(CountedInteger::instanceCount, 0);
+
+ p = returnScopedPointer(1024);
+ const CountedInteger * const rawPtr = p.data();
+ p = std::move(p);
+ // now p is in a "valid, but unspecified state". so the test must not crash.
+ // we do actually know that this move should've been a noop.
+ QVERIFY(!p.isNull());
+ QCOMPARE(p.data(), rawPtr);
+ QCOMPARE(p->i, 1024);
+ QCOMPARE(CountedInteger::instanceCount, 1);
+
+ p.reset();
+ QVERIFY(p.isNull());
+ QCOMPARE(CountedInteger::instanceCount, 0);
+ }
+
+ QCOMPARE(CountedInteger::instanceCount, 0);
+
+ {
+ QScopedPointer<CountedInteger> p = returnScopedPointer(-1);
+ QVERIFY(!p.isNull());
+ QCOMPARE(p->i, -1);
+ QCOMPARE(CountedInteger::instanceCount, 1);
+ }
+
+ QCOMPARE(CountedInteger::instanceCount, 0);
+
+ {
+ QScopedPointer<CountedInteger> p = returnScopedPointer(0);
+ QVERIFY(!p.isNull());
+ QCOMPARE(p->i, 0);
+ QCOMPARE(CountedInteger::instanceCount, 1);
+
+ QScopedPointer<CountedInteger> q;
+ QVERIFY(q.isNull());
+
+ p = std::move(q);
+ QVERIFY(p.isNull());
+ QVERIFY(q.isNull());
+ QCOMPARE(CountedInteger::instanceCount, 0);
+ }
+
+ QCOMPARE(CountedInteger::instanceCount, 0);
+
+ {
+ QScopedPointer<CountedInteger> p;
+ QVERIFY(p.isNull());
+ QCOMPARE(CountedInteger::instanceCount, 0);
+
+ QScopedPointer<CountedInteger> q = returnScopedPointer(123);
+ QVERIFY(!q.isNull());
+ QCOMPARE(q->i, 123);
+ QCOMPARE(CountedInteger::instanceCount, 1);
+
+ p = std::move(q);
+ QVERIFY(!p.isNull());
+ QCOMPARE(p->i, 123);
+ QVERIFY(q.isNull());
+ QCOMPARE(CountedInteger::instanceCount, 1);
+ }
+
+ QCOMPARE(CountedInteger::instanceCount, 0);
+
+ {
+ QScopedPointer<CountedInteger> p;
+ QVERIFY(p.isNull());
+ QCOMPARE(CountedInteger::instanceCount, 0);
+
+ p = returnScopedPointer(2001);
+ QVERIFY(!p.isNull());
+ QCOMPARE(p->i, 2001);
+ QCOMPARE(CountedInteger::instanceCount, 1);
+ }
+
+ QCOMPARE(CountedInteger::instanceCount, 0);
+#endif
+}
QTEST_MAIN(tst_QScopedPointer)
#include "tst_qscopedpointer.moc"
diff --git a/tests/auto/corelib/tools/qtime/tst_qtime.cpp b/tests/auto/corelib/tools/qtime/tst_qtime.cpp
index 97645ea7f6..675aeafc06 100644
--- a/tests/auto/corelib/tools/qtime/tst_qtime.cpp
+++ b/tests/auto/corelib/tools/qtime/tst_qtime.cpp
@@ -600,6 +600,59 @@ void tst_QTime::fromStringDateFormat_data()
QTest::newRow("IsoDate - data2") << QString("19:03:54.998601") << Qt::ISODate << QTime(19, 3, 54, 999);
QTest::newRow("IsoDate - data3") << QString("19:03:54.999601") << Qt::ISODate << QTime(19, 3, 54, 999);
QTest::newRow("IsoDate - minute fraction midnight") << QString("24:00,0") << Qt::ISODate << QTime(0, 0, 0, 0);
+
+ // Test Qt::RFC2822Date format (RFC 2822).
+ QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QTime(0, 12, 34);
+ // No timezone
+ QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
+ << Qt::RFC2822Date << QTime(0, 12, 34);
+ // No time specified
+ QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002")
+ << Qt::RFC2822Date << invalidTime();
+ // Test invalid month, day, year
+ QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Fev 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ // Test invalid characters (should ignore invalid characters at end of string).
+ QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
+ << Qt::RFC2822Date << QTime(8, 0, 0);
+ QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000")
+ << Qt::RFC2822Date << invalidTime();
+
+ // Test Qt::RFC2822Date format (RFC 850 and 1036).
+ QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ // No timezone
+ QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
+ << Qt::RFC2822Date << QTime(0, 12, 34);
+ // No time specified
+ QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002")
+ << Qt::RFC2822Date << invalidTime();
+ // Test invalid characters (should ignore invalid characters at end of string).
+ QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
+ << Qt::RFC2822Date << QTime(8, 0, 0);
+ QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..")
+ << Qt::RFC2822Date << invalidTime();
+
+ QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << invalidTime();
}
void tst_QTime::fromStringDateFormat()
@@ -614,25 +667,28 @@ void tst_QTime::fromStringDateFormat()
void tst_QTime::toStringDateFormat_data()
{
- // Since we can't define an element of Qt::DateFormat, str1 will be the string
- // in TextDate format, and str2 will be the time in ISODate format.
-
- QTest::addColumn<QTime>("t");
- QTest::addColumn<QString>("str1");
- QTest::addColumn<QString>("str2");
-
- QTest::newRow( "data0" ) << QTime(0,0,0,0) << QString("00:00:00") << QString("00:00:00");
- QTest::newRow( "data1" ) << QTime(10,12,34,0) << QString("10:12:34") << QString("10:12:34");
+ QTest::addColumn<QTime>("time");
+ QTest::addColumn<Qt::DateFormat>("format");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("00:00:00.000") << QTime(0, 0, 0, 0) << Qt::TextDate << QString("00:00:00.000");
+ QTest::newRow("ISO 00:00:00.000") << QTime(0, 0, 0, 0) << Qt::ISODate << QString("00:00:00.000");
+ QTest::newRow("Text 10:12:34.000") << QTime(10, 12, 34, 0) << Qt::TextDate << QString("10:12:34.000");
+ QTest::newRow("ISO 10:12:34.000") << QTime(10, 12, 34, 0) << Qt::ISODate << QString("10:12:34.000");
+ QTest::newRow("Text 10:12:34.001") << QTime(10, 12, 34, 001) << Qt::TextDate << QString("10:12:34.001");
+ QTest::newRow("ISO 10:12:34.001") << QTime(10, 12, 34, 001) << Qt::ISODate << QString("10:12:34.001");
+ QTest::newRow("Text 10:12:34.999") << QTime(10, 12, 34, 999) << Qt::TextDate << QString("10:12:34.999");
+ QTest::newRow("ISO 10:12:34.999") << QTime(10, 12, 34, 999) << Qt::ISODate << QString("10:12:34.999");
+ QTest::newRow("RFC2822Date") << QTime(10, 12, 34, 999) << Qt::RFC2822Date << QString("10:12:34");
}
void tst_QTime::toStringDateFormat()
{
- QFETCH( QTime, t );
- QFETCH( QString, str1 );
- QFETCH( QString, str2 );
+ QFETCH(QTime, time);
+ QFETCH(Qt::DateFormat, format);
+ QFETCH(QString, expected);
- QCOMPARE( str1, t.toString( Qt::TextDate ) );
- QCOMPARE( str2, t.toString( Qt::ISODate ) );
+ QCOMPARE(time.toString(format), expected);
}
void tst_QTime::toStringFormat_data()
diff --git a/tests/auto/dbus/qdbusabstractinterface/interface.h b/tests/auto/dbus/qdbusabstractinterface/interface.h
index 5db59b19eb..ecf732ce2d 100644
--- a/tests/auto/dbus/qdbusabstractinterface/interface.h
+++ b/tests/auto/dbus/qdbusabstractinterface/interface.h
@@ -43,6 +43,7 @@
#define INTERFACE_H
#include <QtCore/QObject>
+#include <QtCore/QHash>
#include <QtDBus/QDBusArgument>
struct RegisteredType
@@ -103,7 +104,7 @@ public slots:
Q_SCRIPTABLE void voidMethod() {}
Q_SCRIPTABLE int sleepMethod(int);
Q_SCRIPTABLE QString stringMethod() { return "Hello, world"; }
- Q_SCRIPTABLE RegisteredType complexMethod() { return RegisteredType("Hello, world"); }
+ Q_SCRIPTABLE RegisteredType complexMethod(const QVariantHash &vars) { return RegisteredType(vars.value("arg1").toString()); }
Q_SCRIPTABLE QString multiOutMethod(int &value) { value = 42; return "Hello, world"; }
signals:
diff --git a/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml b/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml
index 845e7be5b4..ad61351cb2 100644
--- a/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml
+++ b/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml
@@ -8,7 +8,7 @@
</property>
<signal name="voidSignal"/>
<signal name="stringSignal">
- <arg type="s"/>
+ <arg type="s" name="string-data"/>
</signal>
<signal name="complexSignal">
<arg name="" type="(s)"/>
@@ -23,6 +23,8 @@
<arg type="s" direction="out"/>
</method>
<method name="complexMethod">
+ <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QHash&lt;QString,QVariant&gt;"/>
+ <arg type='a{sv}' name='platform_data' direction='in'/>
<arg type="(s)" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="RegisteredType"/>
</method>
diff --git a/tests/auto/dbus/qdbusabstractinterface/pinger.h b/tests/auto/dbus/qdbusabstractinterface/pinger.h
deleted file mode 100644
index 6bed72c203..0000000000
--- a/tests/auto/dbus/qdbusabstractinterface/pinger.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDBus module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*
- * This file was generated by qdbusxml2cpp version 0.7
- * Command line was: qdbusxml2cpp -i interface.h -p pinger org.qtproject.QtDBus.Pinger.xml
- *
- * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
- *
- * This is an auto-generated file.
- * Do not edit! All changes made to it will be lost.
- */
-
-#ifndef PINGER_H_1246463415
-#define PINGER_H_1246463415
-
-#include <QtCore/QObject>
-#include <QtCore/QByteArray>
-#include <QtCore/QList>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-#include <QtCore/QStringList>
-#include <QtCore/QVariant>
-#include <QtDBus/QtDBus>
-#include "interface.h"
-
-/*
- * Proxy class for interface org.qtproject.QtDBus.Pinger
- */
-class ComTrolltechQtDBusPingerInterface: public QDBusAbstractInterface
-{
- Q_OBJECT
-public:
- static inline const char *staticInterfaceName()
- { return "org.qtproject.QtDBus.Pinger"; }
-
-public:
- ComTrolltechQtDBusPingerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
-
- ~ComTrolltechQtDBusPingerInterface();
-
- Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp)
- inline RegisteredType complexProp() const
- { return qvariant_cast< RegisteredType >(property("complexProp")); }
- inline void setComplexProp(RegisteredType value)
- { setProperty("complexProp", QVariant::fromValue(value)); }
-
- Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp)
- inline QString stringProp() const
- { return qvariant_cast< QString >(property("stringProp")); }
- inline void setStringProp(const QString &value)
- { setProperty("stringProp", QVariant::fromValue(value)); }
-
- Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp)
- inline QDBusVariant variantProp() const
- { return qvariant_cast< QDBusVariant >(property("variantProp")); }
- inline void setVariantProp(const QDBusVariant &value)
- { setProperty("variantProp", QVariant::fromValue(value)); }
-
-public Q_SLOTS: // METHODS
- inline QDBusPendingReply<RegisteredType> complexMethod()
- {
- QList<QVariant> argumentList;
- return asyncCallWithArgumentList(QLatin1String("complexMethod"), argumentList);
- }
-
- inline QDBusPendingReply<QString, int> multiOutMethod()
- {
- QList<QVariant> argumentList;
- return asyncCallWithArgumentList(QLatin1String("multiOutMethod"), argumentList);
- }
- inline QDBusReply<QString> multiOutMethod(int &out1)
- {
- QList<QVariant> argumentList;
- QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("multiOutMethod"), argumentList);
- if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) {
- out1 = qdbus_cast<int>(reply.arguments().at(1));
- }
- return reply;
- }
-
- inline QDBusPendingReply<int> sleepMethod(int in0)
- {
- QList<QVariant> argumentList;
- argumentList << QVariant::fromValue(in0);
- return asyncCallWithArgumentList(QLatin1String("sleepMethod"), argumentList);
- }
-
- inline QDBusPendingReply<QString> stringMethod()
- {
- QList<QVariant> argumentList;
- return asyncCallWithArgumentList(QLatin1String("stringMethod"), argumentList);
- }
-
- inline QDBusPendingReply<> voidMethod()
- {
- QList<QVariant> argumentList;
- return asyncCallWithArgumentList(QLatin1String("voidMethod"), argumentList);
- }
-
-Q_SIGNALS: // SIGNALS
- void complexSignal(RegisteredType in0);
- void stringSignal(const QString &in0);
- void voidSignal();
-};
-
-namespace com {
- namespace trolltech {
- namespace QtDBus {
- typedef ::ComTrolltechQtDBusPingerInterface Pinger;
- }
- }
-}
-#endif
diff --git a/tests/auto/dbus/qdbusabstractinterface/test/test.pro b/tests/auto/dbus/qdbusabstractinterface/test/test.pro
index 363d5fdf9c..66744b9252 100644
--- a/tests/auto/dbus/qdbusabstractinterface/test/test.pro
+++ b/tests/auto/dbus/qdbusabstractinterface/test/test.pro
@@ -2,13 +2,11 @@ CONFIG += testcase
SOURCES += ../tst_qdbusabstractinterface.cpp ../interface.cpp
HEADERS += ../interface.h
-# These are generated sources
-# To regenerate, see the command-line at the top of the files
-SOURCES += ../pinger.cpp
-HEADERS += ../pinger.h
-
TARGET = ../tst_qdbusabstractinterface
QT = core testlib
QT += dbus
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
+
+DBUS_INTERFACES = ../org.qtproject.QtDBus.Pinger.xml
+QDBUSXML2CPP_INTERFACE_HEADER_FLAGS += -i ../interface.h
diff --git a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp
index 5f3cf539e9..91e69fcdb7 100644
--- a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp
+++ b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp
@@ -47,13 +47,13 @@
#include <QtDBus>
#include "interface.h"
-#include "pinger.h"
+#include "pinger_interface.h"
static const char serviceName[] = "org.qtproject.autotests.qpinger";
static const char objectPath[] = "/org/qtproject/qpinger";
static const char *interfaceName = serviceName;
-typedef QSharedPointer<com::trolltech::QtDBus::Pinger> Pinger;
+typedef QSharedPointer<org::qtproject::QtDBus::Pinger> Pinger;
class tst_QDBusAbstractInterface: public QObject
{
@@ -67,7 +67,7 @@ class tst_QDBusAbstractInterface: public QObject
return Pinger();
if (service.isEmpty() && !service.isNull())
service = con.baseService();
- return Pinger(new com::trolltech::QtDBus::Pinger(service, path, con));
+ return Pinger(new org::qtproject::QtDBus::Pinger(service, path, con));
}
Pinger getPingerPeer(const QString &path = "/", const QString &service = "")
@@ -75,7 +75,7 @@ class tst_QDBusAbstractInterface: public QObject
QDBusConnection con = QDBusConnection("peer");
if (!con.isConnected())
return Pinger();
- return Pinger(new com::trolltech::QtDBus::Pinger(service, path, con));
+ return Pinger(new org::qtproject::QtDBus::Pinger(service, path, con));
}
void resetServer()
@@ -308,14 +308,22 @@ void tst_QDBusAbstractInterface::makeStringCall()
QCOMPARE(r.value(), targetObj.stringMethod());
}
+static QHash<QString, QVariant> complexMethodArgs()
+{
+ QHash<QString, QVariant> args;
+ args.insert("arg1", "Hello world");
+ args.insert("arg2", 12345);
+ return args;
+}
+
void tst_QDBusAbstractInterface::makeComplexCall()
{
Pinger p = getPinger();
QVERIFY2(p, "Not connected to D-Bus");
- QDBusReply<RegisteredType> r = p->complexMethod();
+ QDBusReply<RegisteredType> r = p->complexMethod(complexMethodArgs());
QVERIFY(r.isValid());
- QCOMPARE(r.value(), targetObj.complexMethod());
+ QCOMPARE(r.value(), targetObj.complexMethod(complexMethodArgs()));
}
void tst_QDBusAbstractInterface::makeMultiOutCall()
@@ -356,9 +364,9 @@ void tst_QDBusAbstractInterface::makeComplexCallPeer()
Pinger p = getPingerPeer();
QVERIFY2(p, "Not connected to D-Bus");
- QDBusReply<RegisteredType> r = p->complexMethod();
+ QDBusReply<RegisteredType> r = p->complexMethod(complexMethodArgs());
QVERIFY(r.isValid());
- QCOMPARE(r.value(), targetObj.complexMethod());
+ QCOMPARE(r.value(), targetObj.complexMethod(complexMethodArgs()));
}
void tst_QDBusAbstractInterface::makeMultiOutCallPeer()
@@ -401,10 +409,10 @@ void tst_QDBusAbstractInterface::makeAsyncComplexCall()
Pinger p = getPinger();
QVERIFY2(p, "Not connected to D-Bus");
- QDBusPendingReply<RegisteredType> r = p->complexMethod();
+ QDBusPendingReply<RegisteredType> r = p->complexMethod(complexMethodArgs());
r.waitForFinished();
QVERIFY(r.isValid());
- QCOMPARE(r.value(), targetObj.complexMethod());
+ QCOMPARE(r.value(), targetObj.complexMethod(complexMethodArgs()));
}
void tst_QDBusAbstractInterface::makeAsyncMultiOutCall()
@@ -449,10 +457,10 @@ void tst_QDBusAbstractInterface::makeAsyncComplexCallPeer()
Pinger p = getPingerPeer();
QVERIFY2(p, "Not connected to D-Bus");
- QDBusPendingReply<RegisteredType> r = p->complexMethod();
+ QDBusPendingReply<RegisteredType> r = p->complexMethod(complexMethodArgs());
r.waitForFinished();
QVERIFY(r.isValid());
- QCOMPARE(r.value(), targetObj.complexMethod());
+ QCOMPARE(r.value(), targetObj.complexMethod(complexMethodArgs()));
}
void tst_QDBusAbstractInterface::makeAsyncMultiOutCallPeer()
@@ -551,7 +559,7 @@ void tst_QDBusAbstractInterface::callWithTimeout()
}
// Now using generated code
- com::trolltech::QtDBus::Pinger p(server_serviceName, server_objectPath, QDBusConnection::sessionBus());
+ org::qtproject::QtDBus::Pinger p(server_serviceName, server_objectPath, QDBusConnection::sessionBus());
{
// Call with no timeout
QDBusReply<int> reply = p.sleepMethod(100);
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index 2cd5216c59..7fdb2f4cba 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -728,6 +728,24 @@ void tst_QImage::convertToFormat_data()
<< int(QImage::Format_RGB888) << 0xffffffffu;
QTest::newRow("semiblack pm -> rgb888") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u
<< int(QImage::Format_RGB888) << 0xff000000u;
+
+ QTest::newRow("red rgba8888 -> argb32") << int(QImage::Format_RGBA8888) << 0xffff0000
+ << int(QImage::Format_ARGB32) << 0xffff0000;
+ QTest::newRow("green rgba8888 -> argb32") << int(QImage::Format_RGBA8888) << 0xff00ff00
+ << int(QImage::Format_ARGB32) << 0xff00ff00;
+ QTest::newRow("blue rgba8888 -> argb32") << int(QImage::Format_RGBA8888) << 0xff0000ff
+ << int(QImage::Format_ARGB32) << 0xff0000ff;
+
+ QTest::newRow("semired rgba8888 -> argb pm") << int(QImage::Format_RGBA8888) << 0x7fff0000u
+ << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f0000u;
+ QTest::newRow("semigreen rgba8888 -> argb pm") << int(QImage::Format_RGBA8888) << 0x7f00ff00u
+ << int(QImage::Format_ARGB32_Premultiplied) << 0x7f007f00u;
+ QTest::newRow("semiblue rgba8888 -> argb pm") << int(QImage::Format_RGBA8888) << 0x7f0000ffu
+ << int(QImage::Format_ARGB32_Premultiplied) << 0x7f00007fu;
+ QTest::newRow("semiwhite rgba8888 -> argb pm") << int(QImage::Format_RGBA8888) << 0x7fffffffu
+ << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu;
+ QTest::newRow("semiblack rgba8888 -> argb pm") << int(QImage::Format_RGBA8888) << 0x7f000000u
+ << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u;
}
@@ -953,6 +971,10 @@ void tst_QImage::rotate_data()
<< QImage::Format_RGB888 << d;
QTest::newRow(qPrintable(title.arg("Format_Indexed8")))
<< QImage::Format_Indexed8 << d;
+ QTest::newRow(qPrintable(title.arg("Format_RGBX8888")))
+ << QImage::Format_RGBX8888 << d;
+ QTest::newRow(qPrintable(title.arg("Format_RGBA8888_Premultiplied")))
+ << QImage::Format_RGBA8888_Premultiplied << d;
}
}
@@ -1161,6 +1183,21 @@ void tst_QImage::setPixel_data()
<< 0xff00ff00 << 0x00ff00u;
QTest::newRow("RGB888 blue") << int(QImage::Format_RGB888)
<< 0xff0000ff << 0x0000ffu;
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ QTest::newRow("RGBA8888 red") << int(QImage::Format_RGBA8888)
+ << 0xffff0000u << 0xff0000ffu;
+ QTest::newRow("RGBA8888 green") << int(QImage::Format_RGBA8888)
+ << 0xff00ff00u << 0x00ff00ffu;
+ QTest::newRow("RGBA8888 blue") << int(QImage::Format_RGBA8888)
+ << 0xff0000ffu << 0x0000ffffu;
+#else
+ QTest::newRow("RGBA8888 red") << int(QImage::Format_RGBA8888)
+ << 0xffff0000u << 0xff0000ffu;
+ QTest::newRow("RGBA8888 green") << int(QImage::Format_RGBA8888)
+ << 0xff00ff00u << 0xff00ff00u;
+ QTest::newRow("RGBA8888 blue") << int(QImage::Format_RGBA8888)
+ << 0xff0000ffu << 0xffff0000u;
+#endif
}
void tst_QImage::setPixel()
@@ -1184,6 +1221,9 @@ void tst_QImage::setPixel()
case int(QImage::Format_RGB32):
case int(QImage::Format_ARGB32):
case int(QImage::Format_ARGB32_Premultiplied):
+ case int(QImage::Format_RGBX8888):
+ case int(QImage::Format_RGBA8888):
+ case int(QImage::Format_RGBA8888_Premultiplied):
{
for (int y = 0; y < h; ++y) {
const quint32 *row = (const quint32*)(img.scanLine(y));
@@ -1901,6 +1941,8 @@ void tst_QImage::fillColor_data()
"RGB888",
"RGB444",
"ARGB4444pm",
+ "RGBx8888",
+ "RGBA8888pm",
0
};
@@ -1917,7 +1959,9 @@ void tst_QImage::fillColor_data()
QImage::Format_ARGB8555_Premultiplied,
QImage::Format_RGB888,
QImage::Format_RGB444,
- QImage::Format_ARGB4444_Premultiplied
+ QImage::Format_ARGB4444_Premultiplied,
+ QImage::Format_RGBX8888,
+ QImage::Format_RGBA8888_Premultiplied,
};
for (int i=0; names[i] != 0; ++i) {
@@ -1935,6 +1979,7 @@ void tst_QImage::fillColor_data()
QTest::newRow("RGB32, transparent") << QImage::Format_RGB32 << Qt::transparent << 0xff000000;
QTest::newRow("ARGB32, transparent") << QImage::Format_ARGB32 << Qt::transparent << 0x00000000u;
QTest::newRow("ARGB32pm, transparent") << QImage::Format_ARGB32_Premultiplied << Qt::transparent << 0x00000000u;
+ QTest::newRow("RGBA8888pm, transparent") << QImage::Format_RGBA8888_Premultiplied << Qt::transparent << 0x00000000u;
}
void tst_QImage::fillColor()
@@ -2013,6 +2058,8 @@ void tst_QImage::rgbSwapped_data()
QTest::newRow("Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied;
QTest::newRow("Format_RGB888") << QImage::Format_RGB888;
QTest::newRow("Format_RGB444") << QImage::Format_RGB444;
+ QTest::newRow("Format_RGBX8888") << QImage::Format_RGBX8888;
+ QTest::newRow("Format_RGBA8888_Premultiplied") << QImage::Format_RGBA8888_Premultiplied;
}
void tst_QImage::rgbSwapped()
diff --git a/tests/auto/gui/kernel/qbackingstore/qbackingstore.pro b/tests/auto/gui/kernel/qbackingstore/qbackingstore.pro
index c3113ed4b1..211be4c1c0 100644
--- a/tests/auto/gui/kernel/qbackingstore/qbackingstore.pro
+++ b/tests/auto/gui/kernel/qbackingstore/qbackingstore.pro
@@ -1,5 +1,4 @@
CONFIG += testcase
-CONFIG += parallel_test
TARGET = tst_qbackingstore
QT += core-private gui-private testlib
diff --git a/tests/auto/gui/kernel/qinputmethod/qinputmethod.pro b/tests/auto/gui/kernel/qinputmethod/qinputmethod.pro
index ff491c1e25..015cc782eb 100644
--- a/tests/auto/gui/kernel/qinputmethod/qinputmethod.pro
+++ b/tests/auto/gui/kernel/qinputmethod/qinputmethod.pro
@@ -1,5 +1,4 @@
CONFIG += testcase
-CONFIG += parallel_test
TARGET = tst_qinputmethod
SOURCES += tst_qinputmethod.cpp
QT += core-private gui-private testlib
diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
index 6fe7961545..1b1f5575b1 100644
--- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
+++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
@@ -61,6 +61,8 @@ private slots:
void name_data();
void name();
+ void namehex_data();
+ void namehex();
void setNamedColor();
void constructNamedColorWithSpace();
@@ -254,36 +256,75 @@ void tst_QColor::isValid()
QVERIFY(color.isValid() == isValid);
}
+Q_DECLARE_METATYPE(QColor::NameFormat);
+
void tst_QColor::name_data()
{
QTest::addColumn<QColor>("color");
QTest::addColumn<QString>("name");
-
- QTest::newRow("invalid") << QColor() << "#000000";
- QTest::newRow("global color black") << QColor(Qt::black) << "#000000";
- QTest::newRow("global color white") << QColor(Qt::white) << "#ffffff";
- QTest::newRow("global color darkGray") << QColor(Qt::darkGray) << "#808080";
- QTest::newRow("global color gray") << QColor(Qt::gray) << "#a0a0a4";
- QTest::newRow("global color lightGray") << QColor(Qt::lightGray) << "#c0c0c0";
- QTest::newRow("global color red") << QColor(Qt::red) << "#ff0000";
- QTest::newRow("global color green") << QColor(Qt::green) << "#00ff00";
- QTest::newRow("global color blue") << QColor(Qt::blue) << "#0000ff";
- QTest::newRow("global color cyan") << QColor(Qt::cyan) << "#00ffff";
- QTest::newRow("global color magenta") << QColor(Qt::magenta) << "#ff00ff";
- QTest::newRow("global color yellow") << QColor(Qt::yellow) << "#ffff00";
- QTest::newRow("global color darkRed") << QColor(Qt::darkRed) << "#800000";
- QTest::newRow("global color darkGreen") << QColor(Qt::darkGreen) << "#008000";
- QTest::newRow("global color darkBlue") << QColor(Qt::darkBlue) << "#000080";
- QTest::newRow("global color darkCyan") << QColor(Qt::darkCyan) << "#008080";
- QTest::newRow("global color darkMagenta") << QColor(Qt::darkMagenta) << "#800080";
- QTest::newRow("global color darkYellow") << QColor(Qt::darkYellow) << "#808000";
+ QTest::addColumn<QColor::NameFormat>("nameFormat");
+
+ QTest::newRow("invalid") << QColor() << "#000000" << QColor::HexRgb;
+ QTest::newRow("global color black") << QColor(Qt::black) << "#000000" << QColor::HexRgb;
+ QTest::newRow("global color white") << QColor(Qt::white) << "#ffffff" << QColor::HexRgb;
+ QTest::newRow("global color darkGray") << QColor(Qt::darkGray) << "#808080" << QColor::HexRgb;
+ QTest::newRow("global color gray") << QColor(Qt::gray) << "#a0a0a4" << QColor::HexRgb;
+ QTest::newRow("global color lightGray") << QColor(Qt::lightGray) << "#c0c0c0" << QColor::HexRgb;
+ QTest::newRow("global color red") << QColor(Qt::red) << "#ff0000" << QColor::HexRgb;
+ QTest::newRow("global color green") << QColor(Qt::green) << "#00ff00" << QColor::HexRgb;
+ QTest::newRow("global color blue") << QColor(Qt::blue) << "#0000ff" << QColor::HexRgb;
+ QTest::newRow("global color cyan") << QColor(Qt::cyan) << "#00ffff" << QColor::HexRgb;
+ QTest::newRow("global color magenta") << QColor(Qt::magenta) << "#ff00ff" << QColor::HexRgb;
+ QTest::newRow("global color yellow") << QColor(Qt::yellow) << "#ffff00" << QColor::HexRgb;
+ QTest::newRow("global color darkRed") << QColor(Qt::darkRed) << "#800000" << QColor::HexRgb;
+ QTest::newRow("global color darkGreen") << QColor(Qt::darkGreen) << "#008000" << QColor::HexRgb;
+ QTest::newRow("global color darkBlue") << QColor(Qt::darkBlue) << "#000080" << QColor::HexRgb;
+ QTest::newRow("global color darkCyan") << QColor(Qt::darkCyan) << "#008080" << QColor::HexRgb;
+ QTest::newRow("global color darkMagenta") << QColor(Qt::darkMagenta) << "#800080" << QColor::HexRgb;
+ QTest::newRow("global color darkYellow") << QColor(Qt::darkYellow) << "#808000" << QColor::HexRgb;
+ QTest::newRow("transparent red") << QColor(255, 0, 0, 102) << "#66ff0000" << QColor::HexArgb;
}
void tst_QColor::name()
{
QFETCH(QColor, color);
QFETCH(QString, name);
- QCOMPARE(color.name(), name);
+ QFETCH(QColor::NameFormat, nameFormat);
+ QCOMPARE(color.name(nameFormat), name);
+}
+
+void tst_QColor::namehex_data()
+{
+ QTest::addColumn<QString>("hexcolor");
+ QTest::addColumn<QColor>("color");
+
+ QTest::newRow("global color black") << "#000000" << QColor(Qt::black);
+ QTest::newRow("global color white") << "#ffffff" << QColor(Qt::white);
+ QTest::newRow("global color darkGray") << "#808080" << QColor(Qt::darkGray);
+ QTest::newRow("global color gray") << "#a0a0a4" << QColor(Qt::gray);
+ QTest::newRow("global color lightGray") << "#c0c0c0" << QColor(Qt::lightGray);
+ QTest::newRow("global color red") << "#ff0000" << QColor(Qt::red);
+ QTest::newRow("global color green") << "#00ff00" << QColor(Qt::green);
+ QTest::newRow("global color blue") << "#0000ff" << QColor(Qt::blue);
+ QTest::newRow("global color cyan") << "#00ffff" << QColor(Qt::cyan);
+ QTest::newRow("global color magenta") << "#ff00ff" << QColor(Qt::magenta);
+ QTest::newRow("global color yellow") << "#ffff00" << QColor(Qt::yellow);
+ QTest::newRow("global color darkRed") << "#800000" << QColor(Qt::darkRed);
+ QTest::newRow("global color darkGreen") << "#008000" << QColor(Qt::darkGreen);
+ QTest::newRow("global color darkBlue") << "#000080" << QColor(Qt::darkBlue);
+ QTest::newRow("global color darkCyan") << "#008080" << QColor(Qt::darkCyan);
+ QTest::newRow("global color darkMagenta") << "#800080" << QColor(Qt::darkMagenta);
+ QTest::newRow("global color darkYellow") << "#808000" << QColor(Qt::darkYellow);
+ QTest::newRow("transparent red") << "#66ff0000" << QColor(255, 0, 0, 102);
+ QTest::newRow("invalid red") << "#gg0000" << QColor();
+ QTest::newRow("invalid transparent") << "#gg00ff00" << QColor();
+}
+
+void tst_QColor::namehex()
+{
+ QFETCH(QString, hexcolor);
+ QFETCH(QColor, color);
+ QCOMPARE(QColor(hexcolor), color);
}
void tst_QColor::globalColors_data()
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
index 4f1213dff9..5a1ca855a1 100644
--- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
+++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
@@ -122,10 +122,15 @@ private slots:
void drawRect();
void drawRect2();
+ void fillRect_data();
void fillRect();
+ void fillRect2_data();
void fillRect2();
+ void fillRect3_data() { fillRect2_data(); }
void fillRect3();
+ void fillRect4_data() { fillRect2_data(); }
void fillRect4();
+ void fillRectNonPremul();
void drawEllipse_data();
void drawEllipse();
@@ -1079,9 +1084,19 @@ void tst_QPainter::drawRect2()
}
}
+void tst_QPainter::fillRect_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+
+ QTest::newRow("argb32pm") << QImage::Format_ARGB32_Premultiplied;
+ QTest::newRow("rgba8888pm") << QImage::Format_RGBA8888_Premultiplied;
+}
+
void tst_QPainter::fillRect()
{
- QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
+ QFETCH(QImage::Format, format);
+
+ QImage image(100, 100, format);
image.fill(QColor(0, 0, 0, 0).rgba());
QPainter p(&image);
@@ -1103,17 +1118,29 @@ void tst_QPainter::fillRect()
QRect(0, 0, 50, 100));
}
+void tst_QPainter::fillRect2_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+
+ QTest::newRow("argb32") << QImage::Format_ARGB32;
+ QTest::newRow("argb32pm") << QImage::Format_ARGB32_Premultiplied;
+ QTest::newRow("rgba8888") << QImage::Format_RGBA8888;
+ QTest::newRow("rgba8888pm") << QImage::Format_RGBA8888_Premultiplied;
+}
+
void tst_QPainter::fillRect2()
{
+ QFETCH(QImage::Format, format);
+
QRgb background = 0x0;
- QImage img(1, 20, QImage::Format_ARGB32_Premultiplied);
+ QImage img(1, 20, format);
img.fill(background);
QPainter p(&img);
QRectF rect(0, 1, 1.2, 18);
- p.fillRect(rect, Qt::black);
+ p.fillRect(rect, Qt::yellow);
p.end();
@@ -1122,11 +1149,14 @@ void tst_QPainter::fillRect2()
QCOMPARE(img.pixel(0, 1), img.pixel(0, 2));
QCOMPARE(img.pixel(0, img.height() - 2), img.pixel(0, img.height() - 3));
+ QCOMPARE(img.pixel(0, 1), QColor(Qt::yellow).rgba());
}
void tst_QPainter::fillRect3()
{
- QImage img(1, 1, QImage::Format_ARGB32_Premultiplied);
+ QFETCH(QImage::Format, format);
+
+ QImage img(1, 1, format);
img.fill(QColor(Qt::black).rgba());
QPainter p(&img);
@@ -1139,7 +1169,9 @@ void tst_QPainter::fillRect3()
void tst_QPainter::fillRect4()
{
- QImage image(100, 1, QImage::Format_ARGB32_Premultiplied);
+ QFETCH(QImage::Format, format);
+
+ QImage image(100, 1, format);
image.fill(0x0);
QImage expected = image;
@@ -1157,6 +1189,24 @@ void tst_QPainter::fillRect4()
QCOMPARE(image, expected);
}
+void tst_QPainter::fillRectNonPremul()
+{
+ QImage img1(1, 1, QImage::Format_ARGB32);
+ QImage img2(1, 1, QImage::Format_RGBA8888);
+
+ QPainter p1(&img1);
+ QPainter p2(&img2);
+
+ QRectF rect(0, 0, 1, 1);
+ p1.fillRect(rect, qRgba(31, 63, 127, 127));
+ p2.fillRect(rect, qRgba(31, 63, 127, 127));
+
+ p1.end();
+ p2.end();
+
+ QCOMPARE(img1.pixel(0, 0), img2.pixel(0,0));
+}
+
void tst_QPainter::drawPath_data()
{
QTest::addColumn<QPainterPath>("path");
@@ -2265,6 +2315,27 @@ void tst_QPainter::setOpacity_data()
QTest::newRow("RGB444 on RGB444") << QImage::Format_RGB444
<< QImage::Format_RGB444;
+
+ QTest::newRow("RGBA8888P on RGBA8888P") << QImage::Format_RGBA8888_Premultiplied
+ << QImage::Format_RGBA8888_Premultiplied;
+
+ QTest::newRow("RGBA8888 on RGBA8888") << QImage::Format_RGBA8888
+ << QImage::Format_RGBA8888;
+
+ QTest::newRow("RGBx8888 on RGBx8888") << QImage::Format_RGBX8888
+ << QImage::Format_RGBX8888;
+
+ QTest::newRow("RGBA8888P on ARGB32P") << QImage::Format_RGBA8888_Premultiplied
+ << QImage::Format_ARGB32_Premultiplied;
+
+ QTest::newRow("RGBx8888 on ARGB32P") << QImage::Format_RGBX8888
+ << QImage::Format_ARGB32_Premultiplied;
+
+ QTest::newRow("ARGB32P on RGBA8888P") << QImage::Format_ARGB32_Premultiplied
+ << QImage::Format_RGBA8888_Premultiplied;
+
+ QTest::newRow("RGB32 on RGBx8888") << QImage::Format_RGB32
+ << QImage::Format_RGBX8888;
}
void tst_QPainter::setOpacity()
diff --git a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp
index ca6c42c9bd..86e282fad2 100644
--- a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp
+++ b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp
@@ -344,8 +344,6 @@ void tst_QCssParser::term_data()
val.variant = QVariant(QColor("#ffbb00"));
QTest::newRow("hexcolor2") << true << "#fb0" << val;
- QTest::newRow("hexcolor_failure") << false << "#cafebabe" << val;
-
val.type = QCss::Value::Uri;
val.variant = QString("www.kde.org");
QTest::newRow("uri1") << true << "url(\"www.kde.org\")" << val;
@@ -367,9 +365,6 @@ void tst_QCssParser::term()
QFETCH(QString, css);
QFETCH(QCss::Value, expectedValue);
- if (strcmp(QTest::currentDataTag(), "hexcolor_failure") == 0)
- QTest::ignoreMessage(QtWarningMsg, "QCssParser::parseHexColor: Unknown color name '#cafebabe'");
-
QCss::Parser parser(css);
QCss::Value val;
QVERIFY(parser.testTerm());
diff --git a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro
index 37868dcfde..6975c4088b 100644
--- a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro
+++ b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro
@@ -2,8 +2,7 @@ CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qfontdatabase
SOURCES += tst_qfontdatabase.cpp
-QT += testlib
-!mac: QT += core-private gui-private
+QT += testlib core-private gui-private
wince* {
additionalFiles.files = FreeMono.ttf
diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
index 9cf4082287..104d3465f2 100644
--- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
@@ -44,6 +44,7 @@
#include <qfontdatabase.h>
#include <qfontinfo.h>
#include <qfontmetrics.h>
+#include <qpa/qplatformfontdatabase.h>
class tst_QFontDatabase : public QObject
{
@@ -252,11 +253,8 @@ void tst_QFontDatabase::addAppFont()
return;
#endif
QCOMPARE(fontDbChangedSpy.count(), 1);
-// addApplicationFont is supported on Mac, don't skip the test if it breaks.
-#ifndef Q_OS_MAC
if (id == -1)
QSKIP("Skip the test since app fonts are not supported on this system");
-#endif
const QStringList addedFamilies = QFontDatabase::applicationFontFamilies(id);
QVERIFY(!addedFamilies.isEmpty());
@@ -271,16 +269,9 @@ void tst_QFontDatabase::addAppFont()
QVERIFY(QFontDatabase::removeApplicationFont(id));
QCOMPARE(fontDbChangedSpy.count(), 2);
-#ifdef Q_OS_MAC
- QEXPECT_FAIL("font file", "QTBUG-23062", Continue);
-#endif
QCOMPARE(db.families(), oldFamilies);
}
-QT_BEGIN_NAMESPACE
-Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
-QT_END_NAMESPACE
-
void tst_QFontDatabase::aliases()
{
QFontDatabase db;
@@ -290,7 +281,7 @@ void tst_QFontDatabase::aliases()
QVERIFY(db.hasFamily(firstFont));
const QString alias = QStringLiteral("AliasToFirstFont") + firstFont;
QVERIFY(!db.hasFamily(alias));
- qt_registerAliasToFontFamily(firstFont, alias);
+ QPlatformFontDatabase::registerAliasToFontFamily(firstFont, alias);
QVERIFY(db.hasFamily(alias));
}
diff --git a/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp b/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp
index 25301feee4..125eab2f8c 100644
--- a/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp
+++ b/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp
@@ -77,30 +77,43 @@ void tst_QNetworkAccessManager::networkAccessible()
QSignalSpy spy(&manager,
SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)));
- QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::UnknownAccessibility);
+ // if there is no session, we cannot know in which state we are in
+ QNetworkAccessManager::NetworkAccessibility initialAccessibility =
+ manager.networkAccessible();
+ QCOMPARE(manager.networkAccessible(), initialAccessibility);
manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible);
- QCOMPARE(spy.count(), 1);
- QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
- QNetworkAccessManager::NotAccessible);
+ int expectedCount = (initialAccessibility == QNetworkAccessManager::Accessible) ? 1 : 0;
+ QCOMPARE(spy.count(), expectedCount);
+ if (expectedCount > 0)
+ QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
+ QNetworkAccessManager::NotAccessible);
QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::NotAccessible);
manager.setNetworkAccessible(QNetworkAccessManager::Accessible);
- QCOMPARE(spy.count(), 1);
- QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
- QNetworkAccessManager::UnknownAccessibility);
- QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::UnknownAccessibility);
+ QCOMPARE(spy.count(), expectedCount);
+ if (expectedCount > 0)
+ QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
+ initialAccessibility);
+ QCOMPARE(manager.networkAccessible(), initialAccessibility);
QNetworkConfigurationManager configManager;
+ bool sessionRequired = (configManager.capabilities()
+ & QNetworkConfigurationManager::NetworkSessionRequired);
QNetworkConfiguration defaultConfig = configManager.defaultConfiguration();
if (defaultConfig.isValid()) {
manager.setConfiguration(defaultConfig);
- QCOMPARE(spy.count(), 1);
- QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
- QNetworkAccessManager::Accessible);
+ // the accessibility has not changed if no session is required
+ if (sessionRequired) {
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
+ QNetworkAccessManager::Accessible);
+ } else {
+ QCOMPARE(spy.count(), 0);
+ }
QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::Accessible);
manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible);
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index ce8293edbc..eb9ad81101 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -368,6 +368,8 @@ private Q_SLOTS:
#ifdef QT_BUILD_INTERNAL
void sslSessionSharing_data();
void sslSessionSharing();
+ void sslSessionSharingFromPersistentSession_data();
+ void sslSessionSharingFromPersistentSession();
#endif
#endif
@@ -5964,7 +5966,7 @@ void tst_QNetworkReply::sslSessionSharing()
warmupRequest.setAttribute(QNetworkRequest::User, sessionSharingEnabled); // so we can read it from the slot
if (! sessionSharingEnabled) {
QSslConfiguration configuration(QSslConfiguration::defaultConfiguration());
- configuration.setSslOption(QSsl::SslOptionDisableSessionTickets, true);
+ configuration.setSslOption(QSsl::SslOptionDisableSessionSharing, true);
warmupRequest.setSslConfiguration(configuration);
}
QNetworkReply *reply = manager.get(warmupRequest);
@@ -6010,6 +6012,63 @@ void tst_QNetworkReply::sslSessionSharingHelperSlot()
}
}
+void tst_QNetworkReply::sslSessionSharingFromPersistentSession_data()
+{
+ QTest::addColumn<bool>("sessionPersistenceEnabled");
+ QTest::newRow("enabled") << true;
+ QTest::newRow("disabled") << false;
+}
+
+void tst_QNetworkReply::sslSessionSharingFromPersistentSession()
+{
+ QString urlString("https://" + QtNetworkSettings::serverName());
+
+ // warm up SSL session cache to get a working session
+ QNetworkRequest warmupRequest(urlString);
+ QFETCH(bool, sessionPersistenceEnabled);
+ if (sessionPersistenceEnabled) {
+ QSslConfiguration warmupConfiguration(QSslConfiguration::defaultConfiguration());
+ warmupConfiguration.setSslOption(QSsl::SslOptionDisableSessionPersistence, false);
+ warmupRequest.setSslConfiguration(warmupConfiguration);
+ }
+ QNetworkReply *warmupReply = manager.get(warmupRequest);
+ warmupReply->ignoreSslErrors();
+ connect(warmupReply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
+ QTestEventLoop::instance().enterLoop(20);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QCOMPARE(warmupReply->error(), QNetworkReply::NoError);
+ QByteArray sslSession = warmupReply->sslConfiguration().session();
+ QCOMPARE(!sslSession.isEmpty(), sessionPersistenceEnabled);
+
+ // test server sends a life time hint of 0, which is not common
+ // practice; however it is good enough because the default is -1
+ int expectedSessionTicketLifeTimeHint = sessionPersistenceEnabled ? 0 : -1;
+ QCOMPARE(warmupReply->sslConfiguration().sessionTicketLifeTimeHint(),
+ expectedSessionTicketLifeTimeHint);
+
+ warmupReply->deleteLater();
+
+ // now send another request with a new QNAM and the persisted session,
+ // to verify it can be resumed without any internal state
+ QNetworkRequest request(warmupRequest);
+ if (sessionPersistenceEnabled) {
+ QSslConfiguration configuration = request.sslConfiguration();
+ configuration.setSession(sslSession);
+ request.setSslConfiguration(configuration);
+ }
+ QNetworkAccessManager newManager;
+ QNetworkReply *reply = newManager.get(request);
+ reply->ignoreSslErrors();
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
+ QTestEventLoop::instance().enterLoop(20);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QCOMPARE(reply->error(), QNetworkReply::NoError);
+
+ bool sslSessionSharingWasUsedInReply = QSslConfigurationPrivate::peerSessionWasShared(
+ reply->sslConfiguration());
+ QCOMPARE(sessionPersistenceEnabled, sslSessionSharingWasUsedInReply);
+}
+
#endif // QT_BUILD_INTERNAL
#endif // QT_NO_SSL
diff --git a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
index 40f22d6d1e..f474f97f5d 100644
--- a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
+++ b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
@@ -56,6 +56,10 @@
#include <sys/socket.h>
#endif
+#ifdef Q_OS_VXWORKS
+#include <sockLib.h>
+#endif
+
#include <stddef.h>
#define PLATFORMSOCKETENGINE QNativeSocketEngine
diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
index 2b9dfc5081..ee5c7e42d8 100644
--- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
+++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
@@ -513,7 +513,7 @@ void tst_QTcpSocket::bind()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
- QSKIP("QTBUG-22964");
+ return; // QTBUG-22964 for proxies, QTBUG-29972 for QSKIP
QFETCH(QString, stringAddr);
QFETCH(bool, successExpected);
QFETCH(QString, stringExpectedLocalAddress);
diff --git a/tests/auto/other/exceptionsafety/.gitignore b/tests/auto/other/exceptionsafety/.gitignore
deleted file mode 100644
index 9a854c4c26..0000000000
--- a/tests/auto/other/exceptionsafety/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-tst_exceptionsafety
diff --git a/tests/auto/other/exceptionsafety/exceptionsafety.pro b/tests/auto/other/exceptionsafety/exceptionsafety.pro
deleted file mode 100644
index 3e9c996cd8..0000000000
--- a/tests/auto/other/exceptionsafety/exceptionsafety.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_exceptionsafety
-SOURCES += tst_exceptionsafety.cpp
-QT = core testlib
-CONFIG += parallel_test insignificant_test
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/other/exceptionsafety/tst_exceptionsafety.cpp b/tests/auto/other/exceptionsafety/tst_exceptionsafety.cpp
deleted file mode 100644
index 94360adb0e..0000000000
--- a/tests/auto/other/exceptionsafety/tst_exceptionsafety.cpp
+++ /dev/null
@@ -1,846 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-#include <stdlib.h>
-
-void* internalMalloc(size_t bytes);
-#define malloc internalMalloc
-#include <QVarLengthArray>
-#undef malloc
-
-#include <QtTest/QtTest>
-
-QT_USE_NAMESPACE
-
-class tst_ExceptionSafety: public QObject
-{
- Q_OBJECT
-private slots:
-#ifdef QT_NO_EXCEPTIONS
- void initTestCase();
-#else
- void exceptionInSlot();
- void exceptionVector();
- void exceptionHash();
- void exceptionMap();
- void exceptionList();
- void exceptionLinkedList();
-// void exceptionEventLoop();
-// void exceptionSignalSlot();
- void exceptionOOMQVarLengthArray();
-#endif
-};
-
-#ifdef QT_NO_EXCEPTIONS
-void tst_ExceptionSafety::initTestCase()
-{
- QSKIP("This test requires exception support");
-}
-
-#else
-
-class Emitter : public QObject
-{
- Q_OBJECT
-public:
- inline void emitTestSignal() { emit testSignal(); }
-signals:
- void testSignal();
-};
-
-class ExceptionThrower : public QObject
-{
- Q_OBJECT
-public slots:
- void thrower() { throw 5; }
-};
-
-class Receiver : public QObject
-{
- Q_OBJECT
-public:
- Receiver()
- : received(0) {}
- int received;
-
-public slots:
- void receiver() { ++received; }
-};
-
-enum ThrowType { ThrowNot = 0, ThrowAtCreate = 1, ThrowAtCopy = 2, ThrowLater = 3, ThrowAtComparison = 4 };
-
-ThrowType throwType = ThrowNot; // global flag to indicate when an exception should be throw. Will be reset when the exception has been generated.
-
-int objCounter = 0;
-
-/*! Class that does not throw any exceptions. Used as baseclass for all the other ones.
- */
-template <int T>
-class FlexibleThrower
-{
- public:
- FlexibleThrower() : _value(-1) {
- if( throwType == ThrowAtCreate ) {
- throwType = ThrowNot;
- throw ThrowAtCreate;
- }
- objCounter++;
- }
-
- FlexibleThrower( short value ) : _value(value) {
- if( throwType == ThrowAtCreate ) {
- throwType = ThrowNot;
- throw ThrowAtCreate;
- }
- objCounter++;
- }
-
- FlexibleThrower(FlexibleThrower const& other ) {
- // qDebug("cc");
-
- if( throwType == ThrowAtCopy ) {
- throwType = ThrowNot;
- throw ThrowAtCopy;
-
- } else if( throwType == ThrowLater ) {
- throwType = ThrowAtCopy;
- }
-
- objCounter++;
- _value = other.value();
- }
-
- ~FlexibleThrower() { objCounter--; }
-
- bool operator==(const FlexibleThrower<T> &t) const
- {
- // qDebug("vv == %d %d", value(), t.value());
- if( throwType == ThrowAtComparison ) {
- throwType = ThrowNot;
- throw ThrowAtComparison;
- }
- return value()==t.value();
- }
-
- bool operator<(const FlexibleThrower<T> &t) const
- {
- // qDebug("vv < %d %d", value(), t.value());
- if( throwType == ThrowAtComparison ) {
- throwType = ThrowNot;
- throw ThrowAtComparison;
- }
- return value()<t.value();
- }
-
- int value() const
- { return (int)_value; }
-
- short _value;
- char dummy[T];
-};
-
-uint qHash(const FlexibleThrower<2>& t)
-{
- // qDebug("ha");
- if( throwType == ThrowAtComparison ) {
- throwType = ThrowNot;
- throw ThrowAtComparison;
- }
- return (uint)t.value();
-}
-
-typedef FlexibleThrower<2> FlexibleThrowerSmall;
-typedef QMap<FlexibleThrowerSmall,FlexibleThrowerSmall> MyMap;
-typedef QHash<FlexibleThrowerSmall,FlexibleThrowerSmall> MyHash;
-
-// connect a signal to a slot that throws an exception
-// run this through valgrind to make sure it doesn't corrupt
-void tst_ExceptionSafety::exceptionInSlot()
-{
- Emitter emitter;
- ExceptionThrower thrower;
-
- connect(&emitter, SIGNAL(testSignal()), &thrower, SLOT(thrower()));
-
- try {
- emitter.emitTestSignal();
- } catch (int i) {
- QCOMPARE(i, 5);
- }
-}
-
-void tst_ExceptionSafety::exceptionList()
-{
- const int intancesCount = objCounter;
- {
- int instances;
- QList<FlexibleThrowerSmall> list;
- QList<FlexibleThrowerSmall> list2;
- QList<FlexibleThrowerSmall> list3;
-
- for( int i = 0; i<10; i++ )
- list.append( FlexibleThrowerSmall(i) );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- list.append( FlexibleThrowerSmall(10));
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( list.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- list.prepend( FlexibleThrowerSmall(10));
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( list.at(0).value(), 0 );
- QCOMPARE( list.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- list.insert( 8, FlexibleThrowerSmall(10));
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( list.at(7).value(), 7 );
- QCOMPARE( list.at(8).value(), 8 );
- QCOMPARE( list.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- FlexibleThrowerSmall t = list.takeAt( 6 );
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( list.at(6).value(), 6 );
- QCOMPARE( list.at(7).value(), 7 );
- QCOMPARE( list.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- list3 = list;
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( list.at(0).value(), 0 );
- QCOMPARE( list.at(7).value(), 7 );
- QCOMPARE( list.size(), 10 );
- QCOMPARE( list3.at(0).value(), 0 );
- QCOMPARE( list3.at(7).value(), 7 );
- QCOMPARE( list3.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- list3.append( FlexibleThrowerSmall(11) );
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( list.at(0).value(), 0 );
- QCOMPARE( list.at(7).value(), 7 );
- QCOMPARE( list.size(), 10 );
- QCOMPARE( list3.at(0).value(), 0 );
- QCOMPARE( list3.at(7).value(), 7 );
- QCOMPARE( list3.size(), 10 );
-
- try {
- list2.clear();
- list2.append( FlexibleThrowerSmall(11));
- throwType = ThrowAtCopy;
- instances = objCounter;
- list3 = list+list2;
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( list.at(0).value(), 0 );
- QCOMPARE( list.at(7).value(), 7 );
- QCOMPARE( list.size(), 10 );
-
- // check that copy on write works atomar
- list2.clear();
- list2.append( FlexibleThrowerSmall(11));
- list3 = list+list2;
- instances = objCounter;
- try {
- throwType = ThrowAtCreate;
- list3[7]=FlexibleThrowerSmall(12);
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( list.at(7).value(), 7 );
- QCOMPARE( list.size(), 10 );
- QCOMPARE( list3.at(7).value(), 7 );
- QCOMPARE( list3.size(), 11 );
-
- }
- QCOMPARE(objCounter, intancesCount); // check that every object has been freed
-}
-
-void tst_ExceptionSafety::exceptionLinkedList()
-{
- const int intancesCount = objCounter;
- {
- int instances;
- QLinkedList<FlexibleThrowerSmall> list;
- QLinkedList<FlexibleThrowerSmall> list2;
- QLinkedList<FlexibleThrowerSmall> list3;
-
- for( int i = 0; i<10; i++ )
- list.append( FlexibleThrowerSmall(i) );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- list.append( FlexibleThrowerSmall(10));
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( list.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- list.prepend( FlexibleThrowerSmall(10));
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( list.first().value(), 0 );
- QCOMPARE( list.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- list3 = list;
- list3.append( FlexibleThrowerSmall(11) );
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( list.first().value(), 0 );
- QCOMPARE( list.size(), 10 );
- QCOMPARE( list3.size(), 10 );
- }
- QCOMPARE(objCounter, intancesCount); // check that every object has been freed
-}
-
-void tst_ExceptionSafety::exceptionVector()
-{
- const int intancesCount = objCounter;
- {
- int instances;
- QVector<FlexibleThrowerSmall> vector;
- QVector<FlexibleThrowerSmall> vector2;
- QVector<FlexibleThrowerSmall> vector3;
-
- for (int i = 0; i<10; i++)
- vector.append( FlexibleThrowerSmall(i) );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- vector.append( FlexibleThrowerSmall(10));
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( vector.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- vector.prepend( FlexibleThrowerSmall(10));
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( vector.at(0).value(), 0 );
- QCOMPARE( vector.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- vector.insert( 8, FlexibleThrowerSmall(10));
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( vector.at(7).value(), 7 );
- QCOMPARE( vector.at(8).value(), 8 );
- QCOMPARE( vector.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- vector3 = vector;
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( vector.at(0).value(), 0 );
- QCOMPARE( vector.at(7).value(), 7 );
- QCOMPARE( vector.size(), 10 );
- QCOMPARE( vector3.at(0).value(), 0 );
- QCOMPARE( vector3.at(7).value(), 7 );
- QCOMPARE( vector3.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCopy;
- vector3.append( FlexibleThrowerSmall(11) );
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( vector.at(0).value(), 0 );
- QCOMPARE( vector.at(7).value(), 7 );
- QCOMPARE( vector.size(), 10 );
- QCOMPARE( vector3.at(0).value(), 0 );
- QCOMPARE( vector3.at(7).value(), 7 );
-
- try {
- vector2.clear();
- vector2.append( FlexibleThrowerSmall(11));
- instances = objCounter;
- throwType = ThrowAtCopy;
- vector3 = vector+vector2;
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( vector.at(0).value(), 0 );
- QCOMPARE( vector.at(7).value(), 7 );
- QCOMPARE( vector.size(), 10 );
-
- // check that copy on write works atomar
- vector2.clear();
- vector2.append( FlexibleThrowerSmall(11));
- vector3 = vector+vector2;
- instances = objCounter;
- try {
- throwType = ThrowAtCreate;
- vector3[7]=FlexibleThrowerSmall(12);
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( vector.at(7).value(), 7 );
- QCOMPARE( vector.size(), 10 );
- QCOMPARE( vector3.at(7).value(), 7 );
- QCOMPARE( vector3.size(), 11 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCreate;
- vector.resize(15);
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( vector.at(7).value(), 7 );
- QCOMPARE( vector.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowAtCreate;
- vector.resize(15);
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( vector.at(7).value(), 7 );
- QCOMPARE( vector.size(), 10 );
-
- instances = objCounter;
- try {
- throwType = ThrowLater;
- vector.fill(FlexibleThrowerSmall(1), 15);
- } catch (...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( vector.at(0).value(), 0 );
- QCOMPARE( vector.size(), 10 );
- }
- QCOMPARE(objCounter, intancesCount); // check that every object has been freed
-}
-
-
-void tst_ExceptionSafety::exceptionMap()
-{
- const int intancesCount = objCounter;
- {
- int instances;
- MyMap map;
- MyMap map2;
- MyMap map3;
-
- throwType = ThrowNot;
- for (int i = 0; i<10; i++)
- map[ FlexibleThrowerSmall(i) ] = FlexibleThrowerSmall(i);
-
- return; // further test are deactivated until Map is fixed.
-
- for( int i = ThrowAtCopy; i<=ThrowAtComparison; i++ ) {
- instances = objCounter;
- try {
- throwType = (ThrowType)i;
- map[ FlexibleThrowerSmall(10) ] = FlexibleThrowerSmall(10);
- } catch(...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( map.size(), 10 );
- QCOMPARE( map[ FlexibleThrowerSmall(1) ], FlexibleThrowerSmall(1) );
- }
-
- map2 = map;
- instances = objCounter;
- try {
- throwType = ThrowLater;
- map2[ FlexibleThrowerSmall(10) ] = FlexibleThrowerSmall(10);
- } catch(...) {
- QCOMPARE(instances, objCounter);
- }
- /* qDebug("%d %d", map.size(), map2.size() );
- for( int i=0; i<map.size(); i++ )
- qDebug( "Value at %d: %d",i, map.value(FlexibleThrowerSmall(i), FlexibleThrowerSmall()).value() );
- QCOMPARE( map.value(FlexibleThrowerSmall(1), FlexibleThrowerSmall()), FlexibleThrowerSmall(1) );
- qDebug( "Value at %d: %d",1, map[FlexibleThrowerSmall(1)].value() );
- qDebug("%d %d", map.size(), map2.size() );
- */
- QCOMPARE( map[ FlexibleThrowerSmall(1) ], FlexibleThrowerSmall(1) );
- QCOMPARE( map.size(), 10 );
- QCOMPARE( map2[ FlexibleThrowerSmall(1) ], FlexibleThrowerSmall(1) );
- QCOMPARE( map2.size(), 10 );
-
- }
- QCOMPARE(objCounter, intancesCount); // check that every object has been freed
-}
-
-void tst_ExceptionSafety::exceptionHash()
-{
- const int intancesCount = objCounter;
- {
- int instances;
- MyHash hash;
- MyHash hash2;
- MyHash hash3;
-
- for( int i = 0; i<10; i++ )
- hash[ FlexibleThrowerSmall(i) ] = FlexibleThrowerSmall(i);
-
- for( int i = ThrowAtCopy; i<=ThrowAtComparison; i++ ) {
- instances = objCounter;
- try {
- throwType = (ThrowType)i;
- hash[ FlexibleThrowerSmall(10) ] = FlexibleThrowerSmall(10);
- } catch(...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( hash.size(), 10 );
- }
-
- hash2 = hash;
- instances = objCounter;
- try {
- throwType = ThrowLater;
- hash2[ FlexibleThrowerSmall(10) ] = FlexibleThrowerSmall(10);
- } catch(...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( hash[ FlexibleThrowerSmall(1) ], FlexibleThrowerSmall(1) );
- QCOMPARE( hash.size(), 10 );
- QCOMPARE( hash2[ FlexibleThrowerSmall(1) ], FlexibleThrowerSmall(1) );
- QCOMPARE( hash2.size(), 10 );
-
- hash2.clear();
- instances = objCounter;
- try {
- throwType = ThrowLater;
- hash2.reserve(30);
- } catch(...) {
- QCOMPARE(instances, objCounter);
- }
- QCOMPARE( hash2.size(), 0 );
-
- /*
- try {
- throwType = ThrowAtCopy;
- hash.prepend( FlexibleThrowerSmall(10));
- } catch (...) {
- }
- QCOMPARE( hash.at(0).value(), 0 );
- QCOMPARE( hash.size(), 10 );
-
- try {
- throwType = ThrowAtCopy;
- hash.insert( 8, FlexibleThrowerSmall(10));
- } catch (...) {
- }
- QCOMPARE( hash.at(7).value(), 7 );
- QCOMPARE( hash.at(8).value(), 8 );
- QCOMPARE( hash.size(), 10 );
-
- qDebug("val");
- try {
- throwType = ThrowAtCopy;
- hash3 = hash;
- } catch (...) {
- }
- QCOMPARE( hash.at(0).value(), 0 );
- QCOMPARE( hash.at(7).value(), 7 );
- QCOMPARE( hash.size(), 10 );
- QCOMPARE( hash3.at(0).value(), 0 );
- QCOMPARE( hash3.at(7).value(), 7 );
- QCOMPARE( hash3.size(), 10 );
-
- try {
- throwType = ThrowAtCopy;
- hash3.append( FlexibleThrowerSmall(11) );
- } catch (...) {
- }
- QCOMPARE( hash.at(0).value(), 0 );
- QCOMPARE( hash.at(7).value(), 7 );
- QCOMPARE( hash.size(), 10 );
- QCOMPARE( hash3.at(0).value(), 0 );
- QCOMPARE( hash3.at(7).value(), 7 );
- QCOMPARE( hash3.at(11).value(), 11 );
-
- try {
- hash2.clear();
- hash2.append( FlexibleThrowerSmall(11));
- throwType = ThrowAtCopy;
- hash3 = hash+hash2;
- } catch (...) {
- }
- QCOMPARE( hash.at(0).value(), 0 );
- QCOMPARE( hash.at(7).value(), 7 );
- QCOMPARE( hash.size(), 10 );
-
- // check that copy on write works atomar
- hash2.clear();
- hash2.append( FlexibleThrowerSmall(11));
- hash3 = hash+hash2;
- try {
- throwType = ThrowAtCopy;
- hash3[7]=FlexibleThrowerSmall(12);
- } catch (...) {
- }
- QCOMPARE( hash.at(7).value(), 7 );
- QCOMPARE( hash.size(), 10 );
- QCOMPARE( hash3.at(7).value(), 7 );
- QCOMPARE( hash3.size(), 11 );
- */
-
-
- }
- QCOMPARE(objCounter, intancesCount); // check that every object has been freed
-}
-
-// Disable these tests until the level of exception safety in event loops is clear
-#if 0
-enum
-{
- ThrowEventId = QEvent::User + 42,
- NoThrowEventId = QEvent::User + 43
-};
-
-class ThrowEvent : public QEvent
-{
-public:
- ThrowEvent()
- : QEvent(static_cast<QEvent::Type>(ThrowEventId))
- {
- }
-};
-
-class NoThrowEvent : public QEvent
-{
-public:
- NoThrowEvent()
- : QEvent(static_cast<QEvent::Type>(NoThrowEventId))
- {}
-};
-
-struct IntEx : public std::exception
-{
- IntEx(int aEx) : ex(aEx) {}
- int ex;
-};
-
-class TestObject : public QObject
-{
-public:
- TestObject()
- : throwEventCount(0), noThrowEventCount(0) {}
-
- int throwEventCount;
- int noThrowEventCount;
-
-protected:
- bool event(QEvent *event)
- {
- if (int(event->type()) == ThrowEventId) {
- throw IntEx(++throwEventCount);
- } else if (int(event->type()) == NoThrowEventId) {
- ++noThrowEventCount;
- }
- return QObject::event(event);
- }
-};
-
-void tst_ExceptionSafety::exceptionEventLoop()
-{
- // send an event that throws
- TestObject obj;
- ThrowEvent throwEvent;
- try {
- qApp->sendEvent(&obj, &throwEvent);
- } catch (IntEx code) {
- QCOMPARE(code.ex, 1);
- }
- QCOMPARE(obj.throwEventCount, 1);
-
- // post an event that throws
- qApp->postEvent(&obj, new ThrowEvent);
-
- try {
- qApp->processEvents();
- } catch (IntEx code) {
- QCOMPARE(code.ex, 2);
- }
- QCOMPARE(obj.throwEventCount, 2);
-
- // post a normal event, then a throwing event, then a normal event
- // run this in valgrind to ensure that it doesn't leak.
-
- qApp->postEvent(&obj, new NoThrowEvent);
- qApp->postEvent(&obj, new ThrowEvent);
- qApp->postEvent(&obj, new NoThrowEvent);
-
- try {
- qApp->processEvents();
- } catch (IntEx code) {
- QCOMPARE(code.ex, 3);
- }
- // here, we should have received on non-throwing event and one throwing one
- QCOMPARE(obj.throwEventCount, 3);
- QCOMPARE(obj.noThrowEventCount, 1);
-
- // spin the event loop again
- qApp->processEvents();
-
- // now, we should have received the second non-throwing event
- QCOMPARE(obj.noThrowEventCount, 2);
-}
-
-void tst_ExceptionSafety::exceptionSignalSlot()
-{
- Emitter e;
- ExceptionThrower thrower;
- Receiver r1;
- Receiver r2;
-
- // connect a signal to a normal object, a thrower and a normal object again
- connect(&e, SIGNAL(testSignal()), &r1, SLOT(receiver()));
- connect(&e, SIGNAL(testSignal()), &thrower, SLOT(thrower()));
- connect(&e, SIGNAL(testSignal()), &r2, SLOT(receiver()));
-
- int code = 0;
- try {
- e.emitTestSignal();
- } catch (int c) {
- code = c;
- }
-
- // 5 is the magic number that's thrown by thrower
- QCOMPARE(code, 5);
-
- // assumption: slots are called in the connection order
- QCOMPARE(r1.received, 1);
- QCOMPARE(r2.received, 0);
-}
-#endif
-
-
-static bool outOfMemory = false;
-void* internalMalloc(size_t bytes) { return outOfMemory ? 0 : malloc(bytes); }
-
-struct OutOfMemory
-{
- OutOfMemory() { outOfMemory = true; }
- ~OutOfMemory() { outOfMemory = false; }
-};
-
-void tst_ExceptionSafety::exceptionOOMQVarLengthArray()
-{
-#ifdef QT_NO_EXCEPTIONS
- // it will crash by design
- Q_STATIC_ASSERT(false);
-#else
- QVarLengthArray<char> arr0;
- int minSize = arr0.capacity();
-
- // constructor throws
- bool success = false;
- try {
- OutOfMemory oom;
- QVarLengthArray<char> arr(minSize * 2);
- } catch (const std::bad_alloc&) {
- success = true;
- }
- QVERIFY(success);
-
- QVarLengthArray<char> arr;
-
- // resize throws
- success = false;
- try {
- OutOfMemory oom;
- arr.resize(minSize * 2);
- } catch(const std::bad_alloc&) {
- arr.resize(1);
- success = true;
- }
- QVERIFY(success);
-#endif
-}
-
-#endif
-
-QTEST_MAIN(tst_ExceptionSafety)
-#include "tst_exceptionsafety.moc"
diff --git a/tests/auto/other/exceptionsafety_objects/3rdparty/memcheck.h b/tests/auto/other/exceptionsafety_objects/3rdparty/memcheck.h
deleted file mode 100644
index 72a02ca9ba..0000000000
--- a/tests/auto/other/exceptionsafety_objects/3rdparty/memcheck.h
+++ /dev/null
@@ -1,319 +0,0 @@
-
-/*
- ----------------------------------------------------------------
-
- Notice that the following BSD-style license applies to this one
- file (memcheck.h) only. The rest of Valgrind is licensed under the
- terms of the GNU General Public License, version 2, unless
- otherwise indicated. See the COPYING file in the source
- distribution for details.
-
- ----------------------------------------------------------------
-
- This file is part of MemCheck, a heavyweight Valgrind tool for
- detecting memory errors.
-
- Copyright (C) 2000-2008 Julian Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-
- ----------------------------------------------------------------
-
- Notice that the above BSD-style license applies to this one file
- (memcheck.h) only. The entire rest of Valgrind is licensed under
- the terms of the GNU General Public License, version 2. See the
- COPYING file in the source distribution for details.
-
- ----------------------------------------------------------------
-*/
-
-
-#ifndef __MEMCHECK_H
-#define __MEMCHECK_H
-
-
-/* This file is for inclusion into client (your!) code.
-
- You can use these macros to manipulate and query memory permissions
- inside your own programs.
-
- See comment near the top of valgrind.h on how to use them.
-*/
-
-#include "valgrind.h"
-
-/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
- This enum comprises an ABI exported by Valgrind to programs
- which use client requests. DO NOT CHANGE THE ORDER OF THESE
- ENTRIES, NOR DELETE ANY -- add new ones at the end. */
-typedef
- enum {
- VG_USERREQ__MAKE_MEM_NOACCESS = VG_USERREQ_TOOL_BASE('M','C'),
- VG_USERREQ__MAKE_MEM_UNDEFINED,
- VG_USERREQ__MAKE_MEM_DEFINED,
- VG_USERREQ__DISCARD,
- VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,
- VG_USERREQ__CHECK_MEM_IS_DEFINED,
- VG_USERREQ__DO_LEAK_CHECK,
- VG_USERREQ__COUNT_LEAKS,
-
- VG_USERREQ__GET_VBITS,
- VG_USERREQ__SET_VBITS,
-
- VG_USERREQ__CREATE_BLOCK,
-
- VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE,
-
- VG_USERREQ__ENABLE_OOM,
- VG_USERREQ__GET_ALLOC_INDEX,
-
- /* This is just for memcheck's internal use - don't use it */
- _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR
- = VG_USERREQ_TOOL_BASE('M','C') + 256,
-
- /* This is just for memcheck's internal use - don't use it */
- _VG_USERREQ__EXCEPTION
- = VG_USERREQ_TOOL_BASE('M','C') + 512,
- } Vg_MemCheckClientRequest;
-
-
-
-/* Client-code macros to manipulate the state of memory. */
-
-/* Mark memory at _qzz_addr as unaddressable for _qzz_len bytes. */
-#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr,_qzz_len) \
- (__extension__({unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
- VG_USERREQ__MAKE_MEM_NOACCESS, \
- _qzz_addr, _qzz_len, 0, 0, 0); \
- _qzz_res; \
- }))
-
-/* Similarly, mark memory at _qzz_addr as addressable but undefined
- for _qzz_len bytes. */
-#define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr,_qzz_len) \
- (__extension__({unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
- VG_USERREQ__MAKE_MEM_UNDEFINED, \
- _qzz_addr, _qzz_len, 0, 0, 0); \
- _qzz_res; \
- }))
-
-/* Similarly, mark memory at _qzz_addr as addressable and defined
- for _qzz_len bytes. */
-#define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr,_qzz_len) \
- (__extension__({unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
- VG_USERREQ__MAKE_MEM_DEFINED, \
- _qzz_addr, _qzz_len, 0, 0, 0); \
- _qzz_res; \
- }))
-
-/* Similar to VALGRIND_MAKE_MEM_DEFINED except that addressability is
- not altered: bytes which are addressable are marked as defined,
- but those which are not addressable are left unchanged. */
-#define VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(_qzz_addr,_qzz_len) \
- (__extension__({unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
- VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, \
- _qzz_addr, _qzz_len, 0, 0, 0); \
- _qzz_res; \
- }))
-
-/* Create a block-description handle. The description is an ascii
- string which is included in any messages pertaining to addresses
- within the specified memory range. Has no other effect on the
- properties of the memory range. */
-#define VALGRIND_CREATE_BLOCK(_qzz_addr,_qzz_len, _qzz_desc) \
- (__extension__({unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
- VG_USERREQ__CREATE_BLOCK, \
- _qzz_addr, _qzz_len, _qzz_desc, \
- 0, 0); \
- _qzz_res; \
- }))
-
-/* Discard a block-description-handle. Returns 1 for an
- invalid handle, 0 for a valid handle. */
-#define VALGRIND_DISCARD(_qzz_blkindex) \
- (__extension__ ({unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
- VG_USERREQ__DISCARD, \
- 0, _qzz_blkindex, 0, 0, 0); \
- _qzz_res; \
- }))
-
-
-/* Client-code macros to check the state of memory. */
-
-/* Check that memory at _qzz_addr is addressable for _qzz_len bytes.
- If suitable addressibility is not established, Valgrind prints an
- error message and returns the address of the first offending byte.
- Otherwise it returns zero. */
-#define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(_qzz_addr,_qzz_len) \
- (__extension__({unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,\
- _qzz_addr, _qzz_len, 0, 0, 0); \
- _qzz_res; \
- }))
-
-/* Check that memory at _qzz_addr is addressable and defined for
- _qzz_len bytes. If suitable addressibility and definedness are not
- established, Valgrind prints an error message and returns the
- address of the first offending byte. Otherwise it returns zero. */
-#define VALGRIND_CHECK_MEM_IS_DEFINED(_qzz_addr,_qzz_len) \
- (__extension__({unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__CHECK_MEM_IS_DEFINED, \
- _qzz_addr, _qzz_len, 0, 0, 0); \
- _qzz_res; \
- }))
-
-/* Use this macro to force the definedness and addressibility of an
- lvalue to be checked. If suitable addressibility and definedness
- are not established, Valgrind prints an error message and returns
- the address of the first offending byte. Otherwise it returns
- zero. */
-#define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) \
- VALGRIND_CHECK_MEM_IS_DEFINED( \
- (volatile unsigned char *)&(__lvalue), \
- (unsigned long)(sizeof (__lvalue)))
-
-
-/* Do a memory leak check mid-execution. */
-#define VALGRIND_DO_LEAK_CHECK \
- {unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__DO_LEAK_CHECK, \
- 0, 0, 0, 0, 0); \
- }
-
-/* Just display summaries of leaked memory, rather than all the
- details */
-#define VALGRIND_DO_QUICK_LEAK_CHECK \
- {unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__DO_LEAK_CHECK, \
- 1, 0, 0, 0, 0); \
- }
-
-/* Return number of leaked, dubious, reachable and suppressed bytes found by
- all previous leak checks. They must be lvalues. */
-#define VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed) \
- /* For safety on 64-bit platforms we assign the results to private
- unsigned long variables, then assign these to the lvalues the user
- specified, which works no matter what type 'leaked', 'dubious', etc
- are. We also initialise '_qzz_leaked', etc because
- VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as
- initialised. */ \
- {unsigned long _qzz_res; \
- unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \
- unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__COUNT_LEAKS, \
- &_qzz_leaked, &_qzz_dubious, \
- &_qzz_reachable, &_qzz_suppressed, 0); \
- leaked = _qzz_leaked; \
- dubious = _qzz_dubious; \
- reachable = _qzz_reachable; \
- suppressed = _qzz_suppressed; \
- }
-
-
-/* Get the validity data for addresses [zza..zza+zznbytes-1] and copy it
- into the provided zzvbits array. Return values:
- 0 if not running on valgrind
- 1 success
- 2 [previously indicated unaligned arrays; these are now allowed]
- 3 if any parts of zzsrc/zzvbits are not addressable.
- The metadata is not copied in cases 0, 2 or 3 so it should be
- impossible to segfault your system by using this call.
-*/
-#define VALGRIND_GET_VBITS(zza,zzvbits,zznbytes) \
- (__extension__({unsigned long _qzz_res; \
- char* czza = (char*)zza; \
- char* czzvbits = (char*)zzvbits; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__GET_VBITS, \
- czza, czzvbits, zznbytes, 0, 0 ); \
- _qzz_res; \
- }))
-
-/* Set the validity data for addresses [zza..zza+zznbytes-1], copying it
- from the provided zzvbits array. Return values:
- 0 if not running on valgrind
- 1 success
- 2 [previously indicated unaligned arrays; these are now allowed]
- 3 if any parts of zza/zzvbits are not addressable.
- The metadata is not copied in cases 0, 2 or 3 so it should be
- impossible to segfault your system by using this call.
-*/
-#define VALGRIND_SET_VBITS(zza,zzvbits,zznbytes) \
- (__extension__({unsigned int _qzz_res; \
- char* czza = (char*)zza; \
- char* czzvbits = (char*)zzvbits; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__SET_VBITS, \
- czza, czzvbits, zznbytes, 0, 0 ); \
- _qzz_res; \
- }))
-
-/* Enable or disable OOM simulation. */
-#define VALGRIND_ENABLE_OOM_AT_ALLOC_INDEX(index) \
- (__extension__ ({unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
- VG_USERREQ__ENABLE_OOM, \
- 1, index, 0, 0, 0); \
- _qzz_res; \
- }))
-
-#define VALGRIND_DISABLE_OOM_AT_ALLOC_INDEX(index) \
- (__extension__ ({unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
- VG_USERREQ__ENABLE_OOM, \
- 0, index, 0, 0, 0); \
- _qzz_res; \
- }))
-
-/* Get the current allocation index. */
-#define VALGRIND_GET_ALLOC_INDEX \
- (__extension__ ({unsigned long _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, -1 /* default return */, \
- VG_USERREQ__GET_ALLOC_INDEX, \
- 0, 0, 0, 0, 0); \
- _qzz_res; \
- }))
-
-
-#endif
-
diff --git a/tests/auto/other/exceptionsafety_objects/3rdparty/valgrind.h b/tests/auto/other/exceptionsafety_objects/3rdparty/valgrind.h
deleted file mode 100644
index bb054b5fd1..0000000000
--- a/tests/auto/other/exceptionsafety_objects/3rdparty/valgrind.h
+++ /dev/null
@@ -1,3924 +0,0 @@
-/* -*- c -*-
- ----------------------------------------------------------------
-
- Notice that the following BSD-style license applies to this one
- file (valgrind.h) only. The rest of Valgrind is licensed under the
- terms of the GNU General Public License, version 2, unless
- otherwise indicated. See the COPYING file in the source
- distribution for details.
-
- ----------------------------------------------------------------
-
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2000-2008 Julian Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-
- ----------------------------------------------------------------
-
- Notice that the above BSD-style license applies to this one file
- (valgrind.h) only. The entire rest of Valgrind is licensed under
- the terms of the GNU General Public License, version 2. See the
- COPYING file in the source distribution for details.
-
- ----------------------------------------------------------------
-*/
-
-
-/* This file is for inclusion into client (your!) code.
-
- You can use these macros to manipulate and query Valgrind's
- execution inside your own programs.
-
- The resulting executables will still run without Valgrind, just a
- little bit more slowly than they otherwise would, but otherwise
- unchanged. When not running on valgrind, each client request
- consumes very few (eg. 7) instructions, so the resulting performance
- loss is negligible unless you plan to execute client requests
- millions of times per second. Nevertheless, if that is still a
- problem, you can compile with the NVALGRIND symbol defined (gcc
- -DNVALGRIND) so that client requests are not even compiled in. */
-
-#ifndef __VALGRIND_H
-#define __VALGRIND_H
-
-#include <stdarg.h>
-
-/* Nb: this file might be included in a file compiled with -ansi. So
- we can't use C++ style "//" comments nor the "asm" keyword (instead
- use "__asm__"). */
-
-/* Derive some tags indicating what the target platform is. Note
- that in this file we're using the compiler's CPP symbols for
- identifying architectures, which are different to the ones we use
- within the rest of Valgrind. Note, __powerpc__ is active for both
- 32 and 64-bit PPC, whereas __powerpc64__ is only active for the
- latter (on Linux, that is). */
-#undef PLAT_x86_linux
-#undef PLAT_amd64_linux
-#undef PLAT_ppc32_linux
-#undef PLAT_ppc64_linux
-#undef PLAT_ppc32_aix5
-#undef PLAT_ppc64_aix5
-
-#if !defined(_AIX) && defined(__i386__)
-# define PLAT_x86_linux 1
-#elif !defined(_AIX) && defined(__x86_64__)
-# define PLAT_amd64_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
-# define PLAT_ppc32_linux 1
-#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
-# define PLAT_ppc64_linux 1
-#elif defined(_AIX) && defined(__64BIT__)
-# define PLAT_ppc64_aix5 1
-#elif defined(_AIX) && !defined(__64BIT__)
-# define PLAT_ppc32_aix5 1
-#endif
-
-
-/* If we're not compiling for our target platform, don't generate
- any inline asms. */
-#if !defined(PLAT_x86_linux) && !defined(PLAT_amd64_linux) \
- && !defined(PLAT_ppc32_linux) && !defined(PLAT_ppc64_linux) \
- && !defined(PLAT_ppc32_aix5) && !defined(PLAT_ppc64_aix5)
-# if !defined(NVALGRIND)
-# define NVALGRIND 1
-# endif
-#endif
-
-
-/* ------------------------------------------------------------------ */
-/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */
-/* in here of use to end-users -- skip to the next section. */
-/* ------------------------------------------------------------------ */
-
-#if defined(NVALGRIND)
-
-/* Define NVALGRIND to completely remove the Valgrind magic sequence
- from the compiled code (analogous to NDEBUG's effects on
- assert()) */
-#define VALGRIND_DO_CLIENT_REQUEST( \
- _zzq_rlval, _zzq_default, _zzq_request, \
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
- { \
- (_zzq_rlval) = (_zzq_default); \
- }
-
-#else /* ! NVALGRIND */
-
-/* The following defines the magic code sequences which the JITter
- spots and handles magically. Don't look too closely at them as
- they will rot your brain.
-
- The assembly code sequences for all architectures is in this one
- file. This is because this file must be stand-alone, and we don't
- want to have multiple files.
-
- For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
- value gets put in the return slot, so that everything works when
- this is executed not under Valgrind. Args are passed in a memory
- block, and so there's no intrinsic limit to the number that could
- be passed, but it's currently five.
-
- The macro args are:
- _zzq_rlval result lvalue
- _zzq_default default value (result returned when running on real CPU)
- _zzq_request request code
- _zzq_arg1..5 request params
-
- The other two macros are used to support function wrapping, and are
- a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the
- guest's NRADDR pseudo-register and whatever other information is
- needed to safely run the call original from the wrapper: on
- ppc64-linux, the R2 value at the divert point is also needed. This
- information is abstracted into a user-visible type, OrigFn.
-
- VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
- guest, but guarantees that the branch instruction will not be
- redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
- branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a
- complete inline asm, since it needs to be combined with more magic
- inline asm stuff to be useful.
-*/
-
-/* ------------------------- x86-linux ------------------------- */
-
-#if defined(PLAT_x86_linux)
-
-typedef
- struct {
- unsigned int nraddr; /* where's the code? */
- }
- OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE \
- "roll $3, %%edi ; roll $13, %%edi\n\t" \
- "roll $29, %%edi ; roll $19, %%edi\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST( \
- _zzq_rlval, _zzq_default, _zzq_request, \
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
- { volatile unsigned int _zzq_args[6]; \
- volatile unsigned int _zzq_result; \
- _zzq_args[0] = (unsigned int)(_zzq_request); \
- _zzq_args[1] = (unsigned int)(_zzq_arg1); \
- _zzq_args[2] = (unsigned int)(_zzq_arg2); \
- _zzq_args[3] = (unsigned int)(_zzq_arg3); \
- _zzq_args[4] = (unsigned int)(_zzq_arg4); \
- _zzq_args[5] = (unsigned int)(_zzq_arg5); \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %EDX = client_request ( %EAX ) */ \
- "xchgl %%ebx,%%ebx" \
- : "=d" (_zzq_result) \
- : "a" (&_zzq_args[0]), "0" (_zzq_default) \
- : "cc", "memory" \
- ); \
- _zzq_rlval = _zzq_result; \
- }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
- { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
- volatile unsigned int __addr; \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %EAX = guest_NRADDR */ \
- "xchgl %%ecx,%%ecx" \
- : "=a" (__addr) \
- : \
- : "cc", "memory" \
- ); \
- _zzq_orig->nraddr = __addr; \
- }
-
-#define VALGRIND_CALL_NOREDIR_EAX \
- __SPECIAL_INSTRUCTION_PREAMBLE \
- /* call-noredir *%EAX */ \
- "xchgl %%edx,%%edx\n\t"
-#endif /* PLAT_x86_linux */
-
-/* ------------------------ amd64-linux ------------------------ */
-
-#if defined(PLAT_amd64_linux)
-
-typedef
- struct {
- unsigned long long int nraddr; /* where's the code? */
- }
- OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE \
- "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \
- "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST( \
- _zzq_rlval, _zzq_default, _zzq_request, \
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
- { volatile unsigned long long int _zzq_args[6]; \
- volatile unsigned long long int _zzq_result; \
- _zzq_args[0] = (unsigned long long int)(_zzq_request); \
- _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
- _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
- _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
- _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
- _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %RDX = client_request ( %RAX ) */ \
- "xchgq %%rbx,%%rbx" \
- : "=d" (_zzq_result) \
- : "a" (&_zzq_args[0]), "0" (_zzq_default) \
- : "cc", "memory" \
- ); \
- _zzq_rlval = _zzq_result; \
- }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
- { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
- volatile unsigned long long int __addr; \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %RAX = guest_NRADDR */ \
- "xchgq %%rcx,%%rcx" \
- : "=a" (__addr) \
- : \
- : "cc", "memory" \
- ); \
- _zzq_orig->nraddr = __addr; \
- }
-
-#define VALGRIND_CALL_NOREDIR_RAX \
- __SPECIAL_INSTRUCTION_PREAMBLE \
- /* call-noredir *%RAX */ \
- "xchgq %%rdx,%%rdx\n\t"
-#endif /* PLAT_amd64_linux */
-
-/* ------------------------ ppc32-linux ------------------------ */
-
-#if defined(PLAT_ppc32_linux)
-
-typedef
- struct {
- unsigned int nraddr; /* where's the code? */
- }
- OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE \
- "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \
- "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST( \
- _zzq_rlval, _zzq_default, _zzq_request, \
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
- \
- { unsigned int _zzq_args[6]; \
- unsigned int _zzq_result; \
- unsigned int* _zzq_ptr; \
- _zzq_args[0] = (unsigned int)(_zzq_request); \
- _zzq_args[1] = (unsigned int)(_zzq_arg1); \
- _zzq_args[2] = (unsigned int)(_zzq_arg2); \
- _zzq_args[3] = (unsigned int)(_zzq_arg3); \
- _zzq_args[4] = (unsigned int)(_zzq_arg4); \
- _zzq_args[5] = (unsigned int)(_zzq_arg5); \
- _zzq_ptr = _zzq_args; \
- __asm__ volatile("mr 3,%1\n\t" /*default*/ \
- "mr 4,%2\n\t" /*ptr*/ \
- __SPECIAL_INSTRUCTION_PREAMBLE \
- /* %R3 = client_request ( %R4 ) */ \
- "or 1,1,1\n\t" \
- "mr %0,3" /*result*/ \
- : "=b" (_zzq_result) \
- : "b" (_zzq_default), "b" (_zzq_ptr) \
- : "cc", "memory", "r3", "r4"); \
- _zzq_rlval = _zzq_result; \
- }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
- { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
- unsigned int __addr; \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %R3 = guest_NRADDR */ \
- "or 2,2,2\n\t" \
- "mr %0,3" \
- : "=b" (__addr) \
- : \
- : "cc", "memory", "r3" \
- ); \
- _zzq_orig->nraddr = __addr; \
- }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- __SPECIAL_INSTRUCTION_PREAMBLE \
- /* branch-and-link-to-noredir *%R11 */ \
- "or 3,3,3\n\t"
-#endif /* PLAT_ppc32_linux */
-
-/* ------------------------ ppc64-linux ------------------------ */
-
-#if defined(PLAT_ppc64_linux)
-
-typedef
- struct {
- unsigned long long int nraddr; /* where's the code? */
- unsigned long long int r2; /* what tocptr do we need? */
- }
- OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE \
- "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
- "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST( \
- _zzq_rlval, _zzq_default, _zzq_request, \
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
- \
- { unsigned long long int _zzq_args[6]; \
- register unsigned long long int _zzq_result __asm__("r3"); \
- register unsigned long long int* _zzq_ptr __asm__("r4"); \
- _zzq_args[0] = (unsigned long long int)(_zzq_request); \
- _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
- _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
- _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
- _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
- _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \
- _zzq_ptr = _zzq_args; \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %R3 = client_request ( %R4 ) */ \
- "or 1,1,1" \
- : "=r" (_zzq_result) \
- : "0" (_zzq_default), "r" (_zzq_ptr) \
- : "cc", "memory"); \
- _zzq_rlval = _zzq_result; \
- }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
- { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
- register unsigned long long int __addr __asm__("r3"); \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %R3 = guest_NRADDR */ \
- "or 2,2,2" \
- : "=r" (__addr) \
- : \
- : "cc", "memory" \
- ); \
- _zzq_orig->nraddr = __addr; \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %R3 = guest_NRADDR_GPR2 */ \
- "or 4,4,4" \
- : "=r" (__addr) \
- : \
- : "cc", "memory" \
- ); \
- _zzq_orig->r2 = __addr; \
- }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- __SPECIAL_INSTRUCTION_PREAMBLE \
- /* branch-and-link-to-noredir *%R11 */ \
- "or 3,3,3\n\t"
-
-#endif /* PLAT_ppc64_linux */
-
-/* ------------------------ ppc32-aix5 ------------------------- */
-
-#if defined(PLAT_ppc32_aix5)
-
-typedef
- struct {
- unsigned int nraddr; /* where's the code? */
- unsigned int r2; /* what tocptr do we need? */
- }
- OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE \
- "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \
- "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST( \
- _zzq_rlval, _zzq_default, _zzq_request, \
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
- \
- { unsigned int _zzq_args[7]; \
- register unsigned int _zzq_result; \
- register unsigned int* _zzq_ptr; \
- _zzq_args[0] = (unsigned int)(_zzq_request); \
- _zzq_args[1] = (unsigned int)(_zzq_arg1); \
- _zzq_args[2] = (unsigned int)(_zzq_arg2); \
- _zzq_args[3] = (unsigned int)(_zzq_arg3); \
- _zzq_args[4] = (unsigned int)(_zzq_arg4); \
- _zzq_args[5] = (unsigned int)(_zzq_arg5); \
- _zzq_args[6] = (unsigned int)(_zzq_default); \
- _zzq_ptr = _zzq_args; \
- __asm__ volatile("mr 4,%1\n\t" \
- "lwz 3, 24(4)\n\t" \
- __SPECIAL_INSTRUCTION_PREAMBLE \
- /* %R3 = client_request ( %R4 ) */ \
- "or 1,1,1\n\t" \
- "mr %0,3" \
- : "=b" (_zzq_result) \
- : "b" (_zzq_ptr) \
- : "r3", "r4", "cc", "memory"); \
- _zzq_rlval = _zzq_result; \
- }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
- { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
- register unsigned int __addr; \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %R3 = guest_NRADDR */ \
- "or 2,2,2\n\t" \
- "mr %0,3" \
- : "=b" (__addr) \
- : \
- : "r3", "cc", "memory" \
- ); \
- _zzq_orig->nraddr = __addr; \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %R3 = guest_NRADDR_GPR2 */ \
- "or 4,4,4\n\t" \
- "mr %0,3" \
- : "=b" (__addr) \
- : \
- : "r3", "cc", "memory" \
- ); \
- _zzq_orig->r2 = __addr; \
- }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- __SPECIAL_INSTRUCTION_PREAMBLE \
- /* branch-and-link-to-noredir *%R11 */ \
- "or 3,3,3\n\t"
-
-#endif /* PLAT_ppc32_aix5 */
-
-/* ------------------------ ppc64-aix5 ------------------------- */
-
-#if defined(PLAT_ppc64_aix5)
-
-typedef
- struct {
- unsigned long long int nraddr; /* where's the code? */
- unsigned long long int r2; /* what tocptr do we need? */
- }
- OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE \
- "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
- "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST( \
- _zzq_rlval, _zzq_default, _zzq_request, \
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
- \
- { unsigned long long int _zzq_args[7]; \
- register unsigned long long int _zzq_result; \
- register unsigned long long int* _zzq_ptr; \
- _zzq_args[0] = (unsigned int long long)(_zzq_request); \
- _zzq_args[1] = (unsigned int long long)(_zzq_arg1); \
- _zzq_args[2] = (unsigned int long long)(_zzq_arg2); \
- _zzq_args[3] = (unsigned int long long)(_zzq_arg3); \
- _zzq_args[4] = (unsigned int long long)(_zzq_arg4); \
- _zzq_args[5] = (unsigned int long long)(_zzq_arg5); \
- _zzq_args[6] = (unsigned int long long)(_zzq_default); \
- _zzq_ptr = _zzq_args; \
- __asm__ volatile("mr 4,%1\n\t" \
- "ld 3, 48(4)\n\t" \
- __SPECIAL_INSTRUCTION_PREAMBLE \
- /* %R3 = client_request ( %R4 ) */ \
- "or 1,1,1\n\t" \
- "mr %0,3" \
- : "=b" (_zzq_result) \
- : "b" (_zzq_ptr) \
- : "r3", "r4", "cc", "memory"); \
- _zzq_rlval = _zzq_result; \
- }
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
- { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
- register unsigned long long int __addr; \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %R3 = guest_NRADDR */ \
- "or 2,2,2\n\t" \
- "mr %0,3" \
- : "=b" (__addr) \
- : \
- : "r3", "cc", "memory" \
- ); \
- _zzq_orig->nraddr = __addr; \
- __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
- /* %R3 = guest_NRADDR_GPR2 */ \
- "or 4,4,4\n\t" \
- "mr %0,3" \
- : "=b" (__addr) \
- : \
- : "r3", "cc", "memory" \
- ); \
- _zzq_orig->r2 = __addr; \
- }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- __SPECIAL_INSTRUCTION_PREAMBLE \
- /* branch-and-link-to-noredir *%R11 */ \
- "or 3,3,3\n\t"
-
-#endif /* PLAT_ppc64_aix5 */
-
-/* Insert assembly code for other platforms here... */
-
-#endif /* NVALGRIND */
-
-
-/* ------------------------------------------------------------------ */
-/* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */
-/* ugly. It's the least-worst tradeoff I can think of. */
-/* ------------------------------------------------------------------ */
-
-/* This section defines magic (a.k.a appalling-hack) macros for doing
- guaranteed-no-redirection macros, so as to get from function
- wrappers to the functions they are wrapping. The whole point is to
- construct standard call sequences, but to do the call itself with a
- special no-redirect call pseudo-instruction that the JIT
- understands and handles specially. This section is long and
- repetitious, and I can't see a way to make it shorter.
-
- The naming scheme is as follows:
-
- CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
-
- 'W' stands for "word" and 'v' for "void". Hence there are
- different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
- and for each, the possibility of returning a word-typed result, or
- no result.
-*/
-
-/* Use these to write the name of your wrapper. NOTE: duplicates
- VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
-
-#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \
- _vgwZU_##soname##_##fnname
-
-#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \
- _vgwZZ_##soname##_##fnname
-
-/* Use this macro from within a wrapper function to collect the
- context (address and possibly other info) of the original function.
- Once you have that you can then use it in one of the CALL_FN_
- macros. The type of the argument _lval is OrigFn. */
-#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval)
-
-/* Derivatives of the main macros below, for calling functions
- returning void. */
-
-#define CALL_FN_v_v(fnptr) \
- do { volatile unsigned long _junk; \
- CALL_FN_W_v(_junk,fnptr); } while (0)
-
-#define CALL_FN_v_W(fnptr, arg1) \
- do { volatile unsigned long _junk; \
- CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
-
-#define CALL_FN_v_WW(fnptr, arg1,arg2) \
- do { volatile unsigned long _junk; \
- CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
-
-#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \
- do { volatile unsigned long _junk; \
- CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
-
-/* ------------------------- x86-linux ------------------------- */
-
-#if defined(PLAT_x86_linux)
-
-/* These regs are trashed by the hidden call. No need to mention eax
- as gcc can already see that, plus causes gcc to bomb. */
-#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
-
-/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
- long) == 4. */
-
-#define CALL_FN_W_v(lval, orig) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[1]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- __asm__ volatile( \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[2]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- __asm__ volatile( \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $4, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- __asm__ volatile( \
- "pushl 8(%%eax)\n\t" \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $8, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[4]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- __asm__ volatile( \
- "pushl 12(%%eax)\n\t" \
- "pushl 8(%%eax)\n\t" \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $12, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[5]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- __asm__ volatile( \
- "pushl 16(%%eax)\n\t" \
- "pushl 12(%%eax)\n\t" \
- "pushl 8(%%eax)\n\t" \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $16, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[6]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- __asm__ volatile( \
- "pushl 20(%%eax)\n\t" \
- "pushl 16(%%eax)\n\t" \
- "pushl 12(%%eax)\n\t" \
- "pushl 8(%%eax)\n\t" \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $20, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[7]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- __asm__ volatile( \
- "pushl 24(%%eax)\n\t" \
- "pushl 20(%%eax)\n\t" \
- "pushl 16(%%eax)\n\t" \
- "pushl 12(%%eax)\n\t" \
- "pushl 8(%%eax)\n\t" \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $24, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[8]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- __asm__ volatile( \
- "pushl 28(%%eax)\n\t" \
- "pushl 24(%%eax)\n\t" \
- "pushl 20(%%eax)\n\t" \
- "pushl 16(%%eax)\n\t" \
- "pushl 12(%%eax)\n\t" \
- "pushl 8(%%eax)\n\t" \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $28, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[9]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- __asm__ volatile( \
- "pushl 32(%%eax)\n\t" \
- "pushl 28(%%eax)\n\t" \
- "pushl 24(%%eax)\n\t" \
- "pushl 20(%%eax)\n\t" \
- "pushl 16(%%eax)\n\t" \
- "pushl 12(%%eax)\n\t" \
- "pushl 8(%%eax)\n\t" \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $32, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[10]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
- __asm__ volatile( \
- "pushl 36(%%eax)\n\t" \
- "pushl 32(%%eax)\n\t" \
- "pushl 28(%%eax)\n\t" \
- "pushl 24(%%eax)\n\t" \
- "pushl 20(%%eax)\n\t" \
- "pushl 16(%%eax)\n\t" \
- "pushl 12(%%eax)\n\t" \
- "pushl 8(%%eax)\n\t" \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $36, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[11]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
- _argvec[10] = (unsigned long)(arg10); \
- __asm__ volatile( \
- "pushl 40(%%eax)\n\t" \
- "pushl 36(%%eax)\n\t" \
- "pushl 32(%%eax)\n\t" \
- "pushl 28(%%eax)\n\t" \
- "pushl 24(%%eax)\n\t" \
- "pushl 20(%%eax)\n\t" \
- "pushl 16(%%eax)\n\t" \
- "pushl 12(%%eax)\n\t" \
- "pushl 8(%%eax)\n\t" \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $40, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
- arg6,arg7,arg8,arg9,arg10, \
- arg11) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[12]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
- _argvec[10] = (unsigned long)(arg10); \
- _argvec[11] = (unsigned long)(arg11); \
- __asm__ volatile( \
- "pushl 44(%%eax)\n\t" \
- "pushl 40(%%eax)\n\t" \
- "pushl 36(%%eax)\n\t" \
- "pushl 32(%%eax)\n\t" \
- "pushl 28(%%eax)\n\t" \
- "pushl 24(%%eax)\n\t" \
- "pushl 20(%%eax)\n\t" \
- "pushl 16(%%eax)\n\t" \
- "pushl 12(%%eax)\n\t" \
- "pushl 8(%%eax)\n\t" \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $44, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
- arg6,arg7,arg8,arg9,arg10, \
- arg11,arg12) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[13]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
- _argvec[10] = (unsigned long)(arg10); \
- _argvec[11] = (unsigned long)(arg11); \
- _argvec[12] = (unsigned long)(arg12); \
- __asm__ volatile( \
- "pushl 48(%%eax)\n\t" \
- "pushl 44(%%eax)\n\t" \
- "pushl 40(%%eax)\n\t" \
- "pushl 36(%%eax)\n\t" \
- "pushl 32(%%eax)\n\t" \
- "pushl 28(%%eax)\n\t" \
- "pushl 24(%%eax)\n\t" \
- "pushl 20(%%eax)\n\t" \
- "pushl 16(%%eax)\n\t" \
- "pushl 12(%%eax)\n\t" \
- "pushl 8(%%eax)\n\t" \
- "pushl 4(%%eax)\n\t" \
- "movl (%%eax), %%eax\n\t" /* target->%eax */ \
- VALGRIND_CALL_NOREDIR_EAX \
- "addl $48, %%esp\n" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#endif /* PLAT_x86_linux */
-
-/* ------------------------ amd64-linux ------------------------ */
-
-#if defined(PLAT_amd64_linux)
-
-/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \
- "rdi", "r8", "r9", "r10", "r11"
-
-/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
- long) == 8. */
-
-/* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_
- macros. In order not to trash the stack redzone, we need to drop
- %rsp by 128 before the hidden call, and restore afterwards. The
- nastyness is that it is only by luck that the stack still appears
- to be unwindable during the hidden call - since then the behaviour
- of any routine using this macro does not match what the CFI data
- says. Sigh.
-
- Why is this important? Imagine that a wrapper has a stack
- allocated local, and passes to the hidden call, a pointer to it.
- Because gcc does not know about the hidden call, it may allocate
- that local in the redzone. Unfortunately the hidden call may then
- trash it before it comes to use it. So we must step clear of the
- redzone, for the duration of the hidden call, to make it safe.
-
- Probably the same problem afflicts the other redzone-style ABIs too
- (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is
- self describing (none of this CFI nonsense) so at least messing
- with the stack pointer doesn't give a danger of non-unwindable
- stack. */
-
-#define CALL_FN_W_v(lval, orig) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[1]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[2]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "movq 16(%%rax), %%rsi\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[4]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "movq 24(%%rax), %%rdx\n\t" \
- "movq 16(%%rax), %%rsi\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[5]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "movq 32(%%rax), %%rcx\n\t" \
- "movq 24(%%rax), %%rdx\n\t" \
- "movq 16(%%rax), %%rsi\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[6]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "movq 40(%%rax), %%r8\n\t" \
- "movq 32(%%rax), %%rcx\n\t" \
- "movq 24(%%rax), %%rdx\n\t" \
- "movq 16(%%rax), %%rsi\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[7]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "movq 48(%%rax), %%r9\n\t" \
- "movq 40(%%rax), %%r8\n\t" \
- "movq 32(%%rax), %%rcx\n\t" \
- "movq 24(%%rax), %%rdx\n\t" \
- "movq 16(%%rax), %%rsi\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- "addq $128,%%rsp\n\t" \
- VALGRIND_CALL_NOREDIR_RAX \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[8]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "pushq 56(%%rax)\n\t" \
- "movq 48(%%rax), %%r9\n\t" \
- "movq 40(%%rax), %%r8\n\t" \
- "movq 32(%%rax), %%rcx\n\t" \
- "movq 24(%%rax), %%rdx\n\t" \
- "movq 16(%%rax), %%rsi\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $8, %%rsp\n" \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[9]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "pushq 64(%%rax)\n\t" \
- "pushq 56(%%rax)\n\t" \
- "movq 48(%%rax), %%r9\n\t" \
- "movq 40(%%rax), %%r8\n\t" \
- "movq 32(%%rax), %%rcx\n\t" \
- "movq 24(%%rax), %%rdx\n\t" \
- "movq 16(%%rax), %%rsi\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $16, %%rsp\n" \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[10]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "pushq 72(%%rax)\n\t" \
- "pushq 64(%%rax)\n\t" \
- "pushq 56(%%rax)\n\t" \
- "movq 48(%%rax), %%r9\n\t" \
- "movq 40(%%rax), %%r8\n\t" \
- "movq 32(%%rax), %%rcx\n\t" \
- "movq 24(%%rax), %%rdx\n\t" \
- "movq 16(%%rax), %%rsi\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $24, %%rsp\n" \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[11]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
- _argvec[10] = (unsigned long)(arg10); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "pushq 80(%%rax)\n\t" \
- "pushq 72(%%rax)\n\t" \
- "pushq 64(%%rax)\n\t" \
- "pushq 56(%%rax)\n\t" \
- "movq 48(%%rax), %%r9\n\t" \
- "movq 40(%%rax), %%r8\n\t" \
- "movq 32(%%rax), %%rcx\n\t" \
- "movq 24(%%rax), %%rdx\n\t" \
- "movq 16(%%rax), %%rsi\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $32, %%rsp\n" \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10,arg11) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[12]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
- _argvec[10] = (unsigned long)(arg10); \
- _argvec[11] = (unsigned long)(arg11); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "pushq 88(%%rax)\n\t" \
- "pushq 80(%%rax)\n\t" \
- "pushq 72(%%rax)\n\t" \
- "pushq 64(%%rax)\n\t" \
- "pushq 56(%%rax)\n\t" \
- "movq 48(%%rax), %%r9\n\t" \
- "movq 40(%%rax), %%r8\n\t" \
- "movq 32(%%rax), %%rcx\n\t" \
- "movq 24(%%rax), %%rdx\n\t" \
- "movq 16(%%rax), %%rsi\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $40, %%rsp\n" \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10,arg11,arg12) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[13]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)(arg1); \
- _argvec[2] = (unsigned long)(arg2); \
- _argvec[3] = (unsigned long)(arg3); \
- _argvec[4] = (unsigned long)(arg4); \
- _argvec[5] = (unsigned long)(arg5); \
- _argvec[6] = (unsigned long)(arg6); \
- _argvec[7] = (unsigned long)(arg7); \
- _argvec[8] = (unsigned long)(arg8); \
- _argvec[9] = (unsigned long)(arg9); \
- _argvec[10] = (unsigned long)(arg10); \
- _argvec[11] = (unsigned long)(arg11); \
- _argvec[12] = (unsigned long)(arg12); \
- __asm__ volatile( \
- "subq $128,%%rsp\n\t" \
- "pushq 96(%%rax)\n\t" \
- "pushq 88(%%rax)\n\t" \
- "pushq 80(%%rax)\n\t" \
- "pushq 72(%%rax)\n\t" \
- "pushq 64(%%rax)\n\t" \
- "pushq 56(%%rax)\n\t" \
- "movq 48(%%rax), %%r9\n\t" \
- "movq 40(%%rax), %%r8\n\t" \
- "movq 32(%%rax), %%rcx\n\t" \
- "movq 24(%%rax), %%rdx\n\t" \
- "movq 16(%%rax), %%rsi\n\t" \
- "movq 8(%%rax), %%rdi\n\t" \
- "movq (%%rax), %%rax\n\t" /* target->%rax */ \
- VALGRIND_CALL_NOREDIR_RAX \
- "addq $48, %%rsp\n" \
- "addq $128,%%rsp\n\t" \
- : /*out*/ "=a" (_res) \
- : /*in*/ "a" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#endif /* PLAT_amd64_linux */
-
-/* ------------------------ ppc32-linux ------------------------ */
-
-#if defined(PLAT_ppc32_linux)
-
-/* This is useful for finding out about the on-stack stuff:
-
- extern int f9 ( int,int,int,int,int,int,int,int,int );
- extern int f10 ( int,int,int,int,int,int,int,int,int,int );
- extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
- extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
-
- int g9 ( void ) {
- return f9(11,22,33,44,55,66,77,88,99);
- }
- int g10 ( void ) {
- return f10(11,22,33,44,55,66,77,88,99,110);
- }
- int g11 ( void ) {
- return f11(11,22,33,44,55,66,77,88,99,110,121);
- }
- int g12 ( void ) {
- return f12(11,22,33,44,55,66,77,88,99,110,121,132);
- }
-*/
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS \
- "lr", "ctr", "xer", \
- "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
- "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
- "r11", "r12", "r13"
-
-/* These CALL_FN_ macros assume that on ppc32-linux,
- sizeof(unsigned long) == 4. */
-
-#define CALL_FN_W_v(lval, orig) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[1]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[2]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- _argvec[2] = (unsigned long)arg2; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 4,8(11)\n\t" \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[4]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- _argvec[2] = (unsigned long)arg2; \
- _argvec[3] = (unsigned long)arg3; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 4,8(11)\n\t" \
- "lwz 5,12(11)\n\t" \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[5]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- _argvec[2] = (unsigned long)arg2; \
- _argvec[3] = (unsigned long)arg3; \
- _argvec[4] = (unsigned long)arg4; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 4,8(11)\n\t" \
- "lwz 5,12(11)\n\t" \
- "lwz 6,16(11)\n\t" /* arg4->r6 */ \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[6]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- _argvec[2] = (unsigned long)arg2; \
- _argvec[3] = (unsigned long)arg3; \
- _argvec[4] = (unsigned long)arg4; \
- _argvec[5] = (unsigned long)arg5; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 4,8(11)\n\t" \
- "lwz 5,12(11)\n\t" \
- "lwz 6,16(11)\n\t" /* arg4->r6 */ \
- "lwz 7,20(11)\n\t" \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[7]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- _argvec[2] = (unsigned long)arg2; \
- _argvec[3] = (unsigned long)arg3; \
- _argvec[4] = (unsigned long)arg4; \
- _argvec[5] = (unsigned long)arg5; \
- _argvec[6] = (unsigned long)arg6; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 4,8(11)\n\t" \
- "lwz 5,12(11)\n\t" \
- "lwz 6,16(11)\n\t" /* arg4->r6 */ \
- "lwz 7,20(11)\n\t" \
- "lwz 8,24(11)\n\t" \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[8]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- _argvec[2] = (unsigned long)arg2; \
- _argvec[3] = (unsigned long)arg3; \
- _argvec[4] = (unsigned long)arg4; \
- _argvec[5] = (unsigned long)arg5; \
- _argvec[6] = (unsigned long)arg6; \
- _argvec[7] = (unsigned long)arg7; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 4,8(11)\n\t" \
- "lwz 5,12(11)\n\t" \
- "lwz 6,16(11)\n\t" /* arg4->r6 */ \
- "lwz 7,20(11)\n\t" \
- "lwz 8,24(11)\n\t" \
- "lwz 9,28(11)\n\t" \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[9]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- _argvec[2] = (unsigned long)arg2; \
- _argvec[3] = (unsigned long)arg3; \
- _argvec[4] = (unsigned long)arg4; \
- _argvec[5] = (unsigned long)arg5; \
- _argvec[6] = (unsigned long)arg6; \
- _argvec[7] = (unsigned long)arg7; \
- _argvec[8] = (unsigned long)arg8; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 4,8(11)\n\t" \
- "lwz 5,12(11)\n\t" \
- "lwz 6,16(11)\n\t" /* arg4->r6 */ \
- "lwz 7,20(11)\n\t" \
- "lwz 8,24(11)\n\t" \
- "lwz 9,28(11)\n\t" \
- "lwz 10,32(11)\n\t" /* arg8->r10 */ \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[10]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- _argvec[2] = (unsigned long)arg2; \
- _argvec[3] = (unsigned long)arg3; \
- _argvec[4] = (unsigned long)arg4; \
- _argvec[5] = (unsigned long)arg5; \
- _argvec[6] = (unsigned long)arg6; \
- _argvec[7] = (unsigned long)arg7; \
- _argvec[8] = (unsigned long)arg8; \
- _argvec[9] = (unsigned long)arg9; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "addi 1,1,-16\n\t" \
- /* arg9 */ \
- "lwz 3,36(11)\n\t" \
- "stw 3,8(1)\n\t" \
- /* args1-8 */ \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 4,8(11)\n\t" \
- "lwz 5,12(11)\n\t" \
- "lwz 6,16(11)\n\t" /* arg4->r6 */ \
- "lwz 7,20(11)\n\t" \
- "lwz 8,24(11)\n\t" \
- "lwz 9,28(11)\n\t" \
- "lwz 10,32(11)\n\t" /* arg8->r10 */ \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "addi 1,1,16\n\t" \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[11]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- _argvec[2] = (unsigned long)arg2; \
- _argvec[3] = (unsigned long)arg3; \
- _argvec[4] = (unsigned long)arg4; \
- _argvec[5] = (unsigned long)arg5; \
- _argvec[6] = (unsigned long)arg6; \
- _argvec[7] = (unsigned long)arg7; \
- _argvec[8] = (unsigned long)arg8; \
- _argvec[9] = (unsigned long)arg9; \
- _argvec[10] = (unsigned long)arg10; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "addi 1,1,-16\n\t" \
- /* arg10 */ \
- "lwz 3,40(11)\n\t" \
- "stw 3,12(1)\n\t" \
- /* arg9 */ \
- "lwz 3,36(11)\n\t" \
- "stw 3,8(1)\n\t" \
- /* args1-8 */ \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 4,8(11)\n\t" \
- "lwz 5,12(11)\n\t" \
- "lwz 6,16(11)\n\t" /* arg4->r6 */ \
- "lwz 7,20(11)\n\t" \
- "lwz 8,24(11)\n\t" \
- "lwz 9,28(11)\n\t" \
- "lwz 10,32(11)\n\t" /* arg8->r10 */ \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "addi 1,1,16\n\t" \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10,arg11) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[12]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- _argvec[2] = (unsigned long)arg2; \
- _argvec[3] = (unsigned long)arg3; \
- _argvec[4] = (unsigned long)arg4; \
- _argvec[5] = (unsigned long)arg5; \
- _argvec[6] = (unsigned long)arg6; \
- _argvec[7] = (unsigned long)arg7; \
- _argvec[8] = (unsigned long)arg8; \
- _argvec[9] = (unsigned long)arg9; \
- _argvec[10] = (unsigned long)arg10; \
- _argvec[11] = (unsigned long)arg11; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "addi 1,1,-32\n\t" \
- /* arg11 */ \
- "lwz 3,44(11)\n\t" \
- "stw 3,16(1)\n\t" \
- /* arg10 */ \
- "lwz 3,40(11)\n\t" \
- "stw 3,12(1)\n\t" \
- /* arg9 */ \
- "lwz 3,36(11)\n\t" \
- "stw 3,8(1)\n\t" \
- /* args1-8 */ \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 4,8(11)\n\t" \
- "lwz 5,12(11)\n\t" \
- "lwz 6,16(11)\n\t" /* arg4->r6 */ \
- "lwz 7,20(11)\n\t" \
- "lwz 8,24(11)\n\t" \
- "lwz 9,28(11)\n\t" \
- "lwz 10,32(11)\n\t" /* arg8->r10 */ \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "addi 1,1,32\n\t" \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10,arg11,arg12) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[13]; \
- volatile unsigned long _res; \
- _argvec[0] = (unsigned long)_orig.nraddr; \
- _argvec[1] = (unsigned long)arg1; \
- _argvec[2] = (unsigned long)arg2; \
- _argvec[3] = (unsigned long)arg3; \
- _argvec[4] = (unsigned long)arg4; \
- _argvec[5] = (unsigned long)arg5; \
- _argvec[6] = (unsigned long)arg6; \
- _argvec[7] = (unsigned long)arg7; \
- _argvec[8] = (unsigned long)arg8; \
- _argvec[9] = (unsigned long)arg9; \
- _argvec[10] = (unsigned long)arg10; \
- _argvec[11] = (unsigned long)arg11; \
- _argvec[12] = (unsigned long)arg12; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "addi 1,1,-32\n\t" \
- /* arg12 */ \
- "lwz 3,48(11)\n\t" \
- "stw 3,20(1)\n\t" \
- /* arg11 */ \
- "lwz 3,44(11)\n\t" \
- "stw 3,16(1)\n\t" \
- /* arg10 */ \
- "lwz 3,40(11)\n\t" \
- "stw 3,12(1)\n\t" \
- /* arg9 */ \
- "lwz 3,36(11)\n\t" \
- "stw 3,8(1)\n\t" \
- /* args1-8 */ \
- "lwz 3,4(11)\n\t" /* arg1->r3 */ \
- "lwz 4,8(11)\n\t" \
- "lwz 5,12(11)\n\t" \
- "lwz 6,16(11)\n\t" /* arg4->r6 */ \
- "lwz 7,20(11)\n\t" \
- "lwz 8,24(11)\n\t" \
- "lwz 9,28(11)\n\t" \
- "lwz 10,32(11)\n\t" /* arg8->r10 */ \
- "lwz 11,0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "addi 1,1,32\n\t" \
- "mr %0,3" \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#endif /* PLAT_ppc32_linux */
-
-/* ------------------------ ppc64-linux ------------------------ */
-
-#if defined(PLAT_ppc64_linux)
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS \
- "lr", "ctr", "xer", \
- "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
- "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
- "r11", "r12", "r13"
-
-/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
- long) == 8. */
-
-#define CALL_FN_W_v(lval, orig) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+0]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)" /* restore tocptr */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+1]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)" /* restore tocptr */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+2]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)" /* restore tocptr */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+3]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)" /* restore tocptr */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+4]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)" /* restore tocptr */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+5]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)" /* restore tocptr */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+6]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)" /* restore tocptr */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+7]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)" /* restore tocptr */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+8]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 10, 64(11)\n\t" /* arg8->r10 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)" /* restore tocptr */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+9]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "addi 1,1,-128\n\t" /* expand stack frame */ \
- /* arg9 */ \
- "ld 3,72(11)\n\t" \
- "std 3,112(1)\n\t" \
- /* args1-8 */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 10, 64(11)\n\t" /* arg8->r10 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- "addi 1,1,128" /* restore frame */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+10]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- _argvec[2+10] = (unsigned long)arg10; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "addi 1,1,-128\n\t" /* expand stack frame */ \
- /* arg10 */ \
- "ld 3,80(11)\n\t" \
- "std 3,120(1)\n\t" \
- /* arg9 */ \
- "ld 3,72(11)\n\t" \
- "std 3,112(1)\n\t" \
- /* args1-8 */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 10, 64(11)\n\t" /* arg8->r10 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- "addi 1,1,128" /* restore frame */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10,arg11) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+11]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- _argvec[2+10] = (unsigned long)arg10; \
- _argvec[2+11] = (unsigned long)arg11; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "addi 1,1,-144\n\t" /* expand stack frame */ \
- /* arg11 */ \
- "ld 3,88(11)\n\t" \
- "std 3,128(1)\n\t" \
- /* arg10 */ \
- "ld 3,80(11)\n\t" \
- "std 3,120(1)\n\t" \
- /* arg9 */ \
- "ld 3,72(11)\n\t" \
- "std 3,112(1)\n\t" \
- /* args1-8 */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 10, 64(11)\n\t" /* arg8->r10 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- "addi 1,1,144" /* restore frame */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10,arg11,arg12) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+12]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- _argvec[2+10] = (unsigned long)arg10; \
- _argvec[2+11] = (unsigned long)arg11; \
- _argvec[2+12] = (unsigned long)arg12; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "addi 1,1,-144\n\t" /* expand stack frame */ \
- /* arg12 */ \
- "ld 3,96(11)\n\t" \
- "std 3,136(1)\n\t" \
- /* arg11 */ \
- "ld 3,88(11)\n\t" \
- "std 3,128(1)\n\t" \
- /* arg10 */ \
- "ld 3,80(11)\n\t" \
- "std 3,120(1)\n\t" \
- /* arg9 */ \
- "ld 3,72(11)\n\t" \
- "std 3,112(1)\n\t" \
- /* args1-8 */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 10, 64(11)\n\t" /* arg8->r10 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- "addi 1,1,144" /* restore frame */ \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#endif /* PLAT_ppc64_linux */
-
-/* ------------------------ ppc32-aix5 ------------------------- */
-
-#if defined(PLAT_ppc32_aix5)
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS \
- "lr", "ctr", "xer", \
- "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
- "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
- "r11", "r12", "r13"
-
-/* Expand the stack frame, copying enough info that unwinding
- still works. Trashes r3. */
-
-#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \
- "addi 1,1,-" #_n_fr "\n\t" \
- "lwz 3," #_n_fr "(1)\n\t" \
- "stw 3,0(1)\n\t"
-
-#define VG_CONTRACT_FRAME_BY(_n_fr) \
- "addi 1,1," #_n_fr "\n\t"
-
-/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned
- long) == 4. */
-
-#define CALL_FN_W_v(lval, orig) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+0]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+1]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+2]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+3]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
- "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+4]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
- "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
- "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+5]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
- "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
- "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
- "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+6]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
- "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
- "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
- "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
- "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+7]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
- "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
- "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
- "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
- "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
- "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+8]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
- "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
- "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
- "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
- "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
- "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
- "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+9]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- VG_EXPAND_FRAME_BY_trashes_r3(64) \
- /* arg9 */ \
- "lwz 3,36(11)\n\t" \
- "stw 3,56(1)\n\t" \
- /* args1-8 */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
- "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
- "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
- "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
- "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
- "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
- "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(64) \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+10]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- _argvec[2+10] = (unsigned long)arg10; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- VG_EXPAND_FRAME_BY_trashes_r3(64) \
- /* arg10 */ \
- "lwz 3,40(11)\n\t" \
- "stw 3,60(1)\n\t" \
- /* arg9 */ \
- "lwz 3,36(11)\n\t" \
- "stw 3,56(1)\n\t" \
- /* args1-8 */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
- "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
- "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
- "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
- "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
- "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
- "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(64) \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10,arg11) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+11]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- _argvec[2+10] = (unsigned long)arg10; \
- _argvec[2+11] = (unsigned long)arg11; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- VG_EXPAND_FRAME_BY_trashes_r3(72) \
- /* arg11 */ \
- "lwz 3,44(11)\n\t" \
- "stw 3,64(1)\n\t" \
- /* arg10 */ \
- "lwz 3,40(11)\n\t" \
- "stw 3,60(1)\n\t" \
- /* arg9 */ \
- "lwz 3,36(11)\n\t" \
- "stw 3,56(1)\n\t" \
- /* args1-8 */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
- "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
- "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
- "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
- "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
- "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
- "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(72) \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10,arg11,arg12) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+12]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- _argvec[2+10] = (unsigned long)arg10; \
- _argvec[2+11] = (unsigned long)arg11; \
- _argvec[2+12] = (unsigned long)arg12; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "stw 2,-8(11)\n\t" /* save tocptr */ \
- "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
- VG_EXPAND_FRAME_BY_trashes_r3(72) \
- /* arg12 */ \
- "lwz 3,48(11)\n\t" \
- "stw 3,68(1)\n\t" \
- /* arg11 */ \
- "lwz 3,44(11)\n\t" \
- "stw 3,64(1)\n\t" \
- /* arg10 */ \
- "lwz 3,40(11)\n\t" \
- "stw 3,60(1)\n\t" \
- /* arg9 */ \
- "lwz 3,36(11)\n\t" \
- "stw 3,56(1)\n\t" \
- /* args1-8 */ \
- "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
- "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
- "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
- "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
- "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
- "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
- "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
- "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
- "lwz 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "lwz 2,-8(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(72) \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#endif /* PLAT_ppc32_aix5 */
-
-/* ------------------------ ppc64-aix5 ------------------------- */
-
-#if defined(PLAT_ppc64_aix5)
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS \
- "lr", "ctr", "xer", \
- "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
- "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
- "r11", "r12", "r13"
-
-/* Expand the stack frame, copying enough info that unwinding
- still works. Trashes r3. */
-
-#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \
- "addi 1,1,-" #_n_fr "\n\t" \
- "ld 3," #_n_fr "(1)\n\t" \
- "std 3,0(1)\n\t"
-
-#define VG_CONTRACT_FRAME_BY(_n_fr) \
- "addi 1,1," #_n_fr "\n\t"
-
-/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned
- long) == 8. */
-
-#define CALL_FN_W_v(lval, orig) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+0]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+1]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+2]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+3]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+4]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+5]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+6]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+7]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+8]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 10, 64(11)\n\t" /* arg8->r10 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+9]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- VG_EXPAND_FRAME_BY_trashes_r3(128) \
- /* arg9 */ \
- "ld 3,72(11)\n\t" \
- "std 3,112(1)\n\t" \
- /* args1-8 */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 10, 64(11)\n\t" /* arg8->r10 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(128) \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+10]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- _argvec[2+10] = (unsigned long)arg10; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- VG_EXPAND_FRAME_BY_trashes_r3(128) \
- /* arg10 */ \
- "ld 3,80(11)\n\t" \
- "std 3,120(1)\n\t" \
- /* arg9 */ \
- "ld 3,72(11)\n\t" \
- "std 3,112(1)\n\t" \
- /* args1-8 */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 10, 64(11)\n\t" /* arg8->r10 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(128) \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10,arg11) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+11]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- _argvec[2+10] = (unsigned long)arg10; \
- _argvec[2+11] = (unsigned long)arg11; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- VG_EXPAND_FRAME_BY_trashes_r3(144) \
- /* arg11 */ \
- "ld 3,88(11)\n\t" \
- "std 3,128(1)\n\t" \
- /* arg10 */ \
- "ld 3,80(11)\n\t" \
- "std 3,120(1)\n\t" \
- /* arg9 */ \
- "ld 3,72(11)\n\t" \
- "std 3,112(1)\n\t" \
- /* args1-8 */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 10, 64(11)\n\t" /* arg8->r10 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(144) \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
- arg7,arg8,arg9,arg10,arg11,arg12) \
- do { \
- volatile OrigFn _orig = (orig); \
- volatile unsigned long _argvec[3+12]; \
- volatile unsigned long _res; \
- /* _argvec[0] holds current r2 across the call */ \
- _argvec[1] = (unsigned long)_orig.r2; \
- _argvec[2] = (unsigned long)_orig.nraddr; \
- _argvec[2+1] = (unsigned long)arg1; \
- _argvec[2+2] = (unsigned long)arg2; \
- _argvec[2+3] = (unsigned long)arg3; \
- _argvec[2+4] = (unsigned long)arg4; \
- _argvec[2+5] = (unsigned long)arg5; \
- _argvec[2+6] = (unsigned long)arg6; \
- _argvec[2+7] = (unsigned long)arg7; \
- _argvec[2+8] = (unsigned long)arg8; \
- _argvec[2+9] = (unsigned long)arg9; \
- _argvec[2+10] = (unsigned long)arg10; \
- _argvec[2+11] = (unsigned long)arg11; \
- _argvec[2+12] = (unsigned long)arg12; \
- __asm__ volatile( \
- "mr 11,%1\n\t" \
- VG_EXPAND_FRAME_BY_trashes_r3(512) \
- "std 2,-16(11)\n\t" /* save tocptr */ \
- "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
- VG_EXPAND_FRAME_BY_trashes_r3(144) \
- /* arg12 */ \
- "ld 3,96(11)\n\t" \
- "std 3,136(1)\n\t" \
- /* arg11 */ \
- "ld 3,88(11)\n\t" \
- "std 3,128(1)\n\t" \
- /* arg10 */ \
- "ld 3,80(11)\n\t" \
- "std 3,120(1)\n\t" \
- /* arg9 */ \
- "ld 3,72(11)\n\t" \
- "std 3,112(1)\n\t" \
- /* args1-8 */ \
- "ld 3, 8(11)\n\t" /* arg1->r3 */ \
- "ld 4, 16(11)\n\t" /* arg2->r4 */ \
- "ld 5, 24(11)\n\t" /* arg3->r5 */ \
- "ld 6, 32(11)\n\t" /* arg4->r6 */ \
- "ld 7, 40(11)\n\t" /* arg5->r7 */ \
- "ld 8, 48(11)\n\t" /* arg6->r8 */ \
- "ld 9, 56(11)\n\t" /* arg7->r9 */ \
- "ld 10, 64(11)\n\t" /* arg8->r10 */ \
- "ld 11, 0(11)\n\t" /* target->r11 */ \
- VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
- "mr 11,%1\n\t" \
- "mr %0,3\n\t" \
- "ld 2,-16(11)\n\t" /* restore tocptr */ \
- VG_CONTRACT_FRAME_BY(144) \
- VG_CONTRACT_FRAME_BY(512) \
- : /*out*/ "=r" (_res) \
- : /*in*/ "r" (&_argvec[2]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
- ); \
- lval = (__typeof__(lval)) _res; \
- } while (0)
-
-#endif /* PLAT_ppc64_aix5 */
-
-
-/* ------------------------------------------------------------------ */
-/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */
-/* */
-/* ------------------------------------------------------------------ */
-
-/* Some request codes. There are many more of these, but most are not
- exposed to end-user view. These are the public ones, all of the
- form 0x1000 + small_number.
-
- Core ones are in the range 0x00000000--0x0000ffff. The non-public
- ones start at 0x2000.
-*/
-
-/* These macros are used by tools -- they must be public, but don't
- embed them into other programs. */
-#define VG_USERREQ_TOOL_BASE(a,b) \
- ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
-#define VG_IS_TOOL_USERREQ(a, b, v) \
- (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
-
-/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
- This enum comprises an ABI exported by Valgrind to programs
- which use client requests. DO NOT CHANGE THE ORDER OF THESE
- ENTRIES, NOR DELETE ANY -- add new ones at the end. */
-typedef
- enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001,
- VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
-
- /* These allow any function to be called from the simulated
- CPU but run on the real CPU. Nb: the first arg passed to
- the function is always the ThreadId of the running
- thread! So CLIENT_CALL0 actually requires a 1 arg
- function, etc. */
- VG_USERREQ__CLIENT_CALL0 = 0x1101,
- VG_USERREQ__CLIENT_CALL1 = 0x1102,
- VG_USERREQ__CLIENT_CALL2 = 0x1103,
- VG_USERREQ__CLIENT_CALL3 = 0x1104,
-
- /* Can be useful in regression testing suites -- eg. can
- send Valgrind's output to /dev/null and still count
- errors. */
- VG_USERREQ__COUNT_ERRORS = 0x1201,
-
- /* These are useful and can be interpreted by any tool that
- tracks malloc() et al, by using vg_replace_malloc.c. */
- VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
- VG_USERREQ__FREELIKE_BLOCK = 0x1302,
- /* Memory pool support. */
- VG_USERREQ__CREATE_MEMPOOL = 0x1303,
- VG_USERREQ__DESTROY_MEMPOOL = 0x1304,
- VG_USERREQ__MEMPOOL_ALLOC = 0x1305,
- VG_USERREQ__MEMPOOL_FREE = 0x1306,
- VG_USERREQ__MEMPOOL_TRIM = 0x1307,
- VG_USERREQ__MOVE_MEMPOOL = 0x1308,
- VG_USERREQ__MEMPOOL_CHANGE = 0x1309,
- VG_USERREQ__MEMPOOL_EXISTS = 0x130a,
-
- /* Allow printfs to valgrind log. */
- VG_USERREQ__PRINTF = 0x1401,
- VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
-
- /* Stack support. */
- VG_USERREQ__STACK_REGISTER = 0x1501,
- VG_USERREQ__STACK_DEREGISTER = 0x1502,
- VG_USERREQ__STACK_CHANGE = 0x1503
- } Vg_ClientRequest;
-
-#if !defined(__GNUC__)
-# define __extension__ /* */
-#endif
-
-/* Returns the number of Valgrinds this code is running under. That
- is, 0 if running natively, 1 if running under Valgrind, 2 if
- running under Valgrind which is running under another Valgrind,
- etc. */
-#define RUNNING_ON_VALGRIND __extension__ \
- ({unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */, \
- VG_USERREQ__RUNNING_ON_VALGRIND, \
- 0, 0, 0, 0, 0); \
- _qzz_res; \
- })
-
-
-/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
- _qzz_len - 1]. Useful if you are debugging a JITter or some such,
- since it provides a way to make sure valgrind will retranslate the
- invalidated area. Returns no value. */
-#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__DISCARD_TRANSLATIONS, \
- _qzz_addr, _qzz_len, 0, 0, 0); \
- }
-
-
-/* These requests are for getting Valgrind itself to print something.
- Possibly with a backtrace. This is a really ugly hack. */
-
-#if defined(NVALGRIND)
-
-# define VALGRIND_PRINTF(...)
-# define VALGRIND_PRINTF_BACKTRACE(...)
-
-#else /* NVALGRIND */
-
-/* Modern GCC will optimize the static routine out if unused,
- and unused attribute will shut down warnings about it. */
-static int VALGRIND_PRINTF(const char *format, ...)
- __attribute__((format(__printf__, 1, 2), __unused__));
-static int
-VALGRIND_PRINTF(const char *format, ...)
-{
- unsigned long _qzz_res;
- va_list vargs;
- va_start(vargs, format);
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
- (unsigned long)format, (unsigned long)vargs,
- 0, 0, 0);
- va_end(vargs);
- return (int)_qzz_res;
-}
-
-static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
- __attribute__((format(__printf__, 1, 2), __unused__));
-static int
-VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
-{
- unsigned long _qzz_res;
- va_list vargs;
- va_start(vargs, format);
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
- (unsigned long)format, (unsigned long)vargs,
- 0, 0, 0);
- va_end(vargs);
- return (int)_qzz_res;
-}
-
-#endif /* NVALGRIND */
-
-
-/* These requests allow control to move from the simulated CPU to the
- real CPU, calling an arbitrary function.
-
- Note that the current ThreadId is inserted as the first argument.
- So this call:
-
- VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
-
- requires f to have this signature:
-
- Word f(Word tid, Word arg1, Word arg2)
-
- where "Word" is a word-sized type.
-
- Note that these client requests are not entirely reliable. For example,
- if you call a function with them that subsequently calls printf(),
- there's a high chance Valgrind will crash. Generally, your prospects of
- these working are made higher if the called function does not refer to
- any global variables, and does not refer to any libc or other functions
- (printf et al). Any kind of entanglement with libc or dynamic linking is
- likely to have a bad outcome, for tricky reasons which we've grappled
- with a lot in the past.
-*/
-#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \
- __extension__ \
- ({unsigned long _qyy_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
- VG_USERREQ__CLIENT_CALL0, \
- _qyy_fn, \
- 0, 0, 0, 0); \
- _qyy_res; \
- })
-
-#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \
- __extension__ \
- ({unsigned long _qyy_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
- VG_USERREQ__CLIENT_CALL1, \
- _qyy_fn, \
- _qyy_arg1, 0, 0, 0); \
- _qyy_res; \
- })
-
-#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \
- __extension__ \
- ({unsigned long _qyy_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
- VG_USERREQ__CLIENT_CALL2, \
- _qyy_fn, \
- _qyy_arg1, _qyy_arg2, 0, 0); \
- _qyy_res; \
- })
-
-#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
- __extension__ \
- ({unsigned long _qyy_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
- VG_USERREQ__CLIENT_CALL3, \
- _qyy_fn, \
- _qyy_arg1, _qyy_arg2, \
- _qyy_arg3, 0); \
- _qyy_res; \
- })
-
-
-/* Counts the number of errors that have been recorded by a tool. Nb:
- the tool must record the errors with VG_(maybe_record_error)() or
- VG_(unique_error)() for them to be counted. */
-#define VALGRIND_COUNT_ERRORS \
- __extension__ \
- ({unsigned int _qyy_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
- VG_USERREQ__COUNT_ERRORS, \
- 0, 0, 0, 0, 0); \
- _qyy_res; \
- })
-
-/* Mark a block of memory as having been allocated by a malloc()-like
- function. `addr' is the start of the usable block (ie. after any
- redzone) `rzB' is redzone size if the allocator can apply redzones;
- use '0' if not. Adding redzones makes it more likely Valgrind will spot
- block overruns. `is_zeroed' indicates if the memory is zeroed, as it is
- for calloc(). Put it immediately after the point where a block is
- allocated.
-
- If you're using Memcheck: If you're allocating memory via superblocks,
- and then handing out small chunks of each superblock, if you don't have
- redzones on your small blocks, it's worth marking the superblock with
- VALGRIND_MAKE_MEM_NOACCESS when it's created, so that block overruns are
- detected. But if you can put redzones on, it's probably better to not do
- this, so that messages for small overruns are described in terms of the
- small block rather than the superblock (but if you have a big overrun
- that skips over a redzone, you could miss an error this way). See
- memcheck/tests/custom_alloc.c for an example.
-
- WARNING: if your allocator uses malloc() or 'new' to allocate
- superblocks, rather than mmap() or brk(), this will not work properly --
- you'll likely get assertion failures during leak detection. This is
- because Valgrind doesn't like seeing overlapping heap blocks. Sorry.
-
- Nb: block must be freed via a free()-like function specified
- with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */
-#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__MALLOCLIKE_BLOCK, \
- addr, sizeB, rzB, is_zeroed, 0); \
- }
-
-/* Mark a block of memory as having been freed by a free()-like function.
- `rzB' is redzone size; it must match that given to
- VALGRIND_MALLOCLIKE_BLOCK. Memory not freed will be detected by the leak
- checker. Put it immediately after the point where the block is freed. */
-#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__FREELIKE_BLOCK, \
- addr, rzB, 0, 0, 0); \
- }
-
-/* Create a memory pool. */
-#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__CREATE_MEMPOOL, \
- pool, rzB, is_zeroed, 0, 0); \
- }
-
-/* Destroy a memory pool. */
-#define VALGRIND_DESTROY_MEMPOOL(pool) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__DESTROY_MEMPOOL, \
- pool, 0, 0, 0, 0); \
- }
-
-/* Associate a piece of memory with a memory pool. */
-#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__MEMPOOL_ALLOC, \
- pool, addr, size, 0, 0); \
- }
-
-/* Disassociate a piece of memory from a memory pool. */
-#define VALGRIND_MEMPOOL_FREE(pool, addr) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__MEMPOOL_FREE, \
- pool, addr, 0, 0, 0); \
- }
-
-/* Disassociate any pieces outside a particular range. */
-#define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__MEMPOOL_TRIM, \
- pool, addr, size, 0, 0); \
- }
-
-/* Resize and/or move a piece associated with a memory pool. */
-#define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__MOVE_MEMPOOL, \
- poolA, poolB, 0, 0, 0); \
- }
-
-/* Resize and/or move a piece associated with a memory pool. */
-#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__MEMPOOL_CHANGE, \
- pool, addrA, addrB, size, 0); \
- }
-
-/* Return 1 if a mempool exists, else 0. */
-#define VALGRIND_MEMPOOL_EXISTS(pool) \
- ({unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__MEMPOOL_EXISTS, \
- pool, 0, 0, 0, 0); \
- _qzz_res; \
- })
-
-/* Mark a piece of memory as being a stack. Returns a stack id. */
-#define VALGRIND_STACK_REGISTER(start, end) \
- ({unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__STACK_REGISTER, \
- start, end, 0, 0, 0); \
- _qzz_res; \
- })
-
-/* Unmark the piece of memory associated with a stack id as being a
- stack. */
-#define VALGRIND_STACK_DEREGISTER(id) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__STACK_DEREGISTER, \
- id, 0, 0, 0, 0); \
- }
-
-/* Change the start and end address of the stack id. */
-#define VALGRIND_STACK_CHANGE(id, start, end) \
- {unsigned int _qzz_res; \
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
- VG_USERREQ__STACK_CHANGE, \
- id, start, end, 0, 0); \
- }
-
-
-#undef PLAT_x86_linux
-#undef PLAT_amd64_linux
-#undef PLAT_ppc32_linux
-#undef PLAT_ppc64_linux
-#undef PLAT_ppc32_aix5
-#undef PLAT_ppc64_aix5
-
-#endif /* __VALGRIND_H */
diff --git a/tests/auto/other/exceptionsafety_objects/exceptionsafety_objects.pro b/tests/auto/other/exceptionsafety_objects/exceptionsafety_objects.pro
deleted file mode 100644
index 665ca99e41..0000000000
--- a/tests/auto/other/exceptionsafety_objects/exceptionsafety_objects.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_exceptionsafety_objects
-QT += widgets testlib
-HEADERS += oomsimulator.h 3rdparty/valgrind.h 3rdparty/memcheck.h
-SOURCES += tst_exceptionsafety_objects.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/other/exceptionsafety_objects/oomsimulator.h b/tests/auto/other/exceptionsafety_objects/oomsimulator.h
deleted file mode 100644
index 23a7f3839a..0000000000
--- a/tests/auto/other/exceptionsafety_objects/oomsimulator.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <malloc.h>
-#include <limits.h>
-#include <stdio.h>
-#include <exception>
-
-#if !defined(Q_OS_WIN)
-# include "3rdparty/memcheck.h"
-#endif
-
-static bool mallocFailActive = false;
-static int mallocFailIndex = 0;
-static int mallocCount = 0;
-
-static void my_terminate_handler()
-{
- // set a breakpoint here to get a backtrace for your uncaught exceptions
- fprintf(stderr, "Uncaught Exception Detected. Set a breakpoint in my_terminate_handler()\n");
- exit(1);
-}
-
-#if defined(__GLIBC__) && !defined(__UCLIBC__)
-/* Use glibc's memory allocation hooks */
-
-// From glibc 2.14, the malloc hook variables are declared volatile.
-// Note: The malloc hook implementation is marked as deprecated.
-
-#if !defined(__MALLOC_HOOK_VOLATILE)
-# define __MALLOC_HOOK_VOLATILE
-#endif
-
-/* our hooks */
-static void *my_malloc_hook(size_t, const void *);
-static void *my_realloc_hook(void *, size_t, const void *);
-static void *my_memalign_hook(size_t, size_t, const void *);
-static void my_free_hook(void *, const void *);
-
-/* original hooks. */
-static void *(*__MALLOC_HOOK_VOLATILE old_malloc_hook)(size_t, const void *);
-static void *(*__MALLOC_HOOK_VOLATILE old_realloc_hook)(void *, size_t, const void *);
-static void *(*__MALLOC_HOOK_VOLATILE old_memalign_hook)(size_t, size_t, const void *);
-static void (*__MALLOC_HOOK_VOLATILE old_free_hook)(void *, const void *);
-
-/* initializer function */
-static void my_init_hook();
-
-/* Override initialising hook from the C library. */
-
-void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void) = my_init_hook;
-
-static void disableHooks()
-{
- __malloc_hook = old_malloc_hook;
- __realloc_hook = old_realloc_hook;
- __memalign_hook = old_memalign_hook;
- __free_hook = old_free_hook;
-}
-
-static void enableHooks()
-{
- __malloc_hook = my_malloc_hook;
- __realloc_hook = my_realloc_hook;
- __memalign_hook = my_memalign_hook;
- __free_hook = my_free_hook;
-}
-
-void my_init_hook()
-{
- old_malloc_hook = __malloc_hook;
- old_realloc_hook = __realloc_hook;
- old_memalign_hook = __memalign_hook;
- old_free_hook = __free_hook;
- enableHooks();
-}
-
-void *my_malloc_hook(size_t size, const void *)
-{
- ++mallocCount;
-
- if (mallocFailActive && --mallocFailIndex < 0)
- return 0; // simulate OOM
-
- __malloc_hook = old_malloc_hook;
- void *result = ::malloc (size);
- __malloc_hook = my_malloc_hook;
-
- return result;
-}
-
-void *my_memalign_hook(size_t alignment, size_t size, const void *)
-{
- ++mallocCount;
-
- if (mallocFailActive && --mallocFailIndex < 0)
- return 0; // simulate OOM
-
- __memalign_hook = old_memalign_hook;
- void *result = ::memalign(alignment, size);
- __memalign_hook = my_memalign_hook;
-
- return result;
-}
-
-void *my_realloc_hook(void *ptr, size_t size, const void *)
-{
- ++mallocCount;
-
- if (mallocFailActive && --mallocFailIndex < 0)
- return 0; // simulate OOM
-
- __realloc_hook = old_realloc_hook;
- __malloc_hook = old_malloc_hook;
- void *result = ::realloc(ptr, size);
- __malloc_hook = my_malloc_hook;
- __realloc_hook = my_realloc_hook;
-
- return result;
-}
-
-void my_free_hook(void *ptr, const void *)
-{
- __free_hook = old_free_hook;
- ::free(ptr);
- __free_hook = my_free_hook;
-}
-
-#elif defined(Q_CC_MSVC)
-
-#include "crtdbg.h"
-
-static int qCrtAllocHook(int allocType, void * /*userData*/, size_t /*size*/,
- int blockType, long /*requestNumber*/,
- const unsigned char * /*filename*/, int /*lineNumber*/)
-{
- if (blockType == _CRT_BLOCK)
- return true; // ignore allocations from the C library
-
- switch (allocType) {
- case _HOOK_ALLOC:
- case _HOOK_REALLOC:
- ++mallocCount;
- if (mallocFailActive && --mallocFailIndex < 0)
- return false; // simulate OOM
- }
-
- return true;
-}
-
-static struct QCrtDebugRegistrator
-{
- QCrtDebugRegistrator()
- {
- _CrtSetAllocHook(qCrtAllocHook);
- }
-
-} crtDebugRegistrator;
-
-#else
-
-static void disableHooks()
-{
-}
-
-#endif
-
-struct AllocFailer
-{
- inline AllocFailer(int index) { reactivateAt(index); }
- inline ~AllocFailer() { deactivate(); }
-
- inline void reactivateAt(int index)
- {
-#ifdef RUNNING_ON_VALGRIND
- if (RUNNING_ON_VALGRIND)
- VALGRIND_ENABLE_OOM_AT_ALLOC_INDEX(VALGRIND_GET_ALLOC_INDEX + index + 1);
-#endif
- mallocFailIndex = index;
- mallocFailActive = true;
- }
-
- inline void deactivate()
- {
- mallocFailActive = false;
-#ifdef RUNNING_ON_VALGRIND
- VALGRIND_ENABLE_OOM_AT_ALLOC_INDEX(0);
-#endif
- }
-
- inline int currentAllocIndex() const
- {
-#ifdef RUNNING_ON_VALGRIND
- if (RUNNING_ON_VALGRIND)
- return VALGRIND_GET_ALLOC_INDEX;
-#endif
- return mallocCount;
- }
-
- static bool initialize()
- {
- std::set_terminate(my_terminate_handler);
-#ifdef RUNNING_ON_VALGRIND
- if (RUNNING_ON_VALGRIND) {
- if (VALGRIND_GET_ALLOC_INDEX == -1u) {
- qWarning("You must use a valgrind with oom simulation support");
- return false;
- }
- // running in valgrind - don't use glibc hooks
- disableHooks();
-
- // never stop simulating OOM
- VALGRIND_DISABLE_OOM_AT_ALLOC_INDEX(-1u);
- }
-#endif
- return true;
- }
-};
-
-static void *new_helper(std::size_t size)
-{
- void *ptr = malloc(size);
-#ifndef QT_NO_EXCEPTIONS
- if (!ptr)
- throw std::bad_alloc();
-#endif
- return ptr;
-}
-
-#ifdef Q_CC_MSVC
-# pragma warning(push)
-# pragma warning(disable: 4290)
-#endif
-
-// overload operator new
-#ifndef QT_NO_EXCEPTIONS
-void* operator new(size_t size) throw (std::bad_alloc) { return new_helper(size); }
-void* operator new[](size_t size) throw (std::bad_alloc) { return new_helper(size); }
-#endif
-void* operator new(size_t size, const std::nothrow_t&) throw() { return malloc(size); }
-void* operator new[](std::size_t size, const std::nothrow_t&) throw() { return malloc(size); }
-
-// overload operator delete
-void operator delete(void *ptr) throw() { if (ptr) free(ptr); }
-void operator delete[](void *ptr) throw() { if (ptr) free(ptr); }
-void operator delete(void *ptr, const std::nothrow_t&) throw() { if (ptr) free(ptr); }
-void operator delete[](void *ptr, const std::nothrow_t&) throw() { if (ptr) free (ptr); }
-
-#ifdef Q_CC_MSVC
-# pragma warning(pop)
-#endif
-
-// ignore placement new and placement delete - those don't allocate.
-
-
diff --git a/tests/auto/other/exceptionsafety_objects/tst_exceptionsafety_objects.cpp b/tests/auto/other/exceptionsafety_objects/tst_exceptionsafety_objects.cpp
deleted file mode 100644
index da715516d7..0000000000
--- a/tests/auto/other/exceptionsafety_objects/tst_exceptionsafety_objects.cpp
+++ /dev/null
@@ -1,803 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/QtGui>
-#include <QtWidgets/QtWidgets>
-#include <QtTest/QtTest>
-
-#include <stddef.h>
-#include <exception>
-
-QT_USE_NAMESPACE
-
-// this test only works with GLIBC
-
-#include "oomsimulator.h"
-#include "3rdparty/memcheck.h"
-
-class tst_ExceptionSafety_Objects: public QObject
-{
- Q_OBJECT
-
-public slots:
- void initTestCase();
-#ifndef QT_NO_EXCEPTIONS
- void cleanupTestCase();
-
-private slots:
- void objects_data();
- void objects();
-
- void widgets_data();
- void widgets();
-
- void vector_data();
- void vector();
-
- void list_data();
- void list();
-
- void linkedList_data();
- void linkedList();
-
-private:
- static QtMessageHandler testMessageHandler;
- static void safeMessageHandler(QtMsgType, const QMessageLogContext&, const QString&);
-#endif
-};
-
-#ifdef QT_NO_EXCEPTIONS
-void tst_ExceptionSafety_Objects::initTestCase()
-{
- QSKIP("This test requires exception support");
-}
-
-#else
-// helper structs to create an arbitrary widget
-struct AbstractTester
-{
- virtual ~AbstractTester() {}
- virtual void operator()(QObject *parent) = 0;
-};
-Q_DECLARE_METATYPE(AbstractTester *)
-
-typedef void (*TestFunction)(QObject*);
-Q_DECLARE_METATYPE(TestFunction)
-
-template <typename T>
-struct ObjectCreator : public AbstractTester
-{
- void operator()(QObject *)
- {
- QScopedPointer<T> ptr(new T);
- }
-};
-
-struct BitArrayCreator : public AbstractTester
-{
- void operator()(QObject *)
- { QScopedPointer<QBitArray> bitArray(new QBitArray(100, true)); }
-};
-
-struct ByteArrayMatcherCreator : public AbstractTester
-{
- void operator()(QObject *)
- { QScopedPointer<QByteArrayMatcher> ptr(new QByteArrayMatcher("ralf test",8)); }
-};
-
-struct CryptographicHashCreator : public AbstractTester
-{
- void operator()(QObject *)
- {
- QScopedPointer<QCryptographicHash> ptr(new QCryptographicHash(QCryptographicHash::Sha1));
- ptr->addData("ralf test",8);
- }
-};
-
-struct DataStreamCreator : public AbstractTester
-{
- void operator()(QObject *)
- {
- QScopedPointer<QByteArray> arr(new QByteArray("hallo, test"));
- QScopedPointer<QDataStream> ptr(new QDataStream(arr.data(), QIODevice::ReadWrite));
- ptr->writeBytes("ralf test",8);
- }
-};
-
-struct DirCreator : public AbstractTester
-{
- void operator()(QObject *)
- {
- QDir::cleanPath("../////././");
- QScopedPointer<QDir> ptr(new QDir("."));
- while( ptr->cdUp() )
- ; // just going up
- ptr->count();
- ptr->exists(ptr->path());
-
- QStringList filters;
- filters << "*.cpp" << "*.cxx" << "*.cc";
- ptr->setNameFilters(filters);
- }
-};
-
-void tst_ExceptionSafety_Objects::objects_data()
-{
- QTest::addColumn<AbstractTester *>("objectCreator");
-
-#define NEWROW(T) QTest::newRow(#T) << static_cast<AbstractTester *>(new ObjectCreator<T >)
- NEWROW(QObject);
- NEWROW(QBuffer);
- NEWROW(QFile);
- NEWROW(QProcess);
- NEWROW(QSettings);
- NEWROW(QThread);
- NEWROW(QThreadPool);
- NEWROW(QTranslator);
-
-#define NEWROW2(T, CREATOR) QTest::newRow(#T) << static_cast<AbstractTester *>(new CREATOR)
- NEWROW2(QBitArray, BitArrayCreator);
- NEWROW2(QByteArrayMatcher, ByteArrayMatcherCreator);
- NEWROW2(QCryptographicHash, CryptographicHashCreator);
- NEWROW2(QDataStream, DataStreamCreator);
- NEWROW2(QDir, DirCreator);
-}
-
-// create and destructs an object, and lets each and every allocation
-// during construction and destruction fail.
-template <typename T>
-static void doOOMTest(T &testFunc, QObject *parent, int start=0)
-{
- int currentOOMIndex = start;
- bool caught = false;
- bool done = false;
-
- AllocFailer allocFailer(0);
- int allocCountBefore = allocFailer.currentAllocIndex();
-
- do {
- allocFailer.reactivateAt(++currentOOMIndex);
-
- caught = false;
-
- try {
- testFunc(parent);
- } catch (const std::bad_alloc &) {
- caught = true;
- } catch (const std::exception &ex) {
- if (strcmp(ex.what(), "autotest swallow") != 0)
- throw;
- caught = true;
- }
-
- if (!caught) {
- void *buf = malloc(42);
- if (buf) {
- // we got memory here - oom test is over.
- free(buf);
- done = true;
- }
- }
-
- // if we get a FAIL, stop executing now
- if (QTest::currentTestFailed())
- done = true;
-
-//#define REALLY_VERBOSE
-#ifdef REALLY_VERBOSE
- fprintf(stderr, " OOM Index: %d\n", currentOOMIndex);
-#endif
-
-
- } while (caught || !done);
-
- allocFailer.deactivate();
-
-//#define VERBOSE
-#ifdef VERBOSE
- fprintf(stderr, "OOM Test done, checked allocs: %d (range %d - %d)\n", currentOOMIndex,
- allocCountBefore, allocFailer.currentAllocIndex());
-#else
- Q_UNUSED(allocCountBefore);
-#endif
-}
-
-static int alloc1Failed = 0;
-static int alloc2Failed = 0;
-static int alloc3Failed = 0;
-static int alloc4Failed = 0;
-static int malloc1Failed = 0;
-static int malloc2Failed = 0;
-
-// Tests that new, new[] and malloc() fail at least once during OOM testing.
-class SelfTestObject : public QObject
-{
-public:
- SelfTestObject(QObject *parent = 0)
- : QObject(parent)
- {
- try { delete new int; } catch (const std::bad_alloc &) { ++alloc1Failed; throw; }
- try { delete [] new double[5]; } catch (const std::bad_alloc &) { ++alloc2Failed; throw ;}
- void *buf = malloc(42);
- if (buf)
- free(buf);
- else
- ++malloc1Failed;
- }
-
- ~SelfTestObject()
- {
- try { delete new int; } catch (const std::bad_alloc &) { ++alloc3Failed; }
- try { delete [] new double[5]; } catch (const std::bad_alloc &) { ++alloc4Failed; }
- void *buf = malloc(42);
- if (buf)
- free(buf);
- else
- ++malloc2Failed = true;
- }
-};
-
-QtMessageHandler tst_ExceptionSafety_Objects::testMessageHandler;
-
-void tst_ExceptionSafety_Objects::safeMessageHandler(QtMsgType type, const QMessageLogContext &ctxt,
- const QString &msg)
-{
- // this temporarily suspends OOM testing while handling a message
- int currentIndex = mallocFailIndex;
- AllocFailer allocFailer(0);
- allocFailer.deactivate();
- (*testMessageHandler)(type, ctxt, msg);
- allocFailer.reactivateAt(currentIndex);
-}
-
-typedef void (*PVF)();
-PVF defaultTerminate;
-void debugTerminate()
-{
- // you can detect uncaught exceptions with a breakpoint in here
- (*defaultTerminate)();
-}
-
-PVF defaultUnexpected;
-void debugUnexpected()
-{
- // you can detect unexpected exceptions with a breakpoint in here
- (*defaultUnexpected)();
-}
-
-void tst_ExceptionSafety_Objects::initTestCase()
-{
- // set handlers for bad exception cases, you might want to step in and breakpoint the default handlers too
- defaultTerminate = std::set_terminate(&debugTerminate);
- defaultUnexpected = std::set_unexpected(&debugUnexpected);
- testMessageHandler = qInstallMessageHandler(safeMessageHandler);
-
- QVERIFY(AllocFailer::initialize());
-
- // sanity check whether OOM simulation works
- AllocFailer allocFailer(0);
-
- // malloc fail index is 0 -> this malloc should fail.
- void *buf = malloc(42);
- allocFailer.deactivate();
- QVERIFY(!buf);
-
- // malloc fail index is 1 - second malloc should fail.
- allocFailer.reactivateAt(1);
- buf = malloc(42);
- void *buf2 = malloc(42);
- allocFailer.deactivate();
-
- QVERIFY(buf);
- free(buf);
- QVERIFY(!buf2);
-
- ObjectCreator<SelfTestObject> *selfTest = new ObjectCreator<SelfTestObject>;
- doOOMTest(*selfTest, 0);
- delete selfTest;
- QCOMPARE(alloc1Failed, 1);
- QCOMPARE(alloc2Failed, 1);
- QCOMPARE(alloc3Failed, 2);
- QCOMPARE(alloc4Failed, 3);
- QCOMPARE(malloc1Failed, 1);
- QCOMPARE(malloc2Failed, 1);
-}
-
-void tst_ExceptionSafety_Objects::cleanupTestCase()
-{
- qInstallMessageHandler(testMessageHandler);
-}
-
-void tst_ExceptionSafety_Objects::objects()
-{
- QLatin1String tag = QLatin1String(QTest::currentDataTag());
- if (tag == QLatin1String("QFile")
- || tag == QLatin1String("QProcess")
- || tag == QLatin1String("QSettings")
- || tag == QLatin1String("QThread")
- || tag == QLatin1String("QThreadPool"))
- QSKIP("This type of object is not currently strongly exception safe");
-
- QFETCH(AbstractTester *, objectCreator);
-
- doOOMTest(*objectCreator, 0);
-
- delete objectCreator;
-}
-
-template <typename T>
-struct WidgetCreator : public AbstractTester
-{
- void operator()(QObject *parent)
- {
- if (parent && !parent->isWidgetType())
- qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO);
- QScopedPointer<T> ptr(parent ? new T(static_cast<QWidget *>(parent)) : new T);
- }
-};
-
-// QSizeGrip doesn't have a default constructor - always pass parent (even though it might be 0)
-template <> struct WidgetCreator<QSizeGrip> : public AbstractTester
-{
- void operator()(QObject *parent)
- {
- if (parent && !parent->isWidgetType())
- qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO);
- QScopedPointer<QSizeGrip> ptr(new QSizeGrip(static_cast<QWidget *>(parent)));
- }
-};
-
-// QDesktopWidget doesn't need a parent.
-template <> struct WidgetCreator<QDesktopWidget> : public AbstractTester
-{
- void operator()(QObject *parent)
- {
- if (parent && !parent->isWidgetType())
- qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO);
- QScopedPointer<QDesktopWidget> ptr(new QDesktopWidget());
- }
-};
-void tst_ExceptionSafety_Objects::widgets_data()
-{
- QTest::addColumn<AbstractTester *>("widgetCreator");
-
-#undef NEWROW
-#define NEWROW(T) QTest::newRow(#T) << static_cast<AbstractTester *>(new WidgetCreator<T >)
-
- NEWROW(QWidget);
-
- NEWROW(QButtonGroup);
- NEWROW(QCheckBox);
- NEWROW(QColumnView);
- NEWROW(QComboBox);
- NEWROW(QCommandLinkButton);
- NEWROW(QDateEdit);
- NEWROW(QDateTimeEdit);
- NEWROW(QDesktopWidget);
- NEWROW(QDial);
- NEWROW(QDoubleSpinBox);
- NEWROW(QFocusFrame);
- NEWROW(QFontComboBox);
- NEWROW(QFrame);
- NEWROW(QGroupBox);
- NEWROW(QLabel);
- NEWROW(QLCDNumber);
- NEWROW(QLineEdit);
- NEWROW(QListView);
- NEWROW(QListWidget);
- NEWROW(QMainWindow);
- NEWROW(QMenu);
- NEWROW(QMenuBar);
- NEWROW(QPlainTextEdit);
- NEWROW(QProgressBar);
- NEWROW(QPushButton);
- NEWROW(QRadioButton);
- NEWROW(QScrollArea);
- NEWROW(QScrollBar);
- NEWROW(QSizeGrip);
- NEWROW(QSlider);
- NEWROW(QSpinBox);
- NEWROW(QSplitter);
- NEWROW(QStackedWidget);
- NEWROW(QStatusBar);
- NEWROW(QTabBar);
- NEWROW(QTableView);
- NEWROW(QTableWidget);
- NEWROW(QTabWidget);
- NEWROW(QTextBrowser);
- NEWROW(QTextEdit);
- NEWROW(QTimeEdit);
- NEWROW(QToolBar);
- NEWROW(QToolBox);
- NEWROW(QToolButton);
- NEWROW(QTreeView);
- NEWROW(QTreeWidget);
-}
-
-void tst_ExceptionSafety_Objects::widgets()
-{
- QLatin1String tag = QLatin1String(QTest::currentDataTag());
- if (tag == QLatin1String("QColumnView")
- || tag == QLatin1String("QComboBox")
- || tag == QLatin1String("QCommandLinkButton")
- || tag == QLatin1String("QDateEdit")
- || tag == QLatin1String("QDateTimeEdit")
- || tag == QLatin1String("QDesktopWidget")
- || tag == QLatin1String("QDoubleSpinBox")
- || tag == QLatin1String("QFontComboBox")
- || tag == QLatin1String("QGroupBox")
- || tag == QLatin1String("QLineEdit")
- || tag == QLatin1String("QListView")
- || tag == QLatin1String("QListWidget")
- || tag == QLatin1String("QMainWindow")
- || tag == QLatin1String("QMenu")
- || tag == QLatin1String("QMenuBar")
- || tag == QLatin1String("QPlainTextEdit")
- || tag == QLatin1String("QProgressBar")
- || tag == QLatin1String("QPushButton")
- || tag == QLatin1String("QScrollArea")
- || tag == QLatin1String("QSpinBox")
- || tag == QLatin1String("QStackedWidget")
- || tag == QLatin1String("QStatusBar")
- || tag == QLatin1String("QTableView")
- || tag == QLatin1String("QTableWidget")
- || tag == QLatin1String("QTabWidget")
- || tag == QLatin1String("QTextBrowser")
- || tag == QLatin1String("QTextEdit")
- || tag == QLatin1String("QTimeEdit")
- || tag == QLatin1String("QToolBar")
- || tag == QLatin1String("QToolBox")
- || tag == QLatin1String("QTreeView")
- || tag == QLatin1String("QTreeWidget"))
- QSKIP("This type of widget is not currently strongly exception safe");
-
- if (tag == QLatin1String("QWidget"))
- QSKIP("QTBUG-18927");
-
- QFETCH(AbstractTester *, widgetCreator);
-
- doOOMTest(*widgetCreator, 0, 00000);
-
- QWidget parent;
- doOOMTest(*widgetCreator, &parent, 00000);
-
- delete widgetCreator;
-
- // if the test reaches here without crashing, we passed :)
- QVERIFY(true);
-}
-
-struct Integer
-{
- Integer(int value = 42)
- : ptr(new int(value))
- {
- ++instanceCount;
- }
-
- Integer(const Integer &other)
- : ptr(new int(*other.ptr))
- {
- ++instanceCount;
- }
-
- Integer &operator=(const Integer &other)
- {
- int *newPtr = new int(*other.ptr);
- delete ptr;
- ptr = newPtr;
- return *this;
- }
-
- ~Integer()
- {
- --instanceCount;
- delete ptr;
- }
-
- int value() const
- {
- return *ptr;
- }
-
- int *ptr;
- static int instanceCount;
-};
-
-int Integer::instanceCount = 0;
-
-struct IntegerMoveable
- {
- IntegerMoveable(int value = 42)
- : val(value)
- {
- delete new int;
- ++instanceCount;
- }
-
- IntegerMoveable(const IntegerMoveable &other)
- : val(other.val)
- {
- delete new int;
- ++instanceCount;
- }
-
- IntegerMoveable &operator=(const IntegerMoveable &other)
- {
- delete new int;
- val = other.val;
- return *this;
- }
-
- ~IntegerMoveable()
- {
- --instanceCount;
- }
-
- int value() const
- {
- return val;
- }
-
- int val;
- static int instanceCount;
- };
-
-int IntegerMoveable::instanceCount = 0;
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(IntegerMoveable, Q_MOVABLE_TYPE);
-QT_END_NAMESPACE
-
-template <typename T, template<typename> class Container>
-void containerInsertTest(QObject*)
-{
- Container<T> container;
-
- // insert an item in an empty container
- try {
- container.insert(container.begin(), 41);
- } catch (...) {
- QVERIFY(container.isEmpty());
- QCOMPARE(T::instanceCount, 0);
- return;
- }
-
- QCOMPARE(container.size(), 1);
- QCOMPARE(T::instanceCount, 1);
-
- // insert an item before another item
- try {
- container.insert(container.begin(), 42);
- } catch (...) {
- QCOMPARE(container.size(), 1);
- QCOMPARE(container.first().value(), 41);
- QCOMPARE(T::instanceCount, 1);
- return;
- }
-
- QCOMPARE(T::instanceCount, 2);
-
- // insert an item in between
- try {
- container.insert(container.begin() + 1, 43);
- } catch (...) {
- QCOMPARE(container.size(), 2);
- QCOMPARE(container.first().value(), 41);
- QCOMPARE((container.begin() + 1)->value(), 42);
- QCOMPARE(T::instanceCount, 2);
- return;
- }
-
- QCOMPARE(T::instanceCount, 3);
-}
-
-template <typename T, template<typename> class Container>
-void containerAppendTest(QObject*)
-{
- Container<T> container;
-
- // append to an empty container
- try {
- container.append(42);
- } catch (...) {
- QCOMPARE(container.size(), 0);
- QCOMPARE(T::instanceCount, 0);
- return;
- }
-
- // append to a container with one item
- try {
- container.append(43);
- } catch (...) {
- QCOMPARE(container.size(), 1);
- QCOMPARE(container.first().value(), 42);
- QCOMPARE(T::instanceCount, 1);
- return;
- }
-
- Container<T> container2;
-
- try {
- container2.append(44);
- } catch (...) {
- // don't care
- return;
- }
- QCOMPARE(T::instanceCount, 3);
-
- // append another container with one item
- try {
- container += container2;
- } catch (...) {
- QCOMPARE(container.size(), 2);
- QCOMPARE(container.first().value(), 42);
- QCOMPARE((container.begin() + 1)->value(), 43);
- QCOMPARE(T::instanceCount, 3);
- return;
- }
-
- QCOMPARE(T::instanceCount, 4);
-}
-
-template <typename T, template<typename> class Container>
-void containerEraseTest(QObject*)
-{
- Container<T> container;
-
- try {
- container.append(42);
- container.append(43);
- container.append(44);
- container.append(45);
- container.append(46);
- } catch (...) {
- // don't care
- return;
- }
-
- // sanity checks
- QCOMPARE(container.size(), 5);
- QCOMPARE(T::instanceCount, 5);
-
- // delete the first one
- try {
- container.erase(container.begin());
- } catch (...) {
- QCOMPARE(container.size(), 5);
- QCOMPARE(container.first().value(), 42);
- QCOMPARE(T::instanceCount, 5);
- return;
- }
-
- QCOMPARE(container.size(), 4);
- QCOMPARE(container.first().value(), 43);
- QCOMPARE(T::instanceCount, 4);
-
- // delete the last one
- try {
- container.erase(container.end() - 1);
- } catch (...) {
- QCOMPARE(container.size(), 4);
- QCOMPARE(T::instanceCount, 4);
- return;
- }
-
- QCOMPARE(container.size(), 3);
- QCOMPARE(container.first().value(), 43);
- QCOMPARE((container.begin() + 1)->value(), 44);
- QCOMPARE((container.begin() + 2)->value(), 45);
- QCOMPARE(T::instanceCount, 3);
-
- // delete the middle one
- try {
- container.erase(container.begin() + 1);
- } catch (...) {
- QCOMPARE(container.size(), 3);
- QCOMPARE(container.first().value(), 43);
- QCOMPARE((container.begin() + 1)->value(), 44);
- QCOMPARE((container.begin() + 2)->value(), 45);
- QCOMPARE(T::instanceCount, 3);
- return;
- }
-
- QCOMPARE(container.size(), 2);
- QCOMPARE(container.first().value(), 43);
- QCOMPARE((container.begin() + 1)->value(), 45);
- QCOMPARE(T::instanceCount, 2);
-}
-
-template <template<typename T> class Container>
-static void containerData()
-{
- QTest::addColumn<TestFunction>("testFunction");
-
- QTest::newRow("insert static") << static_cast<TestFunction>(containerInsertTest<Integer, Container>);
- QTest::newRow("append static") << static_cast<TestFunction>(containerAppendTest<Integer, Container>);
- QTest::newRow("erase static") << static_cast<TestFunction>(containerEraseTest<Integer, Container>);
- QTest::newRow("insert moveable") << static_cast<TestFunction>(containerInsertTest<IntegerMoveable, Container>);
- QTest::newRow("append moveable") << static_cast<TestFunction>(containerAppendTest<IntegerMoveable, Container>);
- QTest::newRow("erase moveable") << static_cast<TestFunction>(containerEraseTest<IntegerMoveable, Container>);
-}
-
-void tst_ExceptionSafety_Objects::vector_data()
-{
- containerData<QVector>();
-}
-
-void tst_ExceptionSafety_Objects::vector()
-{
- QFETCH(TestFunction, testFunction);
-
- if (QLatin1String(QTest::currentDataTag()) == QLatin1String("insert static")
- || QLatin1String(QTest::currentDataTag()) == QLatin1String("insert moveable"))
- QSKIP("QVector::insert is currently not strongly exception safe");
-
- doOOMTest(testFunction, 0);
-}
-
-void tst_ExceptionSafety_Objects::list_data()
-{
- containerData<QList>();
-}
-
-void tst_ExceptionSafety_Objects::list()
-{
- QFETCH(TestFunction, testFunction);
-
- doOOMTest(testFunction, 0);
-}
-
-void tst_ExceptionSafety_Objects::linkedList_data()
-{
- containerData<QLinkedList>();
-}
-
-void tst_ExceptionSafety_Objects::linkedList()
-{
- QFETCH(TestFunction, testFunction);
-
- doOOMTest(testFunction, 0);
-}
-
-#endif
-
-QTEST_MAIN(tst_ExceptionSafety_Objects)
-#include "tst_exceptionsafety_objects.moc"
diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro
index 1d57206a73..63cbca539d 100644
--- a/tests/auto/other/other.pro
+++ b/tests/auto/other/other.pro
@@ -4,8 +4,6 @@ SUBDIRS=\
baselineexample \
collections \
compiler \
- exceptionsafety \
- # exceptionsafety_objects \ # QObjectPrivate is not safe
gestures \
headersclean \
lancelot \
@@ -70,4 +68,3 @@ wince*|!contains(QT_CONFIG, accessibility): SUBDIRS -= qaccessibility
!embedded|wince*: SUBDIRS -= \
qdirectpainter
-!linux*-g++*:SUBDIRS -= exceptionsafety_objects
diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml
index 54c5bb85f0..99e2e825c0 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.lightxml
+++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml
@@ -15,7 +15,7 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
<DataTag><![CDATA[int, string]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (actual): QVariant(int,123)
+ Actual (actual) : QVariant(int,123)
Expected (expected): QVariant(QString,hi)]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
@@ -24,19 +24,19 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
<DataTag><![CDATA[null hash, invalid]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (actual): QVariant(QVariantHash)
+ Actual (actual) : QVariant(QVariantHash)
Expected (expected): QVariant()]]></Description>
</Incident>
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
<DataTag><![CDATA[string, null user type]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (actual): QVariant(QString,A simple string)
+ Actual (actual) : QVariant(QString,A simple string)
Expected (expected): QVariant(PhonyClass)]]></Description>
</Incident>
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
<DataTag><![CDATA[both non-null user type]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (actual): QVariant(PhonyClass,<value not representable as string>)
+ Actual (actual) : QVariant(PhonyClass,<value not representable as string>)
Expected (expected): QVariant(PhonyClass,<value not representable as string>)]]></Description>
</Incident>
</TestFunction>
diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt
index 9d03a8e3da..504507f032 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.txt
+++ b/tests/auto/testlib/selftests/expected_cmptest.txt
@@ -4,20 +4,20 @@ PASS : tst_Cmptest::initTestCase()
PASS : tst_Cmptest::compare_boolfuncs()
PASS : tst_Cmptest::compare_pointerfuncs()
FAIL! : tst_Cmptest::compare_tostring(int, string) Compared values are not the same
- Actual (actual): QVariant(int,123)
+ Actual (actual) : QVariant(int,123)
Expected (expected): QVariant(QString,hi)
Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)]
PASS : tst_Cmptest::compare_tostring(both invalid)
FAIL! : tst_Cmptest::compare_tostring(null hash, invalid) Compared values are not the same
- Actual (actual): QVariant(QVariantHash)
+ Actual (actual) : QVariant(QVariantHash)
Expected (expected): QVariant()
Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)]
FAIL! : tst_Cmptest::compare_tostring(string, null user type) Compared values are not the same
- Actual (actual): QVariant(QString,A simple string)
+ Actual (actual) : QVariant(QString,A simple string)
Expected (expected): QVariant(PhonyClass)
Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)]
FAIL! : tst_Cmptest::compare_tostring(both non-null user type) Compared values are not the same
- Actual (actual): QVariant(PhonyClass,<value not representable as string>)
+ Actual (actual) : QVariant(PhonyClass,<value not representable as string>)
Expected (expected): QVariant(PhonyClass,<value not representable as string>)
Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)]
PASS : tst_Cmptest::compareQStringLists(empty lists)
diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml
index ccab93d7c0..df35058acc 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.xml
+++ b/tests/auto/testlib/selftests/expected_cmptest.xml
@@ -17,7 +17,7 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
<DataTag><![CDATA[int, string]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (actual): QVariant(int,123)
+ Actual (actual) : QVariant(int,123)
Expected (expected): QVariant(QString,hi)]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
@@ -26,19 +26,19 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
<DataTag><![CDATA[null hash, invalid]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (actual): QVariant(QVariantHash)
+ Actual (actual) : QVariant(QVariantHash)
Expected (expected): QVariant()]]></Description>
</Incident>
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
<DataTag><![CDATA[string, null user type]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (actual): QVariant(QString,A simple string)
+ Actual (actual) : QVariant(QString,A simple string)
Expected (expected): QVariant(PhonyClass)]]></Description>
</Incident>
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
<DataTag><![CDATA[both non-null user type]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (actual): QVariant(PhonyClass,<value not representable as string>)
+ Actual (actual) : QVariant(PhonyClass,<value not representable as string>)
Expected (expected): QVariant(PhonyClass,<value not representable as string>)]]></Description>
</Incident>
</TestFunction>
diff --git a/tests/auto/testlib/selftests/expected_cmptest.xunitxml b/tests/auto/testlib/selftests/expected_cmptest.xunitxml
index 0cb88147b0..e7d76ac839 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.xunitxml
+++ b/tests/auto/testlib/selftests/expected_cmptest.xunitxml
@@ -9,16 +9,16 @@
<testcase result="pass" name="compare_pointerfuncs"/>
<testcase result="fail" name="compare_tostring">
<failure tag="int, string" message="Compared values are not the same
- Actual (actual): QVariant(int,123)
+ Actual (actual) : QVariant(int,123)
Expected (expected): QVariant(QString,hi)" result="fail"/>
<failure tag="null hash, invalid" message="Compared values are not the same
- Actual (actual): QVariant(QVariantHash)
+ Actual (actual) : QVariant(QVariantHash)
Expected (expected): QVariant()" result="fail"/>
<failure tag="string, null user type" message="Compared values are not the same
- Actual (actual): QVariant(QString,A simple string)
+ Actual (actual) : QVariant(QString,A simple string)
Expected (expected): QVariant(PhonyClass)" result="fail"/>
<failure tag="both non&#x002D;null user type" message="Compared values are not the same
- Actual (actual): QVariant(PhonyClass,&lt;value not representable as string&gt;)
+ Actual (actual) : QVariant(PhonyClass,&lt;value not representable as string&gt;)
Expected (expected): QVariant(PhonyClass,&lt;value not representable as string&gt;)" result="fail"/>
</testcase>
<testcase result="fail" name="compareQStringLists">
diff --git a/tests/auto/testlib/selftests/expected_datetime.lightxml b/tests/auto/testlib/selftests/expected_datetime.lightxml
index d8acae9c26..183744b2e2 100644
--- a/tests/auto/testlib/selftests/expected_datetime.lightxml
+++ b/tests/auto/testlib/selftests/expected_datetime.lightxml
@@ -9,7 +9,7 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp" line="66">
<Description><![CDATA[Compared values are not the same
Actual (local): 2000/05/03 04:03:04.000[local time]
- Expected (utc): 2000/05/03 04:03:04.000[UTC]]]></Description>
+ Expected (utc) : 2000/05/03 04:03:04.000[UTC]]]></Description>
</Incident>
</TestFunction>
<TestFunction name="qurl">
diff --git a/tests/auto/testlib/selftests/expected_datetime.txt b/tests/auto/testlib/selftests/expected_datetime.txt
index ce9e1f36b4..0cbc6506d5 100644
--- a/tests/auto/testlib/selftests/expected_datetime.txt
+++ b/tests/auto/testlib/selftests/expected_datetime.txt
@@ -3,7 +3,7 @@ Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HER
PASS : tst_DateTime::initTestCase()
FAIL! : tst_DateTime::dateTime() Compared values are not the same
Actual (local): 2000/05/03 04:03:04.000[local time]
- Expected (utc): 2000/05/03 04:03:04.000[UTC]
+ Expected (utc) : 2000/05/03 04:03:04.000[UTC]
Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp(33)]
PASS : tst_DateTime::qurl(empty urls)
FAIL! : tst_DateTime::qurl(empty rhs) Compared values are not the same
diff --git a/tests/auto/testlib/selftests/expected_datetime.xml b/tests/auto/testlib/selftests/expected_datetime.xml
index d7c9afabee..42b566c074 100644
--- a/tests/auto/testlib/selftests/expected_datetime.xml
+++ b/tests/auto/testlib/selftests/expected_datetime.xml
@@ -11,7 +11,7 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp" line="66">
<Description><![CDATA[Compared values are not the same
Actual (local): 2000/05/03 04:03:04.000[local time]
- Expected (utc): 2000/05/03 04:03:04.000[UTC]]]></Description>
+ Expected (utc) : 2000/05/03 04:03:04.000[UTC]]]></Description>
</Incident>
</TestFunction>
<TestFunction name="qurl">
diff --git a/tests/auto/testlib/selftests/expected_datetime.xunitxml b/tests/auto/testlib/selftests/expected_datetime.xunitxml
index af0e4db7e8..00bd43f904 100644
--- a/tests/auto/testlib/selftests/expected_datetime.xunitxml
+++ b/tests/auto/testlib/selftests/expected_datetime.xunitxml
@@ -8,7 +8,7 @@
<testcase result="fail" name="dateTime">
<failure message="Compared values are not the same
Actual (local): 2000/05/03 04:03:04.000[local time]
- Expected (utc): 2000/05/03 04:03:04.000[UTC]" result="fail"/>
+ Expected (utc) : 2000/05/03 04:03:04.000[UTC]" result="fail"/>
</testcase>
<testcase result="fail" name="qurl">
<failure tag="empty rhs" message="Compared values are not the same
diff --git a/tests/auto/testlib/selftests/expected_float.txt b/tests/auto/testlib/selftests/expected_float.txt
index dc32fd76f1..da98f9c19d 100644
--- a/tests/auto/testlib/selftests/expected_float.txt
+++ b/tests/auto/testlib/selftests/expected_float.txt
@@ -3,15 +3,15 @@ Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HER
PASS : tst_float::initTestCase()
PASS : tst_float::floatComparisons(should SUCCEED 1)
FAIL! : tst_float::floatComparisons(should FAIL 1) Compared floats are not the same (fuzzy compare)
- Actual (operandLeft): 1
+ Actual (operandLeft) : 1
Expected (operandRight): 3
Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)]
FAIL! : tst_float::floatComparisons(should FAIL 2) Compared floats are not the same (fuzzy compare)
- Actual (operandLeft): 1e-07
+ Actual (operandLeft) : 1e-07
Expected (operandRight): 3e-07
Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)]
FAIL! : tst_float::floatComparisons(should FAIL 3) Compared floats are not the same (fuzzy compare)
- Actual (operandLeft): 99998
+ Actual (operandLeft) : 99998
Expected (operandRight): 99999
Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)]
PASS : tst_float::floatComparisons(should SUCCEED 2)
diff --git a/tests/auto/testlib/selftests/expected_strcmp.lightxml b/tests/auto/testlib/selftests/expected_strcmp.lightxml
index d5135fd7df..4c30c9f801 100644
--- a/tests/auto/testlib/selftests/expected_strcmp.lightxml
+++ b/tests/auto/testlib/selftests/expected_strcmp.lightxml
@@ -35,13 +35,13 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="121">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("foo")): 66 6F 6F
- Expected (QByteArray()): ]]></Description>
+ Expected (QByteArray()) : ]]></Description>
</Incident>
</TestFunction>
<TestFunction name="failByteArrayEmpty">
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="126">
<Description><![CDATA[Compared values are not the same
- Actual (QByteArray("")):
+ Actual (QByteArray("")) :
Expected (QByteArray("foo")): 66 6F 6F]]></Description>
</Incident>
</TestFunction>
diff --git a/tests/auto/testlib/selftests/expected_strcmp.txt b/tests/auto/testlib/selftests/expected_strcmp.txt
index 797aefa82f..f3ad169fb7 100644
--- a/tests/auto/testlib/selftests/expected_strcmp.txt
+++ b/tests/auto/testlib/selftests/expected_strcmp.txt
@@ -18,10 +18,10 @@ FAIL! : tst_StrCmp::failByteArray() Compared values are not the same
Loc: [./tst_strcmp.cpp(82)]
FAIL! : tst_StrCmp::failByteArrayNull() Compared values are not the same
Actual (QByteArray("foo")): 66 6F 6F
- Expected (QByteArray()):
+ Expected (QByteArray()) :
Loc: [./tst_strcmp.cpp(88)]
FAIL! : tst_StrCmp::failByteArrayEmpty() Compared values are not the same
- Actual (QByteArray("")):
+ Actual (QByteArray("")) :
Expected (QByteArray("foo")): 66 6F 6F
Loc: [./tst_strcmp.cpp(93)]
FAIL! : tst_StrCmp::failByteArraySingleChars() Compared values are not the same
diff --git a/tests/auto/testlib/selftests/expected_strcmp.xml b/tests/auto/testlib/selftests/expected_strcmp.xml
index 0c5a73918d..db9ed34bb8 100644
--- a/tests/auto/testlib/selftests/expected_strcmp.xml
+++ b/tests/auto/testlib/selftests/expected_strcmp.xml
@@ -37,13 +37,13 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="121">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("foo")): 66 6F 6F
- Expected (QByteArray()): ]]></Description>
+ Expected (QByteArray()) : ]]></Description>
</Incident>
</TestFunction>
<TestFunction name="failByteArrayEmpty">
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="126">
<Description><![CDATA[Compared values are not the same
- Actual (QByteArray("")):
+ Actual (QByteArray("")) :
Expected (QByteArray("foo")): 66 6F 6F]]></Description>
</Incident>
</TestFunction>
diff --git a/tests/auto/testlib/selftests/expected_strcmp.xunitxml b/tests/auto/testlib/selftests/expected_strcmp.xunitxml
index a900e2f17a..dde9ff5299 100644
--- a/tests/auto/testlib/selftests/expected_strcmp.xunitxml
+++ b/tests/auto/testlib/selftests/expected_strcmp.xunitxml
@@ -22,11 +22,11 @@
<testcase result="fail" name="failByteArrayNull">
<failure message="Compared values are not the same
Actual (QByteArray(&quot;foo&quot;)): 66 6F 6F
- Expected (QByteArray()): " result="fail"/>
+ Expected (QByteArray()) : " result="fail"/>
</testcase>
<testcase result="fail" name="failByteArrayEmpty">
<failure message="Compared values are not the same
- Actual (QByteArray(&quot;&quot;)):
+ Actual (QByteArray(&quot;&quot;)) :
Expected (QByteArray(&quot;foo&quot;)): 66 6F 6F" result="fail"/>
</testcase>
<testcase result="fail" name="failByteArraySingleChars">
diff --git a/tests/auto/testlib/selftests/expected_subtest.lightxml b/tests/auto/testlib/selftests/expected_subtest.lightxml
index b156dc3991..5adbb771af 100644
--- a/tests/auto/testlib/selftests/expected_subtest.lightxml
+++ b/tests/auto/testlib/selftests/expected_subtest.lightxml
@@ -122,7 +122,7 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154">
<DataTag><![CDATA[data1]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (str): hello1
+ Actual (str) : hello1
Expected (QString("hello0")): hello0]]></Description>
</Incident>
<Message type="qdebug" file="" line="0">
@@ -140,7 +140,7 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154">
<DataTag><![CDATA[data2]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (str): hello2
+ Actual (str) : hello2
Expected (QString("hello0")): hello0]]></Description>
</Incident>
<Message type="qdebug" file="" line="0">
diff --git a/tests/auto/testlib/selftests/expected_subtest.txt b/tests/auto/testlib/selftests/expected_subtest.txt
index 4537f983e5..bb88f189ec 100644
--- a/tests/auto/testlib/selftests/expected_subtest.txt
+++ b/tests/auto/testlib/selftests/expected_subtest.txt
@@ -33,14 +33,14 @@ PASS : tst_Subtest::test3(data0)
QDEBUG : tst_Subtest::test3(data1) init test3 data1
QDEBUG : tst_Subtest::test3(data1) test2 test3 data1
FAIL! : tst_Subtest::test3(data1) Compared values are not the same
- Actual (str): hello1
+ Actual (str) : hello1
Expected (QString("hello0")): hello0
Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp(154)]
QDEBUG : tst_Subtest::test3(data1) cleanup test3 data1
QDEBUG : tst_Subtest::test3(data2) init test3 data2
QDEBUG : tst_Subtest::test3(data2) test2 test3 data2
FAIL! : tst_Subtest::test3(data2) Compared values are not the same
- Actual (str): hello2
+ Actual (str) : hello2
Expected (QString("hello0")): hello0
Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp(154)]
QDEBUG : tst_Subtest::test3(data2) cleanup test3 data2
diff --git a/tests/auto/testlib/selftests/expected_subtest.xml b/tests/auto/testlib/selftests/expected_subtest.xml
index 365df51e23..094e22383d 100644
--- a/tests/auto/testlib/selftests/expected_subtest.xml
+++ b/tests/auto/testlib/selftests/expected_subtest.xml
@@ -124,7 +124,7 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154">
<DataTag><![CDATA[data1]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (str): hello1
+ Actual (str) : hello1
Expected (QString("hello0")): hello0]]></Description>
</Incident>
<Message type="qdebug" file="" line="0">
@@ -142,7 +142,7 @@
<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154">
<DataTag><![CDATA[data2]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (str): hello2
+ Actual (str) : hello2
Expected (QString("hello0")): hello0]]></Description>
</Incident>
<Message type="qdebug" file="" line="0">
diff --git a/tests/auto/testlib/selftests/expected_subtest.xunitxml b/tests/auto/testlib/selftests/expected_subtest.xunitxml
index 6097000e7f..6f8fc3db45 100644
--- a/tests/auto/testlib/selftests/expected_subtest.xunitxml
+++ b/tests/auto/testlib/selftests/expected_subtest.xunitxml
@@ -38,13 +38,13 @@
<!-- tag="data1" message="init test3 data1 " type="qdebug" -->
<!-- tag="data1" message="test2 test3 data1 " type="qdebug" -->
<failure tag="data1" message="Compared values are not the same
- Actual (str): hello1
+ Actual (str) : hello1
Expected (QString(&quot;hello0&quot;)): hello0" result="fail"/>
<!-- tag="data1" message="cleanup test3 data1 " type="qdebug" -->
<!-- tag="data2" message="init test3 data2 " type="qdebug" -->
<!-- tag="data2" message="test2 test3 data2 " type="qdebug" -->
<failure tag="data2" message="Compared values are not the same
- Actual (str): hello2
+ Actual (str) : hello2
Expected (QString(&quot;hello0&quot;)): hello0" result="fail"/>
<!-- tag="data2" message="cleanup test3 data2 " type="qdebug" -->
</testcase>
diff --git a/mkspecs/macx-clang-libc++/qplatformdefs.h b/tests/auto/tools/moc/interface-from-include.h
index 2c3a8b1c09..ef8d53684b 100644
--- a/mkspecs/macx-clang-libc++/qplatformdefs.h
+++ b/tests/auto/tools/moc/interface-from-include.h
@@ -3,7 +3,7 @@
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the qmake spec of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -38,6 +38,18 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#ifndef INTERFACE_FROM_INCLUDE_H
+#define INTERFACE_FROM_INCLUDE_H
-#include "../common/mac/qplatformdefs.h"
+#include <testinterface.h>
+class TestComponent : public QObject, public TestInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(TestInterface)
+public:
+
+ virtual void foobar() { }
+};
+
+#endif
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index 3459bede85..e7303d716e 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -523,6 +523,7 @@ private slots:
void structQObject();
void namespacedFlags();
void warnOnMultipleInheritance();
+ void ignoreOptionClashes();
void forgottenQInterface();
void os9Newline();
void winNewline();
@@ -969,6 +970,46 @@ void tst_Moc::warnOnMultipleInheritance()
#endif
}
+void tst_Moc::ignoreOptionClashes()
+{
+#ifdef MOC_CROSS_COMPILED
+ QSKIP("Not tested when cross-compiled");
+#endif
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
+ QProcess proc;
+ QStringList args;
+ const QString header = m_sourceDirectory + QStringLiteral("/interface-from-include.h");
+ const QString includeDir = m_sourceDirectory + "/Test.framework/Headers";
+ // given --ignore-option-clashes, -pthread should be ignored, but the -I path should not be.
+ args << "--ignore-option-clashes" << "-pthread" << "-I" << includeDir << "-fno-builtin" << header;
+ proc.start("moc", args);
+ bool finished = proc.waitForFinished();
+ if (!finished)
+ qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error());
+ QVERIFY(finished);
+ if (proc.exitCode() != 0) {
+ qDebug() << proc.readAllStandardError();
+ }
+ QCOMPARE(proc.exitCode(), 0);
+ QCOMPARE(proc.readAllStandardError(), QByteArray());
+ QByteArray mocOut = proc.readAllStandardOutput();
+
+ // If -pthread wasn't ignored, it was parsed as a prefix of "thread/", which breaks compilation.
+ QStringList gccArgs;
+ gccArgs << "-c" << "-x" << "c++" << "-I" << ".."
+ << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null" << "-fPIE" << "-";
+ proc.start("gcc", gccArgs);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+ proc.closeWriteChannel();
+
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString());
+#else
+ QSKIP("Only tested on linux/gcc");
+#endif
+}
+
void tst_Moc::forgottenQInterface()
{
#ifdef MOC_CROSS_COMPILED
diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
index 65d36247f6..81b69f6b89 100644
--- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
+++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
@@ -612,6 +612,8 @@ void tst_QFiledialog::defaultSuffix()
QCOMPARE(fd.defaultSuffix(), QString());
fd.setDefaultSuffix("txt");
QCOMPARE(fd.defaultSuffix(), QString("txt"));
+ fd.setDefaultSuffix(".txt");
+ QCOMPARE(fd.defaultSuffix(), QString("txt"));
fd.setDefaultSuffix(QString());
QCOMPARE(fd.defaultSuffix(), QString());
}
@@ -1334,6 +1336,38 @@ QString saveName(QWidget *, const QString &, const QString &, const QString &, Q
return "saveName";
}
+QT_BEGIN_NAMESPACE
+typedef QUrl (*_qt_filedialog_existing_directory_url_hook)(QWidget *parent, const QString &caption, const QUrl &dir, QFileDialog::Options options, const QStringList &supportedSchemes);
+extern Q_WIDGETS_EXPORT _qt_filedialog_existing_directory_url_hook qt_filedialog_existing_directory_url_hook;
+QT_END_NAMESPACE
+QUrl existingUrl(QWidget *, const QString &, const QUrl &, QFileDialog::Options, const QStringList &) {
+ return QUrl("http://dirUrl");
+}
+
+QT_BEGIN_NAMESPACE
+typedef QUrl (*_qt_filedialog_open_file_url_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
+extern Q_WIDGETS_EXPORT _qt_filedialog_open_file_url_hook qt_filedialog_open_file_url_hook;
+QT_END_NAMESPACE
+QUrl openUrl(QWidget *, const QString &, const QUrl &, const QString &, QString *, QFileDialog::Options, const QStringList &) {
+ return QUrl("http://openUrl");
+}
+
+QT_BEGIN_NAMESPACE
+typedef QList<QUrl> (*_qt_filedialog_open_file_urls_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
+extern Q_WIDGETS_EXPORT _qt_filedialog_open_file_urls_hook qt_filedialog_open_file_urls_hook;
+QT_END_NAMESPACE
+QList<QUrl> openUrls(QWidget *, const QString &, const QUrl &, const QString &, QString *, QFileDialog::Options, const QStringList &) {
+ return QList<QUrl>() << QUrl("http://openUrls");
+}
+
+QT_BEGIN_NAMESPACE
+typedef QUrl (*_qt_filedialog_save_file_url_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
+extern Q_WIDGETS_EXPORT _qt_filedialog_save_file_url_hook qt_filedialog_save_file_url_hook;
+QT_END_NAMESPACE
+QUrl saveUrl(QWidget *, const QString &, const QUrl &, const QString &, QString *, QFileDialog::Options, const QStringList &) {
+ return QUrl("http://saveUrl");
+}
+
void tst_QFiledialog::hooks()
{
@@ -1346,6 +1380,20 @@ void tst_QFiledialog::hooks()
QCOMPARE(QFileDialog::getOpenFileName(), QString("openName"));
QCOMPARE(QFileDialog::getOpenFileNames(), QStringList("openNames"));
QCOMPARE(QFileDialog::getSaveFileName(), QString("saveName"));
+ QCOMPARE(QFileDialog::getExistingDirectoryUrl(), QUrl::fromLocalFile("dir"));
+ QCOMPARE(QFileDialog::getOpenFileUrl(), QUrl::fromLocalFile("openName"));
+ QCOMPARE(QFileDialog::getOpenFileUrls(), QList<QUrl>() << QUrl::fromLocalFile("openNames"));
+ QCOMPARE(QFileDialog::getSaveFileUrl(), QUrl::fromLocalFile("saveName"));
+
+ qt_filedialog_existing_directory_url_hook = &existingUrl;
+ qt_filedialog_save_file_url_hook = &saveUrl;
+ qt_filedialog_open_file_url_hook = &openUrl;
+ qt_filedialog_open_file_urls_hook = &openUrls;
+
+ QCOMPARE(QFileDialog::getExistingDirectoryUrl(), QUrl("http://dirUrl"));
+ QCOMPARE(QFileDialog::getOpenFileUrl(), QUrl("http://openUrl"));
+ QCOMPARE(QFileDialog::getOpenFileUrls(), QList<QUrl>() << QUrl("http://openUrls"));
+ QCOMPARE(QFileDialog::getSaveFileUrl(), QUrl("http://saveUrl"));
}
#ifdef Q_OS_UNIX
diff --git a/tests/auto/widgets/graphicsview/graphicsview.pro b/tests/auto/widgets/graphicsview/graphicsview.pro
index 9955e45b64..dce3c6dda9 100644
--- a/tests/auto/widgets/graphicsview/graphicsview.pro
+++ b/tests/auto/widgets/graphicsview/graphicsview.pro
@@ -26,7 +26,7 @@ SUBDIRS=\
qgraphicsscene \
qgraphicssceneindex \
-# These tests require the cleanlooks style
-!contains(styles, cleanlooks):SUBDIRS -= \
+# These tests require the fusion style
+!contains(styles, fusion):SUBDIRS -= \
qgraphicsproxywidget \
qgraphicswidget \
diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro
index 3eb18e61eb..8e8c0708a3 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro
+++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro
@@ -3,4 +3,3 @@ TARGET = tst_qgraphicsanchorlayout
QT += widgets widgets-private testlib
QT += core-private gui-private
SOURCES += tst_qgraphicsanchorlayout.cpp
-CONFIG += parallel_test
diff --git a/tests/auto/widgets/graphicsview/qgraphicseffectsource/qgraphicseffectsource.pro b/tests/auto/widgets/graphicsview/qgraphicseffectsource/qgraphicseffectsource.pro
index 4fe3405d11..550d3debf7 100644
--- a/tests/auto/widgets/graphicsview/qgraphicseffectsource/qgraphicseffectsource.pro
+++ b/tests/auto/widgets/graphicsview/qgraphicseffectsource/qgraphicseffectsource.pro
@@ -5,4 +5,3 @@ QT += widgets widgets-private testlib
QT += core-private gui-private
SOURCES += tst_qgraphicseffectsource.cpp
-CONFIG += parallel_test
diff --git a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/qgraphicsgridlayout.pro b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/qgraphicsgridlayout.pro
index 5796cbfd73..e49139a8ad 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/qgraphicsgridlayout.pro
+++ b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/qgraphicsgridlayout.pro
@@ -3,4 +3,3 @@ TARGET = tst_qgraphicsgridlayout
QT += widgets testlib
SOURCES += tst_qgraphicsgridlayout.cpp
-CONFIG += parallel_test
diff --git a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
index 8c8f27d635..1ffb5c3b5c 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
@@ -126,6 +126,7 @@ private slots:
void spanningItem2x3_data();
void spanningItem2x3();
void spanningItem();
+ void spanAcrossEmptyRow();
void heightForWidth();
void widthForHeight();
void heightForWidthWithSpanning();
@@ -3192,23 +3193,19 @@ void tst_QGraphicsGridLayout::heightForWidthWithSpanning()
QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1)), QSizeF(1, 1));
QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)), QSizeF(200, 100));
- QEXPECT_FAIL("", "Due to an old bug this wrongly returns QWIDGETSIZE_MAX", Continue);
QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(-1, -1)), QSizeF(30000, 30000));
QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(200, -1)), QSizeF(200, 100));
QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(200, -1)), QSizeF(200, 100));
- QEXPECT_FAIL("", "Due to an old bug this wrongly returns QWIDGETSIZE_MAX", Continue);
QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(200, -1)), QSizeF(200, 100));
QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(2, -1)), QSizeF(2, 10000));
QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(2, -1)), QSizeF(2, 10000));
- QEXPECT_FAIL("", "Due to an old bug this wrongly returns QWIDGETSIZE_MAX", Continue);
QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(2, -1)), QSizeF(2, 10000));
QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(200, -1)), QSizeF(200, 100));
QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(200, -1)), QSizeF(200, 100));
- QEXPECT_FAIL("", "Due to an old bug this wrongly returns QWIDGETSIZE_MAX", Continue);
- QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(200, -1)), QSizeF(200, 10000));
+ QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(200, -1)), QSizeF(200, 100));
}
Q_DECLARE_METATYPE(QSizePolicy::Policy)
@@ -3364,6 +3361,37 @@ void tst_QGraphicsGridLayout::spanningItem()
QCOMPARE(layout->maximumSize(), QSizeF(160,80));
}
+void tst_QGraphicsGridLayout::spanAcrossEmptyRow()
+{
+ QGraphicsWidget *form = new QGraphicsWidget(0, Qt::Window);
+ QGraphicsGridLayout *layout = new QGraphicsGridLayout(form);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ RectWidget *w1 = new RectWidget;
+ RectWidget *w2 = new RectWidget;
+ RectWidget *w3 = new RectWidget;
+
+ QSizeF size(10, 10);
+ for (int i = 0; i < 3; ++i) {
+ w1->setSizeHint((Qt::SizeHint)i, size);
+ w2->setSizeHint((Qt::SizeHint)i, size);
+ w3->setSizeHint((Qt::SizeHint)i, size);
+ size+=size; //[(10,10), (20,20), (40,40)]
+ }
+ layout->addItem(w1, 0, 0, 1, 1);
+ layout->addItem(w2, 0, 1, 1, 2);
+ layout->addItem(w3, 0, 99, 1, 1);
+
+ form->resize(60,20);
+ QCOMPARE(w1->geometry(), QRectF( 0, 0, 20, 20));
+ QCOMPARE(w2->geometry(), QRectF(20, 0, 20, 20));
+ QCOMPARE(w3->geometry(), QRectF(40, 0, 20, 20));
+
+ QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize), QSizeF(30, 10));
+ QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize), QSizeF(60, 20));
+ QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize), QSizeF(120, 40));
+}
+
void tst_QGraphicsGridLayout::stretchAndHeightForWidth()
{
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
diff --git a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro
index 50a886cece..2bf1a1d676 100644
--- a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro
+++ b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro
@@ -2,5 +2,3 @@ CONFIG += testcase
TARGET = tst_qgraphicslinearlayout
QT += widgets testlib
SOURCES += tst_qgraphicslinearlayout.cpp
-CONFIG += parallel_test
-
diff --git a/tests/auto/widgets/graphicsview/qgraphicssceneindex/qgraphicssceneindex.pro b/tests/auto/widgets/graphicsview/qgraphicssceneindex/qgraphicssceneindex.pro
index 5fd3bdf8d6..3d0d73566e 100644
--- a/tests/auto/widgets/graphicsview/qgraphicssceneindex/qgraphicssceneindex.pro
+++ b/tests/auto/widgets/graphicsview/qgraphicssceneindex/qgraphicssceneindex.pro
@@ -4,5 +4,4 @@ requires(contains(QT_CONFIG,private_tests))
QT += widgets widgets-private testlib
QT += core-private gui-private
SOURCES += tst_qgraphicssceneindex.cpp
-CONFIG += parallel_test
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro b/tests/auto/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro
index 4e119cbcb3..481bc96d96 100644
--- a/tests/auto/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro
+++ b/tests/auto/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro
@@ -6,5 +6,4 @@ QT += core-private gui-private
SOURCES += tst_qgraphicswidget.cpp
-linux-*:system(". /etc/lsb-release && [ $DISTRIB_CODENAME = lucid ]"):DEFINES+=UBUNTU_LUCID # QTBUG-20778
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp
index 31439e203c..2dd2089f81 100644
--- a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp
@@ -3194,9 +3194,6 @@ void tst_QGraphicsWidget::initialShow2()
qApp->setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
-#ifdef UBUNTU_LUCID
- QEXPECT_FAIL("", "QTBUG-20778", Abort);
-#endif
QTRY_COMPARE(widget->repaints, expectedRepaintCount);
}
diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
index 8e888f06ee..dfb780c8fa 100644
--- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
@@ -106,6 +106,8 @@ private slots:
void moveCursorStrikesBack_data();
void moveCursorStrikesBack();
+ void moveCursorBiggerJump();
+
void hideRows_data();
void hideRows();
@@ -1354,6 +1356,34 @@ void tst_QTableView::moveCursorStrikesBack()
QCOMPARE(newColumn, expectedColumn);
}
+void tst_QTableView::moveCursorBiggerJump()
+{
+ QtTestTableModel model(50, 7);
+ QTableView view;
+ view.setModel(&model);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ int height = view.horizontalHeader()->height();
+ for (int i=0;i<8;i++)
+ height += view.verticalHeader()->sectionSize(i);
+ view.resize(view.width(), height);
+ view.setCurrentIndex(model.index(0,0));
+
+ QTest::keyClick(&view, Qt::Key_PageDown);
+ QCOMPARE(view.indexAt(QPoint(0,0)), model.index(1,0));
+ QTest::keyClick(&view, Qt::Key_PageDown);
+ QCOMPARE(view.indexAt(QPoint(0,0)), model.index(8,0));
+ QTest::keyClick(&view, Qt::Key_PageDown);
+ QCOMPARE(view.indexAt(QPoint(0,0)), model.index(15,0));
+ QTest::keyClick(&view, Qt::Key_PageUp);
+ QCOMPARE(view.indexAt(QPoint(0,0)), model.index(14,0));
+ QTest::keyClick(&view, Qt::Key_PageUp);
+ QCOMPARE(view.indexAt(QPoint(0,0)), model.index(7,0));
+ QTest::keyClick(&view, Qt::Key_PageUp);
+ QCOMPARE(view.indexAt(QPoint(0,0)), model.index(0,0));
+}
+
void tst_QTableView::hideRows_data()
{
QTest::addColumn<int>("rowCount");
@@ -3762,8 +3792,6 @@ void tst_QTableView::task259308_scrollVerticalHeaderSwappedSections()
QTRY_COMPARE(tv.rowAt(0), tv.verticalHeader()->logicalIndex(0));
int newRow = tv.rowAt(tv.viewport()->height());
- if (newRow == tv.rowAt(tv.viewport()->height() - 1)) // Overlapping row
- newRow++;
QTest::keyClick(&tv, Qt::Key_PageDown); // Scroll down and check current
QTRY_COMPARE(tv.currentIndex().row(), newRow);
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index 9a7b7956d8..dcda9f7fd7 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -2017,6 +2017,8 @@ void tst_QTreeView::clicked()
view.setModel(&model);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
QModelIndex firstIndex = model.index(0, 0, QModelIndex());
QVERIFY(firstIndex.isValid());
int itemHeight = view.visualRect(firstIndex).height();
diff --git a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp
index 2b9b4fd761..ab2df2e250 100644
--- a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp
+++ b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp
@@ -84,6 +84,7 @@ private slots:
void controlTypes();
void controlTypes2();
void adjustSizeShouldMakeSureLayoutIsActivated();
+ void testRetainSizeWhenHidden();
};
tst_QLayout::tst_QLayout()
@@ -350,5 +351,47 @@ void tst_QLayout::adjustSizeShouldMakeSureLayoutIsActivated()
QCOMPARE(main.size(), QSize(200, 10));
}
+void tst_QLayout::testRetainSizeWhenHidden()
+{
+ QWidget widget;
+ QBoxLayout layout(QBoxLayout::TopToBottom, &widget);
+
+ QLabel *label1 = new QLabel("label1 text", &widget);
+ layout.addWidget(label1);
+ QLabel *label2 = new QLabel("label2 text", &widget);
+ layout.addWidget(label2);
+
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+ int normalHeight = widget.height();
+
+ // a. Verify that a removed visible will mean lesser size after adjust
+ label1->hide();
+ widget.adjustSize();
+ int heightWithoutLabel1 = widget.height();
+ QVERIFY(heightWithoutLabel1 < normalHeight);
+
+ // b restore with verify that the size is the same
+ label1->show();
+ QCOMPARE(widget.sizeHint().height(), normalHeight);
+
+ // c verify that a policy with retainSizeWhenHidden is respected
+ QSizePolicy sp_remove = label1->sizePolicy();
+ QSizePolicy sp_retain = label1->sizePolicy();
+ sp_retain.setRetainSizeWhenHidden(true);
+
+ label1->setSizePolicy(sp_retain);
+ label1->hide();
+ QCOMPARE(widget.sizeHint().height(), normalHeight);
+
+ // d check that changing the policy to not wanting size will result in lesser size
+ label1->setSizePolicy(sp_remove);
+ QCOMPARE(widget.sizeHint().height(), heightWithoutLabel1);
+
+ // e verify that changing back the hidden widget to want the hidden size will ensure that it gets more size
+ label1->setSizePolicy(sp_retain);
+ QCOMPARE(widget.sizeHint().height(), normalHeight);
+}
+
QTEST_MAIN(tst_QLayout)
#include "tst_qlayout.moc"
diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
index 82d3fae0fa..4631154230 100644
--- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
@@ -160,6 +160,7 @@ private slots:
void maxVisibleItems();
void task_QTBUG_10491_currentIndexAndModelColumn();
void highlightedSignal();
+ void itemData();
void task_QTBUG_31146_popupCompletion();
};
@@ -2756,6 +2757,151 @@ void tst_QComboBox::highlightedSignal()
QCOMPARE(spy.size(), 1);
}
+void tst_QComboBox::itemData()
+{
+ QComboBox comboBox;
+ const int itemCount = 10;
+
+ // ensure that the currentText(), the DisplayRole and the EditRole
+ // stay in sync when using QComboBox's default model
+ for (int i = 0; i < itemCount; ++i) {
+ QString itemText = QString("item text %1").arg(i);
+ comboBox.addItem(itemText);
+ }
+
+ for (int i = 0; i < itemCount; ++i) {
+ QString itemText = QString("item text %1").arg(i);
+ QCOMPARE(comboBox.itemText(i), itemText);
+ QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText);
+
+ comboBox.setCurrentIndex(i);
+ QCOMPARE(comboBox.currentIndex(), i);
+ QCOMPARE(comboBox.currentText(), itemText);
+ QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText);
+ }
+
+ for (int i = 0; i < itemCount; ++i) {
+ // now change by using setItemText
+ QString itemText = QString("setItemText %1").arg(i);
+ comboBox.setItemText(i, itemText);
+ }
+
+ for (int i = 0; i < itemCount; ++i) {
+ QString itemText = QString("setItemText %1").arg(i);
+ QCOMPARE(comboBox.itemText(i), itemText);
+ QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText);
+
+ comboBox.setCurrentIndex(i);
+ QCOMPARE(comboBox.currentIndex(), i);
+ QCOMPARE(comboBox.currentText(), itemText);
+ QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText);
+ }
+
+ for (int i = 0; i < itemCount; ++i) {
+ // now change by changing the DisplayRole's data
+ QString itemText = QString("setItemData(DisplayRole) %1").arg(i);
+ comboBox.setItemData(i, QVariant(itemText), Qt::DisplayRole);
+ }
+
+ for (int i = 0; i < itemCount; ++i) {
+ QString itemText = QString("setItemData(DisplayRole) %1").arg(i);
+ QCOMPARE(comboBox.itemText(i), itemText);
+ QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText);
+
+ comboBox.setCurrentIndex(i);
+ QCOMPARE(comboBox.currentIndex(), i);
+ QCOMPARE(comboBox.currentText(), itemText);
+ QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText);
+ }
+
+ for (int i = 0; i < itemCount; ++i) {
+ // now change by changing the EditRole's data
+ QString itemText = QString("setItemData(EditRole) %1").arg(i);
+ comboBox.setItemData(i, QVariant(itemText), Qt::EditRole);
+ }
+
+ for (int i = 0; i < itemCount; ++i) {
+ QString itemText = QString("setItemData(EditRole) %1").arg(i);
+ QCOMPARE(comboBox.itemText(i), itemText);
+ QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText);
+
+ comboBox.setCurrentIndex(i);
+ QCOMPARE(comboBox.currentIndex(), i);
+ QCOMPARE(comboBox.currentText(), itemText);
+ QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText);
+ }
+
+ comboBox.clear();
+
+
+ // set additional user data in the addItem call
+ for (int i = 0; i < itemCount; ++i) {
+ QString itemText = QString("item text %1").arg(i);
+ QString itemDataText = QString("item data %1").arg(i);
+ comboBox.addItem(itemText, QVariant(itemDataText));
+ }
+
+ for (int i = 0; i < itemCount; ++i) {
+ QString itemText = QString("item text %1").arg(i);
+ QString itemDataText = QString("item data %1").arg(i);
+ QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText);
+ QCOMPARE(comboBox.itemData(i).toString(), itemDataText);
+
+ comboBox.setCurrentIndex(i);
+ QCOMPARE(comboBox.currentIndex(), i);
+ QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText);
+ QCOMPARE(comboBox.currentData().toString(), itemDataText);
+
+ }
+
+ comboBox.clear();
+
+
+ // additional roles, setItemData
+ // UserRole + 0 -> string
+ // UserRole + 1 -> double
+ // UserRole + 2 -> icon
+ QString qtlogoPath = QFINDTESTDATA("qtlogo.png");
+ QIcon icon = QIcon(QPixmap(qtlogoPath));
+ for (int i = 0; i < itemCount; ++i) {
+ QString itemText = QString("item text %1").arg(i);
+ QString itemDataText = QString("item data %1").arg(i);
+ double d = i;
+ comboBox.addItem(itemText);
+ comboBox.setItemData(i, QVariant(itemDataText), Qt::UserRole);
+ comboBox.setItemData(i, QVariant(d), Qt::UserRole + 1);
+ comboBox.setItemData(i, QVariant::fromValue(icon), Qt::UserRole + 2);
+ }
+
+ for (int i = 0; i < itemCount; ++i) {
+ QString itemText = QString("item text %1").arg(i);
+ QString itemDataText = QString("item data %1").arg(i);
+ double d = i;
+ QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText);
+ QCOMPARE(comboBox.itemData(i, Qt::UserRole).toString(), itemDataText);
+ QCOMPARE(comboBox.itemData(i, Qt::UserRole + 1).toDouble(), d);
+ QCOMPARE(comboBox.itemData(i, Qt::UserRole + 2).value<QIcon>(), icon);
+
+ comboBox.setCurrentIndex(i);
+ QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText);
+ QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText);
+ QCOMPARE(comboBox.currentData(Qt::UserRole).toString(), itemDataText);
+ QCOMPARE(comboBox.currentData(Qt::UserRole + 1).toDouble(), d);
+ QCOMPARE(comboBox.currentData(Qt::UserRole + 2).value<QIcon>(), icon);
+ }
+}
+
void tst_QComboBox::task_QTBUG_31146_popupCompletion()
{
QComboBox comboBox;
diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp
index b0e454b643..db5b89f396 100644
--- a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp
+++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp
@@ -72,6 +72,8 @@ private slots:
void testConstructor2_data();
void testConstructor3();
void testConstructor3_data();
+ void testConstructor4();
+ void testConstructor4_data();
void setOrientation_data();
void setOrientation();
void addButton1_data();
@@ -201,6 +203,41 @@ void tst_QDialogButtonBox::testConstructor3()
QTEST(buttonBox.buttons().count(), "buttonCount");
}
+void tst_QDialogButtonBox::testConstructor4_data()
+{
+ QTest::addColumn<QDialogButtonBox::StandardButtons>("buttons");
+ QTest::addColumn<int>("buttonCount");
+
+ QTest::newRow("nothing") << (QDialogButtonBox::StandardButtons)0 << 0;
+ QTest::newRow("only 1") << QDialogButtonBox::StandardButtons(QDialogButtonBox::Ok) << 1;
+ QTest::newRow("only 1.. twice")
+ << (QDialogButtonBox::Ok | QDialogButtonBox::Ok)
+ << 1;
+ QTest::newRow("only 2")
+ << (QDialogButtonBox::Ok | QDialogButtonBox::Cancel)
+ << 2;
+ QTest::newRow("two different things")
+ << (QDialogButtonBox::Save | QDialogButtonBox::Close)
+ << 2;
+ QTest::newRow("three")
+ << (QDialogButtonBox::Ok
+ | QDialogButtonBox::Cancel
+ | QDialogButtonBox::Help)
+ << 3;
+ QTest::newRow("everything")
+ << (QDialogButtonBox::StandardButtons)UINT_MAX
+ << 18;
+}
+
+void tst_QDialogButtonBox::testConstructor4()
+{
+ QFETCH(QDialogButtonBox::StandardButtons, buttons);
+
+ QDialogButtonBox buttonBox(buttons);
+ QCOMPARE(buttonBox.orientation(), Qt::Horizontal);
+ QTEST(buttonBox.buttons().count(), "buttonCount");
+}
+
void tst_QDialogButtonBox::setOrientation_data()
{
QTest::addColumn<int>("orientation");
diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
index d428e2705d..3000aad9ce 100644
--- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
@@ -46,6 +46,9 @@
#include "qstringlist.h"
#include "qstyle.h"
#include "qvalidator.h"
+#include "qwidgetaction.h"
+#include "qimage.h"
+#include "qicon.h"
#include "qcompleter.h"
#include "qstandarditemmodel.h"
#include <qpa/qplatformtheme.h>
@@ -61,8 +64,12 @@
#include <private/qlineedit_p.h>
#include <private/qwidgetlinecontrol_p.h>
#include <qmenu.h>
+#include <qlabel.h>
#include <qlayout.h>
#include <qspinbox.h>
+#include <qlistview.h>
+#include <qstringlistmodel.h>
+#include <qsortfilterproxymodel.h>
#include <qdebug.h>
#include "qcommonstyle.h"
@@ -290,6 +297,9 @@ private slots:
void undoRedoAndEchoModes_data();
void undoRedoAndEchoModes();
+ void clearButton();
+ void sideWidgets();
+
protected slots:
void editingFinished();
@@ -866,12 +876,18 @@ public:
void tst_QLineEdit::hasAcceptableInputValidator()
{
+ QSignalSpy spyChanged(testWidget, SIGNAL(textChanged(QString)));
+ QSignalSpy spyEdited(testWidget, SIGNAL(textEdited(QString)));
+
QFocusEvent lostFocus(QEvent::FocusOut);
ValidatorWithFixup val;
testWidget->setValidator(&val);
testWidget->setText("foobar");
qApp->sendEvent(testWidget, &lostFocus);
QVERIFY(testWidget->hasAcceptableInput());
+
+ QCOMPARE(spyChanged.count(), 2);
+ QCOMPARE(spyEdited.count(), 0);
}
@@ -4042,5 +4058,80 @@ void tst_QLineEdit::undoRedoAndEchoModes()
QCOMPARE(testWidget->text(), expected.at(2));
}
+void tst_QLineEdit::clearButton()
+{
+ // Construct a listview with a stringlist model and filter model.
+ QWidget testWidget;
+ QVBoxLayout *l = new QVBoxLayout(&testWidget);
+ QLineEdit *filterLineEdit = new QLineEdit(&testWidget);
+ l->addWidget(filterLineEdit);
+ QListView *listView = new QListView(&testWidget);
+ QStringListModel *model = new QStringListModel(QStringList() << QStringLiteral("aa") << QStringLiteral("ab") << QStringLiteral("cc"), listView);
+ QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(listView);
+ filterModel->setSourceModel(model);
+ connect(filterLineEdit, SIGNAL(textChanged(QString)), filterModel, SLOT(setFilterFixedString(QString)));
+ listView->setModel(filterModel);
+ l->addWidget(listView);
+ testWidget.move(300, 300);
+ testWidget.show();
+ qApp->setActiveWindow(&testWidget);
+ QVERIFY(QTest::qWaitForWindowActive(&testWidget));
+ // Flip the clear button on,off, trying to detect crashes.
+ filterLineEdit->setClearButtonEnabled(true);
+ QVERIFY(filterLineEdit->isClearButtonEnabled());
+ filterLineEdit->setClearButtonEnabled(true);
+ QVERIFY(filterLineEdit->isClearButtonEnabled());
+ filterLineEdit->setClearButtonEnabled(false);
+ QVERIFY(!filterLineEdit->isClearButtonEnabled());
+ filterLineEdit->setClearButtonEnabled(false);
+ QVERIFY(!filterLineEdit->isClearButtonEnabled());
+ filterLineEdit->setClearButtonEnabled(true);
+ QVERIFY(filterLineEdit->isClearButtonEnabled());
+ // Emulate filtering
+ QToolButton *clearButton = filterLineEdit->findChild<QToolButton *>();
+ QVERIFY(clearButton);
+ QCOMPARE(filterModel->rowCount(), 3);
+ QTest::keyClick(filterLineEdit, 'a');
+ QTRY_COMPARE(filterModel->rowCount(), 2); // matches 'aa', 'ab'
+ QTest::keyClick(filterLineEdit, 'b');
+ QTRY_COMPARE(filterModel->rowCount(), 1); // matches 'ab'
+ QTest::mouseClick(clearButton, Qt::LeftButton, 0, QRect(QPoint(0, 0), clearButton->size()).center());
+ QTRY_COMPARE(filterModel->rowCount(), 3);
+}
+
+void tst_QLineEdit::sideWidgets()
+{
+ QWidget testWidget;
+ QVBoxLayout *l = new QVBoxLayout(&testWidget);
+ QLineEdit *lineEdit = new QLineEdit(&testWidget);
+ l->addWidget(lineEdit);
+ l->addSpacerItem(new QSpacerItem(0, 50, QSizePolicy::Ignored, QSizePolicy::Fixed));
+ QImage image(QSize(20, 20), QImage::Format_ARGB32);
+ image.fill(Qt::yellow);
+ QAction *iconAction = new QAction(QIcon(QPixmap::fromImage(image)), QString(), lineEdit);
+ QWidgetAction *label1Action = new QWidgetAction(lineEdit);
+ label1Action->setDefaultWidget(new QLabel(QStringLiteral("l1")));
+ QWidgetAction *label2Action = new QWidgetAction(lineEdit);
+ label2Action->setDefaultWidget(new QLabel(QStringLiteral("l2")));
+ QWidgetAction *label3Action = new QWidgetAction(lineEdit);
+ label3Action->setDefaultWidget(new QLabel(QStringLiteral("l3")));
+ lineEdit->addAction(iconAction, QLineEdit::LeadingPosition);
+ lineEdit->addAction(label2Action, QLineEdit::LeadingPosition);
+ lineEdit->addAction(label1Action, QLineEdit::TrailingPosition);
+ lineEdit->addAction(label3Action, QLineEdit::TrailingPosition);
+ testWidget.move(300, 300);
+ testWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&testWidget));
+ // Arbitrarily add/remove actions, trying to detect crashes. Add QTRY_VERIFY(false) to view the result.
+ delete label3Action;
+ lineEdit->removeAction(label2Action);
+ lineEdit->removeAction(iconAction);
+ lineEdit->removeAction(label1Action);
+ lineEdit->removeAction(iconAction);
+ lineEdit->removeAction(label1Action);
+ lineEdit->addAction(iconAction);
+ lineEdit->addAction(iconAction);
+}
+
QTEST_MAIN(tst_QLineEdit)
#include "tst_qlineedit.moc"
diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
index a64b34c56a..004fdda5ef 100644
--- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
+++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
@@ -98,6 +98,9 @@ private slots:
void setValue_data();
void setValue();
+ void setDisplayIntegerBase_data();
+ void setDisplayIntegerBase();
+
void setPrefixSuffix_data();
void setPrefixSuffix();
@@ -274,6 +277,61 @@ void tst_QSpinBox::setValue()
QCOMPARE(spin.value(), expected);
}
+void tst_QSpinBox::setDisplayIntegerBase_data()
+{
+ QTest::addColumn<int>("value");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<QString>("string");
+
+ QTest::newRow("base 10") << 42 << 10 << "42";
+ QTest::newRow("base 2") << 42 << 2 << "101010";
+ QTest::newRow("base 8") << 42 << 8 << "52";
+ QTest::newRow("base 16") << 42 << 16 << "2a";
+ QTest::newRow("base 0") << 42 << 0 << "42";
+ QTest::newRow("base -4") << 42 << -4 << "42";
+ QTest::newRow("base 40") << 42 << 40 << "42";
+
+ QTest::newRow("negative base 10") << -42 << 10 << "-42";
+ QTest::newRow("negative base 2") << -42 << 2 << "-101010";
+ QTest::newRow("negative base 8") << -42 << 8 << "-52";
+ QTest::newRow("negative base 16") << -42 << 16 << "-2a";
+ QTest::newRow("negative base 0") << -42 << 0 << "-42";
+ QTest::newRow("negative base -4") << -42 << -4 << "-42";
+ QTest::newRow("negative base 40") << -42 << 40 << "-42";
+
+ QTest::newRow("0 base 10") << 0 << 10 << "0";
+ QTest::newRow("0 base 2") << 0 << 2 << "0";
+ QTest::newRow("0 base 8") << 0 << 8 << "0";
+ QTest::newRow("0 base 16") << 0 << 16 << "0";
+ QTest::newRow("0 base 0") << 0 << 0 << "0";
+ QTest::newRow("0 base -4") << 0 << -4 << "0";
+ QTest::newRow("0 base 40") << 0 << 40 << "0";
+}
+
+void tst_QSpinBox::setDisplayIntegerBase()
+{
+ QFETCH(int, value);
+ QFETCH(int, base);
+ QFETCH(QString, string);
+
+ SpinBox spin;
+ spin.setRange(INT_MIN, INT_MAX);
+
+ spin.setValue(value);
+ QCOMPARE(spin.lineEdit()->text(), QString::number(value));
+
+ spin.setDisplayIntegerBase(base);
+ QCOMPARE(spin.lineEdit()->text(), string);
+
+ spin.setValue(0);
+ QCOMPARE(spin.value(), 0);
+ QCOMPARE(spin.lineEdit()->text(), QString::number(0, base));
+
+ spin.lineEdit()->clear();
+ QTest::keyClicks(spin.lineEdit(), string);
+ QCOMPARE(spin.value(), value);
+}
+
void tst_QSpinBox::setPrefixSuffix_data()
{
QTest::addColumn<QString>("prefix");
diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
index a188e3bfe1..0dac7d85e4 100644
--- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
+++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
@@ -97,6 +97,8 @@ private slots:
void changeTitleWhileDoubleClickingTab();
void taskQTBUG_10052_widgetLayoutWhenMoving();
+
+ void tabBarClicked();
};
// Testing get/set functions
@@ -652,5 +654,45 @@ void tst_QTabBar::taskQTBUG_10052_widgetLayoutWhenMoving()
QVERIFY(w2.moved);
}
+void tst_QTabBar::tabBarClicked()
+{
+ QTabBar tabBar;
+ tabBar.addTab("0");
+ QSignalSpy clickSpy(&tabBar, SIGNAL(tabBarClicked(int)));
+ QSignalSpy doubleClickSpy(&tabBar, SIGNAL(tabBarDoubleClicked(int)));
+
+ QCOMPARE(clickSpy.count(), 0);
+ QCOMPARE(doubleClickSpy.count(), 0);
+
+ Qt::MouseButton button = Qt::LeftButton;
+ while (button <= Qt::MaxMouseButton) {
+ const QPoint tabPos = tabBar.tabRect(0).center();
+
+ QTest::mouseClick(&tabBar, button, 0, tabPos);
+ QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0);
+ QCOMPARE(doubleClickSpy.count(), 0);
+
+ QTest::mouseDClick(&tabBar, button, 0, tabPos);
+ QCOMPARE(clickSpy.count(), 0);
+ QCOMPARE(doubleClickSpy.count(), 1);
+ QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), 0);
+
+ const QPoint barPos(tabBar.tabRect(0).right() + 5, tabBar.tabRect(0).center().y());
+
+ QTest::mouseClick(&tabBar, button, 0, barPos);
+ QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1);
+ QCOMPARE(doubleClickSpy.count(), 0);
+
+ QTest::mouseDClick(&tabBar, button, 0, barPos);
+ QCOMPARE(clickSpy.count(), 0);
+ QCOMPARE(doubleClickSpy.count(), 1);
+ QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), -1);
+
+ button = Qt::MouseButton(button << 1);
+ }
+}
+
QTEST_MAIN(tst_QTabBar)
#include "tst_qtabbar.moc"
diff --git a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp
index 5dd9ee9b0f..fa518e6afd 100644
--- a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp
+++ b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp
@@ -42,6 +42,7 @@
#include <QtTest/QtTest>
#include <qtabwidget.h>
+#include <qtabbar.h>
#include <qdebug.h>
#include <qapplication.h>
#include <qlabel.h>
@@ -110,6 +111,7 @@ class tst_QTabWidget:public QObject {
void minimumSizeHint();
void heightForWidth_data();
void heightForWidth();
+ void tabBarClicked();
private:
int addPage();
@@ -666,6 +668,46 @@ void tst_QTabWidget::heightForWidth()
delete window;
}
+void tst_QTabWidget::tabBarClicked()
+{
+ QTabWidget tabWidget;
+ tabWidget.addTab(new QWidget(&tabWidget), "0");
+ QSignalSpy clickSpy(&tabWidget, SIGNAL(tabBarClicked(int)));
+ QSignalSpy doubleClickSpy(&tabWidget, SIGNAL(tabBarDoubleClicked(int)));
+
+ QCOMPARE(clickSpy.count(), 0);
+ QCOMPARE(doubleClickSpy.count(), 0);
+
+ QTabBar &tabBar = *tabWidget.tabBar();
+ Qt::MouseButton button = Qt::LeftButton;
+ while (button <= Qt::MaxMouseButton) {
+ const QPoint tabPos = tabBar.tabRect(0).center();
+
+ QTest::mouseClick(&tabBar, button, 0, tabPos);
+ QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0);
+ QCOMPARE(doubleClickSpy.count(), 0);
+
+ QTest::mouseDClick(&tabBar, button, 0, tabPos);
+ QCOMPARE(clickSpy.count(), 0);
+ QCOMPARE(doubleClickSpy.count(), 1);
+ QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), 0);
+
+ const QPoint barPos(tabBar.tabRect(0).right() + 5, tabBar.tabRect(0).center().y());
+
+ QTest::mouseClick(&tabBar, button, 0, barPos);
+ QCOMPARE(clickSpy.count(), 1);
+ QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1);
+ QCOMPARE(doubleClickSpy.count(), 0);
+
+ QTest::mouseDClick(&tabBar, button, 0, barPos);
+ QCOMPARE(clickSpy.count(), 0);
+ QCOMPARE(doubleClickSpy.count(), 1);
+ QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), -1);
+
+ button = Qt::MouseButton(button << 1);
+ }
+}
QTEST_MAIN(tst_QTabWidget)
#include "tst_qtabwidget.moc"
diff --git a/tests/benchmarks/corelib/io/qfile/main.cpp b/tests/benchmarks/corelib/io/qfile/main.cpp
index ef5fd36254..0beffebfb7 100644
--- a/tests/benchmarks/corelib/io/qfile/main.cpp
+++ b/tests/benchmarks/corelib/io/qfile/main.cpp
@@ -54,6 +54,10 @@
# include <windows.h>
#endif
+#if defined(Q_OS_QNX) && defined(open)
+#undef open
+#endif
+
#define BUFSIZE 1024*512
#define FACTOR 1024*512
#define TF_SIZE FACTOR*81
diff --git a/tests/benchmarks/corelib/tools/qset/main.cpp b/tests/benchmarks/corelib/tools/qset/main.cpp
new file mode 100644
index 0000000000..744cc745d3
--- /dev/null
+++ b/tests/benchmarks/corelib/tools/qset/main.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QSet>
+#include <QTest>
+
+class tst_QSet : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void intersect_int_data();
+ void intersect_int();
+ void intersect_complexType_data();
+ void intersect_complexType();
+};
+
+void tst_QSet::intersect_int_data()
+{
+ QTest::addColumn<int>("lhsSize");
+ QTest::addColumn<int>("rhsSize");
+ QTest::addColumn<int>("intersectSize");
+
+ QTest::newRow("1000000.intersect(1000) = empty") << 1000000 << 1000 << 0;
+ QTest::newRow("1000.intersect(1000000) = empty") << 1000 << 1000000 << 0;
+ QTest::newRow("1000000.intersect(1000) = 500") << 1000000 << 1000 << 500;
+ QTest::newRow("1000.intersect(1000000) = 500") << 1000 << 1000000 << 500;
+ QTest::newRow("1000000.intersect(1000) = 1000") << 1000000 << 1000 << 1000;
+ QTest::newRow("1000.intersect(1000000) = 1000") << 1000 << 1000000 << 1000;
+}
+
+void tst_QSet::intersect_int()
+{
+ QFETCH(int, lhsSize);
+ QFETCH(int, rhsSize);
+ QFETCH(int, intersectSize);
+
+ // E.g. when lhsSize = 1000, rhsSize = 1000000 and intersectSize = 500:
+ // lhsSize = { 0, 1, ... 1000 }
+ // rhsSize = { 500, 501, ... 1000500 }
+
+ QSet<int> lhs;
+ for (int i = 0; i < lhsSize; ++i)
+ lhs.insert(i);
+
+ QSet<int> rhs;
+ const int start = lhsSize - intersectSize;
+ for (int i = start; i < start + rhsSize; ++i)
+ rhs.insert(i);
+
+ QBENCHMARK {
+ lhs.intersect(rhs);
+ }
+
+ QVERIFY(lhs.size() == intersectSize);
+}
+
+struct ComplexType
+{
+ ComplexType(int a) : a(a) {}
+ int a;
+ int b;
+ int c;
+};
+
+inline uint qHash(const ComplexType &key, uint seed = 0)
+{
+ return uint(key.a) ^ seed;
+}
+
+inline bool operator==(const ComplexType &lhs, const ComplexType &rhs)
+{
+ return lhs.a == rhs.a;
+}
+
+void tst_QSet::intersect_complexType_data()
+{
+ intersect_int_data();
+}
+
+void tst_QSet::intersect_complexType()
+{
+ QFETCH(int, lhsSize);
+ QFETCH(int, rhsSize);
+ QFETCH(int, intersectSize);
+
+ QSet<ComplexType> lhs;
+ for (int i = 0; i < lhsSize; ++i)
+ lhs.insert(ComplexType(i));
+
+ QSet<ComplexType> rhs;
+ const int start = lhsSize - intersectSize;
+ for (int i = start; i < start + rhsSize; ++i)
+ rhs.insert(ComplexType(i));
+
+ QBENCHMARK {
+ lhs.intersect(rhs);
+ }
+}
+
+QTEST_MAIN(tst_QSet)
+
+#include "main.moc"
diff --git a/tests/benchmarks/corelib/tools/qset/qset.pro b/tests/benchmarks/corelib/tools/qset/qset.pro
new file mode 100644
index 0000000000..8fb8bcfa0b
--- /dev/null
+++ b/tests/benchmarks/corelib/tools/qset/qset.pro
@@ -0,0 +1,4 @@
+TARGET = tst_qset
+QT = core testlib
+SOURCES += main.cpp
+CONFIG += release
diff --git a/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp b/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp
index c32ff0d099..b590269b70 100644
--- a/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp
+++ b/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp
@@ -44,6 +44,8 @@
#include <QTableView>
#include <QImage>
#include <QPainter>
+#include <QHeaderView>
+#include <QStandardItemModel>
class QtTestTableModel: public QAbstractTableModel
{
@@ -149,6 +151,7 @@ private slots:
void columnInsertion();
void columnRemoval_data();
void columnRemoval();
+ void sizeHintForColumnWhenHidden();
private:
static inline void spanInit_helper(QTableView *);
};
@@ -361,5 +364,23 @@ void tst_QTableView::columnRemoval()
}
}
+void tst_QTableView::sizeHintForColumnWhenHidden()
+{
+ QTableView view;
+ QStandardItemModel model(12500, 6);
+ for (int r = 0; r < model.rowCount(); ++r)
+ for (int c = 0; c < model.columnCount(); ++c) {
+ QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(r).arg(c));
+ model.setItem(r, c, item);
+ }
+
+ view.horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ view.setModel(&model);
+ QBENCHMARK_ONCE {
+ view.horizontalHeader()->resizeSection(0, 10); // this force resizeSections - on a hidden view.
+ }
+
+}
+
QTEST_MAIN(tst_QTableView)
#include "tst_qtableview.moc"
diff --git a/tests/benchmarks/network/access/qnetworkreply/qnetworkreply.pro b/tests/benchmarks/network/access/qnetworkreply/qnetworkreply.pro
index 7031b83210..92d20f50d0 100644
--- a/tests/benchmarks/network/access/qnetworkreply/qnetworkreply.pro
+++ b/tests/benchmarks/network/access/qnetworkreply/qnetworkreply.pro
@@ -2,7 +2,7 @@ TEMPLATE = app
TARGET = tst_bench_qnetworkreply
QT -= gui
-QT += network testlib
+QT += core-private network network-private testlib
CONFIG += release
diff --git a/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 58cb65e1c7..55376d5a79 100644
--- a/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -50,6 +50,9 @@
#include <QtNetwork/qtcpserver.h>
#include "../../../../auto/network-settings.h"
+#ifdef QT_BUILD_INTERNAL
+#include <QtNetwork/private/qhostinfo_p.h>
+#endif
Q_DECLARE_METATYPE(QSharedPointer<char>)
@@ -460,7 +463,9 @@ private slots:
#ifndef QT_NO_SSL
void echoPerformance_data();
void echoPerformance();
-#endif
+ void preConnectEncrypted();
+#endif // !QT_NO_SSL
+ void preConnectEncrypted_data();
void downloadPerformance();
void uploadPerformance();
@@ -472,9 +477,13 @@ private slots:
void httpDownloadPerformanceDownloadBuffer();
void httpsRequestChain();
void httpsUpload();
+ void preConnect_data();
+ void preConnect();
private:
void runHttpsUploadRequest(const QByteArray &data, const QNetworkRequest &request);
+ QPair<QNetworkReply *, qint64> runGetRequest(QNetworkAccessManager *manager,
+ const QNetworkRequest &request);
};
void tst_qnetworkreply::initTestCase()
@@ -495,6 +504,19 @@ void tst_qnetworkreply::httpLatency()
}
}
+QPair<QNetworkReply *, qint64> tst_qnetworkreply::runGetRequest(
+ QNetworkAccessManager *manager, const QNetworkRequest &request)
+{
+ QElapsedTimer timer;
+ timer.start();
+ QNetworkReply *reply = manager->get(request);
+ connect(reply, SIGNAL(sslErrors(QList<QSslError>)), reply, SLOT(ignoreSslErrors()));
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
+ QTestEventLoop::instance().enterLoop(20);
+ qint64 elapsed = timer.elapsed();
+ return qMakePair(reply, elapsed);
+}
+
#ifndef QT_NO_SSL
void tst_qnetworkreply::echoPerformance_data()
{
@@ -527,7 +549,60 @@ void tst_qnetworkreply::echoPerformance()
delete reply;
}
}
+
+void tst_qnetworkreply::preConnectEncrypted()
+{
+ QString hostName = QLatin1String("www.google.com");
+
+ QNetworkAccessManager manager;
+ QNetworkRequest request(QUrl("https://" + hostName));
+
+ // make sure we have a full request including
+ // DNS lookup, TCP and SSL handshakes
+#ifdef QT_BUILD_INTERNAL
+ qt_qhostinfo_clear_cache();
+#else
+ qWarning("no internal build, could not clear DNS cache. Results may not be representative.");
+#endif
+
+ // first, benchmark a normal request
+ QPair<QNetworkReply *, qint64> normalResult = runGetRequest(&manager, request);
+ QNetworkReply *normalReply = normalResult.first;
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QVERIFY(normalReply->error() == QNetworkReply::NoError);
+ qint64 normalElapsed = normalResult.second;
+
+ // clear all caches again
+#ifdef QT_BUILD_INTERNAL
+ qt_qhostinfo_clear_cache();
+#else
+ qWarning("no internal build, could not clear DNS cache. Results may not be representative.");
#endif
+ manager.clearAccessCache();
+
+ // now try to make the connection beforehand
+ QFETCH(int, sleepTime);
+ manager.connectToHostEncrypted(hostName);
+ QTestEventLoop::instance().enterLoopMSecs(sleepTime);
+
+ // now make another request and hopefully use the existing connection
+ QPair<QNetworkReply *, qint64> preConnectResult = runGetRequest(&manager, request);
+ QNetworkReply *preConnectReply = normalResult.first;
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QVERIFY(preConnectReply->error() == QNetworkReply::NoError);
+ qint64 preConnectElapsed = preConnectResult.second;
+ qDebug() << request.url().toString() << "full request:" << normalElapsed
+ << "ms, pre-connect request:" << preConnectElapsed << "ms, difference:"
+ << (normalElapsed - preConnectElapsed) << "ms";
+}
+#endif // !QT_NO_SSL
+
+void tst_qnetworkreply::preConnectEncrypted_data()
+{
+ QTest::addColumn<int>("sleepTime");
+ QTest::newRow("2secs") << 2000; // to start a new request after preconnecting is done
+ QTest::newRow("100ms") << 100; // to start a new request while preconnecting is in-flight
+}
void tst_qnetworkreply::downloadPerformance()
{
@@ -850,6 +925,56 @@ void tst_qnetworkreply::httpsUpload()
}
}
+void tst_qnetworkreply::preConnect_data()
+{
+ preConnectEncrypted_data();
+}
+
+void tst_qnetworkreply::preConnect()
+{
+ QString hostName = QLatin1String("www.google.com");
+
+ QNetworkAccessManager manager;
+ QNetworkRequest request(QUrl("http://" + hostName));
+
+ // make sure we have a full request including
+ // DNS lookup and TCP handshake
+#ifdef QT_BUILD_INTERNAL
+ qt_qhostinfo_clear_cache();
+#else
+ qWarning("no internal build, could not clear DNS cache. Results may not be representative.");
+#endif
+
+ // first, benchmark a normal request
+ QPair<QNetworkReply *, qint64> normalResult = runGetRequest(&manager, request);
+ QNetworkReply *normalReply = normalResult.first;
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QVERIFY(normalReply->error() == QNetworkReply::NoError);
+ qint64 normalElapsed = normalResult.second;
+
+ // clear all caches again
+#ifdef QT_BUILD_INTERNAL
+ qt_qhostinfo_clear_cache();
+#else
+ qWarning("no internal build, could not clear DNS cache. Results may not be representative.");
+#endif
+ manager.clearAccessCache();
+
+ // now try to make the connection beforehand
+ QFETCH(int, sleepTime);
+ manager.connectToHost(hostName);
+ QTestEventLoop::instance().enterLoopMSecs(sleepTime);
+
+ // now make another request and hopefully use the existing connection
+ QPair<QNetworkReply *, qint64> preConnectResult = runGetRequest(&manager, request);
+ QNetworkReply *preConnectReply = normalResult.first;
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QVERIFY(preConnectReply->error() == QNetworkReply::NoError);
+ qint64 preConnectElapsed = preConnectResult.second;
+ qDebug() << request.url().toString() << "full request:" << normalElapsed
+ << "ms, pre-connect request:" << preConnectElapsed << "ms, difference:"
+ << (normalElapsed - preConnectElapsed) << "ms";
+}
QTEST_MAIN(tst_qnetworkreply)
diff --git a/tests/manual/corelib/tools/qhash/main.cpp b/tests/manual/corelib/tools/qhash/main.cpp
new file mode 100644
index 0000000000..fd38350c88
--- /dev/null
+++ b/tests/manual/corelib/tools/qhash/main.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+//#define QT_STRICT_ITERATORS
+#include <QHash>
+
+void testEraseNoError()
+{
+ QHash<int, int> a;
+
+ a.insert(100, 100);
+ a.insert(101, 200);
+ a.insert(5, 50);
+ a.insertMulti(5, 60);
+ a.insertMulti(5, 70);
+ a.insertMulti(5, 80);
+
+ QHash<int, int>::iterator i = a.begin();
+ while (i.key() != 5)
+ ++i;
+ ++i;
+ a.erase(i);
+
+ qDebug() << "Erase - got no errors on iterator check";
+}
+
+void testErase()
+{
+ QHash<int, int> a, b;
+ a.insert(5, 50);
+ a.insert(6, 60);
+ a.insert(7, 70);
+ b = a;
+ a.erase(a.begin());
+ b.erase(b.end() - 1);
+ qDebug() << "Erase - Executing line with error now.";
+ a.erase(b.begin());
+}
+
+
+int main()
+{
+ testEraseNoError();
+ testErase();
+ return 0;
+}
diff --git a/tests/manual/corelib/tools/qhash/main.pro b/tests/manual/corelib/tools/qhash/main.pro
new file mode 100644
index 0000000000..bba41b9c12
--- /dev/null
+++ b/tests/manual/corelib/tools/qhash/main.pro
@@ -0,0 +1 @@
+SOURCES = main.cpp
diff --git a/tests/manual/corelib/tools/qlist/main.cpp b/tests/manual/corelib/tools/qlist/main.cpp
new file mode 100644
index 0000000000..8c1ee2890c
--- /dev/null
+++ b/tests/manual/corelib/tools/qlist/main.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QDebug>
+//#define QT_STRICT_ITERATORS
+#include <QVector>
+void testErase()
+{
+ QList<int> a, b;
+ a.append(5);
+ a.append(6);
+ a.append(7);
+ b = a;
+ a.erase(a.begin());
+ qDebug() << "erase - Executing line with error now.";
+ // a.erase(a.end());
+ a.erase(b.begin());
+}
+void testInsert()
+{
+ QList<int> a, b;
+ a.insert(a.begin(), 1);
+ a.insert(a.begin(), 2);
+ a.insert(a.end(), 3);
+ b = a;
+ qDebug() << "insert - Executing line with error now.";
+ a.insert(b.begin(), 4);
+}
+int main()
+{
+ // testErase();
+ testInsert();
+ return 0;
+} \ No newline at end of file
diff --git a/tests/manual/corelib/tools/qlist/main.pro b/tests/manual/corelib/tools/qlist/main.pro
new file mode 100644
index 0000000000..bba41b9c12
--- /dev/null
+++ b/tests/manual/corelib/tools/qlist/main.pro
@@ -0,0 +1 @@
+SOURCES = main.cpp
diff --git a/tests/auto/dbus/qdbusabstractinterface/pinger.cpp b/tests/manual/corelib/tools/qmap/main.cpp
index be4fc30409..0d88e3f170 100644
--- a/tests/auto/dbus/qdbusabstractinterface/pinger.cpp
+++ b/tests/manual/corelib/tools/qmap/main.cpp
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtDBus module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,29 +39,73 @@
**
****************************************************************************/
-/*
- * This file was generated by qdbusxml2cpp version 0.7
- * Command line was: qdbusxml2cpp -i interface.h -p pinger org.qtproject.QtDBus.Pinger.xml
- *
- * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
- *
- * This is an auto-generated file.
- * This file may have been hand-edited. Look for HAND-EDIT comments
- * before re-generating it.
- */
+//#define Q_NO_DEBUGMAP_PARENT_TEST
+// Comment in line above to skip the parent test.
+#include <QtCore/QMap>
+#include <QDebug>
-#include "pinger.h"
+void noBugErase()
+{
+ QMap<int, int> a, b;
+ a[10] = 11;
+ a[11] = 12;
+ b = a;
+ b.erase(b.begin());
+}
-/*
- * Implementation of interface class ComTrolltechQtDBusPingerInterface
- */
+void noBugInsertWithHints()
+{
+ QMap<int, int> a;
+ QMap<int, int> b;
+ for (int u = 100; u < 10000; u += 20)
+ a.insert(u, u);
+ b = a;
+ QMap<int, int>::const_iterator b_ite(b.begin()); // b.begin() ensures correct detach()
+ ++b_ite;
+ b.insert(b_ite, 501, 501);
+ b.insert(b_ite, 115, 115);
+ QMap<int, int> c;
+ c = b;
+ c.setSharable(false);
+}
-ComTrolltechQtDBusPingerInterface::ComTrolltechQtDBusPingerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
- : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+void testInsertWithHintCorruption()
{
+ qDebug() << "Starting testInsertWithHintCorruption";
+
+ QMap<int, int> a;
+ QMap<int, int> b;
+ for (int u = 100; u < 10000; u += 20)
+ a.insert(u, u);
+ b = a;
+ QMap<int, int>::const_iterator b_ite = b.constBegin();
+ ++b_ite;
+ b.insert(b_ite, 501, 501);
+ b.insert(b_ite, 115, 115); // insert with wrong hint.
+ QMap<int, int> c;
+ c = b;
+ c.setSharable(false);
+ qDebug() << "End of testInsertWithHintCorruption - failed silently";
}
-ComTrolltechQtDBusPingerInterface::~ComTrolltechQtDBusPingerInterface()
+void testEraseCorruption()
{
+ qDebug() << "Starting testEraseCorruption";
+
+ QMap<int, int> a, b;
+ a[10] = 11;
+ a[11] = 12;
+ b = a;
+ b.erase(a.begin());
+ qDebug() << "End of testEraseCorruption - failed silently";
}
+int main()
+{
+ noBugErase();
+ noBugInsertWithHints();
+
+ // testEraseCorruption();
+ testInsertWithHintCorruption();
+ return 0;
+}
diff --git a/tests/manual/corelib/tools/qmap/qmaptest.pro b/tests/manual/corelib/tools/qmap/qmaptest.pro
new file mode 100644
index 0000000000..fbe7013144
--- /dev/null
+++ b/tests/manual/corelib/tools/qmap/qmaptest.pro
@@ -0,0 +1,2 @@
+TEMPLATE = app
+SOURCES = main.cpp
diff --git a/tests/manual/corelib/tools/qset/main.cpp b/tests/manual/corelib/tools/qset/main.cpp
new file mode 100644
index 0000000000..34a6c58c63
--- /dev/null
+++ b/tests/manual/corelib/tools/qset/main.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+//#define QT_STRICT_ITERATORS
+#include <QSet>
+
+void testErase()
+{
+ QSet<int> a, b;
+ a.insert(5);
+ a.insert(6);
+ a.insert(7);
+ b = a;
+ a.erase(a.begin());
+ b.erase(b.end() - 1);
+ qDebug() << "erase - no errors until now";
+ a.erase(b.begin());
+}
+
+int main()
+{
+ testErase();
+ return 0;
+}
diff --git a/tests/manual/corelib/tools/qset/main.pro b/tests/manual/corelib/tools/qset/main.pro
new file mode 100644
index 0000000000..bba41b9c12
--- /dev/null
+++ b/tests/manual/corelib/tools/qset/main.pro
@@ -0,0 +1 @@
+SOURCES = main.cpp
diff --git a/tests/manual/corelib/tools/qvarlengtharray/main.cpp b/tests/manual/corelib/tools/qvarlengtharray/main.cpp
new file mode 100644
index 0000000000..759f4b3905
--- /dev/null
+++ b/tests/manual/corelib/tools/qvarlengtharray/main.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+//#define QT_STRICT_ITERATORS
+#include <QVarLengthArray>
+
+void testErase()
+{
+ QVarLengthArray<int> a, b;
+ a.append(5);
+ a.append(6);
+ a.append(7);
+ b = a;
+ a.erase(a.begin());
+ a.erase(a.end() - 1);
+ qDebug() << "erase - no errors until now";
+ // a.erase(a.end());
+ a.erase(b.begin());
+}
+
+void testInsert()
+{
+ QVarLengthArray<int> a, b;
+ a.insert(a.begin(), 1);
+ a.insert(a.begin(), 2);
+ a.insert(a.end(), 3);
+ b = a;
+ qDebug() << "insert - no errors until now";
+ a.insert(b.begin(), 1, 4);
+}
+
+int main()
+{
+ // testErase();
+ testInsert();
+ return 0;
+}
diff --git a/tests/manual/corelib/tools/qvarlengtharray/main.pro b/tests/manual/corelib/tools/qvarlengtharray/main.pro
new file mode 100644
index 0000000000..4ce070ab75
--- /dev/null
+++ b/tests/manual/corelib/tools/qvarlengtharray/main.pro
@@ -0,0 +1 @@
+SOURCES=main.cpp
diff --git a/tests/manual/corelib/tools/qvector/main.cpp b/tests/manual/corelib/tools/qvector/main.cpp
new file mode 100644
index 0000000000..2dce4a9264
--- /dev/null
+++ b/tests/manual/corelib/tools/qvector/main.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+//#define QT_STRICT_ITERATORS
+#include <QVector>
+
+void testErase()
+{
+ QVector<int> a, b;
+ a.append(5);
+ a.append(6);
+ a.append(7);
+ b = a;
+ a.erase(a.begin());
+ a.erase(a.end() - 1);
+ qDebug() << "erase - no errors until now";
+ // a.erase(a.end());
+ a.erase(b.begin());
+}
+
+void testInsert()
+{
+ QVector<int> a, b;
+ a.insert(a.begin(), 1, 1);
+ a.insert(a.begin(), 1, 2);
+ a.insert(a.begin(), 1, 3);
+ b = a;
+ qDebug() << "insert - no errors until now";
+ a.insert(b.begin(), 1, 4);
+}
+
+int main()
+{
+ testErase();
+ // testInsert();
+ return 0;
+}
diff --git a/tests/manual/corelib/tools/qvector/main.pro b/tests/manual/corelib/tools/qvector/main.pro
new file mode 100644
index 0000000000..bba41b9c12
--- /dev/null
+++ b/tests/manual/corelib/tools/qvector/main.pro
@@ -0,0 +1 @@
+SOURCES = main.cpp
diff --git a/tests/manual/dialogs/colordialogpanel.h b/tests/manual/dialogs/colordialogpanel.h
index 05ca336a23..7f2898cea0 100644
--- a/tests/manual/dialogs/colordialogpanel.h
+++ b/tests/manual/dialogs/colordialogpanel.h
@@ -45,9 +45,11 @@
#include <QPointer>
#include <QColorDialog>
+QT_BEGIN_NAMESPACE
class QComboBox;
class QCheckBox;
class QPushButton;
+QT_END_NAMESPACE
class ColorDialogPanel : public QWidget
{
diff --git a/tests/manual/dialogs/dialogs.pro b/tests/manual/dialogs/dialogs.pro
index 4ed200ab7f..d19c3026d0 100644
--- a/tests/manual/dialogs/dialogs.pro
+++ b/tests/manual/dialogs/dialogs.pro
@@ -5,6 +5,6 @@ TARGET = dialogs
TEMPLATE = app
SOURCES += main.cpp filedialogpanel.cpp colordialogpanel.cpp fontdialogpanel.cpp \
- wizardpanel.cpp
+ wizardpanel.cpp messageboxpanel.cpp
HEADERS += filedialogpanel.h colordialogpanel.h fontdialogpanel.h \
- wizardpanel.h
+ wizardpanel.h messageboxpanel.h
diff --git a/tests/manual/dialogs/filedialogpanel.cpp b/tests/manual/dialogs/filedialogpanel.cpp
index a342122570..000d755cef 100644
--- a/tests/manual/dialogs/filedialogpanel.cpp
+++ b/tests/manual/dialogs/filedialogpanel.cpp
@@ -154,9 +154,11 @@ FileDialogPanel::FileDialogPanel(QWidget *parent)
, m_nameFilterDetailsVisible(new QCheckBox(tr("Name filter details visible")))
, m_resolveSymLinks(new QCheckBox(tr("Resolve symlinks")))
, m_native(new QCheckBox(tr("Use native dialog")))
+ , m_customDirIcons(new QCheckBox(tr("Don't use custom directory icons")))
, m_acceptMode(createCombo(this, acceptModeComboData, sizeof(acceptModeComboData)/sizeof(ComboData)))
, m_fileMode(createCombo(this, fileModeComboData, sizeof(fileModeComboData)/sizeof(ComboData)))
, m_viewMode(createCombo(this, viewModeComboData, sizeof(viewModeComboData)/sizeof(ComboData)))
+ , m_allowedSchemes(new QLineEdit(this))
, m_defaultSuffix(new QLineEdit(this))
, m_directory(new QLineEdit(this))
, m_selectedFileName(new QLineEdit(this))
@@ -171,11 +173,13 @@ FileDialogPanel::FileDialogPanel(QWidget *parent)
optionsLayout->addRow(tr("AcceptMode:"), m_acceptMode);
optionsLayout->addRow(tr("FileMode:"), m_fileMode);
optionsLayout->addRow(tr("ViewMode:"), m_viewMode);
+ optionsLayout->addRow(tr("Allowed Schemes:"), m_allowedSchemes);
optionsLayout->addRow(m_native);
optionsLayout->addRow(m_confirmOverWrite);
optionsLayout->addRow(m_nameFilterDetailsVisible);
optionsLayout->addRow(m_resolveSymLinks);
optionsLayout->addRow(m_readOnly);
+ optionsLayout->addRow(m_customDirIcons);
// Files
QGroupBox *filesGroupBox = new QGroupBox(tr("Files / Filters"));
@@ -216,9 +220,13 @@ FileDialogPanel::FileDialogPanel(QWidget *parent)
row = 0;
column++;
addButton(tr("getOpenFileName"), buttonLayout, row, column, this, SLOT(getOpenFileName()));
+ addButton(tr("getOpenFileUrl"), buttonLayout, row, column, this, SLOT(getOpenFileUrl()));
addButton(tr("getOpenFileNames"), buttonLayout, row, column, this, SLOT(getOpenFileNames()));
+ addButton(tr("getOpenFileUrls"), buttonLayout, row, column, this, SLOT(getOpenFileUrls()));
addButton(tr("getSaveFileName"), buttonLayout, row, column, this, SLOT(getSaveFileName()));
+ addButton(tr("getSaveFileUrl"), buttonLayout, row, column, this, SLOT(getSaveFileUrl()));
addButton(tr("getExistingDirectory"), buttonLayout, row, column, this, SLOT(getExistingDirectory()));
+ addButton(tr("getExistingDirectoryUrl"), buttonLayout, row, column, this, SLOT(getExistingDirectoryUrl()));
addButton(tr("Restore defaults"), buttonLayout, row, column, this, SLOT(restoreDefaults()));
// Main layout
@@ -316,9 +324,16 @@ QFileDialog::Options FileDialogPanel::options() const
result |= QFileDialog::DontConfirmOverwrite;
if (!m_native->isChecked())
result |= QFileDialog::DontUseNativeDialog;
+ if (!m_customDirIcons->isChecked())
+ result |= QFileDialog::DontUseCustomDirectoryIcons;
return result;
}
+QStringList FileDialogPanel::allowedSchemes() const
+{
+ return m_allowedSchemes->text().simplified().split(' ', QString::SkipEmptyParts);
+}
+
void FileDialogPanel::getOpenFileNames()
{
QString selectedFilter = m_selectedNameFilter->text().trimmed();
@@ -334,6 +349,22 @@ void FileDialogPanel::getOpenFileNames()
}
}
+void FileDialogPanel::getOpenFileUrls()
+{
+ QString selectedFilter = m_selectedNameFilter->text().trimmed();
+ const QList<QUrl> files =
+ QFileDialog::getOpenFileUrls(this, tr("getOpenFileNames Qt %1").arg(QLatin1String(QT_VERSION_STR)),
+ QUrl(m_directory->text()), filterString(), &selectedFilter, options(),
+ allowedSchemes());
+ if (!files.isEmpty()) {
+ QString result;
+ QDebug(&result).nospace()
+ << "Files: " << QUrl::toStringList(files)
+ << "\nName filter: " << selectedFilter;
+ QMessageBox::information(this, tr("getOpenFileNames"), result, QMessageBox::Ok);
+ }
+}
+
void FileDialogPanel::getOpenFileName()
{
QString selectedFilter = m_selectedNameFilter->text().trimmed();
@@ -349,6 +380,22 @@ void FileDialogPanel::getOpenFileName()
}
}
+void FileDialogPanel::getOpenFileUrl()
+{
+ QString selectedFilter = m_selectedNameFilter->text().trimmed();
+ const QUrl file =
+ QFileDialog::getOpenFileUrl(this, tr("getOpenFileUrl Qt %1").arg(QLatin1String(QT_VERSION_STR)),
+ QUrl(m_directory->text()), filterString(), &selectedFilter, options(),
+ allowedSchemes());
+ if (file.isValid()) {
+ QString result;
+ QDebug(&result).nospace()
+ << "File: " << file.toString()
+ << "\nName filter: " << selectedFilter;
+ QMessageBox::information(this, tr("getOpenFileName"), result, QMessageBox::Ok);
+ }
+}
+
void FileDialogPanel::getSaveFileName()
{
QString selectedFilter = m_selectedNameFilter->text().trimmed();
@@ -364,6 +411,22 @@ void FileDialogPanel::getSaveFileName()
}
}
+void FileDialogPanel::getSaveFileUrl()
+{
+ QString selectedFilter = m_selectedNameFilter->text().trimmed();
+ const QUrl file =
+ QFileDialog::getSaveFileUrl(this, tr("getSaveFileName Qt %1").arg(QLatin1String(QT_VERSION_STR)),
+ QUrl(m_directory->text()), filterString(), &selectedFilter, options(),
+ allowedSchemes());
+ if (file.isValid()) {
+ QString result;
+ QDebug(&result).nospace()
+ << "File: " << file.toString()
+ << "\nName filter: " << selectedFilter;
+ QMessageBox::information(this, tr("getSaveFileNames"), result, QMessageBox::Ok);
+ }
+}
+
void FileDialogPanel::getExistingDirectory()
{
const QString dir =
@@ -373,17 +436,29 @@ void FileDialogPanel::getExistingDirectory()
QMessageBox::information(this, tr("getExistingDirectory"), QLatin1String("Directory: ") + dir, QMessageBox::Ok);
}
+void FileDialogPanel::getExistingDirectoryUrl()
+{
+ const QUrl dir =
+ QFileDialog::getExistingDirectoryUrl(this, tr("getExistingDirectory Qt %1").arg(QLatin1String(QT_VERSION_STR)),
+ QUrl(m_directory->text()), options() | QFileDialog::ShowDirsOnly,
+ allowedSchemes());
+ if (!dir.isEmpty())
+ QMessageBox::information(this, tr("getExistingDirectory"), QLatin1String("Directory: ") + dir.toString(), QMessageBox::Ok);
+}
+
void FileDialogPanel::restoreDefaults()
{
QFileDialog d;
setComboBoxValue(m_acceptMode, d.acceptMode());
setComboBoxValue(m_fileMode, d.fileMode());
setComboBoxValue(m_viewMode, d.viewMode());
+ m_allowedSchemes->setText(QString());
m_confirmOverWrite->setChecked(d.confirmOverwrite());
m_nameFilterDetailsVisible->setChecked(d.isNameFilterDetailsVisible());
m_resolveSymLinks->setChecked(d.resolveSymlinks());
m_readOnly->setChecked(d.isReadOnly());
m_native->setChecked(true);
+ m_customDirIcons->setChecked(d.testOption(QFileDialog::DontUseCustomDirectoryIcons));
m_directory->setText(QDir::homePath());
m_defaultSuffix->setText(QLatin1String("txt"));
m_nameFilters->setPlainText(QLatin1String("Any files (*)\nImage files (*.png *.xpm *.jpg)\nText files (*.txt)"));
diff --git a/tests/manual/dialogs/filedialogpanel.h b/tests/manual/dialogs/filedialogpanel.h
index 2977de4164..2e1d5d4de9 100644
--- a/tests/manual/dialogs/filedialogpanel.h
+++ b/tests/manual/dialogs/filedialogpanel.h
@@ -46,11 +46,13 @@
#include <QFileDialog>
#include <QPointer>
+QT_BEGIN_NAMESPACE
class QPushButton;
class QCheckBox;
class QComboBox;
class QLineEdit;
class QPlainTextEdit;
+QT_END_NAMESPACE
class LabelLineEdit;
class FileDialogPanel : public QWidget
@@ -66,9 +68,13 @@ public slots:
void deleteNonModalDialog();
void deleteModalDialog();
void getOpenFileNames();
+ void getOpenFileUrls();
void getOpenFileName();
+ void getOpenFileUrl();
void getSaveFileName();
+ void getSaveFileUrl();
void getExistingDirectory();
+ void getExistingDirectoryUrl();
void accepted();
void showAcceptedResult();
void restoreDefaults();
@@ -80,6 +86,7 @@ private slots:
private:
QString filterString() const;
QFileDialog::Options options() const;
+ QStringList allowedSchemes() const;
void applySettings(QFileDialog *d) const;
QCheckBox *m_readOnly;
@@ -87,9 +94,11 @@ private:
QCheckBox *m_nameFilterDetailsVisible;
QCheckBox *m_resolveSymLinks;
QCheckBox *m_native;
+ QCheckBox *m_customDirIcons;
QComboBox *m_acceptMode;
QComboBox *m_fileMode;
QComboBox *m_viewMode;
+ QLineEdit *m_allowedSchemes;
QLineEdit *m_defaultSuffix;
QLineEdit *m_directory;
QLineEdit *m_selectedFileName;
diff --git a/tests/manual/dialogs/fontdialogpanel.cpp b/tests/manual/dialogs/fontdialogpanel.cpp
index 02f05f9580..c72bf77351 100644
--- a/tests/manual/dialogs/fontdialogpanel.cpp
+++ b/tests/manual/dialogs/fontdialogpanel.cpp
@@ -67,12 +67,20 @@ FontDialogPanel::FontDialogPanel(QWidget *parent)
, m_fontSizeBox(new QDoubleSpinBox)
, m_noButtons(new QCheckBox(tr("Don't display OK/Cancel buttons")))
, m_dontUseNativeDialog(new QCheckBox(tr("Don't use native dialog")))
+ , m_scalableFilter(new QCheckBox(tr("Filter scalable fonts")))
+ , m_nonScalableFilter(new QCheckBox(tr("Filter non scalable fonts")))
+ , m_monospacedFilter(new QCheckBox(tr("Filter monospaced fonts")))
+ , m_proportionalFilter(new QCheckBox(tr("Filter proportional fonts")))
{
// Options
QGroupBox *optionsGroupBox = new QGroupBox(tr("Options"), this);
QVBoxLayout *optionsLayout = new QVBoxLayout(optionsGroupBox);
optionsLayout->addWidget(m_noButtons);
optionsLayout->addWidget(m_dontUseNativeDialog);
+ optionsLayout->addWidget(m_scalableFilter);
+ optionsLayout->addWidget(m_nonScalableFilter);
+ optionsLayout->addWidget(m_monospacedFilter);
+ optionsLayout->addWidget(m_proportionalFilter);
// Font
QGroupBox *fontGroupBox = new QGroupBox(tr("Font"), this);
@@ -201,6 +209,10 @@ void FontDialogPanel::applySettings(QFontDialog *d) const
{
d->setOption(QFontDialog::NoButtons, m_noButtons->isChecked());
d->setOption(QFontDialog::DontUseNativeDialog, m_dontUseNativeDialog->isChecked());
+ d->setOption(QFontDialog::ScalableFonts, m_scalableFilter->isChecked());
+ d->setOption(QFontDialog::NonScalableFonts, m_nonScalableFilter->isChecked());
+ d->setOption(QFontDialog::MonospacedFonts, m_monospacedFilter->isChecked());
+ d->setOption(QFontDialog::ProportionalFonts, m_proportionalFilter->isChecked());
QFont font = m_fontFamilyBox->currentFont();
font.setPointSizeF(m_fontSizeBox->value());
diff --git a/tests/manual/dialogs/fontdialogpanel.h b/tests/manual/dialogs/fontdialogpanel.h
index f3bbbb3939..4592c2ec6e 100644
--- a/tests/manual/dialogs/fontdialogpanel.h
+++ b/tests/manual/dialogs/fontdialogpanel.h
@@ -45,10 +45,12 @@
#include <QPointer>
#include <QFontDialog>
+QT_BEGIN_NAMESPACE
class QCheckBox;
class QPushButton;
class QFontComboBox;
class QDoubleSpinBox;
+QT_END_NAMESPACE
class FontDialogPanel : public QWidget
{
@@ -77,6 +79,10 @@ private:
QDoubleSpinBox *m_fontSizeBox;
QCheckBox *m_noButtons;
QCheckBox *m_dontUseNativeDialog;
+ QCheckBox *m_scalableFilter;
+ QCheckBox *m_nonScalableFilter;
+ QCheckBox *m_monospacedFilter;
+ QCheckBox *m_proportionalFilter;
QPushButton *m_deleteNonModalDialogButton;
QPushButton *m_deleteModalDialogButton;
QString m_result;
diff --git a/tests/manual/dialogs/main.cpp b/tests/manual/dialogs/main.cpp
index 4ad2842e44..c5f14cabef 100644
--- a/tests/manual/dialogs/main.cpp
+++ b/tests/manual/dialogs/main.cpp
@@ -43,6 +43,7 @@
#include "colordialogpanel.h"
#include "fontdialogpanel.h"
#include "wizardpanel.h"
+#include "messageboxpanel.h"
#include <QMainWindow>
#include <QApplication>
@@ -73,6 +74,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
tabWidget->addTab(new ColorDialogPanel, tr("QColorDialog"));
tabWidget->addTab(new FontDialogPanel, tr("QFontDialog"));
tabWidget->addTab(new WizardPanel, tr("QWizard"));
+ tabWidget->addTab(new MessageBoxPanel, tr("QMessageBox"));
setCentralWidget(tabWidget);
}
diff --git a/tests/manual/dialogs/messageboxpanel.cpp b/tests/manual/dialogs/messageboxpanel.cpp
new file mode 100644
index 0000000000..6fc84e11fd
--- /dev/null
+++ b/tests/manual/dialogs/messageboxpanel.cpp
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "messageboxpanel.h"
+
+#include <QGroupBox>
+#include <QPushButton>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QMessageBox>
+#include <QPushButton>
+#include <QDebug>
+#include <QComboBox>
+#include <QLineEdit>
+#include <QLabel>
+#include <QCheckBox>
+
+MessageBoxPanel::MessageBoxPanel(QWidget *parent) : QWidget(parent)
+,m_iconComboBox(new QComboBox)
+,m_textInMsgBox(new QLineEdit)
+,m_informativeText(new QLineEdit)
+,m_detailedtext(new QLineEdit)
+,m_buttonsMask(new QLineEdit)
+,m_btnExec(new QPushButton)
+,m_btnShowApply(new QPushButton)
+,m_resultLabel(new QLabel)
+,m_chkReallocMsgBox(new QCheckBox(QString::fromLatin1("Reallocate Message Box")))
+,m_msgbox(new QMessageBox)
+{
+ // --- Options ---
+ QGroupBox *optionsGroupBox = new QGroupBox(tr("Options"), this);
+ QVBoxLayout *optionsLayout = new QVBoxLayout(optionsGroupBox);
+
+ // text
+ optionsLayout->addWidget(new QLabel(QString::fromLatin1("Message box text")));
+ m_textInMsgBox->setText(QString::fromLatin1("This is a simple test with a text that is not long"));
+ optionsLayout->addWidget(m_textInMsgBox);
+
+ // informative text
+ optionsLayout->addWidget(new QLabel(QString::fromLatin1("Informative Text")));
+ optionsLayout->addWidget(m_informativeText);
+
+ // detailed text
+ optionsLayout->addWidget(new QLabel(QString::fromLatin1("detailed Text")));
+ optionsLayout->addWidget(m_detailedtext);
+
+ // icon
+ QStringList items;
+ items << "NoIcon" << "Information" << "Warning" << "Critical" << "Question";
+ m_iconComboBox->addItems(items);
+ optionsLayout->addWidget(new QLabel(QString::fromLatin1("Message box icon")));
+ optionsLayout->addWidget(m_iconComboBox);
+
+ // buttons mask
+ optionsLayout->addWidget(new QLabel(QString::fromLatin1("Message box button mask (in hex)")));
+ m_validator = new QRegExpValidator(QRegExp("0[xX]?[0-9a-fA-F]+"), this);
+ m_buttonsMask->setMaxLength(10);
+ m_buttonsMask->setValidator(m_validator);
+ m_buttonsMask->setText(QString::fromLatin1("0x00300400"));
+ optionsLayout->addWidget(m_buttonsMask);
+
+ // reallocate
+ optionsLayout->addWidget(m_chkReallocMsgBox);
+ optionsLayout->addItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding));
+
+ // Exec/Show
+ QGroupBox *execGroupBox = new QGroupBox(tr("Exec"));
+ QVBoxLayout *execLayout = new QVBoxLayout(execGroupBox);
+ m_btnExec->setText(QString::fromLatin1("Exec message box"));
+ connect(m_btnExec, SIGNAL(clicked()), this, SLOT(doExec()));
+ execLayout->addWidget(m_btnExec);
+
+ m_btnShowApply->setText(QString::fromLatin1("Show / apply"));
+ connect(m_btnShowApply, SIGNAL(clicked()), this, SLOT(doShowApply()));
+ execLayout->addWidget(m_btnShowApply);
+
+ // result label
+ execLayout->addWidget(m_resultLabel);
+
+ execLayout->addItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding));
+ execGroupBox->setLayout(execLayout);
+
+ // Main layout
+ QHBoxLayout *mainLayout = new QHBoxLayout();
+ mainLayout->addWidget(optionsGroupBox);
+ mainLayout->addWidget(execGroupBox);
+
+ setLayout(mainLayout);
+}
+
+void MessageBoxPanel::setupMessageBox(QMessageBox &box)
+{
+ m_resultLabel->setText(QString());
+ box.setText(m_textInMsgBox->text());
+ box.setInformativeText(m_informativeText->text());
+ box.setDetailedText(m_detailedtext->text());
+
+ QString btnHexText = m_buttonsMask->text();
+ btnHexText = btnHexText.replace(QString::fromLatin1("0x"), QString(), Qt::CaseInsensitive);
+ bool ok;
+ QMessageBox::StandardButtons btns = (QMessageBox::StandardButtons) btnHexText.toUInt(&ok, 16);
+ box.setStandardButtons((QMessageBox::StandardButtons) btns);
+ if (box.standardButtons() == (QMessageBox::StandardButtons) 0)
+ box.setStandardButtons(QMessageBox::Ok); // just to have something.
+
+ box.setIcon((QMessageBox::Icon) m_iconComboBox->currentIndex());
+}
+
+MessageBoxPanel::~MessageBoxPanel()
+{
+ if (m_msgbox)
+ m_msgbox->deleteLater();
+}
+
+void MessageBoxPanel::doExec()
+{
+ if (!m_msgbox || m_chkReallocMsgBox->isChecked()) {
+ if (m_msgbox)
+ m_msgbox->deleteLater();
+ m_msgbox = new QMessageBox;
+ }
+ setupMessageBox(*m_msgbox);
+ m_msgbox->setWindowModality(Qt::NonModal);
+
+ int res = m_msgbox->exec();
+ QString sres;
+ sres.setNum(res, 16);
+ m_resultLabel->setText(QString::fromLatin1("Return value (hex): %1").arg(sres));
+}
+
+void MessageBoxPanel::doShowApply()
+{
+ if (!m_msgbox || m_chkReallocMsgBox->isChecked()) {
+ if (m_msgbox)
+ m_msgbox->deleteLater();
+ m_msgbox = new QMessageBox;
+ }
+ setupMessageBox(*m_msgbox);
+ if (!m_msgbox->isVisible()) {
+ m_msgbox->setWindowModality(Qt::NonModal);
+ m_msgbox->show();
+ }
+}
diff --git a/tests/manual/dialogs/messageboxpanel.h b/tests/manual/dialogs/messageboxpanel.h
new file mode 100644
index 0000000000..9f7e35210c
--- /dev/null
+++ b/tests/manual/dialogs/messageboxpanel.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MESSAGEBOXPANEL_H
+#define MESSAGEBOXPANEL_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QCheckBox;
+class QPushButton;
+class QLineEdit;
+class QValidator;
+class QLabel;
+class QMessageBox;
+class QCheckBox;
+QT_END_NAMESPACE
+
+class MessageBoxPanel : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit MessageBoxPanel(QWidget *parent = 0);
+ ~MessageBoxPanel();
+
+public slots:
+ void doExec();
+ void doShowApply();
+
+private:
+ QComboBox *m_iconComboBox;
+ QLineEdit *m_textInMsgBox;
+ QLineEdit *m_informativeText;
+ QLineEdit *m_detailedtext;
+ QLineEdit *m_buttonsMask;
+ QPushButton *m_btnExec;
+ QPushButton *m_btnShowApply;
+ QValidator *m_validator;
+ QLabel *m_resultLabel;
+ QCheckBox *m_chkReallocMsgBox;
+ QMessageBox *m_msgbox;
+ void setupMessageBox(QMessageBox &box);
+};
+
+#endif
diff --git a/tests/manual/dialogs/wizardpanel.h b/tests/manual/dialogs/wizardpanel.h
index 6a2268e94c..10e0c5071e 100644
--- a/tests/manual/dialogs/wizardpanel.h
+++ b/tests/manual/dialogs/wizardpanel.h
@@ -46,7 +46,9 @@
class WizardStyleControl;
class WizardOptionsControl;
+QT_BEGIN_NAMESPACE
class QWizard;
+QT_END_NAMESPACE
class WizardPanel : public QWidget
{
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
index 2fa05f65e0..c04f22b53b 100644
--- a/tests/manual/manual.pro
+++ b/tests/manual/manual.pro
@@ -20,6 +20,7 @@ qlayout \
qlocale \
qnetworkaccessmanager/qget \
qnetworkconfigurationmanager \
+qnetworkconfiguration \
qnetworkreply \
qpainfo \
qscreen \
diff --git a/tests/manual/qdesktopservices/tst_qdesktopservices.cpp b/tests/manual/qdesktopservices/tst_qdesktopservices.cpp
index 534816a01b..9c39002fba 100644
--- a/tests/manual/qdesktopservices/tst_qdesktopservices.cpp
+++ b/tests/manual/qdesktopservices/tst_qdesktopservices.cpp
@@ -104,6 +104,11 @@ void tst_QDesktopServices::openUrl_data()
<< QUrl("http://google.com/search?q=/profile/5")
<< "This should search \"/profile/5\" on Google.";
+ // see QTBUG-31945
+ QTest::newRow("two-fragments")
+ << QUrl("http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006926-CH3-SW81")
+ << "This should open \"Implementing a Container View Controller\" in the UIViewController docs";
+
QTest::newRow("mail")
<< QUrl("mailto:development@qt-project.org")
<< "This should open an email composer with the destination set to development@qt-project.org";
@@ -118,7 +123,7 @@ void tst_QDesktopServices::openUrl()
QFETCH(QUrl, data);
QFETCH(QString, message);
qWarning("\n\nOpening \"%s\": %s", qPrintable(data.toString()), qPrintable(message));
- QDesktopServices::openUrl(data);
+ QVERIFY(QDesktopServices::openUrl(data));
}
QTEST_MAIN(tst_QDesktopServices)
diff --git a/tests/manual/qnetworkconfiguration/main.cpp b/tests/manual/qnetworkconfiguration/main.cpp
new file mode 100644
index 0000000000..c611cfc9e2
--- /dev/null
+++ b/tests/manual/qnetworkconfiguration/main.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research in Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <qtest.h>
+#include <QtTest/QtTest>
+#include <QtNetwork/qnetworkconfiguration.h>
+#include <QtNetwork/qnetworkconfigmanager.h>
+
+class tst_qnetworkconfiguration : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void bearerType();
+ void bearerTypeFamily();
+};
+
+void tst_qnetworkconfiguration::bearerType()
+{
+ QNetworkConfigurationManager m;
+ QList<QNetworkConfiguration> allConfs = m.allConfigurations();
+ QElapsedTimer timer;
+ for (int a = 0; a < allConfs.count(); a++) {
+ timer.start();
+ QNetworkConfiguration::BearerType type = allConfs.at(a).bearerType();
+ qint64 elapsed = timer.elapsed();
+ QString typeString;
+ switch (type) {
+ case QNetworkConfiguration::BearerUnknown:
+ typeString = QLatin1String("Unknown");
+ break;
+ case QNetworkConfiguration::BearerEthernet:
+ typeString = QLatin1String("Ethernet");
+ break;
+ case QNetworkConfiguration::BearerWLAN:
+ typeString = QLatin1String("WLAN");
+ break;
+ case QNetworkConfiguration::Bearer2G:
+ typeString = QLatin1String("2G");
+ break;
+ case QNetworkConfiguration::BearerCDMA2000:
+ typeString = QLatin1String("CDMA2000");
+ break;
+ case QNetworkConfiguration::BearerWCDMA:
+ typeString = QLatin1String("WCDMA");
+ break;
+ case QNetworkConfiguration::BearerHSPA:
+ typeString = QLatin1String("HSPA");
+ break;
+ case QNetworkConfiguration::BearerBluetooth:
+ typeString = QLatin1String("Bluetooth");
+ break;
+ case QNetworkConfiguration::BearerWiMAX:
+ typeString = QLatin1String("WiMAX");
+ break;
+ case QNetworkConfiguration::BearerEVDO:
+ typeString = QLatin1String("EVDO");
+ break;
+ case QNetworkConfiguration::BearerLTE:
+ typeString = QLatin1String("LTE");
+ break;
+ default:
+ typeString = "unknown bearer (?)";
+ }
+
+ const char *isDefault = (allConfs.at(a) == m.defaultConfiguration())
+ ? "*DEFAULT*" : "";
+ qDebug() << isDefault << "identifier:" << allConfs.at(a).identifier()
+ << "bearer type name:" << allConfs.at(a).bearerTypeName()
+ << "bearer type:" << type << "(" << typeString << ")"
+ << "elapsed:" << elapsed;
+ QCOMPARE(allConfs.at(a).bearerTypeName(), typeString);
+ }
+}
+
+void tst_qnetworkconfiguration::bearerTypeFamily()
+{
+ QNetworkConfigurationManager m;
+ foreach (const QNetworkConfiguration &config,
+ m.allConfigurations(QNetworkConfiguration::Active)) {
+ QString family;
+ switch (config.bearerTypeFamily()) {
+ case QNetworkConfiguration::Bearer3G:
+ family = QLatin1String("Bearer3G");
+ break;
+ case QNetworkConfiguration::Bearer4G:
+ family = QLatin1String("Bearer4G");
+ break;
+ default:
+ family = config.bearerTypeName();
+ }
+ qDebug() << config.name() << "has bearer type"
+ << config.bearerTypeName() << "of bearer type family"
+ << family;
+ }
+}
+
+QTEST_MAIN(tst_qnetworkconfiguration)
+
+#include "main.moc"
diff --git a/tests/manual/qnetworkconfiguration/qnetworkconfiguration.pro b/tests/manual/qnetworkconfiguration/qnetworkconfiguration.pro
new file mode 100644
index 0000000000..25ef41b92a
--- /dev/null
+++ b/tests/manual/qnetworkconfiguration/qnetworkconfiguration.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = tst_qnetworkconfiguration
+
+QT -= gui
+QT += network testlib
+
+SOURCES += main.cpp
diff --git a/tests/manual/qpainfo/main.cpp b/tests/manual/qpainfo/main.cpp
index 6b712304a0..0f5119bab3 100644
--- a/tests/manual/qpainfo/main.cpp
+++ b/tests/manual/qpainfo/main.cpp
@@ -49,6 +49,7 @@
#include <QStringList>
#include <QVariant>
#include <QFont>
+#include <QFontDatabase>
#include <QSysInfo>
#include <QLibraryInfo>
#include <QStandardPaths>
@@ -85,6 +86,12 @@ std::ostream &operator<<(std::ostream &str, const QStringList &l)
return str;
}
+std::ostream &operator<<(std::ostream &str, const QFont &f)
+{
+ std::cout << '"' << f.family().toStdString() << "\" " << f.pointSize();
+ return str;
+}
+
static QStringList toNativeSeparators(QStringList in)
{
for (int i = 0; i < in.size(); ++i)
@@ -184,7 +191,12 @@ int main(int argc, char **argv)
<< " from " << platformTheme->themeHint(QPlatformTheme::IconThemeSearchPaths).toStringList() << '\n';
}
if (const QFont *systemFont = platformTheme->font())
- std::cout << " System font: \"" << systemFont->family().toStdString() << "\" " << systemFont->pointSize() << '\n';
+ std::cout << " System font: " << *systemFont<< '\n';
+ std::cout << " General font : " << QFontDatabase::systemFont(QFontDatabase::GeneralFont) << '\n'
+ << " Fixed font : " << QFontDatabase::systemFont(QFontDatabase::FixedFont) << '\n'
+ << " Title font : " << QFontDatabase::systemFont(QFontDatabase::TitleFont) << '\n'
+ << " Smallest font: " << QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont) << "\n\n";
+
if (platformTheme->usePlatformNativeDialog(QPlatformTheme::FileDialog))
std::cout << " Native file dialog\n";
if (platformTheme->usePlatformNativeDialog(QPlatformTheme::ColorDialog))
diff --git a/tests/manual/qtabletevent/regular_widgets/main.cpp b/tests/manual/qtabletevent/regular_widgets/main.cpp
index 1e2f5c00da..ce77cf8cff 100644
--- a/tests/manual/qtabletevent/regular_widgets/main.cpp
+++ b/tests/manual/qtabletevent/regular_widgets/main.cpp
@@ -43,12 +43,38 @@
#include <QDebug>
#include <QMouseEvent>
#include <QTabletEvent>
-#include <QWidget>
+#include <QMainWindow>
+#include <QMenuBar>
+#include <QMenu>
+#include <QAction>
+#include <QVector>
+#include <QPainter>
+#include <QCursor>
+
+enum TabletPointType {
+ TabletButtonPress,
+ TabletButtonRelease,
+ TabletMove,
+ TabletDraw
+};
+
+struct TabletPoint
+{
+ TabletPoint(const QPoint &p = QPoint(), TabletPointType t = TabletMove) : pos(p), type(t) {}
+
+ QPoint pos;
+ TabletPointType type;
+};
class EventReportWidget : public QWidget
{
+ Q_OBJECT
public:
EventReportWidget();
+
+public slots:
+ void clearPoints() { m_points.clear(); update(); }
+
protected:
void mouseDoubleClickEvent(QMouseEvent *event) { outputMouseEvent(event); }
void mouseMoveEvent(QMouseEvent *event) { outputMouseEvent(event); }
@@ -57,11 +83,14 @@ protected:
void tabletEvent(QTabletEvent *);
+ void paintEvent(QPaintEvent *);
+
private:
void outputMouseEvent(QMouseEvent *event);
bool m_lastIsMouseMove;
bool m_lastIsTabletMove;
+ QVector<TabletPoint> m_points;
};
EventReportWidget::EventReportWidget()
@@ -69,6 +98,34 @@ EventReportWidget::EventReportWidget()
, m_lastIsTabletMove(false)
{ }
+void EventReportWidget::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+ const QRect geom = QRect(QPoint(0, 0), size());
+ p.fillRect(geom, Qt::white);
+ p.drawRect(QRect(geom.topLeft(), geom.bottomRight() - QPoint(1,1)));
+ foreach (const TabletPoint &t, m_points) {
+ if (geom.contains(t.pos)) {
+ QPainterPath pp;
+ pp.addEllipse(t.pos, 5, 5);
+ switch (t.type) {
+ case TabletButtonPress:
+ p.fillPath(pp, Qt::black);
+ break;
+ case TabletButtonRelease:
+ p.fillPath(pp, Qt::red);
+ break;
+ case TabletMove:
+ p.drawPath(pp);
+ break;
+ case TabletDraw:
+ p.fillPath(pp, Qt::blue);
+ break;
+ }
+ }
+ }
+}
+
void EventReportWidget::tabletEvent(QTabletEvent *event)
{
QWidget::tabletEvent(event);
@@ -89,14 +146,20 @@ void EventReportWidget::tabletEvent(QTabletEvent *event)
m_lastIsTabletMove = true;
type = QString::fromLatin1("TabletMove");
+ m_points.push_back(TabletPoint(event->pos(), event->pressure() ? TabletDraw : TabletMove));
+ update();
break;
case QEvent::TabletPress:
m_lastIsTabletMove = false;
type = QString::fromLatin1("TabletPress");
+ m_points.push_back(TabletPoint(event->pos(), TabletButtonPress));
+ update();
break;
case QEvent::TabletRelease:
m_lastIsTabletMove = false;
type = QString::fromLatin1("TabletRelease");
+ m_points.push_back(TabletPoint(event->pos(), TabletButtonRelease));
+ update();
break;
default:
Q_ASSERT(false);
@@ -105,7 +168,8 @@ void EventReportWidget::tabletEvent(QTabletEvent *event)
qDebug() << "Tablet event, type = " << type
<< " position = " << event->pos()
- << " global position = " << event->globalPos();
+ << " global position = " << event->globalPos()
+ << " cursor at " << QCursor::pos();
}
void EventReportWidget::outputMouseEvent(QMouseEvent *event)
@@ -144,7 +208,18 @@ void EventReportWidget::outputMouseEvent(QMouseEvent *event)
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
- EventReportWidget widget;
- widget.show();
+ QMainWindow mainWindow;
+ mainWindow.setWindowTitle(QString::fromLatin1("Tablet Test %1").arg(QT_VERSION_STR));
+ EventReportWidget *widget = new EventReportWidget;
+ widget->setMinimumSize(640, 480);
+ QMenu *fileMenu = mainWindow.menuBar()->addMenu("File");
+ QObject::connect(fileMenu->addAction("Clear"), SIGNAL(triggered()), widget, SLOT(clearPoints()));
+ QAction *quitAction = fileMenu->addAction("Quit");
+ QObject::connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+ quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
+ mainWindow.setCentralWidget(widget);
+ mainWindow.show();
return app.exec();
}
+
+#include "main.moc"
diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.cpp b/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.cpp
new file mode 100644
index 0000000000..463366433c
--- /dev/null
+++ b/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets/QtWidgets>
+
+const int rowCount = 2000;
+
+class TableDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ TableDialog() : model(rowCount, 3) { create(); }
+ void create()
+ {
+ resize(1000, 233);
+ gridLayout = new QGridLayout(this);
+ tableView = new QTableView(this);
+
+ gridLayout->addWidget(tableView, 0, 0, 2, 1);
+ spinPrecision = new QSpinBox(this);
+ gridLayout->addWidget(spinPrecision, 0, 1, 1, 1);
+ verticalSpacer = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding);
+ gridLayout->addItem(verticalSpacer, 1, 1, 1, 1);
+
+ QString ii = QString::fromLatin1("ii");
+ QStringList is;
+ spinPrecision->setMinimum(-1);
+ spinPrecision->setMaximum(rowCount + 2);
+ for (int u = 0; u < rowCount; ++u) {
+ if (u % 25 == 0)
+ ii += QString::fromLatin1("i");
+ else
+ ii[ii.length() - 1] = QChar::fromLatin1('a' + (u % 25));
+ ii[ii.length() - 2] = QChar::fromLatin1('i');
+ is.append(ii);
+ }
+
+ for (int u = 0; u < rowCount; ++u) {
+ QString col1;
+ col1 = QString::fromLatin1("Row: %1").arg(u);
+ model.setData(model.index(u, 0), col1);
+ model.setData(model.index(u, 1), is[u]);
+ model.setData(model.index(u, 2), is[rowCount - u -1]);
+ }
+ tableView->setModel(&model);
+
+ tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
+ tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
+ tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
+ spinPrecision->setValue(tableView->horizontalHeader()->resizeContentsPrecision());
+ connect(spinPrecision, SIGNAL(valueChanged(int)), this, SLOT(slotValueChanged(int)));
+ } // setupUi
+protected slots:
+ void slotValueChanged(int newval);
+protected:
+ QGridLayout *gridLayout;
+ QTableView *tableView;
+ QSpinBox *spinPrecision;
+ QSpacerItem *verticalSpacer;
+ QStandardItemModel model;
+};
+
+void TableDialog::slotValueChanged(int newval)
+{
+ tableView->horizontalHeader()->setResizeContentsPrecision(newval, true);
+}
+
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ TableDialog d1;
+ d1.show();
+ app.exec();
+}
+
+#include "testtable1.moc"
diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.pro b/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.pro
new file mode 100644
index 0000000000..e07f40bc2f
--- /dev/null
+++ b/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.pro
@@ -0,0 +1,2 @@
+SOURCES = testtable1.cpp
+QT += widgets
diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.cpp b/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.cpp
new file mode 100644
index 0000000000..027801d528
--- /dev/null
+++ b/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets/QtWidgets>
+
+const int columnCount = 1500;
+
+class TableDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ TableDialog() : model(2, columnCount) { create(); }
+ void create()
+ {
+ resize(1200, 400);
+ gridLayout = new QGridLayout(this);
+ tableView = new QTableView(this);
+
+ gridLayout->addWidget(tableView, 0, 0, 2, 1);
+ spinPrecision = new QSpinBox(this);
+ gridLayout->addWidget(spinPrecision, 0, 1, 1, 1);
+ verticalSpacer = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding);
+ gridLayout->addItem(verticalSpacer, 1, 1, 1, 1);
+
+ QString ii = QString::fromLatin1("ii");
+ QStringList is;
+ spinPrecision->setMinimum(-1);
+ spinPrecision->setMaximum(columnCount + 2);
+
+ QFont f = QApplication::font();
+ for (int u = 0; u < columnCount; ++u) {
+ int size = 10 + (u % 63);
+ f.setPixelSize(size);
+ QString col;
+ if (u % 50 < 25)
+ col = QChar::fromLatin1('a' + (u % 25));
+ else
+ col = QChar::fromLatin1('A' + (u % 25));
+
+ int v = columnCount - u - 1;
+ model.setData(model.index(0, u), col);
+ model.setData(model.index(1, v), col);
+
+ model.setData(model.index(0, u), f, Qt::FontRole);
+ model.setData(model.index(1, v), f, Qt::FontRole);
+ }
+ tableView->setModel(&model);
+
+ for (int u = 0; u < columnCount; ++ u)
+ tableView->horizontalHeader()->resizeSection(u, 60);
+
+ // Make last index in first row a bit special
+ f.setPixelSize(96);
+ model.setData(model.index(0, columnCount - 1), f, Qt::FontRole);
+ model.setData(model.index(0, columnCount - 1), QString::fromLatin1("qI"));
+ tableView->horizontalHeader()->resizeSection(columnCount - 1, 140);
+
+ tableView->verticalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
+ tableView->verticalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
+ spinPrecision->setValue(tableView->verticalHeader()->resizeContentsPrecision());
+ connect(spinPrecision, SIGNAL(valueChanged(int)), this, SLOT(slotValueChanged(int)));
+ } // setupUi
+protected slots:
+ void slotValueChanged(int newval);
+protected:
+ QGridLayout *gridLayout;
+ QTableView *tableView;
+ QSpinBox *spinPrecision;
+ QSpacerItem *verticalSpacer;
+ QStandardItemModel model;
+};
+
+void TableDialog::slotValueChanged(int newval)
+{
+ tableView->verticalHeader()->setResizeContentsPrecision(newval, true);
+}
+
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ TableDialog d1;
+ d1.show();
+ app.exec();
+}
+
+#include "testtable2.moc"
diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.pro b/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.pro
new file mode 100644
index 0000000000..b887fcb14b
--- /dev/null
+++ b/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.pro
@@ -0,0 +1,2 @@
+SOURCES = testtable2.cpp
+QT += widgets
diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.cpp b/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.cpp
new file mode 100644
index 0000000000..c48d933fcd
--- /dev/null
+++ b/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets/QtWidgets>
+
+class TreeDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ TreeDialog() { create(); }
+protected:
+ void create()
+ {
+ resize(1000, 233);
+ gridLayout = new QGridLayout(this);
+ treeWidget = new QTreeWidget(this);
+
+ gridLayout->addWidget(treeWidget, 0, 0, 2, 1);
+ spinPrecision = new QSpinBox(this);
+ gridLayout->addWidget(spinPrecision, 0, 1, 1, 1);
+ verticalSpacer = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding);
+ gridLayout->addItem(verticalSpacer, 1, 1, 1, 1);
+
+ QStringList itemInfo("Col1");
+ itemInfo.append("Col2");
+ itemInfo.append("Col3");
+ itemInfo.append("Dummy");
+ // Developer no. could also have been social security number og some other id.
+ treeWidget->setHeaderLabels(itemInfo);
+
+ QStringList sl1("This is Root Item");
+ sl1.append("i");
+ QTreeWidgetItem *rootitem = new QTreeWidgetItem(treeWidget, sl1);
+
+ QStringList sl2("This is Child1 Item");
+ sl2.append("WW");
+ QTreeWidgetItem *child1 = new QTreeWidgetItem(rootitem, sl2);
+
+ QString ii = QString::fromLatin1("ii");
+ QStringList is;
+ const int rowCount = 3000;
+ spinPrecision->setMinimum(-1);
+ spinPrecision->setMaximum(rowCount + 5);
+ for (int u = 0; u < rowCount; ++u) {
+ if (u % 25 == 0)
+ ii += QString::fromLatin1("i");
+ else
+ ii[ii.length() - 1] = QChar::fromLatin1('a' + (u % 25));
+ ii[ii.length() - 2] = QChar::fromLatin1('i');
+ is.append(ii);
+ }
+
+ for (int u = 0; u < rowCount - 2; ++u) { // -2 since we have rootitem and child1
+ QString col1;
+ col1 = QString::fromLatin1("This is child item %1").arg(u + 2);
+
+ QStringList sl(col1);
+ sl.append(is[u]);
+ sl.append(is[rowCount - u - 1]);
+
+ if (u > 500)
+ new QTreeWidgetItem(rootitem, sl);
+ else
+ new QTreeWidgetItem(child1, sl);
+ }
+ treeWidget->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
+ treeWidget->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
+ treeWidget->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
+ spinPrecision->setValue(treeWidget->header()->resizeContentsPrecision());
+ connect(spinPrecision, SIGNAL(valueChanged(int)), this, SLOT(slotValueChanged(int)));
+ } // setupUi
+protected slots:
+ void slotValueChanged(int newval);
+protected:
+ QGridLayout *gridLayout;
+ QTreeWidget *treeWidget;
+ QSpinBox *spinPrecision;
+ QSpacerItem *verticalSpacer;
+};
+
+void TreeDialog::slotValueChanged(int newval)
+{
+ treeWidget->header()->setResizeContentsPrecision(newval, true);
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ TreeDialog d1;
+ d1.show();
+ app.exec();
+}
+
+#include "testtree.moc"
diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.pro b/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.pro
new file mode 100644
index 0000000000..c062586eac
--- /dev/null
+++ b/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.pro
@@ -0,0 +1,2 @@
+SOURCES = testtree.cpp
+QT += widgets
diff --git a/tests/manual/widgets/itemviews/itemviews.pro b/tests/manual/widgets/itemviews/itemviews.pro
index 58b02bfc0d..6b91531a87 100644
--- a/tests/manual/widgets/itemviews/itemviews.pro
+++ b/tests/manual/widgets/itemviews/itemviews.pro
@@ -1,2 +1,2 @@
TEMPLATE = subdirs
-SUBDIRS = delegate qheaderview qtreeview
+SUBDIRS = delegate qheaderview qtreeview qtreewidget
diff --git a/tests/manual/widgets/itemviews/qtreeview/main.cpp b/tests/manual/widgets/itemviews/qtreeview/main.cpp
index 296ba6bcbf..22b4e07f75 100644
--- a/tests/manual/widgets/itemviews/qtreeview/main.cpp
+++ b/tests/manual/widgets/itemviews/qtreeview/main.cpp
@@ -39,17 +39,34 @@
**
****************************************************************************/
-
-#include <QtWidgets/QFileSystemModel>
-#include <QtWidgets/QtWidgets>
+#include <QtWidgets>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
- QFileSystemModel *model = new QFileSystemModel;
- model->setRootPath(QDir::currentPath());
- QTreeView *tree = new QTreeView();
- tree->setModel(model);
- tree->show();
- app.exec();
+ QFileSystemModel model;
+ QWidget window;
+ QTreeView *tree = new QTreeView(&window);
+ tree->setMaximumSize(1000, 600);
+
+ QHBoxLayout *layout = new QHBoxLayout;
+ layout->setSizeConstraint(QLayout::SetFixedSize);
+ layout->addWidget(tree);
+
+ window.setLayout(layout);
+ model.setRootPath("");
+ tree->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
+ tree->setModel(&model);
+
+ tree->setAnimated(false);
+ tree->setIndentation(20);
+ tree->setSortingEnabled(true);
+ tree->header()->setStretchLastSection(false);
+
+ window.setWindowTitle(QObject::tr("Dir View"));
+ tree->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+
+ window.show();
+
+ return app.exec();
}
diff --git a/tests/manual/widgets/itemviews/qtreewidget/main.cpp b/tests/manual/widgets/itemviews/qtreewidget/main.cpp
new file mode 100644
index 0000000000..9428113250
--- /dev/null
+++ b/tests/manual/widgets/itemviews/qtreewidget/main.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QVBoxLayout>
+#include <QTreeWidget>
+#include <QGroupBox>
+#include <QRadioButton>
+#include <QDialog>
+#include <QApplication>
+#include <QHeaderView>
+
+class ExampleDlg : public QDialog
+{
+ Q_OBJECT
+public:
+ QVBoxLayout *groupLayout;
+ QVBoxLayout *dialogLayout;
+ QTreeWidget *treeWidget;
+ QGroupBox *groupBox;
+ QRadioButton *radioFirstName;
+ QRadioButton *radioLastName;
+ QRadioButton *radioDeveloperNo;
+ QRadioButton *radioTitle;
+
+ ExampleDlg() : QDialog(0)
+ {
+ dialogLayout = new QVBoxLayout(this);
+ treeWidget = new QTreeWidget(this);
+ dialogLayout->addWidget(treeWidget);
+
+ groupBox = new QGroupBox(this);
+ groupLayout = new QVBoxLayout(groupBox);
+ radioFirstName = new QRadioButton("First Name", groupBox);
+ groupLayout->addWidget(radioFirstName);
+ radioLastName = new QRadioButton("Last Name", groupBox);
+ groupLayout->addWidget(radioLastName);
+ radioDeveloperNo = new QRadioButton("Developer No.", groupBox);
+ groupLayout->addWidget(radioDeveloperNo);
+ radioTitle = new QRadioButton("Title", groupBox);
+ groupLayout->addWidget(radioTitle);
+ dialogLayout->addWidget(groupBox);
+
+ QStringList item1sl("Barry");
+ item1sl.append("Butter");
+ item1sl.append("12199");
+ item1sl.append("Key Maintainer");
+ QTreeWidgetItem *item1 = new QTreeWidgetItem(treeWidget, item1sl);
+
+ QStringList item2sl("Cordon");
+ item2sl.append("Rampsey");
+ item2sl.append("59299");
+ item2sl.append("Maintainer");
+ QTreeWidgetItem *item2 = new QTreeWidgetItem(item1, item2sl);
+
+ QStringList item3sl("Samuel le");
+ item3sl.append("Smackson");
+ item3sl.append("708");
+ item3sl.append("Contributer");
+ /* QTreeWidgetItem *item3 = */ new QTreeWidgetItem(item2, item3sl);
+
+ QStringList item4sl("Georg");
+ item4sl.append("Ambush");
+ item4sl.append("86999");
+ item4sl.append("Area Maintainer");
+ QTreeWidgetItem *item4 = new QTreeWidgetItem(item1, item4sl);
+
+ QStringList item5sl("Arne");
+ item5sl.append("Strassenleger");
+ item5sl.append("338999");
+ item5sl.append("Approver");
+ /* QTreeWidgetItem *item4 =*/ new QTreeWidgetItem(item4, item5sl);
+
+ treeWidget->setColumnCount(item2sl.size());
+ QStringList itemInfo("First Name");
+ itemInfo.append("Last Name");
+ itemInfo.append("Developer No.");
+ // Developer no. could also have been social security number og some other id.
+ itemInfo.append("Title");
+ treeWidget->setHeaderLabels(itemInfo);
+ radioFirstName->setChecked(true);
+
+ connect(radioFirstName, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool)));
+ connect(radioLastName, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool)));
+ connect(radioDeveloperNo, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool)));
+ connect(radioTitle, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool)));
+ treeWidget->setTreePosition(-1);
+ }
+
+ protected slots:
+ void fixDataInTree(bool checked)
+ {
+ if (!checked)
+ return;
+ int colInTree = 0; // first Name
+ if (radioLastName->isChecked())
+ colInTree = 1;
+ if (radioDeveloperNo->isChecked())
+ colInTree = 2;
+ if (radioTitle->isChecked())
+ colInTree = 3;
+ treeWidget->header()->swapSections(0, treeWidget->header()->visualIndex(colInTree));
+ }
+};
+
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ ExampleDlg d;
+ d.show();
+ app.exec();
+}
+
+#include "main.moc"
diff --git a/tests/manual/widgets/itemviews/qtreewidget/qtreewidgettest.pro b/tests/manual/widgets/itemviews/qtreewidget/qtreewidgettest.pro
new file mode 100644
index 0000000000..4b1da9be38
--- /dev/null
+++ b/tests/manual/widgets/itemviews/qtreewidget/qtreewidgettest.pro
@@ -0,0 +1,4 @@
+TEMPLATE = app
+SOURCES = main.cpp
+QT += widgets core-private
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/manual/widgets/kernel/kernel.pro b/tests/manual/widgets/kernel/kernel.pro
new file mode 100644
index 0000000000..968d71724f
--- /dev/null
+++ b/tests/manual/widgets/kernel/kernel.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = qtooltip sizeonhide
diff --git a/tests/manual/widgets/kernel/qtooltip/main.cpp b/tests/manual/widgets/kernel/qtooltip/main.cpp
new file mode 100644
index 0000000000..a7a2b9915c
--- /dev/null
+++ b/tests/manual/widgets/kernel/qtooltip/main.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QTest>
+#include <QDialog>
+#include <QToolTip>
+#include <QLabel>
+#include <QPushButton>
+#include <QVBoxLayout>
+#include <QProxyStyle>
+#include <QSpinBox>
+
+class QToolTipTest : public QProxyStyle
+{
+ Q_OBJECT
+public:
+ QToolTipTest() : QProxyStyle()
+ {
+ wakeTime = QApplication::style()->styleHint(SH_ToolTip_WakeUpDelay);
+ sleepTime = QApplication::style()->styleHint(SH_ToolTip_FallAsleepDelay);
+ }
+
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const
+ {
+ switch (hint) {
+ case SH_ToolTip_WakeUpDelay:
+ return wakeTime;
+ case SH_ToolTip_FallAsleepDelay:
+ return sleepTime;
+ default:
+ return QProxyStyle::styleHint(hint, option, widget, returnData);
+ }
+ }
+
+public slots:
+ void setWakeTime(int wake) { wakeTime = wake; }
+ void setSleepTime(int sleep) { sleepTime = sleep; }
+protected:
+ int wakeTime;
+ int sleepTime;
+};
+
+class TestDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ TestDialog(QToolTipTest *s);
+ QToolTipTest *style;
+protected slots:
+ void showSomeToolTips();
+};
+
+void TestDialog::showSomeToolTips()
+{
+ QPoint p(100 + 20, 100 + 20);
+
+ for (int u = 1; u < 20; u += 5) {
+ QString s = tr("Seconds: ") + QString::number(u);
+ QToolTip::showText(p, s, 0, QRect(), 1000 * u);
+ QTest::qWait((u + 1) * 1000);
+ }
+
+ QToolTip::showText(p, tr("Seconds: 2"), 0, QRect(), 2000);
+ QTest::qWait(3000);
+
+ QToolTip::showText(p, tr("Standard label"), 0, QRect());
+ QTest::qWait(12000);
+}
+
+TestDialog::TestDialog(QToolTipTest *s) : style(s)
+{
+ // Notice that these tool tips will disappear if another tool tip is shown.
+ QLabel *label1 = new QLabel(tr("Tooltip - Only two seconds display"));
+ label1->setToolTip(tr("2 seconds display"));
+ label1->setToolTipDuration(2000);
+ Q_ASSERT(label1->toolTipDuration() == 2000);
+
+ QLabel *label2 = new QLabel(tr("Tooltip - 30 seconds display time"));
+ label2->setToolTip(tr("30 seconds display"));
+ label2->setToolTipDuration(30000);
+
+ QPushButton *pb = new QPushButton(tr("&Test"));
+ pb->setToolTip(tr("Show some tool tips."));
+ Q_ASSERT(pb->toolTipDuration() == -1);
+ connect(pb, SIGNAL(clicked()), this, SLOT(showSomeToolTips()));
+
+ QLabel *wakeLabel = new QLabel(tr("Wake Delay:"));
+ QSpinBox *wakeSpinBox = new QSpinBox();
+ wakeSpinBox->setRange(0, 100000);
+ wakeSpinBox->setValue(style->styleHint(QStyle::SH_ToolTip_WakeUpDelay));
+ connect(wakeSpinBox, SIGNAL(valueChanged(int)), style, SLOT(setWakeTime(int)));
+
+ QLabel *sleepLabel = new QLabel(tr("Sleep Delay:"));
+ QSpinBox *sleepSpinBox = new QSpinBox();
+ sleepSpinBox->setRange(0, 100000);
+ sleepSpinBox->setValue(style->styleHint(QStyle::SH_ToolTip_FallAsleepDelay));
+ connect(sleepSpinBox, SIGNAL(valueChanged(int)), style, SLOT(setSleepTime(int)));
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(label1);
+ layout->addWidget(label2);
+ layout->addWidget(pb);
+ layout->addWidget(wakeLabel);
+ layout->addWidget(wakeSpinBox);
+ layout->addWidget(wakeLabel);
+ layout->addWidget(sleepLabel);
+ layout->addWidget(sleepSpinBox);
+
+ setLayout(layout);
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ QToolTipTest *style = new QToolTipTest();
+ QApplication::setStyle(style);
+ TestDialog dlg(style);
+ dlg.show();
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/tests/manual/widgets/kernel/qtooltip/main.pro b/tests/manual/widgets/kernel/qtooltip/main.pro
new file mode 100644
index 0000000000..dac880a10e
--- /dev/null
+++ b/tests/manual/widgets/kernel/qtooltip/main.pro
@@ -0,0 +1,2 @@
+SOURCES = main.cpp
+QT += widgets testlib
diff --git a/tests/manual/widgets/kernel/sizeonhide/main.cpp b/tests/manual/widgets/kernel/sizeonhide/main.cpp
new file mode 100644
index 0000000000..e8b95dfe28
--- /dev/null
+++ b/tests/manual/widgets/kernel/sizeonhide/main.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Thorbjørn Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+class KeepSizeExampleDlg : public QDialog
+{
+ Q_OBJECT
+public:
+ QGridLayout *gridLayout;
+ QHBoxLayout *horizontalLayout;
+ QVBoxLayout *verticalLayout;
+ QCheckBox *checkBox;
+ QCheckBox *checkBox2;
+ QCheckBox *checkBox3;
+ QCheckBox *checkBox4;
+ QGroupBox *groupBox;
+ QVBoxLayout *verticalLayout2;
+ QRadioButton *radioButton;
+ QRadioButton *radioButton2;
+ QRadioButton *radioButton3;
+ QTableView *tableView;
+ QPushButton *pushButton;
+ QSpacerItem *horizontalSpacer;
+
+ KeepSizeExampleDlg()
+ {
+ QWidget *form = this;
+ form->resize(408, 295);
+ gridLayout = new QGridLayout(form);
+ horizontalLayout = new QHBoxLayout();
+ verticalLayout = new QVBoxLayout();
+ checkBox = new QCheckBox(form);
+ verticalLayout->addWidget(checkBox);
+ checkBox2 = new QCheckBox(form);
+ verticalLayout->addWidget(checkBox2);
+ checkBox3 = new QCheckBox(form);
+ verticalLayout->addWidget(checkBox3);
+ checkBox4 = new QCheckBox(form);
+ verticalLayout->addWidget(checkBox4);
+ horizontalLayout->addLayout(verticalLayout);
+ groupBox = new QGroupBox(form);
+ verticalLayout2 = new QVBoxLayout(groupBox);
+ radioButton = new QRadioButton(groupBox);
+ verticalLayout2->addWidget(radioButton);
+ radioButton2 = new QRadioButton(groupBox);
+ verticalLayout2->addWidget(radioButton2);
+ radioButton3 = new QRadioButton(groupBox);
+ verticalLayout2->addWidget(radioButton3);
+ horizontalLayout->addWidget(groupBox);
+ gridLayout->addLayout(horizontalLayout, 0, 0, 1, 2);
+ tableView = new QTableView(form);
+ gridLayout->addWidget(tableView, 1, 0, 1, 2);
+ pushButton = new QPushButton(form);
+ gridLayout->addWidget(pushButton, 2, 0, 1, 1);
+ horizontalSpacer = new QSpacerItem(340, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ gridLayout->addItem(horizontalSpacer, 2, 1, 1, 1);
+ checkBox->setText(QString::fromUtf8("CheckBox1"));
+ checkBox2->setText(QString::fromUtf8("CheckBox2"));
+ checkBox3->setText(QString::fromUtf8("CheckBox - for client A only"));
+ checkBox4->setText(QString::fromUtf8("CheckBox - also for client A"));
+ groupBox->setTitle(QString::fromUtf8("Mode"));
+ radioButton->setText(QString::fromUtf8("Mode 1"));
+ radioButton2->setText(QString::fromUtf8("Mode 2"));
+ radioButton3->setText(QString::fromUtf8("Mode 3"));
+ pushButton->setText(QString::fromUtf8("&Hide/Show"));
+
+ QObject::connect(pushButton, SIGNAL(clicked()), this, SLOT(showOrHide()));
+ }
+
+ protected slots:
+ void showOrHide()
+ {
+ if (checkBox3->isVisible()) {
+ checkBox3->hide();
+ checkBox4->hide();
+ } else {
+ checkBox3->show();
+ checkBox4->show();
+ }
+ }
+};
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ KeepSizeExampleDlg d;
+ QSizePolicy policyKeepSpace = d.checkBox3->sizePolicy();
+ policyKeepSpace.setRetainSizeWhenHidden(true);
+ d.checkBox3->setSizePolicy(policyKeepSpace);
+ d.checkBox4->setSizePolicy(policyKeepSpace);
+ d.show();
+ app.exec();
+}
+
+#include "main.moc"
diff --git a/tests/manual/widgets/kernel/sizeonhide/sizeonhide.pro b/tests/manual/widgets/kernel/sizeonhide/sizeonhide.pro
new file mode 100644
index 0000000000..1969392ab3
--- /dev/null
+++ b/tests/manual/widgets/kernel/sizeonhide/sizeonhide.pro
@@ -0,0 +1,3 @@
+TEMPLATE = app
+SOURCES = main.cpp
+QT += widgets core-private
diff --git a/tests/manual/widgets/qgraphicsview/rubberband/rubberbandtest.cpp b/tests/manual/widgets/qgraphicsview/rubberband/rubberbandtest.cpp
index aec2479239..bb05570f18 100644
--- a/tests/manual/widgets/qgraphicsview/rubberband/rubberbandtest.cpp
+++ b/tests/manual/widgets/qgraphicsview/rubberband/rubberbandtest.cpp
@@ -49,7 +49,7 @@ public:
setFlags(QGraphicsItem::ItemIsSelectable);
}
- void paint(QPainter *painter, const QStyleOptionGraphicsItem * /* option*/, QWidget * /*widget*/)
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem * /* option*/, QWidget * /*widget*/) Q_DECL_OVERRIDE
{
if (isSelected())
painter->fillRect(rect(), QColor(255, 0, 0));
@@ -68,7 +68,7 @@ public:
connect(this, SIGNAL(rubberBandChanged(QRect, QPointF, QPointF)), this, SLOT(updateRubberbandInfo(QRect, QPointF, QPointF)));
}
protected:
- void mouseMoveEvent(QMouseEvent *event)
+ void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE
{
QGraphicsView::mouseMoveEvent(event);
diff --git a/tests/manual/widgets/widgets.pro b/tests/manual/widgets/widgets.pro
index 4e2e4c7cee..e9dcdf39e7 100644
--- a/tests/manual/widgets/widgets.pro
+++ b/tests/manual/widgets/widgets.pro
@@ -1,2 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS = itemviews qgraphicsview
+SUBDIRS = itemviews qgraphicsview kernel
+
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index c7477abe99..430dae5e87 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -135,23 +135,9 @@ Configure::Configure(int& argc, char** argv)
const QString installPath = buildPath;
#endif
if (sourceDir != buildDir) { //shadow builds!
- cout << "Preparing build tree..." << endl;
QDir(buildPath).mkpath("bin");
- //copy the mkspecs
buildDir.mkpath("mkspecs");
- if (!Environment::cpdir(sourcePath + "/mkspecs", buildPath + "/mkspecs")){
- cout << "Couldn't copy mkspecs!" << sourcePath << " " << buildPath << endl;
- dictionary["DONE"] = "error";
- return;
- }
-
- buildDir.mkpath("doc");
- if (!Environment::cpdir(sourcePath + "/doc/global", buildPath + "/doc/global")) {
- cout << "Couldn't copy global documentation!" << sourcePath << " " << buildPath << endl;
- dictionary["DONE"] = "error";
- return;
- }
}
defaultBuildParts << QStringLiteral("libs") << QStringLiteral("tools") << QStringLiteral("examples");
@@ -2819,6 +2805,14 @@ void Configure::generateCachefile()
moduleStream << "QT_SKIP_MODULES += " << skipModules.join(' ') << endl;
moduleStream << endl;
+ moduleStream << "host_build {" << endl;
+ moduleStream << " QT_CPU_FEATURES." << dictionary["QT_HOST_ARCH"] <<
+ " = " << dictionary["QT_HOST_CPU_FEATURES"] << endl;
+ moduleStream << "} else {" << endl;
+ moduleStream << " QT_CPU_FEATURES." << dictionary["QT_ARCH"] <<
+ " = " << dictionary["QT_CPU_FEATURES"] << endl;
+ moduleStream << "}" << endl;
+
if (dictionary["QT_EDITION"] != "QT_EDITION_OPENSOURCE")
moduleStream << "DEFINES *= QT_EDITION=QT_EDITION_DESKTOP" << endl;
@@ -3099,15 +3093,17 @@ void Configure::generateQConfigPri()
configStream << " qpa";
configStream << endl;
- configStream << "QT_ARCH = " << dictionary["QT_ARCH"] << endl;
- configStream << "QT_HOST_ARCH = " << dictionary["QT_HOST_ARCH"] << endl;
- configStream << "QT_CPU_FEATURES = " << dictionary["QT_CPU_FEATURES"] << endl;
- configStream << "QT_HOST_CPU_FEATURES = " << dictionary["QT_HOST_CPU_FEATURES"] << endl;
+ configStream << "host_build {" << endl;
+ configStream << " QT_ARCH = " << dictionary["QT_HOST_ARCH"] << endl;
+ configStream << " QT_TARGET_ARCH = " << dictionary["QT_ARCH"] << endl;
+ configStream << "} else {" << endl;
+ configStream << " QT_ARCH = " << dictionary["QT_ARCH"] << endl;
if (dictionary.contains("XQMAKESPEC") && !dictionary["XQMAKESPEC"].startsWith("wince")) {
// FIXME: add detection
- configStream << "QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib" << endl;
- configStream << "QMAKE_DEFAULT_INCDIRS = /usr/include /usr/local/include" << endl;
+ configStream << " QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib" << endl;
+ configStream << " QMAKE_DEFAULT_INCDIRS = /usr/include /usr/local/include" << endl;
}
+ configStream << "}" << endl;
if (dictionary["QT_EDITION"].contains("OPENSOURCE"))
configStream << "QT_EDITION = " << QLatin1String("OpenSource") << endl;
else
@@ -3867,6 +3863,9 @@ void Configure::buildQmake()
QTextStream confStream(&confFile);
confStream << "[EffectivePaths]" << endl
<< "Prefix=.." << endl;
+ if (sourcePath != buildPath)
+ confStream << "[EffectiveSourcePaths]" << endl
+ << "Prefix=" << sourcePath << endl;
confStream.flush();
confFile.close();
diff --git a/util/local_database/enumdata.py b/util/local_database/enumdata.py
index b5935ca45f..256866e177 100644
--- a/util/local_database/enumdata.py
+++ b/util/local_database/enumdata.py
@@ -616,7 +616,8 @@ country_list = {
253 : [ "TristanDaCunha", "TA" ],
254 : [ "SouthSudan", "SS" ],
255 : [ "Bonaire", "BQ" ],
- 256 : [ "SintMaarten", "SX" ]
+ 256 : [ "SintMaarten", "SX" ],
+ 257 : [ "Kosovo", "XK" ]
}
script_list = {
diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp
index 5affaeb59f..a4d3e0f377 100644
--- a/util/unicode/main.cpp
+++ b/util/unicode/main.cpp
@@ -689,8 +689,9 @@ static const char *property_string =
" ushort titleCaseSpecial : 1;\n"
" ushort caseFoldSpecial : 1;\n"
" ushort unicodeVersion : 4;\n"
- " ushort graphemeBreakClass : 8; /* 4 used */\n"
- " ushort wordBreakClass : 8; /* 4 used */\n"
+ " ushort nfQuickCheck : 8;\n" // could be narrowed
+ " ushort graphemeBreakClass : 4; /* 4 used */\n"
+ " ushort wordBreakClass : 4; /* 4 used */\n"
" ushort sentenceBreakClass : 8; /* 4 used */\n"
" ushort lineBreakClass : 8; /* 6 used */\n"
" ushort script : 8; /* 7 used */\n"
@@ -741,6 +742,7 @@ struct PropertyFlags {
&& sentenceBreakClass == o.sentenceBreakClass
&& lineBreakClass == o.lineBreakClass
&& script == o.script
+ && nfQuickCheck == o.nfQuickCheck
);
}
// from UnicodeData.txt
@@ -768,6 +770,8 @@ struct PropertyFlags {
SentenceBreakClass sentenceBreakClass;
LineBreakClass lineBreakClass;
int script;
+ // from DerivedNormalizationProps.txt
+ uchar nfQuickCheck;
};
@@ -873,6 +877,7 @@ struct UnicodeData {
p.wordBreakClass = WordBreak_Other;
p.sentenceBreakClass = SentenceBreak_Other;
p.script = QChar::Script_Unknown;
+ p.nfQuickCheck = 0;
propertyIndex = -1;
excludedComposition = false;
}
@@ -1270,9 +1275,12 @@ static void readDerivedNormalizationProps()
Q_ASSERT(l.size() >= 2);
QByteArray propName = l[1].trimmed();
- if (propName != "Full_Composition_Exclusion")
+ if (propName != "Full_Composition_Exclusion" &&
+ propName != "NFD_QC" && propName != "NFC_QC" &&
+ propName != "NFKD_QC" && propName != "NFKC_QC") {
// ###
continue;
+ }
QByteArray codes = l[0].trimmed();
codes.replace("..", ".");
@@ -1289,7 +1297,35 @@ static void readDerivedNormalizationProps()
for (int codepoint = from; codepoint <= to; ++codepoint) {
UnicodeData &d = UnicodeData::valueRef(codepoint);
- d.excludedComposition = true;
+ if (propName == "Full_Composition_Exclusion") {
+ d.excludedComposition = true;
+ } else {
+ Q_STATIC_ASSERT(QString::NormalizationForm_D == 0);
+ Q_STATIC_ASSERT(QString::NormalizationForm_C == 1);
+ Q_STATIC_ASSERT(QString::NormalizationForm_KD == 2);
+ Q_STATIC_ASSERT(QString::NormalizationForm_KC == 3);
+
+ QString::NormalizationForm form;
+ if (propName == "NFD_QC")
+ form = QString::NormalizationForm_D;
+ else if (propName == "NFC_QC")
+ form = QString::NormalizationForm_C;
+ else if (propName == "NFKD_QC")
+ form = QString::NormalizationForm_KD;
+ else// if (propName == "NFKC_QC")
+ form = QString::NormalizationForm_KC;
+
+ Q_ASSERT(l.size() == 3);
+ l[2] = l[2].trimmed();
+
+ enum { NFQC_YES = 0, NFQC_NO = 1, NFQC_MAYBE = 3 };
+ uchar ynm = (l[2] == "N" ? NFQC_NO : l[2] == "M" ? NFQC_MAYBE : NFQC_YES);
+ if (ynm == NFQC_MAYBE) {
+ // if this changes, we need to revise the normalizationQuickCheckHelper() implementation
+ Q_ASSERT(form == QString::NormalizationForm_C || form == QString::NormalizationForm_KC);
+ }
+ d.p.nfQuickCheck |= (ynm << (form << 1)); // 2 bits per NF
+ }
}
}
@@ -2246,8 +2282,11 @@ static QByteArray createPropertyInfo()
// " ushort unicodeVersion : 4;\n"
out += QByteArray::number( p.age );
out += ", ";
-// " ushort graphemeBreakClass : 8; /* 4 used */\n"
-// " ushort wordBreakClass : 8; /* 4 used */\n"
+// " ushort nfQuickCheck : 8;\n"
+ out += QByteArray::number( p.nfQuickCheck );
+ out += ", ";
+// " ushort graphemeBreakClass : 4; /* 4 used */\n"
+// " ushort wordBreakClass : 4; /* 4 used */\n"
// " ushort sentenceBreakClass : 8; /* 4 used */\n"
// " ushort lineBreakClass : 8; /* 6 used */\n"
out += QByteArray::number( p.graphemeBreakClass );