summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES.cpp2
-rw-r--r--src/3rdparty/libjpeg/LICENSE29
-rw-r--r--src/3rdparty/libjpeg/jconfig.h18
-rw-r--r--src/3rdparty/libjpeg/qt_attribution.json4
-rw-r--r--src/3rdparty/libjpeg/src/ChangeLog.md70
-rw-r--r--src/3rdparty/libjpeg/src/jconfig.h.in28
-rw-r--r--src/3rdparty/libjpeg/src/jdcolor.c2
-rw-r--r--src/3rdparty/libjpeg/src/jdmerge.c2
-rw-r--r--src/3rdparty/libjpeg/src/jquant1.c2
-rw-r--r--src/3rdparty/libjpeg/src/jversion.h6
-rw-r--r--src/3rdparty/pcre2/qt_attribution.json4
-rw-r--r--src/3rdparty/sqlite.pri2
-rw-r--r--src/3rdparty/sqlite/qt_attribution.json4
-rw-r--r--src/3rdparty/sqlite/sqlite3.c8840
-rw-r--r--src/3rdparty/sqlite/sqlite3.h79
-rw-r--r--src/android/jar/jar.pro1
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java42
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java46
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java13
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java2
-rw-r--r--src/android/templates/AndroidManifest.xml2
-rw-r--r--src/corelib/Qt5CoreMacros.cmake2
-rw-r--r--src/corelib/animation/qabstractanimation.cpp2
-rw-r--r--src/corelib/animation/qabstractanimation.h7
-rw-r--r--src/corelib/animation/qpropertyanimation.cpp4
-rw-r--r--src/corelib/codecs/qbig5codec_p.h20
-rw-r--r--src/corelib/codecs/qtextcodec.cpp16
-rw-r--r--src/corelib/configure.json21
-rw-r--r--src/corelib/corelib.pro1
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp6
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp2
-rw-r--r--src/corelib/doc/snippets/resource-system/mainwindow.cpp8
-rw-r--r--src/corelib/doc/src/containers.qdoc5
-rw-r--r--src/corelib/doc/src/datastreamformat.qdoc402
-rw-r--r--src/corelib/doc/src/objectmodel/metaobjects.qdoc2
-rw-r--r--src/corelib/doc/src/resource-system.qdoc67
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h5
-rw-r--r--src/corelib/global/qfloat16.h2
-rw-r--r--src/corelib/global/qglobal.cpp99
-rw-r--r--src/corelib/global/qglobal.h30
-rw-r--r--src/corelib/global/qglobal_p.h10
-rw-r--r--src/corelib/global/qlogging.cpp2
-rw-r--r--src/corelib/global/qlogging.h4
-rw-r--r--src/corelib/global/qnamespace.h12
-rw-r--r--src/corelib/global/qprocessordetection.h1
-rw-r--r--src/corelib/global/qtypeinfo.h28
-rw-r--r--src/corelib/io/io.pri2
-rw-r--r--src/corelib/io/qabstractfileengine_p.h4
-rw-r--r--src/corelib/io/qbuffer.cpp4
-rw-r--r--src/corelib/io/qdebug.cpp142
-rw-r--r--src/corelib/io/qdebug.h7
-rw-r--r--src/corelib/io/qdir.cpp7
-rw-r--r--src/corelib/io/qdir.h6
-rw-r--r--src/corelib/io/qfile.cpp20
-rw-r--r--src/corelib/io/qfile.h8
-rw-r--r--src/corelib/io/qfiledevice.cpp6
-rw-r--r--src/corelib/io/qfiledevice.h2
-rw-r--r--src/corelib/io/qfileinfo.cpp7
-rw-r--r--src/corelib/io/qfileinfo.h5
-rw-r--r--src/corelib/io/qfilesystemiterator_p.h2
-rw-r--r--src/corelib/io/qfilesystemwatcher_win_p.h6
-rw-r--r--src/corelib/io/qiodevice.cpp2
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice_p.h12
-rw-r--r--src/corelib/io/qprocess.cpp13
-rw-r--r--src/corelib/io/qprocess.h27
-rw-r--r--src/corelib/io/qresource.cpp308
-rw-r--r--src/corelib/io/qresource.h11
-rw-r--r--src/corelib/io/qresource_p.h56
-rw-r--r--src/corelib/io/qsettings.cpp50
-rw-r--r--src/corelib/io/qsettings.h12
-rw-r--r--src/corelib/io/qstandardpaths_android.cpp14
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp2
-rw-r--r--src/corelib/io/qt_attribution.json8
-rw-r--r--src/corelib/io/qurlquery.cpp8
-rw-r--r--src/corelib/io/qurlquery.h9
-rw-r--r--src/corelib/io/qurltlds_p.h27271
-rw-r--r--src/corelib/io/qwindowspipereader_p.h2
-rw-r--r--src/corelib/io/qwindowspipewriter_p.h2
-rw-r--r--src/corelib/itemmodels/itemmodels.pri17
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp25
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.h6
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel_p.h7
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.cpp12
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.h3
-rw-r--r--src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp750
-rw-r--r--src/corelib/itemmodels/qconcatenatetablesproxymodel.h100
-rw-r--r--src/corelib/itemmodels/qidentityproxymodel.cpp10
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp2
-rw-r--r--src/corelib/itemmodels/qstringlistmodel.cpp87
-rw-r--r--src/corelib/itemmodels/qstringlistmodel.h7
-rw-r--r--src/corelib/itemmodels/qtransposeproxymodel.cpp447
-rw-r--r--src/corelib/itemmodels/qtransposeproxymodel.h83
-rw-r--r--src/corelib/itemmodels/qtransposeproxymodel_p.h84
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp34
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib.cpp5
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp2
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp10
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h34
-rw-r--r--src/corelib/kernel/qjni_p.h2
-rw-r--r--src/corelib/kernel/qmetaobject.cpp20
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder_p.h2
-rw-r--r--src/corelib/kernel/qmetatype.cpp623
-rw-r--r--src/corelib/kernel/qmetatype.h10
-rw-r--r--src/corelib/kernel/qmimedata.cpp5
-rw-r--r--src/corelib/kernel/qobject.cpp54
-rw-r--r--src/corelib/kernel/qobject.h8
-rw-r--r--src/corelib/kernel/qobject_p.h6
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h2
-rw-r--r--src/corelib/kernel/qppsobject_p.h2
-rw-r--r--src/corelib/kernel/qsystemerror.cpp5
-rw-r--r--src/corelib/kernel/qtranslator.cpp33
-rw-r--r--src/corelib/kernel/qvariant.cpp4
-rw-r--r--src/corelib/kernel/qvariant.h4
-rw-r--r--src/corelib/mimetypes/mime/packages/freedesktop.org.xml4417
-rw-r--r--src/corelib/mimetypes/mimetypes.pri2
-rw-r--r--src/corelib/mimetypes/mimetypes.qrc2
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp64
-rw-r--r--src/corelib/mimetypes/qmimedatabase_p.h9
-rw-r--r--src/corelib/mimetypes/qmimeglobpattern.cpp6
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp6
-rw-r--r--src/corelib/mimetypes/qmimeprovider_p.h16
-rw-r--r--src/corelib/mimetypes/qmimetypeparser_p.h2
-rw-r--r--src/corelib/platform/platform.pri1
-rw-r--r--src/corelib/platform/wasm/qstdweb.cpp236
-rw-r--r--src/corelib/platform/wasm/qstdweb_p.h169
-rw-r--r--src/corelib/platform/wasm/wasm.pri3
-rw-r--r--src/corelib/plugin/qfactoryinterface.h3
-rw-r--r--src/corelib/plugin/qlibrary.cpp4
-rw-r--r--src/corelib/plugin/qplugin.h26
-rw-r--r--src/corelib/plugin/quuid.cpp2
-rw-r--r--src/corelib/serialization/qcborarray.cpp20
-rw-r--r--src/corelib/serialization/qcborarray.h7
-rw-r--r--src/corelib/serialization/qcborcommon.h5
-rw-r--r--src/corelib/serialization/qcbormap.cpp19
-rw-r--r--src/corelib/serialization/qcbormap.h14
-rw-r--r--src/corelib/serialization/qcborstream.cpp16
-rw-r--r--src/corelib/serialization/qcborvalue.cpp530
-rw-r--r--src/corelib/serialization/qcborvalue.h28
-rw-r--r--src/corelib/serialization/qdatastream.cpp12
-rw-r--r--src/corelib/serialization/qdatastream.h8
-rw-r--r--src/corelib/serialization/qjson_p.h2
-rw-r--r--src/corelib/serialization/qjsonarray.cpp33
-rw-r--r--src/corelib/serialization/qjsonarray.h7
-rw-r--r--src/corelib/serialization/qjsoncbor.cpp2
-rw-r--r--src/corelib/serialization/qjsondocument.cpp20
-rw-r--r--src/corelib/serialization/qjsondocument.h5
-rw-r--r--src/corelib/serialization/qjsonobject.cpp17
-rw-r--r--src/corelib/serialization/qjsonobject.h5
-rw-r--r--src/corelib/serialization/qjsonvalue.cpp75
-rw-r--r--src/corelib/serialization/qjsonvalue.h8
-rw-r--r--src/corelib/serialization/qtextstream.cpp6
-rw-r--r--src/corelib/serialization/qxmlstream.cpp8
-rw-r--r--src/corelib/serialization/qxmlstream.g14
-rw-r--r--src/corelib/statemachine/qabstractstate.cpp7
-rw-r--r--src/corelib/statemachine/qabstracttransition.cpp14
-rw-r--r--src/corelib/statemachine/qsignaleventgenerator_p.h2
-rw-r--r--src/corelib/statemachine/qsignaltransition_p.h2
-rw-r--r--src/corelib/statemachine/qstate.cpp3
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp4
-rw-r--r--src/corelib/thread/qfuturewatcher.cpp2
-rw-r--r--src/corelib/thread/qresultstore.cpp15
-rw-r--r--src/corelib/thread/qresultstore.h2
-rw-r--r--src/corelib/thread/qsemaphore.cpp4
-rw-r--r--src/corelib/thread/qthread_unix.cpp5
-rw-r--r--src/corelib/tools/qarraydata.cpp2
-rw-r--r--src/corelib/tools/qbytearray.cpp77
-rw-r--r--src/corelib/tools/qbytearraylist.cpp22
-rw-r--r--src/corelib/tools/qbytearraylist.h10
-rw-r--r--src/corelib/tools/qcache.qdoc6
-rw-r--r--src/corelib/tools/qcollator_p.h4
-rw-r--r--src/corelib/tools/qcommandlineparser.cpp2
-rw-r--r--src/corelib/tools/qdatetime.cpp22
-rw-r--r--src/corelib/tools/qfreelist_p.h2
-rw-r--r--src/corelib/tools/qlist.cpp25
-rw-r--r--src/corelib/tools/qlist.h93
-rw-r--r--src/corelib/tools/qlocale.cpp217
-rw-r--r--src/corelib/tools/qlocale.h23
-rw-r--r--src/corelib/tools/qlocale.qdoc651
-rw-r--r--src/corelib/tools/qlocale_data_p.h172
-rw-r--r--src/corelib/tools/qlocale_p.h8
-rw-r--r--src/corelib/tools/qmakearray_p.h4
-rw-r--r--src/corelib/tools/qoffsetstringarray_p.h198
-rw-r--r--src/corelib/tools/qshareddata.cpp6
-rw-r--r--src/corelib/tools/qsharedpointer.cpp10
-rw-r--r--src/corelib/tools/qsimd.cpp3
-rw-r--r--src/corelib/tools/qsimd_p.h8
-rw-r--r--src/corelib/tools/qstring.cpp100
-rw-r--r--src/corelib/tools/qstring.h6
-rw-r--r--src/corelib/tools/qstringlist.cpp52
-rw-r--r--src/corelib/tools/qstringlist.h26
-rw-r--r--src/corelib/tools/qstringview.cpp12
-rw-r--r--src/corelib/tools/qvector.h184
-rw-r--r--src/corelib/tools/tools.pri1
-rw-r--r--src/dbus/dbus.pro5
-rw-r--r--src/dbus/dbus_minimal_p.h32
-rw-r--r--src/dbus/doc/qtdbus.qdocconf2
-rw-r--r--src/dbus/qdbusargument.cpp2
-rw-r--r--src/dbus/qdbusargument.h13
-rw-r--r--src/dbus/qdbusargument_p.h4
-rw-r--r--src/dbus/qdbusconnection.h2
-rw-r--r--src/dbus/qdbusconnection_p.h22
-rw-r--r--src/dbus/qdbuserror.cpp145
-rw-r--r--src/dbus/qdbusintegrator.cpp89
-rw-r--r--src/dbus/qdbuspendingcall.cpp12
-rw-r--r--src/dbus/qdbuspendingcall.h2
-rw-r--r--src/dbus/qdbuspendingreply.cpp29
-rw-r--r--src/dbus/qdbuspendingreply.h3
-rw-r--r--src/dbus/qdbusreply.cpp2
-rw-r--r--src/dbus/qdbusreply.h4
-rw-r--r--src/dbus/qdbusservicewatcher.cpp11
-rw-r--r--src/dbus/qdbusutil.cpp30
-rw-r--r--src/dbus/qt_attribution.json2
-rw-r--r--src/gui/accessible/qaccessible.h2
-rw-r--r--src/gui/accessible/qaccessibleobject.h2
-rw-r--r--src/gui/configure.json12
-rw-r--r--src/gui/doc/snippets/clipboard/clipwindow.cpp9
-rw-r--r--src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp4
-rw-r--r--src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp9
-rw-r--r--src/gui/doc/snippets/code/src_gui_kernel_qguiapplication_x11.cpp4
-rw-r--r--src/gui/doc/snippets/draganddrop/mainwindow.cpp10
-rw-r--r--src/gui/doc/snippets/picture/picture.cpp10
-rw-r--r--src/gui/doc/snippets/qfontdatabase/main.cpp11
-rw-r--r--src/gui/doc/snippets/separations/screenwidget.cpp4
-rw-r--r--src/gui/doc/snippets/separations/viewer.cpp18
-rw-r--r--src/gui/doc/snippets/textblock-fragments/mainwindow.cpp8
-rw-r--r--src/gui/doc/snippets/textdocument-blocks/mainwindow.cpp8
-rw-r--r--src/gui/doc/snippets/textdocument-frames/mainwindow.cpp8
-rw-r--r--src/gui/doc/snippets/textdocument-lists/mainwindow.cpp5
-rw-r--r--src/gui/doc/snippets/textdocument-printing/mainwindow.cpp2
-rw-r--r--src/gui/doc/snippets/textdocument-selections/mainwindow.cpp5
-rw-r--r--src/gui/doc/snippets/textdocument-tables/mainwindow.cpp8
-rw-r--r--src/gui/doc/src/richtext.qdoc3
-rw-r--r--src/gui/gui.pro1
-rw-r--r--src/gui/image/qbitmap.cpp2
-rw-r--r--src/gui/image/qbitmap.h3
-rw-r--r--src/gui/image/qbmphandler.cpp2
-rw-r--r--src/gui/image/qbmphandler_p.h3
-rw-r--r--src/gui/image/qicon.cpp13
-rw-r--r--src/gui/image/qicon.h1
-rw-r--r--src/gui/image/qimage.cpp60
-rw-r--r--src/gui/image/qimage.h5
-rw-r--r--src/gui/image/qimage_conversions.cpp336
-rw-r--r--src/gui/image/qimage_p.h1
-rw-r--r--src/gui/image/qimageiohandler.cpp4
-rw-r--r--src/gui/image/qimageiohandler.h5
-rw-r--r--src/gui/image/qimagereader.cpp8
-rw-r--r--src/gui/image/qimagewriter.cpp6
-rw-r--r--src/gui/image/qimagewriter.h5
-rw-r--r--src/gui/image/qmovie.cpp2
-rw-r--r--src/gui/image/qpaintengine_pic_p.h2
-rw-r--r--src/gui/image/qpicture.cpp8
-rw-r--r--src/gui/image/qpixmap.cpp29
-rw-r--r--src/gui/image/qpixmap.h16
-rw-r--r--src/gui/image/qpixmap_raster.cpp3
-rw-r--r--src/gui/image/qpixmap_win.cpp2
-rw-r--r--src/gui/image/qpixmapcache.cpp12
-rw-r--r--src/gui/image/qpixmapcache.h4
-rw-r--r--src/gui/image/qpnghandler.cpp22
-rw-r--r--src/gui/image/qpnghandler_p.h2
-rw-r--r--src/gui/image/qppmhandler.cpp16
-rw-r--r--src/gui/image/qppmhandler_p.h2
-rw-r--r--src/gui/image/qxbmhandler.cpp2
-rw-r--r--src/gui/image/qxbmhandler_p.h2
-rw-r--r--src/gui/image/qxpmhandler.cpp2
-rw-r--r--src/gui/image/qxpmhandler_p.h2
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.cpp14
-rw-r--r--src/gui/itemmodels/qstandarditemmodel_p.h2
-rw-r--r--src/gui/kernel/qclipboard.cpp2
-rw-r--r--src/gui/kernel/qcursor.cpp8
-rw-r--r--src/gui/kernel/qdnd_p.h2
-rw-r--r--src/gui/kernel/qdrag.cpp2
-rw-r--r--src/gui/kernel/qdrag.h3
-rw-r--r--src/gui/kernel/qguiapplication.cpp75
-rw-r--r--src/gui/kernel/qguiapplication.h2
-rw-r--r--src/gui/kernel/qguiapplication_p.h6
-rw-r--r--src/gui/kernel/qkeymapper_p.h2
-rw-r--r--src/gui/kernel/qkeysequence.cpp6
-rw-r--r--src/gui/kernel/qoffscreensurface.h2
-rw-r--r--src/gui/kernel/qopenglcontext.cpp10
-rw-r--r--src/gui/kernel/qopenglcontext_p.h4
-rw-r--r--src/gui/kernel/qpalette.cpp6
-rw-r--r--src/gui/kernel/qpalette.h13
-rw-r--r--src/gui/kernel/qplatformclipboard.h3
-rw-r--r--src/gui/kernel/qplatformcursor.cpp2
-rw-r--r--src/gui/kernel/qplatformcursor.h2
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp24
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h5
-rw-r--r--src/gui/kernel/qplatformdrag.h4
-rw-r--r--src/gui/kernel/qplatformgraphicsbuffer.cpp2
-rw-r--r--src/gui/kernel/qplatformgraphicsbuffer.h2
-rw-r--r--src/gui/kernel/qplatforminputcontext.h2
-rw-r--r--src/gui/kernel/qplatformintegration.cpp40
-rw-r--r--src/gui/kernel/qplatformintegration.h12
-rw-r--r--src/gui/kernel/qplatformscreen.cpp4
-rw-r--r--src/gui/kernel/qplatformscreen.h4
-rw-r--r--src/gui/kernel/qplatformservices.h2
-rw-r--r--src/gui/kernel/qplatformsessionmanager.h4
-rw-r--r--src/gui/kernel/qplatformsurface.h2
-rw-r--r--src/gui/kernel/qplatformtheme.h4
-rw-r--r--src/gui/kernel/qplatformwindow.cpp4
-rw-r--r--src/gui/kernel/qplatformwindow.h4
-rw-r--r--src/gui/kernel/qscreen.cpp20
-rw-r--r--src/gui/kernel/qsessionmanager_p.h2
-rw-r--r--src/gui/kernel/qshortcutmap.cpp6
-rw-r--r--src/gui/kernel/qsimpledrag_p.h2
-rw-r--r--src/gui/kernel/qstylehints.cpp51
-rw-r--r--src/gui/kernel/qstylehints.h4
-rw-r--r--src/gui/kernel/qwindow.cpp34
-rw-r--r--src/gui/kernel/qwindow.h5
-rw-r--r--src/gui/kernel/qwindow_p.h2
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp9
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h2
-rw-r--r--src/gui/opengl/qopengl.cpp11
-rw-r--r--src/gui/opengl/qopenglcustomshaderstage_p.h2
-rw-r--r--src/gui/opengl/qopenglext.h11
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp2
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp7
-rw-r--r--src/gui/opengl/qopenglfunctions.h18
-rw-r--r--src/gui/opengl/qopenglpaintdevice.h2
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp5
-rw-r--r--src/gui/opengl/qopenglpaintengine_p.h2
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp6
-rw-r--r--src/gui/opengl/qopenglshaderprogram.h11
-rw-r--r--src/gui/opengl/qopengltexture.cpp2
-rw-r--r--src/gui/opengl/qopengltextureuploader.cpp28
-rw-r--r--src/gui/opengl/qopengltextureuploader_p.h2
-rw-r--r--src/gui/opengl/qopenglversionfunctions.h1
-rw-r--r--src/gui/painting/qbackingstore.cpp2
-rw-r--r--src/gui/painting/qblendfunctions.cpp18
-rw-r--r--src/gui/painting/qbrush.cpp2
-rw-r--r--src/gui/painting/qcolor.cpp71
-rw-r--r--src/gui/painting/qcolor.h18
-rw-r--r--src/gui/painting/qcompositionfunctions.cpp88
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp2
-rw-r--r--src/gui/painting/qdatabuffer_p.h2
-rw-r--r--src/gui/painting/qdrawhelper.cpp591
-rw-r--r--src/gui/painting/qdrawhelper_avx2.cpp308
-rw-r--r--src/gui/painting/qdrawhelper_mips_dsp.cpp2
-rw-r--r--src/gui/painting/qdrawhelper_mips_dsp_p.h2
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp98
-rw-r--r--src/gui/painting/qdrawhelper_neon_p.h2
-rw-r--r--src/gui/painting/qdrawhelper_p.h166
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp138
-rw-r--r--src/gui/painting/qdrawhelper_sse4.cpp81
-rw-r--r--src/gui/painting/qdrawhelper_ssse3.cpp169
-rw-r--r--src/gui/painting/qdrawhelper_x86_p.h7
-rw-r--r--src/gui/painting/qdrawingprimitive_sse2_p.h4
-rw-r--r--src/gui/painting/qimagescale_sse4.cpp4
-rw-r--r--src/gui/painting/qmemrotate.cpp14
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp129
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h1
-rw-r--r--src/gui/painting/qpaintengineex.cpp5
-rw-r--r--src/gui/painting/qpainter.cpp38
-rw-r--r--src/gui/painting/qpainter.h50
-rw-r--r--src/gui/painting/qpainter_p.h3
-rw-r--r--src/gui/painting/qpainterpath.cpp92
-rw-r--r--src/gui/painting/qpainterpath.h48
-rw-r--r--src/gui/painting/qpainterpath_p.h22
-rw-r--r--src/gui/painting/qpathclipper_p.h2
-rw-r--r--src/gui/painting/qpdf.cpp18
-rw-r--r--src/gui/painting/qpdf_p.h2
-rw-r--r--src/gui/painting/qpdfwriter.cpp2
-rw-r--r--src/gui/painting/qrgba64.h40
-rw-r--r--src/gui/painting/qstroker.cpp5
-rw-r--r--src/gui/painting/qstroker_p.h5
-rw-r--r--src/gui/painting/qtransform.cpp22
-rw-r--r--src/gui/painting/qtransform.h5
-rw-r--r--src/gui/painting/qvectorpath_p.h8
-rw-r--r--src/gui/platform/platform.pri1
-rw-r--r--src/gui/platform/wasm/qwasmlocalfileaccess.cpp169
-rw-r--r--src/gui/platform/wasm/qwasmlocalfileaccess_p.h78
-rw-r--r--src/gui/platform/wasm/wasm.pri3
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.h2
-rw-r--r--src/gui/text/qcssparser.cpp68
-rw-r--r--src/gui/text/qcssparser_p.h3
-rw-r--r--src/gui/text/qcssscanner.cpp847
-rw-r--r--src/gui/text/qfont.cpp156
-rw-r--r--src/gui/text/qfont.h19
-rw-r--r--src/gui/text/qfont_p.h8
-rw-r--r--src/gui/text/qfontdatabase.cpp54
-rw-r--r--src/gui/text/qfontengine.cpp5
-rw-r--r--src/gui/text/qfontmetrics.cpp31
-rw-r--r--src/gui/text/qfontmetrics.h33
-rw-r--r--src/gui/text/qsyntaxhighlighter.h2
-rw-r--r--src/gui/text/qtextdocument.cpp6
-rw-r--r--src/gui/text/qtextdocument_p.cpp2
-rw-r--r--src/gui/text/qtextdocumentfragment.cpp6
-rw-r--r--src/gui/text/qtextdocumentfragment_p.h2
-rw-r--r--src/gui/text/qtextdocumentwriter.cpp8
-rw-r--r--src/gui/text/qtextformat.cpp52
-rw-r--r--src/gui/text/qtextformat.h16
-rw-r--r--src/gui/text/qtextformat_p.h2
-rw-r--r--src/gui/text/qtexthtmlparser.cpp7
-rw-r--r--src/gui/text/qtextlayout.cpp21
-rw-r--r--src/gui/text/qtextlayout.h14
-rw-r--r--src/gui/text/qtextlist.cpp2
-rw-r--r--src/gui/text/qtextlist.h3
-rw-r--r--src/gui/text/qtextobject.cpp12
-rw-r--r--src/gui/text/qtextodfwriter.cpp32
-rw-r--r--src/gui/text/qzipreader_p.h2
-rw-r--r--src/gui/text/qzipwriter_p.h2
-rw-r--r--src/gui/util/qastchandler.cpp168
-rw-r--r--src/gui/util/qastchandler_p.h73
-rw-r--r--src/gui/util/qlayoutpolicy_p.h1
-rw-r--r--src/gui/util/qtexturefilereader.cpp5
-rw-r--r--src/gui/util/util.pri6
-rw-r--r--src/gui/vulkan/qvulkaninstance.cpp2
-rw-r--r--src/network/access/http2/bitstreams_p.h2
-rw-r--r--src/network/access/http2/hpacktable_p.h2
-rw-r--r--src/network/access/qabstractnetworkcache.cpp14
-rw-r--r--src/network/access/qftp.cpp4
-rw-r--r--src/network/access/qftp_p.h2
-rw-r--r--src/network/access/qhstsstore_p.h2
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp18
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h6
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp1
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp15
-rw-r--r--src/network/access/qhttpnetworkrequest_p.h3
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp13
-rw-r--r--src/network/access/qnetworkaccessftpbackend.cpp2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp32
-rw-r--r--src/network/access/qnetworkaccessmanager.h3
-rw-r--r--src/network/access/qnetworkcookiejar.cpp21
-rw-r--r--src/network/access/qnetworkfile.cpp12
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp3
-rw-r--r--src/network/access/qnetworkreplywasmimpl.cpp23
-rw-r--r--src/network/access/qnetworkrequest.cpp31
-rw-r--r--src/network/access/qnetworkrequest.h2
-rw-r--r--src/network/bearer/qnetworkconfiguration.cpp2
-rw-r--r--src/network/bearer/qnetworkconfiguration_p.h2
-rw-r--r--src/network/configure.json43
-rw-r--r--src/network/kernel/qauthenticator.cpp15
-rw-r--r--src/network/kernel/qauthenticator_p.h2
-rw-r--r--src/network/kernel/qhostinfo.cpp29
-rw-r--r--src/network/kernel/qhostinfo.h7
-rw-r--r--src/network/kernel/qnetworkproxy_win.cpp4
-rw-r--r--src/network/socket/qabstractsocket.cpp34
-rw-r--r--src/network/socket/qabstractsocket.h2
-rw-r--r--src/network/socket/qabstractsocket_p.h3
-rw-r--r--src/network/socket/qabstractsocketengine_p.h2
-rw-r--r--src/network/socket/qhttpsocketengine.cpp8
-rw-r--r--src/network/socket/qhttpsocketengine_p.h2
-rw-r--r--src/network/socket/qlocalserver.cpp4
-rw-r--r--src/network/socket/qlocalsocket_win.cpp4
-rw-r--r--src/network/socket/qnativesocketengine.cpp8
-rw-r--r--src/network/socket/qnativesocketengine_p.h2
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp26
-rw-r--r--src/network/socket/qnativesocketengine_winrt_p.h2
-rw-r--r--src/network/socket/qsocks5socketengine.cpp10
-rw-r--r--src/network/socket/qsocks5socketengine_p.h2
-rw-r--r--src/network/socket/qtcpserver.cpp2
-rw-r--r--src/network/ssl/qasn1element_p.h2
-rw-r--r--src/network/ssl/qdtls.h2
-rw-r--r--src/network/ssl/qocsp_p.h74
-rw-r--r--src/network/ssl/qocspresponse.cpp258
-rw-r--r--src/network/ssl/qocspresponse.h116
-rw-r--r--src/network/ssl/qocspresponse_p.h84
-rw-r--r--src/network/ssl/qssl.cpp26
-rw-r--r--src/network/ssl/qssl.h6
-rw-r--r--src/network/ssl/qsslcertificate.cpp3
-rw-r--r--src/network/ssl/qsslcertificate_openssl.cpp48
-rw-r--r--src/network/ssl/qsslcertificate_p.h18
-rw-r--r--src/network/ssl/qsslcertificate_qt.cpp34
-rw-r--r--src/network/ssl/qsslcertificate_schannel.cpp62
-rw-r--r--src/network/ssl/qsslconfiguration.cpp41
-rw-r--r--src/network/ssl/qsslconfiguration.h3
-rw-r--r--src/network/ssl/qsslconfiguration_p.h6
-rw-r--r--src/network/ssl/qsslcontext_openssl.cpp24
-rw-r--r--src/network/ssl/qsslcontext_openssl11.cpp17
-rw-r--r--src/network/ssl/qsslcontext_opensslpre11.cpp22
-rw-r--r--src/network/ssl/qssldiffiehellmanparameters.cpp2
-rw-r--r--src/network/ssl/qsslellipticcurve.cpp2
-rw-r--r--src/network/ssl/qsslerror.cpp45
-rw-r--r--src/network/ssl/qsslerror.h12
-rw-r--r--src/network/ssl/qsslkey_openssl.cpp46
-rw-r--r--src/network/ssl/qsslkey_p.cpp8
-rw-r--r--src/network/ssl/qsslkey_p.h3
-rw-r--r--src/network/ssl/qsslkey_qt.cpp32
-rw-r--r--src/network/ssl/qsslkey_schannel.cpp174
-rw-r--r--src/network/ssl/qsslpresharedkeyauthenticator.cpp2
-rw-r--r--src/network/ssl/qsslsocket.cpp97
-rw-r--r--src/network/ssl/qsslsocket.h5
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp289
-rw-r--r--src/network/ssl/qsslsocket_mac_p.h4
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp441
-rw-r--r--src/network/ssl/qsslsocket_openssl11.cpp16
-rw-r--r--src/network/ssl/qsslsocket_openssl11_symbols_p.h17
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h13
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp146
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h89
-rw-r--r--src/network/ssl/qsslsocket_opensslpre11.cpp16
-rw-r--r--src/network/ssl/qsslsocket_opensslpre11_symbols_p.h47
-rw-r--r--src/network/ssl/qsslsocket_p.h26
-rw-r--r--src/network/ssl/qsslsocket_qt.cpp307
-rw-r--r--src/network/ssl/qsslsocket_schannel.cpp1994
-rw-r--r--src/network/ssl/qsslsocket_schannel_p.h155
-rw-r--r--src/network/ssl/qsslsocket_winrt.cpp12
-rw-r--r--src/network/ssl/ssl.pri23
-rw-r--r--src/opengl/doc/qtopengl.qdocconf2
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h2
-rw-r--r--src/opengl/qgl.cpp35
-rw-r--r--src/opengl/qgl.h16
-rw-r--r--src/opengl/qglframebufferobject.cpp2
-rw-r--r--src/opengl/qglfunctions.cpp5
-rw-r--r--src/opengl/qglshaderprogram.cpp6
-rw-r--r--src/opengl/qglshaderprogram.h11
-rw-r--r--src/opengl/qgraphicsshadereffect_p.h2
-rw-r--r--src/platformheaders/doc/qtplatformheaders.qdocconf2
-rw-r--r--src/platformheaders/windowsfunctions/qwindowswindowfunctions.h9
-rw-r--r--src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc33
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_p.h2
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp8
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp2
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp18
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h4
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h2
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp2
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h2
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h2
-rw-r--r--src/platformsupport/glxconvenience/qglxconvenience.cpp17
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp2
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h2
-rw-r--r--src/platformsupport/input/input-support.pro35
-rw-r--r--src/platformsupport/input/input.pro37
-rw-r--r--src/platformsupport/input/libinput/libinput.pri5
-rw-r--r--src/platformsupport/input/libinput/qlibinputkeyboard.cpp185
-rw-r--r--src/platformsupport/input/libinput/qlibinputkeyboard_p.h8
-rw-r--r--src/platformsupport/input/xkbcommon/qxkbcommon.cpp828
-rw-r--r--src/platformsupport/input/xkbcommon/qxkbcommon_3rdparty.cpp (renamed from src/plugins/platforms/xcb/qxcbxkbcommon.h)28
-rw-r--r--src/platformsupport/input/xkbcommon/qxkbcommon_p.h122
-rw-r--r--src/platformsupport/input/xkbcommon/xkbcommon.pro23
-rw-r--r--src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp3
-rw-r--r--src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor.cpp3
-rw-r--r--src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy_p.h1
-rw-r--r--src/platformsupport/themes/qabstractfileiconengine.cpp2
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp4
-rw-r--r--src/plugins/bearer/qnetworksession_impl.cpp4
-rw-r--r--src/plugins/generic/tuiotouch/qtuiohandler.cpp10
-rw-r--r--src/plugins/platforminputcontexts/compose/compose.pro8
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp658
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h145
-rw-r--r--src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp291
-rw-r--r--src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h33
-rw-r--r--src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp4
-rw-r--r--src/plugins/platforminputcontexts/ibus/ibus.pro2
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp60
-rw-r--r--src/plugins/platforminputcontexts/platforminputcontexts.pro11
-rw-r--r--src/plugins/platforms/android/android.pro8
-rw-r--r--src/plugins/platforms/android/androidcontentfileengine.cpp92
-rw-r--r--src/plugins/platforms/android/androidcontentfileengine.h (renamed from src/plugins/platforms/offscreen/qoffscreenintegration_dummy.cpp)25
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp5
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp5
-rw-r--r--src/plugins/platforms/android/extract-dummy.cpp10
-rw-r--r--src/plugins/platforms/android/extract.cpp40
-rw-r--r--src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp149
-rw-r--r--src/plugins/platforms/android/qandroidplatformfiledialoghelper.h81
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm46
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm3
-rw-r--r--src/plugins/platforms/cocoa/qnsview_drawing.mm2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp2
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.h2
-rw-r--r--src/plugins/platforms/offscreen/offscreen.pro5
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration.cpp14
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration.h1
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp117
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration_x11.h12
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp5
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp88
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h4
-rw-r--r--src/plugins/platforms/vnc/qvnc.cpp10
-rw-r--r--src/plugins/platforms/vnc/qvncscreen.cpp2
-rw-r--r--src/plugins/platforms/wasm/qtloader.js84
-rw-r--r--src/plugins/platforms/wasm/qwasmclipboard.cpp229
-rw-r--r--src/plugins/platforms/wasm/qwasmclipboard.h60
-rw-r--r--src/plugins/platforms/wasm/qwasmcompositor.cpp25
-rw-r--r--src/plugins/platforms/wasm/qwasmcompositor.h7
-rw-r--r--src/plugins/platforms/wasm/qwasmcursor.cpp22
-rw-r--r--src/plugins/platforms/wasm/qwasmeventtranslator.cpp717
-rw-r--r--src/plugins/platforms/wasm/qwasmeventtranslator.h186
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.cpp151
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.h27
-rw-r--r--src/plugins/platforms/wasm/qwasmopenglcontext.cpp10
-rw-r--r--src/plugins/platforms/wasm/qwasmopenglcontext.h2
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp75
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.h23
-rw-r--r--src/plugins/platforms/wasm/qwasmservices.cpp45
-rw-r--r--src/plugins/platforms/wasm/qwasmservices.h (renamed from src/tools/uic/globaldefs.h)26
-rw-r--r--src/plugins/platforms/wasm/qwasmwindow.cpp4
-rw-r--r--src/plugins/platforms/wasm/wasm.pro8
-rw-r--r--src/plugins/platforms/wasm/wasm_shell.html20
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp19
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h2
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp2
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp17
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp23
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp26
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h10
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_basic.cpp14
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_basic.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_screens.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbeventqueue.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp729
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h36
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp33
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro4
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h2
-rw-r--r--src/plugins/printsupport/cups/qcupsprintengine_p.h4
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintersupport.h2
-rw-r--r--src/plugins/sqldrivers/mysql/qsql_mysql.cpp12
-rw-r--r--src/plugins/sqldrivers/odbc/qsql_odbc.cpp2
-rw-r--r--src/plugins/sqldrivers/psql/main.cpp8
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp296
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql_p.h18
-rw-r--r--src/plugins/styles/android/qandroidstyle_p.h2
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm2
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac_p.h2
-rw-r--r--src/plugins/styles/windowsvista/qwindowsvistastyle.cpp12
-rw-r--r--src/plugins/styles/windowsvista/qwindowsvistastyle_p.h2
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle.cpp9
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle_p.h2
-rw-r--r--src/printsupport/dialogs/qprintdialog_unix.cpp2
-rw-r--r--src/printsupport/dialogs/qprintpreviewdialog.cpp2
-rw-r--r--src/printsupport/kernel/qplatformprintdevice.cpp26
-rw-r--r--src/printsupport/kernel/qprinter.cpp2
-rw-r--r--src/printsupport/kernel/qprinterinfo.cpp29
-rw-r--r--src/printsupport/kernel/qprinterinfo.h3
-rw-r--r--src/printsupport/widgets/qcupsjobwidget_p.h2
-rw-r--r--src/sql/doc/snippets/code/doc_src_sql-driver.qdoc13
-rw-r--r--src/sql/doc/src/sql-driver.qdoc17
-rw-r--r--src/sql/kernel/qsqldatabase.cpp44
-rw-r--r--src/sql/kernel/qsqldatabase.h1
-rw-r--r--src/sql/kernel/qsqldriver.cpp16
-rw-r--r--src/sql/models/qsqlrelationaldelegate.h2
-rw-r--r--src/sql/models/qsqlrelationaltablemodel.cpp10
-rw-r--r--src/sql/models/qsqltablemodel.cpp10
-rw-r--r--src/sql/models/qsqltablemodel.h3
-rw-r--r--src/testlib/configure.json6
-rw-r--r--src/testlib/doc/qttestlib.qdocconf2
-rw-r--r--src/testlib/doc/src/qttest-index.qdoc10
-rw-r--r--src/testlib/qabstractitemmodeltester.h4
-rw-r--r--src/testlib/qsignalspy.qdoc4
-rw-r--r--src/testlib/qtest.h58
-rw-r--r--src/testlib/qtestblacklist.cpp42
-rw-r--r--src/testlib/qtestblacklist_p.h1
-rw-r--r--src/testlib/qtestcase.cpp189
-rw-r--r--src/testlib/qtestcase.h17
-rw-r--r--src/testlib/qtestcorelist_p.h17
-rw-r--r--src/testlib/qtestlog.cpp5
-rw-r--r--src/testlib/selfcover.pri28
-rw-r--r--src/testlib/testlib.pro1
-rw-r--r--src/tools/androiddeployqt/main.cpp4
-rw-r--r--src/tools/moc/generator.cpp10
-rw-r--r--src/tools/moc/moc.cpp2
-rw-r--r--src/tools/moc/moc.h72
-rwxr-xr-xsrc/tools/moc/util/generate.sh2
-rw-r--r--src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp3
-rw-r--r--src/tools/qfloat16-tables/gen_qfloat16_tables.cpp4
-rw-r--r--src/tools/qlalr/cppgenerator.cpp2
-rw-r--r--src/tools/qlalr/lalr.h2
-rw-r--r--src/tools/rcc/main.cpp37
-rw-r--r--src/tools/rcc/rcc.cpp271
-rw-r--r--src/tools/rcc/rcc.h26
-rw-r--r--src/tools/rcc/rcc.pro11
-rw-r--r--src/tools/tracegen/helpers.cpp2
-rw-r--r--src/tools/uic/cpp/cppwriteincludes.cpp16
-rw-r--r--src/tools/uic/cpp/cppwriteincludes.h6
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.cpp401
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.h5
-rw-r--r--src/tools/uic/customwidgetsinfo.cpp39
-rw-r--r--src/tools/uic/customwidgetsinfo.h8
-rw-r--r--src/tools/uic/databaseinfo.h6
-rw-r--r--src/tools/uic/driver.cpp151
-rw-r--r--src/tools/uic/driver.h57
-rw-r--r--src/tools/uic/main.cpp2
-rw-r--r--src/tools/uic/shared/language.cpp144
-rw-r--r--src/tools/uic/shared/language.h81
-rw-r--r--src/tools/uic/shared/shared.pri5
-rw-r--r--src/tools/uic/treewalker.h1
-rw-r--r--src/tools/uic/uic.cpp61
-rw-r--r--src/tools/uic/uic.h7
-rw-r--r--src/tools/uic/uic.pri1
-rw-r--r--src/tools/uic/uic.pro1
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp15
-rw-r--r--src/widgets/dialogs/qdialog.cpp37
-rw-r--r--src/widgets/dialogs/qdialog.h15
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp157
-rw-r--r--src/widgets/dialogs/qfiledialog.h25
-rw-r--r--src/widgets/dialogs/qfiledialog_p.h10
-rw-r--r--src/widgets/dialogs/qfontdialog.cpp2
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp16
-rw-r--r--src/widgets/dialogs/qmessagebox.h4
-rw-r--r--src/widgets/dialogs/qprogressdialog.cpp10
-rw-r--r--src/widgets/dialogs/qsidebar.cpp2
-rw-r--r--src/widgets/dialogs/qwizard.cpp26
-rw-r--r--src/widgets/dialogs/qwizard_win_p.h2
-rw-r--r--src/widgets/doc/snippets/code/doc_src_examples_dropsite.qdoc55
-rw-r--r--src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc16
-rw-r--r--src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp11
-rw-r--r--src/widgets/doc/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp8
-rw-r--r--src/widgets/doc/snippets/code/src_gui_kernel_qapplication.cpp12
-rw-r--r--src/widgets/doc/snippets/code/src_gui_widgets_qmenu.cpp2
-rw-r--r--src/widgets/doc/snippets/dialogs/dialogs.cpp9
-rw-r--r--src/widgets/doc/snippets/dockwidgets/mainwindow.cpp8
-rw-r--r--src/widgets/doc/snippets/mdiareasnippets.cpp4
-rw-r--r--src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp3
-rw-r--r--src/widgets/doc/snippets/qlistview-dnd/model.cpp8
-rw-r--r--src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp4
-rw-r--r--src/widgets/doc/snippets/qlistwidget-using/mainwindow.cpp17
-rw-r--r--src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp7
-rw-r--r--src/widgets/doc/snippets/qstackedlayout/main.cpp9
-rw-r--r--src/widgets/doc/snippets/qstackedwidget/main.cpp7
-rw-r--r--src/widgets/doc/snippets/qtablewidget-resizing/mainwindow.cpp8
-rw-r--r--src/widgets/doc/snippets/qtablewidget-using/mainwindow.cpp20
-rw-r--r--src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp35
-rw-r--r--src/widgets/doc/snippets/qtreewidgetitemiterator-using/mainwindow.cpp21
-rw-r--r--src/widgets/doc/snippets/reading-selections/window.cpp18
-rw-r--r--src/widgets/doc/snippets/updating-selections/window.cpp17
-rw-r--r--src/widgets/doc/src/model-view-programming.qdoc21
-rw-r--r--src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc18
-rw-r--r--src/widgets/effects/qgraphicseffect_p.h2
-rw-r--r--src/widgets/effects/qpixmapfilter.cpp5
-rw-r--r--src/widgets/graphicsview/qgraphicsgridlayout.cpp11
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp105
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.h8
-rw-r--r--src/widgets/graphicsview/qgraphicsitemanimation.cpp2
-rw-r--r--src/widgets/graphicsview/qgraphicsitemanimation.h3
-rw-r--r--src/widgets/graphicsview/qgraphicslayout.h2
-rw-r--r--src/widgets/graphicsview/qgraphicslayoutitem.cpp14
-rw-r--r--src/widgets/graphicsview/qgraphicslayoutitem.h2
-rw-r--r--src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp8
-rw-r--r--src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h4
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp4
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.cpp54
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.h8
-rw-r--r--src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h2
-rw-r--r--src/widgets/graphicsview/qgraphicssceneevent.cpp4
-rw-r--r--src/widgets/graphicsview/qgraphicssceneindex_p.h4
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp2
-rw-r--r--src/widgets/graphicsview/qgraphicswidget.cpp37
-rw-r--r--src/widgets/graphicsview/qsimplex_p.h2
-rw-r--r--src/widgets/itemviews/qabstractitemdelegate.cpp6
-rw-r--r--src/widgets/itemviews/qabstractitemdelegate.h3
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp21
-rw-r--r--src/widgets/itemviews/qabstractitemview.h10
-rw-r--r--src/widgets/itemviews/qcolumnview.cpp2
-rw-r--r--src/widgets/itemviews/qcolumnview_p.h1
-rw-r--r--src/widgets/itemviews/qcolumnviewgrip_p.h2
-rw-r--r--src/widgets/itemviews/qdatawidgetmapper.cpp1
-rw-r--r--src/widgets/itemviews/qdirmodel.cpp3
-rw-r--r--src/widgets/itemviews/qheaderview.cpp29
-rw-r--r--src/widgets/itemviews/qitemdelegate.cpp42
-rw-r--r--src/widgets/itemviews/qitemdelegate.h5
-rw-r--r--src/widgets/itemviews/qitemeditorfactory.cpp16
-rw-r--r--src/widgets/itemviews/qitemeditorfactory.h4
-rw-r--r--src/widgets/itemviews/qlistview.cpp35
-rw-r--r--src/widgets/itemviews/qlistview_p.h8
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp180
-rw-r--r--src/widgets/itemviews/qlistwidget.h46
-rw-r--r--src/widgets/itemviews/qlistwidget_p.h4
-rw-r--r--src/widgets/itemviews/qstyleditemdelegate.cpp4
-rw-r--r--src/widgets/itemviews/qtableview.cpp52
-rw-r--r--src/widgets/itemviews/qtableview.h6
-rw-r--r--src/widgets/itemviews/qtableview_p.h1
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp122
-rw-r--r--src/widgets/itemviews/qtablewidget.h33
-rw-r--r--src/widgets/itemviews/qtablewidget_p.h3
-rw-r--r--src/widgets/itemviews/qtreeview.cpp131
-rw-r--r--src/widgets/itemviews/qtreeview.h6
-rw-r--r--src/widgets/itemviews/qtreeview_p.h2
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp270
-rw-r--r--src/widgets/itemviews/qtreewidget.h65
-rw-r--r--src/widgets/itemviews/qtreewidget_p.h4
-rw-r--r--src/widgets/kernel/qactiongroup.cpp4
-rw-r--r--src/widgets/kernel/qapplication.cpp25
-rw-r--r--src/widgets/kernel/qapplication.h8
-rw-r--r--src/widgets/kernel/qdesktopwidget.cpp24
-rw-r--r--src/widgets/kernel/qdesktopwidget.h2
-rw-r--r--src/widgets/kernel/qformlayout.cpp15
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp10
-rw-r--r--src/widgets/kernel/qgridlayout.cpp6
-rw-r--r--src/widgets/kernel/qlayout.cpp37
-rw-r--r--src/widgets/kernel/qlayout.h8
-rw-r--r--src/widgets/kernel/qlayoutitem.cpp18
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp4
-rw-r--r--src/widgets/kernel/qstackedlayout.cpp12
-rw-r--r--src/widgets/kernel/qtooltip.cpp4
-rw-r--r--src/widgets/kernel/qwhatsthis.cpp6
-rw-r--r--src/widgets/kernel/qwidget.cpp128
-rw-r--r--src/widgets/kernel/qwidget.h5
-rw-r--r--src/widgets/kernel/qwidget_p.h17
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp270
-rw-r--r--src/widgets/kernel/qwidgetbackingstore_p.h8
-rw-r--r--src/widgets/statemachine/qbasickeyeventtransition_p.h2
-rw-r--r--src/widgets/statemachine/qbasicmouseeventtransition_p.h2
-rw-r--r--src/widgets/styles/qcommonstyle.cpp94
-rw-r--r--src/widgets/styles/qdrawutil.cpp2
-rw-r--r--src/widgets/styles/qfusionstyle.cpp76
-rw-r--r--src/widgets/styles/qfusionstyle_p_p.h2
-rw-r--r--src/widgets/styles/qstyle.h29
-rw-r--r--src/widgets/styles/qstyle_p.h2
-rw-r--r--src/widgets/styles/qstyleoption.cpp8
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp42
-rw-r--r--src/widgets/styles/qstylesheetstyle_p.h2
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp52
-rw-r--r--src/widgets/styles/qwindowsstyle_p.h2
-rw-r--r--src/widgets/util/qcompleter_p.h1
-rw-r--r--src/widgets/util/qflickgesture.cpp2
-rw-r--r--src/widgets/util/qflickgesture_p.h3
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp2
-rw-r--r--src/widgets/util/qundostack.cpp12
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp10
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp2
-rw-r--r--src/widgets/widgets/qbuttongroup.cpp8
-rw-r--r--src/widgets/widgets/qcalendarwidget.cpp11
-rw-r--r--src/widgets/widgets/qcombobox.cpp29
-rw-r--r--src/widgets/widgets/qcombobox.h7
-rw-r--r--src/widgets/widgets/qcombobox_p.h3
-rw-r--r--src/widgets/widgets/qcommandlinkbutton.h6
-rw-r--r--src/widgets/widgets/qdatetimeedit.cpp2
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp2
-rw-r--r--src/widgets/widgets/qdockwidget.cpp39
-rw-r--r--src/widgets/widgets/qdockwidget_p.h29
-rw-r--r--src/widgets/widgets/qfontcombobox.cpp16
-rw-r--r--src/widgets/widgets/qlabel.cpp2
-rw-r--r--src/widgets/widgets/qlineedit.cpp2
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp2
-rw-r--r--src/widgets/widgets/qmainwindow.cpp6
-rw-r--r--src/widgets/widgets/qmainwindow.h6
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp29
-rw-r--r--src/widgets/widgets/qmainwindowlayout_p.h2
-rw-r--r--src/widgets/widgets/qmdiarea.cpp32
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp14
-rw-r--r--src/widgets/widgets/qmenu.cpp60
-rw-r--r--src/widgets/widgets/qmenu.h4
-rw-r--r--src/widgets/widgets/qmenu_p.h8
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp26
-rw-r--r--src/widgets/widgets/qplaintextedit.h4
-rw-r--r--src/widgets/widgets/qpushbutton.cpp4
-rw-r--r--src/widgets/widgets/qscrollarea.cpp2
-rw-r--r--src/widgets/widgets/qspinbox.cpp4
-rw-r--r--src/widgets/widgets/qsplitter.cpp6
-rw-r--r--src/widgets/widgets/qsplitter.h4
-rw-r--r--src/widgets/widgets/qstackedwidget.cpp6
-rw-r--r--src/widgets/widgets/qstatusbar.cpp6
-rw-r--r--src/widgets/widgets/qtabbar.cpp9
-rw-r--r--src/widgets/widgets/qtabwidget.cpp8
-rw-r--r--src/widgets/widgets/qtextbrowser.cpp6
-rw-r--r--src/widgets/widgets/qtextedit.cpp29
-rw-r--r--src/widgets/widgets/qtextedit.h4
-rw-r--r--src/widgets/widgets/qtoolbar.cpp40
-rw-r--r--src/widgets/widgets/qtoolbar.h8
-rw-r--r--src/widgets/widgets/qtoolbararealayout.cpp8
-rw-r--r--src/widgets/widgets/qtoolbararealayout_p.h2
-rw-r--r--src/widgets/widgets/qtoolbarlayout.cpp45
-rw-r--r--src/widgets/widgets/qtoolbox.cpp15
-rw-r--r--src/widgets/widgets/qtoolbutton.cpp5
-rw-r--r--src/widgets/widgets/qwidgetresizehandler_p.h2
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp31
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p.h6
-rw-r--r--src/xml/dom/qdom.cpp16
-rw-r--r--src/xml/sax/qxml.cpp45
874 files changed, 42696 insertions, 28983 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/validationES.cpp b/src/3rdparty/angle/src/libANGLE/validationES.cpp
index ae564b7412..069ca045f8 100644
--- a/src/3rdparty/angle/src/libANGLE/validationES.cpp
+++ b/src/3rdparty/angle/src/libANGLE/validationES.cpp
@@ -3525,7 +3525,7 @@ bool ValidateGetBufferPointervBase(Context *context,
if (context->getGLState().getTargetBuffer(target) == nullptr)
{
context->handleError(InvalidOperation()
- << "Can not get pointer for reserved buffer name zero.");
+ << "Cannot get pointer for reserved buffer name zero.");
return false;
}
diff --git a/src/3rdparty/libjpeg/LICENSE b/src/3rdparty/libjpeg/LICENSE
index 0f6ec4b30a..5ca512b34d 100644
--- a/src/3rdparty/libjpeg/LICENSE
+++ b/src/3rdparty/libjpeg/LICENSE
@@ -14,7 +14,7 @@ libjpeg-turbo is covered by three compatible BSD-style open source licenses:
This license covers the TurboJPEG API library and associated programs, as
well as the build system.
-- The zlib License, which is listed below
+- The [zlib License](https://opensource.org/licenses/Zlib)
This license is a subset of the other two, and it covers the libjpeg-turbo
SIMD extensions.
@@ -66,7 +66,7 @@ best of our understanding.
2. If your binary distribution includes or uses the TurboJPEG API, then
your product documentation must include the text of the Modified BSD
- License.
+ License (see below.)
**Origin**
- Clause 2 of the Modified BSD License
@@ -91,7 +91,8 @@ best of our understanding.
The Modified (3-clause) BSD License
===================================
-Copyright (C)\<YEAR\> \<AUTHOR\>. All Rights Reserved.
+Copyright (C)2009-2019 D. R. Commander. All Rights Reserved.
+Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -118,28 +119,6 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-The zlib License
-================
-
-Copyright (C) \<YEAR\>, \<AUTHOR\>.
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-1. 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.
-2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
-3. This notice may not be removed or altered from any source distribution.
-
-
Why Three Licenses?
===================
diff --git a/src/3rdparty/libjpeg/jconfig.h b/src/3rdparty/libjpeg/jconfig.h
index bcfef5f0b6..3f6a7f6b3c 100644
--- a/src/3rdparty/libjpeg/jconfig.h
+++ b/src/3rdparty/libjpeg/jconfig.h
@@ -2,22 +2,22 @@
#define JPEG_LIB_VERSION 80
-#define LIBJPEG_TURBO_VERSION 2.0.0
+#define LIBJPEG_TURBO_VERSION 2.0.2
-#define LIBJPEG_TURBO_VERSION_NUMBER 2000000
+#define LIBJPEG_TURBO_VERSION_NUMBER 2000002
-#define C_ARITH_CODING_SUPPORTED
+#define C_ARITH_CODING_SUPPORTED 1
-#define D_ARITH_CODING_SUPPORTED
+#define D_ARITH_CODING_SUPPORTED 1
-#define MEM_SRCDST_SUPPORTED
+#define MEM_SRCDST_SUPPORTED 1
#define BITS_IN_JSAMPLE 8
-#define HAVE_STDDEF_H
+#define HAVE_STDDEF_H 1
-#define HAVE_STDLIB_H
+#define HAVE_STDLIB_H 1
-#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_CHAR 1
-#define HAVE_UNSIGNED_SHORT
+#define HAVE_UNSIGNED_SHORT 1
diff --git a/src/3rdparty/libjpeg/qt_attribution.json b/src/3rdparty/libjpeg/qt_attribution.json
index 8fbdfdb9b7..d1497bc20f 100644
--- a/src/3rdparty/libjpeg/qt_attribution.json
+++ b/src/3rdparty/libjpeg/qt_attribution.json
@@ -6,11 +6,11 @@
"Description": "The Independent JPEG Group's JPEG software",
"Homepage": "http://libjpeg-turbo.virtualgl.org/",
- "Version": "2.0.0",
+ "Version": "2.0.2",
"License": "Independent JPEG Group License",
"LicenseId": "IJG",
"LicenseFile": "LICENSE",
- "Copyright": "Copyright (C) 2009-2018 D. R. Commander
+ "Copyright": "Copyright (C) 2009-2019 D. R. Commander
Copyright (C) 2011-2016 Siarhei Siamashka
Copyright (C) 2015-2016, 2018 Matthieu Darbois
Copyright (C) 2015 Intel Corporation
diff --git a/src/3rdparty/libjpeg/src/ChangeLog.md b/src/3rdparty/libjpeg/src/ChangeLog.md
index 8f0d11b1a6..7cf92c30fd 100644
--- a/src/3rdparty/libjpeg/src/ChangeLog.md
+++ b/src/3rdparty/libjpeg/src/ChangeLog.md
@@ -1,3 +1,73 @@
+2.0.2
+=====
+
+### Significant changes relative to 2.0.1:
+
+1. Fixed a regression introduced by 2.0.1[5] that prevented a runtime search
+path (rpath) from being embedded in the libjpeg-turbo shared libraries and
+executables for macOS and iOS. This caused a fatal error of the form
+"dyld: Library not loaded" when attempting to use one of the executables,
+unless `DYLD_LIBRARY_PATH` was explicitly set to the location of the
+libjpeg-turbo shared libraries.
+
+2. Fixed an integer overflow and subsequent segfault (CVE-2018-20330) that
+occurred when attempting to load a BMP file with more than 1 billion pixels
+using the `tjLoadImage()` function.
+
+3. Fixed a buffer overrun (CVE-2018-19664) that occurred when attempting to
+decompress a specially-crafted malformed JPEG image to a 256-color BMP using
+djpeg.
+
+4. Fixed a floating point exception that occurred when attempting to
+decompress a specially-crafted malformed JPEG image with a specified image
+width or height of 0 using the C version of TJBench.
+
+5. The TurboJPEG API will now decompress 4:4:4 JPEG images with 2x1, 1x2, 3x1,
+or 1x3 luminance and chrominance sampling factors. This is a non-standard way
+of specifying 1x subsampling (normally 4:4:4 JPEGs have 1x1 luminance and
+chrominance sampling factors), but the JPEG format and the libjpeg API both
+allow it.
+
+6. Fixed a regression introduced by 2.0 beta1[7] that caused djpeg to generate
+incorrect PPM images when used with the `-colors` option.
+
+7. Fixed an issue whereby a static build of libjpeg-turbo (a build in which
+`ENABLE_SHARED` is `0`) could not be installed using the Visual Studio IDE.
+
+8. Fixed a severe performance issue in the Loongson MMI SIMD extensions that
+occurred when compressing RGB images whose image rows were not 64-bit-aligned.
+
+
+2.0.1
+=====
+
+### Significant changes relative to 2.0.0:
+
+1. Fixed a regression introduced with the new CMake-based Un*x build system,
+whereby jconfig.h could cause compiler warnings of the form
+`"HAVE_*_H" redefined` if it was included by downstream Autotools-based
+projects that used `AC_CHECK_HEADERS()` to check for the existence of locale.h,
+stddef.h, or stdlib.h.
+
+2. The `jsimd_quantize_float_dspr2()` and `jsimd_convsamp_float_dspr2()`
+functions in the MIPS DSPr2 SIMD extensions are now disabled at compile time
+if the soft float ABI is enabled. Those functions use instructions that are
+incompatible with the soft float ABI.
+
+3. Fixed a regression in the SIMD feature detection code, introduced by
+the AVX2 SIMD extensions (2.0 beta1[1]), that caused libjpeg-turbo to crash on
+Windows 7 if Service Pack 1 was not installed.
+
+4. Fixed out-of-bounds read in cjpeg that occurred when attempting to compress
+a specially-crafted malformed color-index (8-bit-per-sample) Targa file in
+which some of the samples (color indices) exceeded the bounds of the Targa
+file's color table.
+
+5. Fixed an issue whereby installing a fully static build of libjpeg-turbo
+(a build in which `CFLAGS` contains `-static` and `ENABLE_SHARED` is `0`) would
+fail with "No valid ELF RPATH or RUNPATH entry exists in the file."
+
+
2.0.0
=====
diff --git a/src/3rdparty/libjpeg/src/jconfig.h.in b/src/3rdparty/libjpeg/src/jconfig.h.in
index 28427548e8..18a69a4814 100644
--- a/src/3rdparty/libjpeg/src/jconfig.h.in
+++ b/src/3rdparty/libjpeg/src/jconfig.h.in
@@ -10,16 +10,16 @@
#define LIBJPEG_TURBO_VERSION_NUMBER @LIBJPEG_TURBO_VERSION_NUMBER@
/* Support arithmetic encoding */
-#cmakedefine C_ARITH_CODING_SUPPORTED
+#cmakedefine C_ARITH_CODING_SUPPORTED 1
/* Support arithmetic decoding */
-#cmakedefine D_ARITH_CODING_SUPPORTED
+#cmakedefine D_ARITH_CODING_SUPPORTED 1
/* Support in-memory source/destination managers */
-#cmakedefine MEM_SRCDST_SUPPORTED
+#cmakedefine MEM_SRCDST_SUPPORTED 1
/* Use accelerated SIMD routines. */
-#cmakedefine WITH_SIMD
+#cmakedefine WITH_SIMD 1
/*
* Define BITS_IN_JSAMPLE as either
@@ -33,37 +33,37 @@
#define BITS_IN_JSAMPLE @BITS_IN_JSAMPLE@ /* use 8 or 12 */
/* Define to 1 if you have the <locale.h> header file. */
-#cmakedefine HAVE_LOCALE_H
+#cmakedefine HAVE_LOCALE_H 1
/* Define to 1 if you have the <stddef.h> header file. */
-#cmakedefine HAVE_STDDEF_H
+#cmakedefine HAVE_STDDEF_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
-#cmakedefine HAVE_STDLIB_H
+#cmakedefine HAVE_STDLIB_H 1
/* Define if you need to include <sys/types.h> to get size_t. */
-#cmakedefine NEED_SYS_TYPES_H
+#cmakedefine NEED_SYS_TYPES_H 1
/* Define if you have BSD-like bzero and bcopy in <strings.h> rather than
memset/memcpy in <string.h>. */
-#cmakedefine NEED_BSD_STRINGS
+#cmakedefine NEED_BSD_STRINGS 1
/* Define to 1 if the system has the type `unsigned char'. */
-#cmakedefine HAVE_UNSIGNED_CHAR
+#cmakedefine HAVE_UNSIGNED_CHAR 1
/* Define to 1 if the system has the type `unsigned short'. */
-#cmakedefine HAVE_UNSIGNED_SHORT
+#cmakedefine HAVE_UNSIGNED_SHORT 1
/* Compiler does not support pointers to undefined structures. */
-#cmakedefine INCOMPLETE_TYPES_BROKEN
+#cmakedefine INCOMPLETE_TYPES_BROKEN 1
/* Define if your (broken) compiler shifts signed values as if they were
unsigned. */
-#cmakedefine RIGHT_SHIFT_IS_UNSIGNED
+#cmakedefine RIGHT_SHIFT_IS_UNSIGNED 1
/* Define to 1 if type `char' is unsigned and you are not using gcc. */
#ifndef __CHAR_UNSIGNED__
- #cmakedefine __CHAR_UNSIGNED__
+ #cmakedefine __CHAR_UNSIGNED__ 1
#endif
/* Define to empty if `const' does not conform to ANSI C. */
diff --git a/src/3rdparty/libjpeg/src/jdcolor.c b/src/3rdparty/libjpeg/src/jdcolor.c
index fd7f661d5a..dc0e3b6c0e 100644
--- a/src/3rdparty/libjpeg/src/jdcolor.c
+++ b/src/3rdparty/libjpeg/src/jdcolor.c
@@ -592,7 +592,7 @@ ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
/* Declarations for ordered dithering
*
* We use a 4x4 ordered dither array packed into 32 bits. This array is
- * sufficent for dithering RGB888 to RGB565.
+ * sufficient for dithering RGB888 to RGB565.
*/
#define DITHER_MASK 0x3
diff --git a/src/3rdparty/libjpeg/src/jdmerge.c b/src/3rdparty/libjpeg/src/jdmerge.c
index d67faec036..b3fec04f71 100644
--- a/src/3rdparty/libjpeg/src/jdmerge.c
+++ b/src/3rdparty/libjpeg/src/jdmerge.c
@@ -448,7 +448,7 @@ h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
/* Declarations for ordered dithering
*
* We use a 4x4 ordered dither array packed into 32 bits. This array is
- * sufficent for dithering RGB888 to RGB565.
+ * sufficient for dithering RGB888 to RGB565.
*/
#define DITHER_MASK 0x3
diff --git a/src/3rdparty/libjpeg/src/jquant1.c b/src/3rdparty/libjpeg/src/jquant1.c
index a336abdbbb..40bbb28cc7 100644
--- a/src/3rdparty/libjpeg/src/jquant1.c
+++ b/src/3rdparty/libjpeg/src/jquant1.c
@@ -154,7 +154,7 @@ typedef struct {
*/
boolean is_padded; /* is the colorindex padded for odither? */
- int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */
+ int Ncolors[MAX_Q_COMPS]; /* # of values allocated to each component */
/* Variables for ordered dithering */
int row_index; /* cur row's vertical index in dither matrix */
diff --git a/src/3rdparty/libjpeg/src/jversion.h b/src/3rdparty/libjpeg/src/jversion.h
index 2039f44c3a..191fb6bb54 100644
--- a/src/3rdparty/libjpeg/src/jversion.h
+++ b/src/3rdparty/libjpeg/src/jversion.h
@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
* libjpeg-turbo Modifications:
- * Copyright (C) 2010, 2012-2018, D. R. Commander.
+ * Copyright (C) 2010, 2012-2019, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -36,7 +36,7 @@
*/
#define JCOPYRIGHT \
- "Copyright (C) 2009-2018 D. R. Commander\n" \
+ "Copyright (C) 2009-2019 D. R. Commander\n" \
"Copyright (C) 2011-2016 Siarhei Siamashka\n" \
"Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \
"Copyright (C) 2015 Intel Corporation\n" \
@@ -49,4 +49,4 @@
"Copyright (C) 1991-2016 Thomas G. Lane, Guido Vollbeding"
#define JCOPYRIGHT_SHORT \
- "Copyright (C) 1991-2018 The libjpeg-turbo Project and many others"
+ "Copyright (C) 1991-2019 The libjpeg-turbo Project and many others"
diff --git a/src/3rdparty/pcre2/qt_attribution.json b/src/3rdparty/pcre2/qt_attribution.json
index 828c4e8314..72f04e7c06 100644
--- a/src/3rdparty/pcre2/qt_attribution.json
+++ b/src/3rdparty/pcre2/qt_attribution.json
@@ -8,7 +8,7 @@
"Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.",
"Homepage": "http://www.pcre.org/",
"Version": "10.32",
- "DownloadLocation": "https://ftp.pcre.org/pub/pcre/pcre2-10.31.tar.bz2",
+ "DownloadLocation": "https://ftp.pcre.org/pub/pcre/pcre2-10.32.tar.bz2",
"License": "BSD 3-clause \"New\" or \"Revised\" License",
"LicenseId": "BSD-3-Clause",
"LicenseFile": "LICENCE",
@@ -27,7 +27,7 @@ Copyright (c) 2013-2013 Tilera Corporation (jiwang@tilera.com)"
"Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.",
"Homepage": "http://www.pcre.org/",
"Version": "10.32",
- "DownloadLocation": "https://ftp.pcre.org/pub/pcre/pcre2-10.31.tar.bz2",
+ "DownloadLocation": "https://ftp.pcre.org/pub/pcre/pcre2-10.32.tar.bz2",
"License": "BSD 2-clause \"Simplified\" License",
"LicenseId": "BSD-2-Clause",
"LicenseFile": "LICENCE-SLJIT",
diff --git a/src/3rdparty/sqlite.pri b/src/3rdparty/sqlite.pri
index cb8b888a6a..068764c726 100644
--- a/src/3rdparty/sqlite.pri
+++ b/src/3rdparty/sqlite.pri
@@ -1,5 +1,5 @@
CONFIG(release, debug|release):DEFINES *= NDEBUG
-DEFINES += SQLITE_ENABLE_COLUMN_METADATA SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_FTS5 SQLITE_ENABLE_RTREE
+DEFINES += SQLITE_ENABLE_COLUMN_METADATA SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_FTS5 SQLITE_ENABLE_RTREE SQLITE_ENABLE_JSON1
!contains(CONFIG, largefile):DEFINES += SQLITE_DISABLE_LFS
qtConfig(posix_fallocate): DEFINES += HAVE_POSIX_FALLOCATE=1
winrt {
diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json
index 542fa9efb9..30f266ee23 100644
--- a/src/3rdparty/sqlite/qt_attribution.json
+++ b/src/3rdparty/sqlite/qt_attribution.json
@@ -6,8 +6,8 @@
"Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.",
"Homepage": "https://www.sqlite.org/",
- "Version": "3.26.0",
- "DownloadLocation": "https://www.sqlite.org/2018/sqlite-amalgamation-3260000.zip",
+ "Version": "3.27.1",
+ "DownloadLocation": "https://www.sqlite.org/2018/sqlite-amalgamation-3270100.zip",
"License": "Public Domain",
"Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed."
}
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index d015df2c31..70e84b589c 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.26.0. By combining all the individual C code files into this
+** version 3.27.1. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -1162,9 +1162,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.26.0"
-#define SQLITE_VERSION_NUMBER 3026000
-#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
+#define SQLITE_VERSION "3.27.1"
+#define SQLITE_VERSION_NUMBER 3027001
+#define SQLITE_SOURCE_ID "2019-02-08 13:17:39 0eca3dd3d38b31c92b49ca2d311128b74584714d9e7de895b1a6286ef959a1dd"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -1862,6 +1862,15 @@ struct sqlite3_io_methods {
** file space based on this hint in order to help writes to the database
** file run faster.
**
+** <li>[[SQLITE_FCNTL_SIZE_LIMIT]]
+** The [SQLITE_FCNTL_SIZE_LIMIT] opcode is used by in-memory VFS that
+** implements [sqlite3_deserialize()] to set an upper bound on the size
+** of the in-memory database. The argument is a pointer to a [sqlite3_int64].
+** If the integer pointed to is negative, then it is filled in with the
+** current limit. Otherwise the limit is set to the larger of the value
+** of the integer pointed to and the current database size. The integer
+** pointed to is set to the new limit.
+**
** <li>[[SQLITE_FCNTL_CHUNK_SIZE]]
** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
** extends and truncates the database file in chunks of a size specified
@@ -2170,6 +2179,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
#define SQLITE_FCNTL_DATA_VERSION 35
+#define SQLITE_FCNTL_SIZE_LIMIT 36
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -3011,6 +3021,17 @@ struct sqlite3_mem_methods {
** negative value for this option restores the default behaviour.
** This option is only available if SQLite is compiled with the
** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
+**
+** [[SQLITE_CONFIG_MEMDB_MAXSIZE]]
+** <dt>SQLITE_CONFIG_MEMDB_MAXSIZE
+** <dd>The SQLITE_CONFIG_MEMDB_MAXSIZE option accepts a single parameter
+** [sqlite3_int64] parameter which is the default maximum size for an in-memory
+** database created using [sqlite3_deserialize()]. This default maximum
+** size can be adjusted up or down for individual databases using the
+** [SQLITE_FCNTL_SIZE_LIMIT] [sqlite3_file_control|file-control]. If this
+** configuration setting is never used, then the default maximum is determined
+** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that
+** compile-time option is not set, then the default maximum is 1073741824.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -3041,6 +3062,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
+#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -4030,9 +4052,9 @@ SQLITE_API int sqlite3_set_authorizer(
** time is in units of nanoseconds, however the current implementation
** is only capable of millisecond resolution so the six least significant
** digits in the time are meaningless. Future versions of SQLite
-** might provide greater resolution on the profiler callback. The
-** sqlite3_profile() function is considered experimental and is
-** subject to change in future versions of SQLite.
+** might provide greater resolution on the profiler callback. Invoking
+** either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the
+** profile callback.
*/
SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
void(*xTrace)(void*,const char*), void*);
@@ -4446,6 +4468,8 @@ SQLITE_API int sqlite3_open_v2(
** is not a database file pathname pointer that SQLite passed into the xOpen
** VFS method, then the behavior of this routine is undefined and probably
** undesirable.
+**
+** See the [URI filename] documentation for additional information.
*/
SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
@@ -4668,18 +4692,23 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** deplete the limited store of lookaside memory. Future versions of
** SQLite may act on this hint differently.
**
-** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
-** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
-** representation of the SQL statement should be calculated and then
-** associated with the prepared statement, which can be obtained via
-** the [sqlite3_normalized_sql()] interface.)^ The semantics used to
-** normalize a SQL statement are unspecified and subject to change.
-** At a minimum, literal values will be replaced with suitable
-** placeholders.
+** [[SQLITE_PREPARE_NORMALIZE]] <dt>SQLITE_PREPARE_NORMALIZE</dt>
+** <dd>The SQLITE_PREPARE_NORMALIZE flag is a no-op. This flag used
+** to be required for any prepared statement that wanted to use the
+** [sqlite3_normalized_sql()] interface. However, the
+** [sqlite3_normalized_sql()] interface is now available to all
+** prepared statements, regardless of whether or not they use this
+** flag.
+**
+** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
+** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
+** to return an error (error code SQLITE_ERROR) if the statement uses
+** any virtual tables.
** </dl>
*/
#define SQLITE_PREPARE_PERSISTENT 0x01
#define SQLITE_PREPARE_NORMALIZE 0x02
+#define SQLITE_PREPARE_NO_VTAB 0x04
/*
** CAPI3REF: Compiling An SQL Statement
@@ -11035,7 +11064,7 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
** sqlite3changeset_next() is called on the iterator or until the
** conflict-handler function returns. If pnCol is not NULL, then *pnCol is
** set to the number of columns in the table affected by the change. If
-** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
+** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
** is an indirect change, or false (0) otherwise. See the documentation for
** [sqlite3session_indirect()] for a description of direct and indirect
** changes. Finally, if pOp is not NULL, then *pOp is set to one of
@@ -12269,12 +12298,8 @@ struct Fts5PhraseIter {
**
** Usually, output parameter *piPhrase is set to the phrase number, *piCol
** to the column in which it occurs and *piOff the token offset of the
-** first token of the phrase. The exception is if the table was created
-** with the offsets=0 option specified. In this case *piOff is always
-** set to -1.
-**
-** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
-** if an error occurs.
+** first token of the phrase. Returns SQLITE_OK if successful, or an error
+** code (i.e. SQLITE_NOMEM) if an error occurs.
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
@@ -12563,11 +12588,11 @@ struct Fts5ExtensionApi {
** the tokenizer substitutes "first" for "1st" and the query works
** as expected.
**
-** <li> By adding multiple synonyms for a single term to the FTS index.
-** In this case, when tokenizing query text, the tokenizer may
-** provide multiple synonyms for a single term within the document.
-** FTS5 then queries the index for each synonym individually. For
-** example, faced with the query:
+** <li> By querying the index for all synonyms of each query term
+** separately. In this case, when tokenizing query text, the
+** tokenizer may provide multiple synonyms for a single term
+** within the document. FTS5 then queries the index for each
+** synonym individually. For example, faced with the query:
**
** <codeblock>
** ... MATCH 'first place'</codeblock>
@@ -12591,7 +12616,7 @@ struct Fts5ExtensionApi {
** "place".
**
** This way, even if the tokenizer does not provide synonyms
-** when tokenizing query text (it should not - to do would be
+** when tokenizing query text (it should not - to do so would be
** inefficient), it doesn't matter if the user queries for
** 'first + place' or '1st + place', as there are entries in the
** FTS index corresponding to both forms of the first token.
@@ -14535,6 +14560,7 @@ SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
+SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
@@ -14774,12 +14800,11 @@ typedef struct VdbeOpList VdbeOpList;
#endif
/*
-** The following macro converts a relative address in the p2 field
-** of a VdbeOp structure into a negative number so that
-** sqlite3VdbeAddOpList() knows that the address is relative. Calling
-** the macro again restores the address.
+** The following macro converts a label returned by sqlite3VdbeMakeLabel()
+** into an index into the Parse.aLabel[] array that contains the resolved
+** address of that label.
*/
-#define ADDR(X) (-1-(X))
+#define ADDR(X) (~(X))
/*
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
@@ -15055,6 +15080,12 @@ SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse*);
# define ExplainQueryPlan(P)
# define ExplainQueryPlanPop(P)
# define ExplainQueryPlanParent(P) 0
+# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
+#endif
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN)
+SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char*,const char*);
+#else
+# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
#endif
SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
@@ -15070,7 +15101,7 @@ SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);
SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
+SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*);
SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
@@ -15091,6 +15122,10 @@ SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8);
+#ifdef SQLITE_ENABLE_NORMALIZE
+SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3*,Vdbe*,const char*);
+SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*);
+#endif
SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
@@ -16216,10 +16251,13 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing
** in the style of sqlite3_trace()
*/
-#define SQLITE_TRACE_LEGACY 0x80
+#define SQLITE_TRACE_LEGACY 0x40 /* Use the legacy xTrace */
+#define SQLITE_TRACE_XPROFILE 0x80 /* Use the legacy xProfile */
#else
-#define SQLITE_TRACE_LEGACY 0
+#define SQLITE_TRACE_LEGACY 0
+#define SQLITE_TRACE_XPROFILE 0
#endif /* SQLITE_OMIT_DEPRECATED */
+#define SQLITE_TRACE_NONLEGACY_MASK 0x0f /* Normal flags */
/*
@@ -16278,8 +16316,10 @@ struct sqlite3 {
void **aExtension; /* Array of shared library handles */
int (*xTrace)(u32,void*,void*,void*); /* Trace function */
void *pTraceArg; /* Argument to the trace function */
+#ifndef SQLITE_OMIT_DEPRECATED
void (*xProfile)(void*,const char*,u64); /* Profiling function */
void *pProfileArg; /* Argument to profile function */
+#endif
void *pCommitArg; /* Argument to xCommitCallback() */
int (*xCommitCallback)(void*); /* Invoked at every commit. */
void *pRollbackArg; /* Argument to xRollbackCallback() */
@@ -16410,6 +16450,7 @@ struct sqlite3 {
#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */
#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */
#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */
+#define SQLITE_ParserTrace HI(0x0020) /* PRAGMA parser_trace=ON */
#endif
/*
@@ -16812,9 +16853,6 @@ struct VTable {
struct Table {
char *zName; /* Name of the table or view */
Column *aCol; /* Information about each column */
-#ifdef SQLITE_ENABLE_NORMALIZE
- Hash *pColHash; /* All columns indexed by name */
-#endif
Index *pIndex; /* List of SQL indexes on this table. */
Select *pSelect; /* NULL for tables. Points to definition if a view. */
FKey *pFKey; /* Linked list of all foreign keys in this table */
@@ -17101,7 +17139,7 @@ struct Index {
u16 nKeyCol; /* Number of columns forming the key */
u16 nColumn; /* Number of columns stored in the index */
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
- unsigned idxType:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
+ unsigned idxType:2; /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */
unsigned bUnordered:1; /* Use this index for == or IN queries only */
unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */
unsigned isResized:1; /* True if resizeIndexObject() has been called */
@@ -17126,6 +17164,7 @@ struct Index {
#define SQLITE_IDXTYPE_APPDEF 0 /* Created using CREATE INDEX */
#define SQLITE_IDXTYPE_UNIQUE 1 /* Implements a UNIQUE constraint */
#define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */
+#define SQLITE_IDXTYPE_IPK 3 /* INTEGER PRIMARY KEY index */
/* Return true if index X is a PRIMARY KEY index */
#define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY)
@@ -17343,6 +17382,10 @@ struct Expr {
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
** for a column of an index on an expression */
Window *pWin; /* TK_FUNCTION: Window definition for the func */
+ struct { /* TK_IN, TK_SELECT, and TK_EXISTS */
+ int iAddr; /* Subroutine entry address */
+ int regReturn; /* Register used to hold return address */
+ } sub;
} y;
};
@@ -17374,6 +17417,8 @@ struct Expr {
#define EP_Alias 0x400000 /* Is an alias for a result set column */
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
+#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
+#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
/*
** The EP_Propagate mask is a set of properties that automatically propagate
@@ -17917,16 +17962,17 @@ struct Parse {
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
u8 okConstFactor; /* OK to factor out constants */
u8 disableLookaside; /* Number of times lookaside has been disabled */
+ u8 disableVtab; /* Disable all virtual tables for this parse */
int nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */
int nErr; /* Number of errors seen */
int nTab; /* Number of previously allocated VDBE cursors */
int nMem; /* Number of memory cells used so far */
- int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
int iSelfTab; /* Table associated with an index on expr, or negative
** of the base register during check-constraint eval */
- int nLabel; /* Number of labels used */
+ int nLabel; /* The *negative* of the number of labels used */
+ int nLabelAlloc; /* Number of slots in aLabel */
int *aLabel; /* Space to hold the labels */
ExprList *pConstExpr;/* Constant expressions */
Token constraintName;/* Name of the constraint currently being parsed */
@@ -17986,7 +18032,9 @@ struct Parse {
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
const char *zTail; /* All SQL text past the last semicolon parsed */
Table *pNewTable; /* A table being constructed by CREATE TABLE */
- Index *pNewIndex; /* An index being constructed by CREATE INDEX */
+ Index *pNewIndex; /* An index being constructed by CREATE INDEX.
+ ** Also used to hold redundant UNIQUE constraints
+ ** during a RENAME COLUMN */
Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -18214,6 +18262,7 @@ typedef struct {
int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */
int rc; /* Result code stored here */
u32 mInitFlags; /* Flags controlling error messages */
+ u32 nInitRow; /* Number of rows processed */
} InitData;
/*
@@ -18274,6 +18323,9 @@ struct Sqlite3Config {
void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx); /* Callback */
void *pVdbeBranchArg; /* 1st argument */
#endif
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ sqlite3_int64 mxMemdbSize; /* Default max memdb size */
+#endif
#ifndef SQLITE_UNTESTABLE
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
#endif
@@ -18662,6 +18714,7 @@ SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
SQLITE_PRIVATE void sqlite3Dequote(char*);
+SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*);
SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*);
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
@@ -18690,6 +18743,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
+SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*);
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32);
@@ -18723,6 +18777,11 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
sqlite3_vfs**,char**,char **);
+#ifdef SQLITE_HAS_CODEC
+SQLITE_PRIVATE int sqlite3CodecQueryParameters(sqlite3*,const char*,const char*);
+#else
+# define sqlite3CodecQueryParameters(A,B,C) 0
+#endif
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
#ifdef SQLITE_UNTESTABLE
@@ -18775,8 +18834,8 @@ SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upser
SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*);
SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
-SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
-SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
+SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
+SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
Token*, Select*, Expr*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
@@ -18843,8 +18902,8 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_ite
SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
-SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*);
-SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int);
+SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*);
+SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*);
SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3ExprCompare(Parse*,Expr*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int);
@@ -18882,9 +18941,6 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
-#ifdef SQLITE_ENABLE_NORMALIZE
-SQLITE_PRIVATE int sqlite3IsRowidN(const char*, int);
-#endif
SQLITE_PRIVATE void sqlite3GenerateRowDelete(
Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
@@ -18911,9 +18967,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
-#ifdef SQLITE_ENABLE_NORMALIZE
-SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(int,const char*,int);
-#endif
+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*);
SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
@@ -19118,19 +19172,17 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(void);
SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
-#ifdef SQLITE_ENABLE_NORMALIZE
-SQLITE_PRIVATE int sqlite3GetTokenNormalized(const unsigned char *, int *, int *);
-#endif
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
-SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
+SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int, int);
+SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*);
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
-SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
+SQLITE_PRIVATE int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -19279,7 +19331,7 @@ SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
#ifdef SQLITE_ENABLE_NORMALIZE
-SQLITE_PRIVATE void sqlite3Normalize(Vdbe*, const char*, int, u8);
+SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*);
#endif
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
@@ -19375,7 +19427,7 @@ SQLITE_PRIVATE void sqlite3EndBenignMalloc(void);
#define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */
#define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */
#define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*);
+SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*);
SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
@@ -19691,6 +19743,13 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
#endif
+/* The default maximum size of an in-memory database created using
+** sqlite3_deserialize()
+*/
+#ifndef SQLITE_MEMDB_DEFAULT_MAXSIZE
+# define SQLITE_MEMDB_DEFAULT_MAXSIZE 1073741824
+#endif
+
/*
** The following singleton contains the global configuration for
** the SQLite library.
@@ -19738,13 +19797,16 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* xVdbeBranch */
0, /* pVbeBranchArg */
#endif
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ SQLITE_MEMDB_DEFAULT_MAXSIZE, /* mxMemdbSize */
+#endif
#ifndef SQLITE_UNTESTABLE
0, /* xTestCallback */
#endif
0, /* bLocaltimeFault */
0, /* bInternalFunctions */
0x7ffffffe, /* iOnceResetThreshold */
- SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */
+ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
};
/*
@@ -20163,6 +20225,9 @@ struct sqlite3_context {
*/
typedef unsigned bft; /* Bit Field Type */
+/* The ScanStatus object holds a single value for the
+** sqlite3_stmt_scanstatus() interface.
+*/
typedef struct ScanStatus ScanStatus;
struct ScanStatus {
int addrExplain; /* OP_Explain for loop */
@@ -20173,6 +20238,19 @@ struct ScanStatus {
char *zName; /* Name of table or index */
};
+/* The DblquoteStr object holds the text of a double-quoted
+** string for a prepared statement. A linked list of these objects
+** is constructed during statement parsing and is held on Vdbe.pDblStr.
+** When computing a normalized SQL statement for an SQL statement, that
+** list is consulted for each double-quoted identifier to see if the
+** identifier should really be a string literal.
+*/
+typedef struct DblquoteStr DblquoteStr;
+struct DblquoteStr {
+ DblquoteStr *pNextStr; /* Next string literal in the list */
+ char z[8]; /* Dequoted value for the string */
+};
+
/*
** An instance of the virtual machine. This structure contains the complete
** state of the virtual machine.
@@ -20192,28 +20270,29 @@ struct Vdbe {
int pc; /* The program counter */
int rc; /* Value to return */
int nChange; /* Number of db changes made since last reset */
- int iStatement; /* Statement number (or 0 if has not opened stmt) */
+ int iStatement; /* Statement number (or 0 if has no opened stmt) */
i64 iCurrentTime; /* Value of julianday('now') for this statement */
i64 nFkConstraint; /* Number of imm. FK constraints this VM */
i64 nStmtDefCons; /* Number of def. constraints when stmt started */
i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
+ Mem *aMem; /* The memory locations */
+ Mem **apArg; /* Arguments to currently executing user function */
+ VdbeCursor **apCsr; /* One element of this array for each open cursor */
+ Mem *aVar; /* Values for the OP_Variable opcode. */
/* When allocating a new Vdbe object, all of the fields below should be
** initialized to zero or NULL */
Op *aOp; /* Space to hold the virtual machine's program */
- Mem *aMem; /* The memory locations */
- Mem **apArg; /* Arguments to currently executing user function */
+ int nOp; /* Number of instructions in the program */
+ int nOpAlloc; /* Slots allocated for aOp[] */
Mem *aColName; /* Column names to return */
Mem *pResultSet; /* Pointer to an array of results */
char *zErrMsg; /* Error message written here */
- VdbeCursor **apCsr; /* One element of this array for each open cursor */
- Mem *aVar; /* Values for the OP_Variable opcode. */
VList *pVList; /* Name of variables */
#ifndef SQLITE_OMIT_TRACE
i64 startTime; /* Time when query started - used for profiling */
#endif
- int nOp; /* Number of instructions in the program */
#ifdef SQLITE_DEBUG
int rcApp; /* errcode set by sqlite3_result_error_code() */
u32 nWrite; /* Number of write operations that have occurred */
@@ -20236,6 +20315,7 @@ struct Vdbe {
char *zSql; /* Text of the SQL statement that generated this */
#ifdef SQLITE_ENABLE_NORMALIZE
char *zNormSql; /* Normalization of the associated SQL statement */
+ DblquoteStr *pDblStr; /* List of double-quoted string literals */
#endif
void *pFree; /* Free this when deleting the vdbe */
VdbeFrame *pFrame; /* Parent frame */
@@ -27253,6 +27333,27 @@ static char *getTextArg(PrintfArguments *p){
return (char*)sqlite3_value_text(p->apArg[p->nUsed++]);
}
+/*
+** Allocate memory for a temporary buffer needed for printf rendering.
+**
+** If the requested size of the temp buffer is larger than the size
+** of the output buffer in pAccum, then cause an SQLITE_TOOBIG error.
+** Do the size check before the memory allocation to prevent rogue
+** SQL from requesting large allocations using the precision or width
+** field of the printf() function.
+*/
+static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){
+ char *z;
+ if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){
+ setStrAccumError(pAccum, SQLITE_TOOBIG);
+ return 0;
+ }
+ z = sqlite3DbMallocRaw(pAccum->db, n);
+ if( z==0 ){
+ setStrAccumError(pAccum, SQLITE_NOMEM);
+ }
+ return z;
+}
/*
** On machines with a small stack size, you can redefine the
@@ -27335,6 +27436,9 @@ SQLITE_API void sqlite3_str_vappendf(
flag_leftjustify = flag_prefix = cThousand =
flag_alternateform = flag_altform2 = flag_zeropad = 0;
done = 0;
+ width = 0;
+ flag_long = 0;
+ precision = -1;
do{
switch( c ){
case '-': flag_leftjustify = 1; break;
@@ -27345,80 +27449,93 @@ SQLITE_API void sqlite3_str_vappendf(
case '0': flag_zeropad = 1; break;
case ',': cThousand = ','; break;
default: done = 1; break;
- }
- }while( !done && (c=(*++fmt))!=0 );
- /* Get the field width */
- if( c=='*' ){
- if( bArgList ){
- width = (int)getIntArg(pArgList);
- }else{
- width = va_arg(ap,int);
- }
- if( width<0 ){
- flag_leftjustify = 1;
- width = width >= -2147483647 ? -width : 0;
- }
- c = *++fmt;
- }else{
- unsigned wx = 0;
- while( c>='0' && c<='9' ){
- wx = wx*10 + c - '0';
- c = *++fmt;
- }
- testcase( wx>0x7fffffff );
- width = wx & 0x7fffffff;
- }
- assert( width>=0 );
+ case 'l': {
+ flag_long = 1;
+ c = *++fmt;
+ if( c=='l' ){
+ c = *++fmt;
+ flag_long = 2;
+ }
+ done = 1;
+ break;
+ }
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9': {
+ unsigned wx = c - '0';
+ while( (c = *++fmt)>='0' && c<='9' ){
+ wx = wx*10 + c - '0';
+ }
+ testcase( wx>0x7fffffff );
+ width = wx & 0x7fffffff;
#ifdef SQLITE_PRINTF_PRECISION_LIMIT
- if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
- width = SQLITE_PRINTF_PRECISION_LIMIT;
- }
+ if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
+ width = SQLITE_PRINTF_PRECISION_LIMIT;
+ }
#endif
-
- /* Get the precision */
- if( c=='.' ){
- c = *++fmt;
- if( c=='*' ){
- if( bArgList ){
- precision = (int)getIntArg(pArgList);
- }else{
- precision = va_arg(ap,int);
+ if( c!='.' && c!='l' ){
+ done = 1;
+ }else{
+ fmt--;
+ }
+ break;
}
- c = *++fmt;
- if( precision<0 ){
- precision = precision >= -2147483647 ? -precision : -1;
+ case '*': {
+ if( bArgList ){
+ width = (int)getIntArg(pArgList);
+ }else{
+ width = va_arg(ap,int);
+ }
+ if( width<0 ){
+ flag_leftjustify = 1;
+ width = width >= -2147483647 ? -width : 0;
+ }
+#ifdef SQLITE_PRINTF_PRECISION_LIMIT
+ if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
+ width = SQLITE_PRINTF_PRECISION_LIMIT;
+ }
+#endif
+ if( (c = fmt[1])!='.' && c!='l' ){
+ c = *++fmt;
+ done = 1;
+ }
+ break;
}
- }else{
- unsigned px = 0;
- while( c>='0' && c<='9' ){
- px = px*10 + c - '0';
+ case '.': {
c = *++fmt;
- }
- testcase( px>0x7fffffff );
- precision = px & 0x7fffffff;
- }
- }else{
- precision = -1;
- }
- assert( precision>=(-1) );
+ if( c=='*' ){
+ if( bArgList ){
+ precision = (int)getIntArg(pArgList);
+ }else{
+ precision = va_arg(ap,int);
+ }
+ if( precision<0 ){
+ precision = precision >= -2147483647 ? -precision : -1;
+ }
+ c = *++fmt;
+ }else{
+ unsigned px = 0;
+ while( c>='0' && c<='9' ){
+ px = px*10 + c - '0';
+ c = *++fmt;
+ }
+ testcase( px>0x7fffffff );
+ precision = px & 0x7fffffff;
+ }
#ifdef SQLITE_PRINTF_PRECISION_LIMIT
- if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
- precision = SQLITE_PRINTF_PRECISION_LIMIT;
- }
+ if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
+ precision = SQLITE_PRINTF_PRECISION_LIMIT;
+ }
#endif
-
-
- /* Get the conversion type modifier */
- if( c=='l' ){
- flag_long = 1;
- c = *++fmt;
- if( c=='l' ){
- flag_long = 2;
- c = *++fmt;
+ if( c=='l' ){
+ --fmt;
+ }else{
+ done = 1;
+ }
+ break;
+ }
}
- }else{
- flag_long = 0;
- }
+ }while( !done && (c=(*++fmt))!=0 );
+
/* Fetch the info entry for the field */
infop = &fmtinfo[0];
xtype = etINVALID;
@@ -27503,12 +27620,11 @@ SQLITE_API void sqlite3_str_vappendf(
nOut = etBUFSIZE;
zOut = buf;
}else{
- u64 n = (u64)precision + 10 + precision/3;
- zOut = zExtra = sqlite3Malloc( n );
- if( zOut==0 ){
- setStrAccumError(pAccum, SQLITE_NOMEM);
- return;
- }
+ u64 n;
+ n = (u64)precision + 10;
+ if( cThousand ) n += precision/3;
+ zOut = zExtra = printfTempBuf(pAccum, n);
+ if( zOut==0 ) return;
nOut = (int)n;
}
bufpt = &zOut[nOut-1];
@@ -27627,12 +27743,12 @@ SQLITE_API void sqlite3_str_vappendf(
}else{
e2 = exp;
}
- if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
- bufpt = zExtra
- = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
- if( bufpt==0 ){
- setStrAccumError(pAccum, SQLITE_NOMEM);
- return;
+ {
+ i64 szBufNeeded; /* Size of a temporary buffer needed */
+ szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15;
+ if( szBufNeeded > etBUFSIZE ){
+ bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded);
+ if( bufpt==0 ) return;
}
}
zOut = bufpt;
@@ -27856,11 +27972,8 @@ SQLITE_API void sqlite3_str_vappendf(
needQuote = !isnull && xtype==etSQLESCAPE2;
n += i + 3;
if( n>etBUFSIZE ){
- bufpt = zExtra = sqlite3Malloc( n );
- if( bufpt==0 ){
- setStrAccumError(pAccum, SQLITE_NOMEM);
- return;
- }
+ bufpt = zExtra = printfTempBuf(pAccum, n);
+ if( bufpt==0 ) return;
}else{
bufpt = buf;
}
@@ -28486,7 +28599,8 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc)
sqlite3_str_appendf(&x, " %s", pItem->zName);
}
if( pItem->pTab ){
- sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
+ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p",
+ pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab);
}
if( pItem->zAlias ){
sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
@@ -30226,7 +30340,7 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
** dequoted string, exclusive of the zero terminator, if dequoting does
** occur.
**
-** 2002-Feb-14: This routine is extended to remove MS-Access style
+** 2002-02-14: This routine is extended to remove MS-Access style
** brackets from around identifiers. For example: "[a-b-c]" becomes
** "a-b-c".
*/
@@ -30252,6 +30366,11 @@ SQLITE_PRIVATE void sqlite3Dequote(char *z){
}
z[j] = 0;
}
+SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){
+ assert( sqlite3Isquote(p->u.zToken[0]) );
+ p->flags |= p->u.zToken[0]=='"' ? EP_Quoted|EP_DblQuoted : EP_Quoted;
+ sqlite3Dequote(p->u.zToken);
+}
/*
** Generate a Token object from a string
@@ -31679,20 +31798,6 @@ static unsigned int strHash(const char *z){
}
return h;
}
-#ifdef SQLITE_ENABLE_NORMALIZE
-static unsigned int strHashN(const char *z, int n){
- unsigned int h = 0;
- int i;
- for(i=0; i<n; i++){
- /* Knuth multiplicative hashing. (Sorting & Searching, p. 510).
- ** 0x9e3779b1 is 2654435761 which is the closest prime number to
- ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
- h += sqlite3UpperToLower[z[i]];
- h *= 0x9e3779b1;
- }
- return h;
-}
-#endif /* SQLITE_ENABLE_NORMALIZE */
/* Link pNew element into the hash table pH. If pEntry!=0 then also
@@ -31804,40 +31909,6 @@ static HashElem *findElementWithHash(
}
return &nullElement;
}
-#ifdef SQLITE_ENABLE_NORMALIZE
-static HashElem *findElementWithHashN(
- const Hash *pH, /* The pH to be searched */
- const char *pKey, /* The key we are searching for */
- int nKey, /* Number of key bytes to use */
- unsigned int *pHash /* Write the hash value here */
-){
- HashElem *elem; /* Used to loop thru the element list */
- int count; /* Number of elements left to test */
- unsigned int h; /* The computed hash */
- static HashElem nullElement = { 0, 0, 0, 0 };
-
- if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
- struct _ht *pEntry;
- h = strHashN(pKey, nKey) % pH->htsize;
- pEntry = &pH->ht[h];
- elem = pEntry->chain;
- count = pEntry->count;
- }else{
- h = 0;
- elem = pH->first;
- count = pH->count;
- }
- if( pHash ) *pHash = h;
- while( count-- ){
- assert( elem!=0 );
- if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){
- return elem;
- }
- elem = elem->next;
- }
- return &nullElement;
-}
-#endif /* SQLITE_ENABLE_NORMALIZE */
/* Remove a single entry from the hash table given a pointer to that
** element and a hash on the element's key.
@@ -31882,14 +31953,6 @@ SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){
assert( pKey!=0 );
return findElementWithHash(pH, pKey, 0)->data;
}
-#ifdef SQLITE_ENABLE_NORMALIZE
-SQLITE_PRIVATE void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){
- assert( pH!=0 );
- assert( pKey!=0 );
- assert( nKey>=0 );
- return findElementWithHashN(pH, pKey, nKey, 0)->data;
-}
-#endif /* SQLITE_ENABLE_NORMALIZE */
/* Insert an element into the hash table pH. The key is pKey
** and the data is "data".
@@ -46577,7 +46640,8 @@ typedef struct MemFile MemFile;
struct MemFile {
sqlite3_file base; /* IO methods */
sqlite3_int64 sz; /* Size of the file */
- sqlite3_int64 szMax; /* Space allocated to aData */
+ sqlite3_int64 szAlloc; /* Space allocated to aData */
+ sqlite3_int64 szMax; /* Maximum allowed size of the file */
unsigned char *aData; /* content of the file */
int nMmap; /* Number of memory mapped pages */
unsigned mFlags; /* Flags */
@@ -46703,10 +46767,15 @@ static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
return SQLITE_FULL;
}
+ if( newSz>p->szMax ){
+ return SQLITE_FULL;
+ }
+ newSz *= 2;
+ if( newSz>p->szMax ) newSz = p->szMax;
pNew = sqlite3_realloc64(p->aData, newSz);
if( pNew==0 ) return SQLITE_NOMEM;
p->aData = pNew;
- p->szMax = newSz;
+ p->szAlloc = newSz;
return SQLITE_OK;
}
@@ -46720,10 +46789,11 @@ static int memdbWrite(
sqlite_int64 iOfst
){
MemFile *p = (MemFile *)pFile;
+ if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ) return SQLITE_READONLY;
if( iOfst+iAmt>p->sz ){
int rc;
- if( iOfst+iAmt>p->szMax
- && (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK
+ if( iOfst+iAmt>p->szAlloc
+ && (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK
){
return rc;
}
@@ -46769,6 +46839,11 @@ static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
*/
static int memdbLock(sqlite3_file *pFile, int eLock){
MemFile *p = (MemFile *)pFile;
+ if( eLock>SQLITE_LOCK_SHARED
+ && (p->mFlags & SQLITE_DESERIALIZE_READONLY)!=0
+ ){
+ return SQLITE_READONLY;
+ }
p->eLock = eLock;
return SQLITE_OK;
}
@@ -46793,6 +46868,19 @@ static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
*(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
rc = SQLITE_OK;
}
+ if( op==SQLITE_FCNTL_SIZE_LIMIT ){
+ sqlite3_int64 iLimit = *(sqlite3_int64*)pArg;
+ if( iLimit<p->sz ){
+ if( iLimit<0 ){
+ iLimit = p->szMax;
+ }else{
+ iLimit = p->sz;
+ }
+ }
+ p->szMax = iLimit;
+ *(sqlite3_int64*)pArg = iLimit;
+ rc = SQLITE_OK;
+ }
return rc;
}
@@ -46823,8 +46911,12 @@ static int memdbFetch(
void **pp
){
MemFile *p = (MemFile *)pFile;
- p->nMmap++;
- *pp = (void*)(p->aData + iOfst);
+ if( iOfst+iAmt>p->sz ){
+ *pp = 0;
+ }else{
+ p->nMmap++;
+ *pp = (void*)(p->aData + iOfst);
+ }
return SQLITE_OK;
}
@@ -46854,6 +46946,7 @@ static int memdbOpen(
assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
*pOutFlags = flags | SQLITE_OPEN_MEMORY;
p->base.pMethods = &memdb_io_methods;
+ p->szMax = sqlite3GlobalConfig.mxMemdbSize;
return SQLITE_OK;
}
@@ -47103,7 +47196,11 @@ SQLITE_API int sqlite3_deserialize(
}else{
p->aData = pData;
p->sz = szDb;
+ p->szAlloc = szBuf;
p->szMax = szBuf;
+ if( p->szMax<sqlite3GlobalConfig.mxMemdbSize ){
+ p->szMax = sqlite3GlobalConfig.mxMemdbSize;
+ }
p->mFlags = mFlags;
rc = SQLITE_OK;
}
@@ -48524,16 +48621,27 @@ typedef struct PGroup PGroup;
** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
** PgHdr1.pCache->szPage bytes is allocated directly before this structure
** in memory.
+**
+** Note: Variables isBulkLocal and isAnchor were once type "u8". That works,
+** but causes a 2-byte gap in the structure for most architectures (since
+** pointers must be either 4 or 8-byte aligned). As this structure is located
+** in memory directly after the associated page data, if the database is
+** corrupt, code at the b-tree layer may overread the page buffer and
+** read part of this structure before the corruption is detected. This
+** can cause a valgrind error if the unitialized gap is accessed. Using u16
+** ensures there is no such gap, and therefore no bytes of unitialized memory
+** in the structure.
*/
struct PgHdr1 {
sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */
unsigned int iKey; /* Key value (page number) */
- u8 isBulkLocal; /* This page from bulk local storage */
- u8 isAnchor; /* This is the PGroup.lru element */
+ u16 isBulkLocal; /* This page from bulk local storage */
+ u16 isAnchor; /* This is the PGroup.lru element */
PgHdr1 *pNext; /* Next in hash table chain */
PCache1 *pCache; /* Cache that currently owns this page */
PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
+ /* NB: pLruPrev is only valid if pLruNext!=0 */
};
/*
@@ -48599,6 +48707,7 @@ struct PCache1 {
unsigned int nMax; /* Configured "cache_size" value */
unsigned int n90pct; /* nMax*9/10 */
unsigned int iMaxKey; /* Largest key seen since xTruncate() */
+ unsigned int nPurgeableDummy; /* pnPurgeable points here when not used*/
/* Hash table of all pages. The following variables may only be accessed
** when the accessor is holding the PGroup mutex.
@@ -48733,6 +48842,7 @@ static int pcache1InitBulk(PCache1 *pCache){
pX->isBulkLocal = 1;
pX->isAnchor = 0;
pX->pNext = pCache->pFree;
+ pX->pLruPrev = 0; /* Initializing this saves a valgrind error */
pCache->pFree = pX;
zBulk += pCache->szAlloc;
}while( --nBulk );
@@ -48908,6 +49018,9 @@ static void pcache1FreePage(PgHdr1 *p){
** exists, this function falls back to sqlite3Malloc().
*/
SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){
+ /* During rebalance operations on a corrupt database file, it is sometimes
+ ** (rarely) possible to overread the temporary page buffer by a few bytes.
+ ** Enlarge the allocation slightly so that this does not cause problems. */
return pcache1Alloc(sz);
}
@@ -49002,7 +49115,8 @@ static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){
pPage->pLruPrev->pLruNext = pPage->pLruNext;
pPage->pLruNext->pLruPrev = pPage->pLruPrev;
pPage->pLruNext = 0;
- pPage->pLruPrev = 0;
+ /* pPage->pLruPrev = 0;
+ ** No need to clear pLruPrev as it is never accessed if pLruNext is 0 */
assert( pPage->isAnchor==0 );
assert( pPage->pCache->pGroup->lru.isAnchor==1 );
pPage->pCache->nRecyclable--;
@@ -49212,8 +49326,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
pCache->pnPurgeable = &pGroup->nPurgeable;
}else{
- static unsigned int dummyCurrentPage;
- pCache->pnPurgeable = &dummyCurrentPage;
+ pCache->pnPurgeable = &pCache->nPurgeableDummy;
}
pcache1LeaveMutex(pGroup);
if( pCache->nHash==0 ){
@@ -49340,8 +49453,9 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
pPage->iKey = iKey;
pPage->pNext = pCache->apHash[h];
pPage->pCache = pCache;
- pPage->pLruPrev = 0;
pPage->pLruNext = 0;
+ /* pPage->pLruPrev = 0;
+ ** No need to clear pLruPrev since it is not accessed when pLruNext==0 */
*(void **)pPage->page.pExtra = 0;
pCache->apHash[h] = pPage;
if( iKey>pCache->iMaxKey ){
@@ -49501,7 +49615,7 @@ static void pcache1Unpin(
/* It is an error to call this function if the page is already
** part of the PGroup LRU list.
*/
- assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
+ assert( pPage->pLruNext==0 );
assert( PAGE_IS_PINNED(pPage) );
if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){
@@ -54192,7 +54306,10 @@ SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
pPager->mxPgno = mxPage;
}
assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */
- assert( pPager->mxPgno>=pPager->dbSize ); /* OP_MaxPgcnt enforces this */
+ /* assert( pPager->mxPgno>=pPager->dbSize ); */
+ /* OP_MaxPgcnt ensures that the parameter passed to this function is not
+ ** less than the total number of valid pages in the database. But this
+ ** may be less than Pager.dbSize, and so the assert() above is not valid */
return pPager->mxPgno;
}
@@ -62431,9 +62548,16 @@ struct CellInfo {
** found at self->pBt->mutex.
**
** skipNext meaning:
-** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op.
-** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op.
-** eState==FAULT: Cursor fault with skipNext as error code.
+** The meaning of skipNext depends on the value of eState:
+**
+** eState Meaning of skipNext
+** VALID skipNext is meaningless and is ignored
+** INVALID skipNext is meaningless and is ignored
+** SKIPNEXT sqlite3BtreeNext() is a no-op if skipNext>0 and
+** sqlite3BtreePrevious() is no-op if skipNext<0.
+** REQUIRESEEK restoreCursorPosition() restores the cursor to
+** eState=SKIPNEXT if skipNext!=0
+** FAULT skipNext holds the cursor fault error code.
*/
struct BtCursor {
u8 eState; /* One of the CURSOR_XXX constants (see below) */
@@ -63597,13 +63721,19 @@ static int saveCursorKey(BtCursor *pCur){
/* Only the rowid is required for a table btree */
pCur->nKey = sqlite3BtreeIntegerKey(pCur);
}else{
- /* For an index btree, save the complete key content */
+ /* For an index btree, save the complete key content. It is possible
+ ** that the current key is corrupt. In that case, it is possible that
+ ** the sqlite3VdbeRecordUnpack() function may overread the buffer by
+ ** up to the size of 1 varint plus 1 8-byte value when the cursor
+ ** position is restored. Hence the 17 bytes of padding allocated
+ ** below. */
void *pKey;
pCur->nKey = sqlite3BtreePayloadSize(pCur);
- pKey = sqlite3Malloc( pCur->nKey );
+ pKey = sqlite3Malloc( pCur->nKey + 9 + 8 );
if( pKey ){
rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey);
if( rc==SQLITE_OK ){
+ memset(((u8*)pKey)+pCur->nKey, 0, 9+8);
pCur->pKey = pKey;
}else{
sqlite3_free(pKey);
@@ -63735,11 +63865,12 @@ static int btreeMoveto(
UnpackedRecord *pIdxKey; /* Unpacked index key */
if( pKey ){
+ KeyInfo *pKeyInfo = pCur->pKeyInfo;
assert( nKey==(i64)(int)nKey );
- pIdxKey = sqlite3VdbeAllocUnpackedRecord(pCur->pKeyInfo);
+ pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
- sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
- if( pIdxKey->nField==0 ){
+ sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey);
+ if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){
rc = SQLITE_CORRUPT_BKPT;
goto moveto_done;
}
@@ -63775,7 +63906,7 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){
sqlite3_free(pCur->pKey);
pCur->pKey = 0;
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
- pCur->skipNext |= skipNext;
+ if( skipNext ) pCur->skipNext = skipNext;
if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
pCur->eState = CURSOR_SKIPNEXT;
}
@@ -63845,7 +63976,6 @@ SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow)
if( pCur->eState!=CURSOR_VALID ){
*pDifferentRow = 1;
}else{
- assert( pCur->skipNext==0 );
*pDifferentRow = 0;
}
return SQLITE_OK;
@@ -63929,6 +64059,13 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
*pRC = rc;
return;
}
+ if( ((char*)sqlite3PagerGetExtra(pDbPage))[0]!=0 ){
+ /* The first byte of the extra data is the MemPage.isInit byte.
+ ** If that byte is set, it means this page is also being used
+ ** as a btree page. */
+ *pRC = SQLITE_CORRUPT_BKPT;
+ goto ptrmap_exit;
+ }
offset = PTRMAP_PTROFFSET(iPtrmap, key);
if( offset<0 ){
*pRC = SQLITE_CORRUPT_BKPT;
@@ -63991,7 +64128,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
#else /* if defined SQLITE_OMIT_AUTOVACUUM */
#define ptrmapPut(w,x,y,z,rc)
#define ptrmapGet(w,x,y,z) SQLITE_OK
- #define ptrmapPutOvflPtr(x, y, rc)
+ #define ptrmapPutOvflPtr(x, y, z, rc)
#endif
/*
@@ -64284,17 +64421,24 @@ static u16 cellSize(MemPage *pPage, int iCell){
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
-** If the cell pCell, part of page pPage contains a pointer
-** to an overflow page, insert an entry into the pointer-map
-** for the overflow page.
+** The cell pCell is currently part of page pSrc but will ultimately be part
+** of pPage. (pSrc and pPager are often the same.) If pCell contains a
+** pointer to an overflow page, insert an entry into the pointer-map for
+** the overflow page that will be valid after pCell has been moved to pPage.
*/
-static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
+static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
CellInfo info;
if( *pRC ) return;
assert( pCell!=0 );
pPage->xParseCell(pPage, pCell, &info);
if( info.nLocal<info.nPayload ){
- Pgno ovfl = get4byte(&pCell[info.nSize-4]);
+ Pgno ovfl;
+ if( SQLITE_WITHIN(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){
+ testcase( pSrc!=pPage );
+ *pRC = SQLITE_CORRUPT_BKPT;
+ return;
+ }
+ ovfl = get4byte(&pCell[info.nSize-4]);
ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
}
}
@@ -64349,19 +64493,14 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
** reconstruct the entire page. */
if( (int)data[hdr+7]<=nMaxFrag ){
int iFree = get2byte(&data[hdr+1]);
+
+ /* If the initial freeblock offset were out of bounds, that would
+ ** have been detected by btreeInitPage() when it was computing the
+ ** number of free bytes on the page. */
+ assert( iFree<=usableSize-4 );
if( iFree ){
int iFree2 = get2byte(&data[iFree]);
-
- /* pageFindSlot() has already verified that free blocks are sorted
- ** in order of offset within the page, and that no block extends
- ** past the end of the page. Provided the two free slots do not
- ** overlap, this guarantees that the memmove() calls below will not
- ** overwrite the usableSize byte buffer, even if the database page
- ** is corrupt. */
- assert( iFree2==0 || iFree2>iFree );
- assert( iFree+get2byte(&data[iFree+2]) <= usableSize );
- assert( iFree2==0 || iFree2+get2byte(&data[iFree2+2]) <= usableSize );
-
+ if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
u8 *pEnd = &data[cellOffset + nCell*2];
u8 *pAddr;
@@ -64372,9 +64511,9 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
return SQLITE_CORRUPT_PAGE(pPage);
}
if( iFree2 ){
- assert( iFree+sz<=iFree2 ); /* Verified by pageFindSlot() */
+ if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
sz2 = get2byte(&data[iFree2+2]);
- assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
+ if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
sz += sz2;
}
@@ -65929,9 +66068,9 @@ static int newDatabase(BtShared*);
static int lockBtree(BtShared *pBt){
int rc; /* Result code from subfunctions */
MemPage *pPage1; /* Page 1 of the database file */
- int nPage; /* Number of pages in the database */
- int nPageFile = 0; /* Number of pages in the database file */
- int nPageHeader; /* Number of pages in the database according to hdr */
+ u32 nPage; /* Number of pages in the database */
+ u32 nPageFile = 0; /* Number of pages in the database file */
+ u32 nPageHeader; /* Number of pages in the database according to hdr */
assert( sqlite3_mutex_held(pBt->mutex) );
assert( pBt->pPage1==0 );
@@ -65944,7 +66083,7 @@ static int lockBtree(BtShared *pBt){
** a valid database file.
*/
nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
- sqlite3PagerPagecount(pBt->pPager, &nPageFile);
+ sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile);
if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
nPage = nPageFile;
}
@@ -66025,6 +66164,7 @@ static int lockBtree(BtShared *pBt){
){
goto page1_init_failed;
}
+ pBt->btsFlags |= BTS_PAGESIZE_FIXED;
assert( (pageSize & 7)==0 );
/* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte
** integer at offset 20 is the number of bytes of space at the end of
@@ -66415,7 +66555,7 @@ static int setChildPtrmaps(MemPage *pPage){
for(i=0; i<nCell; i++){
u8 *pCell = findCell(pPage, i);
- ptrmapPutOvflPtr(pPage, pCell, &rc);
+ ptrmapPutOvflPtr(pPage, pPage, pCell, &rc);
if( !pPage->leaf ){
Pgno childPgno = get4byte(pCell);
@@ -67341,6 +67481,7 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
sqlite3_free(pCur->aOverflow);
sqlite3_free(pCur->pKey);
sqlite3BtreeLeave(pBtree);
+ pCur->pBtree = 0;
}
return SQLITE_OK;
}
@@ -67440,6 +67581,25 @@ SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){
}
/*
+** Return an upper bound on the size of any record for the table
+** that the cursor is pointing into.
+**
+** This is an optimization. Everything will still work if this
+** routine always returns 2147483647 (which is the largest record
+** that SQLite can handle) or more. But returning a smaller value might
+** prevent large memory allocations when trying to interpret a
+** corrupt datrabase.
+**
+** The current implementation merely returns the size of the underlying
+** database file.
+*/
+SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor *pCur){
+ assert( cursorHoldsMutex(pCur) );
+ assert( pCur->eState==CURSOR_VALID );
+ return pCur->pBt->pageSize * (sqlite3_int64)pCur->pBt->nPage;
+}
+
+/*
** Given the page number of an overflow page in the database (parameter
** ovfl), this function finds the page number of the next page in the
** linked list of overflow pages. If possible, it uses the auto-vacuum
@@ -68253,7 +68413,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
** try to get there using sqlite3BtreeNext() rather than a full
** binary search. This is an optimization only. The correct answer
** is still obtained without this case, only a little more slowely */
- if( pCur->info.nKey+1==intKey && !pCur->skipNext ){
+ if( pCur->info.nKey+1==intKey ){
*pRes = 0;
rc = sqlite3BtreeNext(pCur, 0);
if( rc==SQLITE_OK ){
@@ -68395,7 +68555,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */
testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */
testcase( nCell==2 ); /* Minimum legal index key size */
- if( nCell<2 ){
+ if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){
rc = SQLITE_CORRUPT_PAGE(pPage);
goto moveto_finish;
}
@@ -68527,7 +68687,6 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
MemPage *pPage;
assert( cursorOwnsBtShared(pCur) );
- assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
if( pCur->eState!=CURSOR_VALID ){
assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
rc = restoreCursorPosition(pCur);
@@ -68537,14 +68696,9 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
if( CURSOR_INVALID==pCur->eState ){
return SQLITE_DONE;
}
- if( pCur->skipNext ){
- assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+ if( pCur->eState==CURSOR_SKIPNEXT ){
pCur->eState = CURSOR_VALID;
- if( pCur->skipNext>0 ){
- pCur->skipNext = 0;
- return SQLITE_OK;
- }
- pCur->skipNext = 0;
+ if( pCur->skipNext>0 ) return SQLITE_OK;
}
}
@@ -68599,7 +68753,6 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){
UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */
assert( cursorOwnsBtShared(pCur) );
assert( flags==0 || flags==1 );
- assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur);
@@ -68640,7 +68793,6 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
MemPage *pPage;
assert( cursorOwnsBtShared(pCur) );
- assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
assert( pCur->info.nSize==0 );
if( pCur->eState!=CURSOR_VALID ){
@@ -68651,14 +68803,9 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
if( CURSOR_INVALID==pCur->eState ){
return SQLITE_DONE;
}
- if( pCur->skipNext ){
- assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+ if( CURSOR_SKIPNEXT==pCur->eState ){
pCur->eState = CURSOR_VALID;
- if( pCur->skipNext<0 ){
- pCur->skipNext = 0;
- return SQLITE_OK;
- }
- pCur->skipNext = 0;
+ if( pCur->skipNext<0 ) return SQLITE_OK;
}
}
@@ -68693,7 +68840,6 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int flags){
assert( cursorOwnsBtShared(pCur) );
assert( flags==0 || flags==1 );
- assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
pCur->info.nSize = 0;
@@ -69029,7 +69175,7 @@ static int allocateBtreePage(
TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
}
- assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
+ assert( CORRUPT_DB || *pPgno!=PENDING_BYTE_PAGE(pBt) );
end_allocate_page:
releasePage(pTrunk);
@@ -69584,9 +69730,16 @@ static void insertCell(
assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB );
assert( idx+sz <= (int)pPage->pBt->usableSize );
pPage->nFree -= (u16)(2 + sz);
- memcpy(&data[idx], pCell, sz);
if( iChild ){
+ /* In a corrupt database where an entry in the cell index section of
+ ** a btree page has a value of 3 or less, the pCell value might point
+ ** as many as 4 bytes in front of the start of the aData buffer for
+ ** the source page. Make sure this does not cause problems by not
+ ** reading the first 4 bytes */
+ memcpy(&data[idx+4], pCell+4, sz-4);
put4byte(&data[idx], iChild);
+ }else{
+ memcpy(&data[idx], pCell, sz);
}
pIns = pPage->aCellIdx + i*2;
memmove(pIns+2, pIns, 2*(pPage->nCell - i));
@@ -69600,15 +69753,89 @@ static void insertCell(
/* The cell may contain a pointer to an overflow page. If so, write
** the entry for the overflow page into the pointer map.
*/
- ptrmapPutOvflPtr(pPage, pCell, pRC);
+ ptrmapPutOvflPtr(pPage, pPage, pCell, pRC);
}
#endif
}
}
/*
+** The following parameters determine how many adjacent pages get involved
+** in a balancing operation. NN is the number of neighbors on either side
+** of the page that participate in the balancing operation. NB is the
+** total number of pages that participate, including the target page and
+** NN neighbors on either side.
+**
+** The minimum value of NN is 1 (of course). Increasing NN above 1
+** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
+** in exchange for a larger degradation in INSERT and UPDATE performance.
+** The value of NN appears to give the best results overall.
+**
+** (Later:) The description above makes it seem as if these values are
+** tunable - as if you could change them and recompile and it would all work.
+** But that is unlikely. NB has been 3 since the inception of SQLite and
+** we have never tested any other value.
+*/
+#define NN 1 /* Number of neighbors on either side of pPage */
+#define NB 3 /* (NN*2+1): Total pages involved in the balance */
+
+/*
** A CellArray object contains a cache of pointers and sizes for a
** consecutive sequence of cells that might be held on multiple pages.
+**
+** The cells in this array are the divider cell or cells from the pParent
+** page plus up to three child pages. There are a total of nCell cells.
+**
+** pRef is a pointer to one of the pages that contributes cells. This is
+** used to access information such as MemPage.intKey and MemPage.pBt->pageSize
+** which should be common to all pages that contribute cells to this array.
+**
+** apCell[] and szCell[] hold, respectively, pointers to the start of each
+** cell and the size of each cell. Some of the apCell[] pointers might refer
+** to overflow cells. In other words, some apCel[] pointers might not point
+** to content area of the pages.
+**
+** A szCell[] of zero means the size of that cell has not yet been computed.
+**
+** The cells come from as many as four different pages:
+**
+** -----------
+** | Parent |
+** -----------
+** / | \
+** / | \
+** --------- --------- ---------
+** |Child-1| |Child-2| |Child-3|
+** --------- --------- ---------
+**
+** The order of cells is in the array is for an index btree is:
+**
+** 1. All cells from Child-1 in order
+** 2. The first divider cell from Parent
+** 3. All cells from Child-2 in order
+** 4. The second divider cell from Parent
+** 5. All cells from Child-3 in order
+**
+** For a table-btree (with rowids) the items 2 and 4 are empty because
+** content exists only in leaves and there are no divider cells.
+**
+** For an index btree, the apEnd[] array holds pointer to the end of page
+** for Child-1, the Parent, Child-2, the Parent (again), and Child-3,
+** respectively. The ixNx[] array holds the number of cells contained in
+** each of these 5 stages, and all stages to the left. Hence:
+**
+** ixNx[0] = Number of cells in Child-1.
+** ixNx[1] = Number of cells in Child-1 plus 1 for first divider.
+** ixNx[2] = Number of cells in Child-1 and Child-2 + 1 for 1st divider.
+** ixNx[3] = Number of cells in Child-1 and Child-2 + both divider cells
+** ixNx[4] = Total number of cells.
+**
+** For a table-btree, the concept is similar, except only apEnd[0]..apEnd[2]
+** are used and they point to the leaf pages only, and the ixNx value are:
+**
+** ixNx[0] = Number of cells in Child-1.
+** ixNx[1] = Number of cells in Child-1 and Child-2 + 1 for 1st divider.
+** ixNx[2] = Number of cells in Child-1 and Child-2 + both divider cells
*/
typedef struct CellArray CellArray;
struct CellArray {
@@ -69616,6 +69843,8 @@ struct CellArray {
MemPage *pRef; /* Reference page */
u8 **apCell; /* All cells begin balanced */
u16 *szCell; /* Local size of all cells in apCell[] */
+ u8 *apEnd[NB*2]; /* MemPage.aDataEnd values */
+ int ixNx[NB*2]; /* Index of at which we move to the next apEnd[] */
};
/*
@@ -69666,36 +69895,59 @@ static u16 cachedCellSize(CellArray *p, int N){
** responsibility of the caller to set it correctly.
*/
static int rebuildPage(
- MemPage *pPg, /* Edit this page */
+ CellArray *pCArray, /* Content to be added to page pPg */
+ int iFirst, /* First cell in pCArray to use */
int nCell, /* Final number of cells on page */
- u8 **apCell, /* Array of cells */
- u16 *szCell /* Array of cell sizes */
+ MemPage *pPg /* The page to be reconstructed */
){
const int hdr = pPg->hdrOffset; /* Offset of header on pPg */
u8 * const aData = pPg->aData; /* Pointer to data for pPg */
const int usableSize = pPg->pBt->usableSize;
u8 * const pEnd = &aData[usableSize];
- int i;
+ int i = iFirst; /* Which cell to copy from pCArray*/
+ u32 j; /* Start of cell content area */
+ int iEnd = i+nCell; /* Loop terminator */
u8 *pCellptr = pPg->aCellIdx;
u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
u8 *pData;
+ int k; /* Current slot in pCArray->apEnd[] */
+ u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */
+
+ assert( i<iEnd );
+ j = get2byte(&aData[hdr+5]);
+ if( NEVER(j>(u32)usableSize) ){ j = 0; }
+ memcpy(&pTmp[j], &aData[j], usableSize - j);
- i = get2byte(&aData[hdr+5]);
- memcpy(&pTmp[i], &aData[i], usableSize - i);
+ for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
+ pSrcEnd = pCArray->apEnd[k];
pData = pEnd;
- for(i=0; i<nCell; i++){
- u8 *pCell = apCell[i];
+ while( 1/*exit by break*/ ){
+ u8 *pCell = pCArray->apCell[i];
+ u16 sz = pCArray->szCell[i];
+ assert( sz>0 );
if( SQLITE_WITHIN(pCell,aData,pEnd) ){
+ if( ((uptr)(pCell+sz))>(uptr)pEnd ) return SQLITE_CORRUPT_BKPT;
pCell = &pTmp[pCell - aData];
+ }else if( (uptr)(pCell+sz)>(uptr)pSrcEnd
+ && (uptr)(pCell)<(uptr)pSrcEnd
+ ){
+ return SQLITE_CORRUPT_BKPT;
}
- pData -= szCell[i];
+
+ pData -= sz;
put2byte(pCellptr, (pData - aData));
pCellptr += 2;
if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
- memcpy(pData, pCell, szCell[i]);
- assert( szCell[i]==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
- testcase( szCell[i]!=pPg->xCellSize(pPg,pCell) );
+ memcpy(pData, pCell, sz);
+ assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
+ testcase( sz!=pPg->xCellSize(pPg,pCell) );
+ i++;
+ if( i>=iEnd ) break;
+ if( pCArray->ixNx[k]<=i ){
+ k++;
+ pSrcEnd = pCArray->apEnd[k];
+ }
}
/* The pPg->nFree field is now set incorrectly. The caller will fix it. */
@@ -69710,12 +69962,11 @@ static int rebuildPage(
}
/*
-** Array apCell[] contains nCell pointers to b-tree cells. Array szCell
-** contains the size in bytes of each such cell. This function attempts to
-** add the cells stored in the array to page pPg. If it cannot (because
-** the page needs to be defragmented before the cells will fit), non-zero
-** is returned. Otherwise, if the cells are added successfully, zero is
-** returned.
+** The pCArray objects contains pointers to b-tree cells and the cell sizes.
+** This function attempts to add the cells stored in the array to page pPg.
+** If it cannot (because the page needs to be defragmented before the cells
+** will fit), non-zero is returned. Otherwise, if the cells are added
+** successfully, zero is returned.
**
** Argument pCellptr points to the first entry in the cell-pointer array
** (part of page pPg) to populate. After cell apCell[0] is written to the
@@ -69737,18 +69988,23 @@ static int rebuildPage(
static int pageInsertArray(
MemPage *pPg, /* Page to add cells to */
u8 *pBegin, /* End of cell-pointer array */
- u8 **ppData, /* IN/OUT: Page content -area pointer */
+ u8 **ppData, /* IN/OUT: Page content-area pointer */
u8 *pCellptr, /* Pointer to cell-pointer area */
int iFirst, /* Index of first cell to add */
int nCell, /* Number of cells to add to pPg */
CellArray *pCArray /* Array of cells */
){
- int i;
- u8 *aData = pPg->aData;
- u8 *pData = *ppData;
- int iEnd = iFirst + nCell;
+ int i = iFirst; /* Loop counter - cell index to insert */
+ u8 *aData = pPg->aData; /* Complete page */
+ u8 *pData = *ppData; /* Content area. A subset of aData[] */
+ int iEnd = iFirst + nCell; /* End of loop. One past last cell to ins */
+ int k; /* Current slot in pCArray->apEnd[] */
+ u8 *pEnd; /* Maximum extent of cell data */
assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */
- for(i=iFirst; i<iEnd; i++){
+ if( iEnd<=iFirst ) return 0;
+ for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
+ pEnd = pCArray->apEnd[k];
+ while( 1 /*Exit by break*/ ){
int sz, rc;
u8 *pSlot;
sz = cachedCellSize(pCArray, i);
@@ -69763,20 +70019,33 @@ static int pageInsertArray(
assert( (pSlot+sz)<=pCArray->apCell[i]
|| pSlot>=(pCArray->apCell[i]+sz)
|| CORRUPT_DB );
+ if( (uptr)(pCArray->apCell[i]+sz)>(uptr)pEnd
+ && (uptr)(pCArray->apCell[i])<(uptr)pEnd
+ ){
+ assert( CORRUPT_DB );
+ (void)SQLITE_CORRUPT_BKPT;
+ return 1;
+ }
memmove(pSlot, pCArray->apCell[i], sz);
put2byte(pCellptr, (pSlot - aData));
pCellptr += 2;
+ i++;
+ if( i>=iEnd ) break;
+ if( pCArray->ixNx[k]<=i ){
+ k++;
+ pEnd = pCArray->apEnd[k];
+ }
}
*ppData = pData;
return 0;
}
/*
-** Array apCell[] contains nCell pointers to b-tree cells. Array szCell
-** contains the size in bytes of each such cell. This function adds the
-** space associated with each cell in the array that is currently stored
-** within the body of pPg to the pPg free-list. The cell-pointers and other
-** fields of the page are not updated.
+** The pCArray object contains pointers to b-tree cells and their sizes.
+**
+** This function adds the space associated with each cell in the array
+** that is currently stored within the body of pPg to the pPg free-list.
+** The cell-pointers and other fields of the page are not updated.
**
** This function returns the total number of cells added to the free-list.
*/
@@ -69826,9 +70095,9 @@ static int pageFreeArray(
}
/*
-** apCell[] and szCell[] contains pointers to and sizes of all cells in the
-** pages being balanced. The current page, pPg, has pPg->nCell cells starting
-** with apCell[iOld]. After balancing, this page should hold nNew cells
+** pCArray contains pointers to and sizes of all cells in the page being
+** balanced. The current page, pPg, has pPg->nCell cells starting with
+** pCArray->apCell[iOld]. After balancing, this page should hold nNew cells
** starting at apCell[iNew].
**
** This routine makes the necessary adjustments to pPg so that it contains
@@ -69860,13 +70129,17 @@ static int editPage(
#endif
/* Remove cells from the start and end of the page */
+ assert( nCell>=0 );
if( iOld<iNew ){
int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
+ if( nShift>nCell ) return SQLITE_CORRUPT_BKPT;
memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
nCell -= nShift;
}
if( iNewEnd < iOldEnd ){
- nCell -= pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
+ int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
+ assert( nCell>=nTail );
+ nCell -= nTail;
}
pData = &aData[get2byteNotZero(&aData[hdr+5])];
@@ -69876,6 +70149,7 @@ static int editPage(
if( iNew<iOld ){
int nAdd = MIN(nNew,iOld-iNew);
assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB );
+ assert( nAdd>=0 );
pCellptr = pPg->aCellIdx;
memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
if( pageInsertArray(
@@ -69890,6 +70164,7 @@ static int editPage(
int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
if( iCell>=0 && iCell<nNew ){
pCellptr = &pPg->aCellIdx[iCell * 2];
+ assert( nCell>=iCell );
memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
nCell++;
if( pageInsertArray(
@@ -69900,6 +70175,7 @@ static int editPage(
}
/* Append cells to the end of the page */
+ assert( nCell>=0 );
pCellptr = &pPg->aCellIdx[nCell*2];
if( pageInsertArray(
pPg, pBegin, &pData, pCellptr,
@@ -69928,24 +70204,9 @@ static int editPage(
editpage_fail:
/* Unable to edit this page. Rebuild it from scratch instead. */
populateCellCache(pCArray, iNew, nNew);
- return rebuildPage(pPg, nNew, &pCArray->apCell[iNew], &pCArray->szCell[iNew]);
+ return rebuildPage(pCArray, iNew, nNew, pPg);
}
-/*
-** The following parameters determine how many adjacent pages get involved
-** in a balancing operation. NN is the number of neighbors on either side
-** of the page that participate in the balancing operation. NB is the
-** total number of pages that participate, including the target page and
-** NN neighbors on either side.
-**
-** The minimum value of NN is 1 (of course). Increasing NN above 1
-** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
-** in exchange for a larger degradation in INSERT and UPDATE performance.
-** The value of NN appears to give the best results overall.
-*/
-#define NN 1 /* Number of neighbors on either side of pPage */
-#define NB (NN*2+1) /* Total pages involved in the balance */
-
#ifndef SQLITE_OMIT_QUICKBALANCE
/*
@@ -69981,8 +70242,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
assert( pPage->nOverflow==1 );
- /* This error condition is now caught prior to reaching this function */
- if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT;
+ if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; /* dbfuzz001.test */
/* Allocate a new page. This page will become the right-sibling of
** pPage. Make the parent page writable, so that the new divider cell
@@ -69996,12 +70256,22 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
u8 *pCell = pPage->apOvfl[0];
u16 szCell = pPage->xCellSize(pPage, pCell);
u8 *pStop;
+ CellArray b;
assert( sqlite3PagerIswriteable(pNew->pDbPage) );
- assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
+ assert( CORRUPT_DB || pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
- rc = rebuildPage(pNew, 1, &pCell, &szCell);
- if( NEVER(rc) ) return rc;
+ b.nCell = 1;
+ b.pRef = pPage;
+ b.apCell = &pCell;
+ b.szCell = &szCell;
+ b.apEnd[0] = pPage->aDataEnd;
+ b.ixNx[0] = 2;
+ rc = rebuildPage(&b, 0, 1, pNew);
+ if( NEVER(rc) ){
+ releasePage(pNew);
+ return rc;
+ }
pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell;
/* If this is an auto-vacuum database, update the pointer map
@@ -70016,7 +70286,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
if( ISAUTOVACUUM ){
ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc);
if( szCell>pNew->minLocal ){
- ptrmapPutOvflPtr(pNew, pCell, &rc);
+ ptrmapPutOvflPtr(pNew, pNew, pCell, &rc);
}
}
@@ -70239,10 +70509,6 @@ static int balance_nonroot(
assert( sqlite3_mutex_held(pBt->mutex) );
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
-#if 0
- TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
-#endif
-
/* At this point pParent may have at most one overflow cell. And if
** this overflow cell is present, it must be the cell with
** index iParentIdx. This scenario comes about when this function
@@ -70483,8 +70749,15 @@ static int balance_nonroot(
**
*/
usableSpace = pBt->usableSize - 12 + leafCorrection;
- for(i=0; i<nOld; i++){
+ for(i=k=0; i<nOld; i++, k++){
MemPage *p = apOld[i];
+ b.apEnd[k] = p->aDataEnd;
+ b.ixNx[k] = cntOld[i];
+ if( !leafData ){
+ k++;
+ b.apEnd[k] = pParent->aDataEnd;
+ b.ixNx[k] = cntOld[i]+1;
+ }
szNew[i] = usableSpace - p->nFree;
for(j=0; j<p->nOverflow; j++){
szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]);
@@ -70708,7 +70981,8 @@ static int balance_nonroot(
** populated, not here.
*/
if( ISAUTOVACUUM ){
- MemPage *pNew = apNew[0];
+ MemPage *pOld;
+ MemPage *pNew = pOld = apNew[0];
u8 *aOld = pNew->aData;
int cntOldNext = pNew->nCell + pNew->nOverflow;
int usableSize = pBt->usableSize;
@@ -70718,7 +70992,7 @@ static int balance_nonroot(
for(i=0; i<b.nCell; i++){
u8 *pCell = b.apCell[i];
if( i==cntOldNext ){
- MemPage *pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld];
+ pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld];
cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
aOld = pOld->aData;
}
@@ -70741,7 +71015,7 @@ static int balance_nonroot(
ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
}
if( cachedCellSize(&b,i)>pNew->minLocal ){
- ptrmapPutOvflPtr(pNew, pCell, &rc);
+ ptrmapPutOvflPtr(pNew, pOld, pCell, &rc);
}
if( rc ) goto balance_cleanup;
}
@@ -71165,7 +71439,11 @@ static int btreeOverwriteContent(
if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){
int rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc ) return rc;
- memcpy(pDest, ((u8*)pX->pData) + iOffset, iAmt);
+ /* In a corrupt database, it is possible for the source and destination
+ ** buffers to overlap. This is harmless since the database is already
+ ** corrupt but it does cause valgrind and ASAN warnings. So use
+ ** memmove(). */
+ memmove(pDest, ((u8*)pX->pData) + iOffset, iAmt);
}
}
return SQLITE_OK;
@@ -71560,6 +71838,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
if( bPreserve ){
if( !pPage->leaf
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
+ || pPage->nCell==1 /* See dbfuzz001.test for a test case */
){
/* A b-tree rebalance will be required after deleting this entry.
** Save the cursor key. */
@@ -72338,18 +72617,18 @@ static void checkList(
}
pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
if( isFreeList ){
- int n = get4byte(&pOvflData[4]);
+ u32 n = (u32)get4byte(&pOvflData[4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pCheck->pBt->autoVacuum ){
checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0);
}
#endif
- if( n>(int)pCheck->pBt->usableSize/4-2 ){
+ if( n>pCheck->pBt->usableSize/4-2 ){
checkAppendMsg(pCheck,
"freelist leaf count too big on page %d", iPage);
N--;
}else{
- for(i=0; i<n; i++){
+ for(i=0; i<(int)n; i++){
Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pCheck->pBt->autoVacuum ){
@@ -72726,7 +73005,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
Pgno i;
IntegrityCk sCheck;
BtShared *pBt = p->pBt;
- int savedDbFlags = pBt->db->flags;
+ u64 savedDbFlags = pBt->db->flags;
char zErr[100];
VVA_ONLY( int nRef );
@@ -72793,7 +73072,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
}
#endif
testcase( pBt->db->flags & SQLITE_CellSizeCk );
- pBt->db->flags &= ~SQLITE_CellSizeCk;
+ pBt->db->flags &= ~(u64)SQLITE_CellSizeCk;
for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
i64 notUsed;
if( aRoot[i]==0 ) continue;
@@ -74181,7 +74460,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
** if unable to complete the resizing.
*/
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
- assert( szNew>0 );
+ assert( CORRUPT_DB || szNew>0 );
assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
if( pMem->szMalloc<szNew ){
return sqlite3VdbeMemGrow(pMem, szNew, 0);
@@ -75062,6 +75341,9 @@ static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
){
int rc;
pMem->flags = MEM_Null;
+ if( sqlite3BtreeMaxRecordSize(pCur)<offset+amt ){
+ return SQLITE_CORRUPT_BKPT;
+ }
if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){
rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z);
if( rc==SQLITE_OK ){
@@ -75468,9 +75750,11 @@ static int valueFromExpr(
}
#endif
else if( op==TK_TRUEFALSE ){
- pVal = valueNew(db, pCtx);
- pVal->flags = MEM_Int;
- pVal->u.i = pExpr->u.zToken[4]==0;
+ pVal = valueNew(db, pCtx);
+ if( pVal ){
+ pVal->flags = MEM_Int;
+ pVal->u.i = pExpr->u.zToken[4]==0;
+ }
}
*ppVal = pVal;
@@ -75863,7 +76147,7 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
pParse->pVdbe = p;
assert( pParse->aLabel==0 );
assert( pParse->nLabel==0 );
- assert( pParse->nOpAlloc==0 );
+ assert( p->nOpAlloc==0 );
assert( pParse->szOpAlloc==0 );
sqlite3VdbeAddOp2(p, OP_Init, 0, 1);
return p;
@@ -75891,14 +76175,44 @@ SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlag
}
assert( p->zSql==0 );
p->zSql = sqlite3DbStrNDup(p->db, z, n);
+}
+
#ifdef SQLITE_ENABLE_NORMALIZE
- assert( p->zNormSql==0 );
- if( p->zSql && (prepFlags & SQLITE_PREPARE_NORMALIZE)!=0 ){
- sqlite3Normalize(p, p->zSql, n, prepFlags);
- assert( p->zNormSql!=0 || p->db->mallocFailed );
+/*
+** Add a new element to the Vdbe->pDblStr list.
+*/
+SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3 *db, Vdbe *p, const char *z){
+ if( p ){
+ int n = sqlite3Strlen30(z);
+ DblquoteStr *pStr = sqlite3DbMallocRawNN(db,
+ sizeof(*pStr)+n+1-sizeof(pStr->z));
+ if( pStr ){
+ pStr->pNextStr = p->pDblStr;
+ p->pDblStr = pStr;
+ memcpy(pStr->z, z, n+1);
+ }
}
+}
#endif
+
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** zId of length nId is a double-quoted identifier. Check to see if
+** that identifier is really used as a string literal.
+*/
+SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(
+ Vdbe *pVdbe, /* The prepared statement */
+ const char *zId /* The double-quoted identifier, already dequoted */
+){
+ DblquoteStr *pStr;
+ assert( zId!=0 );
+ if( pVdbe->pDblStr==0 ) return 0;
+ for(pStr=pVdbe->pDblStr; pStr; pStr=pStr->pNextStr){
+ if( strcmp(zId, pStr->z)==0 ) return 1;
+ }
+ return 0;
}
+#endif
/*
** Swap all content between two VDBE structures.
@@ -75919,7 +76233,7 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
zTmp = pA->zSql;
pA->zSql = pB->zSql;
pB->zSql = zTmp;
-#ifdef SQLITE_ENABLE_NORMALIZE
+#if 0
zTmp = pA->zNormSql;
pA->zNormSql = pB->zNormSql;
pB->zNormSql = zTmp;
@@ -75936,7 +76250,7 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
** to 1024/sizeof(Op).
**
** If an out-of-memory error occurs while resizing the array, return
-** SQLITE_NOMEM. In this case Vdbe.aOp and Parse.nOpAlloc remain
+** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain
** unchanged (this is so that any opcodes already allocated can be
** correctly deallocated along with the rest of the Vdbe).
*/
@@ -75952,9 +76266,9 @@ static int growOpArray(Vdbe *v, int nOp){
** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current
** size of the op array or add 1KB of space, whichever is smaller. */
#ifdef SQLITE_TEST_REALLOC_STRESS
- int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp);
+ int nNew = (v->nOpAlloc>=512 ? v->nOpAlloc*2 : v->nOpAlloc+nOp);
#else
- int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
+ int nNew = (v->nOpAlloc ? v->nOpAlloc*2 : (int)(1024/sizeof(Op)));
UNUSED_PARAMETER(nOp);
#endif
@@ -75965,11 +76279,11 @@ static int growOpArray(Vdbe *v, int nOp){
}
assert( nOp<=(1024/sizeof(Op)) );
- assert( nNew>=(p->nOpAlloc+nOp) );
+ assert( nNew>=(v->nOpAlloc+nOp) );
pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
if( pNew ){
p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
- p->nOpAlloc = p->szOpAlloc/sizeof(Op);
+ v->nOpAlloc = p->szOpAlloc/sizeof(Op);
v->aOp = pNew;
}
return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
@@ -76003,9 +76317,9 @@ static void test_addop_breakpoint(void){
** operand.
*/
static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){
- assert( p->pParse->nOpAlloc<=p->nOp );
+ assert( p->nOpAlloc<=p->nOp );
if( growOpArray(p, 1) ) return 1;
- assert( p->pParse->nOpAlloc>p->nOp );
+ assert( p->nOpAlloc>p->nOp );
return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
}
SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
@@ -76015,7 +76329,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
i = p->nOp;
assert( p->magic==VDBE_MAGIC_INIT );
assert( op>=0 && op<0xff );
- if( p->pParse->nOpAlloc<=i ){
+ if( p->nOpAlloc<=i ){
return growOp3(p, op, p1, p2, p3);
}
p->nOp++;
@@ -76147,13 +76461,29 @@ SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){
}
/*
-** Add a new OP_Explain opcode.
+** Set a debugger breakpoint on the following routine in order to
+** monitor the EXPLAIN QUERY PLAN code generation.
+*/
+#if defined(SQLITE_DEBUG)
+SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char *z1, const char *z2){
+ (void)z1;
+ (void)z2;
+}
+#endif
+
+/*
+** Add a new OP_ opcode.
**
** If the bPush flag is true, then make this opcode the parent for
** subsequent Explains until sqlite3VdbeExplainPop() is called.
*/
SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
- if( pParse->explain==2 ){
+#ifndef SQLITE_DEBUG
+ /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined.
+ ** But omit them (for performance) during production builds */
+ if( pParse->explain==2 )
+#endif
+ {
char *zMsg;
Vdbe *v;
va_list ap;
@@ -76165,7 +76495,10 @@ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt
iThis = v->nOp;
sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
zMsg, P4_DYNAMIC);
- if( bPush) pParse->addrExplain = iThis;
+ sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetOp(v,-1)->p4.z);
+ if( bPush){
+ pParse->addrExplain = iThis;
+ }
}
}
@@ -76173,6 +76506,7 @@ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt
** Pop the EXPLAIN QUERY PLAN stack one level.
*/
SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){
+ sqlite3ExplainBreakpoint("POP", 0);
pParse->addrExplain = sqlite3VdbeExplainParent(pParse);
}
#endif /* SQLITE_OMIT_EXPLAIN */
@@ -76237,21 +76571,22 @@ SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){
** The VDBE knows that a P2 value is a label because labels are
** always negative and P2 values are suppose to be non-negative.
** Hence, a negative P2 value is a label that has yet to be resolved.
+** (Later:) This is only true for opcodes that have the OPFLG_JUMP
+** property.
+**
+** Variable usage notes:
**
-** Zero is returned if a malloc() fails.
+** Parse.aLabel[x] Stores the address that the x-th label resolves
+** into. For testing (SQLITE_DEBUG), unresolved
+** labels stores -1, but that is not required.
+** Parse.nLabelAlloc Number of slots allocated to Parse.aLabel[]
+** Parse.nLabel The *negative* of the number of labels that have
+** been issued. The negative is stored because
+** that gives a performance improvement over storing
+** the equivalent positive value.
*/
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){
- Parse *p = v->pParse;
- int i = p->nLabel++;
- assert( v->magic==VDBE_MAGIC_INIT );
- if( (i & (i-1))==0 ){
- p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
- (i*2+1)*sizeof(p->aLabel[0]));
- }
- if( p->aLabel ){
- p->aLabel[i] = -1;
- }
- return ADDR(i);
+SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse *pParse){
+ return --pParse->nLabel;
}
/*
@@ -76259,18 +76594,35 @@ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){
** be inserted. The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/
+static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){
+ int nNewSize = 10 - p->nLabel;
+ p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
+ nNewSize*sizeof(p->aLabel[0]));
+ if( p->aLabel==0 ){
+ p->nLabelAlloc = 0;
+ }else{
+#ifdef SQLITE_DEBUG
+ int i;
+ for(i=p->nLabelAlloc; i<nNewSize; i++) p->aLabel[i] = -1;
+#endif
+ p->nLabelAlloc = nNewSize;
+ p->aLabel[j] = v->nOp;
+ }
+}
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
Parse *p = v->pParse;
int j = ADDR(x);
assert( v->magic==VDBE_MAGIC_INIT );
- assert( j<p->nLabel );
+ assert( j<-p->nLabel );
assert( j>=0 );
- if( p->aLabel ){
#ifdef SQLITE_DEBUG
- if( p->db->flags & SQLITE_VdbeAddopTrace ){
- printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
- }
+ if( p->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
+ }
#endif
+ if( p->nLabelAlloc + p->nLabel < 0 ){
+ resizeResolveLabel(p,v,j);
+ }else{
assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */
p->aLabel[j] = v->nOp;
}
@@ -76395,8 +76747,9 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
while( (pOp = opIterNext(&sIter))!=0 ){
int opcode = pOp->opcode;
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
+ || opcode==OP_VDestroy
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
- && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
+ && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
){
hasAbort = 1;
break;
@@ -76545,7 +76898,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
** have non-negative values for P2. */
assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 );
- assert( ADDR(pOp->p2)<pParse->nLabel );
+ assert( ADDR(pOp->p2)<-pParse->nLabel );
pOp->p2 = aLabel[ADDR(pOp->p2)];
}
break;
@@ -76584,7 +76937,7 @@ SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){
*/
#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){
- assert( p->nOp + N <= p->pParse->nOpAlloc );
+ assert( p->nOp + N <= p->nOpAlloc );
}
#endif
@@ -76656,7 +77009,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(
VdbeOp *pOut, *pFirst;
assert( nOp>0 );
assert( p->magic==VDBE_MAGIC_INIT );
- if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
+ if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
return 0;
}
pFirst = pOut = &p->aOp[p->nOp];
@@ -77978,19 +78331,27 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
** the leftover memory at the end of the opcode array. This can significantly
** reduce the amount of memory held by a prepared statement.
*/
- do {
- x.nNeeded = 0;
- p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
- p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
- p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
- p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
+ x.nNeeded = 0;
+ p->aMem = allocSpace(&x, 0, nMem*sizeof(Mem));
+ p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem));
+ p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*));
+ p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*));
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
- p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
+ p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64));
#endif
- if( x.nNeeded==0 ) break;
+ if( x.nNeeded ){
x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
x.nFree = x.nNeeded;
- }while( !db->mallocFailed );
+ if( !db->mallocFailed ){
+ p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
+ p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
+ p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
+ p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
+#endif
+ }
+ }
p->pVList = pParse->pVList;
pParse->pVList = 0;
@@ -78682,7 +79043,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
}else{
db->nDeferredCons = 0;
db->nDeferredImmCons = 0;
- db->flags &= ~SQLITE_DeferFKs;
+ db->flags &= ~(u64)SQLITE_DeferFKs;
sqlite3CommitInternalChanges(db);
}
}else{
@@ -78997,6 +79358,13 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
sqlite3DbFree(db, p->zSql);
#ifdef SQLITE_ENABLE_NORMALIZE
sqlite3DbFree(db, p->zNormSql);
+ {
+ DblquoteStr *pThis, *pNext;
+ for(pThis=p->pDblStr; pThis; pThis=pNext){
+ pNext = pThis->pNextStr;
+ sqlite3DbFree(db, pThis);
+ }
+ }
#endif
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
{
@@ -79537,7 +79905,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
UnpackedRecord *p /* Populate this structure before returning. */
){
const unsigned char *aKey = (const unsigned char *)pKey;
- int d;
+ u32 d;
u32 idx; /* Offset in aKey[] to read from */
u16 u; /* Unsigned loop counter */
u32 szHdr;
@@ -79548,7 +79916,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
idx = getVarint32(aKey, szHdr);
d = szHdr;
u = 0;
- while( idx<szHdr && d<=nKey ){
+ while( idx<szHdr && d<=(u32)nKey ){
u32 serial_type;
idx += getVarint32(&aKey[idx], serial_type);
@@ -79561,6 +79929,13 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
pMem++;
if( (++u)>=p->nField ) break;
}
+ if( d>(u32)nKey && u ){
+ assert( CORRUPT_DB );
+ /* In a corrupt record entry, the last pMem might have been set up using
+ ** uninitialized memory. Overwrite its value with NULL, to prevent
+ ** warnings from MSAN. */
+ sqlite3VdbeMemSetNull(pMem-1);
+ }
assert( u<=pKeyInfo->nKeyField + 1 );
p->nField = u;
}
@@ -79626,8 +80001,8 @@ static int vdbeRecordCompareDebug(
** Use that approximation to avoid the more expensive call to
** sqlite3VdbeSerialTypeLen() in the common case.
*/
- if( d1+serial_type1+2>(u32)nKey1
- && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1
+ if( d1+(u64)serial_type1+2>(u64)nKey1
+ && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1
){
break;
}
@@ -79638,7 +80013,8 @@ static int vdbeRecordCompareDebug(
/* Do the comparison
*/
- rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
+ rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
+ pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0);
if( rc!=0 ){
assert( mem1.szMalloc==0 ); /* See comment below */
if( pKeyInfo->aSortOrder[i] ){
@@ -79994,12 +80370,12 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
}else{
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
- if( d1>(unsigned)nKey1 ){
- pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
- return 0; /* Corruption */
- }
i = 0;
}
+ if( d1>(unsigned)nKey1 ){
+ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
+ return 0; /* Corruption */
+ }
VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField
@@ -80069,10 +80445,12 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
mem1.n = (serial_type - 12) / 2;
testcase( (d1+mem1.n)==(unsigned)nKey1 );
testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
- if( (d1+mem1.n) > (unsigned)nKey1 ){
+ if( (d1+mem1.n) > (unsigned)nKey1
+ || (pKeyInfo = pPKey2->pKeyInfo)->nAllField<=i
+ ){
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
- }else if( (pKeyInfo = pPKey2->pKeyInfo)->aColl[i] ){
+ }else if( pKeyInfo->aColl[i] ){
mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
mem1.flags = MEM_Str;
@@ -80772,14 +81150,16 @@ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
sqlite3_int64 iNow;
sqlite3_int64 iElapse;
assert( p->startTime>0 );
- assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 );
+ assert( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 );
assert( db->init.busy==0 );
assert( p->zSql!=0 );
sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
iElapse = (iNow - p->startTime)*1000000;
+#ifndef SQLITE_OMIT_DEPRECATED
if( db->xProfile ){
db->xProfile(db->pProfileArg, p->zSql, iElapse);
}
+#endif
if( db->mTrace & SQLITE_TRACE_PROFILE ){
db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse);
}
@@ -81293,7 +81673,7 @@ static int sqlite3Step(Vdbe *p){
return SQLITE_NOMEM_BKPT;
}
- if( p->pc<=0 && p->expired ){
+ if( p->pc<0 && p->expired ){
p->rc = SQLITE_SCHEMA;
rc = SQLITE_ERROR;
goto end_of_step;
@@ -81312,7 +81692,7 @@ static int sqlite3Step(Vdbe *p){
);
#ifndef SQLITE_OMIT_TRACE
- if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0)
+ if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
&& !db->init.busy && p->zSql ){
sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
}else{
@@ -81339,16 +81719,18 @@ static int sqlite3Step(Vdbe *p){
db->nVdbeExec--;
}
+ if( rc!=SQLITE_ROW ){
#ifndef SQLITE_OMIT_TRACE
- /* If the statement completed successfully, invoke the profile callback */
- if( rc!=SQLITE_ROW ) checkProfileCallback(db, p);
+ /* If the statement completed successfully, invoke the profile callback */
+ checkProfileCallback(db, p);
#endif
- if( rc==SQLITE_DONE && db->autoCommit ){
- assert( p->rc==SQLITE_OK );
- p->rc = doWalCallbacks(db);
- if( p->rc!=SQLITE_OK ){
- rc = SQLITE_ERROR;
+ if( rc==SQLITE_DONE && db->autoCommit ){
+ assert( p->rc==SQLITE_OK );
+ p->rc = doWalCallbacks(db);
+ if( p->rc!=SQLITE_OK ){
+ rc = SQLITE_ERROR;
+ }
}
}
@@ -81368,9 +81750,9 @@ end_of_step:
|| (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE
);
assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp );
- if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0
- && rc!=SQLITE_ROW
- && rc!=SQLITE_DONE
+ if( rc!=SQLITE_ROW
+ && rc!=SQLITE_DONE
+ && (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0
){
/* If this statement was prepared using saved SQL and an
** error has occurred, then return the error code in p->rc to the
@@ -81992,7 +82374,7 @@ static int vdbeUnbind(Vdbe *p, int i){
pVar = &p->aVar[i];
sqlite3VdbeMemRelease(pVar);
pVar->flags = MEM_Null;
- sqlite3Error(p->db, SQLITE_OK);
+ p->db->errCode = SQLITE_OK;
/* If the bit corresponding to this variable in Vdbe.expmask is set, then
** binding a new value to this variable invalidates the current query plan.
@@ -82418,7 +82800,13 @@ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
*/
SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe *)pStmt;
- return p ? p->zNormSql : 0;
+ if( p==0 ) return 0;
+ if( p->zNormSql==0 && ALWAYS(p->zSql!=0) ){
+ sqlite3_mutex_enter(p->db->mutex);
+ p->zNormSql = sqlite3Normalize(p, p->zSql);
+ sqlite3_mutex_leave(p->db->mutex);
+ }
+ return p->zNormSql;
}
#endif /* SQLITE_ENABLE_NORMALIZE */
@@ -83118,6 +83506,11 @@ static VdbeCursor *allocateCursor(
assert( iCur>=0 && iCur<p->nCursor );
if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
+ /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag
+ ** is clear. Otherwise, if this is an ephemeral cursor created by
+ ** OP_OpenDup, the cursor will not be closed and will still be part
+ ** of a BtShared.pCursor list. */
+ p->apCsr[iCur]->isEphemeral = 0;
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
p->apCsr[iCur] = 0;
}
@@ -83258,6 +83651,7 @@ SQLITE_PRIVATE void sqlite3ValueApplyAffinity(
static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
+ ExpandBlob(pMem);
if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
return 0;
}
@@ -84545,8 +84939,8 @@ fp_math:
break;
}
default: {
- iA = (i64)rA;
- iB = (i64)rB;
+ iA = sqlite3VdbeIntValue(pIn1);
+ iB = sqlite3VdbeIntValue(pIn2);
if( iA==0 ) goto arithmetic_result_is_null;
if( iA==-1 ) iA = 1;
rB = (double)(iB % iA);
@@ -84892,7 +85286,8 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
*/
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
assert( (flags1 & MEM_Cleared)==0 );
- assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
+ assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB );
+ testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 );
if( (flags1&flags3&MEM_Null)!=0
&& (flags3&MEM_Cleared)==0
){
@@ -86576,7 +86971,8 @@ case OP_OpenDup: {
pCx->isEphemeral = 1;
pCx->pKeyInfo = pOrig->pKeyInfo;
pCx->isTable = pOrig->isTable;
- rc = sqlite3BtreeCursor(pOrig->pBtx, MASTER_ROOT, BTREE_WRCSR,
+ pCx->pgnoRoot = pOrig->pgnoRoot;
+ rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
pCx->pKeyInfo, pCx->uc.pCursor);
/* The sqlite3BtreeCursor() routine can only fail for the first cursor
** opened for a database. Since there is already an open cursor when this
@@ -86594,6 +86990,9 @@ case OP_OpenDup: {
** the main database is read-only. The ephemeral
** table is deleted automatically when the cursor is closed.
**
+** If the cursor P1 is already opened on an ephemeral table, the table
+** is cleared (all content is erased).
+**
** P2 is the number of columns in the ephemeral table.
** The cursor points to a BTree table if P4==0 and to a BTree index
** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure
@@ -86625,41 +87024,50 @@ case OP_OpenEphemeral: {
SQLITE_OPEN_TRANSIENT_DB;
assert( pOp->p1>=0 );
assert( pOp->p2>=0 );
- pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
- if( pCx==0 ) goto no_mem;
- pCx->nullRow = 1;
- pCx->isEphemeral = 1;
- rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx,
- BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
- if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
- }
- if( rc==SQLITE_OK ){
- /* If a transient index is required, create it by calling
- ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
- ** opening it. If a transient table is required, just use the
- ** automatically created table with root-page 1 (an BLOB_INTKEY table).
- */
- if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
- int pgno;
- assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(pCx->pBtx, &pgno, BTREE_BLOBKEY | pOp->p5);
- if( rc==SQLITE_OK ){
- assert( pgno==MASTER_ROOT+1 );
- assert( pKeyInfo->db==db );
- assert( pKeyInfo->enc==ENC(db) );
- rc = sqlite3BtreeCursor(pCx->pBtx, pgno, BTREE_WRCSR,
- pKeyInfo, pCx->uc.pCursor);
+ pCx = p->apCsr[pOp->p1];
+ if( pCx ){
+ /* If the ephermeral table is already open, erase all existing content
+ ** so that the table is empty again, rather than creating a new table. */
+ rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
+ }else{
+ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
+ if( pCx==0 ) goto no_mem;
+ pCx->nullRow = 1;
+ pCx->isEphemeral = 1;
+ rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx,
+ BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5,
+ vfsFlags);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
+ }
+ if( rc==SQLITE_OK ){
+ /* If a transient index is required, create it by calling
+ ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
+ ** opening it. If a transient table is required, just use the
+ ** automatically created table with root-page 1 (an BLOB_INTKEY table).
+ */
+ if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
+ assert( pOp->p4type==P4_KEYINFO );
+ rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot,
+ BTREE_BLOBKEY | pOp->p5);
+ if( rc==SQLITE_OK ){
+ assert( pCx->pgnoRoot==MASTER_ROOT+1 );
+ assert( pKeyInfo->db==db );
+ assert( pKeyInfo->enc==ENC(db) );
+ rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
+ pKeyInfo, pCx->uc.pCursor);
+ }
+ pCx->isTable = 0;
+ }else{
+ pCx->pgnoRoot = MASTER_ROOT;
+ rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
+ 0, pCx->uc.pCursor);
+ pCx->isTable = 1;
}
- pCx->isTable = 0;
- }else{
- rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
- 0, pCx->uc.pCursor);
- pCx->isTable = 1;
}
+ pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
}
if( rc ) goto abort_due_to_error;
- pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
break;
}
@@ -87309,7 +87717,7 @@ case OP_NotExists: /* jump, in3 */
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
#ifdef SQLITE_DEBUG
- pC->seekOp = OP_SeekRowid;
+ if( pOp->opcode==OP_SeekRowid ) pC->seekOp = OP_SeekRowid;
#endif
assert( pC->isTable );
assert( pC->eCurType==CURTYPE_BTREE );
@@ -88217,7 +88625,7 @@ case OP_Next: /* jump */
assert( pOp->opcode!=OP_Next
|| pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
|| pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
- || pC->seekOp==OP_NullRow);
+ || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid);
assert( pOp->opcode!=OP_Prev
|| pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
|| pC->seekOp==OP_Last
@@ -88747,9 +89155,16 @@ case OP_ParseSchema: {
assert( db->init.busy==0 );
db->init.busy = 1;
initData.rc = SQLITE_OK;
+ initData.nInitRow = 0;
assert( !db->mallocFailed );
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
if( rc==SQLITE_OK ) rc = initData.rc;
+ if( rc==SQLITE_OK && initData.nInitRow==0 ){
+ /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse
+ ** at least one SQL statement. Any less than that indicates that
+ ** the sqlite_master table is corrupt. */
+ rc = SQLITE_CORRUPT_BKPT;
+ }
sqlite3DbFreeNN(db, zSql);
db->init.busy = 0;
}
@@ -89113,6 +89528,17 @@ case OP_Program: { /* jump */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = 0;
#endif
+#ifdef SQLITE_DEBUG
+ /* Verify that second and subsequent executions of the same trigger do not
+ ** try to reuse register values from the first use. */
+ {
+ int i;
+ for(i=0; i<p->nMem; i++){
+ aMem[i].pScopyFrom = 0; /* Prevent false-positive AboutToChange() errs */
+ aMem[i].flags |= MEM_Undefined; /* Cause a fault if this reg is reused */
+ }
+ }
+#endif
pOp = &aOp[-1];
break;
@@ -89651,14 +90077,19 @@ case OP_JournalMode: { /* out2 */
#endif /* SQLITE_OMIT_PRAGMA */
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
-/* Opcode: Vacuum P1 * * * *
+/* Opcode: Vacuum P1 P2 * * *
**
** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more
** for an attached database. The "temp" database may not be vacuumed.
+**
+** If P2 is not zero, then it is a register holding a string which is
+** the file into which the result of vacuum should be written. When
+** P2 is zero, the vacuum overwrites the original database.
*/
case OP_Vacuum: {
assert( p->readOnly==0 );
- rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1);
+ rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1,
+ pOp->p2 ? &aMem[pOp->p2] : 0);
if( rc ) goto abort_due_to_error;
break;
}
@@ -89810,6 +90241,7 @@ case OP_VDestroy: {
db->nVDestroy++;
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
db->nVDestroy--;
+ assert( p->errorAction==OE_Abort && p->usesStmtJournal );
if( rc ) goto abort_due_to_error;
break;
}
@@ -90053,7 +90485,7 @@ case OP_VRename: {
rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
if( rc ) goto abort_due_to_error;
rc = pVtab->pModule->xRename(pVtab, pName->z);
- if( isLegacy==0 ) db->flags &= ~SQLITE_LegacyAlter;
+ if( isLegacy==0 ) db->flags &= ~(u64)SQLITE_LegacyAlter;
sqlite3VtabImportErrmsg(p, pVtab);
p->expired = 0;
if( rc ) goto abort_due_to_error;
@@ -94280,6 +94712,22 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
/* #include <string.h> */
+#if !defined(SQLITE_OMIT_WINDOWFUNC)
+/*
+** Walk all expressions linked into the list of Window objects passed
+** as the second argument.
+*/
+static int walkWindowList(Walker *pWalker, Window *pList){
+ Window *pWin;
+ for(pWin=pList; pWin; pWin=pWin->pNextWin){
+ if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
+ if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
+ if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
+ }
+ return WRC_Continue;
+}
+#endif
+
/*
** Walk an expression tree. Invoke the callback once for each node
** of the expression, while descending. (In other words, the callback
@@ -94319,10 +94767,7 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
}
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(pExpr, EP_WinFunc) ){
- Window *pWin = pExpr->y.pWin;
- if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
- if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
+ if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort;
}
#endif
}
@@ -94362,6 +94807,16 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort;
if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
+#if !defined(SQLITE_OMIT_WINDOWFUNC) && !defined(SQLITE_OMIT_ALTERTABLE)
+ {
+ Parse *pParse = pWalker->pParse;
+ if( pParse && IN_RENAME_OBJECT ){
+ int rc = walkWindowList(pWalker, p->pWinDefn);
+ assert( rc==WRC_Continue );
+ return rc;
+ }
+ }
+#endif
return WRC_Continue;
}
@@ -94513,7 +94968,6 @@ static void resolveAlias(
if( pExpr->op==TK_COLLATE ){
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
}
- ExprSetProperty(pDup, EP_Alias);
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
** prevents ExprDelete() from deleting the Expr structure itself,
@@ -94907,6 +95361,25 @@ static int lookupName(
if( cnt==0 && zTab==0 ){
assert( pExpr->op==TK_ID );
if( ExprHasProperty(pExpr,EP_DblQuoted) ){
+ /* If a double-quoted identifier does not match any known column name,
+ ** then treat it as a string.
+ **
+ ** This hack was added in the early days of SQLite in a misguided attempt
+ ** to be compatible with MySQL 3.x, which used double-quotes for strings.
+ ** I now sorely regret putting in this hack. The effect of this hack is
+ ** that misspelled identifier names are silently converted into strings
+ ** rather than causing an error, to the frustration of countless
+ ** programmers. To all those frustrated programmers, my apologies.
+ **
+ ** Someday, I hope to get rid of this hack. Unfortunately there is
+ ** a huge amount of legacy SQL that uses it. So for now, we just
+ ** issue a warning.
+ */
+ sqlite3_log(SQLITE_WARNING,
+ "double-quoted string literal: \"%w\"", zCol);
+#ifdef SQLITE_ENABLE_NORMALIZE
+ sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol);
+#endif
pExpr->op = TK_STRING;
pExpr->y.pTab = 0;
return WRC_Prune;
@@ -95273,10 +95746,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pExpr->y.pWin ){
Select *pSel = pNC->pWinSelect;
+ sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
- sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
if( 0==pSel->pWin
|| 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
){
@@ -95553,32 +96026,53 @@ static int resolveCompoundOrderBy(
}else{
iCol = resolveAsName(pParse, pEList, pE);
if( iCol==0 ){
- pDup = sqlite3ExprDup(db, pE, 0);
+ /* Now test if expression pE matches one of the values returned
+ ** by pSelect. In the usual case this is done by duplicating the
+ ** expression, resolving any symbols in it, and then comparing
+ ** it against each expression returned by the SELECT statement.
+ ** Once the comparisons are finished, the duplicate expression
+ ** is deleted.
+ **
+ ** Or, if this is running as part of an ALTER TABLE operation,
+ ** resolve the symbols in the actual expression, not a duplicate.
+ ** And, if one of the comparisons is successful, leave the expression
+ ** as is instead of transforming it to an integer as in the usual
+ ** case. This allows the code in alter.c to modify column
+ ** refererences within the ORDER BY expression as required. */
+ if( IN_RENAME_OBJECT ){
+ pDup = pE;
+ }else{
+ pDup = sqlite3ExprDup(db, pE, 0);
+ }
if( !db->mallocFailed ){
assert(pDup);
iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup);
}
- sqlite3ExprDelete(db, pDup);
+ if( !IN_RENAME_OBJECT ){
+ sqlite3ExprDelete(db, pDup);
+ }
}
}
if( iCol>0 ){
/* Convert the ORDER BY term into an integer column number iCol,
** taking care to preserve the COLLATE clause if it exists */
- Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
- if( pNew==0 ) return 1;
- pNew->flags |= EP_IntValue;
- pNew->u.iValue = iCol;
- if( pItem->pExpr==pE ){
- pItem->pExpr = pNew;
- }else{
- Expr *pParent = pItem->pExpr;
- assert( pParent->op==TK_COLLATE );
- while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
- assert( pParent->pLeft==pE );
- pParent->pLeft = pNew;
+ if( !IN_RENAME_OBJECT ){
+ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
+ if( pNew==0 ) return 1;
+ pNew->flags |= EP_IntValue;
+ pNew->u.iValue = iCol;
+ if( pItem->pExpr==pE ){
+ pItem->pExpr = pNew;
+ }else{
+ Expr *pParent = pItem->pExpr;
+ assert( pParent->op==TK_COLLATE );
+ while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
+ assert( pParent->pLeft==pE );
+ pParent->pLeft = pNew;
+ }
+ sqlite3ExprDelete(db, pE);
+ pItem->u.x.iOrderByCol = (u16)iCol;
}
- sqlite3ExprDelete(db, pE);
- pItem->u.x.iOrderByCol = (u16)iCol;
pItem->done = 1;
}else{
moreToDo = 1;
@@ -95927,6 +96421,17 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
+ if( IN_RENAME_OBJECT ){
+ Window *pWin;
+ for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){
+ if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy)
+ || sqlite3ResolveExprListNames(&sNC, pWin->pPartition)
+ ){
+ return WRC_Abort;
+ }
+ }
+ }
+
/* If this is part of a compound SELECT, check that it has the right
** number of expressions in the select list. */
if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){
@@ -96077,38 +96582,47 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
}
/*
-** Resolve names in expressions that can only reference a single table:
+** Resolve names in expressions that can only reference a single table
+** or which cannot reference any tables at all. Examples:
**
-** * CHECK constraints
-** * WHERE clauses on partial indices
+** (1) CHECK constraints
+** (2) WHERE clauses on partial indices
+** (3) Expressions in indexes on expressions
+** (4) Expression arguments to VACUUM INTO.
**
-** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
-** is set to -1 and the Expr.iColumn value is set to the column number.
+** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN
+** nodes of the expression is set to -1 and the Expr.iColumn value is
+** set to the column number. In case (4), TK_COLUMN nodes cause an error.
**
** Any errors cause an error message to be set in pParse.
*/
-SQLITE_PRIVATE void sqlite3ResolveSelfReference(
+SQLITE_PRIVATE int sqlite3ResolveSelfReference(
Parse *pParse, /* Parsing context */
- Table *pTab, /* The table being referenced */
- int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */
+ Table *pTab, /* The table being referenced, or NULL */
+ int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr, or 0 */
Expr *pExpr, /* Expression to resolve. May be NULL. */
ExprList *pList /* Expression list to resolve. May be NULL. */
){
SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
NameContext sNC; /* Name context for pParse->pNewTable */
+ int rc;
- assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr );
+ assert( type==0 || pTab!=0 );
+ assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || pTab==0 );
memset(&sNC, 0, sizeof(sNC));
memset(&sSrc, 0, sizeof(sSrc));
- sSrc.nSrc = 1;
- sSrc.a[0].zName = pTab->zName;
- sSrc.a[0].pTab = pTab;
- sSrc.a[0].iCursor = -1;
+ if( pTab ){
+ sSrc.nSrc = 1;
+ sSrc.a[0].zName = pTab->zName;
+ sSrc.a[0].pTab = pTab;
+ sSrc.a[0].iCursor = -1;
+ }
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
sNC.ncFlags = type;
- if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
- if( pList ) sqlite3ResolveExprListNames(&sNC, pList);
+ if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc;
+ if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList);
+ return rc;
}
/************** End of resolve.c *********************************************/
@@ -96256,8 +96770,8 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
while( p ){
int op = p->op;
if( p->flags & EP_Generic ) break;
- if( (op==TK_AGG_COLUMN || op==TK_COLUMN
- || op==TK_REGISTER || op==TK_TRIGGER)
+ if( op==TK_REGISTER ) op = p->op2;
+ if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER)
&& p->y.pTab!=0
){
/* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
@@ -96273,7 +96787,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
p = p->pLeft;
continue;
}
- if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
+ if( op==TK_COLLATE ){
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
break;
}
@@ -96580,6 +97094,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(
}else{
if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr;
pRet = sqlite3ExprDup(pParse->db, pVector, 0);
+ sqlite3RenameTokenRemap(pParse, pRet, pVector);
}
return pRet;
}
@@ -96596,7 +97111,7 @@ static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
int reg = 0;
#ifndef SQLITE_OMIT_SUBQUERY
if( pExpr->op==TK_SELECT ){
- reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
+ reg = sqlite3CodeSubselect(pParse, pExpr);
}
#endif
return reg;
@@ -96668,7 +97183,7 @@ static void codeVectorCompare(
int regLeft = 0;
int regRight = 0;
u8 opx = op;
- int addrDone = sqlite3VdbeMakeLabel(v);
+ int addrDone = sqlite3VdbeMakeLabel(pParse);
if( nLeft!=sqlite3ExprVectorSize(pRight) ){
sqlite3ErrorMsg(pParse, "row value misused");
@@ -96895,8 +97410,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
pNew->u.zToken[pToken->n] = 0;
if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
- if( pNew->u.zToken[0]=='"' ) pNew->flags |= EP_DblQuoted;
- sqlite3Dequote(pNew->u.zToken);
+ sqlite3DequoteExpr(pNew);
}
}
}
@@ -96965,7 +97479,7 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
Expr *pRight /* Right operand */
){
Expr *p;
- if( op==TK_AND && pParse->nErr==0 ){
+ if( op==TK_AND && pParse->nErr==0 && !IN_RENAME_OBJECT ){
/* Take advantage of short-circuit false optimization for AND */
p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
}else{
@@ -97215,6 +97729,16 @@ static int exprStructSize(Expr *p){
}
/*
+** Copy the complete content of an Expr node, taking care not to read
+** past the end of the structure for a reduced-size version of the source
+** Expr.
+*/
+static void exprNodeCopy(Expr *pDest, Expr *pSrc){
+ memset(pDest, 0, sizeof(Expr));
+ memcpy(pDest, pSrc, exprStructSize(pSrc));
+}
+
+/*
** The dupedExpr*Size() routines each return the number of bytes required
** to store a copy of an expression or expression tree. They differ in
** how much of the tree is measured.
@@ -97445,6 +97969,36 @@ static With *withDup(sqlite3 *db, With *p){
# define withDup(x,y) 0
#endif
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** The gatherSelectWindows() procedure and its helper routine
+** gatherSelectWindowsCallback() are used to scan all the expressions
+** an a newly duplicated SELECT statement and gather all of the Window
+** objects found there, assembling them onto the linked list at Select->pWin.
+*/
+static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){
+ if( pExpr->op==TK_FUNCTION && pExpr->y.pWin!=0 ){
+ assert( ExprHasProperty(pExpr, EP_WinFunc) );
+ pExpr->y.pWin->pNextWin = pWalker->u.pSelect->pWin;
+ pWalker->u.pSelect->pWin = pExpr->y.pWin;
+ }
+ return WRC_Continue;
+}
+static int gatherSelectWindowsSelectCallback(Walker *pWalker, Select *p){
+ return p==pWalker->u.pSelect ? WRC_Continue : WRC_Prune;
+}
+static void gatherSelectWindows(Select *p){
+ Walker w;
+ w.xExprCallback = gatherSelectWindowsCallback;
+ w.xSelectCallback = gatherSelectWindowsSelectCallback;
+ w.xSelectCallback2 = 0;
+ w.pParse = 0;
+ w.u.pSelect = p;
+ sqlite3WalkSelect(&w, p);
+}
+#endif
+
+
/*
** The following group of routines make deep copies of expressions,
** expression lists, ID lists, and select statements. The copies can
@@ -97612,6 +98166,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
#ifndef SQLITE_OMIT_WINDOWFUNC
pNew->pWin = 0;
pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
+ if( p->pWin ) gatherSelectWindows(pNew);
#endif
pNew->selId = p->selId;
*pp = pNew;
@@ -97744,6 +98299,9 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(
}
vector_append_error:
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameExprUnmap(pParse, pExpr);
+ }
sqlite3ExprDelete(db, pExpr);
sqlite3IdListDelete(db, pColumns);
return pList;
@@ -97887,8 +98445,9 @@ SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
*/
SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
- if( sqlite3StrICmp(pExpr->u.zToken, "true")==0
- || sqlite3StrICmp(pExpr->u.zToken, "false")==0
+ if( !ExprHasProperty(pExpr, EP_Quoted)
+ && (sqlite3StrICmp(pExpr->u.zToken, "true")==0
+ || sqlite3StrICmp(pExpr->u.zToken, "false")==0)
){
pExpr->op = TK_TRUEFALSE;
return 1;
@@ -98197,7 +98756,9 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
*/
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
u8 op;
- while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
+ while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
+ p = p->pLeft;
+ }
op = p->op;
if( op==TK_REGISTER ) op = p->op2;
switch( op ){
@@ -98264,14 +98825,6 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){
if( sqlite3StrICmp(z, "OID")==0 ) return 1;
return 0;
}
-#ifdef SQLITE_ENABLE_NORMALIZE
-SQLITE_PRIVATE int sqlite3IsRowidN(const char *z, int n){
- if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1;
- if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1;
- if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1;
- return 0;
-}
-#endif
/*
** pX is the RHS of an IN operator. If pX is a SELECT statement
@@ -98441,7 +98994,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
Expr *pX, /* The right-hand side (RHS) of the IN operator */
u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
int *prRhsHasNull, /* Register holding NULL status. See notes */
- int *aiMap /* Mapping from Index fields to RHS fields */
+ int *aiMap, /* Mapping from Index fields to RHS fields */
+ int *piTab /* OUT: index to use */
){
Select *p; /* SELECT to the right of IN operator */
int eType = 0; /* Type of RHS table. IN_INDEX_* */
@@ -98536,6 +99090,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
Bitmask colUsed; /* Columns of the index used */
Bitmask mCol; /* Mask for the current column */
if( pIdx->nColumn<nExpr ) continue;
+ if( pIdx->pPartIdxWhere!=0 ) continue;
/* Maximum nColumn is BMS-2, not BMS-1, so that we can compute
** BITMASK(nExpr) without overflowing */
testcase( pIdx->nColumn==BMS-2 );
@@ -98632,10 +99187,12 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
}else if( prRhsHasNull ){
*prRhsHasNull = rMayHaveNull = ++pParse->nMem;
}
- sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
+ assert( pX->op==TK_IN );
+ sqlite3CodeRhsOfIN(pParse, pX, iTab, eType==IN_INDEX_ROWID);
+ if( rMayHaveNull ){
+ sqlite3SetHasNullFlag(v, iTab, rMayHaveNull);
+ }
pParse->nQueryLoop = savedNQueryLoop;
- }else{
- pX->iTable = iTab;
}
if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
@@ -98643,6 +99200,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
n = sqlite3ExprVectorSize(pX->pLeft);
for(i=0; i<n; i++) aiMap[i] = i;
}
+ *piTab = iTab;
return eType;
}
#endif
@@ -98716,260 +99274,326 @@ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
}
}
+#ifndef SQLITE_OMIT_SUBQUERY
/*
-** Generate code for scalar subqueries used as a subquery expression, EXISTS,
-** or IN operators. Examples:
+** Generate code that will construct an ephemeral table containing all terms
+** in the RHS of an IN operator. The IN operator can be in either of two
+** forms:
**
-** (SELECT a FROM b) -- subquery
-** EXISTS (SELECT a FROM b) -- EXISTS subquery
** x IN (4,5,11) -- IN operator with list on right-hand side
** x IN (SELECT a FROM b) -- IN operator with subquery on the right
**
-** The pExpr parameter describes the expression that contains the IN
-** operator or subquery.
-**
-** If parameter isRowid is non-zero, then expression pExpr is guaranteed
-** to be of the form "<rowid> IN (?, ?, ?)", where <rowid> is a reference
-** to some integer key column of a table B-Tree. In this case, use an
-** intkey B-Tree to store the set of IN(...) values instead of the usual
-** (slower) variable length keys B-Tree.
-**
-** If rMayHaveNull is non-zero, that means that the operation is an IN
-** (not a SELECT or EXISTS) and that the RHS might contains NULLs.
-** All this routine does is initialize the register given by rMayHaveNull
-** to NULL. Calling routines will take care of changing this register
-** value to non-NULL if the RHS is NULL-free.
-**
-** For a SELECT or EXISTS operator, return the register that holds the
-** result. For a multi-column SELECT, the result is stored in a contiguous
-** array of registers and the return value is the register of the left-most
-** result column. Return 0 for IN operators or if an error occurs.
-*/
-#ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE int sqlite3CodeSubselect(
+** The pExpr parameter is the IN operator. The cursor number for the
+** constructed ephermeral table is returned. The first time the ephemeral
+** table is computed, the cursor number is also stored in pExpr->iTable,
+** however the cursor number returned might not be the same, as it might
+** have been duplicated using OP_OpenDup.
+**
+** If parameter isRowid is non-zero, then LHS of the IN operator is guaranteed
+** to be a non-null integer. In this case, the ephemeral table can be an
+** table B-Tree that keyed by only integers. The more general cases uses
+** an index B-Tree which can have arbitrary keys, but is slower to both
+** read and write.
+**
+** If the LHS expression ("x" in the examples) is a column value, or
+** the SELECT statement returns a column value, then the affinity of that
+** column is used to build the index keys. If both 'x' and the
+** SELECT... statement are columns, then numeric affinity is used
+** if either column has NUMERIC or INTEGER affinity. If neither
+** 'x' nor the SELECT... statement are columns, then numeric affinity
+** is used.
+*/
+SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
Parse *pParse, /* Parsing context */
- Expr *pExpr, /* The IN, SELECT, or EXISTS operator */
- int rHasNullFlag, /* Register that records whether NULLs exist in RHS */
- int isRowid /* If true, LHS of IN operator is a rowid */
+ Expr *pExpr, /* The IN operator */
+ int iTab, /* Use this cursor number */
+ int isRowid /* If true, LHS is a rowid */
){
- int jmpIfDynamic = -1; /* One-time test address */
- int rReg = 0; /* Register storing resulting */
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return 0;
+ int addrOnce = 0; /* Address of the OP_Once instruction at top */
+ int addr; /* Address of OP_OpenEphemeral instruction */
+ Expr *pLeft; /* the LHS of the IN operator */
+ KeyInfo *pKeyInfo = 0; /* Key information */
+ int nVal; /* Size of vector pLeft */
+ Vdbe *v; /* The prepared statement under construction */
- /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it
+ v = pParse->pVdbe;
+ assert( v!=0 );
+
+ /* The evaluation of the IN must be repeated every time it
** is encountered if any of the following is true:
**
** * The right-hand side is a correlated subquery
** * The right-hand side is an expression list containing variables
** * We are inside a trigger
**
- ** If all of the above are false, then we can run this code just once
- ** save the results, and reuse the same result on subsequent invocations.
+ ** If all of the above are false, then we can compute the RHS just once
+ ** and reuse it many names.
*/
- if( !ExprHasProperty(pExpr, EP_VarSelect) ){
- jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
- }
+ if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){
+ /* Reuse of the RHS is allowed */
+ /* If this routine has already been coded, but the previous code
+ ** might not have been invoked yet, so invoke it now as a subroutine.
+ */
+ if( ExprHasProperty(pExpr, EP_Subrtn) ){
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
+ pExpr->x.pSelect->selId));
+ }
+ sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
+ pExpr->y.sub.iAddr);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
+ sqlite3VdbeJumpHere(v, addrOnce);
+ return;
+ }
- switch( pExpr->op ){
- case TK_IN: {
- int addr; /* Address of OP_OpenEphemeral instruction */
- Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
- KeyInfo *pKeyInfo = 0; /* Key information */
- int nVal; /* Size of vector pLeft */
-
- nVal = sqlite3ExprVectorSize(pLeft);
- assert( !isRowid || nVal==1 );
+ /* Begin coding the subroutine */
+ ExprSetProperty(pExpr, EP_Subrtn);
+ pExpr->y.sub.regReturn = ++pParse->nMem;
+ pExpr->y.sub.iAddr =
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
+ VdbeComment((v, "return address"));
- /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
- ** expression it is handled the same way. An ephemeral table is
- ** filled with index keys representing the results from the
- ** SELECT or the <exprlist>.
- **
- ** If the 'x' expression is a column value, or the SELECT...
- ** statement returns a column value, then the affinity of that
- ** column is used to build the index keys. If both 'x' and the
- ** SELECT... statement are columns, then numeric affinity is used
- ** if either column has NUMERIC or INTEGER affinity. If neither
- ** 'x' nor the SELECT... statement are columns, then numeric affinity
- ** is used.
- */
- pExpr->iTable = pParse->nTab++;
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral,
- pExpr->iTable, (isRowid?0:nVal));
- pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ }
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- /* Case 1: expr IN (SELECT ...)
- **
- ** Generate code to write the results of the select into the temporary
- ** table allocated and opened above.
- */
- Select *pSelect = pExpr->x.pSelect;
- ExprList *pEList = pSelect->pEList;
-
- ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
- jmpIfDynamic>=0?"":"CORRELATED "
- ));
- assert( !isRowid );
- /* If the LHS and RHS of the IN operator do not match, that
- ** error will have been caught long before we reach this point. */
- if( ALWAYS(pEList->nExpr==nVal) ){
- SelectDest dest;
- int i;
- sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
- dest.zAffSdst = exprINAffinity(pParse, pExpr);
- pSelect->iLimit = 0;
- testcase( pSelect->selFlags & SF_Distinct );
- testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
- if( sqlite3Select(pParse, pSelect, &dest) ){
- sqlite3DbFree(pParse->db, dest.zAffSdst);
- sqlite3KeyInfoUnref(pKeyInfo);
- return 0;
- }
- sqlite3DbFree(pParse->db, dest.zAffSdst);
- assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
- assert( pEList!=0 );
- assert( pEList->nExpr>0 );
- assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
- for(i=0; i<nVal; i++){
- Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
- pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
- pParse, p, pEList->a[i].pExpr
- );
- }
- }
- }else if( ALWAYS(pExpr->x.pList!=0) ){
- /* Case 2: expr IN (exprlist)
- **
- ** For each expression, build an index key from the evaluation and
- ** store it in the temporary table. If <expr> is a column, then use
- ** that columns affinity when building index keys. If <expr> is not
- ** a column, use numeric affinity.
- */
- char affinity; /* Affinity of the LHS of the IN */
- int i;
- ExprList *pList = pExpr->x.pList;
- struct ExprList_item *pItem;
- int r1, r2, r3;
- affinity = sqlite3ExprAffinity(pLeft);
- if( !affinity ){
- affinity = SQLITE_AFF_BLOB;
- }
- if( pKeyInfo ){
- assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
- pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
- }
+ /* Check to see if this is a vector IN operator */
+ pLeft = pExpr->pLeft;
+ nVal = sqlite3ExprVectorSize(pLeft);
+ assert( !isRowid || nVal==1 );
- /* Loop through each expression in <exprlist>. */
- r1 = sqlite3GetTempReg(pParse);
- r2 = sqlite3GetTempReg(pParse);
- if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC);
- for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
- Expr *pE2 = pItem->pExpr;
- int iValToIns;
-
- /* If the expression is not constant then we will need to
- ** disable the test that was generated above that makes sure
- ** this code only executes once. Because for a non-constant
- ** expression we need to rerun this code each time.
- */
- if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){
- sqlite3VdbeChangeToNoop(v, jmpIfDynamic);
- jmpIfDynamic = -1;
- }
+ /* Construct the ephemeral table that will contain the content of
+ ** RHS of the IN operator.
+ */
+ pExpr->iTable = iTab;
+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral,
+ pExpr->iTable, (isRowid?0:nVal));
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId));
+ }else{
+ VdbeComment((v, "RHS of IN operator"));
+ }
+#endif
+ pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
- /* Evaluate the expression and insert it into the temp table */
- if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
- sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
- }else{
- r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
- if( isRowid ){
- sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
- sqlite3VdbeCurrentAddr(v)+2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
- }else{
- sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
- }
- }
- }
- sqlite3ReleaseTempReg(pParse, r1);
- sqlite3ReleaseTempReg(pParse, r2);
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ /* Case 1: expr IN (SELECT ...)
+ **
+ ** Generate code to write the results of the select into the temporary
+ ** table allocated and opened above.
+ */
+ Select *pSelect = pExpr->x.pSelect;
+ ExprList *pEList = pSelect->pEList;
+
+ ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY %d",
+ addrOnce?"":"CORRELATED ", pSelect->selId
+ ));
+ assert( !isRowid );
+ /* If the LHS and RHS of the IN operator do not match, that
+ ** error will have been caught long before we reach this point. */
+ if( ALWAYS(pEList->nExpr==nVal) ){
+ SelectDest dest;
+ int i;
+ sqlite3SelectDestInit(&dest, SRT_Set, iTab);
+ dest.zAffSdst = exprINAffinity(pParse, pExpr);
+ pSelect->iLimit = 0;
+ testcase( pSelect->selFlags & SF_Distinct );
+ testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
+ if( sqlite3Select(pParse, pSelect, &dest) ){
+ sqlite3DbFree(pParse->db, dest.zAffSdst);
+ sqlite3KeyInfoUnref(pKeyInfo);
+ return;
}
- if( pKeyInfo ){
- sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
+ sqlite3DbFree(pParse->db, dest.zAffSdst);
+ assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
+ assert( pEList!=0 );
+ assert( pEList->nExpr>0 );
+ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+ for(i=0; i<nVal; i++){
+ Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
+ pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
+ pParse, p, pEList->a[i].pExpr
+ );
}
- break;
+ }
+ }else if( ALWAYS(pExpr->x.pList!=0) ){
+ /* Case 2: expr IN (exprlist)
+ **
+ ** For each expression, build an index key from the evaluation and
+ ** store it in the temporary table. If <expr> is a column, then use
+ ** that columns affinity when building index keys. If <expr> is not
+ ** a column, use numeric affinity.
+ */
+ char affinity; /* Affinity of the LHS of the IN */
+ int i;
+ ExprList *pList = pExpr->x.pList;
+ struct ExprList_item *pItem;
+ int r1, r2, r3;
+ affinity = sqlite3ExprAffinity(pLeft);
+ if( !affinity ){
+ affinity = SQLITE_AFF_BLOB;
+ }
+ if( pKeyInfo ){
+ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+ pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
}
- case TK_EXISTS:
- case TK_SELECT:
- default: {
- /* Case 3: (SELECT ... FROM ...)
- ** or: EXISTS(SELECT ... FROM ...)
- **
- ** For a SELECT, generate code to put the values for all columns of
- ** the first row into an array of registers and return the index of
- ** the first register.
- **
- ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
- ** into a register and return that register number.
- **
- ** In both cases, the query is augmented with "LIMIT 1". Any
- ** preexisting limit is discarded in place of the new LIMIT 1.
+ /* Loop through each expression in <exprlist>. */
+ r1 = sqlite3GetTempReg(pParse);
+ r2 = sqlite3GetTempReg(pParse);
+ if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC);
+ for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
+ Expr *pE2 = pItem->pExpr;
+ int iValToIns;
+
+ /* If the expression is not constant then we will need to
+ ** disable the test that was generated above that makes sure
+ ** this code only executes once. Because for a non-constant
+ ** expression we need to rerun this code each time.
*/
- Select *pSel; /* SELECT statement to encode */
- SelectDest dest; /* How to deal with SELECT result */
- int nReg; /* Registers to allocate */
- Expr *pLimit; /* New limit expression */
-
- testcase( pExpr->op==TK_EXISTS );
- testcase( pExpr->op==TK_SELECT );
- assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
- assert( ExprHasProperty(pExpr, EP_xIsSelect) );
+ if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
+ sqlite3VdbeChangeToNoop(v, addrOnce);
+ addrOnce = 0;
+ }
- pSel = pExpr->x.pSelect;
- ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
- jmpIfDynamic>=0?"":"CORRELATED "));
- nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
- sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
- pParse->nMem += nReg;
- if( pExpr->op==TK_SELECT ){
- dest.eDest = SRT_Mem;
- dest.iSdst = dest.iSDParm;
- dest.nSdst = nReg;
- sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
- VdbeComment((v, "Init subquery result"));
- }else{
- dest.eDest = SRT_Exists;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
- VdbeComment((v, "Init EXISTS result"));
- }
- pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
- if( pSel->pLimit ){
- sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
- pSel->pLimit->pLeft = pLimit;
+ /* Evaluate the expression and insert it into the temp table */
+ if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
+ sqlite3VdbeAddOp3(v, OP_InsertInt, iTab, r2, iValToIns);
}else{
- pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
- }
- pSel->iLimit = 0;
- if( sqlite3Select(pParse, pSel, &dest) ){
- return 0;
+ r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
+ if( isRowid ){
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
+ sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_Insert, iTab, r2, r3);
+ }else{
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1);
+ }
}
- rReg = dest.iSDParm;
- ExprSetVVAProperty(pExpr, EP_NoReduce);
- break;
}
+ sqlite3ReleaseTempReg(pParse, r1);
+ sqlite3ReleaseTempReg(pParse, r2);
+ }
+ if( pKeyInfo ){
+ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
}
+ if( addrOnce ){
+ sqlite3VdbeJumpHere(v, addrOnce);
+ /* Subroutine return */
+ sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
+ sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
+ }
+}
+#endif /* SQLITE_OMIT_SUBQUERY */
+
+/*
+** Generate code for scalar subqueries used as a subquery expression
+** or EXISTS operator:
+**
+** (SELECT a FROM b) -- subquery
+** EXISTS (SELECT a FROM b) -- EXISTS subquery
+**
+** The pExpr parameter is the SELECT or EXISTS operator to be coded.
+**
+** The register that holds the result. For a multi-column SELECT,
+** the result is stored in a contiguous array of registers and the
+** return value is the register of the left-most result column.
+** Return 0 if an error occurs.
+*/
+#ifndef SQLITE_OMIT_SUBQUERY
+SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
+ int addrOnce = 0; /* Address of OP_Once at top of subroutine */
+ int rReg = 0; /* Register storing resulting */
+ Select *pSel; /* SELECT statement to encode */
+ SelectDest dest; /* How to deal with SELECT result */
+ int nReg; /* Registers to allocate */
+ Expr *pLimit; /* New limit expression */
+
+ Vdbe *v = pParse->pVdbe;
+ assert( v!=0 );
+ testcase( pExpr->op==TK_EXISTS );
+ testcase( pExpr->op==TK_SELECT );
+ assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
+ assert( ExprHasProperty(pExpr, EP_xIsSelect) );
+ pSel = pExpr->x.pSelect;
+
+ /* The evaluation of the EXISTS/SELECT must be repeated every time it
+ ** is encountered if any of the following is true:
+ **
+ ** * The right-hand side is a correlated subquery
+ ** * The right-hand side is an expression list containing variables
+ ** * We are inside a trigger
+ **
+ ** If all of the above are false, then we can run this code just once
+ ** save the results, and reuse the same result on subsequent invocations.
+ */
+ if( !ExprHasProperty(pExpr, EP_VarSelect) ){
+ /* If this routine has already been coded, then invoke it as a
+ ** subroutine. */
+ if( ExprHasProperty(pExpr, EP_Subrtn) ){
+ ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
+ sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
+ pExpr->y.sub.iAddr);
+ return pExpr->iTable;
+ }
+
+ /* Begin coding the subroutine */
+ ExprSetProperty(pExpr, EP_Subrtn);
+ pExpr->y.sub.regReturn = ++pParse->nMem;
+ pExpr->y.sub.iAddr =
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
+ VdbeComment((v, "return address"));
- if( rHasNullFlag ){
- sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag);
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ }
+
+ /* For a SELECT, generate code to put the values for all columns of
+ ** the first row into an array of registers and return the index of
+ ** the first register.
+ **
+ ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
+ ** into a register and return that register number.
+ **
+ ** In both cases, the query is augmented with "LIMIT 1". Any
+ ** preexisting limit is discarded in place of the new LIMIT 1.
+ */
+ ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY %d",
+ addrOnce?"":"CORRELATED ", pSel->selId));
+ nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
+ sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
+ pParse->nMem += nReg;
+ if( pExpr->op==TK_SELECT ){
+ dest.eDest = SRT_Mem;
+ dest.iSdst = dest.iSDParm;
+ dest.nSdst = nReg;
+ sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
+ VdbeComment((v, "Init subquery result"));
+ }else{
+ dest.eDest = SRT_Exists;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
+ VdbeComment((v, "Init EXISTS result"));
+ }
+ pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
+ if( pSel->pLimit ){
+ sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
+ pSel->pLimit->pLeft = pLimit;
+ }else{
+ pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
}
+ pSel->iLimit = 0;
+ if( sqlite3Select(pParse, pSel, &dest) ){
+ return 0;
+ }
+ pExpr->iTable = rReg = dest.iSDParm;
+ ExprSetVVAProperty(pExpr, EP_NoReduce);
+ if( addrOnce ){
+ sqlite3VdbeJumpHere(v, addrOnce);
- if( jmpIfDynamic>=0 ){
- sqlite3VdbeJumpHere(v, jmpIfDynamic);
+ /* Subroutine return */
+ sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
+ sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
}
return rReg;
@@ -99046,6 +99670,7 @@ static void sqlite3ExprCodeIN(
int addrTruthOp; /* Address of opcode that determines the IN is true */
int destNotNull; /* Jump here if a comparison is not true in step 6 */
int addrTop; /* Top of the step-6 loop */
+ int iTab = 0; /* Index to use */
pLeft = pExpr->pLeft;
if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
@@ -99057,7 +99682,7 @@ static void sqlite3ExprCodeIN(
if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
/* Attempt to compute the RHS. After this step, if anything other than
- ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable
+ ** IN_INDEX_NOOP is returned, the table opened with cursor iTab
** contains the values that make up the RHS. If IN_INDEX_NOOP is returned,
** the RHS has not yet been coded. */
v = pParse->pVdbe;
@@ -99065,7 +99690,8 @@ static void sqlite3ExprCodeIN(
VdbeNoopComment((v, "begin IN expr"));
eType = sqlite3FindInIndex(pParse, pExpr,
IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK,
- destIfFalse==destIfNull ? 0 : &rRhsHasNull, aiMap);
+ destIfFalse==destIfNull ? 0 : &rRhsHasNull,
+ aiMap, &iTab);
assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH
|| eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC
@@ -99111,7 +99737,7 @@ static void sqlite3ExprCodeIN(
if( eType==IN_INDEX_NOOP ){
ExprList *pList = pExpr->x.pList;
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
- int labelOk = sqlite3VdbeMakeLabel(v);
+ int labelOk = sqlite3VdbeMakeLabel(pParse);
int r2, regToFree;
int regCkNull = 0;
int ii;
@@ -99155,7 +99781,7 @@ static void sqlite3ExprCodeIN(
if( destIfNull==destIfFalse ){
destStep2 = destIfFalse;
}else{
- destStep2 = destStep6 = sqlite3VdbeMakeLabel(v);
+ destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
}
for(i=0; i<nVector; i++){
Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
@@ -99173,19 +99799,19 @@ static void sqlite3ExprCodeIN(
/* In this case, the RHS is the ROWID of table b-tree and so we also
** know that the RHS is non-NULL. Hence, we combine steps 3 and 4
** into a single opcode. */
- sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, rLhs);
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs);
VdbeCoverage(v);
addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */
}else{
sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
if( destIfFalse==destIfNull ){
/* Combine Step 3 and Step 5 into a single opcode */
- sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse,
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse,
rLhs, nVector); VdbeCoverage(v);
goto sqlite3ExprCodeIN_finished;
}
/* Ordinary Step 3, for the case where FALSE and NULL are distinct */
- addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0,
+ addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0,
rLhs, nVector); VdbeCoverage(v);
}
@@ -99210,10 +99836,10 @@ static void sqlite3ExprCodeIN(
** of the RHS.
*/
if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6);
- addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
+ addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse);
VdbeCoverage(v);
if( nVector>1 ){
- destNotNull = sqlite3VdbeMakeLabel(v);
+ destNotNull = sqlite3VdbeMakeLabel(pParse);
}else{
/* For nVector==1, combine steps 6 and 7 by immediately returning
** FALSE if the first comparison is not NULL */
@@ -99225,7 +99851,7 @@ static void sqlite3ExprCodeIN(
int r3 = sqlite3GetTempReg(pParse);
p = sqlite3VectorFieldSubexpr(pLeft, i);
pColl = sqlite3ExprCollSeq(pParse, p);
- sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, i, r3);
+ sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3);
sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
(void*)pColl, P4_COLLSEQ);
VdbeCoverage(v);
@@ -99234,7 +99860,7 @@ static void sqlite3ExprCodeIN(
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
if( nVector>1 ){
sqlite3VdbeResolveLabel(v, destNotNull);
- sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrTop+1);
+ sqlite3VdbeAddOp2(v, OP_Next, iTab, addrTop+1);
VdbeCoverage(v);
/* Step 7: If we reach this point, we know that the result must
@@ -99433,7 +100059,7 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
#if SQLITE_OMIT_SUBQUERY
iResult = 0;
#else
- iResult = sqlite3CodeSubselect(pParse, p, 0, 0);
+ iResult = sqlite3CodeSubselect(pParse, p);
#endif
}else{
int i;
@@ -99778,7 +100404,7 @@ expr_code_doover:
** arguments past the first non-NULL argument.
*/
if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){
- int endCoalesce = sqlite3VdbeMakeLabel(v);
+ int endCoalesce = sqlite3VdbeMakeLabel(pParse);
assert( nFarg>=2 );
sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
for(i=1; i<nFarg; i++){
@@ -99907,14 +100533,14 @@ expr_code_doover:
if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
sqlite3SubselectError(pParse, nCol, 1);
}else{
- return sqlite3CodeSubselect(pParse, pExpr, 0, 0);
+ return sqlite3CodeSubselect(pParse, pExpr);
}
break;
}
case TK_SELECT_COLUMN: {
int n;
if( pExpr->pLeft->iTable==0 ){
- pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0);
+ pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
}
assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
if( pExpr->iTable
@@ -99926,8 +100552,8 @@ expr_code_doover:
return pExpr->pLeft->iTable + pExpr->iColumn;
}
case TK_IN: {
- int destIfFalse = sqlite3VdbeMakeLabel(v);
- int destIfNull = sqlite3VdbeMakeLabel(v);
+ int destIfFalse = sqlite3VdbeMakeLabel(pParse);
+ int destIfNull = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
@@ -100067,9 +100693,9 @@ expr_code_doover:
pEList = pExpr->x.pList;
aListelem = pEList->a;
nExpr = pEList->nExpr;
- endLabel = sqlite3VdbeMakeLabel(v);
+ endLabel = sqlite3VdbeMakeLabel(pParse);
if( (pX = pExpr->pLeft)!=0 ){
- tempX = *pX;
+ exprNodeCopy(&tempX, pX);
testcase( pX->op==TK_COLUMN );
exprToRegister(&tempX, exprCodeVector(pParse, &tempX, &regFree1));
testcase( regFree1==0 );
@@ -100090,7 +100716,7 @@ expr_code_doover:
}else{
pTest = aListelem[i].pExpr;
}
- nextCase = sqlite3VdbeMakeLabel(v);
+ nextCase = sqlite3VdbeMakeLabel(pParse);
testcase( pTest->op==TK_COLUMN );
sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
@@ -100390,13 +101016,12 @@ static void exprCodeBetween(
Expr exprX; /* The x subexpression */
int regFree1 = 0; /* Temporary use register */
-
memset(&compLeft, 0, sizeof(Expr));
memset(&compRight, 0, sizeof(Expr));
memset(&exprAnd, 0, sizeof(Expr));
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- exprX = *pExpr->pLeft;
+ exprNodeCopy(&exprX, pExpr->pLeft);
exprAnd.op = TK_AND;
exprAnd.pLeft = &compLeft;
exprAnd.pRight = &compRight;
@@ -100459,7 +101084,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
op = pExpr->op;
switch( op ){
case TK_AND: {
- int d2 = sqlite3VdbeMakeLabel(v);
+ int d2 = sqlite3VdbeMakeLabel(pParse);
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
@@ -100545,7 +101170,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_IN: {
- int destIfFalse = sqlite3VdbeMakeLabel(v);
+ int destIfFalse = sqlite3VdbeMakeLabel(pParse);
int destIfNull = jumpIfNull ? dest : destIfFalse;
sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
sqlite3VdbeGoto(v, dest);
@@ -100632,7 +101257,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
break;
}
case TK_OR: {
- int d2 = sqlite3VdbeMakeLabel(v);
+ int d2 = sqlite3VdbeMakeLabel(pParse);
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
@@ -100716,7 +101341,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
if( jumpIfNull ){
sqlite3ExprCodeIN(pParse, pExpr, dest, dest);
}else{
- int destIfNull = sqlite3VdbeMakeLabel(v);
+ int destIfNull = sqlite3VdbeMakeLabel(pParse);
sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull);
sqlite3VdbeResolveLabel(v, destIfNull);
}
@@ -100837,7 +101462,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa
}
return 2;
}
- if( pA->op!=pB->op ){
+ if( pA->op!=pB->op || pA->op==TK_RAISE ){
if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){
return 1;
}
@@ -100863,21 +101488,25 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa
if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
}
#endif
+ }else if( pA->op==TK_NULL ){
+ return 0;
}else if( pA->op==TK_COLLATE ){
if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
- }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
+ }else if( ALWAYS(pB->u.zToken!=0) && strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 2;
}
}
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
- if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
+ if( (combinedFlags & EP_TokenOnly)==0 ){
if( combinedFlags & EP_xIsSelect ) return 2;
if( (combinedFlags & EP_FixedCol)==0
&& sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
- assert( (combinedFlags & EP_Reduced)==0 );
- if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){
+ if( pA->op!=TK_STRING
+ && pA->op!=TK_TRUEFALSE
+ && (combinedFlags & EP_Reduced)==0
+ ){
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
@@ -100986,6 +101615,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
case TK_ISNOT:
case TK_NOT:
case TK_ISNULL:
+ case TK_NOTNULL:
case TK_IS:
case TK_OR:
case TK_CASE:
@@ -100994,6 +101624,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_ISNOT );
testcase( pExpr->op==TK_NOT );
testcase( pExpr->op==TK_ISNULL );
+ testcase( pExpr->op==TK_NOTNULL );
testcase( pExpr->op==TK_IS );
testcase( pExpr->op==TK_OR );
testcase( pExpr->op==TK_CASE );
@@ -101367,6 +101998,7 @@ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
w.xSelectCallback2 = analyzeAggregatesInSelectEnd;
w.walkerDepth = 0;
w.u.pNC = pNC;
+ w.pParse = 0;
assert( pNC->pSrcList!=0 );
sqlite3WalkExpr(&w, pExpr);
}
@@ -101498,9 +102130,16 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
**
** Or, if zName is not a system table, zero is returned.
*/
-static int isSystemTable(Parse *pParse, const char *zName){
- if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
- sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
+static int isAlterableTable(Parse *pParse, Table *pTab){
+ if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7)
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ || ( (pTab->tabFlags & TF_Shadow)
+ && (pParse->db->flags & SQLITE_Defensive)
+ && pParse->db->nVdbeExec==0
+ )
+#endif
+ ){
+ sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
return 1;
}
return 0;
@@ -101596,7 +102235,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
/* Make sure it is not a system table being altered, or a reserved name
** that the table is being renamed to.
*/
- if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
+ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
goto exit_rename_table;
}
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto
@@ -101894,7 +102533,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
goto exit_begin_add_column;
}
- if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
+ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
goto exit_begin_add_column;
}
@@ -101996,7 +102635,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn(
if( !pTab ) goto exit_rename_column;
/* Cannot alter a system table */
- if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column;
+ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column;
if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column;
/* Which schema holds the table to be altered */
@@ -102251,13 +102890,30 @@ static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){
}
/*
+** Iterate through the Select objects that are part of WITH clauses attached
+** to select statement pSelect.
+*/
+static void renameWalkWith(Walker *pWalker, Select *pSelect){
+ if( pSelect->pWith ){
+ int i;
+ for(i=0; i<pSelect->pWith->nCte; i++){
+ Select *p = pSelect->pWith->a[i].pSelect;
+ NameContext sNC;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pWalker->pParse;
+ sqlite3SelectPrep(sNC.pParse, p, &sNC);
+ sqlite3WalkSelect(pWalker, p);
+ }
+ }
+}
+
+/*
** This is a Walker select callback. It does nothing. It is only required
** because without a dummy callback, sqlite3WalkExpr() and similar do not
** descend into sub-select statements.
*/
static int renameColumnSelectCb(Walker *pWalker, Select *p){
- UNUSED_PARAMETER(pWalker);
- UNUSED_PARAMETER(p);
+ renameWalkWith(pWalker, p);
return WRC_Continue;
}
@@ -102407,7 +103063,6 @@ static int renameParseSql(
rc = sqlite3RunParser(p, zSql, &zErr);
assert( p->zErrMsg==0 );
assert( rc!=SQLITE_OK || zErr==0 );
- assert( (0!=p->pNewTable) + (0!=p->pNewIndex) + (0!=p->pNewTrigger)<2 );
p->zErrMsg = zErr;
if( db->mallocFailed ) rc = SQLITE_NOMEM;
if( rc==SQLITE_OK
@@ -102590,6 +103245,7 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){
}
sNC.ncFlags = 0;
}
+ sNC.pSrcList = 0;
}
}
}
@@ -102627,11 +103283,15 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){
*/
static void renameParseCleanup(Parse *pParse){
sqlite3 *db = pParse->db;
+ Index *pIdx;
if( pParse->pVdbe ){
sqlite3VdbeFinalize(pParse->pVdbe);
}
sqlite3DeleteTable(db, pParse->pNewTable);
- if( pParse->pNewIndex ) sqlite3FreeIndex(db, pParse->pNewIndex);
+ while( (pIdx = pParse->pNewIndex)!=0 ){
+ pParse->pNewIndex = pIdx->pNext;
+ sqlite3FreeIndex(db, pIdx);
+ }
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
sqlite3DbFree(db, pParse->zErrMsg);
renameTokenFree(db, pParse->pRename);
@@ -102742,6 +103402,9 @@ static void renameColumnFunc(
for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
}
+ for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){
+ sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
+ }
}
for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
@@ -102828,12 +103491,17 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
int i;
RenameCtx *p = pWalker->u.pRename;
SrcList *pSrc = pSelect->pSrc;
+ if( pSrc==0 ){
+ assert( pWalker->pParse->db->mallocFailed );
+ return WRC_Abort;
+ }
for(i=0; i<pSrc->nSrc; i++){
struct SrcList_item *pItem = &pSrc->a[i];
if( pItem->pTab==p->pTab ){
renameTokenFind(pWalker->pParse, p, pItem->zName);
}
}
+ renameWalkWith(pWalker, pSelect);
return WRC_Continue;
}
@@ -104235,7 +104903,7 @@ static void analyzeOneTable(
addrNextRow = sqlite3VdbeCurrentAddr(v);
if( nColTest>0 ){
- int endDistinctTest = sqlite3VdbeMakeLabel(v);
+ int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
int *aGotoChng; /* Array of jump instruction addresses */
aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest);
if( aGotoChng==0 ) continue;
@@ -105173,8 +105841,8 @@ static void attachFunc(
assert( pVfs );
flags |= SQLITE_OPEN_MAIN_DB;
rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
- sqlite3_free( zPath );
db->nDb++;
+ pNew->zDbSName = sqlite3DbStrDup(db, zName);
}
db->noSharedCache = 0;
if( rc==SQLITE_CONSTRAINT ){
@@ -105202,7 +105870,6 @@ static void attachFunc(
sqlite3BtreeLeave(pNew->pBt);
}
pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
- if( !REOPEN_AS_MEMDB(db) ) pNew->zDbSName = sqlite3DbStrDup(db, zName);
if( rc==SQLITE_OK && pNew->zDbSName==0 ){
rc = SQLITE_NOMEM_BKPT;
}
@@ -105230,15 +105897,19 @@ static void attachFunc(
break;
case SQLITE_NULL:
- /* No key specified. Use the key from the main database */
- sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
- if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
- rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+ /* No key specified. Use the key from URI filename, or if none,
+ ** use the key from the main database. */
+ if( sqlite3CodecQueryParameters(db, zName, zPath)==0 ){
+ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
+ if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
+ rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+ }
}
break;
}
}
#endif
+ sqlite3_free( zPath );
/* If the file was opened successfully, read the schema for the new database.
** If this fails, or if opening the file failed, then close the file and
@@ -106150,7 +106821,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
if( v && pParse->nErr==0 && !db->mallocFailed ){
/* A minimum of one cursor is required if autoincrement is used
* See ticket [a696379c1f08866] */
- if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
+ assert( pParse->pAinc==0 || pParse->nTab>0 );
sqlite3VdbeMakeReady(v, pParse);
pParse->rc = SQLITE_DONE;
}else{
@@ -106277,26 +106948,32 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
p = sqlite3FindTable(db, zName, zDbase);
if( p==0 ){
- const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* If zName is the not the name of a table in the schema created using
** CREATE, then check to see if it is the name of an virtual table that
** can be an eponymous virtual table. */
- Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
- if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
- pMod = sqlite3PragmaVtabRegister(db, zName);
- }
- if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
- return pMod->pEpoTab;
+ if( pParse->disableVtab==0 ){
+ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
+ if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
+ pMod = sqlite3PragmaVtabRegister(db, zName);
+ }
+ if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
+ return pMod->pEpoTab;
+ }
}
#endif
- if( (flags & LOCATE_NOERR)==0 ){
- if( zDbase ){
- sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
- }else{
- sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
- }
- pParse->checkSchema = 1;
+ if( flags & LOCATE_NOERR ) return 0;
+ pParse->checkSchema = 1;
+ }else if( IsVirtual(p) && pParse->disableVtab ){
+ p = 0;
+ }
+
+ if( p==0 ){
+ const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
+ if( zDbase ){
+ sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
+ }else{
+ sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
}
}
@@ -106559,12 +107236,6 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
/* Delete the Table structure itself.
*/
-#ifdef SQLITE_ENABLE_NORMALIZE
- if( pTable->pColHash ){
- sqlite3HashClear(pTable->pColHash);
- sqlite3_free(pTable->pColHash);
- }
-#endif
sqlite3DeleteColumnNames(db, pTable);
sqlite3DbFree(db, pTable->zName);
sqlite3DbFree(db, pTable->zColAff);
@@ -108561,6 +109232,7 @@ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, in
*/
if( IsVirtual(pTab) ){
sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
+ sqlite3MayAbort(pParse);
}
sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
sqlite3ChangeCookie(pParse, iDb);
@@ -109389,6 +110061,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
}
}
if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType;
+ if( IN_RENAME_OBJECT ){
+ pIndex->pNext = pParse->pNewIndex;
+ pParse->pNewIndex = pIndex;
+ pIndex = 0;
+ }
goto exit_create_index;
}
}
@@ -109404,6 +110081,14 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
Index *p;
assert( !IN_SPECIAL_PARSE );
assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
+ if( pTblName!=0 ){
+ pIndex->tnum = db->init.newTnum;
+ if( sqlite3IndexHasDuplicateRootPage(pIndex) ){
+ sqlite3ErrorMsg(pParse, "invalid rootpage");
+ pParse->rc = SQLITE_CORRUPT_BKPT;
+ goto exit_create_index;
+ }
+ }
p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
pIndex->zName, pIndex);
if( p ){
@@ -109412,9 +110097,6 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
goto exit_create_index;
}
db->mDbFlags |= DBFLAG_SchemaChange;
- if( pTblName!=0 ){
- pIndex->tnum = db->init.newTnum;
- }
}
/* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
@@ -109741,6 +110423,18 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
}
/*
+** Maximum size of a SrcList object.
+** The SrcList object is used to represent the FROM clause of a
+** SELECT statement, and the query planner cannot deal with more
+** than 64 tables in a join. So any value larger than 64 here
+** is sufficient for most uses. Smaller values, like say 10, are
+** appropriate for small and memory-limited applications.
+*/
+#ifndef SQLITE_MAX_SRCLIST
+# define SQLITE_MAX_SRCLIST 200
+#endif
+
+/*
** Expand the space allocated for the given SrcList object by
** creating nExtra new slots beginning at iStart. iStart is zero based.
** New slots are zeroed.
@@ -109756,11 +110450,12 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
** the iStart value would be 0. The result then would
** be: nil, nil, nil, A, B.
**
-** If a memory allocation fails the SrcList is unchanged. The
-** db->mallocFailed flag will be set to true.
+** If a memory allocation fails or the SrcList becomes too large, leave
+** the original SrcList unchanged, return NULL, and leave an error message
+** in pParse.
*/
SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
- sqlite3 *db, /* Database connection to notify of OOM errors */
+ Parse *pParse, /* Parsing context into which errors are reported */
SrcList *pSrc, /* The SrcList to be enlarged */
int nExtra, /* Number of new slots to add to pSrc->a[] */
int iStart /* Index in pSrc->a[] of first new slot */
@@ -109777,16 +110472,22 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){
SrcList *pNew;
int nAlloc = pSrc->nSrc*2+nExtra;
- int nGot;
+ sqlite3 *db = pParse->db;
+
+ if( pSrc->nSrc+nExtra>=SQLITE_MAX_SRCLIST ){
+ sqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d",
+ SQLITE_MAX_SRCLIST);
+ return 0;
+ }
+ if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST;
pNew = sqlite3DbRealloc(db, pSrc,
sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) );
if( pNew==0 ){
assert( db->mallocFailed );
- return pSrc;
+ return 0;
}
pSrc = pNew;
- nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
- pSrc->nAlloc = nGot;
+ pSrc->nAlloc = nAlloc;
}
/* Move existing slots that come after the newly inserted slots
@@ -109811,7 +110512,8 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
** Append a new table name to the given SrcList. Create a new SrcList if
** need be. A new entry is created in the SrcList even if pTable is NULL.
**
-** A SrcList is returned, or NULL if there is an OOM error. The returned
+** A SrcList is returned, or NULL if there is an OOM error or if the
+** SrcList grows to large. The returned
** SrcList might be the same as the SrcList that was input or it might be
** a new one. If an OOM error does occurs, then the prior value of pList
** that is input to this routine is automatically freed.
@@ -109842,27 +110544,32 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
** before being added to the SrcList.
*/
SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
- sqlite3 *db, /* Connection to notify of malloc failures */
+ Parse *pParse, /* Parsing context, in which errors are reported */
SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */
Token *pTable, /* Table to append */
Token *pDatabase /* Database of the table */
){
struct SrcList_item *pItem;
+ sqlite3 *db;
assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */
- assert( db!=0 );
+ assert( pParse!=0 );
+ assert( pParse->db!=0 );
+ db = pParse->db;
if( pList==0 ){
- pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) );
+ pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) );
if( pList==0 ) return 0;
pList->nAlloc = 1;
pList->nSrc = 1;
memset(&pList->a[0], 0, sizeof(pList->a[0]));
pList->a[0].iCursor = -1;
}else{
- pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc);
- }
- if( db->mallocFailed ){
- sqlite3SrcListDelete(db, pList);
- return 0;
+ SrcList *pNew = sqlite3SrcListEnlarge(pParse, pList, 1, pList->nSrc);
+ if( pNew==0 ){
+ sqlite3SrcListDelete(db, pList);
+ return 0;
+ }else{
+ pList = pNew;
+ }
}
pItem = &pList->a[pList->nSrc-1];
if( pDatabase && pDatabase->z==0 ){
@@ -109951,7 +110658,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
);
goto append_from_error;
}
- p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
+ p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase);
if( p==0 ){
goto append_from_error;
}
@@ -110340,13 +111047,15 @@ static int collationMatch(const char *zColl, Index *pIndex){
*/
#ifndef SQLITE_OMIT_REINDEX
static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){
- Index *pIndex; /* An index associated with pTab */
+ if( !IsVirtual(pTab) ){
+ Index *pIndex; /* An index associated with pTab */
- for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
- if( zColl==0 || collationMatch(zColl, pIndex) ){
- int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3RefillIndex(pParse, pIndex, -1);
+ for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
+ if( zColl==0 || collationMatch(zColl, pIndex) ){
+ int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ sqlite3RefillIndex(pParse, pIndex, -1);
+ }
}
}
}
@@ -110845,7 +111554,7 @@ static int matchQuality(
** Search a FuncDefHash for a function with the given name. Return
** a pointer to the matching FuncDef if found, or 0 if there is no match.
*/
-static FuncDef *functionSearch(
+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(
int h, /* Hash of the name */
const char *zFunc /* Name of function */
){
@@ -110857,21 +111566,6 @@ static FuncDef *functionSearch(
}
return 0;
}
-#ifdef SQLITE_ENABLE_NORMALIZE
-SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(
- int h, /* Hash of the name */
- const char *zFunc, /* Name of function */
- int nFunc /* Length of the name */
-){
- FuncDef *p;
- for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
- if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){
- return p;
- }
- }
- return 0;
-}
-#endif /* SQLITE_ENABLE_NORMALIZE */
/*
** Insert a new FuncDef into a FuncDefHash hash table.
@@ -110887,7 +111581,7 @@ SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
int nName = sqlite3Strlen30(zName);
int h = SQLITE_FUNC_HASH(zName[0], nName);
assert( zName[0]>='a' && zName[0]<='z' );
- pOther = functionSearch(h, zName);
+ pOther = sqlite3FunctionSearch(h, zName);
if( pOther ){
assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
aDef[i].pNext = pOther->pNext;
@@ -110965,7 +111659,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
bestScore = 0;
h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
- p = functionSearch(h, zName);
+ p = sqlite3FunctionSearch(h, zName);
while( p ){
int score = matchQuality(p, nArg, enc);
if( score>bestScore ){
@@ -111185,7 +111879,7 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
sqlite3 *db = pParse->db;
int iDb = sqlite3SchemaToIndex(db, pView->pSchema);
pWhere = sqlite3ExprDup(db, pWhere, 0);
- pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
+ pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( pFrom ){
assert( pFrom->nSrc==1 );
pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
@@ -111585,7 +112279,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
/* If this DELETE cannot use the ONEPASS strategy, this is the
** end of the WHERE loop */
if( eOnePass!=ONEPASS_OFF ){
- addrBypass = sqlite3VdbeMakeLabel(v);
+ addrBypass = sqlite3VdbeMakeLabel(pParse);
}else{
sqlite3WhereEnd(pWInfo);
}
@@ -111774,7 +112468,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
/* Seek cursor iCur to the row to delete. If this row no longer exists
** (this can happen if a trigger program has already deleted it), do
** not attempt to delete it or fire any DELETE triggers. */
- iLabel = sqlite3VdbeMakeLabel(v);
+ iLabel = sqlite3VdbeMakeLabel(pParse);
opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
if( eMode==ONEPASS_OFF ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
@@ -111980,7 +112674,7 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
if( piPartIdxLabel ){
if( pIdx->pPartIdxWhere ){
- *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
+ *piPartIdxLabel = sqlite3VdbeMakeLabel(pParse);
pParse->iSelfTab = iDataCur + 1;
sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
SQLITE_JUMPIFNULL);
@@ -112236,6 +112930,7 @@ static void instrFunc(
int typeHaystack, typeNeedle;
int N = 1;
int isText;
+ unsigned char firstChar;
UNUSED_PARAMETER(argc);
typeHaystack = sqlite3_value_type(argv[0]);
@@ -112254,7 +112949,10 @@ static void instrFunc(
isText = 1;
}
if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
- while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
+ firstChar = zNeedle[0];
+ while( nNeedle<=nHaystack
+ && (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0)
+ ){
N++;
do{
nHaystack--;
@@ -112545,11 +113243,11 @@ static void randomBlob(
int argc,
sqlite3_value **argv
){
- int n;
+ sqlite3_int64 n;
unsigned char *p;
assert( argc==1 );
UNUSED_PARAMETER(argc);
- n = sqlite3_value_int(argv[0]);
+ n = sqlite3_value_int64(argv[0]);
if( n<1 ){
n = 1;
}
@@ -114385,7 +115083,7 @@ static void fkLookupParent(
int i; /* Iterator variable */
Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */
int iCur = pParse->nTab - 1; /* Cursor number to use */
- int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */
+ int iOk = sqlite3VdbeMakeLabel(pParse); /* jump here if parent key found */
sqlite3VdbeVerifyAbortable(v,
(!pFKey->isDeferred
@@ -114658,8 +115356,11 @@ static void fkScanChildren(
** NOT( $current_a==a AND $current_b==b AND ... )
**
** The first form is used for rowid tables. The second form is used
- ** for WITHOUT ROWID tables. In the second form, the primary key is
- ** (a,b,...)
+ ** for WITHOUT ROWID tables. In the second form, the *parent* key is
+ ** (a,b,...). Either the parent or primary key could be used to
+ ** uniquely identify the current row, but the parent key is more convenient
+ ** as the required values have already been loaded into registers
+ ** by the caller.
*/
if( pTab==pFKey->pFrom && nIncr>0 ){
Expr *pNe; /* Expression (pLeft != pRight) */
@@ -114671,14 +115372,13 @@ static void fkScanChildren(
pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
}else{
Expr *pEq, *pAll = 0;
- Index *pPk = sqlite3PrimaryKeyIndex(pTab);
assert( pIdx!=0 );
- for(i=0; i<pPk->nKeyCol; i++){
+ for(i=0; i<pIdx->nKeyCol; i++){
i16 iCol = pIdx->aiColumn[i];
assert( iCol>=0 );
pLeft = exprTableRegister(pParse, pTab, regData, iCol);
- pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
- pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
+ pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
+ pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
pAll = sqlite3ExprAnd(db, pAll, pEq);
}
pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
@@ -114783,7 +115483,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break;
}
if( !p ) return;
- iSkip = sqlite3VdbeMakeLabel(v);
+ iSkip = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v);
}
@@ -115068,7 +115768,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
/* Create a SrcList structure containing the child table. We need the
** child table as a SrcList for sqlite3WhereBegin() */
- pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+ pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( pSrc ){
struct SrcList_item *pItem = pSrc->a;
pItem->pTab = pFKey->pFrom;
@@ -115345,7 +116045,7 @@ static Trigger *fkActionTrigger(
}
pSelect = sqlite3SelectNew(pParse,
sqlite3ExprListAppend(pParse, 0, pRaise),
- sqlite3SrcListAppend(db, 0, &tFrom, 0),
+ sqlite3SrcListAppend(pParse, 0, &tFrom, 0),
pWhere,
0, 0, 0, 0, 0
);
@@ -115807,6 +116507,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
aOp[7].p2 = memId+2;
aOp[7].p1 = memId;
aOp[10].p2 = memId;
+ if( pParse->nTab==0 ) pParse->nTab = 1;
}
}
@@ -116313,6 +117014,11 @@ SQLITE_PRIVATE void sqlite3Insert(
}
#ifndef SQLITE_OMIT_UPSERT
if( pUpsert ){
+ if( IsVirtual(pTab) ){
+ sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"",
+ pTab->zName);
+ goto insert_cleanup;
+ }
pTabList->a[0].iCursor = iDataCur;
pUpsert->pUpsertSrc = pTabList;
pUpsert->regData = regData;
@@ -116353,7 +117059,7 @@ SQLITE_PRIVATE void sqlite3Insert(
/* Run the BEFORE and INSTEAD OF triggers, if there are any
*/
- endOfLoop = sqlite3VdbeMakeLabel(v);
+ endOfLoop = sqlite3VdbeMakeLabel(pParse);
if( tmask & TRIGGER_BEFORE ){
int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1);
@@ -116435,16 +117141,12 @@ SQLITE_PRIVATE void sqlite3Insert(
}else if( pSelect ){
sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
}else{
- VdbeOp *pOp;
- sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
- pOp = sqlite3VdbeGetOp(v, -1);
- assert( pOp!=0 );
- if( pOp->opcode==OP_Null && !IsVirtual(pTab) ){
+ Expr *pIpk = pList->a[ipkColumn].pExpr;
+ if( pIpk->op==TK_NULL && !IsVirtual(pTab) ){
+ sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
appendFlag = 1;
- pOp->opcode = OP_NewRowid;
- pOp->p1 = iDataCur;
- pOp->p2 = regRowid;
- pOp->p3 = regAutoinc;
+ }else{
+ sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
}
}
/* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
@@ -116839,7 +117541,20 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|| onError==OE_Ignore || onError==OE_Replace );
+ addr1 = 0;
switch( onError ){
+ case OE_Replace: {
+ assert( onError==OE_Replace );
+ addr1 = sqlite3VdbeMakeLabel(pParse);
+ sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
+ VdbeCoverage(v);
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
+ sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
+ VdbeCoverage(v);
+ onError = OE_Abort;
+ /* Fall through into the OE_Abort case to generate code that runs
+ ** if both the input and the default value are NULL */
+ }
case OE_Abort:
sqlite3MayAbort(pParse);
/* Fall through */
@@ -116852,21 +117567,15 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
VdbeCoverage(v);
+ if( addr1 ) sqlite3VdbeResolveLabel(v, addr1);
break;
}
- case OE_Ignore: {
+ default: {
+ assert( onError==OE_Ignore );
sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
VdbeCoverage(v);
break;
}
- default: {
- assert( onError==OE_Replace );
- addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
- VdbeCoverage(v);
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
- sqlite3VdbeJumpHere(v, addr1);
- break;
- }
}
}
@@ -116887,7 +117596,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
** updated so there is no point it verifying the check constraint */
continue;
}
- allOk = sqlite3VdbeMakeLabel(v);
+ allOk = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeVerifyAbortable(v, onError);
sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
if( onError==OE_Ignore ){
@@ -116954,7 +117663,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
** exist in the table.
*/
if( pkChng && pPk==0 ){
- int addrRowidOk = sqlite3VdbeMakeLabel(v);
+ int addrRowidOk = sqlite3VdbeMakeLabel(pParse);
/* Figure out what action to take in case of a rowid collision */
onError = pTab->keyConf;
@@ -117104,7 +117813,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
VdbeComment((v, "Skip upsert subroutine"));
sqlite3VdbeJumpHere(v, upsertJump);
}else{
- addrUniqueOk = sqlite3VdbeMakeLabel(v);
+ addrUniqueOk = sqlite3VdbeMakeLabel(pParse);
}
if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
sqlite3TableAffinity(v, pTab, regNewData+1);
@@ -117187,7 +117896,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
** (3) There are no secondary indexes on the table
** (4) No delete triggers need to be fired if there is a conflict
** (5) No FK constraint counters need to be updated if a conflict occurs.
- */
+ **
+ ** This is not possible for ENABLE_PREUPDATE_HOOK builds, as the row
+ ** must be explicitly deleted in order to ensure any pre-update hook
+ ** is invoked. */
+#ifndef SQLITE_ENABLE_PREUPDATE_HOOK
if( (ix==0 && pIdx->pNext==0) /* Condition 3 */
&& pPk==pIdx /* Condition 2 */
&& onError==OE_Replace /* Condition 1 */
@@ -117199,6 +117912,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
sqlite3VdbeResolveLabel(v, addrUniqueOk);
continue;
}
+#endif /* ifndef SQLITE_ENABLE_PREUPDATE_HOOK */
/* Check to see if the new index entry will be unique */
sqlite3VdbeVerifyAbortable(v, onError);
@@ -117312,7 +118026,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
/* If the IPK constraint is a REPLACE, run it last */
if( ipkTop ){
- sqlite3VdbeGoto(v, ipkTop+1);
+ sqlite3VdbeGoto(v, ipkTop);
VdbeComment((v, "Do IPK REPLACE"));
sqlite3VdbeJumpHere(v, ipkBottom);
}
@@ -117682,7 +118396,8 @@ static int xferOptimization(
if( pSrc==0 ){
return 0; /* FROM clause does not contain a real table */
}
- if( pSrc==pDest ){
+ if( pSrc->tnum==pDest->tnum && pSrc->pSchema==pDest->pSchema ){
+ testcase( pSrc!=pDest ); /* Possible due to bad sqlite_master.rootpage */
return 0; /* tab1 and tab2 may not be the same table */
}
if( HasRowid(pDest)!=HasRowid(pSrc) ){
@@ -117958,7 +118673,7 @@ SQLITE_API int sqlite3_exec(
sqlite3_mutex_enter(db->mutex);
sqlite3Error(db, SQLITE_OK);
while( rc==SQLITE_OK && zSql[0] ){
- int nCol;
+ int nCol = 0;
char **azVals = 0;
pStmt = 0;
@@ -117972,9 +118687,7 @@ SQLITE_API int sqlite3_exec(
zSql = zLeftover;
continue;
}
-
callbackIsInit = 0;
- nCol = sqlite3_column_count(pStmt);
while( 1 ){
int i;
@@ -117985,6 +118698,7 @@ SQLITE_API int sqlite3_exec(
(SQLITE_DONE==rc && !callbackIsInit
&& db->flags&SQLITE_NullCallback)) ){
if( !callbackIsInit ){
+ nCol = sqlite3_column_count(pStmt);
azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*));
if( azCols==0 ){
goto exec_out;
@@ -119339,7 +120053,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
if( onoff ){
db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
}else{
- db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
+ db->flags &= ~(u64)(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
}
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
@@ -119598,8 +120312,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
#define PragTyp_HEXKEY 41
#define PragTyp_KEY 42
#define PragTyp_LOCK_STATUS 43
-#define PragTyp_PARSER_TRACE 44
-#define PragTyp_STATS 45
+#define PragTyp_STATS 44
/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
@@ -120010,12 +120723,14 @@ static const PragmaName aPragmaName[] = {
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
-#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE)
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if defined(SQLITE_DEBUG)
{/* zName: */ "parser_trace",
- /* ePragTyp: */ PragTyp_PARSER_TRACE,
- /* ePragFlg: */ 0,
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ /* iArg: */ SQLITE_ParserTrace },
+#endif
#endif
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
{/* zName: */ "pragma_list",
@@ -121006,7 +121721,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( sqlite3GetBoolean(zRight, size!=0) ){
db->flags |= SQLITE_CacheSpill;
}else{
- db->flags &= ~SQLITE_CacheSpill;
+ db->flags &= ~(u64)SQLITE_CacheSpill;
}
setAllPagerFlags(db);
}
@@ -121566,7 +122281,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
assert( x==0 );
}
- addrOk = sqlite3VdbeMakeLabel(v);
+ addrOk = sqlite3VdbeMakeLabel(pParse);
/* Generate code to read the child key values into registers
** regRow..regRow+n. If any of the child key values are NULL, this
@@ -121611,19 +122326,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
-#ifndef NDEBUG
- case PragTyp_PARSER_TRACE: {
- if( zRight ){
- if( sqlite3GetBoolean(zRight, 0) ){
- sqlite3ParserTrace(stdout, "parser: ");
- }else{
- sqlite3ParserTrace(0, 0);
- }
- }
- }
- break;
-#endif
-
/* Reinstall the LIKE and GLOB functions. The variant of LIKE
** used will be case sensitive or not depending on the RHS.
*/
@@ -121786,8 +122488,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
if( db->mallocFailed==0 ){
- int addrCkFault = sqlite3VdbeMakeLabel(v);
- int addrCkOk = sqlite3VdbeMakeLabel(v);
+ int addrCkFault = sqlite3VdbeMakeLabel(pParse);
+ int addrCkOk = sqlite3VdbeMakeLabel(pParse);
char *zErr;
int k;
pParse->iSelfTab = iDataCur + 1;
@@ -121810,7 +122512,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Validate index entries for the current row */
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int jmp2, jmp3, jmp4, jmp5;
- int ckUniq = sqlite3VdbeMakeLabel(v);
+ int ckUniq = sqlite3VdbeMakeLabel(pParse);
if( pPk==pIdx ) continue;
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
pPrior, r1);
@@ -121831,7 +122533,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** current key. The entry is unique if (1) any column is NULL
** or (2) the next entry has a different key */
if( IsUniqueIndex(pIdx) ){
- int uniqOk = sqlite3VdbeMakeLabel(v);
+ int uniqOk = sqlite3VdbeMakeLabel(pParse);
int jmp6;
int kk;
for(kk=0; kk<pIdx->nKeyCol; kk++){
@@ -122746,6 +123448,19 @@ static void corruptSchema(
}
/*
+** Check to see if any sibling index (another index on the same table)
+** of pIndex has the same root page number, and if it does, return true.
+** This would indicate a corrupt schema.
+*/
+SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index *pIndex){
+ Index *p;
+ for(p=pIndex->pTable->pIndex; p; p=p->pNext){
+ if( p->tnum==pIndex->tnum && p!=pIndex ) return 1;
+ }
+ return 0;
+}
+
+/*
** This is the callback routine for the code that initializes the
** database. See sqlite3Init() below for additional information.
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
@@ -122766,6 +123481,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
UNUSED_PARAMETER2(NotUsed, argc);
assert( sqlite3_mutex_held(db->mutex) );
DbClearProperty(db, iDb, DB_Empty);
+ pData->nInitRow++;
if( db->mallocFailed ){
corruptSchema(pData, argv[0], 0);
return 1;
@@ -122819,15 +123535,12 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
*/
Index *pIndex;
pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
- if( pIndex==0 ){
- /* This can occur if there exists an index on a TEMP table which
- ** has the same name as another index on a permanent index. Since
- ** the permanent table is hidden by the TEMP table, we can also
- ** safely ignore the index on the permanent table.
- */
- /* Do Nothing */;
- }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){
- corruptSchema(pData, argv[0], "invalid rootpage");
+ if( pIndex==0
+ || sqlite3GetInt32(argv[1],&pIndex->tnum)==0
+ || pIndex->tnum<2
+ || sqlite3IndexHasDuplicateRootPage(pIndex)
+ ){
+ corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index");
}
}
return 0;
@@ -122877,6 +123590,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
initData.rc = SQLITE_OK;
initData.pzErrMsg = pzErrMsg;
initData.mInitFlags = mFlags;
+ initData.nInitRow = 0;
sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
if( initData.rc ){
rc = initData.rc;
@@ -122994,7 +123708,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
** indices that the user might have created.
*/
if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){
- db->flags &= ~SQLITE_LegacyFileFmt;
+ db->flags &= ~(u64)SQLITE_LegacyFileFmt;
}
/* Read the schema information out of the schema tables
@@ -123246,6 +123960,7 @@ static int sqlite3Prepare(
sParse.disableLookaside++;
db->lookaside.bDisable++;
}
+ sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0;
/* Check to verify that it is possible to get a read lock on all
** database schemas. The inability to get a read lock indicates that
@@ -123410,293 +124125,6 @@ static int sqlite3LockAndPrepare(
return rc;
}
-#ifdef SQLITE_ENABLE_NORMALIZE
-/*
-** Checks if the specified token is a table, column, or function name,
-** based on the databases associated with the statement being prepared.
-** If the function fails, zero is returned and pRc is filled with the
-** error code.
-*/
-static int shouldTreatAsIdentifier(
- sqlite3 *db, /* Database handle. */
- const char *zToken, /* Pointer to start of token to be checked */
- int nToken, /* Length of token to be checked */
- int *pRc /* Pointer to error code upon failure */
-){
- int bFound = 0; /* Non-zero if token is an identifier name. */
- int i, j; /* Database and column loop indexes. */
- Schema *pSchema; /* Schema for current database. */
- Hash *pHash; /* Hash table of tables for current database. */
- HashElem *e; /* Hash element for hash table iteration. */
- Table *pTab; /* Database table for columns being checked. */
-
- if( sqlite3IsRowidN(zToken, nToken) ){
- return 1;
- }
- if( nToken>0 ){
- int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken);
- if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1;
- }
- assert( db!=0 );
- sqlite3_mutex_enter(db->mutex);
- sqlite3BtreeEnterAll(db);
- for(i=0; i<db->nDb; i++){
- pHash = &db->aFunc;
- if( sqlite3HashFindN(pHash, zToken, nToken) ){
- bFound = 1;
- break;
- }
- pSchema = db->aDb[i].pSchema;
- if( pSchema==0 ) continue;
- pHash = &pSchema->tblHash;
- if( sqlite3HashFindN(pHash, zToken, nToken) ){
- bFound = 1;
- break;
- }
- for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){
- pTab = sqliteHashData(e);
- if( pTab==0 ) continue;
- pHash = pTab->pColHash;
- if( pHash==0 ){
- pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash));
- if( pHash ){
- sqlite3HashInit(pHash);
- for(j=0; j<pTab->nCol; j++){
- Column *pCol = &pTab->aCol[j];
- sqlite3HashInsert(pHash, pCol->zName, pCol);
- }
- }else{
- *pRc = SQLITE_NOMEM_BKPT;
- bFound = 0;
- goto done;
- }
- }
- if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){
- bFound = 1;
- goto done;
- }
- }
- }
-done:
- sqlite3BtreeLeaveAll(db);
- sqlite3_mutex_leave(db->mutex);
- return bFound;
-}
-
-/*
-** Attempt to estimate the final output buffer size needed for the fully
-** normalized version of the specified SQL string. This should take into
-** account any potential expansion that could occur (e.g. via IN clauses
-** being expanded, etc). This size returned is the total number of bytes
-** including the NUL terminator.
-*/
-static int estimateNormalizedSize(
- const char *zSql, /* The original SQL string */
- int nSql, /* Length of original SQL string */
- u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
-){
- int nOut = nSql + 4;
- const char *z = zSql;
- while( nOut<nSql*5 ){
- while( z[0]!=0 && z[0]!='I' && z[0]!='i' ){ z++; }
- if( z[0]==0 ) break;
- z++;
- if( z[0]!='N' && z[0]!='n' ) break;
- z++;
- while( sqlite3Isspace(z[0]) ){ z++; }
- if( z[0]!='(' ) break;
- z++;
- nOut += 5; /* ?,?,? */
- }
- return nOut;
-}
-
-/*
-** Copy the current token into the output buffer while dealing with quoted
-** identifiers. By default, all letters will be converted into lowercase.
-** If the bUpper flag is set, uppercase will be used. The piOut argument
-** will be used to update the target index into the output string.
-*/
-static void copyNormalizedToken(
- const char *zSql, /* The original SQL string */
- int iIn, /* Current index into the original SQL string */
- int nToken, /* Number of bytes in the current token */
- int tokenFlags, /* Flags returned by the tokenizer */
- char *zOut, /* The output string */
- int *piOut /* Pointer to target index into the output string */
-){
- int bQuoted = tokenFlags & SQLITE_TOKEN_QUOTED;
- int bKeyword = tokenFlags & SQLITE_TOKEN_KEYWORD;
- int j = *piOut, k = 0;
- for(; k<nToken; k++){
- if( bQuoted ){
- if( k==0 && iIn>0 ){
- zOut[j++] = '"';
- continue;
- }else if( k==nToken-1 ){
- zOut[j++] = '"';
- continue;
- }
- }
- if( bKeyword ){
- zOut[j++] = sqlite3Toupper(zSql[iIn+k]);
- }else{
- zOut[j++] = sqlite3Tolower(zSql[iIn+k]);
- }
- }
- *piOut = j;
-}
-
-/*
-** Perform normalization of the SQL contained in the prepared statement and
-** store the result in the zNormSql field. The schema for the associated
-** databases are consulted while performing the normalization in order to
-** determine if a token appears to be an identifier. All identifiers are
-** left intact in the normalized SQL and all literals are replaced with a
-** single '?'.
-*/
-SQLITE_PRIVATE void sqlite3Normalize(
- Vdbe *pVdbe, /* VM being reprepared */
- const char *zSql, /* The original SQL string */
- int nSql, /* Size of the input string in bytes */
- u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
-){
- sqlite3 *db; /* Database handle. */
- char *z; /* The output string */
- int nZ; /* Size of the output string in bytes */
- int i; /* Next character to read from zSql[] */
- int j; /* Next character to fill in on z[] */
- int tokenType = 0; /* Type of the next token */
- int prevTokenType = 0; /* Type of the previous token, except spaces */
- int n; /* Size of the next token */
- int nParen = 0; /* Nesting level of parenthesis */
- Hash inHash; /* Table of parenthesis levels to output index. */
-
- db = sqlite3VdbeDb(pVdbe);
- assert( db!=0 );
- assert( pVdbe->zNormSql==0 );
- if( zSql==0 ) return;
- nZ = estimateNormalizedSize(zSql, nSql, prepFlags);
- z = sqlite3DbMallocRawNN(db, nZ);
- if( z==0 ) return;
- sqlite3HashInit(&inHash);
- for(i=j=0; i<nSql && zSql[i]; i+=n){
- int flags = 0;
- if( tokenType!=TK_SPACE ) prevTokenType = tokenType;
- n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags);
- switch( tokenType ){
- case TK_SPACE: {
- break;
- }
- case TK_ILLEGAL: {
- sqlite3DbFree(db, z);
- sqlite3HashClear(&inHash);
- return;
- }
- case TK_STRING:
- case TK_INTEGER:
- case TK_FLOAT:
- case TK_VARIABLE:
- case TK_BLOB: {
- z[j++] = '?';
- break;
- }
- case TK_LP:
- case TK_RP: {
- if( tokenType==TK_LP ){
- nParen++;
- if( prevTokenType==TK_IN ){
- assert( nParen<nSql );
- sqlite3HashInsert(&inHash, zSql+nParen, SQLITE_INT_TO_PTR(j));
- }
- }else{
- int jj;
- assert( nParen<nSql );
- jj = SQLITE_PTR_TO_INT(sqlite3HashFind(&inHash, zSql+nParen));
- if( jj>0 ){
- sqlite3HashInsert(&inHash, zSql+nParen, 0);
- assert( jj+6<nZ );
- memcpy(z+jj+1, "?,?,?", 5);
- j = jj+6;
- assert( nZ-1-j>=0 );
- assert( nZ-1-j<nZ );
- memset(z+j, 0, nZ-1-j);
- }
- nParen--;
- }
- assert( nParen>=0 );
- /* Fall through */
- }
- case TK_MINUS:
- case TK_SEMI:
- case TK_PLUS:
- case TK_STAR:
- case TK_SLASH:
- case TK_REM:
- case TK_EQ:
- case TK_LE:
- case TK_NE:
- case TK_LSHIFT:
- case TK_LT:
- case TK_RSHIFT:
- case TK_GT:
- case TK_GE:
- case TK_BITOR:
- case TK_CONCAT:
- case TK_COMMA:
- case TK_BITAND:
- case TK_BITNOT:
- case TK_DOT:
- case TK_IN:
- case TK_IS:
- case TK_NOT:
- case TK_NULL:
- case TK_ID: {
- if( tokenType==TK_NULL ){
- if( prevTokenType==TK_IS || prevTokenType==TK_NOT ){
- /* NULL is a keyword in this case, not a literal value */
- }else{
- /* Here the NULL is a literal value */
- z[j++] = '?';
- break;
- }
- }
- if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){
- z[j++] = ' ';
- }
- if( tokenType==TK_ID ){
- int i2 = i, n2 = n, rc = SQLITE_OK;
- if( nParen>0 ){
- assert( nParen<nSql );
- sqlite3HashInsert(&inHash, zSql+nParen, 0);
- }
- if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; }
- if( shouldTreatAsIdentifier(db, zSql+i2, n2, &rc)==0 ){
- if( rc!=SQLITE_OK ){
- sqlite3DbFree(db, z);
- sqlite3HashClear(&inHash);
- return;
- }
- if( sqlite3_keyword_check(zSql+i2, n2)==0 ){
- z[j++] = '?';
- break;
- }
- }
- }
- copyNormalizedToken(zSql, i, n, flags, z, &j);
- break;
- }
- }
- }
- assert( j<nZ && "one" );
- while( j>0 && z[j-1]==' ' ){ j--; }
- if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; }
- z[j] = 0;
- assert( j<nZ && "two" );
- pVdbe->zNormSql = z;
- sqlite3HashClear(&inHash);
-}
-#endif /* SQLITE_ENABLE_NORMALIZE */
/*
** Rerun the compilation of a statement after a schema change.
@@ -124538,7 +124966,7 @@ static void pushOntoSorter(
}
assert( pSelect->iOffset==0 || pSelect->iLimit!=0 );
iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
- pSort->labelDone = sqlite3VdbeMakeLabel(v);
+ pSort->labelDone = sqlite3VdbeMakeLabel(pParse);
sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
if( bSeq ){
@@ -124577,7 +125005,7 @@ static void pushOntoSorter(
pKI->nAllField-pKI->nKeyField-1);
addrJmp = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
- pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
+ pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse);
pSort->regReturn = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
@@ -125324,7 +125752,7 @@ static void generateSortTail(
){
Vdbe *v = pParse->pVdbe; /* The prepared statement */
int addrBreak = pSort->labelDone; /* Jump here to exit loop */
- int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */
+ int addrContinue = sqlite3VdbeMakeLabel(pParse);/* Jump here for next cycle */
int addr; /* Top of output loop. Jump for Next. */
int addrOnce = 0;
int iTab;
@@ -125364,7 +125792,12 @@ static void generateSortTail(
regRow = pDest->iSdst;
}else{
regRowid = sqlite3GetTempReg(pParse);
- regRow = sqlite3GetTempRange(pParse, nColumn);
+ if( eDest==SRT_EphemTab || eDest==SRT_Table ){
+ regRow = sqlite3GetTempReg(pParse);
+ nColumn = 0;
+ }else{
+ regRow = sqlite3GetTempRange(pParse, nColumn);
+ }
}
nKey = pOrderBy->nExpr - pSort->nOBSat;
if( pSort->sortFlags & SORTFLAG_UseSorter ){
@@ -125444,6 +125877,7 @@ static void generateSortTail(
switch( eDest ){
case SRT_Table:
case SRT_EphemTab: {
+ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq, regRow);
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -125984,15 +126418,15 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
Table *pTab;
sqlite3 *db = pParse->db;
- int savedFlags;
+ u64 savedFlags;
savedFlags = db->flags;
- db->flags &= ~SQLITE_FullColNames;
+ db->flags &= ~(u64)SQLITE_FullColNames;
db->flags |= SQLITE_ShortColNames;
sqlite3SelectPrep(pParse, pSelect, 0);
+ db->flags = savedFlags;
if( pParse->nErr ) return 0;
while( pSelect->pPrior ) pSelect = pSelect->pPrior;
- db->flags = savedFlags;
pTab = sqlite3DbMallocZero(db, sizeof(Table) );
if( pTab==0 ){
return 0;
@@ -126236,7 +126670,7 @@ static void generateWithRecursiveQuery(
if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
/* Process the LIMIT and OFFSET clauses, if they exist */
- addrBreak = sqlite3VdbeMakeLabel(v);
+ addrBreak = sqlite3VdbeMakeLabel(pParse);
p->nSelectRow = 320; /* 4 billion rows */
computeLimitRegisters(pParse, p, addrBreak);
pLimit = p->pLimit;
@@ -126306,7 +126740,7 @@ static void generateWithRecursiveQuery(
sqlite3VdbeAddOp1(v, OP_Delete, iQueue);
/* Output the single row in Current */
- addrCont = sqlite3VdbeMakeLabel(v);
+ addrCont = sqlite3VdbeMakeLabel(pParse);
codeOffset(v, regOffset, addrCont);
selectInnerLoop(pParse, p, iCurrent,
0, 0, pDest, addrCont, addrBreak);
@@ -126614,8 +127048,8 @@ static int multiSelect(
if( dest.eDest!=priorOp ){
int iCont, iBreak, iStart;
assert( p->pEList );
- iBreak = sqlite3VdbeMakeLabel(v);
- iCont = sqlite3VdbeMakeLabel(v);
+ iBreak = sqlite3VdbeMakeLabel(pParse);
+ iCont = sqlite3VdbeMakeLabel(pParse);
computeLimitRegisters(pParse, p, iBreak);
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
iStart = sqlite3VdbeCurrentAddr(v);
@@ -126683,8 +127117,8 @@ static int multiSelect(
** tables.
*/
assert( p->pEList );
- iBreak = sqlite3VdbeMakeLabel(v);
- iCont = sqlite3VdbeMakeLabel(v);
+ iBreak = sqlite3VdbeMakeLabel(pParse);
+ iCont = sqlite3VdbeMakeLabel(pParse);
computeLimitRegisters(pParse, p, iBreak);
sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
r1 = sqlite3GetTempReg(pParse);
@@ -126814,7 +127248,7 @@ static int generateOutputSubroutine(
int addr;
addr = sqlite3VdbeCurrentAddr(v);
- iContinue = sqlite3VdbeMakeLabel(v);
+ iContinue = sqlite3VdbeMakeLabel(pParse);
/* Suppress duplicates for UNION, EXCEPT, and INTERSECT
*/
@@ -127051,8 +127485,8 @@ static int multiSelectOrderBy(
db = pParse->db;
v = pParse->pVdbe;
assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */
- labelEnd = sqlite3VdbeMakeLabel(v);
- labelCmpr = sqlite3VdbeMakeLabel(v);
+ labelEnd = sqlite3VdbeMakeLabel(pParse);
+ labelCmpr = sqlite3VdbeMakeLabel(pParse);
/* Patch up the ORDER BY clause
@@ -127368,6 +127802,7 @@ static Expr *substExpr(
ifNullRow.iTable = pSubst->iNewTable;
pCopy = &ifNullRow;
}
+ testcase( ExprHasProperty(pCopy, EP_Subquery) );
pNew = sqlite3ExprDup(db, pCopy, 0);
if( pNew && pSubst->isLeftJoin ){
ExprSetProperty(pNew, EP_CanBeNull);
@@ -127860,11 +128295,9 @@ static int flattenSubquery(
jointype = pSubitem->fg.jointype;
}else{
assert( pParent!=p ); /* 2nd and subsequent times through the loop */
- pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
- if( pSrc==0 ){
- assert( db->mallocFailed );
- break;
- }
+ pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
+ if( pSrc==0 ) break;
+ pParent->pSrc = pSrc;
}
/* The subquery uses a single slot of the FROM clause of the outer
@@ -127883,10 +128316,9 @@ static int flattenSubquery(
** for the two elements in the FROM clause of the subquery.
*/
if( nSubSrc>1 ){
- pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
- if( db->mallocFailed ){
- break;
- }
+ pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1);
+ if( pSrc==0 ) break;
+ pParent->pSrc = pSrc;
}
/* Transfer the FROM clause terms from the subquery into the
@@ -127932,7 +128364,8 @@ static int flattenSubquery(
pParent->pOrderBy = pOrderBy;
pSub->pOrderBy = 0;
}
- pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
+ pWhere = pSub->pWhere;
+ pSub->pWhere = 0;
if( isLeftJoin>0 ){
setJoinExpr(pWhere, iNewParent);
}
@@ -129235,7 +129668,7 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
regAgg = 0;
}
if( pF->iDistinct>=0 ){
- addrNext = sqlite3VdbeMakeLabel(v);
+ addrNext = sqlite3VdbeMakeLabel(pParse);
testcase( nArg==0 ); /* Error condition */
testcase( nArg>1 ); /* Also an error */
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
@@ -129371,14 +129804,19 @@ static struct SrcList_item *isSelfJoinView(
){
struct SrcList_item *pItem;
for(pItem = pTabList->a; pItem<pThis; pItem++){
+ Select *pS1;
if( pItem->pSelect==0 ) continue;
if( pItem->fg.viaCoroutine ) continue;
if( pItem->zName==0 ) continue;
if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
- if( sqlite3ExprCompare(0,
- pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1)
- ){
+ pS1 = pItem->pSelect;
+ if( pThis->pSelect->selId!=pS1->selId ){
+ /* The query flattener left two different CTE tables with identical
+ ** names in the same FROM clause. */
+ continue;
+ }
+ if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) ){
/* The view was modified by some other optimization such as
** pushDownWhereTerms() */
continue;
@@ -129640,6 +130078,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
if( flattenSubquery(pParse, p, i, isAgg) ){
+ if( pParse->nErr ) goto select_end;
/* This subquery can be absorbed into its parent. */
i = -1;
}
@@ -129735,22 +130174,12 @@ SQLITE_PRIVATE int sqlite3Select(
pSub = pItem->pSelect;
if( pSub==0 ) continue;
- /* Sometimes the code for a subquery will be generated more than
- ** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
- ** for example. In that case, do not regenerate the code to manifest
- ** a view or the co-routine to implement a view. The first instance
- ** is sufficient, though the subroutine to manifest the view does need
- ** to be invoked again. */
- if( pItem->addrFillSub ){
- if( pItem->fg.viaCoroutine==0 ){
- /* The subroutine that manifests the view might be a one-time routine,
- ** or it might need to be rerun on each iteration because it
- ** encodes a correlated subquery. */
- testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once );
- sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
- }
- continue;
- }
+ /* The code for a subquery should only be generated once, though it is
+ ** technically harmless for it to be generated multiple times. The
+ ** following assert() will detect if something changes to cause
+ ** the same subquery to be coded multiple times, as a signal to the
+ ** developers to try to optimize the situation. */
+ assert( pItem->addrFillSub==0 );
/* Increment Parse.nHeight by the height of the largest expression
** tree referred to by this, the parent select. The child select
@@ -129938,7 +130367,7 @@ SQLITE_PRIVATE int sqlite3Select(
/* Set the limiter.
*/
- iEnd = sqlite3VdbeMakeLabel(v);
+ iEnd = sqlite3VdbeMakeLabel(pParse);
if( (p->selFlags & SF_FixedLimit)==0 ){
p->nSelectRow = 320; /* 4 billion rows */
}
@@ -130005,9 +130434,9 @@ SQLITE_PRIVATE int sqlite3Select(
assert( p->pEList==pEList );
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pWin ){
- int addrGosub = sqlite3VdbeMakeLabel(v);
- int iCont = sqlite3VdbeMakeLabel(v);
- int iBreak = sqlite3VdbeMakeLabel(v);
+ int addrGosub = sqlite3VdbeMakeLabel(pParse);
+ int iCont = sqlite3VdbeMakeLabel(pParse);
+ int iBreak = sqlite3VdbeMakeLabel(pParse);
int regGosub = ++pParse->nMem;
sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);
@@ -130082,7 +130511,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
/* Create a label to jump to when we want to abort the query */
- addrEnd = sqlite3VdbeMakeLabel(v);
+ addrEnd = sqlite3VdbeMakeLabel(pParse);
/* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
@@ -130171,9 +130600,9 @@ SQLITE_PRIVATE int sqlite3Select(
iUseFlag = ++pParse->nMem;
iAbortFlag = ++pParse->nMem;
regOutputRow = ++pParse->nMem;
- addrOutputRow = sqlite3VdbeMakeLabel(v);
+ addrOutputRow = sqlite3VdbeMakeLabel(pParse);
regReset = ++pParse->nMem;
- addrReset = sqlite3VdbeMakeLabel(v);
+ addrReset = sqlite3VdbeMakeLabel(pParse);
iAMem = pParse->nMem + 1;
pParse->nMem += pGroupBy->nExpr;
iBMem = pParse->nMem + 1;
@@ -131460,7 +131889,7 @@ static SrcList *targetSrcList(
int iDb; /* Index of the database to use */
SrcList *pSrc; /* SrcList to be returned */
- pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+ pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( pSrc ){
assert( pSrc->nSrc>0 );
pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
@@ -131645,6 +132074,7 @@ static TriggerPrg *codeRowTrigger(
pSubParse->zAuthContext = pTrigger->zName;
pSubParse->eTriggerOp = pTrigger->op;
pSubParse->nQueryLoop = pParse->nQueryLoop;
+ pSubParse->disableVtab = pParse->disableVtab;
v = sqlite3GetVdbe(pSubParse);
if( v ){
@@ -131672,7 +132102,7 @@ static TriggerPrg *codeRowTrigger(
if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen)
&& db->mallocFailed==0
){
- iEndTrigger = sqlite3VdbeMakeLabel(v);
+ iEndTrigger = sqlite3VdbeMakeLabel(pSubParse);
sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
}
sqlite3ExprDelete(db, pWhen);
@@ -132271,6 +132701,7 @@ SQLITE_PRIVATE void sqlite3Update(
** being updated. Fill in aRegIdx[] with a register number that will hold
** the key for accessing each index.
*/
+ if( onError==OE_Replace ) bReplace = 1;
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
if( chngKey || hasFK>1 || pIdx==pPk
@@ -132284,9 +132715,7 @@ SQLITE_PRIVATE void sqlite3Update(
if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
- if( (onError==OE_Replace)
- || (onError==OE_Default && pIdx->onError==OE_Replace)
- ){
+ if( onError==OE_Default && pIdx->onError==OE_Replace ){
bReplace = 1;
}
break;
@@ -132358,7 +132787,7 @@ SQLITE_PRIVATE void sqlite3Update(
#endif
/* Jump to labelBreak to abandon further processing of this UPDATE */
- labelContinue = labelBreak = sqlite3VdbeMakeLabel(v);
+ labelContinue = labelBreak = sqlite3VdbeMakeLabel(pParse);
/* Not an UPSERT. Normal processing. Begin by
** initialize the count of updated rows */
@@ -132493,13 +132922,13 @@ SQLITE_PRIVATE void sqlite3Update(
VdbeCoverage(v);
}
if( eOnePass!=ONEPASS_SINGLE ){
- labelContinue = sqlite3VdbeMakeLabel(v);
+ labelContinue = sqlite3VdbeMakeLabel(pParse);
}
sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
VdbeCoverageIf(v, pPk==0);
VdbeCoverageIf(v, pPk!=0);
}else if( pPk ){
- labelContinue = sqlite3VdbeMakeLabel(v);
+ labelContinue = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
@@ -133267,16 +133696,16 @@ static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
** transient would cause the database file to appear to be deleted
** following reboot.
*/
-SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
+SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){
Vdbe *v = sqlite3GetVdbe(pParse);
int iDb = 0;
- if( v==0 ) return;
+ if( v==0 ) goto build_vacuum_end;
if( pNm ){
#ifndef SQLITE_BUG_COMPATIBLE_20160819
/* Default behavior: Report an error if the argument to VACUUM is
** not recognized */
iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
- if( iDb<0 ) return;
+ if( iDb<0 ) goto build_vacuum_end;
#else
/* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments
** to VACUUM are silently ignored. This is a back-out of a bug fix that
@@ -133288,21 +133717,33 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
#endif
}
if( iDb!=1 ){
- sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
+ int iIntoReg = 0;
+ if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){
+ iIntoReg = ++pParse->nMem;
+ sqlite3ExprCode(pParse, pInto, iIntoReg);
+ }
+ sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg);
sqlite3VdbeUsesBtree(v, iDb);
}
+build_vacuum_end:
+ sqlite3ExprDelete(pParse->db, pInto);
return;
}
/*
** This routine implements the OP_Vacuum opcode of the VDBE.
*/
-SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
+SQLITE_PRIVATE int sqlite3RunVacuum(
+ char **pzErrMsg, /* Write error message here */
+ sqlite3 *db, /* Database connection */
+ int iDb, /* Which attached DB to vacuum */
+ sqlite3_value *pOut /* Write results here, if not NULL */
+){
int rc = SQLITE_OK; /* Return code from service routines */
Btree *pMain; /* The database being vacuumed */
Btree *pTemp; /* The temporary database we vacuum into */
- u16 saved_mDbFlags; /* Saved value of db->mDbFlags */
- u32 saved_flags; /* Saved value of db->flags */
+ u32 saved_mDbFlags; /* Saved value of db->mDbFlags */
+ u64 saved_flags; /* Saved value of db->flags */
int saved_nChange; /* Saved value of db->nChange */
int saved_nTotalChange; /* Saved value of db->nTotalChange */
u8 saved_mTrace; /* Saved trace settings */
@@ -133311,6 +133752,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
int nRes; /* Bytes of reserved space at the end of each page */
int nDb; /* Number of attached databases */
const char *zDbMain; /* Schema name of database to vacuum */
+ const char *zOut; /* Name of output file */
if( !db->autoCommit ){
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
@@ -133320,6 +133762,15 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
return SQLITE_ERROR;
}
+ if( pOut ){
+ if( sqlite3_value_type(pOut)!=SQLITE_TEXT ){
+ sqlite3SetString(pzErrMsg, db, "non-text filename");
+ return SQLITE_ERROR;
+ }
+ zOut = (const char*)sqlite3_value_text(pOut);
+ }else{
+ zOut = "";
+ }
/* Save the current value of the database flags so that it can be
** restored before returning. Then set the writable-schema flag, and
@@ -133331,7 +133782,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
saved_mTrace = db->mTrace;
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
- db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder
+ db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder
| SQLITE_Defensive | SQLITE_CountRows);
db->mTrace = 0;
@@ -133354,19 +133805,21 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
** to write the journal header file.
*/
nDb = db->nDb;
- rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db");
+ rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
assert( (db->nDb-1)==nDb );
pDb = &db->aDb[nDb];
assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
pTemp = pDb->pBt;
-
- /* The call to execSql() to attach the temp database has left the file
- ** locked (as there was more than one active statement when the transaction
- ** to read the schema was concluded. Unlock it here so that this doesn't
- ** cause problems for the call to BtreeSetPageSize() below. */
- sqlite3BtreeCommit(pTemp);
-
+ if( pOut ){
+ sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
+ i64 sz = 0;
+ if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){
+ rc = SQLITE_ERROR;
+ sqlite3SetString(pzErrMsg, db, "output file already exists");
+ goto end_of_vacuum;
+ }
+ }
nRes = sqlite3BtreeGetOptimalReserve(pMain);
/* A VACUUM cannot change the pagesize of an encrypted database. */
@@ -133390,7 +133843,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
*/
rc = execSql(db, pzErrMsg, "BEGIN");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = sqlite3BtreeBeginTrans(pMain, 2, 0);
+ rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Do not attempt to change the page size for a WAL database */
@@ -133485,7 +133938,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
};
assert( 1==sqlite3BtreeIsInTrans(pTemp) );
- assert( 1==sqlite3BtreeIsInTrans(pMain) );
+ assert( pOut!=0 || 1==sqlite3BtreeIsInTrans(pMain) );
/* Copy Btree meta values */
for(i=0; i<ArraySize(aCopy); i+=2){
@@ -133496,17 +133949,23 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum;
}
- rc = sqlite3BtreeCopyFile(pMain, pTemp);
+ if( pOut==0 ){
+ rc = sqlite3BtreeCopyFile(pMain, pTemp);
+ }
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = sqlite3BtreeCommit(pTemp);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
#ifndef SQLITE_OMIT_AUTOVACUUM
- sqlite3BtreeSetAutoVacuum(pMain, sqlite3BtreeGetAutoVacuum(pTemp));
+ if( pOut==0 ){
+ sqlite3BtreeSetAutoVacuum(pMain, sqlite3BtreeGetAutoVacuum(pTemp));
+ }
#endif
}
assert( rc==SQLITE_OK );
- rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1);
+ if( pOut==0 ){
+ rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1);
+ }
end_of_vacuum:
/* Restore the original value of db->flags */
@@ -134547,6 +135006,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
const sqlite3_module *pMod = pVTab->pMod->pModule;
if( pVTab->pVtab && pMod->iVersion>=2 ){
int (*xMethod)(sqlite3_vtab *, int);
+ sqlite3VtabLock(pVTab);
switch( op ){
case SAVEPOINT_BEGIN:
xMethod = pMod->xSavepoint;
@@ -134562,6 +135022,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
if( xMethod && pVTab->iSavepoint>iSavepoint ){
rc = xMethod(pVTab->pVtab, iSavepoint);
}
+ sqlite3VtabUnlock(pVTab);
}
}
}
@@ -135323,8 +135784,11 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
# define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d)
#endif
SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
+ Parse *pParse, /* Parsing context */
+ Vdbe *v, /* Prepared statement under construction */
WhereInfo *pWInfo, /* Complete information about the WHERE clause */
int iLevel, /* Which level of pWInfo->a[] should be coded */
+ WhereLevel *pLevel, /* The current level pointer */
Bitmask notReady /* Which tables are currently available */
);
@@ -135594,6 +136058,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
}
#endif
zMsg = sqlite3StrAccumFinish(&str);
+ sqlite3ExplainBreakpoint("",zMsg);
ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
}
@@ -135919,16 +136384,17 @@ static int codeEqualityTerm(
if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
}
+ iTab = 0;
if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
- eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0);
+ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
}else{
sqlite3 *db = pParse->db;
pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
if( !db->mallocFailed ){
aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
- eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap);
- pTerm->pExpr->iTable = pX->iTable;
+ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
+ pTerm->pExpr->iTable = iTab;
}
sqlite3ExprDelete(db, pX);
pX = pTerm->pExpr;
@@ -135938,7 +136404,6 @@ static int codeEqualityTerm(
testcase( bRev );
bRev = !bRev;
}
- iTab = pX->iTable;
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
VdbeCoverageIf(v, bRev);
VdbeCoverageIf(v, !bRev);
@@ -135946,7 +136411,7 @@ static int codeEqualityTerm(
pLoop->wsFlags |= WHERE_IN_ABLE;
if( pLevel->u.in.nIn==0 ){
- pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
+ pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
}
i = pLevel->u.in.nIn;
@@ -136457,7 +136922,9 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
#ifndef SQLITE_OMIT_SUBQUERY
if( (p->flags & EP_xIsSelect) ){
Vdbe *v = pParse->pVdbe;
- int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0);
+ int iSelect;
+ assert( p->op==TK_SELECT );
+ iSelect = sqlite3CodeSubselect(pParse, p);
sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
}else
#endif
@@ -136543,22 +137010,21 @@ static void whereIndexExprTrans(
** implementation described by pWInfo.
*/
SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
+ Parse *pParse, /* Parsing context */
+ Vdbe *v, /* Prepared statement under construction */
WhereInfo *pWInfo, /* Complete information about the WHERE clause */
int iLevel, /* Which level of pWInfo->a[] should be coded */
+ WhereLevel *pLevel, /* The current level pointer */
Bitmask notReady /* Which tables are currently available */
){
int j, k; /* Loop counters */
int iCur; /* The VDBE cursor for the table */
int addrNxt; /* Where to jump to continue with the next IN case */
- int omitTable; /* True if we use the index only */
int bRev; /* True if we need to scan in reverse order */
- WhereLevel *pLevel; /* The where level to be coded */
WhereLoop *pLoop; /* The WhereLoop object being coded */
WhereClause *pWC; /* Decomposition of the entire WHERE clause */
WhereTerm *pTerm; /* A WHERE clause term */
- Parse *pParse; /* Parsing context */
sqlite3 *db; /* Database connection */
- Vdbe *v; /* The prepared stmt under constructions */
struct SrcList_item *pTabItem; /* FROM clause term being coded */
int addrBrk; /* Jump here to break out of the loop */
int addrHalt; /* addrBrk for the outermost loop */
@@ -136568,18 +137034,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
Index *pIdx = 0; /* Index used by loop (if any) */
int iLoop; /* Iteration of constraint generator loop */
- pParse = pWInfo->pParse;
- v = pParse->pVdbe;
pWC = &pWInfo->sWC;
db = pParse->db;
- pLevel = &pWInfo->a[iLevel];
pLoop = pLevel->pWLoop;
pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
iCur = pTabItem->iCursor;
pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
bRev = (pWInfo->revMask>>iLevel)&1;
- omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
- && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
/* Create labels for the "break" and "continue" instructions
@@ -136592,8 +137053,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** there are no IN operators in the constraints, the "addrNxt" label
** is the same as "addrBrk".
*/
- addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
- addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v);
+ addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
+ addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(pParse);
/* If this is the right table of a LEFT OUTER JOIN, allocate and
** initialize a memory cell that records if this table matches any
@@ -136720,7 +137181,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->pExpr!=0 );
- assert( omitTable==0 );
testcase( pTerm->wtFlags & TERM_VIRTUAL );
iReleaseReg = ++pParse->nMem;
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
@@ -136739,7 +137199,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int memEndValue = 0;
WhereTerm *pStart, *pEnd;
- assert( omitTable==0 );
j = 0;
pStart = pEnd = 0;
if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
@@ -136903,6 +137362,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
char *zEndAff = 0; /* Affinity for end of range constraint */
u8 bSeekPastNull = 0; /* True to seek past initial nulls */
u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */
+ int omitTable; /* True if we use the index only */
+
pIdx = pLoop->u.btree.pIndex;
iIdxCur = pLevel->iIdxCur;
@@ -137104,6 +137565,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
}
/* Seek the table cursor, if required */
+ omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
+ && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
if( omitTable ){
/* pIdx is a covering index. No need to access the main table. */
}else if( HasRowid(pIdx->pTable) ){
@@ -137138,8 +137601,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** the cursor. In this case it is important to do the full evaluation,
** as the result of the expression may not be NULL, even if all table
** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a
+ **
+ ** Also, do not do this when processing one index an a multi-index
+ ** OR clause, since the transformation will become invalid once we
+ ** move forward to the next index.
+ ** https://sqlite.org/src/info/4e8e4857d32d401f
*/
- if( pLevel->iLeftJoin==0 ){
+ if( pLevel->iLeftJoin==0 && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
}
@@ -137214,7 +137682,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */
int regRowset = 0; /* Register for RowSet object */
int regRowid = 0; /* Register holding rowid */
- int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */
+ int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */
int iRetInit; /* Address of regReturn init */
int untestedTerms = 0; /* Some terms not completely tested */
int ii; /* Loop counter */
@@ -137330,6 +137798,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
pOrExpr = pAndExpr;
}
/* Loop through table entries that match term pOrTerm. */
+ ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
wctrlFlags, iCovCur);
@@ -137433,6 +137902,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
/* Finish the loop through table entries that match term pOrTerm. */
sqlite3WhereEnd(pSubWInfo);
+ ExplainQueryPlanPop(pParse);
}
}
}
@@ -138394,6 +138864,7 @@ static void exprAnalyzeOrTerm(
** and column is found but leave okToChngToIN false if not found.
*/
for(j=0; j<2 && !okToChngToIN; j++){
+ Expr *pLeft = 0;
pOrTerm = pOrWc->a;
for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
assert( pOrTerm->eOperator & WO_EQ );
@@ -138417,6 +138888,7 @@ static void exprAnalyzeOrTerm(
}
iColumn = pOrTerm->u.leftColumn;
iCursor = pOrTerm->leftCursor;
+ pLeft = pOrTerm->pExpr->pLeft;
break;
}
if( i<0 ){
@@ -138436,7 +138908,9 @@ static void exprAnalyzeOrTerm(
assert( pOrTerm->eOperator & WO_EQ );
if( pOrTerm->leftCursor!=iCursor ){
pOrTerm->wtFlags &= ~TERM_OR_OK;
- }else if( pOrTerm->u.leftColumn!=iColumn ){
+ }else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR
+ && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
+ )){
okToChngToIN = 0;
}else{
int affLeft, affRight;
@@ -139525,6 +139999,17 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
}
/*
+** This is whereScanInit() for the case of an index on an expression.
+** It is factored out into a separate tail-recursion subroutine so that
+** the normal whereScanInit() routine, which is a high-runner, does not
+** need to push registers onto the stack as part of its prologue.
+*/
+static SQLITE_NOINLINE WhereTerm *whereScanInitIndexExpr(WhereScan *pScan){
+ pScan->idxaff = sqlite3ExprAffinity(pScan->pIdxExpr);
+ return whereScanNext(pScan);
+}
+
+/*
** Initialize a WHERE clause scanner object. Return a pointer to the
** first match. Return NULL if there are no matches.
**
@@ -139556,12 +140041,19 @@ static WhereTerm *whereScanInit(
pScan->pIdxExpr = 0;
pScan->idxaff = 0;
pScan->zCollName = 0;
+ pScan->opMask = opMask;
+ pScan->k = 0;
+ pScan->aiCur[0] = iCur;
+ pScan->nEquiv = 1;
+ pScan->iEquiv = 1;
if( pIdx ){
int j = iColumn;
iColumn = pIdx->aiColumn[j];
if( iColumn==XN_EXPR ){
pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
pScan->zCollName = pIdx->azColl[j];
+ pScan->aiColumn[0] = XN_EXPR;
+ return whereScanInitIndexExpr(pScan);
}else if( iColumn==pIdx->pTable->iPKey ){
iColumn = XN_ROWID;
}else if( iColumn>=0 ){
@@ -139571,12 +140063,7 @@ static WhereTerm *whereScanInit(
}else if( iColumn==XN_EXPR ){
return 0;
}
- pScan->opMask = opMask;
- pScan->k = 0;
- pScan->aiCur[0] = iCur;
pScan->aiColumn[0] = iColumn;
- pScan->nEquiv = 1;
- pScan->iEquiv = 1;
return whereScanNext(pScan);
}
@@ -140051,7 +140538,7 @@ static void constructAutomaticIndex(
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
}
if( pPartial ){
- iContinue = sqlite3VdbeMakeLabel(v);
+ iContinue = sqlite3VdbeMakeLabel(pParse);
sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
pLoop->wsFlags |= WHERE_PARTIALIDX;
}
@@ -140068,6 +140555,7 @@ static void constructAutomaticIndex(
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
pTabItem->regResult, 1);
sqlite3VdbeGoto(v, addrTop);
+ pTabItem->fg.viaCoroutine = 0;
}else{
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
}
@@ -141423,7 +141911,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
rc = whereLoopXfer(db, p, pTemplate);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
Index *pIndex = p->u.btree.pIndex;
- if( pIndex && pIndex->tnum==0 ){
+ if( pIndex && pIndex->idxType==SQLITE_IDXTYPE_IPK ){
p->u.btree.pIndex = 0;
}
}
@@ -141590,8 +142078,8 @@ static int whereRangeVectorLen(
** terms only. If it is modified, this value is restored before this
** function returns.
**
-** If pProbe->tnum==0, that means pIndex is a fake index used for the
-** INTEGER PRIMARY KEY.
+** If pProbe->idxType==SQLITE_IDXTYPE_IPK, that means pIndex is
+** a fake index used for the INTEGER PRIMARY KEY.
*/
static int whereLoopAddBtreeIndex(
WhereLoopBuilder *pBuilder, /* The WhereLoop factory */
@@ -142091,6 +142579,7 @@ static int whereLoopAddBtree(
sPk.onError = OE_Replace;
sPk.pTable = pTab;
sPk.szIdxRow = pTab->szTabRow;
+ sPk.idxType = SQLITE_IDXTYPE_IPK;
aiRowEstPk[0] = pTab->nRowLogEst;
aiRowEstPk[1] = 0;
pFirst = pSrc->pTab->pIndex;
@@ -142181,7 +142670,7 @@ static int whereLoopAddBtree(
b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
/* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
- if( pProbe->tnum<=0 ){
+ if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
/* Integer primary key index */
pNew->wsFlags = WHERE_IPK;
@@ -143857,7 +144346,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
pWInfo->pResultSet = pResultSet;
pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
pWInfo->nLevel = nTabList;
- pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
+ pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse);
pWInfo->wctrlFlags = wctrlFlags;
pWInfo->iLimit = iAuxArg;
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
@@ -144131,9 +144620,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
+ assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) );
if( bOnerow || (
0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
- && 0==(wsFlags & WHERE_VIRTUALTABLE)
+ && !IsVirtual(pTabList->a[0].pTab)
&& (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
)){
pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
@@ -144288,7 +144778,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
pParse, pTabList, pLevel, wctrlFlags
);
pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
- notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady);
+ notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady);
pWInfo->iContinue = pLevel->addrCont;
if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){
sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain);
@@ -144473,6 +144963,29 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
continue;
}
+#ifdef SQLITE_ENABLE_EARLY_CURSOR_CLOSE
+ /* Close all of the cursors that were opened by sqlite3WhereBegin.
+ ** Except, do not close cursors that will be reused by the OR optimization
+ ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors
+ ** created for the ONEPASS optimization.
+ */
+ if( (pTab->tabFlags & TF_Ephemeral)==0
+ && pTab->pSelect==0
+ && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
+ ){
+ int ws = pLoop->wsFlags;
+ if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){
+ sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
+ }
+ if( (ws & WHERE_INDEXED)!=0
+ && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0
+ && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1]
+ ){
+ sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
+ }
+ }
+#endif
+
/* If this scan uses an index, make VDBE code substitutions to read data
** from the index instead of from the table where possible. In some cases
** this optimization prevents the table from ever being read, which can
@@ -145372,8 +145885,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
pSub = sqlite3SelectNew(
pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
);
- p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
- assert( p->pSrc || db->mallocFailed );
+ p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( p->pSrc ){
p->pSrc->a[0].pSelect = pSub;
sqlite3SrcListAssignCursors(pParse, p->pSrc);
@@ -145430,6 +145942,7 @@ SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){
*/
static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
if( 0==sqlite3ExprIsConstant(pExpr) ){
+ if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr);
sqlite3ExprDelete(pParse->db, pExpr);
pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0);
}
@@ -145624,6 +146137,7 @@ static void windowCheckIntValue(Parse *pParse, int reg, int eCond){
VdbeCoverageNeverNullIf(v, eCond==0);
VdbeCoverageNeverNullIf(v, eCond==1);
VdbeCoverageNeverNullIf(v, eCond==2);
+ sqlite3MayAbort(pParse);
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
sqlite3ReleaseTempReg(pParse, regZero);
@@ -145879,7 +146393,7 @@ static void windowReturnOneRow(
|| pFunc->zName==first_valueName
){
int csr = pWin->csrApp;
- int lbl = sqlite3VdbeMakeLabel(v);
+ int lbl = sqlite3VdbeMakeLabel(pParse);
int tmpReg = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
@@ -145902,7 +146416,7 @@ static void windowReturnOneRow(
int nArg = pWin->pOwner->x.pList->nExpr;
int iEph = pMWin->iEphCsr;
int csr = pWin->csrApp;
- int lbl = sqlite3VdbeMakeLabel(v);
+ int lbl = sqlite3VdbeMakeLabel(pParse);
int tmpReg = sqlite3GetTempReg(pParse);
if( nArg<3 ){
@@ -146163,8 +146677,8 @@ static void windowCodeRowExprStep(
/* Allocate register and label for the "flush_partition" sub-routine. */
regFlushPart = ++pParse->nMem;
- lblFlushPart = sqlite3VdbeMakeLabel(v);
- lblFlushDone = sqlite3VdbeMakeLabel(v);
+ lblFlushPart = sqlite3VdbeMakeLabel(pParse);
+ lblFlushDone = sqlite3VdbeMakeLabel(pParse);
regStart = ++pParse->nMem;
regEnd = ++pParse->nMem;
@@ -146274,7 +146788,7 @@ static void windowCodeRowExprStep(
|| pMWin->eStart==TK_PRECEDING
|| pMWin->eStart==TK_FOLLOWING
){
- int lblSkipInverse = sqlite3VdbeMakeLabel(v);;
+ int lblSkipInverse = sqlite3VdbeMakeLabel(pParse);;
if( pMWin->eStart==TK_PRECEDING ){
sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1);
VdbeCoverage(v);
@@ -146439,13 +146953,13 @@ static void windowCodeCacheStep(
|| (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED)
);
- lblEmpty = sqlite3VdbeMakeLabel(v);
+ lblEmpty = sqlite3VdbeMakeLabel(pParse);
regNewPeer = pParse->nMem+1;
pParse->nMem += nPeer;
/* Allocate register and label for the "flush_partition" sub-routine. */
regFlushPart = ++pParse->nMem;
- lblFlushPart = sqlite3VdbeMakeLabel(v);
+ lblFlushPart = sqlite3VdbeMakeLabel(pParse);
csrLead = pParse->nTab++;
regCtr = ++pParse->nMem;
@@ -146682,6 +147196,7 @@ SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
if( pNew ){
pNew->zName = sqlite3DbStrDup(db, p->zName);
pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
+ pNew->pFunc = p->pFunc;
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
pNew->eType = p->eType;
@@ -146939,8 +147454,7 @@ static void disableLookaside(Parse *pParse){
memcpy(p->u.zToken, t.z, t.n);
p->u.zToken[t.n] = 0;
if( sqlite3Isquote(p->u.zToken[0]) ){
- if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted;
- sqlite3Dequote(p->u.zToken);
+ sqlite3DequoteExpr(p);
}
#if SQLITE_MAX_EXPR_DEPTH>0
p->nHeight = 1;
@@ -147049,27 +147563,27 @@ static void disableLookaside(Parse *pParse){
#endif
/************* Begin control #defines *****************************************/
#define YYCODETYPE unsigned short int
-#define YYNOCODE 277
+#define YYNOCODE 278
#define YYACTIONTYPE unsigned short int
#define YYWILDCARD 91
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
- Expr* yy18;
- struct TrigEvent yy34;
- IdList* yy48;
- int yy70;
- struct {int value; int mask;} yy111;
- struct FrameBound yy119;
- SrcList* yy135;
- TriggerStep* yy207;
- Window* yy327;
- Upsert* yy340;
- const char* yy392;
- ExprList* yy420;
- With* yy449;
- Select* yy489;
+ ExprList* yy42;
+ int yy96;
+ TriggerStep* yy119;
+ Window* yy147;
+ SrcList* yy167;
+ Upsert* yy266;
+ struct FrameBound yy317;
+ IdList* yy336;
+ struct TrigEvent yy350;
+ struct {int value; int mask;} yy367;
+ Select* yy423;
+ const char* yy464;
+ Expr* yy490;
+ With* yy499;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
@@ -147085,17 +147599,17 @@ typedef union {
#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
#define YYFALLBACK 1
-#define YYNSTATE 521
-#define YYNRULE 367
+#define YYNSTATE 524
+#define YYNRULE 369
#define YYNTOKEN 155
-#define YY_MAX_SHIFT 520
-#define YY_MIN_SHIFTREDUCE 756
-#define YY_MAX_SHIFTREDUCE 1122
-#define YY_ERROR_ACTION 1123
-#define YY_ACCEPT_ACTION 1124
-#define YY_NO_ACTION 1125
-#define YY_MIN_REDUCE 1126
-#define YY_MAX_REDUCE 1492
+#define YY_MAX_SHIFT 523
+#define YY_MIN_SHIFTREDUCE 760
+#define YY_MAX_SHIFTREDUCE 1128
+#define YY_ERROR_ACTION 1129
+#define YY_ACCEPT_ACTION 1130
+#define YY_NO_ACTION 1131
+#define YY_MIN_REDUCE 1132
+#define YY_MAX_REDUCE 1500
/************* End control #defines *******************************************/
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
@@ -147164,566 +147678,567 @@ typedef union {
*********** Begin parsing tables **********************************************/
#define YY_ACTTAB_COUNT (2009)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 368, 105, 102, 197, 105, 102, 197, 515, 1124, 1,
- /* 10 */ 1, 520, 2, 1128, 515, 1192, 1171, 1456, 275, 370,
- /* 20 */ 127, 1389, 1197, 1197, 1192, 1166, 178, 1205, 64, 64,
- /* 30 */ 477, 887, 322, 428, 348, 37, 37, 808, 362, 888,
- /* 40 */ 509, 509, 509, 112, 113, 103, 1100, 1100, 953, 956,
- /* 50 */ 946, 946, 110, 110, 111, 111, 111, 111, 365, 252,
- /* 60 */ 252, 515, 252, 252, 497, 515, 309, 515, 459, 515,
- /* 70 */ 1079, 491, 512, 478, 6, 512, 809, 134, 498, 228,
- /* 80 */ 194, 428, 37, 37, 515, 208, 64, 64, 64, 64,
- /* 90 */ 13, 13, 109, 109, 109, 109, 108, 108, 107, 107,
- /* 100 */ 107, 106, 401, 258, 381, 13, 13, 398, 397, 428,
- /* 110 */ 252, 252, 370, 476, 405, 1104, 1079, 1080, 1081, 386,
- /* 120 */ 1106, 390, 497, 512, 497, 1423, 1419, 304, 1105, 307,
- /* 130 */ 1256, 496, 370, 499, 16, 16, 112, 113, 103, 1100,
- /* 140 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111,
- /* 150 */ 111, 262, 1107, 495, 1107, 401, 112, 113, 103, 1100,
- /* 160 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111,
- /* 170 */ 111, 129, 1425, 343, 1420, 339, 1059, 492, 1057, 263,
- /* 180 */ 73, 105, 102, 197, 994, 109, 109, 109, 109, 108,
- /* 190 */ 108, 107, 107, 107, 106, 401, 370, 111, 111, 111,
- /* 200 */ 111, 104, 492, 89, 1432, 109, 109, 109, 109, 108,
- /* 210 */ 108, 107, 107, 107, 106, 401, 111, 111, 111, 111,
- /* 220 */ 112, 113, 103, 1100, 1100, 953, 956, 946, 946, 110,
- /* 230 */ 110, 111, 111, 111, 111, 109, 109, 109, 109, 108,
- /* 240 */ 108, 107, 107, 107, 106, 401, 114, 108, 108, 107,
- /* 250 */ 107, 107, 106, 401, 109, 109, 109, 109, 108, 108,
- /* 260 */ 107, 107, 107, 106, 401, 152, 399, 399, 399, 109,
- /* 270 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401,
- /* 280 */ 178, 493, 1412, 434, 1037, 1486, 1079, 515, 1486, 370,
- /* 290 */ 421, 297, 357, 412, 74, 1079, 109, 109, 109, 109,
- /* 300 */ 108, 108, 107, 107, 107, 106, 401, 1413, 37, 37,
- /* 310 */ 1431, 274, 506, 112, 113, 103, 1100, 1100, 953, 956,
- /* 320 */ 946, 946, 110, 110, 111, 111, 111, 111, 1436, 520,
- /* 330 */ 2, 1128, 1079, 1080, 1081, 430, 275, 1079, 127, 366,
- /* 340 */ 933, 1079, 1080, 1081, 220, 1205, 913, 458, 455, 454,
- /* 350 */ 392, 167, 515, 1035, 152, 445, 924, 453, 152, 874,
- /* 360 */ 923, 289, 109, 109, 109, 109, 108, 108, 107, 107,
- /* 370 */ 107, 106, 401, 13, 13, 261, 853, 252, 252, 227,
- /* 380 */ 106, 401, 370, 1079, 1080, 1081, 311, 388, 1079, 296,
- /* 390 */ 512, 923, 923, 925, 231, 323, 1255, 1388, 1423, 490,
- /* 400 */ 274, 506, 12, 208, 274, 506, 112, 113, 103, 1100,
- /* 410 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111,
- /* 420 */ 111, 1440, 286, 1128, 288, 1079, 1097, 247, 275, 1098,
- /* 430 */ 127, 387, 405, 389, 1079, 1080, 1081, 1205, 159, 238,
- /* 440 */ 255, 321, 461, 316, 460, 225, 790, 105, 102, 197,
- /* 450 */ 513, 314, 842, 842, 445, 109, 109, 109, 109, 108,
- /* 460 */ 108, 107, 107, 107, 106, 401, 515, 514, 515, 252,
- /* 470 */ 252, 1079, 1080, 1081, 435, 370, 1098, 933, 1460, 794,
- /* 480 */ 274, 506, 512, 105, 102, 197, 336, 63, 63, 64,
- /* 490 */ 64, 27, 790, 924, 287, 208, 1354, 923, 515, 112,
- /* 500 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110,
- /* 510 */ 111, 111, 111, 111, 107, 107, 107, 106, 401, 49,
- /* 520 */ 49, 515, 28, 1079, 405, 497, 421, 297, 923, 923,
- /* 530 */ 925, 186, 468, 1079, 467, 999, 999, 442, 515, 1079,
- /* 540 */ 334, 515, 45, 45, 1083, 342, 173, 168, 109, 109,
- /* 550 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 13,
- /* 560 */ 13, 205, 13, 13, 252, 252, 1195, 1195, 370, 1079,
- /* 570 */ 1080, 1081, 787, 265, 5, 359, 494, 512, 469, 1079,
- /* 580 */ 1080, 1081, 398, 397, 1079, 1079, 1080, 1081, 3, 282,
- /* 590 */ 1079, 1083, 112, 113, 103, 1100, 1100, 953, 956, 946,
- /* 600 */ 946, 110, 110, 111, 111, 111, 111, 252, 252, 1015,
- /* 610 */ 220, 1079, 873, 458, 455, 454, 943, 943, 954, 957,
- /* 620 */ 512, 252, 252, 453, 1016, 1079, 445, 1107, 1209, 1107,
- /* 630 */ 1079, 1080, 1081, 515, 512, 426, 1079, 1080, 1081, 1017,
- /* 640 */ 512, 109, 109, 109, 109, 108, 108, 107, 107, 107,
- /* 650 */ 106, 401, 1052, 515, 50, 50, 515, 1079, 1080, 1081,
- /* 660 */ 828, 370, 1051, 379, 411, 1064, 1358, 207, 408, 773,
- /* 670 */ 829, 1079, 1080, 1081, 64, 64, 322, 64, 64, 1302,
- /* 680 */ 947, 411, 410, 1358, 1360, 112, 113, 103, 1100, 1100,
- /* 690 */ 953, 956, 946, 946, 110, 110, 111, 111, 111, 111,
- /* 700 */ 294, 482, 515, 1037, 1487, 515, 434, 1487, 354, 1120,
- /* 710 */ 483, 996, 913, 485, 466, 996, 132, 178, 33, 450,
- /* 720 */ 1203, 136, 406, 64, 64, 479, 64, 64, 419, 369,
- /* 730 */ 283, 1146, 252, 252, 109, 109, 109, 109, 108, 108,
- /* 740 */ 107, 107, 107, 106, 401, 512, 224, 440, 411, 266,
- /* 750 */ 1358, 266, 252, 252, 370, 296, 416, 284, 934, 396,
- /* 760 */ 976, 470, 400, 252, 252, 512, 9, 473, 231, 500,
- /* 770 */ 354, 1036, 1035, 1488, 355, 374, 512, 1121, 112, 113,
- /* 780 */ 103, 1100, 1100, 953, 956, 946, 946, 110, 110, 111,
- /* 790 */ 111, 111, 111, 252, 252, 1015, 515, 1347, 295, 252,
- /* 800 */ 252, 252, 252, 1098, 375, 249, 512, 445, 872, 322,
- /* 810 */ 1016, 480, 512, 195, 512, 434, 273, 15, 15, 515,
- /* 820 */ 314, 515, 95, 515, 93, 1017, 367, 109, 109, 109,
- /* 830 */ 109, 108, 108, 107, 107, 107, 106, 401, 515, 1121,
- /* 840 */ 39, 39, 51, 51, 52, 52, 503, 370, 515, 1204,
- /* 850 */ 1098, 918, 439, 341, 133, 436, 223, 222, 221, 53,
- /* 860 */ 53, 322, 1400, 761, 762, 763, 515, 370, 88, 54,
- /* 870 */ 54, 112, 113, 103, 1100, 1100, 953, 956, 946, 946,
- /* 880 */ 110, 110, 111, 111, 111, 111, 407, 55, 55, 196,
- /* 890 */ 515, 112, 113, 103, 1100, 1100, 953, 956, 946, 946,
- /* 900 */ 110, 110, 111, 111, 111, 111, 135, 264, 1149, 376,
- /* 910 */ 515, 40, 40, 515, 872, 515, 993, 515, 993, 116,
- /* 920 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106,
- /* 930 */ 401, 41, 41, 515, 43, 43, 44, 44, 56, 56,
- /* 940 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106,
- /* 950 */ 401, 515, 379, 515, 57, 57, 515, 799, 515, 379,
- /* 960 */ 515, 445, 200, 515, 323, 515, 1397, 515, 1459, 515,
- /* 970 */ 1287, 817, 58, 58, 14, 14, 515, 59, 59, 118,
- /* 980 */ 118, 60, 60, 515, 46, 46, 61, 61, 62, 62,
- /* 990 */ 47, 47, 515, 190, 189, 91, 515, 140, 140, 515,
- /* 1000 */ 394, 515, 277, 1200, 141, 141, 515, 1115, 515, 992,
- /* 1010 */ 515, 992, 515, 69, 69, 370, 278, 48, 48, 259,
- /* 1020 */ 65, 65, 119, 119, 246, 246, 260, 66, 66, 120,
- /* 1030 */ 120, 121, 121, 117, 117, 370, 515, 512, 383, 112,
- /* 1040 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110,
- /* 1050 */ 111, 111, 111, 111, 515, 872, 515, 139, 139, 112,
- /* 1060 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110,
- /* 1070 */ 111, 111, 111, 111, 1287, 138, 138, 125, 125, 515,
- /* 1080 */ 12, 515, 281, 1287, 515, 445, 131, 1287, 109, 109,
- /* 1090 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 515,
- /* 1100 */ 124, 124, 122, 122, 515, 123, 123, 515, 109, 109,
- /* 1110 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 515,
- /* 1120 */ 68, 68, 463, 783, 515, 70, 70, 302, 67, 67,
- /* 1130 */ 1032, 253, 253, 356, 1287, 191, 196, 1433, 465, 1301,
- /* 1140 */ 38, 38, 384, 94, 512, 42, 42, 177, 848, 274,
- /* 1150 */ 506, 385, 420, 847, 1356, 441, 508, 376, 377, 153,
- /* 1160 */ 423, 872, 432, 370, 224, 251, 194, 887, 182, 293,
- /* 1170 */ 783, 848, 88, 254, 466, 888, 847, 915, 807, 806,
- /* 1180 */ 230, 1241, 910, 370, 17, 413, 797, 112, 113, 103,
- /* 1190 */ 1100, 1100, 953, 956, 946, 946, 110, 110, 111, 111,
- /* 1200 */ 111, 111, 395, 814, 815, 1175, 983, 112, 101, 103,
- /* 1210 */ 1100, 1100, 953, 956, 946, 946, 110, 110, 111, 111,
- /* 1220 */ 111, 111, 375, 422, 427, 429, 298, 230, 230, 88,
- /* 1230 */ 1240, 451, 312, 797, 226, 88, 109, 109, 109, 109,
- /* 1240 */ 108, 108, 107, 107, 107, 106, 401, 86, 433, 979,
- /* 1250 */ 927, 881, 226, 983, 230, 415, 109, 109, 109, 109,
- /* 1260 */ 108, 108, 107, 107, 107, 106, 401, 320, 845, 781,
- /* 1270 */ 846, 100, 130, 100, 1403, 290, 370, 319, 1377, 1376,
- /* 1280 */ 437, 1449, 299, 1237, 303, 306, 308, 310, 1188, 1174,
- /* 1290 */ 1173, 1172, 315, 324, 325, 1228, 370, 927, 1249, 271,
- /* 1300 */ 1286, 113, 103, 1100, 1100, 953, 956, 946, 946, 110,
- /* 1310 */ 110, 111, 111, 111, 111, 1224, 1235, 502, 501, 1292,
- /* 1320 */ 1221, 1155, 103, 1100, 1100, 953, 956, 946, 946, 110,
- /* 1330 */ 110, 111, 111, 111, 111, 1148, 1137, 1136, 1138, 1443,
- /* 1340 */ 446, 244, 184, 98, 507, 188, 4, 353, 327, 109,
- /* 1350 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401,
- /* 1360 */ 510, 329, 331, 199, 414, 456, 292, 285, 318, 109,
- /* 1370 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401,
- /* 1380 */ 11, 1271, 1279, 402, 361, 192, 1171, 1351, 431, 505,
- /* 1390 */ 346, 1350, 333, 98, 507, 504, 4, 187, 1446, 1115,
- /* 1400 */ 233, 1396, 155, 1394, 1112, 152, 72, 75, 378, 425,
- /* 1410 */ 510, 165, 149, 157, 933, 1276, 86, 30, 1268, 417,
- /* 1420 */ 96, 96, 8, 160, 161, 162, 163, 97, 418, 402,
- /* 1430 */ 517, 516, 449, 402, 923, 210, 358, 424, 1282, 438,
- /* 1440 */ 169, 214, 360, 1345, 80, 504, 31, 444, 1365, 301,
- /* 1450 */ 245, 274, 506, 216, 174, 305, 488, 447, 217, 462,
- /* 1460 */ 1139, 487, 218, 363, 933, 923, 923, 925, 926, 24,
- /* 1470 */ 96, 96, 1191, 1190, 1189, 391, 1182, 97, 1163, 402,
- /* 1480 */ 517, 516, 799, 364, 923, 1162, 317, 1161, 98, 507,
- /* 1490 */ 1181, 4, 1458, 472, 393, 269, 270, 475, 481, 1232,
- /* 1500 */ 85, 1233, 326, 328, 232, 510, 495, 1231, 330, 98,
- /* 1510 */ 507, 1230, 4, 486, 335, 923, 923, 925, 926, 24,
- /* 1520 */ 1435, 1068, 404, 181, 336, 256, 510, 115, 402, 332,
- /* 1530 */ 352, 352, 351, 241, 349, 1214, 1414, 770, 338, 10,
- /* 1540 */ 504, 340, 272, 92, 1331, 1213, 87, 183, 484, 402,
- /* 1550 */ 201, 488, 280, 239, 344, 345, 489, 1145, 29, 933,
- /* 1560 */ 279, 504, 1074, 518, 240, 96, 96, 242, 243, 519,
- /* 1570 */ 1134, 1129, 97, 154, 402, 517, 516, 372, 373, 923,
- /* 1580 */ 933, 142, 143, 128, 1381, 267, 96, 96, 852, 757,
- /* 1590 */ 203, 144, 403, 97, 1382, 402, 517, 516, 204, 1380,
- /* 1600 */ 923, 146, 1379, 1159, 1158, 71, 1156, 276, 202, 185,
- /* 1610 */ 923, 923, 925, 926, 24, 198, 257, 126, 991, 989,
- /* 1620 */ 907, 98, 507, 156, 4, 145, 158, 206, 831, 209,
- /* 1630 */ 291, 923, 923, 925, 926, 24, 1005, 911, 510, 164,
- /* 1640 */ 147, 380, 371, 382, 166, 76, 77, 274, 506, 148,
- /* 1650 */ 78, 79, 1008, 211, 212, 1004, 137, 213, 18, 300,
- /* 1660 */ 230, 402, 997, 1109, 443, 215, 32, 170, 171, 772,
- /* 1670 */ 409, 448, 319, 504, 219, 172, 452, 81, 19, 457,
- /* 1680 */ 313, 20, 82, 268, 488, 150, 810, 179, 83, 487,
- /* 1690 */ 464, 151, 933, 180, 959, 84, 1040, 34, 96, 96,
- /* 1700 */ 471, 1041, 35, 474, 193, 97, 248, 402, 517, 516,
- /* 1710 */ 1068, 404, 923, 250, 256, 880, 229, 175, 875, 352,
- /* 1720 */ 352, 351, 241, 349, 100, 21, 770, 22, 1054, 1056,
- /* 1730 */ 7, 98, 507, 1045, 4, 337, 1058, 23, 974, 201,
- /* 1740 */ 176, 280, 88, 923, 923, 925, 926, 24, 510, 279,
- /* 1750 */ 960, 958, 962, 1014, 963, 1013, 235, 234, 25, 36,
- /* 1760 */ 99, 90, 507, 928, 4, 511, 350, 782, 26, 841,
- /* 1770 */ 236, 402, 347, 1069, 237, 1125, 1125, 1451, 510, 203,
- /* 1780 */ 1450, 1125, 1125, 504, 1125, 1125, 1125, 204, 1125, 1125,
- /* 1790 */ 146, 1125, 1125, 1125, 1125, 1125, 1125, 202, 1125, 1125,
- /* 1800 */ 1125, 402, 933, 1125, 1125, 1125, 1125, 1125, 96, 96,
- /* 1810 */ 1125, 1125, 1125, 504, 1125, 97, 1125, 402, 517, 516,
- /* 1820 */ 1125, 1125, 923, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1830 */ 1125, 371, 933, 1125, 1125, 1125, 274, 506, 96, 96,
- /* 1840 */ 1125, 1125, 1125, 1125, 1125, 97, 1125, 402, 517, 516,
- /* 1850 */ 1125, 1125, 923, 923, 923, 925, 926, 24, 1125, 409,
- /* 1860 */ 1125, 1125, 1125, 256, 1125, 1125, 1125, 1125, 352, 352,
- /* 1870 */ 351, 241, 349, 1125, 1125, 770, 1125, 1125, 1125, 1125,
- /* 1880 */ 1125, 1125, 1125, 923, 923, 925, 926, 24, 201, 1125,
- /* 1890 */ 280, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 279, 1125,
- /* 1900 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1910 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1920 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 203, 1125,
- /* 1930 */ 1125, 1125, 1125, 1125, 1125, 1125, 204, 1125, 1125, 146,
- /* 1940 */ 1125, 1125, 1125, 1125, 1125, 1125, 202, 1125, 1125, 1125,
- /* 1950 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1960 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1970 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1980 */ 371, 1125, 1125, 1125, 1125, 274, 506, 1125, 1125, 1125,
- /* 1990 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 2000 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 409,
+ /* 0 */ 377, 518, 371, 107, 104, 200, 1293, 518, 1130, 1,
+ /* 10 */ 1, 523, 2, 1134, 518, 1203, 1203, 1262, 277, 373,
+ /* 20 */ 129, 495, 37, 37, 1397, 1201, 1201, 1211, 65, 65,
+ /* 30 */ 480, 891, 107, 104, 200, 37, 37, 1043, 1494, 892,
+ /* 40 */ 346, 1494, 342, 114, 115, 105, 1106, 1106, 957, 960,
+ /* 50 */ 950, 950, 112, 112, 113, 113, 113, 113, 285, 254,
+ /* 60 */ 254, 518, 254, 254, 500, 518, 495, 518, 107, 104,
+ /* 70 */ 200, 1085, 515, 481, 386, 515, 1464, 442, 501, 230,
+ /* 80 */ 197, 439, 37, 37, 1172, 210, 65, 65, 65, 65,
+ /* 90 */ 254, 254, 111, 111, 111, 111, 110, 110, 109, 109,
+ /* 100 */ 109, 108, 404, 515, 404, 155, 1041, 431, 401, 400,
+ /* 110 */ 254, 254, 373, 1431, 1427, 408, 1110, 1085, 1086, 1087,
+ /* 120 */ 284, 1112, 500, 515, 500, 368, 1433, 1421, 1428, 1111,
+ /* 130 */ 1261, 499, 373, 502, 108, 404, 114, 115, 105, 1106,
+ /* 140 */ 1106, 957, 960, 950, 950, 112, 112, 113, 113, 113,
+ /* 150 */ 113, 276, 509, 1113, 369, 1113, 114, 115, 105, 1106,
+ /* 160 */ 1106, 957, 960, 950, 950, 112, 112, 113, 113, 113,
+ /* 170 */ 113, 496, 1420, 1431, 493, 1468, 1065, 260, 1063, 433,
+ /* 180 */ 74, 107, 104, 200, 498, 111, 111, 111, 111, 110,
+ /* 190 */ 110, 109, 109, 109, 108, 404, 373, 113, 113, 113,
+ /* 200 */ 113, 106, 131, 91, 1361, 111, 111, 111, 111, 110,
+ /* 210 */ 110, 109, 109, 109, 108, 404, 113, 113, 113, 113,
+ /* 220 */ 114, 115, 105, 1106, 1106, 957, 960, 950, 950, 112,
+ /* 230 */ 112, 113, 113, 113, 113, 111, 111, 111, 111, 110,
+ /* 240 */ 110, 109, 109, 109, 108, 404, 116, 110, 110, 109,
+ /* 250 */ 109, 109, 108, 404, 111, 111, 111, 111, 110, 110,
+ /* 260 */ 109, 109, 109, 108, 404, 917, 512, 512, 512, 111,
+ /* 270 */ 111, 111, 111, 110, 110, 109, 109, 109, 108, 404,
+ /* 280 */ 517, 1198, 1177, 181, 109, 109, 109, 108, 404, 373,
+ /* 290 */ 1198, 402, 402, 402, 75, 360, 111, 111, 111, 111,
+ /* 300 */ 110, 110, 109, 109, 109, 108, 404, 382, 299, 419,
+ /* 310 */ 287, 170, 518, 114, 115, 105, 1106, 1106, 957, 960,
+ /* 320 */ 950, 950, 112, 112, 113, 113, 113, 113, 1444, 523,
+ /* 330 */ 2, 1134, 518, 13, 13, 337, 277, 1085, 129, 226,
+ /* 340 */ 937, 1058, 1000, 471, 917, 1211, 453, 384, 1085, 395,
+ /* 350 */ 162, 1057, 155, 45, 45, 416, 928, 401, 400, 479,
+ /* 360 */ 927, 12, 111, 111, 111, 111, 110, 110, 109, 109,
+ /* 370 */ 109, 108, 404, 226, 286, 254, 254, 254, 254, 518,
+ /* 380 */ 16, 16, 373, 1085, 1086, 1087, 314, 299, 515, 472,
+ /* 390 */ 515, 927, 927, 929, 1085, 1086, 1087, 378, 276, 509,
+ /* 400 */ 65, 65, 1113, 210, 1113, 1085, 114, 115, 105, 1106,
+ /* 410 */ 1106, 957, 960, 950, 950, 112, 112, 113, 113, 113,
+ /* 420 */ 113, 1448, 222, 1134, 1089, 461, 458, 457, 277, 180,
+ /* 430 */ 129, 378, 392, 408, 423, 456, 500, 1211, 240, 257,
+ /* 440 */ 324, 464, 319, 463, 227, 470, 12, 317, 424, 300,
+ /* 450 */ 317, 1085, 1086, 1087, 485, 111, 111, 111, 111, 110,
+ /* 460 */ 110, 109, 109, 109, 108, 404, 181, 118, 1085, 254,
+ /* 470 */ 254, 1089, 518, 90, 351, 373, 518, 1181, 365, 798,
+ /* 480 */ 1440, 339, 515, 248, 248, 77, 325, 133, 1085, 249,
+ /* 490 */ 424, 300, 794, 49, 49, 210, 515, 65, 65, 114,
+ /* 500 */ 115, 105, 1106, 1106, 957, 960, 950, 950, 112, 112,
+ /* 510 */ 113, 113, 113, 113, 1085, 1086, 1087, 222, 1085, 438,
+ /* 520 */ 461, 458, 457, 937, 787, 408, 171, 857, 362, 1021,
+ /* 530 */ 456, 136, 198, 486, 1085, 1086, 1087, 448, 794, 928,
+ /* 540 */ 5, 193, 192, 927, 1022, 107, 104, 200, 111, 111,
+ /* 550 */ 111, 111, 110, 110, 109, 109, 109, 108, 404, 1023,
+ /* 560 */ 254, 254, 803, 1085, 1085, 1086, 1087, 437, 373, 1085,
+ /* 570 */ 344, 787, 791, 515, 927, 927, 929, 1085, 1408, 1396,
+ /* 580 */ 832, 1085, 176, 3, 852, 1085, 518, 1439, 429, 851,
+ /* 590 */ 833, 518, 114, 115, 105, 1106, 1106, 957, 960, 950,
+ /* 600 */ 950, 112, 112, 113, 113, 113, 113, 13, 13, 1085,
+ /* 610 */ 1086, 1087, 13, 13, 518, 1085, 1086, 1087, 1496, 358,
+ /* 620 */ 1085, 389, 1234, 1085, 1086, 1087, 391, 1085, 1086, 1087,
+ /* 630 */ 448, 1085, 1086, 1087, 518, 65, 65, 947, 947, 958,
+ /* 640 */ 961, 111, 111, 111, 111, 110, 110, 109, 109, 109,
+ /* 650 */ 108, 404, 518, 382, 878, 13, 13, 518, 877, 518,
+ /* 660 */ 263, 373, 518, 431, 448, 1070, 1085, 1086, 1087, 267,
+ /* 670 */ 448, 488, 1360, 64, 64, 431, 812, 155, 50, 50,
+ /* 680 */ 65, 65, 518, 65, 65, 114, 115, 105, 1106, 1106,
+ /* 690 */ 957, 960, 950, 950, 112, 112, 113, 113, 113, 113,
+ /* 700 */ 518, 951, 382, 13, 13, 415, 411, 462, 414, 1085,
+ /* 710 */ 1366, 777, 1210, 292, 297, 813, 399, 497, 181, 403,
+ /* 720 */ 261, 15, 15, 276, 509, 414, 413, 1366, 1368, 410,
+ /* 730 */ 372, 345, 1209, 264, 111, 111, 111, 111, 110, 110,
+ /* 740 */ 109, 109, 109, 108, 404, 265, 254, 254, 229, 1405,
+ /* 750 */ 268, 1215, 268, 1103, 373, 1085, 1086, 1087, 938, 515,
+ /* 760 */ 393, 409, 876, 515, 254, 254, 1152, 482, 473, 262,
+ /* 770 */ 422, 476, 325, 503, 289, 518, 291, 515, 114, 115,
+ /* 780 */ 105, 1106, 1106, 957, 960, 950, 950, 112, 112, 113,
+ /* 790 */ 113, 113, 113, 414, 1021, 1366, 39, 39, 254, 254,
+ /* 800 */ 254, 254, 980, 254, 254, 254, 254, 255, 255, 1022,
+ /* 810 */ 279, 515, 516, 515, 846, 846, 515, 138, 515, 518,
+ /* 820 */ 515, 1043, 1495, 251, 1023, 1495, 876, 111, 111, 111,
+ /* 830 */ 111, 110, 110, 109, 109, 109, 108, 404, 518, 1353,
+ /* 840 */ 51, 51, 518, 199, 518, 506, 290, 373, 518, 276,
+ /* 850 */ 509, 922, 9, 483, 233, 1005, 1005, 445, 189, 52,
+ /* 860 */ 52, 325, 280, 53, 53, 54, 54, 373, 876, 55,
+ /* 870 */ 55, 114, 115, 105, 1106, 1106, 957, 960, 950, 950,
+ /* 880 */ 112, 112, 113, 113, 113, 113, 97, 518, 95, 1104,
+ /* 890 */ 1041, 114, 115, 105, 1106, 1106, 957, 960, 950, 950,
+ /* 900 */ 112, 112, 113, 113, 113, 113, 135, 199, 56, 56,
+ /* 910 */ 765, 766, 767, 225, 224, 223, 518, 283, 437, 233,
+ /* 920 */ 111, 111, 111, 111, 110, 110, 109, 109, 109, 108,
+ /* 930 */ 404, 1002, 876, 326, 518, 1002, 1104, 40, 40, 518,
+ /* 940 */ 111, 111, 111, 111, 110, 110, 109, 109, 109, 108,
+ /* 950 */ 404, 518, 448, 518, 1104, 41, 41, 518, 17, 518,
+ /* 960 */ 43, 43, 1155, 379, 518, 448, 518, 443, 518, 390,
+ /* 970 */ 518, 194, 44, 44, 57, 57, 1247, 518, 58, 58,
+ /* 980 */ 59, 59, 518, 466, 326, 14, 14, 60, 60, 120,
+ /* 990 */ 120, 61, 61, 449, 1206, 93, 518, 425, 46, 46,
+ /* 1000 */ 518, 1104, 518, 62, 62, 518, 437, 305, 518, 852,
+ /* 1010 */ 518, 298, 518, 1246, 851, 373, 518, 63, 63, 1293,
+ /* 1020 */ 397, 47, 47, 142, 142, 1467, 143, 143, 821, 70,
+ /* 1030 */ 70, 48, 48, 66, 66, 373, 518, 121, 121, 114,
+ /* 1040 */ 115, 105, 1106, 1106, 957, 960, 950, 950, 112, 112,
+ /* 1050 */ 113, 113, 113, 113, 518, 418, 518, 67, 67, 114,
+ /* 1060 */ 115, 105, 1106, 1106, 957, 960, 950, 950, 112, 112,
+ /* 1070 */ 113, 113, 113, 113, 312, 122, 122, 123, 123, 1293,
+ /* 1080 */ 518, 357, 1126, 88, 518, 435, 325, 387, 111, 111,
+ /* 1090 */ 111, 111, 110, 110, 109, 109, 109, 108, 404, 266,
+ /* 1100 */ 518, 119, 119, 518, 1293, 141, 141, 518, 111, 111,
+ /* 1110 */ 111, 111, 110, 110, 109, 109, 109, 108, 404, 518,
+ /* 1120 */ 801, 140, 140, 518, 127, 127, 511, 379, 126, 126,
+ /* 1130 */ 518, 137, 518, 1308, 518, 307, 518, 310, 518, 203,
+ /* 1140 */ 124, 124, 1307, 96, 125, 125, 207, 388, 1441, 468,
+ /* 1150 */ 1127, 69, 69, 71, 71, 68, 68, 38, 38, 42,
+ /* 1160 */ 42, 357, 1042, 373, 1293, 276, 509, 801, 185, 469,
+ /* 1170 */ 494, 436, 444, 6, 380, 156, 253, 197, 469, 134,
+ /* 1180 */ 426, 33, 1038, 373, 1121, 359, 1411, 114, 115, 105,
+ /* 1190 */ 1106, 1106, 957, 960, 950, 950, 112, 112, 113, 113,
+ /* 1200 */ 113, 113, 914, 296, 27, 293, 90, 114, 103, 105,
+ /* 1210 */ 1106, 1106, 957, 960, 950, 950, 112, 112, 113, 113,
+ /* 1220 */ 113, 113, 919, 275, 430, 232, 891, 232, 432, 256,
+ /* 1230 */ 1127, 232, 398, 370, 892, 28, 111, 111, 111, 111,
+ /* 1240 */ 110, 110, 109, 109, 109, 108, 404, 301, 454, 1385,
+ /* 1250 */ 90, 228, 209, 987, 811, 810, 111, 111, 111, 111,
+ /* 1260 */ 110, 110, 109, 109, 109, 108, 404, 315, 818, 819,
+ /* 1270 */ 90, 323, 983, 931, 885, 228, 373, 232, 999, 849,
+ /* 1280 */ 999, 322, 102, 998, 1384, 998, 785, 850, 440, 132,
+ /* 1290 */ 102, 302, 1243, 306, 309, 311, 373, 313, 1194, 1180,
+ /* 1300 */ 987, 115, 105, 1106, 1106, 957, 960, 950, 950, 112,
+ /* 1310 */ 112, 113, 113, 113, 113, 1178, 1179, 318, 327, 328,
+ /* 1320 */ 931, 1255, 105, 1106, 1106, 957, 960, 950, 950, 112,
+ /* 1330 */ 112, 113, 113, 113, 113, 1292, 1230, 1457, 273, 1241,
+ /* 1340 */ 504, 505, 1298, 100, 510, 246, 4, 1161, 1154, 111,
+ /* 1350 */ 111, 111, 111, 110, 110, 109, 109, 109, 108, 404,
+ /* 1360 */ 513, 1143, 187, 1142, 202, 1144, 1451, 356, 1227, 111,
+ /* 1370 */ 111, 111, 111, 110, 110, 109, 109, 109, 108, 404,
+ /* 1380 */ 11, 1277, 330, 405, 332, 334, 191, 1285, 364, 195,
+ /* 1390 */ 295, 417, 288, 100, 510, 507, 4, 434, 459, 321,
+ /* 1400 */ 1177, 349, 1357, 1356, 336, 155, 190, 1454, 1121, 158,
+ /* 1410 */ 513, 508, 235, 1404, 937, 1402, 1118, 381, 77, 428,
+ /* 1420 */ 98, 98, 8, 1282, 168, 30, 152, 99, 160, 405,
+ /* 1430 */ 520, 519, 88, 405, 927, 1362, 1274, 420, 163, 73,
+ /* 1440 */ 164, 76, 165, 166, 421, 507, 452, 212, 361, 363,
+ /* 1450 */ 427, 276, 509, 31, 1288, 172, 491, 441, 216, 1351,
+ /* 1460 */ 82, 490, 447, 1373, 937, 927, 927, 929, 930, 24,
+ /* 1470 */ 98, 98, 304, 247, 218, 177, 308, 99, 219, 405,
+ /* 1480 */ 520, 519, 450, 1145, 927, 220, 366, 1197, 100, 510,
+ /* 1490 */ 465, 4, 1188, 1196, 1195, 394, 803, 1169, 1187, 367,
+ /* 1500 */ 1168, 396, 484, 320, 1167, 513, 1466, 87, 475, 100,
+ /* 1510 */ 510, 271, 4, 272, 478, 927, 927, 929, 930, 24,
+ /* 1520 */ 1443, 1074, 407, 1238, 1239, 258, 513, 329, 405, 331,
+ /* 1530 */ 355, 355, 354, 243, 352, 234, 489, 774, 498, 184,
+ /* 1540 */ 507, 338, 1422, 339, 117, 1220, 10, 341, 333, 405,
+ /* 1550 */ 204, 491, 282, 1219, 1237, 1236, 492, 335, 343, 937,
+ /* 1560 */ 281, 507, 94, 1337, 186, 98, 98, 347, 89, 487,
+ /* 1570 */ 348, 241, 99, 29, 405, 520, 519, 274, 1151, 927,
+ /* 1580 */ 937, 521, 1080, 245, 242, 244, 98, 98, 856, 522,
+ /* 1590 */ 206, 1140, 1135, 99, 144, 405, 520, 519, 147, 375,
+ /* 1600 */ 927, 149, 376, 157, 1389, 1390, 1388, 1387, 205, 145,
+ /* 1610 */ 927, 927, 929, 930, 24, 146, 130, 761, 1165, 1164,
+ /* 1620 */ 72, 100, 510, 1162, 4, 269, 406, 188, 278, 201,
+ /* 1630 */ 259, 927, 927, 929, 930, 24, 128, 911, 513, 997,
+ /* 1640 */ 995, 159, 374, 208, 148, 161, 835, 276, 509, 211,
+ /* 1650 */ 294, 1011, 915, 167, 150, 383, 169, 78, 385, 79,
+ /* 1660 */ 80, 405, 81, 151, 1014, 213, 214, 1010, 139, 18,
+ /* 1670 */ 412, 215, 303, 507, 232, 1115, 1003, 446, 173, 217,
+ /* 1680 */ 174, 32, 776, 451, 491, 322, 221, 175, 814, 490,
+ /* 1690 */ 83, 455, 937, 19, 460, 316, 20, 84, 98, 98,
+ /* 1700 */ 270, 182, 85, 467, 153, 99, 154, 405, 520, 519,
+ /* 1710 */ 1074, 407, 927, 183, 258, 963, 1046, 86, 34, 355,
+ /* 1720 */ 355, 354, 243, 352, 474, 1047, 774, 35, 477, 196,
+ /* 1730 */ 250, 100, 510, 252, 4, 884, 178, 231, 1060, 204,
+ /* 1740 */ 21, 282, 102, 927, 927, 929, 930, 24, 513, 281,
+ /* 1750 */ 879, 22, 1064, 1062, 1051, 7, 340, 23, 978, 179,
+ /* 1760 */ 90, 92, 510, 964, 4, 236, 962, 966, 1020, 1019,
+ /* 1770 */ 237, 405, 967, 25, 36, 514, 932, 786, 513, 206,
+ /* 1780 */ 101, 26, 845, 507, 238, 239, 1459, 147, 350, 1458,
+ /* 1790 */ 149, 353, 1075, 1131, 1131, 1131, 1131, 205, 1131, 1131,
+ /* 1800 */ 1131, 405, 937, 1131, 1131, 1131, 1131, 1131, 98, 98,
+ /* 1810 */ 1131, 1131, 1131, 507, 1131, 99, 1131, 405, 520, 519,
+ /* 1820 */ 1131, 1131, 927, 1131, 1131, 1131, 1131, 1131, 1131, 1131,
+ /* 1830 */ 1131, 374, 937, 1131, 1131, 1131, 276, 509, 98, 98,
+ /* 1840 */ 1131, 1131, 1131, 1131, 1131, 99, 1131, 405, 520, 519,
+ /* 1850 */ 1131, 1131, 927, 927, 927, 929, 930, 24, 1131, 412,
+ /* 1860 */ 1131, 1131, 1131, 258, 1131, 1131, 1131, 1131, 355, 355,
+ /* 1870 */ 354, 243, 352, 1131, 1131, 774, 1131, 1131, 1131, 1131,
+ /* 1880 */ 1131, 1131, 1131, 927, 927, 929, 930, 24, 204, 1131,
+ /* 1890 */ 282, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 281, 1131,
+ /* 1900 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131,
+ /* 1910 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131,
+ /* 1920 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 206, 1131,
+ /* 1930 */ 1131, 1131, 1131, 1131, 1131, 1131, 147, 1131, 1131, 149,
+ /* 1940 */ 1131, 1131, 1131, 1131, 1131, 1131, 205, 1131, 1131, 1131,
+ /* 1950 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131,
+ /* 1960 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131,
+ /* 1970 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131,
+ /* 1980 */ 374, 1131, 1131, 1131, 1131, 276, 509, 1131, 1131, 1131,
+ /* 1990 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131,
+ /* 2000 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 412,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 184, 238, 239, 240, 238, 239, 240, 163, 155, 156,
- /* 10 */ 157, 158, 159, 160, 163, 191, 192, 183, 165, 19,
- /* 20 */ 167, 258, 202, 203, 200, 191, 163, 174, 184, 185,
- /* 30 */ 174, 31, 163, 163, 171, 184, 185, 35, 175, 39,
- /* 40 */ 179, 180, 181, 43, 44, 45, 46, 47, 48, 49,
- /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 184, 206,
- /* 60 */ 207, 163, 206, 207, 220, 163, 16, 163, 66, 163,
- /* 70 */ 59, 270, 219, 229, 273, 219, 74, 208, 174, 223,
- /* 80 */ 224, 163, 184, 185, 163, 232, 184, 185, 184, 185,
- /* 90 */ 184, 185, 92, 93, 94, 95, 96, 97, 98, 99,
- /* 100 */ 100, 101, 102, 233, 198, 184, 185, 96, 97, 163,
- /* 110 */ 206, 207, 19, 163, 261, 104, 105, 106, 107, 198,
- /* 120 */ 109, 119, 220, 219, 220, 274, 275, 77, 117, 79,
- /* 130 */ 187, 229, 19, 229, 184, 185, 43, 44, 45, 46,
+ /* 0 */ 168, 163, 184, 238, 239, 240, 163, 163, 155, 156,
+ /* 10 */ 157, 158, 159, 160, 163, 202, 203, 187, 165, 19,
+ /* 20 */ 167, 163, 184, 185, 259, 202, 203, 174, 184, 185,
+ /* 30 */ 174, 31, 238, 239, 240, 184, 185, 22, 23, 39,
+ /* 40 */ 216, 26, 218, 43, 44, 45, 46, 47, 48, 49,
+ /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 174, 206,
+ /* 60 */ 207, 163, 206, 207, 220, 163, 163, 163, 238, 239,
+ /* 70 */ 240, 59, 219, 229, 231, 219, 183, 245, 174, 223,
+ /* 80 */ 224, 249, 184, 185, 191, 232, 184, 185, 184, 185,
+ /* 90 */ 206, 207, 92, 93, 94, 95, 96, 97, 98, 99,
+ /* 100 */ 100, 101, 102, 219, 102, 81, 91, 163, 96, 97,
+ /* 110 */ 206, 207, 19, 275, 276, 262, 104, 105, 106, 107,
+ /* 120 */ 163, 109, 220, 219, 220, 184, 275, 269, 277, 117,
+ /* 130 */ 187, 229, 19, 229, 101, 102, 43, 44, 45, 46,
/* 140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 150 */ 57, 233, 141, 134, 143, 102, 43, 44, 45, 46,
+ /* 150 */ 57, 127, 128, 141, 184, 143, 43, 44, 45, 46,
/* 160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 170 */ 57, 152, 274, 216, 276, 218, 83, 163, 85, 233,
- /* 180 */ 67, 238, 239, 240, 11, 92, 93, 94, 95, 96,
+ /* 170 */ 57, 268, 269, 275, 276, 197, 83, 233, 85, 163,
+ /* 180 */ 67, 238, 239, 240, 134, 92, 93, 94, 95, 96,
/* 190 */ 97, 98, 99, 100, 101, 102, 19, 54, 55, 56,
- /* 200 */ 57, 58, 163, 26, 163, 92, 93, 94, 95, 96,
+ /* 200 */ 57, 58, 152, 26, 247, 92, 93, 94, 95, 96,
/* 210 */ 97, 98, 99, 100, 101, 102, 54, 55, 56, 57,
/* 220 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
/* 230 */ 53, 54, 55, 56, 57, 92, 93, 94, 95, 96,
/* 240 */ 97, 98, 99, 100, 101, 102, 69, 96, 97, 98,
/* 250 */ 99, 100, 101, 102, 92, 93, 94, 95, 96, 97,
- /* 260 */ 98, 99, 100, 101, 102, 81, 179, 180, 181, 92,
+ /* 260 */ 98, 99, 100, 101, 102, 73, 179, 180, 181, 92,
/* 270 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
- /* 280 */ 163, 267, 268, 163, 22, 23, 59, 163, 26, 19,
- /* 290 */ 117, 118, 175, 109, 24, 59, 92, 93, 94, 95,
- /* 300 */ 96, 97, 98, 99, 100, 101, 102, 268, 184, 185,
- /* 310 */ 269, 127, 128, 43, 44, 45, 46, 47, 48, 49,
+ /* 280 */ 163, 191, 192, 163, 98, 99, 100, 101, 102, 19,
+ /* 290 */ 200, 179, 180, 181, 24, 175, 92, 93, 94, 95,
+ /* 300 */ 96, 97, 98, 99, 100, 101, 102, 163, 116, 117,
+ /* 310 */ 118, 22, 163, 43, 44, 45, 46, 47, 48, 49,
/* 320 */ 50, 51, 52, 53, 54, 55, 56, 57, 157, 158,
- /* 330 */ 159, 160, 105, 106, 107, 163, 165, 59, 167, 184,
- /* 340 */ 90, 105, 106, 107, 108, 174, 73, 111, 112, 113,
- /* 350 */ 19, 22, 163, 91, 81, 163, 106, 121, 81, 132,
- /* 360 */ 110, 16, 92, 93, 94, 95, 96, 97, 98, 99,
- /* 370 */ 100, 101, 102, 184, 185, 255, 98, 206, 207, 26,
- /* 380 */ 101, 102, 19, 105, 106, 107, 23, 198, 59, 116,
- /* 390 */ 219, 141, 142, 143, 24, 163, 187, 205, 274, 275,
- /* 400 */ 127, 128, 182, 232, 127, 128, 43, 44, 45, 46,
+ /* 330 */ 159, 160, 163, 184, 185, 163, 165, 59, 167, 46,
+ /* 340 */ 90, 76, 11, 174, 73, 174, 19, 198, 59, 19,
+ /* 350 */ 72, 86, 81, 184, 185, 234, 106, 96, 97, 163,
+ /* 360 */ 110, 182, 92, 93, 94, 95, 96, 97, 98, 99,
+ /* 370 */ 100, 101, 102, 46, 230, 206, 207, 206, 207, 163,
+ /* 380 */ 184, 185, 19, 105, 106, 107, 23, 116, 219, 220,
+ /* 390 */ 219, 141, 142, 143, 105, 106, 107, 104, 127, 128,
+ /* 400 */ 184, 185, 141, 232, 143, 59, 43, 44, 45, 46,
/* 410 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 420 */ 57, 158, 77, 160, 79, 59, 26, 182, 165, 59,
- /* 430 */ 167, 199, 261, 102, 105, 106, 107, 174, 72, 108,
- /* 440 */ 109, 110, 111, 112, 113, 114, 59, 238, 239, 240,
- /* 450 */ 123, 120, 125, 126, 163, 92, 93, 94, 95, 96,
- /* 460 */ 97, 98, 99, 100, 101, 102, 163, 163, 163, 206,
- /* 470 */ 207, 105, 106, 107, 254, 19, 106, 90, 197, 23,
- /* 480 */ 127, 128, 219, 238, 239, 240, 22, 184, 185, 184,
- /* 490 */ 185, 22, 105, 106, 149, 232, 205, 110, 163, 43,
+ /* 420 */ 57, 158, 108, 160, 59, 111, 112, 113, 165, 250,
+ /* 430 */ 167, 104, 102, 262, 255, 121, 220, 174, 108, 109,
+ /* 440 */ 110, 111, 112, 113, 114, 229, 182, 120, 117, 118,
+ /* 450 */ 120, 105, 106, 107, 163, 92, 93, 94, 95, 96,
+ /* 460 */ 97, 98, 99, 100, 101, 102, 163, 22, 59, 206,
+ /* 470 */ 207, 106, 163, 26, 171, 19, 163, 193, 175, 23,
+ /* 480 */ 163, 22, 219, 206, 207, 139, 163, 22, 59, 182,
+ /* 490 */ 117, 118, 59, 184, 185, 232, 219, 184, 185, 43,
/* 500 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 510 */ 54, 55, 56, 57, 98, 99, 100, 101, 102, 184,
- /* 520 */ 185, 163, 53, 59, 261, 220, 117, 118, 141, 142,
- /* 530 */ 143, 131, 174, 59, 229, 116, 117, 118, 163, 59,
- /* 540 */ 163, 163, 184, 185, 59, 242, 72, 22, 92, 93,
- /* 550 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 184,
- /* 560 */ 185, 24, 184, 185, 206, 207, 202, 203, 19, 105,
- /* 570 */ 106, 107, 23, 198, 22, 174, 198, 219, 220, 105,
- /* 580 */ 106, 107, 96, 97, 59, 105, 106, 107, 22, 174,
- /* 590 */ 59, 106, 43, 44, 45, 46, 47, 48, 49, 50,
- /* 600 */ 51, 52, 53, 54, 55, 56, 57, 206, 207, 12,
- /* 610 */ 108, 59, 132, 111, 112, 113, 46, 47, 48, 49,
- /* 620 */ 219, 206, 207, 121, 27, 59, 163, 141, 207, 143,
- /* 630 */ 105, 106, 107, 163, 219, 234, 105, 106, 107, 42,
- /* 640 */ 219, 92, 93, 94, 95, 96, 97, 98, 99, 100,
- /* 650 */ 101, 102, 76, 163, 184, 185, 163, 105, 106, 107,
- /* 660 */ 63, 19, 86, 163, 163, 23, 163, 130, 205, 21,
- /* 670 */ 73, 105, 106, 107, 184, 185, 163, 184, 185, 237,
- /* 680 */ 110, 180, 181, 180, 181, 43, 44, 45, 46, 47,
+ /* 510 */ 54, 55, 56, 57, 105, 106, 107, 108, 59, 255,
+ /* 520 */ 111, 112, 113, 90, 59, 262, 22, 98, 174, 12,
+ /* 530 */ 121, 208, 163, 220, 105, 106, 107, 163, 105, 106,
+ /* 540 */ 22, 96, 97, 110, 27, 238, 239, 240, 92, 93,
+ /* 550 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 42,
+ /* 560 */ 206, 207, 115, 59, 105, 106, 107, 163, 19, 59,
+ /* 570 */ 163, 106, 23, 219, 141, 142, 143, 59, 163, 205,
+ /* 580 */ 63, 59, 72, 22, 124, 59, 163, 270, 234, 129,
+ /* 590 */ 73, 163, 43, 44, 45, 46, 47, 48, 49, 50,
+ /* 600 */ 51, 52, 53, 54, 55, 56, 57, 184, 185, 105,
+ /* 610 */ 106, 107, 184, 185, 163, 105, 106, 107, 265, 266,
+ /* 620 */ 59, 198, 225, 105, 106, 107, 198, 105, 106, 107,
+ /* 630 */ 163, 105, 106, 107, 163, 184, 185, 46, 47, 48,
+ /* 640 */ 49, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+ /* 650 */ 101, 102, 163, 163, 132, 184, 185, 163, 132, 163,
+ /* 660 */ 256, 19, 163, 163, 163, 23, 105, 106, 107, 198,
+ /* 670 */ 163, 220, 205, 184, 185, 163, 35, 81, 184, 185,
+ /* 680 */ 184, 185, 163, 184, 185, 43, 44, 45, 46, 47,
/* 690 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- /* 700 */ 174, 163, 163, 22, 23, 163, 163, 26, 22, 23,
- /* 710 */ 220, 29, 73, 220, 272, 33, 22, 163, 24, 19,
- /* 720 */ 174, 208, 259, 184, 185, 19, 184, 185, 80, 175,
- /* 730 */ 230, 174, 206, 207, 92, 93, 94, 95, 96, 97,
- /* 740 */ 98, 99, 100, 101, 102, 219, 46, 65, 247, 195,
- /* 750 */ 247, 197, 206, 207, 19, 116, 117, 118, 23, 220,
- /* 760 */ 112, 174, 220, 206, 207, 219, 22, 174, 24, 174,
- /* 770 */ 22, 23, 91, 264, 265, 168, 219, 91, 43, 44,
+ /* 700 */ 163, 110, 163, 184, 185, 109, 205, 66, 163, 59,
+ /* 710 */ 163, 21, 205, 16, 174, 74, 220, 198, 163, 220,
+ /* 720 */ 230, 184, 185, 127, 128, 180, 181, 180, 181, 163,
+ /* 730 */ 175, 242, 174, 233, 92, 93, 94, 95, 96, 97,
+ /* 740 */ 98, 99, 100, 101, 102, 233, 206, 207, 26, 163,
+ /* 750 */ 195, 207, 197, 26, 19, 105, 106, 107, 23, 219,
+ /* 760 */ 119, 260, 26, 219, 206, 207, 174, 19, 174, 230,
+ /* 770 */ 80, 174, 163, 174, 77, 163, 79, 219, 43, 44,
/* 780 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- /* 790 */ 55, 56, 57, 206, 207, 12, 163, 149, 255, 206,
- /* 800 */ 207, 206, 207, 59, 104, 23, 219, 163, 26, 163,
- /* 810 */ 27, 105, 219, 163, 219, 163, 211, 184, 185, 163,
- /* 820 */ 120, 163, 146, 163, 148, 42, 221, 92, 93, 94,
- /* 830 */ 95, 96, 97, 98, 99, 100, 101, 102, 163, 91,
- /* 840 */ 184, 185, 184, 185, 184, 185, 63, 19, 163, 205,
- /* 850 */ 106, 23, 245, 163, 208, 248, 116, 117, 118, 184,
- /* 860 */ 185, 163, 163, 7, 8, 9, 163, 19, 26, 184,
+ /* 790 */ 55, 56, 57, 248, 12, 248, 184, 185, 206, 207,
+ /* 800 */ 206, 207, 112, 206, 207, 206, 207, 206, 207, 27,
+ /* 810 */ 163, 219, 123, 219, 125, 126, 219, 208, 219, 163,
+ /* 820 */ 219, 22, 23, 23, 42, 26, 26, 92, 93, 94,
+ /* 830 */ 95, 96, 97, 98, 99, 100, 101, 102, 163, 149,
+ /* 840 */ 184, 185, 163, 107, 163, 63, 149, 19, 163, 127,
+ /* 850 */ 128, 23, 22, 105, 24, 116, 117, 118, 131, 184,
+ /* 860 */ 185, 163, 163, 184, 185, 184, 185, 19, 132, 184,
/* 870 */ 185, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- /* 880 */ 52, 53, 54, 55, 56, 57, 163, 184, 185, 107,
- /* 890 */ 163, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- /* 900 */ 52, 53, 54, 55, 56, 57, 208, 255, 177, 178,
- /* 910 */ 163, 184, 185, 163, 132, 163, 141, 163, 143, 22,
+ /* 880 */ 52, 53, 54, 55, 56, 57, 146, 163, 148, 59,
+ /* 890 */ 91, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ /* 900 */ 52, 53, 54, 55, 56, 57, 208, 107, 184, 185,
+ /* 910 */ 7, 8, 9, 116, 117, 118, 163, 163, 163, 24,
/* 920 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
- /* 930 */ 102, 184, 185, 163, 184, 185, 184, 185, 184, 185,
+ /* 930 */ 102, 29, 132, 163, 163, 33, 106, 184, 185, 163,
/* 940 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
- /* 950 */ 102, 163, 163, 163, 184, 185, 163, 115, 163, 163,
- /* 960 */ 163, 163, 15, 163, 163, 163, 163, 163, 23, 163,
- /* 970 */ 163, 26, 184, 185, 184, 185, 163, 184, 185, 184,
- /* 980 */ 185, 184, 185, 163, 184, 185, 184, 185, 184, 185,
- /* 990 */ 184, 185, 163, 96, 97, 147, 163, 184, 185, 163,
- /* 1000 */ 199, 163, 163, 205, 184, 185, 163, 60, 163, 141,
- /* 1010 */ 163, 143, 163, 184, 185, 19, 163, 184, 185, 230,
- /* 1020 */ 184, 185, 184, 185, 206, 207, 230, 184, 185, 184,
- /* 1030 */ 185, 184, 185, 184, 185, 19, 163, 219, 231, 43,
+ /* 950 */ 102, 163, 163, 163, 59, 184, 185, 163, 22, 163,
+ /* 960 */ 184, 185, 177, 178, 163, 163, 163, 65, 163, 199,
+ /* 970 */ 163, 26, 184, 185, 184, 185, 163, 163, 184, 185,
+ /* 980 */ 184, 185, 163, 98, 163, 184, 185, 184, 185, 184,
+ /* 990 */ 185, 184, 185, 252, 205, 147, 163, 61, 184, 185,
+ /* 1000 */ 163, 106, 163, 184, 185, 163, 163, 205, 163, 124,
+ /* 1010 */ 163, 256, 163, 163, 129, 19, 163, 184, 185, 163,
+ /* 1020 */ 199, 184, 185, 184, 185, 23, 184, 185, 26, 184,
+ /* 1030 */ 185, 184, 185, 184, 185, 19, 163, 184, 185, 43,
/* 1040 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 1050 */ 54, 55, 56, 57, 163, 26, 163, 184, 185, 43,
+ /* 1050 */ 54, 55, 56, 57, 163, 163, 163, 184, 185, 43,
/* 1060 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 1070 */ 54, 55, 56, 57, 163, 184, 185, 184, 185, 163,
- /* 1080 */ 182, 163, 163, 163, 163, 163, 22, 163, 92, 93,
- /* 1090 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163,
- /* 1100 */ 184, 185, 184, 185, 163, 184, 185, 163, 92, 93,
+ /* 1070 */ 54, 55, 56, 57, 16, 184, 185, 184, 185, 163,
+ /* 1080 */ 163, 22, 23, 138, 163, 19, 163, 231, 92, 93,
+ /* 1090 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 256,
+ /* 1100 */ 163, 184, 185, 163, 163, 184, 185, 163, 92, 93,
/* 1110 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163,
- /* 1120 */ 184, 185, 98, 59, 163, 184, 185, 205, 184, 185,
- /* 1130 */ 23, 206, 207, 26, 163, 26, 107, 153, 154, 237,
- /* 1140 */ 184, 185, 231, 147, 219, 184, 185, 249, 124, 127,
- /* 1150 */ 128, 231, 254, 129, 163, 231, 177, 178, 262, 263,
- /* 1160 */ 118, 132, 19, 19, 46, 223, 224, 31, 24, 23,
- /* 1170 */ 106, 124, 26, 22, 272, 39, 129, 23, 109, 110,
- /* 1180 */ 26, 163, 140, 19, 22, 234, 59, 43, 44, 45,
+ /* 1120 */ 59, 184, 185, 163, 184, 185, 177, 178, 184, 185,
+ /* 1130 */ 163, 208, 163, 237, 163, 77, 163, 79, 163, 15,
+ /* 1140 */ 184, 185, 237, 147, 184, 185, 24, 231, 153, 154,
+ /* 1150 */ 91, 184, 185, 184, 185, 184, 185, 184, 185, 184,
+ /* 1160 */ 185, 22, 23, 19, 163, 127, 128, 106, 24, 273,
+ /* 1170 */ 271, 105, 231, 274, 263, 264, 223, 224, 273, 22,
+ /* 1180 */ 118, 24, 23, 19, 60, 26, 163, 43, 44, 45,
/* 1190 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 1200 */ 56, 57, 231, 7, 8, 193, 59, 43, 44, 45,
+ /* 1200 */ 56, 57, 140, 23, 22, 163, 26, 43, 44, 45,
/* 1210 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 1220 */ 56, 57, 104, 61, 23, 23, 23, 26, 26, 26,
- /* 1230 */ 163, 23, 23, 106, 26, 26, 92, 93, 94, 95,
- /* 1240 */ 96, 97, 98, 99, 100, 101, 102, 138, 105, 23,
- /* 1250 */ 59, 23, 26, 106, 26, 163, 92, 93, 94, 95,
- /* 1260 */ 96, 97, 98, 99, 100, 101, 102, 110, 23, 23,
- /* 1270 */ 23, 26, 26, 26, 163, 163, 19, 120, 163, 163,
- /* 1280 */ 163, 130, 163, 163, 163, 163, 163, 163, 163, 193,
- /* 1290 */ 193, 163, 163, 163, 163, 225, 19, 106, 163, 222,
- /* 1300 */ 163, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 1310 */ 53, 54, 55, 56, 57, 163, 163, 203, 163, 163,
- /* 1320 */ 222, 163, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 1330 */ 53, 54, 55, 56, 57, 163, 163, 163, 163, 163,
- /* 1340 */ 251, 250, 209, 19, 20, 182, 22, 161, 222, 92,
+ /* 1220 */ 56, 57, 23, 211, 23, 26, 31, 26, 23, 22,
+ /* 1230 */ 91, 26, 231, 221, 39, 53, 92, 93, 94, 95,
+ /* 1240 */ 96, 97, 98, 99, 100, 101, 102, 23, 23, 163,
+ /* 1250 */ 26, 26, 130, 59, 109, 110, 92, 93, 94, 95,
+ /* 1260 */ 96, 97, 98, 99, 100, 101, 102, 23, 7, 8,
+ /* 1270 */ 26, 110, 23, 59, 23, 26, 19, 26, 141, 23,
+ /* 1280 */ 143, 120, 26, 141, 163, 143, 23, 23, 163, 26,
+ /* 1290 */ 26, 163, 163, 163, 163, 163, 19, 163, 163, 193,
+ /* 1300 */ 106, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 1310 */ 53, 54, 55, 56, 57, 163, 193, 163, 163, 163,
+ /* 1320 */ 106, 163, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 1330 */ 53, 54, 55, 56, 57, 163, 163, 130, 222, 163,
+ /* 1340 */ 163, 203, 163, 19, 20, 251, 22, 163, 163, 92,
/* 1350 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
- /* 1360 */ 36, 222, 222, 260, 226, 188, 256, 226, 187, 92,
+ /* 1360 */ 36, 163, 209, 163, 261, 163, 163, 161, 222, 92,
/* 1370 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
- /* 1380 */ 210, 213, 213, 59, 213, 196, 192, 187, 256, 244,
- /* 1390 */ 212, 187, 226, 19, 20, 71, 22, 210, 166, 60,
- /* 1400 */ 130, 170, 260, 170, 38, 81, 257, 257, 170, 104,
- /* 1410 */ 36, 22, 43, 201, 90, 236, 138, 235, 213, 18,
- /* 1420 */ 96, 97, 48, 204, 204, 204, 204, 103, 170, 105,
- /* 1430 */ 106, 107, 18, 59, 110, 169, 213, 213, 201, 170,
- /* 1440 */ 201, 169, 236, 213, 146, 71, 235, 62, 253, 252,
- /* 1450 */ 170, 127, 128, 169, 22, 170, 82, 189, 169, 104,
- /* 1460 */ 170, 87, 169, 189, 90, 141, 142, 143, 144, 145,
- /* 1470 */ 96, 97, 186, 186, 186, 64, 194, 103, 186, 105,
- /* 1480 */ 106, 107, 115, 189, 110, 188, 186, 186, 19, 20,
- /* 1490 */ 194, 22, 186, 189, 102, 246, 246, 189, 133, 228,
- /* 1500 */ 104, 228, 227, 227, 170, 36, 134, 228, 227, 19,
- /* 1510 */ 20, 228, 22, 84, 271, 141, 142, 143, 144, 145,
- /* 1520 */ 0, 1, 2, 216, 22, 5, 36, 137, 59, 227,
- /* 1530 */ 10, 11, 12, 13, 14, 217, 269, 17, 216, 22,
- /* 1540 */ 71, 170, 243, 146, 241, 217, 136, 215, 135, 59,
- /* 1550 */ 30, 82, 32, 25, 214, 213, 87, 173, 26, 90,
- /* 1560 */ 40, 71, 13, 172, 164, 96, 97, 164, 6, 162,
- /* 1570 */ 162, 162, 103, 263, 105, 106, 107, 266, 266, 110,
- /* 1580 */ 90, 176, 176, 190, 182, 190, 96, 97, 98, 4,
- /* 1590 */ 70, 176, 3, 103, 182, 105, 106, 107, 78, 182,
- /* 1600 */ 110, 81, 182, 182, 182, 182, 182, 151, 88, 22,
- /* 1610 */ 141, 142, 143, 144, 145, 15, 89, 16, 23, 23,
- /* 1620 */ 128, 19, 20, 139, 22, 119, 131, 24, 20, 133,
- /* 1630 */ 16, 141, 142, 143, 144, 145, 1, 140, 36, 131,
- /* 1640 */ 119, 61, 122, 37, 139, 53, 53, 127, 128, 119,
- /* 1650 */ 53, 53, 105, 34, 130, 1, 5, 104, 22, 149,
- /* 1660 */ 26, 59, 68, 75, 41, 130, 24, 68, 104, 20,
- /* 1670 */ 150, 19, 120, 71, 114, 22, 67, 22, 22, 67,
- /* 1680 */ 23, 22, 22, 67, 82, 37, 28, 23, 138, 87,
- /* 1690 */ 22, 153, 90, 23, 23, 26, 23, 22, 96, 97,
- /* 1700 */ 24, 23, 22, 24, 130, 103, 23, 105, 106, 107,
- /* 1710 */ 1, 2, 110, 23, 5, 105, 34, 22, 132, 10,
- /* 1720 */ 11, 12, 13, 14, 26, 34, 17, 34, 85, 83,
- /* 1730 */ 44, 19, 20, 23, 22, 24, 75, 34, 23, 30,
- /* 1740 */ 26, 32, 26, 141, 142, 143, 144, 145, 36, 40,
- /* 1750 */ 23, 23, 23, 23, 11, 23, 22, 26, 22, 22,
- /* 1760 */ 22, 19, 20, 23, 22, 26, 15, 23, 22, 124,
- /* 1770 */ 130, 59, 23, 1, 130, 277, 277, 130, 36, 70,
- /* 1780 */ 130, 277, 277, 71, 277, 277, 277, 78, 277, 277,
- /* 1790 */ 81, 277, 277, 277, 277, 277, 277, 88, 277, 277,
- /* 1800 */ 277, 59, 90, 277, 277, 277, 277, 277, 96, 97,
- /* 1810 */ 277, 277, 277, 71, 277, 103, 277, 105, 106, 107,
- /* 1820 */ 277, 277, 110, 277, 277, 277, 277, 277, 277, 277,
- /* 1830 */ 277, 122, 90, 277, 277, 277, 127, 128, 96, 97,
- /* 1840 */ 277, 277, 277, 277, 277, 103, 277, 105, 106, 107,
- /* 1850 */ 277, 277, 110, 141, 142, 143, 144, 145, 277, 150,
- /* 1860 */ 277, 277, 277, 5, 277, 277, 277, 277, 10, 11,
- /* 1870 */ 12, 13, 14, 277, 277, 17, 277, 277, 277, 277,
- /* 1880 */ 277, 277, 277, 141, 142, 143, 144, 145, 30, 277,
- /* 1890 */ 32, 277, 277, 277, 277, 277, 277, 277, 40, 277,
- /* 1900 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 1910 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 1920 */ 277, 277, 277, 277, 277, 277, 277, 277, 70, 277,
- /* 1930 */ 277, 277, 277, 277, 277, 277, 78, 277, 277, 81,
- /* 1940 */ 277, 277, 277, 277, 277, 277, 88, 277, 277, 277,
- /* 1950 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 1960 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 1970 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 1980 */ 122, 277, 277, 277, 277, 127, 128, 277, 277, 277,
- /* 1990 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 2000 */ 277, 277, 277, 277, 277, 277, 277, 277, 150, 277,
- /* 2010 */ 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ /* 1380 */ 210, 213, 222, 59, 222, 222, 182, 213, 213, 196,
+ /* 1390 */ 257, 226, 226, 19, 20, 71, 22, 257, 188, 187,
+ /* 1400 */ 192, 212, 187, 187, 226, 81, 210, 166, 60, 261,
+ /* 1410 */ 36, 244, 130, 170, 90, 170, 38, 170, 139, 104,
+ /* 1420 */ 96, 97, 48, 236, 22, 235, 43, 103, 201, 105,
+ /* 1430 */ 106, 107, 138, 59, 110, 247, 213, 18, 204, 258,
+ /* 1440 */ 204, 258, 204, 204, 170, 71, 18, 169, 213, 236,
+ /* 1450 */ 213, 127, 128, 235, 201, 201, 82, 170, 169, 213,
+ /* 1460 */ 146, 87, 62, 254, 90, 141, 142, 143, 144, 145,
+ /* 1470 */ 96, 97, 253, 170, 169, 22, 170, 103, 169, 105,
+ /* 1480 */ 106, 107, 189, 170, 110, 169, 189, 186, 19, 20,
+ /* 1490 */ 104, 22, 194, 186, 186, 64, 115, 186, 194, 189,
+ /* 1500 */ 188, 102, 133, 186, 186, 36, 186, 104, 189, 19,
+ /* 1510 */ 20, 246, 22, 246, 189, 141, 142, 143, 144, 145,
+ /* 1520 */ 0, 1, 2, 228, 228, 5, 36, 227, 59, 227,
+ /* 1530 */ 10, 11, 12, 13, 14, 170, 84, 17, 134, 216,
+ /* 1540 */ 71, 272, 270, 22, 137, 217, 22, 216, 227, 59,
+ /* 1550 */ 30, 82, 32, 217, 228, 228, 87, 227, 170, 90,
+ /* 1560 */ 40, 71, 146, 241, 215, 96, 97, 214, 136, 135,
+ /* 1570 */ 213, 25, 103, 26, 105, 106, 107, 243, 173, 110,
+ /* 1580 */ 90, 172, 13, 6, 164, 164, 96, 97, 98, 162,
+ /* 1590 */ 70, 162, 162, 103, 176, 105, 106, 107, 78, 267,
+ /* 1600 */ 110, 81, 267, 264, 182, 182, 182, 182, 88, 176,
+ /* 1610 */ 141, 142, 143, 144, 145, 176, 190, 4, 182, 182,
+ /* 1620 */ 182, 19, 20, 182, 22, 190, 3, 22, 151, 15,
+ /* 1630 */ 89, 141, 142, 143, 144, 145, 16, 128, 36, 23,
+ /* 1640 */ 23, 139, 122, 24, 119, 131, 20, 127, 128, 133,
+ /* 1650 */ 16, 1, 140, 131, 119, 61, 139, 53, 37, 53,
+ /* 1660 */ 53, 59, 53, 119, 105, 34, 130, 1, 5, 22,
+ /* 1670 */ 150, 104, 149, 71, 26, 75, 68, 41, 68, 130,
+ /* 1680 */ 104, 24, 20, 19, 82, 120, 114, 22, 28, 87,
+ /* 1690 */ 22, 67, 90, 22, 67, 23, 22, 22, 96, 97,
+ /* 1700 */ 67, 23, 138, 22, 37, 103, 153, 105, 106, 107,
+ /* 1710 */ 1, 2, 110, 23, 5, 23, 23, 26, 22, 10,
+ /* 1720 */ 11, 12, 13, 14, 24, 23, 17, 22, 24, 130,
+ /* 1730 */ 23, 19, 20, 23, 22, 105, 22, 34, 85, 30,
+ /* 1740 */ 34, 32, 26, 141, 142, 143, 144, 145, 36, 40,
+ /* 1750 */ 132, 34, 75, 83, 23, 44, 24, 34, 23, 26,
+ /* 1760 */ 26, 19, 20, 23, 22, 26, 23, 23, 23, 23,
+ /* 1770 */ 22, 59, 11, 22, 22, 26, 23, 23, 36, 70,
+ /* 1780 */ 22, 22, 124, 71, 130, 130, 130, 78, 23, 130,
+ /* 1790 */ 81, 15, 1, 278, 278, 278, 278, 88, 278, 278,
+ /* 1800 */ 278, 59, 90, 278, 278, 278, 278, 278, 96, 97,
+ /* 1810 */ 278, 278, 278, 71, 278, 103, 278, 105, 106, 107,
+ /* 1820 */ 278, 278, 110, 278, 278, 278, 278, 278, 278, 278,
+ /* 1830 */ 278, 122, 90, 278, 278, 278, 127, 128, 96, 97,
+ /* 1840 */ 278, 278, 278, 278, 278, 103, 278, 105, 106, 107,
+ /* 1850 */ 278, 278, 110, 141, 142, 143, 144, 145, 278, 150,
+ /* 1860 */ 278, 278, 278, 5, 278, 278, 278, 278, 10, 11,
+ /* 1870 */ 12, 13, 14, 278, 278, 17, 278, 278, 278, 278,
+ /* 1880 */ 278, 278, 278, 141, 142, 143, 144, 145, 30, 278,
+ /* 1890 */ 32, 278, 278, 278, 278, 278, 278, 278, 40, 278,
+ /* 1900 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
+ /* 1910 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
+ /* 1920 */ 278, 278, 278, 278, 278, 278, 278, 278, 70, 278,
+ /* 1930 */ 278, 278, 278, 278, 278, 278, 78, 278, 278, 81,
+ /* 1940 */ 278, 278, 278, 278, 278, 278, 88, 278, 278, 278,
+ /* 1950 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
+ /* 1960 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
+ /* 1970 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
+ /* 1980 */ 122, 278, 278, 278, 278, 127, 128, 278, 278, 278,
+ /* 1990 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
+ /* 2000 */ 278, 278, 278, 278, 278, 278, 278, 278, 150, 278,
+ /* 2010 */ 278, 278, 278, 278, 278, 278, 278, 278, 278,
};
-#define YY_SHIFT_COUNT (520)
+#define YY_SHIFT_COUNT (523)
#define YY_SHIFT_MIN (0)
#define YY_SHIFT_MAX (1858)
static const unsigned short int yy_shift_ofst[] = {
- /* 0 */ 1709, 1520, 1858, 1324, 1324, 277, 1374, 1469, 1602, 1712,
- /* 10 */ 1712, 1712, 273, 0, 0, 113, 1016, 1712, 1712, 1712,
- /* 20 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 11, 11, 236,
- /* 30 */ 184, 277, 277, 277, 277, 277, 277, 93, 177, 270,
+ /* 0 */ 1709, 1520, 1858, 1324, 1324, 24, 1374, 1469, 1602, 1712,
+ /* 10 */ 1712, 1712, 271, 0, 0, 113, 1016, 1712, 1712, 1712,
+ /* 20 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 12, 12, 409,
+ /* 30 */ 596, 24, 24, 24, 24, 24, 24, 93, 177, 270,
/* 40 */ 363, 456, 549, 642, 735, 828, 848, 996, 1144, 1016,
/* 50 */ 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016,
- /* 60 */ 1016, 1016, 1016, 1016, 1016, 1016, 1164, 1016, 1257, 1277,
- /* 70 */ 1277, 1490, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
+ /* 60 */ 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1164, 1016, 1257,
+ /* 70 */ 1277, 1277, 1490, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
/* 80 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
/* 90 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
- /* 100 */ 1712, 1712, 1712, 1742, 1712, 1712, 1712, 1712, 1712, 1712,
- /* 110 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 143, 162, 162,
- /* 120 */ 162, 162, 162, 204, 151, 416, 531, 648, 700, 531,
- /* 130 */ 486, 486, 531, 353, 353, 353, 353, 409, 279, 53,
- /* 140 */ 2009, 2009, 331, 331, 331, 329, 366, 329, 329, 597,
- /* 150 */ 597, 464, 474, 262, 681, 531, 531, 531, 531, 531,
- /* 160 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531,
- /* 170 */ 531, 531, 531, 531, 531, 531, 531, 173, 485, 984,
- /* 180 */ 984, 576, 485, 19, 1022, 2009, 2009, 2009, 387, 250,
- /* 190 */ 250, 525, 502, 278, 552, 227, 480, 566, 531, 531,
- /* 200 */ 531, 531, 531, 531, 531, 531, 531, 531, 639, 531,
- /* 210 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531,
- /* 220 */ 531, 2, 2, 2, 531, 531, 531, 531, 782, 531,
- /* 230 */ 531, 531, 744, 531, 531, 783, 531, 531, 531, 531,
- /* 240 */ 531, 531, 531, 531, 419, 682, 327, 370, 370, 370,
- /* 250 */ 370, 1029, 327, 327, 1024, 897, 856, 947, 1109, 706,
- /* 260 */ 706, 1143, 1109, 1109, 1143, 842, 945, 1118, 1136, 1136,
- /* 270 */ 1136, 706, 676, 400, 1047, 694, 1339, 1270, 1270, 1366,
- /* 280 */ 1366, 1270, 1305, 1389, 1369, 1278, 1401, 1401, 1401, 1401,
- /* 290 */ 1270, 1414, 1278, 1278, 1305, 1389, 1369, 1369, 1278, 1270,
- /* 300 */ 1414, 1298, 1385, 1270, 1414, 1432, 1270, 1414, 1270, 1414,
- /* 310 */ 1432, 1355, 1355, 1355, 1411, 1432, 1355, 1367, 1355, 1411,
- /* 320 */ 1355, 1355, 1432, 1392, 1392, 1432, 1365, 1396, 1365, 1396,
- /* 330 */ 1365, 1396, 1365, 1396, 1270, 1372, 1429, 1502, 1390, 1372,
- /* 340 */ 1517, 1270, 1397, 1390, 1410, 1413, 1278, 1528, 1532, 1549,
- /* 350 */ 1549, 1562, 1562, 1562, 2009, 2009, 2009, 2009, 2009, 2009,
+ /* 100 */ 1712, 1712, 1712, 1712, 1712, 1742, 1712, 1712, 1712, 1712,
+ /* 110 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 143,
+ /* 120 */ 162, 162, 162, 162, 162, 204, 151, 186, 650, 690,
+ /* 130 */ 327, 650, 261, 261, 650, 722, 722, 722, 722, 373,
+ /* 140 */ 33, 2, 2009, 2009, 330, 330, 330, 346, 289, 278,
+ /* 150 */ 289, 289, 517, 517, 459, 510, 15, 799, 650, 650,
+ /* 160 */ 650, 650, 650, 650, 650, 650, 650, 650, 650, 650,
+ /* 170 */ 650, 650, 650, 650, 650, 650, 650, 650, 650, 650,
+ /* 180 */ 331, 365, 995, 995, 265, 365, 50, 1038, 2009, 2009,
+ /* 190 */ 2009, 433, 250, 250, 504, 314, 429, 518, 522, 526,
+ /* 200 */ 561, 650, 650, 650, 650, 650, 650, 650, 650, 650,
+ /* 210 */ 192, 650, 650, 650, 650, 650, 650, 650, 650, 650,
+ /* 220 */ 650, 650, 650, 641, 641, 641, 650, 650, 650, 650,
+ /* 230 */ 800, 650, 650, 650, 830, 650, 650, 782, 650, 650,
+ /* 240 */ 650, 650, 650, 650, 650, 650, 739, 902, 689, 895,
+ /* 250 */ 895, 895, 895, 736, 689, 689, 885, 445, 903, 1124,
+ /* 260 */ 945, 748, 748, 1066, 945, 945, 1066, 447, 1002, 293,
+ /* 270 */ 1195, 1195, 1195, 748, 740, 727, 460, 1157, 1348, 1282,
+ /* 280 */ 1282, 1378, 1378, 1282, 1279, 1315, 1402, 1383, 1294, 1419,
+ /* 290 */ 1419, 1419, 1419, 1282, 1428, 1294, 1294, 1315, 1402, 1383,
+ /* 300 */ 1383, 1294, 1282, 1428, 1314, 1400, 1282, 1428, 1453, 1282,
+ /* 310 */ 1428, 1282, 1428, 1453, 1386, 1386, 1386, 1431, 1453, 1386,
+ /* 320 */ 1381, 1386, 1431, 1386, 1386, 1453, 1399, 1399, 1453, 1369,
+ /* 330 */ 1403, 1369, 1403, 1369, 1403, 1369, 1403, 1282, 1404, 1452,
+ /* 340 */ 1521, 1407, 1404, 1524, 1282, 1416, 1407, 1432, 1434, 1294,
+ /* 350 */ 1546, 1547, 1569, 1569, 1577, 1577, 1577, 2009, 2009, 2009,
/* 360 */ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
- /* 370 */ 570, 345, 686, 748, 50, 740, 1064, 1107, 469, 537,
- /* 380 */ 1042, 1146, 1162, 1154, 1201, 1202, 1203, 1208, 1209, 1127,
- /* 390 */ 1069, 1196, 1157, 1147, 1226, 1228, 1245, 775, 868, 1246,
- /* 400 */ 1247, 1191, 1151, 1585, 1589, 1587, 1456, 1600, 1527, 1601,
- /* 410 */ 1595, 1596, 1492, 1484, 1506, 1603, 1495, 1608, 1496, 1614,
- /* 420 */ 1635, 1508, 1497, 1521, 1580, 1606, 1505, 1592, 1593, 1597,
- /* 430 */ 1598, 1530, 1547, 1619, 1524, 1654, 1651, 1636, 1553, 1510,
- /* 440 */ 1594, 1634, 1599, 1588, 1623, 1535, 1564, 1642, 1649, 1652,
- /* 450 */ 1552, 1560, 1653, 1609, 1655, 1656, 1657, 1659, 1612, 1658,
- /* 460 */ 1660, 1616, 1648, 1664, 1550, 1668, 1538, 1670, 1671, 1669,
- /* 470 */ 1673, 1675, 1676, 1678, 1680, 1679, 1574, 1683, 1690, 1610,
- /* 480 */ 1682, 1695, 1586, 1698, 1691, 1698, 1693, 1643, 1661, 1646,
- /* 490 */ 1686, 1710, 1711, 1714, 1716, 1703, 1715, 1698, 1727, 1728,
- /* 500 */ 1729, 1730, 1731, 1732, 1734, 1743, 1736, 1737, 1740, 1744,
- /* 510 */ 1738, 1746, 1739, 1645, 1640, 1644, 1647, 1650, 1749, 1751,
- /* 520 */ 1772,
+ /* 370 */ 2009, 2009, 2009, 591, 697, 1059, 1139, 1058, 797, 465,
+ /* 380 */ 1159, 1182, 1122, 1062, 1180, 936, 1199, 1201, 1205, 1224,
+ /* 390 */ 1225, 1244, 1061, 1145, 1261, 1161, 1194, 1249, 1251, 1256,
+ /* 400 */ 1137, 1142, 1263, 1264, 1214, 1207, 1613, 1623, 1605, 1477,
+ /* 410 */ 1614, 1541, 1620, 1616, 1617, 1509, 1502, 1525, 1619, 1514,
+ /* 420 */ 1626, 1516, 1634, 1650, 1522, 1512, 1535, 1594, 1621, 1517,
+ /* 430 */ 1604, 1606, 1607, 1609, 1544, 1559, 1631, 1536, 1666, 1663,
+ /* 440 */ 1647, 1567, 1523, 1608, 1648, 1610, 1600, 1636, 1549, 1576,
+ /* 450 */ 1657, 1662, 1664, 1565, 1572, 1665, 1624, 1668, 1671, 1672,
+ /* 460 */ 1674, 1627, 1660, 1675, 1633, 1667, 1678, 1564, 1681, 1553,
+ /* 470 */ 1690, 1692, 1691, 1693, 1696, 1700, 1702, 1705, 1704, 1599,
+ /* 480 */ 1707, 1710, 1630, 1703, 1714, 1618, 1716, 1706, 1716, 1717,
+ /* 490 */ 1653, 1677, 1670, 1711, 1731, 1732, 1733, 1734, 1723, 1735,
+ /* 500 */ 1716, 1740, 1743, 1744, 1745, 1739, 1746, 1748, 1761, 1751,
+ /* 510 */ 1752, 1753, 1754, 1758, 1759, 1749, 1658, 1654, 1655, 1656,
+ /* 520 */ 1659, 1765, 1776, 1791,
};
-#define YY_REDUCE_COUNT (369)
-#define YY_REDUCE_MIN (-237)
-#define YY_REDUCE_MAX (1424)
+#define YY_REDUCE_COUNT (372)
+#define YY_REDUCE_MIN (-235)
+#define YY_REDUCE_MAX (1441)
static const short yy_reduce_ofst[] = {
- /* 0 */ -147, 171, 263, -96, 358, -144, -149, -102, 124, -156,
- /* 10 */ -98, 305, 401, -57, 209, -237, 245, -94, -79, 189,
- /* 20 */ 375, 490, 493, 378, 303, 539, 542, 501, 503, 554,
- /* 30 */ 415, 526, 546, 557, 587, 593, 595, -234, -234, -234,
- /* 40 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
- /* 50 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
- /* 60 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
- /* 70 */ -234, -50, 335, 470, 633, 656, 658, 660, 675, 685,
- /* 80 */ 703, 727, 747, 750, 752, 754, 770, 788, 790, 793,
- /* 90 */ 795, 797, 800, 802, 804, 806, 813, 820, 829, 833,
- /* 100 */ 836, 838, 843, 845, 847, 849, 873, 891, 893, 916,
- /* 110 */ 918, 921, 936, 941, 944, 956, 961, -234, -234, -234,
- /* 120 */ -234, -234, -234, -234, -234, -234, 463, 607, -176, 14,
- /* 130 */ -139, 87, -137, 818, 925, 818, 925, 898, -234, -234,
- /* 140 */ -234, -234, -166, -166, -166, -130, -131, -82, -54, -180,
- /* 150 */ 364, 41, 513, 509, 509, 117, 500, 789, 796, 646,
- /* 160 */ 192, 291, 644, 798, 120, 807, 543, 911, 920, 652,
- /* 170 */ 924, 922, 232, 698, 801, 971, 39, 220, 731, 442,
- /* 180 */ 902, -199, 979, -43, 421, 896, 942, 605, -184, -126,
- /* 190 */ 155, 172, 281, 304, 377, 538, 650, 690, 699, 723,
- /* 200 */ 803, 839, 853, 919, 991, 1018, 1067, 1092, 951, 1111,
- /* 210 */ 1112, 1115, 1116, 1117, 1119, 1120, 1121, 1122, 1123, 1124,
- /* 220 */ 1125, 1012, 1096, 1097, 1128, 1129, 1130, 1131, 1070, 1135,
- /* 230 */ 1137, 1152, 1077, 1153, 1155, 1114, 1156, 304, 1158, 1172,
- /* 240 */ 1173, 1174, 1175, 1176, 1089, 1091, 1133, 1098, 1126, 1139,
- /* 250 */ 1140, 1070, 1133, 1133, 1170, 1163, 1186, 1103, 1168, 1138,
- /* 260 */ 1141, 1110, 1169, 1171, 1132, 1177, 1189, 1194, 1181, 1200,
- /* 270 */ 1204, 1166, 1145, 1178, 1187, 1232, 1142, 1231, 1233, 1149,
- /* 280 */ 1150, 1238, 1179, 1182, 1212, 1205, 1219, 1220, 1221, 1222,
- /* 290 */ 1258, 1266, 1223, 1224, 1206, 1211, 1237, 1239, 1230, 1269,
- /* 300 */ 1272, 1195, 1197, 1280, 1284, 1268, 1285, 1289, 1290, 1293,
- /* 310 */ 1274, 1286, 1287, 1288, 1282, 1294, 1292, 1297, 1300, 1296,
- /* 320 */ 1301, 1306, 1304, 1249, 1250, 1308, 1271, 1275, 1273, 1276,
- /* 330 */ 1279, 1281, 1283, 1302, 1334, 1307, 1243, 1267, 1318, 1322,
- /* 340 */ 1303, 1371, 1299, 1328, 1332, 1340, 1342, 1384, 1391, 1400,
- /* 350 */ 1403, 1407, 1408, 1409, 1311, 1312, 1310, 1405, 1402, 1412,
- /* 360 */ 1417, 1420, 1406, 1393, 1395, 1421, 1422, 1423, 1424, 1415,
+ /* 0 */ -147, 171, 263, -96, 169, -144, -162, -149, -102, -156,
+ /* 10 */ -98, 216, 354, -170, -57, -235, 307, 149, 423, 428,
+ /* 20 */ 471, 313, 451, 519, 489, 496, 499, 545, 547, 555,
+ /* 30 */ -116, 540, 558, 592, 594, 597, 599, -206, -206, -206,
+ /* 40 */ -206, -206, -206, -206, -206, -206, -206, -206, -206, -206,
+ /* 50 */ -206, -206, -206, -206, -206, -206, -206, -206, -206, -206,
+ /* 60 */ -206, -206, -206, -206, -206, -206, -206, -206, -206, -206,
+ /* 70 */ -206, -206, 196, 309, 494, 537, 612, 656, 675, 679,
+ /* 80 */ 681, 685, 724, 753, 771, 776, 788, 790, 794, 796,
+ /* 90 */ 801, 803, 805, 807, 814, 819, 833, 837, 839, 842,
+ /* 100 */ 845, 847, 849, 853, 873, 891, 893, 917, 921, 937,
+ /* 110 */ 940, 944, 956, 960, 967, 969, 971, 973, 975, -206,
+ /* 120 */ -206, -206, -206, -206, -206, -206, -206, -206, 501, -168,
+ /* 130 */ 90, -97, 87, 112, 303, 277, 601, 277, 601, 179,
+ /* 140 */ -206, -206, -206, -206, -107, -107, -107, -43, -56, 323,
+ /* 150 */ 500, 512, -187, -177, 317, 609, 353, 353, 120, 144,
+ /* 160 */ 490, 539, 698, 374, 467, 507, 789, 404, -157, 755,
+ /* 170 */ 856, 916, 843, 941, 802, 770, 923, 821, 1001, -142,
+ /* 180 */ 264, 785, 896, 905, 899, 949, -176, 544, 911, 953,
+ /* 190 */ 1012, -182, -59, -30, 16, -22, 117, 172, 291, 369,
+ /* 200 */ 407, 415, 566, 586, 647, 699, 754, 813, 850, 892,
+ /* 210 */ 121, 1023, 1042, 1086, 1121, 1125, 1128, 1129, 1130, 1131,
+ /* 220 */ 1132, 1134, 1135, 284, 1106, 1123, 1152, 1154, 1155, 1156,
+ /* 230 */ 397, 1158, 1172, 1173, 1116, 1176, 1177, 1138, 1179, 117,
+ /* 240 */ 1184, 1185, 1198, 1200, 1202, 1203, 741, 1094, 1153, 1146,
+ /* 250 */ 1160, 1162, 1163, 397, 1153, 1153, 1170, 1204, 1206, 1103,
+ /* 260 */ 1168, 1165, 1166, 1133, 1174, 1175, 1140, 1210, 1193, 1208,
+ /* 270 */ 1212, 1215, 1216, 1178, 1167, 1189, 1196, 1241, 1148, 1243,
+ /* 280 */ 1245, 1181, 1183, 1247, 1188, 1187, 1190, 1227, 1223, 1234,
+ /* 290 */ 1236, 1238, 1239, 1274, 1278, 1235, 1237, 1213, 1218, 1253,
+ /* 300 */ 1254, 1246, 1287, 1289, 1209, 1219, 1303, 1305, 1293, 1306,
+ /* 310 */ 1309, 1313, 1316, 1297, 1301, 1307, 1308, 1298, 1310, 1311,
+ /* 320 */ 1312, 1317, 1304, 1318, 1320, 1319, 1265, 1267, 1325, 1295,
+ /* 330 */ 1300, 1296, 1302, 1326, 1321, 1327, 1330, 1365, 1323, 1269,
+ /* 340 */ 1272, 1328, 1331, 1322, 1388, 1334, 1336, 1349, 1353, 1357,
+ /* 350 */ 1405, 1409, 1420, 1421, 1427, 1429, 1430, 1332, 1335, 1339,
+ /* 360 */ 1418, 1422, 1423, 1424, 1425, 1433, 1426, 1435, 1436, 1437,
+ /* 370 */ 1438, 1441, 1439,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 1492, 1492, 1492, 1340, 1123, 1229, 1123, 1123, 1123, 1340,
- /* 10 */ 1340, 1340, 1123, 1259, 1259, 1391, 1154, 1123, 1123, 1123,
- /* 20 */ 1123, 1123, 1123, 1123, 1339, 1123, 1123, 1123, 1123, 1123,
- /* 30 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1265, 1123,
- /* 40 */ 1123, 1123, 1123, 1123, 1341, 1342, 1123, 1123, 1123, 1390,
- /* 50 */ 1392, 1275, 1274, 1273, 1272, 1373, 1246, 1270, 1263, 1267,
- /* 60 */ 1335, 1336, 1334, 1338, 1342, 1341, 1123, 1266, 1306, 1320,
- /* 70 */ 1305, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 80 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 90 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 100 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 110 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1314, 1319, 1325,
- /* 120 */ 1318, 1315, 1308, 1307, 1309, 1310, 1123, 1144, 1193, 1123,
- /* 130 */ 1123, 1123, 1123, 1409, 1408, 1123, 1123, 1154, 1311, 1312,
- /* 140 */ 1322, 1321, 1398, 1448, 1447, 1123, 1123, 1123, 1123, 1123,
- /* 150 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 160 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 170 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1154, 1150, 1300,
- /* 180 */ 1299, 1418, 1150, 1253, 1123, 1404, 1229, 1220, 1123, 1123,
- /* 190 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 200 */ 1123, 1395, 1393, 1123, 1355, 1123, 1123, 1123, 1123, 1123,
- /* 210 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 220 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 230 */ 1123, 1123, 1225, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 240 */ 1123, 1123, 1123, 1442, 1123, 1368, 1207, 1225, 1225, 1225,
- /* 250 */ 1225, 1227, 1208, 1206, 1219, 1154, 1130, 1484, 1269, 1248,
- /* 260 */ 1248, 1481, 1269, 1269, 1481, 1168, 1462, 1165, 1259, 1259,
- /* 270 */ 1259, 1248, 1337, 1226, 1219, 1123, 1484, 1234, 1234, 1483,
- /* 280 */ 1483, 1234, 1278, 1284, 1196, 1269, 1202, 1202, 1202, 1202,
- /* 290 */ 1234, 1141, 1269, 1269, 1278, 1284, 1196, 1196, 1269, 1234,
- /* 300 */ 1141, 1372, 1478, 1234, 1141, 1348, 1234, 1141, 1234, 1141,
- /* 310 */ 1348, 1194, 1194, 1194, 1183, 1348, 1194, 1168, 1194, 1183,
- /* 320 */ 1194, 1194, 1348, 1352, 1352, 1348, 1252, 1247, 1252, 1247,
- /* 330 */ 1252, 1247, 1252, 1247, 1234, 1253, 1417, 1123, 1264, 1253,
- /* 340 */ 1343, 1234, 1123, 1264, 1262, 1260, 1269, 1147, 1186, 1445,
- /* 350 */ 1445, 1441, 1441, 1441, 1489, 1489, 1404, 1457, 1154, 1154,
- /* 360 */ 1154, 1154, 1457, 1170, 1170, 1154, 1154, 1154, 1154, 1457,
- /* 370 */ 1123, 1123, 1123, 1123, 1123, 1123, 1452, 1123, 1357, 1238,
- /* 380 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 390 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 400 */ 1123, 1123, 1289, 1123, 1126, 1401, 1123, 1123, 1399, 1123,
- /* 410 */ 1123, 1123, 1123, 1123, 1123, 1239, 1123, 1123, 1123, 1123,
- /* 420 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 430 */ 1123, 1123, 1123, 1123, 1480, 1123, 1123, 1123, 1123, 1123,
- /* 440 */ 1123, 1371, 1370, 1123, 1123, 1236, 1123, 1123, 1123, 1123,
- /* 450 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 460 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 470 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 480 */ 1123, 1123, 1123, 1261, 1123, 1416, 1123, 1123, 1123, 1123,
- /* 490 */ 1123, 1123, 1123, 1430, 1254, 1123, 1123, 1471, 1123, 1123,
- /* 500 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 510 */ 1123, 1123, 1466, 1210, 1291, 1123, 1290, 1294, 1123, 1135,
- /* 520 */ 1123,
+ /* 0 */ 1500, 1500, 1500, 1346, 1129, 1235, 1129, 1129, 1129, 1346,
+ /* 10 */ 1346, 1346, 1129, 1265, 1265, 1399, 1160, 1129, 1129, 1129,
+ /* 20 */ 1129, 1129, 1129, 1129, 1345, 1129, 1129, 1129, 1129, 1129,
+ /* 30 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1271, 1129,
+ /* 40 */ 1129, 1129, 1129, 1129, 1347, 1348, 1129, 1129, 1129, 1398,
+ /* 50 */ 1400, 1363, 1281, 1280, 1279, 1278, 1381, 1252, 1276, 1269,
+ /* 60 */ 1273, 1341, 1342, 1340, 1344, 1348, 1347, 1129, 1272, 1312,
+ /* 70 */ 1326, 1311, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 80 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 90 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 100 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 110 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1320,
+ /* 120 */ 1325, 1331, 1324, 1321, 1314, 1313, 1315, 1316, 1129, 1150,
+ /* 130 */ 1199, 1129, 1129, 1129, 1129, 1417, 1416, 1129, 1129, 1160,
+ /* 140 */ 1317, 1318, 1328, 1327, 1406, 1456, 1455, 1364, 1129, 1129,
+ /* 150 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 160 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 170 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 180 */ 1160, 1156, 1306, 1305, 1426, 1156, 1259, 1129, 1412, 1235,
+ /* 190 */ 1226, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 200 */ 1129, 1129, 1129, 1129, 1403, 1401, 1129, 1129, 1129, 1129,
+ /* 210 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 220 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 230 */ 1129, 1129, 1129, 1129, 1231, 1129, 1129, 1129, 1129, 1129,
+ /* 240 */ 1129, 1129, 1129, 1129, 1129, 1450, 1129, 1376, 1213, 1231,
+ /* 250 */ 1231, 1231, 1231, 1233, 1214, 1212, 1225, 1160, 1136, 1492,
+ /* 260 */ 1275, 1254, 1254, 1489, 1275, 1275, 1489, 1174, 1470, 1171,
+ /* 270 */ 1265, 1265, 1265, 1254, 1343, 1232, 1225, 1129, 1492, 1240,
+ /* 280 */ 1240, 1491, 1491, 1240, 1364, 1284, 1290, 1202, 1275, 1208,
+ /* 290 */ 1208, 1208, 1208, 1240, 1147, 1275, 1275, 1284, 1290, 1202,
+ /* 300 */ 1202, 1275, 1240, 1147, 1380, 1486, 1240, 1147, 1354, 1240,
+ /* 310 */ 1147, 1240, 1147, 1354, 1200, 1200, 1200, 1189, 1354, 1200,
+ /* 320 */ 1174, 1200, 1189, 1200, 1200, 1354, 1358, 1358, 1354, 1258,
+ /* 330 */ 1253, 1258, 1253, 1258, 1253, 1258, 1253, 1240, 1259, 1425,
+ /* 340 */ 1129, 1270, 1259, 1349, 1240, 1129, 1270, 1268, 1266, 1275,
+ /* 350 */ 1153, 1192, 1453, 1453, 1449, 1449, 1449, 1497, 1497, 1412,
+ /* 360 */ 1465, 1160, 1160, 1160, 1160, 1465, 1176, 1176, 1160, 1160,
+ /* 370 */ 1160, 1160, 1465, 1129, 1129, 1129, 1129, 1129, 1129, 1460,
+ /* 380 */ 1129, 1365, 1244, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 390 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 400 */ 1129, 1129, 1129, 1129, 1129, 1295, 1129, 1132, 1409, 1129,
+ /* 410 */ 1129, 1407, 1129, 1129, 1129, 1129, 1129, 1129, 1245, 1129,
+ /* 420 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 430 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1488, 1129, 1129,
+ /* 440 */ 1129, 1129, 1129, 1129, 1379, 1378, 1129, 1129, 1242, 1129,
+ /* 450 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 460 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 470 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 480 */ 1129, 1129, 1129, 1129, 1129, 1129, 1267, 1129, 1424, 1129,
+ /* 490 */ 1129, 1129, 1129, 1129, 1129, 1129, 1438, 1260, 1129, 1129,
+ /* 500 */ 1479, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 510 */ 1129, 1129, 1129, 1129, 1129, 1474, 1216, 1297, 1129, 1296,
+ /* 520 */ 1300, 1129, 1141, 1129,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -148168,36 +148683,37 @@ static const char *const yyTokenName[] = {
/* 244 */ "case_else",
/* 245 */ "uniqueflag",
/* 246 */ "collate",
- /* 247 */ "nmnum",
- /* 248 */ "trigger_decl",
- /* 249 */ "trigger_cmd_list",
- /* 250 */ "trigger_time",
- /* 251 */ "trigger_event",
- /* 252 */ "foreach_clause",
- /* 253 */ "when_clause",
- /* 254 */ "trigger_cmd",
- /* 255 */ "trnm",
- /* 256 */ "tridxby",
- /* 257 */ "database_kw_opt",
- /* 258 */ "key_opt",
- /* 259 */ "add_column_fullname",
- /* 260 */ "kwcolumn_opt",
- /* 261 */ "create_vtab",
- /* 262 */ "vtabarglist",
- /* 263 */ "vtabarg",
- /* 264 */ "vtabargtoken",
- /* 265 */ "lp",
- /* 266 */ "anylist",
- /* 267 */ "windowdefn_list",
- /* 268 */ "windowdefn",
- /* 269 */ "window",
- /* 270 */ "frame_opt",
- /* 271 */ "part_opt",
- /* 272 */ "filter_opt",
- /* 273 */ "range_or_rows",
- /* 274 */ "frame_bound",
- /* 275 */ "frame_bound_s",
- /* 276 */ "frame_bound_e",
+ /* 247 */ "vinto",
+ /* 248 */ "nmnum",
+ /* 249 */ "trigger_decl",
+ /* 250 */ "trigger_cmd_list",
+ /* 251 */ "trigger_time",
+ /* 252 */ "trigger_event",
+ /* 253 */ "foreach_clause",
+ /* 254 */ "when_clause",
+ /* 255 */ "trigger_cmd",
+ /* 256 */ "trnm",
+ /* 257 */ "tridxby",
+ /* 258 */ "database_kw_opt",
+ /* 259 */ "key_opt",
+ /* 260 */ "add_column_fullname",
+ /* 261 */ "kwcolumn_opt",
+ /* 262 */ "create_vtab",
+ /* 263 */ "vtabarglist",
+ /* 264 */ "vtabarg",
+ /* 265 */ "vtabargtoken",
+ /* 266 */ "lp",
+ /* 267 */ "anylist",
+ /* 268 */ "windowdefn_list",
+ /* 269 */ "windowdefn",
+ /* 270 */ "window",
+ /* 271 */ "frame_opt",
+ /* 272 */ "part_opt",
+ /* 273 */ "filter_opt",
+ /* 274 */ "range_or_rows",
+ /* 275 */ "frame_bound",
+ /* 276 */ "frame_bound_s",
+ /* 277 */ "frame_bound_e",
};
#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
@@ -148434,144 +148950,146 @@ static const char *const yyRuleName[] = {
/* 226 */ "collate ::=",
/* 227 */ "collate ::= COLLATE ID|STRING",
/* 228 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 229 */ "cmd ::= VACUUM",
- /* 230 */ "cmd ::= VACUUM nm",
- /* 231 */ "cmd ::= PRAGMA nm dbnm",
- /* 232 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 233 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 234 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 235 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 236 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 237 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 238 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 239 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 240 */ "trigger_time ::= BEFORE|AFTER",
- /* 241 */ "trigger_time ::= INSTEAD OF",
- /* 242 */ "trigger_time ::=",
- /* 243 */ "trigger_event ::= DELETE|INSERT",
- /* 244 */ "trigger_event ::= UPDATE",
- /* 245 */ "trigger_event ::= UPDATE OF idlist",
- /* 246 */ "when_clause ::=",
- /* 247 */ "when_clause ::= WHEN expr",
- /* 248 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 249 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 250 */ "trnm ::= nm DOT nm",
- /* 251 */ "tridxby ::= INDEXED BY nm",
- /* 252 */ "tridxby ::= NOT INDEXED",
- /* 253 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt",
- /* 254 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
- /* 255 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
- /* 256 */ "trigger_cmd ::= scanpt select scanpt",
- /* 257 */ "expr ::= RAISE LP IGNORE RP",
- /* 258 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 259 */ "raisetype ::= ROLLBACK",
- /* 260 */ "raisetype ::= ABORT",
- /* 261 */ "raisetype ::= FAIL",
- /* 262 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 263 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 264 */ "cmd ::= DETACH database_kw_opt expr",
- /* 265 */ "key_opt ::=",
- /* 266 */ "key_opt ::= KEY expr",
- /* 267 */ "cmd ::= REINDEX",
- /* 268 */ "cmd ::= REINDEX nm dbnm",
- /* 269 */ "cmd ::= ANALYZE",
- /* 270 */ "cmd ::= ANALYZE nm dbnm",
- /* 271 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 272 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
- /* 273 */ "add_column_fullname ::= fullname",
- /* 274 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
- /* 275 */ "cmd ::= create_vtab",
- /* 276 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 277 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 278 */ "vtabarg ::=",
- /* 279 */ "vtabargtoken ::= ANY",
- /* 280 */ "vtabargtoken ::= lp anylist RP",
- /* 281 */ "lp ::= LP",
- /* 282 */ "with ::= WITH wqlist",
- /* 283 */ "with ::= WITH RECURSIVE wqlist",
- /* 284 */ "wqlist ::= nm eidlist_opt AS LP select RP",
- /* 285 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
- /* 286 */ "windowdefn_list ::= windowdefn",
- /* 287 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
- /* 288 */ "windowdefn ::= nm AS window",
- /* 289 */ "window ::= LP part_opt orderby_opt frame_opt RP",
- /* 290 */ "part_opt ::= PARTITION BY nexprlist",
- /* 291 */ "part_opt ::=",
- /* 292 */ "frame_opt ::=",
- /* 293 */ "frame_opt ::= range_or_rows frame_bound_s",
- /* 294 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e",
- /* 295 */ "range_or_rows ::= RANGE",
- /* 296 */ "range_or_rows ::= ROWS",
- /* 297 */ "frame_bound_s ::= frame_bound",
- /* 298 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
- /* 299 */ "frame_bound_e ::= frame_bound",
- /* 300 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
- /* 301 */ "frame_bound ::= expr PRECEDING",
- /* 302 */ "frame_bound ::= CURRENT ROW",
- /* 303 */ "frame_bound ::= expr FOLLOWING",
- /* 304 */ "window_clause ::= WINDOW windowdefn_list",
- /* 305 */ "over_clause ::= filter_opt OVER window",
- /* 306 */ "over_clause ::= filter_opt OVER nm",
- /* 307 */ "filter_opt ::=",
- /* 308 */ "filter_opt ::= FILTER LP WHERE expr RP",
- /* 309 */ "input ::= cmdlist",
- /* 310 */ "cmdlist ::= cmdlist ecmd",
- /* 311 */ "cmdlist ::= ecmd",
- /* 312 */ "ecmd ::= SEMI",
- /* 313 */ "ecmd ::= cmdx SEMI",
- /* 314 */ "ecmd ::= explain cmdx",
- /* 315 */ "trans_opt ::=",
- /* 316 */ "trans_opt ::= TRANSACTION",
- /* 317 */ "trans_opt ::= TRANSACTION nm",
- /* 318 */ "savepoint_opt ::= SAVEPOINT",
- /* 319 */ "savepoint_opt ::=",
- /* 320 */ "cmd ::= create_table create_table_args",
- /* 321 */ "columnlist ::= columnlist COMMA columnname carglist",
- /* 322 */ "columnlist ::= columnname carglist",
- /* 323 */ "nm ::= ID|INDEXED",
- /* 324 */ "nm ::= STRING",
- /* 325 */ "nm ::= JOIN_KW",
- /* 326 */ "typetoken ::= typename",
- /* 327 */ "typename ::= ID|STRING",
- /* 328 */ "signed ::= plus_num",
- /* 329 */ "signed ::= minus_num",
- /* 330 */ "carglist ::= carglist ccons",
- /* 331 */ "carglist ::=",
- /* 332 */ "ccons ::= NULL onconf",
- /* 333 */ "conslist_opt ::= COMMA conslist",
- /* 334 */ "conslist ::= conslist tconscomma tcons",
- /* 335 */ "conslist ::= tcons",
- /* 336 */ "tconscomma ::=",
- /* 337 */ "defer_subclause_opt ::= defer_subclause",
- /* 338 */ "resolvetype ::= raisetype",
- /* 339 */ "selectnowith ::= oneselect",
- /* 340 */ "oneselect ::= values",
- /* 341 */ "sclp ::= selcollist COMMA",
- /* 342 */ "as ::= ID|STRING",
- /* 343 */ "expr ::= term",
- /* 344 */ "likeop ::= LIKE_KW|MATCH",
- /* 345 */ "exprlist ::= nexprlist",
- /* 346 */ "nmnum ::= plus_num",
- /* 347 */ "nmnum ::= nm",
- /* 348 */ "nmnum ::= ON",
- /* 349 */ "nmnum ::= DELETE",
- /* 350 */ "nmnum ::= DEFAULT",
- /* 351 */ "plus_num ::= INTEGER|FLOAT",
- /* 352 */ "foreach_clause ::=",
- /* 353 */ "foreach_clause ::= FOR EACH ROW",
- /* 354 */ "trnm ::= nm",
- /* 355 */ "tridxby ::=",
- /* 356 */ "database_kw_opt ::= DATABASE",
- /* 357 */ "database_kw_opt ::=",
- /* 358 */ "kwcolumn_opt ::=",
- /* 359 */ "kwcolumn_opt ::= COLUMNKW",
- /* 360 */ "vtabarglist ::= vtabarg",
- /* 361 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 362 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 363 */ "anylist ::=",
- /* 364 */ "anylist ::= anylist LP anylist RP",
- /* 365 */ "anylist ::= anylist ANY",
- /* 366 */ "with ::=",
+ /* 229 */ "cmd ::= VACUUM vinto",
+ /* 230 */ "cmd ::= VACUUM nm vinto",
+ /* 231 */ "vinto ::= INTO expr",
+ /* 232 */ "vinto ::=",
+ /* 233 */ "cmd ::= PRAGMA nm dbnm",
+ /* 234 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 235 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 236 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 237 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 238 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 239 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 240 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 241 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 242 */ "trigger_time ::= BEFORE|AFTER",
+ /* 243 */ "trigger_time ::= INSTEAD OF",
+ /* 244 */ "trigger_time ::=",
+ /* 245 */ "trigger_event ::= DELETE|INSERT",
+ /* 246 */ "trigger_event ::= UPDATE",
+ /* 247 */ "trigger_event ::= UPDATE OF idlist",
+ /* 248 */ "when_clause ::=",
+ /* 249 */ "when_clause ::= WHEN expr",
+ /* 250 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 251 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 252 */ "trnm ::= nm DOT nm",
+ /* 253 */ "tridxby ::= INDEXED BY nm",
+ /* 254 */ "tridxby ::= NOT INDEXED",
+ /* 255 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt",
+ /* 256 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
+ /* 257 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
+ /* 258 */ "trigger_cmd ::= scanpt select scanpt",
+ /* 259 */ "expr ::= RAISE LP IGNORE RP",
+ /* 260 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 261 */ "raisetype ::= ROLLBACK",
+ /* 262 */ "raisetype ::= ABORT",
+ /* 263 */ "raisetype ::= FAIL",
+ /* 264 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 265 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 266 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 267 */ "key_opt ::=",
+ /* 268 */ "key_opt ::= KEY expr",
+ /* 269 */ "cmd ::= REINDEX",
+ /* 270 */ "cmd ::= REINDEX nm dbnm",
+ /* 271 */ "cmd ::= ANALYZE",
+ /* 272 */ "cmd ::= ANALYZE nm dbnm",
+ /* 273 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 274 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 275 */ "add_column_fullname ::= fullname",
+ /* 276 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
+ /* 277 */ "cmd ::= create_vtab",
+ /* 278 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 279 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 280 */ "vtabarg ::=",
+ /* 281 */ "vtabargtoken ::= ANY",
+ /* 282 */ "vtabargtoken ::= lp anylist RP",
+ /* 283 */ "lp ::= LP",
+ /* 284 */ "with ::= WITH wqlist",
+ /* 285 */ "with ::= WITH RECURSIVE wqlist",
+ /* 286 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 287 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+ /* 288 */ "windowdefn_list ::= windowdefn",
+ /* 289 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
+ /* 290 */ "windowdefn ::= nm AS window",
+ /* 291 */ "window ::= LP part_opt orderby_opt frame_opt RP",
+ /* 292 */ "part_opt ::= PARTITION BY nexprlist",
+ /* 293 */ "part_opt ::=",
+ /* 294 */ "frame_opt ::=",
+ /* 295 */ "frame_opt ::= range_or_rows frame_bound_s",
+ /* 296 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e",
+ /* 297 */ "range_or_rows ::= RANGE",
+ /* 298 */ "range_or_rows ::= ROWS",
+ /* 299 */ "frame_bound_s ::= frame_bound",
+ /* 300 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
+ /* 301 */ "frame_bound_e ::= frame_bound",
+ /* 302 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
+ /* 303 */ "frame_bound ::= expr PRECEDING",
+ /* 304 */ "frame_bound ::= CURRENT ROW",
+ /* 305 */ "frame_bound ::= expr FOLLOWING",
+ /* 306 */ "window_clause ::= WINDOW windowdefn_list",
+ /* 307 */ "over_clause ::= filter_opt OVER window",
+ /* 308 */ "over_clause ::= filter_opt OVER nm",
+ /* 309 */ "filter_opt ::=",
+ /* 310 */ "filter_opt ::= FILTER LP WHERE expr RP",
+ /* 311 */ "input ::= cmdlist",
+ /* 312 */ "cmdlist ::= cmdlist ecmd",
+ /* 313 */ "cmdlist ::= ecmd",
+ /* 314 */ "ecmd ::= SEMI",
+ /* 315 */ "ecmd ::= cmdx SEMI",
+ /* 316 */ "ecmd ::= explain cmdx",
+ /* 317 */ "trans_opt ::=",
+ /* 318 */ "trans_opt ::= TRANSACTION",
+ /* 319 */ "trans_opt ::= TRANSACTION nm",
+ /* 320 */ "savepoint_opt ::= SAVEPOINT",
+ /* 321 */ "savepoint_opt ::=",
+ /* 322 */ "cmd ::= create_table create_table_args",
+ /* 323 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 324 */ "columnlist ::= columnname carglist",
+ /* 325 */ "nm ::= ID|INDEXED",
+ /* 326 */ "nm ::= STRING",
+ /* 327 */ "nm ::= JOIN_KW",
+ /* 328 */ "typetoken ::= typename",
+ /* 329 */ "typename ::= ID|STRING",
+ /* 330 */ "signed ::= plus_num",
+ /* 331 */ "signed ::= minus_num",
+ /* 332 */ "carglist ::= carglist ccons",
+ /* 333 */ "carglist ::=",
+ /* 334 */ "ccons ::= NULL onconf",
+ /* 335 */ "conslist_opt ::= COMMA conslist",
+ /* 336 */ "conslist ::= conslist tconscomma tcons",
+ /* 337 */ "conslist ::= tcons",
+ /* 338 */ "tconscomma ::=",
+ /* 339 */ "defer_subclause_opt ::= defer_subclause",
+ /* 340 */ "resolvetype ::= raisetype",
+ /* 341 */ "selectnowith ::= oneselect",
+ /* 342 */ "oneselect ::= values",
+ /* 343 */ "sclp ::= selcollist COMMA",
+ /* 344 */ "as ::= ID|STRING",
+ /* 345 */ "expr ::= term",
+ /* 346 */ "likeop ::= LIKE_KW|MATCH",
+ /* 347 */ "exprlist ::= nexprlist",
+ /* 348 */ "nmnum ::= plus_num",
+ /* 349 */ "nmnum ::= nm",
+ /* 350 */ "nmnum ::= ON",
+ /* 351 */ "nmnum ::= DELETE",
+ /* 352 */ "nmnum ::= DEFAULT",
+ /* 353 */ "plus_num ::= INTEGER|FLOAT",
+ /* 354 */ "foreach_clause ::=",
+ /* 355 */ "foreach_clause ::= FOR EACH ROW",
+ /* 356 */ "trnm ::= nm",
+ /* 357 */ "tridxby ::=",
+ /* 358 */ "database_kw_opt ::= DATABASE",
+ /* 359 */ "database_kw_opt ::=",
+ /* 360 */ "kwcolumn_opt ::=",
+ /* 361 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 362 */ "vtabarglist ::= vtabarg",
+ /* 363 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 364 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 365 */ "anylist ::=",
+ /* 366 */ "anylist ::= anylist LP anylist RP",
+ /* 367 */ "anylist ::= anylist ANY",
+ /* 368 */ "with ::=",
};
#endif /* NDEBUG */
@@ -148702,7 +149220,7 @@ static void yy_destructor(
case 207: /* oneselect */
case 219: /* values */
{
-sqlite3SelectDelete(pParse->db, (yypminor->yy489));
+sqlite3SelectDelete(pParse->db, (yypminor->yy423));
}
break;
case 184: /* term */
@@ -148712,11 +149230,12 @@ sqlite3SelectDelete(pParse->db, (yypminor->yy489));
case 227: /* on_opt */
case 242: /* case_operand */
case 244: /* case_else */
- case 253: /* when_clause */
- case 258: /* key_opt */
- case 272: /* filter_opt */
+ case 247: /* vinto */
+ case 254: /* when_clause */
+ case 259: /* key_opt */
+ case 273: /* filter_opt */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy18));
+sqlite3ExprDelete(pParse->db, (yypminor->yy490));
}
break;
case 189: /* eidlist_opt */
@@ -148731,9 +149250,9 @@ sqlite3ExprDelete(pParse->db, (yypminor->yy18));
case 233: /* setlist */
case 241: /* paren_exprlist */
case 243: /* case_exprlist */
- case 271: /* part_opt */
+ case 272: /* part_opt */
{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy420));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy42));
}
break;
case 205: /* fullname */
@@ -148742,51 +149261,51 @@ sqlite3ExprListDelete(pParse->db, (yypminor->yy420));
case 224: /* stl_prefix */
case 230: /* xfullname */
{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy135));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy167));
}
break;
case 208: /* wqlist */
{
-sqlite3WithDelete(pParse->db, (yypminor->yy449));
+sqlite3WithDelete(pParse->db, (yypminor->yy499));
}
break;
case 218: /* window_clause */
- case 267: /* windowdefn_list */
+ case 268: /* windowdefn_list */
{
-sqlite3WindowListDelete(pParse->db, (yypminor->yy327));
+sqlite3WindowListDelete(pParse->db, (yypminor->yy147));
}
break;
case 228: /* using_opt */
case 231: /* idlist */
case 235: /* idlist_opt */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy48));
+sqlite3IdListDelete(pParse->db, (yypminor->yy336));
}
break;
case 237: /* over_clause */
- case 268: /* windowdefn */
- case 269: /* window */
- case 270: /* frame_opt */
+ case 269: /* windowdefn */
+ case 270: /* window */
+ case 271: /* frame_opt */
{
-sqlite3WindowDelete(pParse->db, (yypminor->yy327));
+sqlite3WindowDelete(pParse->db, (yypminor->yy147));
}
break;
- case 249: /* trigger_cmd_list */
- case 254: /* trigger_cmd */
+ case 250: /* trigger_cmd_list */
+ case 255: /* trigger_cmd */
{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy207));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy119));
}
break;
- case 251: /* trigger_event */
+ case 252: /* trigger_event */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy34).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy350).b);
}
break;
- case 274: /* frame_bound */
- case 275: /* frame_bound_s */
- case 276: /* frame_bound_e */
+ case 275: /* frame_bound */
+ case 276: /* frame_bound_s */
+ case 277: /* frame_bound_e */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy119).pExpr);
+sqlite3ExprDelete(pParse->db, (yypminor->yy317).pExpr);
}
break;
/********* End destructor definitions *****************************************/
@@ -149078,380 +149597,752 @@ static void yy_shift(
yyTraceShift(yypParser, yyNewState, "Shift");
}
-/* The following table contains information about every rule that
-** is used during the reduce.
-*/
-static const struct {
- YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
- signed char nrhs; /* Negative of the number of RHS symbols in the rule */
-} yyRuleInfo[] = {
- { 159, -1 }, /* (0) explain ::= EXPLAIN */
- { 159, -3 }, /* (1) explain ::= EXPLAIN QUERY PLAN */
- { 158, -1 }, /* (2) cmdx ::= cmd */
- { 160, -3 }, /* (3) cmd ::= BEGIN transtype trans_opt */
- { 161, 0 }, /* (4) transtype ::= */
- { 161, -1 }, /* (5) transtype ::= DEFERRED */
- { 161, -1 }, /* (6) transtype ::= IMMEDIATE */
- { 161, -1 }, /* (7) transtype ::= EXCLUSIVE */
- { 160, -2 }, /* (8) cmd ::= COMMIT|END trans_opt */
- { 160, -2 }, /* (9) cmd ::= ROLLBACK trans_opt */
- { 160, -2 }, /* (10) cmd ::= SAVEPOINT nm */
- { 160, -3 }, /* (11) cmd ::= RELEASE savepoint_opt nm */
- { 160, -5 }, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
- { 165, -6 }, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
- { 167, -1 }, /* (14) createkw ::= CREATE */
- { 169, 0 }, /* (15) ifnotexists ::= */
- { 169, -3 }, /* (16) ifnotexists ::= IF NOT EXISTS */
- { 168, -1 }, /* (17) temp ::= TEMP */
- { 168, 0 }, /* (18) temp ::= */
- { 166, -5 }, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
- { 166, -2 }, /* (20) create_table_args ::= AS select */
- { 173, 0 }, /* (21) table_options ::= */
- { 173, -2 }, /* (22) table_options ::= WITHOUT nm */
- { 175, -2 }, /* (23) columnname ::= nm typetoken */
- { 177, 0 }, /* (24) typetoken ::= */
- { 177, -4 }, /* (25) typetoken ::= typename LP signed RP */
- { 177, -6 }, /* (26) typetoken ::= typename LP signed COMMA signed RP */
- { 178, -2 }, /* (27) typename ::= typename ID|STRING */
- { 182, 0 }, /* (28) scanpt ::= */
- { 183, -2 }, /* (29) ccons ::= CONSTRAINT nm */
- { 183, -4 }, /* (30) ccons ::= DEFAULT scanpt term scanpt */
- { 183, -4 }, /* (31) ccons ::= DEFAULT LP expr RP */
- { 183, -4 }, /* (32) ccons ::= DEFAULT PLUS term scanpt */
- { 183, -4 }, /* (33) ccons ::= DEFAULT MINUS term scanpt */
- { 183, -3 }, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */
- { 183, -3 }, /* (35) ccons ::= NOT NULL onconf */
- { 183, -5 }, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */
- { 183, -2 }, /* (37) ccons ::= UNIQUE onconf */
- { 183, -4 }, /* (38) ccons ::= CHECK LP expr RP */
- { 183, -4 }, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */
- { 183, -1 }, /* (40) ccons ::= defer_subclause */
- { 183, -2 }, /* (41) ccons ::= COLLATE ID|STRING */
- { 188, 0 }, /* (42) autoinc ::= */
- { 188, -1 }, /* (43) autoinc ::= AUTOINCR */
- { 190, 0 }, /* (44) refargs ::= */
- { 190, -2 }, /* (45) refargs ::= refargs refarg */
- { 192, -2 }, /* (46) refarg ::= MATCH nm */
- { 192, -3 }, /* (47) refarg ::= ON INSERT refact */
- { 192, -3 }, /* (48) refarg ::= ON DELETE refact */
- { 192, -3 }, /* (49) refarg ::= ON UPDATE refact */
- { 193, -2 }, /* (50) refact ::= SET NULL */
- { 193, -2 }, /* (51) refact ::= SET DEFAULT */
- { 193, -1 }, /* (52) refact ::= CASCADE */
- { 193, -1 }, /* (53) refact ::= RESTRICT */
- { 193, -2 }, /* (54) refact ::= NO ACTION */
- { 191, -3 }, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
- { 191, -2 }, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- { 194, 0 }, /* (57) init_deferred_pred_opt ::= */
- { 194, -2 }, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */
- { 194, -2 }, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
- { 172, 0 }, /* (60) conslist_opt ::= */
- { 196, -1 }, /* (61) tconscomma ::= COMMA */
- { 197, -2 }, /* (62) tcons ::= CONSTRAINT nm */
- { 197, -7 }, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
- { 197, -5 }, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */
- { 197, -5 }, /* (65) tcons ::= CHECK LP expr RP onconf */
- { 197, -10 }, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
- { 200, 0 }, /* (67) defer_subclause_opt ::= */
- { 186, 0 }, /* (68) onconf ::= */
- { 186, -3 }, /* (69) onconf ::= ON CONFLICT resolvetype */
- { 201, 0 }, /* (70) orconf ::= */
- { 201, -2 }, /* (71) orconf ::= OR resolvetype */
- { 202, -1 }, /* (72) resolvetype ::= IGNORE */
- { 202, -1 }, /* (73) resolvetype ::= REPLACE */
- { 160, -4 }, /* (74) cmd ::= DROP TABLE ifexists fullname */
- { 204, -2 }, /* (75) ifexists ::= IF EXISTS */
- { 204, 0 }, /* (76) ifexists ::= */
- { 160, -9 }, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
- { 160, -4 }, /* (78) cmd ::= DROP VIEW ifexists fullname */
- { 160, -1 }, /* (79) cmd ::= select */
- { 174, -3 }, /* (80) select ::= WITH wqlist selectnowith */
- { 174, -4 }, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */
- { 174, -1 }, /* (82) select ::= selectnowith */
- { 206, -3 }, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */
- { 209, -1 }, /* (84) multiselect_op ::= UNION */
- { 209, -2 }, /* (85) multiselect_op ::= UNION ALL */
- { 209, -1 }, /* (86) multiselect_op ::= EXCEPT|INTERSECT */
- { 207, -9 }, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
- { 207, -10 }, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
- { 219, -4 }, /* (89) values ::= VALUES LP nexprlist RP */
- { 219, -5 }, /* (90) values ::= values COMMA LP nexprlist RP */
- { 210, -1 }, /* (91) distinct ::= DISTINCT */
- { 210, -1 }, /* (92) distinct ::= ALL */
- { 210, 0 }, /* (93) distinct ::= */
- { 221, 0 }, /* (94) sclp ::= */
- { 211, -5 }, /* (95) selcollist ::= sclp scanpt expr scanpt as */
- { 211, -3 }, /* (96) selcollist ::= sclp scanpt STAR */
- { 211, -5 }, /* (97) selcollist ::= sclp scanpt nm DOT STAR */
- { 222, -2 }, /* (98) as ::= AS nm */
- { 222, 0 }, /* (99) as ::= */
- { 212, 0 }, /* (100) from ::= */
- { 212, -2 }, /* (101) from ::= FROM seltablist */
- { 224, -2 }, /* (102) stl_prefix ::= seltablist joinop */
- { 224, 0 }, /* (103) stl_prefix ::= */
- { 223, -7 }, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
- { 223, -9 }, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
- { 223, -7 }, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
- { 223, -7 }, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
- { 170, 0 }, /* (108) dbnm ::= */
- { 170, -2 }, /* (109) dbnm ::= DOT nm */
- { 205, -1 }, /* (110) fullname ::= nm */
- { 205, -3 }, /* (111) fullname ::= nm DOT nm */
- { 230, -1 }, /* (112) xfullname ::= nm */
- { 230, -3 }, /* (113) xfullname ::= nm DOT nm */
- { 230, -5 }, /* (114) xfullname ::= nm DOT nm AS nm */
- { 230, -3 }, /* (115) xfullname ::= nm AS nm */
- { 225, -1 }, /* (116) joinop ::= COMMA|JOIN */
- { 225, -2 }, /* (117) joinop ::= JOIN_KW JOIN */
- { 225, -3 }, /* (118) joinop ::= JOIN_KW nm JOIN */
- { 225, -4 }, /* (119) joinop ::= JOIN_KW nm nm JOIN */
- { 227, -2 }, /* (120) on_opt ::= ON expr */
- { 227, 0 }, /* (121) on_opt ::= */
- { 226, 0 }, /* (122) indexed_opt ::= */
- { 226, -3 }, /* (123) indexed_opt ::= INDEXED BY nm */
- { 226, -2 }, /* (124) indexed_opt ::= NOT INDEXED */
- { 228, -4 }, /* (125) using_opt ::= USING LP idlist RP */
- { 228, 0 }, /* (126) using_opt ::= */
- { 216, 0 }, /* (127) orderby_opt ::= */
- { 216, -3 }, /* (128) orderby_opt ::= ORDER BY sortlist */
- { 198, -4 }, /* (129) sortlist ::= sortlist COMMA expr sortorder */
- { 198, -2 }, /* (130) sortlist ::= expr sortorder */
- { 187, -1 }, /* (131) sortorder ::= ASC */
- { 187, -1 }, /* (132) sortorder ::= DESC */
- { 187, 0 }, /* (133) sortorder ::= */
- { 214, 0 }, /* (134) groupby_opt ::= */
- { 214, -3 }, /* (135) groupby_opt ::= GROUP BY nexprlist */
- { 215, 0 }, /* (136) having_opt ::= */
- { 215, -2 }, /* (137) having_opt ::= HAVING expr */
- { 217, 0 }, /* (138) limit_opt ::= */
- { 217, -2 }, /* (139) limit_opt ::= LIMIT expr */
- { 217, -4 }, /* (140) limit_opt ::= LIMIT expr OFFSET expr */
- { 217, -4 }, /* (141) limit_opt ::= LIMIT expr COMMA expr */
- { 160, -6 }, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
- { 213, 0 }, /* (143) where_opt ::= */
- { 213, -2 }, /* (144) where_opt ::= WHERE expr */
- { 160, -8 }, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
- { 233, -5 }, /* (146) setlist ::= setlist COMMA nm EQ expr */
- { 233, -7 }, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */
- { 233, -3 }, /* (148) setlist ::= nm EQ expr */
- { 233, -5 }, /* (149) setlist ::= LP idlist RP EQ expr */
- { 160, -7 }, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
- { 160, -7 }, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
- { 236, 0 }, /* (152) upsert ::= */
- { 236, -11 }, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
- { 236, -8 }, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
- { 236, -4 }, /* (155) upsert ::= ON CONFLICT DO NOTHING */
- { 234, -2 }, /* (156) insert_cmd ::= INSERT orconf */
- { 234, -1 }, /* (157) insert_cmd ::= REPLACE */
- { 235, 0 }, /* (158) idlist_opt ::= */
- { 235, -3 }, /* (159) idlist_opt ::= LP idlist RP */
- { 231, -3 }, /* (160) idlist ::= idlist COMMA nm */
- { 231, -1 }, /* (161) idlist ::= nm */
- { 185, -3 }, /* (162) expr ::= LP expr RP */
- { 185, -1 }, /* (163) expr ::= ID|INDEXED */
- { 185, -1 }, /* (164) expr ::= JOIN_KW */
- { 185, -3 }, /* (165) expr ::= nm DOT nm */
- { 185, -5 }, /* (166) expr ::= nm DOT nm DOT nm */
- { 184, -1 }, /* (167) term ::= NULL|FLOAT|BLOB */
- { 184, -1 }, /* (168) term ::= STRING */
- { 184, -1 }, /* (169) term ::= INTEGER */
- { 185, -1 }, /* (170) expr ::= VARIABLE */
- { 185, -3 }, /* (171) expr ::= expr COLLATE ID|STRING */
- { 185, -6 }, /* (172) expr ::= CAST LP expr AS typetoken RP */
- { 185, -5 }, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */
- { 185, -4 }, /* (174) expr ::= ID|INDEXED LP STAR RP */
- { 185, -6 }, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
- { 185, -5 }, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */
- { 184, -1 }, /* (177) term ::= CTIME_KW */
- { 185, -5 }, /* (178) expr ::= LP nexprlist COMMA expr RP */
- { 185, -3 }, /* (179) expr ::= expr AND expr */
- { 185, -3 }, /* (180) expr ::= expr OR expr */
- { 185, -3 }, /* (181) expr ::= expr LT|GT|GE|LE expr */
- { 185, -3 }, /* (182) expr ::= expr EQ|NE expr */
- { 185, -3 }, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
- { 185, -3 }, /* (184) expr ::= expr PLUS|MINUS expr */
- { 185, -3 }, /* (185) expr ::= expr STAR|SLASH|REM expr */
- { 185, -3 }, /* (186) expr ::= expr CONCAT expr */
- { 238, -2 }, /* (187) likeop ::= NOT LIKE_KW|MATCH */
- { 185, -3 }, /* (188) expr ::= expr likeop expr */
- { 185, -5 }, /* (189) expr ::= expr likeop expr ESCAPE expr */
- { 185, -2 }, /* (190) expr ::= expr ISNULL|NOTNULL */
- { 185, -3 }, /* (191) expr ::= expr NOT NULL */
- { 185, -3 }, /* (192) expr ::= expr IS expr */
- { 185, -4 }, /* (193) expr ::= expr IS NOT expr */
- { 185, -2 }, /* (194) expr ::= NOT expr */
- { 185, -2 }, /* (195) expr ::= BITNOT expr */
- { 185, -2 }, /* (196) expr ::= PLUS|MINUS expr */
- { 239, -1 }, /* (197) between_op ::= BETWEEN */
- { 239, -2 }, /* (198) between_op ::= NOT BETWEEN */
- { 185, -5 }, /* (199) expr ::= expr between_op expr AND expr */
- { 240, -1 }, /* (200) in_op ::= IN */
- { 240, -2 }, /* (201) in_op ::= NOT IN */
- { 185, -5 }, /* (202) expr ::= expr in_op LP exprlist RP */
- { 185, -3 }, /* (203) expr ::= LP select RP */
- { 185, -5 }, /* (204) expr ::= expr in_op LP select RP */
- { 185, -5 }, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */
- { 185, -4 }, /* (206) expr ::= EXISTS LP select RP */
- { 185, -5 }, /* (207) expr ::= CASE case_operand case_exprlist case_else END */
- { 243, -5 }, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */
- { 243, -4 }, /* (209) case_exprlist ::= WHEN expr THEN expr */
- { 244, -2 }, /* (210) case_else ::= ELSE expr */
- { 244, 0 }, /* (211) case_else ::= */
- { 242, -1 }, /* (212) case_operand ::= expr */
- { 242, 0 }, /* (213) case_operand ::= */
- { 229, 0 }, /* (214) exprlist ::= */
- { 220, -3 }, /* (215) nexprlist ::= nexprlist COMMA expr */
- { 220, -1 }, /* (216) nexprlist ::= expr */
- { 241, 0 }, /* (217) paren_exprlist ::= */
- { 241, -3 }, /* (218) paren_exprlist ::= LP exprlist RP */
- { 160, -12 }, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
- { 245, -1 }, /* (220) uniqueflag ::= UNIQUE */
- { 245, 0 }, /* (221) uniqueflag ::= */
- { 189, 0 }, /* (222) eidlist_opt ::= */
- { 189, -3 }, /* (223) eidlist_opt ::= LP eidlist RP */
- { 199, -5 }, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */
- { 199, -3 }, /* (225) eidlist ::= nm collate sortorder */
- { 246, 0 }, /* (226) collate ::= */
- { 246, -2 }, /* (227) collate ::= COLLATE ID|STRING */
- { 160, -4 }, /* (228) cmd ::= DROP INDEX ifexists fullname */
- { 160, -1 }, /* (229) cmd ::= VACUUM */
- { 160, -2 }, /* (230) cmd ::= VACUUM nm */
- { 160, -3 }, /* (231) cmd ::= PRAGMA nm dbnm */
- { 160, -5 }, /* (232) cmd ::= PRAGMA nm dbnm EQ nmnum */
- { 160, -6 }, /* (233) cmd ::= PRAGMA nm dbnm LP nmnum RP */
- { 160, -5 }, /* (234) cmd ::= PRAGMA nm dbnm EQ minus_num */
- { 160, -6 }, /* (235) cmd ::= PRAGMA nm dbnm LP minus_num RP */
- { 180, -2 }, /* (236) plus_num ::= PLUS INTEGER|FLOAT */
- { 181, -2 }, /* (237) minus_num ::= MINUS INTEGER|FLOAT */
- { 160, -5 }, /* (238) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
- { 248, -11 }, /* (239) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
- { 250, -1 }, /* (240) trigger_time ::= BEFORE|AFTER */
- { 250, -2 }, /* (241) trigger_time ::= INSTEAD OF */
- { 250, 0 }, /* (242) trigger_time ::= */
- { 251, -1 }, /* (243) trigger_event ::= DELETE|INSERT */
- { 251, -1 }, /* (244) trigger_event ::= UPDATE */
- { 251, -3 }, /* (245) trigger_event ::= UPDATE OF idlist */
- { 253, 0 }, /* (246) when_clause ::= */
- { 253, -2 }, /* (247) when_clause ::= WHEN expr */
- { 249, -3 }, /* (248) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
- { 249, -2 }, /* (249) trigger_cmd_list ::= trigger_cmd SEMI */
- { 255, -3 }, /* (250) trnm ::= nm DOT nm */
- { 256, -3 }, /* (251) tridxby ::= INDEXED BY nm */
- { 256, -2 }, /* (252) tridxby ::= NOT INDEXED */
- { 254, -8 }, /* (253) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
- { 254, -8 }, /* (254) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
- { 254, -6 }, /* (255) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
- { 254, -3 }, /* (256) trigger_cmd ::= scanpt select scanpt */
- { 185, -4 }, /* (257) expr ::= RAISE LP IGNORE RP */
- { 185, -6 }, /* (258) expr ::= RAISE LP raisetype COMMA nm RP */
- { 203, -1 }, /* (259) raisetype ::= ROLLBACK */
- { 203, -1 }, /* (260) raisetype ::= ABORT */
- { 203, -1 }, /* (261) raisetype ::= FAIL */
- { 160, -4 }, /* (262) cmd ::= DROP TRIGGER ifexists fullname */
- { 160, -6 }, /* (263) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
- { 160, -3 }, /* (264) cmd ::= DETACH database_kw_opt expr */
- { 258, 0 }, /* (265) key_opt ::= */
- { 258, -2 }, /* (266) key_opt ::= KEY expr */
- { 160, -1 }, /* (267) cmd ::= REINDEX */
- { 160, -3 }, /* (268) cmd ::= REINDEX nm dbnm */
- { 160, -1 }, /* (269) cmd ::= ANALYZE */
- { 160, -3 }, /* (270) cmd ::= ANALYZE nm dbnm */
- { 160, -6 }, /* (271) cmd ::= ALTER TABLE fullname RENAME TO nm */
- { 160, -7 }, /* (272) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
- { 259, -1 }, /* (273) add_column_fullname ::= fullname */
- { 160, -8 }, /* (274) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
- { 160, -1 }, /* (275) cmd ::= create_vtab */
- { 160, -4 }, /* (276) cmd ::= create_vtab LP vtabarglist RP */
- { 261, -8 }, /* (277) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
- { 263, 0 }, /* (278) vtabarg ::= */
- { 264, -1 }, /* (279) vtabargtoken ::= ANY */
- { 264, -3 }, /* (280) vtabargtoken ::= lp anylist RP */
- { 265, -1 }, /* (281) lp ::= LP */
- { 232, -2 }, /* (282) with ::= WITH wqlist */
- { 232, -3 }, /* (283) with ::= WITH RECURSIVE wqlist */
- { 208, -6 }, /* (284) wqlist ::= nm eidlist_opt AS LP select RP */
- { 208, -8 }, /* (285) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
- { 267, -1 }, /* (286) windowdefn_list ::= windowdefn */
- { 267, -3 }, /* (287) windowdefn_list ::= windowdefn_list COMMA windowdefn */
- { 268, -3 }, /* (288) windowdefn ::= nm AS window */
- { 269, -5 }, /* (289) window ::= LP part_opt orderby_opt frame_opt RP */
- { 271, -3 }, /* (290) part_opt ::= PARTITION BY nexprlist */
- { 271, 0 }, /* (291) part_opt ::= */
- { 270, 0 }, /* (292) frame_opt ::= */
- { 270, -2 }, /* (293) frame_opt ::= range_or_rows frame_bound_s */
- { 270, -5 }, /* (294) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
- { 273, -1 }, /* (295) range_or_rows ::= RANGE */
- { 273, -1 }, /* (296) range_or_rows ::= ROWS */
- { 275, -1 }, /* (297) frame_bound_s ::= frame_bound */
- { 275, -2 }, /* (298) frame_bound_s ::= UNBOUNDED PRECEDING */
- { 276, -1 }, /* (299) frame_bound_e ::= frame_bound */
- { 276, -2 }, /* (300) frame_bound_e ::= UNBOUNDED FOLLOWING */
- { 274, -2 }, /* (301) frame_bound ::= expr PRECEDING */
- { 274, -2 }, /* (302) frame_bound ::= CURRENT ROW */
- { 274, -2 }, /* (303) frame_bound ::= expr FOLLOWING */
- { 218, -2 }, /* (304) window_clause ::= WINDOW windowdefn_list */
- { 237, -3 }, /* (305) over_clause ::= filter_opt OVER window */
- { 237, -3 }, /* (306) over_clause ::= filter_opt OVER nm */
- { 272, 0 }, /* (307) filter_opt ::= */
- { 272, -5 }, /* (308) filter_opt ::= FILTER LP WHERE expr RP */
- { 155, -1 }, /* (309) input ::= cmdlist */
- { 156, -2 }, /* (310) cmdlist ::= cmdlist ecmd */
- { 156, -1 }, /* (311) cmdlist ::= ecmd */
- { 157, -1 }, /* (312) ecmd ::= SEMI */
- { 157, -2 }, /* (313) ecmd ::= cmdx SEMI */
- { 157, -2 }, /* (314) ecmd ::= explain cmdx */
- { 162, 0 }, /* (315) trans_opt ::= */
- { 162, -1 }, /* (316) trans_opt ::= TRANSACTION */
- { 162, -2 }, /* (317) trans_opt ::= TRANSACTION nm */
- { 164, -1 }, /* (318) savepoint_opt ::= SAVEPOINT */
- { 164, 0 }, /* (319) savepoint_opt ::= */
- { 160, -2 }, /* (320) cmd ::= create_table create_table_args */
- { 171, -4 }, /* (321) columnlist ::= columnlist COMMA columnname carglist */
- { 171, -2 }, /* (322) columnlist ::= columnname carglist */
- { 163, -1 }, /* (323) nm ::= ID|INDEXED */
- { 163, -1 }, /* (324) nm ::= STRING */
- { 163, -1 }, /* (325) nm ::= JOIN_KW */
- { 177, -1 }, /* (326) typetoken ::= typename */
- { 178, -1 }, /* (327) typename ::= ID|STRING */
- { 179, -1 }, /* (328) signed ::= plus_num */
- { 179, -1 }, /* (329) signed ::= minus_num */
- { 176, -2 }, /* (330) carglist ::= carglist ccons */
- { 176, 0 }, /* (331) carglist ::= */
- { 183, -2 }, /* (332) ccons ::= NULL onconf */
- { 172, -2 }, /* (333) conslist_opt ::= COMMA conslist */
- { 195, -3 }, /* (334) conslist ::= conslist tconscomma tcons */
- { 195, -1 }, /* (335) conslist ::= tcons */
- { 196, 0 }, /* (336) tconscomma ::= */
- { 200, -1 }, /* (337) defer_subclause_opt ::= defer_subclause */
- { 202, -1 }, /* (338) resolvetype ::= raisetype */
- { 206, -1 }, /* (339) selectnowith ::= oneselect */
- { 207, -1 }, /* (340) oneselect ::= values */
- { 221, -2 }, /* (341) sclp ::= selcollist COMMA */
- { 222, -1 }, /* (342) as ::= ID|STRING */
- { 185, -1 }, /* (343) expr ::= term */
- { 238, -1 }, /* (344) likeop ::= LIKE_KW|MATCH */
- { 229, -1 }, /* (345) exprlist ::= nexprlist */
- { 247, -1 }, /* (346) nmnum ::= plus_num */
- { 247, -1 }, /* (347) nmnum ::= nm */
- { 247, -1 }, /* (348) nmnum ::= ON */
- { 247, -1 }, /* (349) nmnum ::= DELETE */
- { 247, -1 }, /* (350) nmnum ::= DEFAULT */
- { 180, -1 }, /* (351) plus_num ::= INTEGER|FLOAT */
- { 252, 0 }, /* (352) foreach_clause ::= */
- { 252, -3 }, /* (353) foreach_clause ::= FOR EACH ROW */
- { 255, -1 }, /* (354) trnm ::= nm */
- { 256, 0 }, /* (355) tridxby ::= */
- { 257, -1 }, /* (356) database_kw_opt ::= DATABASE */
- { 257, 0 }, /* (357) database_kw_opt ::= */
- { 260, 0 }, /* (358) kwcolumn_opt ::= */
- { 260, -1 }, /* (359) kwcolumn_opt ::= COLUMNKW */
- { 262, -1 }, /* (360) vtabarglist ::= vtabarg */
- { 262, -3 }, /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */
- { 263, -2 }, /* (362) vtabarg ::= vtabarg vtabargtoken */
- { 266, 0 }, /* (363) anylist ::= */
- { 266, -4 }, /* (364) anylist ::= anylist LP anylist RP */
- { 266, -2 }, /* (365) anylist ::= anylist ANY */
- { 232, 0 }, /* (366) with ::= */
+/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side
+** of that rule */
+static const YYCODETYPE yyRuleInfoLhs[] = {
+ 159, /* (0) explain ::= EXPLAIN */
+ 159, /* (1) explain ::= EXPLAIN QUERY PLAN */
+ 158, /* (2) cmdx ::= cmd */
+ 160, /* (3) cmd ::= BEGIN transtype trans_opt */
+ 161, /* (4) transtype ::= */
+ 161, /* (5) transtype ::= DEFERRED */
+ 161, /* (6) transtype ::= IMMEDIATE */
+ 161, /* (7) transtype ::= EXCLUSIVE */
+ 160, /* (8) cmd ::= COMMIT|END trans_opt */
+ 160, /* (9) cmd ::= ROLLBACK trans_opt */
+ 160, /* (10) cmd ::= SAVEPOINT nm */
+ 160, /* (11) cmd ::= RELEASE savepoint_opt nm */
+ 160, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+ 165, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ 167, /* (14) createkw ::= CREATE */
+ 169, /* (15) ifnotexists ::= */
+ 169, /* (16) ifnotexists ::= IF NOT EXISTS */
+ 168, /* (17) temp ::= TEMP */
+ 168, /* (18) temp ::= */
+ 166, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
+ 166, /* (20) create_table_args ::= AS select */
+ 173, /* (21) table_options ::= */
+ 173, /* (22) table_options ::= WITHOUT nm */
+ 175, /* (23) columnname ::= nm typetoken */
+ 177, /* (24) typetoken ::= */
+ 177, /* (25) typetoken ::= typename LP signed RP */
+ 177, /* (26) typetoken ::= typename LP signed COMMA signed RP */
+ 178, /* (27) typename ::= typename ID|STRING */
+ 182, /* (28) scanpt ::= */
+ 183, /* (29) ccons ::= CONSTRAINT nm */
+ 183, /* (30) ccons ::= DEFAULT scanpt term scanpt */
+ 183, /* (31) ccons ::= DEFAULT LP expr RP */
+ 183, /* (32) ccons ::= DEFAULT PLUS term scanpt */
+ 183, /* (33) ccons ::= DEFAULT MINUS term scanpt */
+ 183, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */
+ 183, /* (35) ccons ::= NOT NULL onconf */
+ 183, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+ 183, /* (37) ccons ::= UNIQUE onconf */
+ 183, /* (38) ccons ::= CHECK LP expr RP */
+ 183, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */
+ 183, /* (40) ccons ::= defer_subclause */
+ 183, /* (41) ccons ::= COLLATE ID|STRING */
+ 188, /* (42) autoinc ::= */
+ 188, /* (43) autoinc ::= AUTOINCR */
+ 190, /* (44) refargs ::= */
+ 190, /* (45) refargs ::= refargs refarg */
+ 192, /* (46) refarg ::= MATCH nm */
+ 192, /* (47) refarg ::= ON INSERT refact */
+ 192, /* (48) refarg ::= ON DELETE refact */
+ 192, /* (49) refarg ::= ON UPDATE refact */
+ 193, /* (50) refact ::= SET NULL */
+ 193, /* (51) refact ::= SET DEFAULT */
+ 193, /* (52) refact ::= CASCADE */
+ 193, /* (53) refact ::= RESTRICT */
+ 193, /* (54) refact ::= NO ACTION */
+ 191, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+ 191, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ 194, /* (57) init_deferred_pred_opt ::= */
+ 194, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ 194, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+ 172, /* (60) conslist_opt ::= */
+ 196, /* (61) tconscomma ::= COMMA */
+ 197, /* (62) tcons ::= CONSTRAINT nm */
+ 197, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+ 197, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */
+ 197, /* (65) tcons ::= CHECK LP expr RP onconf */
+ 197, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ 200, /* (67) defer_subclause_opt ::= */
+ 186, /* (68) onconf ::= */
+ 186, /* (69) onconf ::= ON CONFLICT resolvetype */
+ 201, /* (70) orconf ::= */
+ 201, /* (71) orconf ::= OR resolvetype */
+ 202, /* (72) resolvetype ::= IGNORE */
+ 202, /* (73) resolvetype ::= REPLACE */
+ 160, /* (74) cmd ::= DROP TABLE ifexists fullname */
+ 204, /* (75) ifexists ::= IF EXISTS */
+ 204, /* (76) ifexists ::= */
+ 160, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ 160, /* (78) cmd ::= DROP VIEW ifexists fullname */
+ 160, /* (79) cmd ::= select */
+ 174, /* (80) select ::= WITH wqlist selectnowith */
+ 174, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */
+ 174, /* (82) select ::= selectnowith */
+ 206, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */
+ 209, /* (84) multiselect_op ::= UNION */
+ 209, /* (85) multiselect_op ::= UNION ALL */
+ 209, /* (86) multiselect_op ::= EXCEPT|INTERSECT */
+ 207, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ 207, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+ 219, /* (89) values ::= VALUES LP nexprlist RP */
+ 219, /* (90) values ::= values COMMA LP nexprlist RP */
+ 210, /* (91) distinct ::= DISTINCT */
+ 210, /* (92) distinct ::= ALL */
+ 210, /* (93) distinct ::= */
+ 221, /* (94) sclp ::= */
+ 211, /* (95) selcollist ::= sclp scanpt expr scanpt as */
+ 211, /* (96) selcollist ::= sclp scanpt STAR */
+ 211, /* (97) selcollist ::= sclp scanpt nm DOT STAR */
+ 222, /* (98) as ::= AS nm */
+ 222, /* (99) as ::= */
+ 212, /* (100) from ::= */
+ 212, /* (101) from ::= FROM seltablist */
+ 224, /* (102) stl_prefix ::= seltablist joinop */
+ 224, /* (103) stl_prefix ::= */
+ 223, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ 223, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ 223, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ 223, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ 170, /* (108) dbnm ::= */
+ 170, /* (109) dbnm ::= DOT nm */
+ 205, /* (110) fullname ::= nm */
+ 205, /* (111) fullname ::= nm DOT nm */
+ 230, /* (112) xfullname ::= nm */
+ 230, /* (113) xfullname ::= nm DOT nm */
+ 230, /* (114) xfullname ::= nm DOT nm AS nm */
+ 230, /* (115) xfullname ::= nm AS nm */
+ 225, /* (116) joinop ::= COMMA|JOIN */
+ 225, /* (117) joinop ::= JOIN_KW JOIN */
+ 225, /* (118) joinop ::= JOIN_KW nm JOIN */
+ 225, /* (119) joinop ::= JOIN_KW nm nm JOIN */
+ 227, /* (120) on_opt ::= ON expr */
+ 227, /* (121) on_opt ::= */
+ 226, /* (122) indexed_opt ::= */
+ 226, /* (123) indexed_opt ::= INDEXED BY nm */
+ 226, /* (124) indexed_opt ::= NOT INDEXED */
+ 228, /* (125) using_opt ::= USING LP idlist RP */
+ 228, /* (126) using_opt ::= */
+ 216, /* (127) orderby_opt ::= */
+ 216, /* (128) orderby_opt ::= ORDER BY sortlist */
+ 198, /* (129) sortlist ::= sortlist COMMA expr sortorder */
+ 198, /* (130) sortlist ::= expr sortorder */
+ 187, /* (131) sortorder ::= ASC */
+ 187, /* (132) sortorder ::= DESC */
+ 187, /* (133) sortorder ::= */
+ 214, /* (134) groupby_opt ::= */
+ 214, /* (135) groupby_opt ::= GROUP BY nexprlist */
+ 215, /* (136) having_opt ::= */
+ 215, /* (137) having_opt ::= HAVING expr */
+ 217, /* (138) limit_opt ::= */
+ 217, /* (139) limit_opt ::= LIMIT expr */
+ 217, /* (140) limit_opt ::= LIMIT expr OFFSET expr */
+ 217, /* (141) limit_opt ::= LIMIT expr COMMA expr */
+ 160, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+ 213, /* (143) where_opt ::= */
+ 213, /* (144) where_opt ::= WHERE expr */
+ 160, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+ 233, /* (146) setlist ::= setlist COMMA nm EQ expr */
+ 233, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ 233, /* (148) setlist ::= nm EQ expr */
+ 233, /* (149) setlist ::= LP idlist RP EQ expr */
+ 160, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ 160, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+ 236, /* (152) upsert ::= */
+ 236, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+ 236, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+ 236, /* (155) upsert ::= ON CONFLICT DO NOTHING */
+ 234, /* (156) insert_cmd ::= INSERT orconf */
+ 234, /* (157) insert_cmd ::= REPLACE */
+ 235, /* (158) idlist_opt ::= */
+ 235, /* (159) idlist_opt ::= LP idlist RP */
+ 231, /* (160) idlist ::= idlist COMMA nm */
+ 231, /* (161) idlist ::= nm */
+ 185, /* (162) expr ::= LP expr RP */
+ 185, /* (163) expr ::= ID|INDEXED */
+ 185, /* (164) expr ::= JOIN_KW */
+ 185, /* (165) expr ::= nm DOT nm */
+ 185, /* (166) expr ::= nm DOT nm DOT nm */
+ 184, /* (167) term ::= NULL|FLOAT|BLOB */
+ 184, /* (168) term ::= STRING */
+ 184, /* (169) term ::= INTEGER */
+ 185, /* (170) expr ::= VARIABLE */
+ 185, /* (171) expr ::= expr COLLATE ID|STRING */
+ 185, /* (172) expr ::= CAST LP expr AS typetoken RP */
+ 185, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */
+ 185, /* (174) expr ::= ID|INDEXED LP STAR RP */
+ 185, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+ 185, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */
+ 184, /* (177) term ::= CTIME_KW */
+ 185, /* (178) expr ::= LP nexprlist COMMA expr RP */
+ 185, /* (179) expr ::= expr AND expr */
+ 185, /* (180) expr ::= expr OR expr */
+ 185, /* (181) expr ::= expr LT|GT|GE|LE expr */
+ 185, /* (182) expr ::= expr EQ|NE expr */
+ 185, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ 185, /* (184) expr ::= expr PLUS|MINUS expr */
+ 185, /* (185) expr ::= expr STAR|SLASH|REM expr */
+ 185, /* (186) expr ::= expr CONCAT expr */
+ 238, /* (187) likeop ::= NOT LIKE_KW|MATCH */
+ 185, /* (188) expr ::= expr likeop expr */
+ 185, /* (189) expr ::= expr likeop expr ESCAPE expr */
+ 185, /* (190) expr ::= expr ISNULL|NOTNULL */
+ 185, /* (191) expr ::= expr NOT NULL */
+ 185, /* (192) expr ::= expr IS expr */
+ 185, /* (193) expr ::= expr IS NOT expr */
+ 185, /* (194) expr ::= NOT expr */
+ 185, /* (195) expr ::= BITNOT expr */
+ 185, /* (196) expr ::= PLUS|MINUS expr */
+ 239, /* (197) between_op ::= BETWEEN */
+ 239, /* (198) between_op ::= NOT BETWEEN */
+ 185, /* (199) expr ::= expr between_op expr AND expr */
+ 240, /* (200) in_op ::= IN */
+ 240, /* (201) in_op ::= NOT IN */
+ 185, /* (202) expr ::= expr in_op LP exprlist RP */
+ 185, /* (203) expr ::= LP select RP */
+ 185, /* (204) expr ::= expr in_op LP select RP */
+ 185, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */
+ 185, /* (206) expr ::= EXISTS LP select RP */
+ 185, /* (207) expr ::= CASE case_operand case_exprlist case_else END */
+ 243, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ 243, /* (209) case_exprlist ::= WHEN expr THEN expr */
+ 244, /* (210) case_else ::= ELSE expr */
+ 244, /* (211) case_else ::= */
+ 242, /* (212) case_operand ::= expr */
+ 242, /* (213) case_operand ::= */
+ 229, /* (214) exprlist ::= */
+ 220, /* (215) nexprlist ::= nexprlist COMMA expr */
+ 220, /* (216) nexprlist ::= expr */
+ 241, /* (217) paren_exprlist ::= */
+ 241, /* (218) paren_exprlist ::= LP exprlist RP */
+ 160, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ 245, /* (220) uniqueflag ::= UNIQUE */
+ 245, /* (221) uniqueflag ::= */
+ 189, /* (222) eidlist_opt ::= */
+ 189, /* (223) eidlist_opt ::= LP eidlist RP */
+ 199, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */
+ 199, /* (225) eidlist ::= nm collate sortorder */
+ 246, /* (226) collate ::= */
+ 246, /* (227) collate ::= COLLATE ID|STRING */
+ 160, /* (228) cmd ::= DROP INDEX ifexists fullname */
+ 160, /* (229) cmd ::= VACUUM vinto */
+ 160, /* (230) cmd ::= VACUUM nm vinto */
+ 247, /* (231) vinto ::= INTO expr */
+ 247, /* (232) vinto ::= */
+ 160, /* (233) cmd ::= PRAGMA nm dbnm */
+ 160, /* (234) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ 160, /* (235) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ 160, /* (236) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ 160, /* (237) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ 180, /* (238) plus_num ::= PLUS INTEGER|FLOAT */
+ 181, /* (239) minus_num ::= MINUS INTEGER|FLOAT */
+ 160, /* (240) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ 249, /* (241) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ 251, /* (242) trigger_time ::= BEFORE|AFTER */
+ 251, /* (243) trigger_time ::= INSTEAD OF */
+ 251, /* (244) trigger_time ::= */
+ 252, /* (245) trigger_event ::= DELETE|INSERT */
+ 252, /* (246) trigger_event ::= UPDATE */
+ 252, /* (247) trigger_event ::= UPDATE OF idlist */
+ 254, /* (248) when_clause ::= */
+ 254, /* (249) when_clause ::= WHEN expr */
+ 250, /* (250) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ 250, /* (251) trigger_cmd_list ::= trigger_cmd SEMI */
+ 256, /* (252) trnm ::= nm DOT nm */
+ 257, /* (253) tridxby ::= INDEXED BY nm */
+ 257, /* (254) tridxby ::= NOT INDEXED */
+ 255, /* (255) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+ 255, /* (256) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ 255, /* (257) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ 255, /* (258) trigger_cmd ::= scanpt select scanpt */
+ 185, /* (259) expr ::= RAISE LP IGNORE RP */
+ 185, /* (260) expr ::= RAISE LP raisetype COMMA nm RP */
+ 203, /* (261) raisetype ::= ROLLBACK */
+ 203, /* (262) raisetype ::= ABORT */
+ 203, /* (263) raisetype ::= FAIL */
+ 160, /* (264) cmd ::= DROP TRIGGER ifexists fullname */
+ 160, /* (265) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ 160, /* (266) cmd ::= DETACH database_kw_opt expr */
+ 259, /* (267) key_opt ::= */
+ 259, /* (268) key_opt ::= KEY expr */
+ 160, /* (269) cmd ::= REINDEX */
+ 160, /* (270) cmd ::= REINDEX nm dbnm */
+ 160, /* (271) cmd ::= ANALYZE */
+ 160, /* (272) cmd ::= ANALYZE nm dbnm */
+ 160, /* (273) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ 160, /* (274) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ 260, /* (275) add_column_fullname ::= fullname */
+ 160, /* (276) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ 160, /* (277) cmd ::= create_vtab */
+ 160, /* (278) cmd ::= create_vtab LP vtabarglist RP */
+ 262, /* (279) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ 264, /* (280) vtabarg ::= */
+ 265, /* (281) vtabargtoken ::= ANY */
+ 265, /* (282) vtabargtoken ::= lp anylist RP */
+ 266, /* (283) lp ::= LP */
+ 232, /* (284) with ::= WITH wqlist */
+ 232, /* (285) with ::= WITH RECURSIVE wqlist */
+ 208, /* (286) wqlist ::= nm eidlist_opt AS LP select RP */
+ 208, /* (287) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ 268, /* (288) windowdefn_list ::= windowdefn */
+ 268, /* (289) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ 269, /* (290) windowdefn ::= nm AS window */
+ 270, /* (291) window ::= LP part_opt orderby_opt frame_opt RP */
+ 272, /* (292) part_opt ::= PARTITION BY nexprlist */
+ 272, /* (293) part_opt ::= */
+ 271, /* (294) frame_opt ::= */
+ 271, /* (295) frame_opt ::= range_or_rows frame_bound_s */
+ 271, /* (296) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
+ 274, /* (297) range_or_rows ::= RANGE */
+ 274, /* (298) range_or_rows ::= ROWS */
+ 276, /* (299) frame_bound_s ::= frame_bound */
+ 276, /* (300) frame_bound_s ::= UNBOUNDED PRECEDING */
+ 277, /* (301) frame_bound_e ::= frame_bound */
+ 277, /* (302) frame_bound_e ::= UNBOUNDED FOLLOWING */
+ 275, /* (303) frame_bound ::= expr PRECEDING */
+ 275, /* (304) frame_bound ::= CURRENT ROW */
+ 275, /* (305) frame_bound ::= expr FOLLOWING */
+ 218, /* (306) window_clause ::= WINDOW windowdefn_list */
+ 237, /* (307) over_clause ::= filter_opt OVER window */
+ 237, /* (308) over_clause ::= filter_opt OVER nm */
+ 273, /* (309) filter_opt ::= */
+ 273, /* (310) filter_opt ::= FILTER LP WHERE expr RP */
+ 155, /* (311) input ::= cmdlist */
+ 156, /* (312) cmdlist ::= cmdlist ecmd */
+ 156, /* (313) cmdlist ::= ecmd */
+ 157, /* (314) ecmd ::= SEMI */
+ 157, /* (315) ecmd ::= cmdx SEMI */
+ 157, /* (316) ecmd ::= explain cmdx */
+ 162, /* (317) trans_opt ::= */
+ 162, /* (318) trans_opt ::= TRANSACTION */
+ 162, /* (319) trans_opt ::= TRANSACTION nm */
+ 164, /* (320) savepoint_opt ::= SAVEPOINT */
+ 164, /* (321) savepoint_opt ::= */
+ 160, /* (322) cmd ::= create_table create_table_args */
+ 171, /* (323) columnlist ::= columnlist COMMA columnname carglist */
+ 171, /* (324) columnlist ::= columnname carglist */
+ 163, /* (325) nm ::= ID|INDEXED */
+ 163, /* (326) nm ::= STRING */
+ 163, /* (327) nm ::= JOIN_KW */
+ 177, /* (328) typetoken ::= typename */
+ 178, /* (329) typename ::= ID|STRING */
+ 179, /* (330) signed ::= plus_num */
+ 179, /* (331) signed ::= minus_num */
+ 176, /* (332) carglist ::= carglist ccons */
+ 176, /* (333) carglist ::= */
+ 183, /* (334) ccons ::= NULL onconf */
+ 172, /* (335) conslist_opt ::= COMMA conslist */
+ 195, /* (336) conslist ::= conslist tconscomma tcons */
+ 195, /* (337) conslist ::= tcons */
+ 196, /* (338) tconscomma ::= */
+ 200, /* (339) defer_subclause_opt ::= defer_subclause */
+ 202, /* (340) resolvetype ::= raisetype */
+ 206, /* (341) selectnowith ::= oneselect */
+ 207, /* (342) oneselect ::= values */
+ 221, /* (343) sclp ::= selcollist COMMA */
+ 222, /* (344) as ::= ID|STRING */
+ 185, /* (345) expr ::= term */
+ 238, /* (346) likeop ::= LIKE_KW|MATCH */
+ 229, /* (347) exprlist ::= nexprlist */
+ 248, /* (348) nmnum ::= plus_num */
+ 248, /* (349) nmnum ::= nm */
+ 248, /* (350) nmnum ::= ON */
+ 248, /* (351) nmnum ::= DELETE */
+ 248, /* (352) nmnum ::= DEFAULT */
+ 180, /* (353) plus_num ::= INTEGER|FLOAT */
+ 253, /* (354) foreach_clause ::= */
+ 253, /* (355) foreach_clause ::= FOR EACH ROW */
+ 256, /* (356) trnm ::= nm */
+ 257, /* (357) tridxby ::= */
+ 258, /* (358) database_kw_opt ::= DATABASE */
+ 258, /* (359) database_kw_opt ::= */
+ 261, /* (360) kwcolumn_opt ::= */
+ 261, /* (361) kwcolumn_opt ::= COLUMNKW */
+ 263, /* (362) vtabarglist ::= vtabarg */
+ 263, /* (363) vtabarglist ::= vtabarglist COMMA vtabarg */
+ 264, /* (364) vtabarg ::= vtabarg vtabargtoken */
+ 267, /* (365) anylist ::= */
+ 267, /* (366) anylist ::= anylist LP anylist RP */
+ 267, /* (367) anylist ::= anylist ANY */
+ 232, /* (368) with ::= */
+};
+
+/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
+** of symbols on the right-hand side of that rule. */
+static const signed char yyRuleInfoNRhs[] = {
+ -1, /* (0) explain ::= EXPLAIN */
+ -3, /* (1) explain ::= EXPLAIN QUERY PLAN */
+ -1, /* (2) cmdx ::= cmd */
+ -3, /* (3) cmd ::= BEGIN transtype trans_opt */
+ 0, /* (4) transtype ::= */
+ -1, /* (5) transtype ::= DEFERRED */
+ -1, /* (6) transtype ::= IMMEDIATE */
+ -1, /* (7) transtype ::= EXCLUSIVE */
+ -2, /* (8) cmd ::= COMMIT|END trans_opt */
+ -2, /* (9) cmd ::= ROLLBACK trans_opt */
+ -2, /* (10) cmd ::= SAVEPOINT nm */
+ -3, /* (11) cmd ::= RELEASE savepoint_opt nm */
+ -5, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+ -6, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ -1, /* (14) createkw ::= CREATE */
+ 0, /* (15) ifnotexists ::= */
+ -3, /* (16) ifnotexists ::= IF NOT EXISTS */
+ -1, /* (17) temp ::= TEMP */
+ 0, /* (18) temp ::= */
+ -5, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
+ -2, /* (20) create_table_args ::= AS select */
+ 0, /* (21) table_options ::= */
+ -2, /* (22) table_options ::= WITHOUT nm */
+ -2, /* (23) columnname ::= nm typetoken */
+ 0, /* (24) typetoken ::= */
+ -4, /* (25) typetoken ::= typename LP signed RP */
+ -6, /* (26) typetoken ::= typename LP signed COMMA signed RP */
+ -2, /* (27) typename ::= typename ID|STRING */
+ 0, /* (28) scanpt ::= */
+ -2, /* (29) ccons ::= CONSTRAINT nm */
+ -4, /* (30) ccons ::= DEFAULT scanpt term scanpt */
+ -4, /* (31) ccons ::= DEFAULT LP expr RP */
+ -4, /* (32) ccons ::= DEFAULT PLUS term scanpt */
+ -4, /* (33) ccons ::= DEFAULT MINUS term scanpt */
+ -3, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */
+ -3, /* (35) ccons ::= NOT NULL onconf */
+ -5, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+ -2, /* (37) ccons ::= UNIQUE onconf */
+ -4, /* (38) ccons ::= CHECK LP expr RP */
+ -4, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */
+ -1, /* (40) ccons ::= defer_subclause */
+ -2, /* (41) ccons ::= COLLATE ID|STRING */
+ 0, /* (42) autoinc ::= */
+ -1, /* (43) autoinc ::= AUTOINCR */
+ 0, /* (44) refargs ::= */
+ -2, /* (45) refargs ::= refargs refarg */
+ -2, /* (46) refarg ::= MATCH nm */
+ -3, /* (47) refarg ::= ON INSERT refact */
+ -3, /* (48) refarg ::= ON DELETE refact */
+ -3, /* (49) refarg ::= ON UPDATE refact */
+ -2, /* (50) refact ::= SET NULL */
+ -2, /* (51) refact ::= SET DEFAULT */
+ -1, /* (52) refact ::= CASCADE */
+ -1, /* (53) refact ::= RESTRICT */
+ -2, /* (54) refact ::= NO ACTION */
+ -3, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+ -2, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ 0, /* (57) init_deferred_pred_opt ::= */
+ -2, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ -2, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+ 0, /* (60) conslist_opt ::= */
+ -1, /* (61) tconscomma ::= COMMA */
+ -2, /* (62) tcons ::= CONSTRAINT nm */
+ -7, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+ -5, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */
+ -5, /* (65) tcons ::= CHECK LP expr RP onconf */
+ -10, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ 0, /* (67) defer_subclause_opt ::= */
+ 0, /* (68) onconf ::= */
+ -3, /* (69) onconf ::= ON CONFLICT resolvetype */
+ 0, /* (70) orconf ::= */
+ -2, /* (71) orconf ::= OR resolvetype */
+ -1, /* (72) resolvetype ::= IGNORE */
+ -1, /* (73) resolvetype ::= REPLACE */
+ -4, /* (74) cmd ::= DROP TABLE ifexists fullname */
+ -2, /* (75) ifexists ::= IF EXISTS */
+ 0, /* (76) ifexists ::= */
+ -9, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ -4, /* (78) cmd ::= DROP VIEW ifexists fullname */
+ -1, /* (79) cmd ::= select */
+ -3, /* (80) select ::= WITH wqlist selectnowith */
+ -4, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */
+ -1, /* (82) select ::= selectnowith */
+ -3, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */
+ -1, /* (84) multiselect_op ::= UNION */
+ -2, /* (85) multiselect_op ::= UNION ALL */
+ -1, /* (86) multiselect_op ::= EXCEPT|INTERSECT */
+ -9, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ -10, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+ -4, /* (89) values ::= VALUES LP nexprlist RP */
+ -5, /* (90) values ::= values COMMA LP nexprlist RP */
+ -1, /* (91) distinct ::= DISTINCT */
+ -1, /* (92) distinct ::= ALL */
+ 0, /* (93) distinct ::= */
+ 0, /* (94) sclp ::= */
+ -5, /* (95) selcollist ::= sclp scanpt expr scanpt as */
+ -3, /* (96) selcollist ::= sclp scanpt STAR */
+ -5, /* (97) selcollist ::= sclp scanpt nm DOT STAR */
+ -2, /* (98) as ::= AS nm */
+ 0, /* (99) as ::= */
+ 0, /* (100) from ::= */
+ -2, /* (101) from ::= FROM seltablist */
+ -2, /* (102) stl_prefix ::= seltablist joinop */
+ 0, /* (103) stl_prefix ::= */
+ -7, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ -9, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ -7, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ -7, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ 0, /* (108) dbnm ::= */
+ -2, /* (109) dbnm ::= DOT nm */
+ -1, /* (110) fullname ::= nm */
+ -3, /* (111) fullname ::= nm DOT nm */
+ -1, /* (112) xfullname ::= nm */
+ -3, /* (113) xfullname ::= nm DOT nm */
+ -5, /* (114) xfullname ::= nm DOT nm AS nm */
+ -3, /* (115) xfullname ::= nm AS nm */
+ -1, /* (116) joinop ::= COMMA|JOIN */
+ -2, /* (117) joinop ::= JOIN_KW JOIN */
+ -3, /* (118) joinop ::= JOIN_KW nm JOIN */
+ -4, /* (119) joinop ::= JOIN_KW nm nm JOIN */
+ -2, /* (120) on_opt ::= ON expr */
+ 0, /* (121) on_opt ::= */
+ 0, /* (122) indexed_opt ::= */
+ -3, /* (123) indexed_opt ::= INDEXED BY nm */
+ -2, /* (124) indexed_opt ::= NOT INDEXED */
+ -4, /* (125) using_opt ::= USING LP idlist RP */
+ 0, /* (126) using_opt ::= */
+ 0, /* (127) orderby_opt ::= */
+ -3, /* (128) orderby_opt ::= ORDER BY sortlist */
+ -4, /* (129) sortlist ::= sortlist COMMA expr sortorder */
+ -2, /* (130) sortlist ::= expr sortorder */
+ -1, /* (131) sortorder ::= ASC */
+ -1, /* (132) sortorder ::= DESC */
+ 0, /* (133) sortorder ::= */
+ 0, /* (134) groupby_opt ::= */
+ -3, /* (135) groupby_opt ::= GROUP BY nexprlist */
+ 0, /* (136) having_opt ::= */
+ -2, /* (137) having_opt ::= HAVING expr */
+ 0, /* (138) limit_opt ::= */
+ -2, /* (139) limit_opt ::= LIMIT expr */
+ -4, /* (140) limit_opt ::= LIMIT expr OFFSET expr */
+ -4, /* (141) limit_opt ::= LIMIT expr COMMA expr */
+ -6, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+ 0, /* (143) where_opt ::= */
+ -2, /* (144) where_opt ::= WHERE expr */
+ -8, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+ -5, /* (146) setlist ::= setlist COMMA nm EQ expr */
+ -7, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ -3, /* (148) setlist ::= nm EQ expr */
+ -5, /* (149) setlist ::= LP idlist RP EQ expr */
+ -7, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ -7, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+ 0, /* (152) upsert ::= */
+ -11, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+ -8, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+ -4, /* (155) upsert ::= ON CONFLICT DO NOTHING */
+ -2, /* (156) insert_cmd ::= INSERT orconf */
+ -1, /* (157) insert_cmd ::= REPLACE */
+ 0, /* (158) idlist_opt ::= */
+ -3, /* (159) idlist_opt ::= LP idlist RP */
+ -3, /* (160) idlist ::= idlist COMMA nm */
+ -1, /* (161) idlist ::= nm */
+ -3, /* (162) expr ::= LP expr RP */
+ -1, /* (163) expr ::= ID|INDEXED */
+ -1, /* (164) expr ::= JOIN_KW */
+ -3, /* (165) expr ::= nm DOT nm */
+ -5, /* (166) expr ::= nm DOT nm DOT nm */
+ -1, /* (167) term ::= NULL|FLOAT|BLOB */
+ -1, /* (168) term ::= STRING */
+ -1, /* (169) term ::= INTEGER */
+ -1, /* (170) expr ::= VARIABLE */
+ -3, /* (171) expr ::= expr COLLATE ID|STRING */
+ -6, /* (172) expr ::= CAST LP expr AS typetoken RP */
+ -5, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */
+ -4, /* (174) expr ::= ID|INDEXED LP STAR RP */
+ -6, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+ -5, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */
+ -1, /* (177) term ::= CTIME_KW */
+ -5, /* (178) expr ::= LP nexprlist COMMA expr RP */
+ -3, /* (179) expr ::= expr AND expr */
+ -3, /* (180) expr ::= expr OR expr */
+ -3, /* (181) expr ::= expr LT|GT|GE|LE expr */
+ -3, /* (182) expr ::= expr EQ|NE expr */
+ -3, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ -3, /* (184) expr ::= expr PLUS|MINUS expr */
+ -3, /* (185) expr ::= expr STAR|SLASH|REM expr */
+ -3, /* (186) expr ::= expr CONCAT expr */
+ -2, /* (187) likeop ::= NOT LIKE_KW|MATCH */
+ -3, /* (188) expr ::= expr likeop expr */
+ -5, /* (189) expr ::= expr likeop expr ESCAPE expr */
+ -2, /* (190) expr ::= expr ISNULL|NOTNULL */
+ -3, /* (191) expr ::= expr NOT NULL */
+ -3, /* (192) expr ::= expr IS expr */
+ -4, /* (193) expr ::= expr IS NOT expr */
+ -2, /* (194) expr ::= NOT expr */
+ -2, /* (195) expr ::= BITNOT expr */
+ -2, /* (196) expr ::= PLUS|MINUS expr */
+ -1, /* (197) between_op ::= BETWEEN */
+ -2, /* (198) between_op ::= NOT BETWEEN */
+ -5, /* (199) expr ::= expr between_op expr AND expr */
+ -1, /* (200) in_op ::= IN */
+ -2, /* (201) in_op ::= NOT IN */
+ -5, /* (202) expr ::= expr in_op LP exprlist RP */
+ -3, /* (203) expr ::= LP select RP */
+ -5, /* (204) expr ::= expr in_op LP select RP */
+ -5, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */
+ -4, /* (206) expr ::= EXISTS LP select RP */
+ -5, /* (207) expr ::= CASE case_operand case_exprlist case_else END */
+ -5, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ -4, /* (209) case_exprlist ::= WHEN expr THEN expr */
+ -2, /* (210) case_else ::= ELSE expr */
+ 0, /* (211) case_else ::= */
+ -1, /* (212) case_operand ::= expr */
+ 0, /* (213) case_operand ::= */
+ 0, /* (214) exprlist ::= */
+ -3, /* (215) nexprlist ::= nexprlist COMMA expr */
+ -1, /* (216) nexprlist ::= expr */
+ 0, /* (217) paren_exprlist ::= */
+ -3, /* (218) paren_exprlist ::= LP exprlist RP */
+ -12, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ -1, /* (220) uniqueflag ::= UNIQUE */
+ 0, /* (221) uniqueflag ::= */
+ 0, /* (222) eidlist_opt ::= */
+ -3, /* (223) eidlist_opt ::= LP eidlist RP */
+ -5, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */
+ -3, /* (225) eidlist ::= nm collate sortorder */
+ 0, /* (226) collate ::= */
+ -2, /* (227) collate ::= COLLATE ID|STRING */
+ -4, /* (228) cmd ::= DROP INDEX ifexists fullname */
+ -2, /* (229) cmd ::= VACUUM vinto */
+ -3, /* (230) cmd ::= VACUUM nm vinto */
+ -2, /* (231) vinto ::= INTO expr */
+ 0, /* (232) vinto ::= */
+ -3, /* (233) cmd ::= PRAGMA nm dbnm */
+ -5, /* (234) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ -6, /* (235) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ -5, /* (236) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ -6, /* (237) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ -2, /* (238) plus_num ::= PLUS INTEGER|FLOAT */
+ -2, /* (239) minus_num ::= MINUS INTEGER|FLOAT */
+ -5, /* (240) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ -11, /* (241) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ -1, /* (242) trigger_time ::= BEFORE|AFTER */
+ -2, /* (243) trigger_time ::= INSTEAD OF */
+ 0, /* (244) trigger_time ::= */
+ -1, /* (245) trigger_event ::= DELETE|INSERT */
+ -1, /* (246) trigger_event ::= UPDATE */
+ -3, /* (247) trigger_event ::= UPDATE OF idlist */
+ 0, /* (248) when_clause ::= */
+ -2, /* (249) when_clause ::= WHEN expr */
+ -3, /* (250) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ -2, /* (251) trigger_cmd_list ::= trigger_cmd SEMI */
+ -3, /* (252) trnm ::= nm DOT nm */
+ -3, /* (253) tridxby ::= INDEXED BY nm */
+ -2, /* (254) tridxby ::= NOT INDEXED */
+ -8, /* (255) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+ -8, /* (256) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ -6, /* (257) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ -3, /* (258) trigger_cmd ::= scanpt select scanpt */
+ -4, /* (259) expr ::= RAISE LP IGNORE RP */
+ -6, /* (260) expr ::= RAISE LP raisetype COMMA nm RP */
+ -1, /* (261) raisetype ::= ROLLBACK */
+ -1, /* (262) raisetype ::= ABORT */
+ -1, /* (263) raisetype ::= FAIL */
+ -4, /* (264) cmd ::= DROP TRIGGER ifexists fullname */
+ -6, /* (265) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ -3, /* (266) cmd ::= DETACH database_kw_opt expr */
+ 0, /* (267) key_opt ::= */
+ -2, /* (268) key_opt ::= KEY expr */
+ -1, /* (269) cmd ::= REINDEX */
+ -3, /* (270) cmd ::= REINDEX nm dbnm */
+ -1, /* (271) cmd ::= ANALYZE */
+ -3, /* (272) cmd ::= ANALYZE nm dbnm */
+ -6, /* (273) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ -7, /* (274) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ -1, /* (275) add_column_fullname ::= fullname */
+ -8, /* (276) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ -1, /* (277) cmd ::= create_vtab */
+ -4, /* (278) cmd ::= create_vtab LP vtabarglist RP */
+ -8, /* (279) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ 0, /* (280) vtabarg ::= */
+ -1, /* (281) vtabargtoken ::= ANY */
+ -3, /* (282) vtabargtoken ::= lp anylist RP */
+ -1, /* (283) lp ::= LP */
+ -2, /* (284) with ::= WITH wqlist */
+ -3, /* (285) with ::= WITH RECURSIVE wqlist */
+ -6, /* (286) wqlist ::= nm eidlist_opt AS LP select RP */
+ -8, /* (287) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ -1, /* (288) windowdefn_list ::= windowdefn */
+ -3, /* (289) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ -3, /* (290) windowdefn ::= nm AS window */
+ -5, /* (291) window ::= LP part_opt orderby_opt frame_opt RP */
+ -3, /* (292) part_opt ::= PARTITION BY nexprlist */
+ 0, /* (293) part_opt ::= */
+ 0, /* (294) frame_opt ::= */
+ -2, /* (295) frame_opt ::= range_or_rows frame_bound_s */
+ -5, /* (296) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
+ -1, /* (297) range_or_rows ::= RANGE */
+ -1, /* (298) range_or_rows ::= ROWS */
+ -1, /* (299) frame_bound_s ::= frame_bound */
+ -2, /* (300) frame_bound_s ::= UNBOUNDED PRECEDING */
+ -1, /* (301) frame_bound_e ::= frame_bound */
+ -2, /* (302) frame_bound_e ::= UNBOUNDED FOLLOWING */
+ -2, /* (303) frame_bound ::= expr PRECEDING */
+ -2, /* (304) frame_bound ::= CURRENT ROW */
+ -2, /* (305) frame_bound ::= expr FOLLOWING */
+ -2, /* (306) window_clause ::= WINDOW windowdefn_list */
+ -3, /* (307) over_clause ::= filter_opt OVER window */
+ -3, /* (308) over_clause ::= filter_opt OVER nm */
+ 0, /* (309) filter_opt ::= */
+ -5, /* (310) filter_opt ::= FILTER LP WHERE expr RP */
+ -1, /* (311) input ::= cmdlist */
+ -2, /* (312) cmdlist ::= cmdlist ecmd */
+ -1, /* (313) cmdlist ::= ecmd */
+ -1, /* (314) ecmd ::= SEMI */
+ -2, /* (315) ecmd ::= cmdx SEMI */
+ -2, /* (316) ecmd ::= explain cmdx */
+ 0, /* (317) trans_opt ::= */
+ -1, /* (318) trans_opt ::= TRANSACTION */
+ -2, /* (319) trans_opt ::= TRANSACTION nm */
+ -1, /* (320) savepoint_opt ::= SAVEPOINT */
+ 0, /* (321) savepoint_opt ::= */
+ -2, /* (322) cmd ::= create_table create_table_args */
+ -4, /* (323) columnlist ::= columnlist COMMA columnname carglist */
+ -2, /* (324) columnlist ::= columnname carglist */
+ -1, /* (325) nm ::= ID|INDEXED */
+ -1, /* (326) nm ::= STRING */
+ -1, /* (327) nm ::= JOIN_KW */
+ -1, /* (328) typetoken ::= typename */
+ -1, /* (329) typename ::= ID|STRING */
+ -1, /* (330) signed ::= plus_num */
+ -1, /* (331) signed ::= minus_num */
+ -2, /* (332) carglist ::= carglist ccons */
+ 0, /* (333) carglist ::= */
+ -2, /* (334) ccons ::= NULL onconf */
+ -2, /* (335) conslist_opt ::= COMMA conslist */
+ -3, /* (336) conslist ::= conslist tconscomma tcons */
+ -1, /* (337) conslist ::= tcons */
+ 0, /* (338) tconscomma ::= */
+ -1, /* (339) defer_subclause_opt ::= defer_subclause */
+ -1, /* (340) resolvetype ::= raisetype */
+ -1, /* (341) selectnowith ::= oneselect */
+ -1, /* (342) oneselect ::= values */
+ -2, /* (343) sclp ::= selcollist COMMA */
+ -1, /* (344) as ::= ID|STRING */
+ -1, /* (345) expr ::= term */
+ -1, /* (346) likeop ::= LIKE_KW|MATCH */
+ -1, /* (347) exprlist ::= nexprlist */
+ -1, /* (348) nmnum ::= plus_num */
+ -1, /* (349) nmnum ::= nm */
+ -1, /* (350) nmnum ::= ON */
+ -1, /* (351) nmnum ::= DELETE */
+ -1, /* (352) nmnum ::= DEFAULT */
+ -1, /* (353) plus_num ::= INTEGER|FLOAT */
+ 0, /* (354) foreach_clause ::= */
+ -3, /* (355) foreach_clause ::= FOR EACH ROW */
+ -1, /* (356) trnm ::= nm */
+ 0, /* (357) tridxby ::= */
+ -1, /* (358) database_kw_opt ::= DATABASE */
+ 0, /* (359) database_kw_opt ::= */
+ 0, /* (360) kwcolumn_opt ::= */
+ -1, /* (361) kwcolumn_opt ::= COLUMNKW */
+ -1, /* (362) vtabarglist ::= vtabarg */
+ -3, /* (363) vtabarglist ::= vtabarglist COMMA vtabarg */
+ -2, /* (364) vtabarg ::= vtabarg vtabargtoken */
+ 0, /* (365) anylist ::= */
+ -4, /* (366) anylist ::= anylist LP anylist RP */
+ -2, /* (367) anylist ::= anylist ANY */
+ 0, /* (368) with ::= */
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -149483,7 +150374,7 @@ static YYACTIONTYPE yy_reduce(
yymsp = yypParser->yytos;
#ifndef NDEBUG
if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
- yysize = yyRuleInfo[yyruleno].nrhs;
+ yysize = yyRuleInfoNRhs[yyruleno];
if( yysize ){
fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
yyTracePrompt,
@@ -149498,7 +150389,7 @@ static YYACTIONTYPE yy_reduce(
/* Check that the stack is large enough to grow by a single entry
** if the RHS of the rule is empty. This ensures that there is room
** enough on the stack to push the LHS value */
- if( yyRuleInfo[yyruleno].nrhs==0 ){
+ if( yyRuleInfoNRhs[yyruleno]==0 ){
#ifdef YYTRACKMAXSTACKDEPTH
if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
yypParser->yyhwm++;
@@ -149548,15 +150439,15 @@ static YYACTIONTYPE yy_reduce(
{ sqlite3FinishCoding(pParse); }
break;
case 3: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy70);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy96);}
break;
case 4: /* transtype ::= */
-{yymsp[1].minor.yy70 = TK_DEFERRED;}
+{yymsp[1].minor.yy96 = TK_DEFERRED;}
break;
case 5: /* transtype ::= DEFERRED */
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
-{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/}
+{yymsp[0].minor.yy96 = yymsp[0].major; /*A-overwrites-X*/}
break;
case 8: /* cmd ::= COMMIT|END trans_opt */
case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
@@ -149579,7 +150470,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy70,0,0,yymsp[-2].minor.yy70);
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy96,0,0,yymsp[-2].minor.yy96);
}
break;
case 14: /* createkw ::= CREATE */
@@ -149594,32 +150485,32 @@ static YYACTIONTYPE yy_reduce(
case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
case 93: /* distinct ::= */ yytestcase(yyruleno==93);
case 226: /* collate ::= */ yytestcase(yyruleno==226);
-{yymsp[1].minor.yy70 = 0;}
+{yymsp[1].minor.yy96 = 0;}
break;
case 16: /* ifnotexists ::= IF NOT EXISTS */
-{yymsp[-2].minor.yy70 = 1;}
+{yymsp[-2].minor.yy96 = 1;}
break;
case 17: /* temp ::= TEMP */
case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43);
-{yymsp[0].minor.yy70 = 1;}
+{yymsp[0].minor.yy96 = 1;}
break;
case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
{
- sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy70,0);
+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy96,0);
}
break;
case 20: /* create_table_args ::= AS select */
{
- sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy489);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy423);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy423);
}
break;
case 22: /* table_options ::= WITHOUT nm */
{
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
- yymsp[-1].minor.yy70 = TF_WithoutRowid | TF_NoVisibleRowid;
+ yymsp[-1].minor.yy96 = TF_WithoutRowid | TF_NoVisibleRowid;
}else{
- yymsp[-1].minor.yy70 = 0;
+ yymsp[-1].minor.yy96 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
@@ -149648,7 +150539,7 @@ static YYACTIONTYPE yy_reduce(
case 28: /* scanpt ::= */
{
assert( yyLookahead!=YYNOCODE );
- yymsp[1].minor.yy392 = yyLookaheadToken.z;
+ yymsp[1].minor.yy464 = yyLookaheadToken.z;
}
break;
case 29: /* ccons ::= CONSTRAINT nm */
@@ -149656,18 +150547,18 @@ static YYACTIONTYPE yy_reduce(
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
case 30: /* ccons ::= DEFAULT scanpt term scanpt */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy392,yymsp[0].minor.yy392);}
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy490,yymsp[-2].minor.yy464,yymsp[0].minor.yy464);}
break;
case 31: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy490,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
break;
case 32: /* ccons ::= DEFAULT PLUS term scanpt */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);}
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy490,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy464);}
break;
case 33: /* ccons ::= DEFAULT MINUS term scanpt */
{
- Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy18, 0);
- sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);
+ Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy490, 0);
+ sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy464);
}
break;
case 34: /* ccons ::= DEFAULT scanpt ID|INDEXED */
@@ -149681,170 +150572,170 @@ static YYACTIONTYPE yy_reduce(
}
break;
case 35: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy70);}
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy96);}
break;
case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy70,yymsp[0].minor.yy70,yymsp[-2].minor.yy70);}
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy96,yymsp[0].minor.yy96,yymsp[-2].minor.yy96);}
break;
case 37: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy70,0,0,0,0,
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy96,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
case 38: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy18);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy490);}
break;
case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy420,yymsp[0].minor.yy70);}
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy42,yymsp[0].minor.yy96);}
break;
case 40: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy70);}
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy96);}
break;
case 41: /* ccons ::= COLLATE ID|STRING */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
case 44: /* refargs ::= */
-{ yymsp[1].minor.yy70 = OE_None*0x0101; /* EV: R-19803-45884 */}
+{ yymsp[1].minor.yy96 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
case 45: /* refargs ::= refargs refarg */
-{ yymsp[-1].minor.yy70 = (yymsp[-1].minor.yy70 & ~yymsp[0].minor.yy111.mask) | yymsp[0].minor.yy111.value; }
+{ yymsp[-1].minor.yy96 = (yymsp[-1].minor.yy96 & ~yymsp[0].minor.yy367.mask) | yymsp[0].minor.yy367.value; }
break;
case 46: /* refarg ::= MATCH nm */
-{ yymsp[-1].minor.yy111.value = 0; yymsp[-1].minor.yy111.mask = 0x000000; }
+{ yymsp[-1].minor.yy367.value = 0; yymsp[-1].minor.yy367.mask = 0x000000; }
break;
case 47: /* refarg ::= ON INSERT refact */
-{ yymsp[-2].minor.yy111.value = 0; yymsp[-2].minor.yy111.mask = 0x000000; }
+{ yymsp[-2].minor.yy367.value = 0; yymsp[-2].minor.yy367.mask = 0x000000; }
break;
case 48: /* refarg ::= ON DELETE refact */
-{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70; yymsp[-2].minor.yy111.mask = 0x0000ff; }
+{ yymsp[-2].minor.yy367.value = yymsp[0].minor.yy96; yymsp[-2].minor.yy367.mask = 0x0000ff; }
break;
case 49: /* refarg ::= ON UPDATE refact */
-{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70<<8; yymsp[-2].minor.yy111.mask = 0x00ff00; }
+{ yymsp[-2].minor.yy367.value = yymsp[0].minor.yy96<<8; yymsp[-2].minor.yy367.mask = 0x00ff00; }
break;
case 50: /* refact ::= SET NULL */
-{ yymsp[-1].minor.yy70 = OE_SetNull; /* EV: R-33326-45252 */}
+{ yymsp[-1].minor.yy96 = OE_SetNull; /* EV: R-33326-45252 */}
break;
case 51: /* refact ::= SET DEFAULT */
-{ yymsp[-1].minor.yy70 = OE_SetDflt; /* EV: R-33326-45252 */}
+{ yymsp[-1].minor.yy96 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
case 52: /* refact ::= CASCADE */
-{ yymsp[0].minor.yy70 = OE_Cascade; /* EV: R-33326-45252 */}
+{ yymsp[0].minor.yy96 = OE_Cascade; /* EV: R-33326-45252 */}
break;
case 53: /* refact ::= RESTRICT */
-{ yymsp[0].minor.yy70 = OE_Restrict; /* EV: R-33326-45252 */}
+{ yymsp[0].minor.yy96 = OE_Restrict; /* EV: R-33326-45252 */}
break;
case 54: /* refact ::= NO ACTION */
-{ yymsp[-1].minor.yy70 = OE_None; /* EV: R-33326-45252 */}
+{ yymsp[-1].minor.yy96 = OE_None; /* EV: R-33326-45252 */}
break;
case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
-{yymsp[-2].minor.yy70 = 0;}
+{yymsp[-2].minor.yy96 = 0;}
break;
case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71);
case 156: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==156);
-{yymsp[-1].minor.yy70 = yymsp[0].minor.yy70;}
+{yymsp[-1].minor.yy96 = yymsp[0].minor.yy96;}
break;
case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
case 198: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==198);
case 201: /* in_op ::= NOT IN */ yytestcase(yyruleno==201);
case 227: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==227);
-{yymsp[-1].minor.yy70 = 1;}
+{yymsp[-1].minor.yy96 = 1;}
break;
case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
-{yymsp[-1].minor.yy70 = 0;}
+{yymsp[-1].minor.yy96 = 0;}
break;
case 61: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy420,yymsp[0].minor.yy70,yymsp[-2].minor.yy70,0);}
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy42,yymsp[0].minor.yy96,yymsp[-2].minor.yy96,0);}
break;
case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy420,yymsp[0].minor.yy70,0,0,0,0,
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy42,yymsp[0].minor.yy96,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
case 65: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy18);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy490);}
break;
case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy420, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy70);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy70);
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy42, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy42, yymsp[-1].minor.yy96);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy96);
}
break;
case 68: /* onconf ::= */
case 70: /* orconf ::= */ yytestcase(yyruleno==70);
-{yymsp[1].minor.yy70 = OE_Default;}
+{yymsp[1].minor.yy96 = OE_Default;}
break;
case 69: /* onconf ::= ON CONFLICT resolvetype */
-{yymsp[-2].minor.yy70 = yymsp[0].minor.yy70;}
+{yymsp[-2].minor.yy96 = yymsp[0].minor.yy96;}
break;
case 72: /* resolvetype ::= IGNORE */
-{yymsp[0].minor.yy70 = OE_Ignore;}
+{yymsp[0].minor.yy96 = OE_Ignore;}
break;
case 73: /* resolvetype ::= REPLACE */
case 157: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==157);
-{yymsp[0].minor.yy70 = OE_Replace;}
+{yymsp[0].minor.yy96 = OE_Replace;}
break;
case 74: /* cmd ::= DROP TABLE ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy135, 0, yymsp[-1].minor.yy70);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy167, 0, yymsp[-1].minor.yy96);
}
break;
case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
{
- sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[0].minor.yy489, yymsp[-7].minor.yy70, yymsp[-5].minor.yy70);
+ sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy42, yymsp[0].minor.yy423, yymsp[-7].minor.yy96, yymsp[-5].minor.yy96);
}
break;
case 78: /* cmd ::= DROP VIEW ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy135, 1, yymsp[-1].minor.yy70);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy167, 1, yymsp[-1].minor.yy96);
}
break;
case 79: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy489, &dest);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
+ sqlite3Select(pParse, yymsp[0].minor.yy423, &dest);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy423);
}
break;
case 80: /* select ::= WITH wqlist selectnowith */
{
- Select *p = yymsp[0].minor.yy489;
+ Select *p = yymsp[0].minor.yy423;
if( p ){
- p->pWith = yymsp[-1].minor.yy449;
+ p->pWith = yymsp[-1].minor.yy499;
parserDoubleLinkSelect(pParse, p);
}else{
- sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy499);
}
- yymsp[-2].minor.yy489 = p;
+ yymsp[-2].minor.yy423 = p;
}
break;
case 81: /* select ::= WITH RECURSIVE wqlist selectnowith */
{
- Select *p = yymsp[0].minor.yy489;
+ Select *p = yymsp[0].minor.yy423;
if( p ){
- p->pWith = yymsp[-1].minor.yy449;
+ p->pWith = yymsp[-1].minor.yy499;
parserDoubleLinkSelect(pParse, p);
}else{
- sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy499);
}
- yymsp[-3].minor.yy489 = p;
+ yymsp[-3].minor.yy423 = p;
}
break;
case 82: /* select ::= selectnowith */
{
- Select *p = yymsp[0].minor.yy489;
+ Select *p = yymsp[0].minor.yy423;
if( p ){
parserDoubleLinkSelect(pParse, p);
}
- yymsp[0].minor.yy489 = p; /*A-overwrites-X*/
+ yymsp[0].minor.yy423 = p; /*A-overwrites-X*/
}
break;
case 83: /* selectnowith ::= selectnowith multiselect_op oneselect */
{
- Select *pRhs = yymsp[0].minor.yy489;
- Select *pLhs = yymsp[-2].minor.yy489;
+ Select *pRhs = yymsp[0].minor.yy423;
+ Select *pLhs = yymsp[-2].minor.yy423;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
@@ -149854,63 +150745,63 @@ static YYACTIONTYPE yy_reduce(
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
}
if( pRhs ){
- pRhs->op = (u8)yymsp[-1].minor.yy70;
+ pRhs->op = (u8)yymsp[-1].minor.yy96;
pRhs->pPrior = pLhs;
if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
pRhs->selFlags &= ~SF_MultiValue;
- if( yymsp[-1].minor.yy70!=TK_ALL ) pParse->hasCompound = 1;
+ if( yymsp[-1].minor.yy96!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, pLhs);
}
- yymsp[-2].minor.yy489 = pRhs;
+ yymsp[-2].minor.yy423 = pRhs;
}
break;
case 84: /* multiselect_op ::= UNION */
case 86: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==86);
-{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-OP*/}
+{yymsp[0].minor.yy96 = yymsp[0].major; /*A-overwrites-OP*/}
break;
case 85: /* multiselect_op ::= UNION ALL */
-{yymsp[-1].minor.yy70 = TK_ALL;}
+{yymsp[-1].minor.yy96 = TK_ALL;}
break;
case 87: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
- yymsp[-8].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy420,yymsp[-5].minor.yy135,yymsp[-4].minor.yy18,yymsp[-3].minor.yy420,yymsp[-2].minor.yy18,yymsp[-1].minor.yy420,yymsp[-7].minor.yy70,yymsp[0].minor.yy18);
+ yymsp[-8].minor.yy423 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy42,yymsp[-5].minor.yy167,yymsp[-4].minor.yy490,yymsp[-3].minor.yy42,yymsp[-2].minor.yy490,yymsp[-1].minor.yy42,yymsp[-7].minor.yy96,yymsp[0].minor.yy490);
}
break;
case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
{
- yymsp[-9].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy420,yymsp[-6].minor.yy135,yymsp[-5].minor.yy18,yymsp[-4].minor.yy420,yymsp[-3].minor.yy18,yymsp[-1].minor.yy420,yymsp[-8].minor.yy70,yymsp[0].minor.yy18);
- if( yymsp[-9].minor.yy489 ){
- yymsp[-9].minor.yy489->pWinDefn = yymsp[-2].minor.yy327;
+ yymsp[-9].minor.yy423 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy42,yymsp[-6].minor.yy167,yymsp[-5].minor.yy490,yymsp[-4].minor.yy42,yymsp[-3].minor.yy490,yymsp[-1].minor.yy42,yymsp[-8].minor.yy96,yymsp[0].minor.yy490);
+ if( yymsp[-9].minor.yy423 ){
+ yymsp[-9].minor.yy423->pWinDefn = yymsp[-2].minor.yy147;
}else{
- sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy327);
+ sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy147);
}
}
break;
case 89: /* values ::= VALUES LP nexprlist RP */
{
- yymsp[-3].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values,0);
+ yymsp[-3].minor.yy423 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy42,0,0,0,0,0,SF_Values,0);
}
break;
case 90: /* values ::= values COMMA LP nexprlist RP */
{
- Select *pRight, *pLeft = yymsp[-4].minor.yy489;
- pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values|SF_MultiValue,0);
+ Select *pRight, *pLeft = yymsp[-4].minor.yy423;
+ pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy42,0,0,0,0,0,SF_Values|SF_MultiValue,0);
if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
if( pRight ){
pRight->op = TK_ALL;
pRight->pPrior = pLeft;
- yymsp[-4].minor.yy489 = pRight;
+ yymsp[-4].minor.yy423 = pRight;
}else{
- yymsp[-4].minor.yy489 = pLeft;
+ yymsp[-4].minor.yy423 = pLeft;
}
}
break;
case 91: /* distinct ::= DISTINCT */
-{yymsp[0].minor.yy70 = SF_Distinct;}
+{yymsp[0].minor.yy96 = SF_Distinct;}
break;
case 92: /* distinct ::= ALL */
-{yymsp[0].minor.yy70 = SF_All;}
+{yymsp[0].minor.yy96 = SF_All;}
break;
case 94: /* sclp ::= */
case 127: /* orderby_opt ::= */ yytestcase(yyruleno==127);
@@ -149918,19 +150809,19 @@ static YYACTIONTYPE yy_reduce(
case 214: /* exprlist ::= */ yytestcase(yyruleno==214);
case 217: /* paren_exprlist ::= */ yytestcase(yyruleno==217);
case 222: /* eidlist_opt ::= */ yytestcase(yyruleno==222);
-{yymsp[1].minor.yy420 = 0;}
+{yymsp[1].minor.yy42 = 0;}
break;
case 95: /* selcollist ::= sclp scanpt expr scanpt as */
{
- yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[-2].minor.yy18);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy420,yymsp[-3].minor.yy392,yymsp[-1].minor.yy392);
+ yymsp[-4].minor.yy42 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy42, yymsp[-2].minor.yy490);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy42, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy42,yymsp[-3].minor.yy464,yymsp[-1].minor.yy464);
}
break;
case 96: /* selcollist ::= sclp scanpt STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
- yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy420, p);
+ yymsp[-2].minor.yy42 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy42, p);
}
break;
case 97: /* selcollist ::= sclp scanpt nm DOT STAR */
@@ -149938,70 +150829,76 @@ static YYACTIONTYPE yy_reduce(
Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
- yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, pDot);
+ yymsp[-4].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy42, pDot);
}
break;
case 98: /* as ::= AS nm */
case 109: /* dbnm ::= DOT nm */ yytestcase(yyruleno==109);
- case 236: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==236);
- case 237: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==237);
+ case 238: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==238);
+ case 239: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==239);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
break;
case 100: /* from ::= */
-{yymsp[1].minor.yy135 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy135));}
+{yymsp[1].minor.yy167 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy167));}
break;
case 101: /* from ::= FROM seltablist */
{
- yymsp[-1].minor.yy135 = yymsp[0].minor.yy135;
- sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy135);
+ yymsp[-1].minor.yy167 = yymsp[0].minor.yy167;
+ sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy167);
}
break;
case 102: /* stl_prefix ::= seltablist joinop */
{
- if( ALWAYS(yymsp[-1].minor.yy135 && yymsp[-1].minor.yy135->nSrc>0) ) yymsp[-1].minor.yy135->a[yymsp[-1].minor.yy135->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy70;
+ if( ALWAYS(yymsp[-1].minor.yy167 && yymsp[-1].minor.yy167->nSrc>0) ) yymsp[-1].minor.yy167->a[yymsp[-1].minor.yy167->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy96;
}
break;
case 103: /* stl_prefix ::= */
-{yymsp[1].minor.yy135 = 0;}
+{yymsp[1].minor.yy167 = 0;}
break;
case 104: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
{
- yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
- sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy135, &yymsp[-2].minor.yy0);
+ yymsp[-6].minor.yy167 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy167,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy490,yymsp[0].minor.yy336);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy167, &yymsp[-2].minor.yy0);
}
break;
case 105: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
{
- yymsp[-8].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy135,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
- sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy135, yymsp[-4].minor.yy420);
+ yymsp[-8].minor.yy167 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy167,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy490,yymsp[0].minor.yy336);
+ sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy167, yymsp[-4].minor.yy42);
}
break;
case 106: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
{
- yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy489,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
+ yymsp[-6].minor.yy167 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy167,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy423,yymsp[-1].minor.yy490,yymsp[0].minor.yy336);
}
break;
case 107: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
{
- if( yymsp[-6].minor.yy135==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy18==0 && yymsp[0].minor.yy48==0 ){
- yymsp[-6].minor.yy135 = yymsp[-4].minor.yy135;
- }else if( yymsp[-4].minor.yy135->nSrc==1 ){
- yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
- if( yymsp[-6].minor.yy135 ){
- struct SrcList_item *pNew = &yymsp[-6].minor.yy135->a[yymsp[-6].minor.yy135->nSrc-1];
- struct SrcList_item *pOld = yymsp[-4].minor.yy135->a;
+ if( yymsp[-6].minor.yy167==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy490==0 && yymsp[0].minor.yy336==0 ){
+ yymsp[-6].minor.yy167 = yymsp[-4].minor.yy167;
+ }else if( yymsp[-4].minor.yy167->nSrc==1 ){
+ yymsp[-6].minor.yy167 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy167,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy490,yymsp[0].minor.yy336);
+ if( yymsp[-6].minor.yy167 ){
+ struct SrcList_item *pNew = &yymsp[-6].minor.yy167->a[yymsp[-6].minor.yy167->nSrc-1];
+ struct SrcList_item *pOld = yymsp[-4].minor.yy167->a;
pNew->zName = pOld->zName;
pNew->zDatabase = pOld->zDatabase;
pNew->pSelect = pOld->pSelect;
+ if( pOld->fg.isTabFunc ){
+ pNew->u1.pFuncArg = pOld->u1.pFuncArg;
+ pOld->u1.pFuncArg = 0;
+ pOld->fg.isTabFunc = 0;
+ pNew->fg.isTabFunc = 1;
+ }
pOld->zName = pOld->zDatabase = 0;
pOld->pSelect = 0;
}
- sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy135);
+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy167);
}else{
Select *pSubquery;
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy135);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy135,0,0,0,0,SF_NestedFrom,0);
- yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
+ sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy167);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy167,0,0,0,0,SF_NestedFrom,0);
+ yymsp[-6].minor.yy167 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy167,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy490,yymsp[0].minor.yy336);
}
}
break;
@@ -150011,53 +150908,54 @@ static YYACTIONTYPE yy_reduce(
break;
case 110: /* fullname ::= nm */
{
- yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0);
- if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0);
+ yylhsminor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy167 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy167->a[0].zName, &yymsp[0].minor.yy0);
}
- yymsp[0].minor.yy135 = yylhsminor.yy135;
+ yymsp[0].minor.yy167 = yylhsminor.yy167;
break;
case 111: /* fullname ::= nm DOT nm */
{
- yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
- if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0);
+ yylhsminor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy167 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy167->a[0].zName, &yymsp[0].minor.yy0);
}
- yymsp[-2].minor.yy135 = yylhsminor.yy135;
+ yymsp[-2].minor.yy167 = yylhsminor.yy167;
break;
case 112: /* xfullname ::= nm */
-{yymsp[0].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
+{yymsp[0].minor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
break;
case 113: /* xfullname ::= nm DOT nm */
-{yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
+{yymsp[-2].minor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
case 114: /* xfullname ::= nm DOT nm AS nm */
{
- yymsp[-4].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
- if( yymsp[-4].minor.yy135 ) yymsp[-4].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+ yymsp[-4].minor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
+ if( yymsp[-4].minor.yy167 ) yymsp[-4].minor.yy167->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
case 115: /* xfullname ::= nm AS nm */
{
- yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
- if( yymsp[-2].minor.yy135 ) yymsp[-2].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+ yymsp[-2].minor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
+ if( yymsp[-2].minor.yy167 ) yymsp[-2].minor.yy167->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
case 116: /* joinop ::= COMMA|JOIN */
-{ yymsp[0].minor.yy70 = JT_INNER; }
+{ yymsp[0].minor.yy96 = JT_INNER; }
break;
case 117: /* joinop ::= JOIN_KW JOIN */
-{yymsp[-1].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
+{yymsp[-1].minor.yy96 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
break;
case 118: /* joinop ::= JOIN_KW nm JOIN */
-{yymsp[-2].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
+{yymsp[-2].minor.yy96 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
break;
case 119: /* joinop ::= JOIN_KW nm nm JOIN */
-{yymsp[-3].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
+{yymsp[-3].minor.yy96 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
break;
case 120: /* on_opt ::= ON expr */
case 137: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==137);
case 144: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==144);
case 210: /* case_else ::= ELSE expr */ yytestcase(yyruleno==210);
-{yymsp[-1].minor.yy18 = yymsp[0].minor.yy18;}
+ case 231: /* vinto ::= INTO expr */ yytestcase(yyruleno==231);
+{yymsp[-1].minor.yy490 = yymsp[0].minor.yy490;}
break;
case 121: /* on_opt ::= */
case 136: /* having_opt ::= */ yytestcase(yyruleno==136);
@@ -150065,7 +150963,8 @@ static YYACTIONTYPE yy_reduce(
case 143: /* where_opt ::= */ yytestcase(yyruleno==143);
case 211: /* case_else ::= */ yytestcase(yyruleno==211);
case 213: /* case_operand ::= */ yytestcase(yyruleno==213);
-{yymsp[1].minor.yy18 = 0;}
+ case 232: /* vinto ::= */ yytestcase(yyruleno==232);
+{yymsp[1].minor.yy490 = 0;}
break;
case 123: /* indexed_opt ::= INDEXED BY nm */
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
@@ -150074,119 +150973,119 @@ static YYACTIONTYPE yy_reduce(
{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
break;
case 125: /* using_opt ::= USING LP idlist RP */
-{yymsp[-3].minor.yy48 = yymsp[-1].minor.yy48;}
+{yymsp[-3].minor.yy336 = yymsp[-1].minor.yy336;}
break;
case 126: /* using_opt ::= */
case 158: /* idlist_opt ::= */ yytestcase(yyruleno==158);
-{yymsp[1].minor.yy48 = 0;}
+{yymsp[1].minor.yy336 = 0;}
break;
case 128: /* orderby_opt ::= ORDER BY sortlist */
case 135: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==135);
-{yymsp[-2].minor.yy420 = yymsp[0].minor.yy420;}
+{yymsp[-2].minor.yy42 = yymsp[0].minor.yy42;}
break;
case 129: /* sortlist ::= sortlist COMMA expr sortorder */
{
- yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420,yymsp[-1].minor.yy18);
- sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy420,yymsp[0].minor.yy70);
+ yymsp[-3].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy42,yymsp[-1].minor.yy490);
+ sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy42,yymsp[0].minor.yy96);
}
break;
case 130: /* sortlist ::= expr sortorder */
{
- yymsp[-1].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy18); /*A-overwrites-Y*/
- sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy420,yymsp[0].minor.yy70);
+ yymsp[-1].minor.yy42 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy490); /*A-overwrites-Y*/
+ sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy42,yymsp[0].minor.yy96);
}
break;
case 131: /* sortorder ::= ASC */
-{yymsp[0].minor.yy70 = SQLITE_SO_ASC;}
+{yymsp[0].minor.yy96 = SQLITE_SO_ASC;}
break;
case 132: /* sortorder ::= DESC */
-{yymsp[0].minor.yy70 = SQLITE_SO_DESC;}
+{yymsp[0].minor.yy96 = SQLITE_SO_DESC;}
break;
case 133: /* sortorder ::= */
-{yymsp[1].minor.yy70 = SQLITE_SO_UNDEFINED;}
+{yymsp[1].minor.yy96 = SQLITE_SO_UNDEFINED;}
break;
case 139: /* limit_opt ::= LIMIT expr */
-{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,0);}
+{yymsp[-1].minor.yy490 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy490,0);}
break;
case 140: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);}
+{yymsp[-3].minor.yy490 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy490,yymsp[0].minor.yy490);}
break;
case 141: /* limit_opt ::= LIMIT expr COMMA expr */
-{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,yymsp[-2].minor.yy18);}
+{yymsp[-3].minor.yy490 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy490,yymsp[-2].minor.yy490);}
break;
case 142: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy135, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy135,yymsp[0].minor.yy18,0,0);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy167, &yymsp[-1].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy167,yymsp[0].minor.yy490,0,0);
}
break;
case 145: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy135, &yymsp[-3].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy420,"set list");
- sqlite3Update(pParse,yymsp[-4].minor.yy135,yymsp[-1].minor.yy420,yymsp[0].minor.yy18,yymsp[-5].minor.yy70,0,0,0);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy167, &yymsp[-3].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy42,"set list");
+ sqlite3Update(pParse,yymsp[-4].minor.yy167,yymsp[-1].minor.yy42,yymsp[0].minor.yy490,yymsp[-5].minor.yy96,0,0,0);
}
break;
case 146: /* setlist ::= setlist COMMA nm EQ expr */
{
- yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[0].minor.yy18);
- sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, 1);
+ yymsp[-4].minor.yy42 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy42, yymsp[0].minor.yy490);
+ sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy42, &yymsp[-2].minor.yy0, 1);
}
break;
case 147: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
{
- yymsp[-6].minor.yy420 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy420, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
+ yymsp[-6].minor.yy42 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy42, yymsp[-3].minor.yy336, yymsp[0].minor.yy490);
}
break;
case 148: /* setlist ::= nm EQ expr */
{
- yylhsminor.yy420 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy18);
- sqlite3ExprListSetName(pParse, yylhsminor.yy420, &yymsp[-2].minor.yy0, 1);
+ yylhsminor.yy42 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy490);
+ sqlite3ExprListSetName(pParse, yylhsminor.yy42, &yymsp[-2].minor.yy0, 1);
}
- yymsp[-2].minor.yy420 = yylhsminor.yy420;
+ yymsp[-2].minor.yy42 = yylhsminor.yy42;
break;
case 149: /* setlist ::= LP idlist RP EQ expr */
{
- yymsp[-4].minor.yy420 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
+ yymsp[-4].minor.yy42 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy336, yymsp[0].minor.yy490);
}
break;
case 150: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
{
- sqlite3Insert(pParse, yymsp[-3].minor.yy135, yymsp[-1].minor.yy489, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, yymsp[0].minor.yy340);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy167, yymsp[-1].minor.yy423, yymsp[-2].minor.yy336, yymsp[-5].minor.yy96, yymsp[0].minor.yy266);
}
break;
case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
{
- sqlite3Insert(pParse, yymsp[-3].minor.yy135, 0, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, 0);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy167, 0, yymsp[-2].minor.yy336, yymsp[-5].minor.yy96, 0);
}
break;
case 152: /* upsert ::= */
-{ yymsp[1].minor.yy340 = 0; }
+{ yymsp[1].minor.yy266 = 0; }
break;
case 153: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
-{ yymsp[-10].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy420,yymsp[-5].minor.yy18,yymsp[-1].minor.yy420,yymsp[0].minor.yy18);}
+{ yymsp[-10].minor.yy266 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy42,yymsp[-5].minor.yy490,yymsp[-1].minor.yy42,yymsp[0].minor.yy490);}
break;
case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
-{ yymsp[-7].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy420,yymsp[-2].minor.yy18,0,0); }
+{ yymsp[-7].minor.yy266 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy42,yymsp[-2].minor.yy490,0,0); }
break;
case 155: /* upsert ::= ON CONFLICT DO NOTHING */
-{ yymsp[-3].minor.yy340 = sqlite3UpsertNew(pParse->db,0,0,0,0); }
+{ yymsp[-3].minor.yy266 = sqlite3UpsertNew(pParse->db,0,0,0,0); }
break;
case 159: /* idlist_opt ::= LP idlist RP */
-{yymsp[-2].minor.yy48 = yymsp[-1].minor.yy48;}
+{yymsp[-2].minor.yy336 = yymsp[-1].minor.yy336;}
break;
case 160: /* idlist ::= idlist COMMA nm */
-{yymsp[-2].minor.yy48 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy48,&yymsp[0].minor.yy0);}
+{yymsp[-2].minor.yy336 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy336,&yymsp[0].minor.yy0);}
break;
case 161: /* idlist ::= nm */
-{yymsp[0].minor.yy48 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
+{yymsp[0].minor.yy336 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
break;
case 162: /* expr ::= LP expr RP */
-{yymsp[-2].minor.yy18 = yymsp[-1].minor.yy18;}
+{yymsp[-2].minor.yy490 = yymsp[-1].minor.yy490;}
break;
case 163: /* expr ::= ID|INDEXED */
case 164: /* expr ::= JOIN_KW */ yytestcase(yyruleno==164);
-{yymsp[0].minor.yy18=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+{yymsp[0].minor.yy490=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
case 165: /* expr ::= nm DOT nm */
{
@@ -150196,9 +151095,9 @@ static YYACTIONTYPE yy_reduce(
sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
}
- yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
+ yylhsminor.yy490 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
- yymsp[-2].minor.yy18 = yylhsminor.yy18;
+ yymsp[-2].minor.yy490 = yylhsminor.yy490;
break;
case 166: /* expr ::= nm DOT nm DOT nm */
{
@@ -150210,26 +151109,26 @@ static YYACTIONTYPE yy_reduce(
sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
}
- yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
+ yylhsminor.yy490 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
- yymsp[-4].minor.yy18 = yylhsminor.yy18;
+ yymsp[-4].minor.yy490 = yylhsminor.yy490;
break;
case 167: /* term ::= NULL|FLOAT|BLOB */
case 168: /* term ::= STRING */ yytestcase(yyruleno==168);
-{yymsp[0].minor.yy18=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+{yymsp[0].minor.yy490=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
case 169: /* term ::= INTEGER */
{
- yylhsminor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
+ yylhsminor.yy490 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
}
- yymsp[0].minor.yy18 = yylhsminor.yy18;
+ yymsp[0].minor.yy490 = yylhsminor.yy490;
break;
case 170: /* expr ::= VARIABLE */
{
if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
u32 n = yymsp[0].minor.yy0.n;
- yymsp[0].minor.yy18 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy18, n);
+ yymsp[0].minor.yy490 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy490, n);
}else{
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
@@ -150238,63 +151137,63 @@ static YYACTIONTYPE yy_reduce(
assert( t.n>=2 );
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
- yymsp[0].minor.yy18 = 0;
+ yymsp[0].minor.yy490 = 0;
}else{
- yymsp[0].minor.yy18 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
- if( yymsp[0].minor.yy18 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy18->iTable);
+ yymsp[0].minor.yy490 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
+ if( yymsp[0].minor.yy490 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy490->iTable);
}
}
}
break;
case 171: /* expr ::= expr COLLATE ID|STRING */
{
- yymsp[-2].minor.yy18 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy18, &yymsp[0].minor.yy0, 1);
+ yymsp[-2].minor.yy490 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy490, &yymsp[0].minor.yy0, 1);
}
break;
case 172: /* expr ::= CAST LP expr AS typetoken RP */
{
- yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
- sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy18, yymsp[-3].minor.yy18, 0);
+ yymsp[-5].minor.yy490 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
+ sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy490, yymsp[-3].minor.yy490, 0);
}
break;
case 173: /* expr ::= ID|INDEXED LP distinct exprlist RP */
{
- yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy420, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy70);
+ yylhsminor.yy490 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy42, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy96);
}
- yymsp[-4].minor.yy18 = yylhsminor.yy18;
+ yymsp[-4].minor.yy490 = yylhsminor.yy490;
break;
case 174: /* expr ::= ID|INDEXED LP STAR RP */
{
- yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
+ yylhsminor.yy490 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
}
- yymsp[-3].minor.yy18 = yylhsminor.yy18;
+ yymsp[-3].minor.yy490 = yylhsminor.yy490;
break;
case 175: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
{
- yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy420, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy70);
- sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
+ yylhsminor.yy490 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy42, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy96);
+ sqlite3WindowAttach(pParse, yylhsminor.yy490, yymsp[0].minor.yy147);
}
- yymsp[-5].minor.yy18 = yylhsminor.yy18;
+ yymsp[-5].minor.yy490 = yylhsminor.yy490;
break;
case 176: /* expr ::= ID|INDEXED LP STAR RP over_clause */
{
- yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
- sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
+ yylhsminor.yy490 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
+ sqlite3WindowAttach(pParse, yylhsminor.yy490, yymsp[0].minor.yy147);
}
- yymsp[-4].minor.yy18 = yylhsminor.yy18;
+ yymsp[-4].minor.yy490 = yylhsminor.yy490;
break;
case 177: /* term ::= CTIME_KW */
{
- yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
+ yylhsminor.yy490 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
}
- yymsp[0].minor.yy18 = yylhsminor.yy18;
+ yymsp[0].minor.yy490 = yylhsminor.yy490;
break;
case 178: /* expr ::= LP nexprlist COMMA expr RP */
{
- ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy420, yymsp[-1].minor.yy18);
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
- if( yymsp[-4].minor.yy18 ){
- yymsp[-4].minor.yy18->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy42, yymsp[-1].minor.yy490);
+ yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( yymsp[-4].minor.yy490 ){
+ yymsp[-4].minor.yy490->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
@@ -150308,7 +151207,7 @@ static YYACTIONTYPE yy_reduce(
case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184);
case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185);
case 186: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==186);
-{yymsp[-2].minor.yy18=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);}
+{yymsp[-2].minor.yy490=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy490,yymsp[0].minor.yy490);}
break;
case 187: /* likeop ::= NOT LIKE_KW|MATCH */
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
@@ -150318,11 +151217,11 @@ static YYACTIONTYPE yy_reduce(
ExprList *pList;
int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
yymsp[-1].minor.yy0.n &= 0x7fffffff;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy18);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy18);
- yymsp[-2].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
- if( bNot ) yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy18, 0);
- if( yymsp[-2].minor.yy18 ) yymsp[-2].minor.yy18->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy490);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy490);
+ yymsp[-2].minor.yy490 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
+ if( bNot ) yymsp[-2].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy490, 0);
+ if( yymsp[-2].minor.yy490 ) yymsp[-2].minor.yy490->flags |= EP_InfixFunc;
}
break;
case 189: /* expr ::= expr likeop expr ESCAPE expr */
@@ -150330,62 +151229,62 @@ static YYACTIONTYPE yy_reduce(
ExprList *pList;
int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
yymsp[-3].minor.yy0.n &= 0x7fffffff;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy18);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18);
- yymsp[-4].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
- if( bNot ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
- if( yymsp[-4].minor.yy18 ) yymsp[-4].minor.yy18->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy490);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy490);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy490);
+ yymsp[-4].minor.yy490 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
+ if( bNot ) yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy490, 0);
+ if( yymsp[-4].minor.yy490 ) yymsp[-4].minor.yy490->flags |= EP_InfixFunc;
}
break;
case 190: /* expr ::= expr ISNULL|NOTNULL */
-{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy18,0);}
+{yymsp[-1].minor.yy490 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy490,0);}
break;
case 191: /* expr ::= expr NOT NULL */
-{yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy18,0);}
+{yymsp[-2].minor.yy490 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy490,0);}
break;
case 192: /* expr ::= expr IS expr */
{
- yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-2].minor.yy18, TK_ISNULL);
+ yymsp[-2].minor.yy490 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy490,yymsp[0].minor.yy490);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy490, yymsp[-2].minor.yy490, TK_ISNULL);
}
break;
case 193: /* expr ::= expr IS NOT expr */
{
- yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy18,yymsp[0].minor.yy18);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-3].minor.yy18, TK_NOTNULL);
+ yymsp[-3].minor.yy490 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy490,yymsp[0].minor.yy490);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy490, yymsp[-3].minor.yy490, TK_NOTNULL);
}
break;
case 194: /* expr ::= NOT expr */
case 195: /* expr ::= BITNOT expr */ yytestcase(yyruleno==195);
-{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy18, 0);/*A-overwrites-B*/}
+{yymsp[-1].minor.yy490 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy490, 0);/*A-overwrites-B*/}
break;
case 196: /* expr ::= PLUS|MINUS expr */
{
- yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy18, 0);
+ yymsp[-1].minor.yy490 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy490, 0);
/*A-overwrites-B*/
}
break;
case 197: /* between_op ::= BETWEEN */
case 200: /* in_op ::= IN */ yytestcase(yyruleno==200);
-{yymsp[0].minor.yy70 = 0;}
+{yymsp[0].minor.yy96 = 0;}
break;
case 199: /* expr ::= expr between_op expr AND expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18);
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy18, 0);
- if( yymsp[-4].minor.yy18 ){
- yymsp[-4].minor.yy18->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy490);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy490);
+ yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy490, 0);
+ if( yymsp[-4].minor.yy490 ){
+ yymsp[-4].minor.yy490->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+ if( yymsp[-3].minor.yy96 ) yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy490, 0);
}
break;
case 202: /* expr ::= expr in_op LP exprlist RP */
{
- if( yymsp[-1].minor.yy420==0 ){
+ if( yymsp[-1].minor.yy42==0 ){
/* Expressions of the form
**
** expr1 IN ()
@@ -150394,9 +151293,11 @@ static YYACTIONTYPE yy_reduce(
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy18);
- yymsp[-4].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy70],1);
- }else if( yymsp[-1].minor.yy420->nExpr==1 ){
+ if( IN_RENAME_OBJECT==0 ){
+ sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy490);
+ yymsp[-4].minor.yy490 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy96],1);
+ }
+ }else if( yymsp[-1].minor.yy42->nExpr==1 ){
/* Expressions of the form:
**
** expr1 IN (?1)
@@ -150413,199 +151314,199 @@ static YYACTIONTYPE yy_reduce(
** affinity or the collating sequence to use for comparison. Otherwise,
** the semantics would be subtly different from IN or NOT IN.
*/
- Expr *pRHS = yymsp[-1].minor.yy420->a[0].pExpr;
- yymsp[-1].minor.yy420->a[0].pExpr = 0;
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
+ Expr *pRHS = yymsp[-1].minor.yy42->a[0].pExpr;
+ yymsp[-1].minor.yy42->a[0].pExpr = 0;
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy42);
/* pRHS cannot be NULL because a malloc error would have been detected
** before now and control would have never reached this point */
if( ALWAYS(pRHS) ){
pRHS->flags &= ~EP_Collate;
pRHS->flags |= EP_Generic;
}
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, yymsp[-3].minor.yy70 ? TK_NE : TK_EQ, yymsp[-4].minor.yy18, pRHS);
+ yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, yymsp[-3].minor.yy96 ? TK_NE : TK_EQ, yymsp[-4].minor.yy490, pRHS);
}else{
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
- if( yymsp[-4].minor.yy18 ){
- yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy420;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18);
+ yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy490, 0);
+ if( yymsp[-4].minor.yy490 ){
+ yymsp[-4].minor.yy490->x.pList = yymsp[-1].minor.yy42;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy490);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy42);
}
- if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+ if( yymsp[-3].minor.yy96 ) yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy490, 0);
}
}
break;
case 203: /* expr ::= LP select RP */
{
- yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy18, yymsp[-1].minor.yy489);
+ yymsp[-2].minor.yy490 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy490, yymsp[-1].minor.yy423);
}
break;
case 204: /* expr ::= expr in_op LP select RP */
{
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, yymsp[-1].minor.yy489);
- if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+ yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy490, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy490, yymsp[-1].minor.yy423);
+ if( yymsp[-3].minor.yy96 ) yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy490, 0);
}
break;
case 205: /* expr ::= expr in_op nm dbnm paren_exprlist */
{
- SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
+ SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
- if( yymsp[0].minor.yy420 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy420);
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, pSelect);
- if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+ if( yymsp[0].minor.yy42 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy42);
+ yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy490, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy490, pSelect);
+ if( yymsp[-3].minor.yy96 ) yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy490, 0);
}
break;
case 206: /* expr ::= EXISTS LP select RP */
{
Expr *p;
- p = yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
- sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy489);
+ p = yymsp[-3].minor.yy490 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
+ sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy423);
}
break;
case 207: /* expr ::= CASE case_operand case_exprlist case_else END */
{
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy18, 0);
- if( yymsp[-4].minor.yy18 ){
- yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy18 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[-1].minor.yy18) : yymsp[-2].minor.yy420;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18);
+ yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy490, 0);
+ if( yymsp[-4].minor.yy490 ){
+ yymsp[-4].minor.yy490->x.pList = yymsp[-1].minor.yy490 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy42,yymsp[-1].minor.yy490) : yymsp[-2].minor.yy42;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy490);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy420);
- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy18);
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy42);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy490);
}
}
break;
case 208: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
- yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[-2].minor.yy18);
- yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[0].minor.yy18);
+ yymsp[-4].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy42, yymsp[-2].minor.yy490);
+ yymsp[-4].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy42, yymsp[0].minor.yy490);
}
break;
case 209: /* case_exprlist ::= WHEN expr THEN expr */
{
- yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
- yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420, yymsp[0].minor.yy18);
+ yymsp[-3].minor.yy42 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy490);
+ yymsp[-3].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy42, yymsp[0].minor.yy490);
}
break;
case 212: /* case_operand ::= expr */
-{yymsp[0].minor.yy18 = yymsp[0].minor.yy18; /*A-overwrites-X*/}
+{yymsp[0].minor.yy490 = yymsp[0].minor.yy490; /*A-overwrites-X*/}
break;
case 215: /* nexprlist ::= nexprlist COMMA expr */
-{yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[0].minor.yy18);}
+{yymsp[-2].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy42,yymsp[0].minor.yy490);}
break;
case 216: /* nexprlist ::= expr */
-{yymsp[0].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy18); /*A-overwrites-Y*/}
+{yymsp[0].minor.yy42 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy490); /*A-overwrites-Y*/}
break;
case 218: /* paren_exprlist ::= LP exprlist RP */
case 223: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==223);
-{yymsp[-2].minor.yy420 = yymsp[-1].minor.yy420;}
+{yymsp[-2].minor.yy42 = yymsp[-1].minor.yy42;}
break;
case 219: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
{
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
- sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy420, yymsp[-10].minor.yy70,
- &yymsp[-11].minor.yy0, yymsp[0].minor.yy18, SQLITE_SO_ASC, yymsp[-8].minor.yy70, SQLITE_IDXTYPE_APPDEF);
+ sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy42, yymsp[-10].minor.yy96,
+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy490, SQLITE_SO_ASC, yymsp[-8].minor.yy96, SQLITE_IDXTYPE_APPDEF);
if( IN_RENAME_OBJECT && pParse->pNewIndex ){
sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
}
}
break;
case 220: /* uniqueflag ::= UNIQUE */
- case 260: /* raisetype ::= ABORT */ yytestcase(yyruleno==260);
-{yymsp[0].minor.yy70 = OE_Abort;}
+ case 262: /* raisetype ::= ABORT */ yytestcase(yyruleno==262);
+{yymsp[0].minor.yy96 = OE_Abort;}
break;
case 221: /* uniqueflag ::= */
-{yymsp[1].minor.yy70 = OE_None;}
+{yymsp[1].minor.yy96 = OE_None;}
break;
case 224: /* eidlist ::= eidlist COMMA nm collate sortorder */
{
- yymsp[-4].minor.yy420 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70);
+ yymsp[-4].minor.yy42 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy42, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy96, yymsp[0].minor.yy96);
}
break;
case 225: /* eidlist ::= nm collate sortorder */
{
- yymsp[-2].minor.yy420 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); /*A-overwrites-Y*/
+ yymsp[-2].minor.yy42 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy96, yymsp[0].minor.yy96); /*A-overwrites-Y*/
}
break;
case 228: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy135, yymsp[-1].minor.yy70);}
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy167, yymsp[-1].minor.yy96);}
break;
- case 229: /* cmd ::= VACUUM */
-{sqlite3Vacuum(pParse,0);}
+ case 229: /* cmd ::= VACUUM vinto */
+{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy490);}
break;
- case 230: /* cmd ::= VACUUM nm */
-{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
+ case 230: /* cmd ::= VACUUM nm vinto */
+{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy490);}
break;
- case 231: /* cmd ::= PRAGMA nm dbnm */
+ case 233: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 232: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 234: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 233: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 235: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 234: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 236: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 235: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 237: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
- case 238: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 240: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
- sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy207, &all);
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy119, &all);
}
break;
- case 239: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 241: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
- sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy70, yymsp[-4].minor.yy34.a, yymsp[-4].minor.yy34.b, yymsp[-2].minor.yy135, yymsp[0].minor.yy18, yymsp[-10].minor.yy70, yymsp[-8].minor.yy70);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy96, yymsp[-4].minor.yy350.a, yymsp[-4].minor.yy350.b, yymsp[-2].minor.yy167, yymsp[0].minor.yy490, yymsp[-10].minor.yy96, yymsp[-8].minor.yy96);
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
}
break;
- case 240: /* trigger_time ::= BEFORE|AFTER */
-{ yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/ }
+ case 242: /* trigger_time ::= BEFORE|AFTER */
+{ yymsp[0].minor.yy96 = yymsp[0].major; /*A-overwrites-X*/ }
break;
- case 241: /* trigger_time ::= INSTEAD OF */
-{ yymsp[-1].minor.yy70 = TK_INSTEAD;}
+ case 243: /* trigger_time ::= INSTEAD OF */
+{ yymsp[-1].minor.yy96 = TK_INSTEAD;}
break;
- case 242: /* trigger_time ::= */
-{ yymsp[1].minor.yy70 = TK_BEFORE; }
+ case 244: /* trigger_time ::= */
+{ yymsp[1].minor.yy96 = TK_BEFORE; }
break;
- case 243: /* trigger_event ::= DELETE|INSERT */
- case 244: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==244);
-{yymsp[0].minor.yy34.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy34.b = 0;}
+ case 245: /* trigger_event ::= DELETE|INSERT */
+ case 246: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==246);
+{yymsp[0].minor.yy350.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy350.b = 0;}
break;
- case 245: /* trigger_event ::= UPDATE OF idlist */
-{yymsp[-2].minor.yy34.a = TK_UPDATE; yymsp[-2].minor.yy34.b = yymsp[0].minor.yy48;}
+ case 247: /* trigger_event ::= UPDATE OF idlist */
+{yymsp[-2].minor.yy350.a = TK_UPDATE; yymsp[-2].minor.yy350.b = yymsp[0].minor.yy336;}
break;
- case 246: /* when_clause ::= */
- case 265: /* key_opt ::= */ yytestcase(yyruleno==265);
- case 307: /* filter_opt ::= */ yytestcase(yyruleno==307);
-{ yymsp[1].minor.yy18 = 0; }
+ case 248: /* when_clause ::= */
+ case 267: /* key_opt ::= */ yytestcase(yyruleno==267);
+ case 309: /* filter_opt ::= */ yytestcase(yyruleno==309);
+{ yymsp[1].minor.yy490 = 0; }
break;
- case 247: /* when_clause ::= WHEN expr */
- case 266: /* key_opt ::= KEY expr */ yytestcase(yyruleno==266);
-{ yymsp[-1].minor.yy18 = yymsp[0].minor.yy18; }
+ case 249: /* when_clause ::= WHEN expr */
+ case 268: /* key_opt ::= KEY expr */ yytestcase(yyruleno==268);
+{ yymsp[-1].minor.yy490 = yymsp[0].minor.yy490; }
break;
- case 248: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 250: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
- assert( yymsp[-2].minor.yy207!=0 );
- yymsp[-2].minor.yy207->pLast->pNext = yymsp[-1].minor.yy207;
- yymsp[-2].minor.yy207->pLast = yymsp[-1].minor.yy207;
+ assert( yymsp[-2].minor.yy119!=0 );
+ yymsp[-2].minor.yy119->pLast->pNext = yymsp[-1].minor.yy119;
+ yymsp[-2].minor.yy119->pLast = yymsp[-1].minor.yy119;
}
break;
- case 249: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 251: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
- assert( yymsp[-1].minor.yy207!=0 );
- yymsp[-1].minor.yy207->pLast = yymsp[-1].minor.yy207;
+ assert( yymsp[-1].minor.yy119!=0 );
+ yymsp[-1].minor.yy119->pLast = yymsp[-1].minor.yy119;
}
break;
- case 250: /* trnm ::= nm DOT nm */
+ case 252: /* trnm ::= nm DOT nm */
{
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -150613,312 +151514,312 @@ static YYACTIONTYPE yy_reduce(
"statements within triggers");
}
break;
- case 251: /* tridxby ::= INDEXED BY nm */
+ case 253: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 252: /* tridxby ::= NOT INDEXED */
+ case 254: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 253: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
-{yylhsminor.yy207 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy18, yymsp[-6].minor.yy70, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy392);}
- yymsp[-7].minor.yy207 = yylhsminor.yy207;
+ case 255: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+{yylhsminor.yy119 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy42, yymsp[-1].minor.yy490, yymsp[-6].minor.yy96, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy464);}
+ yymsp[-7].minor.yy119 = yylhsminor.yy119;
break;
- case 254: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ case 256: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
{
- yylhsminor.yy207 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy48,yymsp[-2].minor.yy489,yymsp[-6].minor.yy70,yymsp[-1].minor.yy340,yymsp[-7].minor.yy392,yymsp[0].minor.yy392);/*yylhsminor.yy207-overwrites-yymsp[-6].minor.yy70*/
+ yylhsminor.yy119 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy336,yymsp[-2].minor.yy423,yymsp[-6].minor.yy96,yymsp[-1].minor.yy266,yymsp[-7].minor.yy464,yymsp[0].minor.yy464);/*yylhsminor.yy119-overwrites-yymsp[-6].minor.yy96*/
}
- yymsp[-7].minor.yy207 = yylhsminor.yy207;
+ yymsp[-7].minor.yy119 = yylhsminor.yy119;
break;
- case 255: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
-{yylhsminor.yy207 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy18, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy392);}
- yymsp[-5].minor.yy207 = yylhsminor.yy207;
+ case 257: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+{yylhsminor.yy119 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy490, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy464);}
+ yymsp[-5].minor.yy119 = yylhsminor.yy119;
break;
- case 256: /* trigger_cmd ::= scanpt select scanpt */
-{yylhsminor.yy207 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy489, yymsp[-2].minor.yy392, yymsp[0].minor.yy392); /*yylhsminor.yy207-overwrites-yymsp[-1].minor.yy489*/}
- yymsp[-2].minor.yy207 = yylhsminor.yy207;
+ case 258: /* trigger_cmd ::= scanpt select scanpt */
+{yylhsminor.yy119 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy423, yymsp[-2].minor.yy464, yymsp[0].minor.yy464); /*yylhsminor.yy119-overwrites-yymsp[-1].minor.yy423*/}
+ yymsp[-2].minor.yy119 = yylhsminor.yy119;
break;
- case 257: /* expr ::= RAISE LP IGNORE RP */
+ case 259: /* expr ::= RAISE LP IGNORE RP */
{
- yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
- if( yymsp[-3].minor.yy18 ){
- yymsp[-3].minor.yy18->affinity = OE_Ignore;
+ yymsp[-3].minor.yy490 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
+ if( yymsp[-3].minor.yy490 ){
+ yymsp[-3].minor.yy490->affinity = OE_Ignore;
}
}
break;
- case 258: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 260: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
- yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
- if( yymsp[-5].minor.yy18 ) {
- yymsp[-5].minor.yy18->affinity = (char)yymsp[-3].minor.yy70;
+ yymsp[-5].minor.yy490 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
+ if( yymsp[-5].minor.yy490 ) {
+ yymsp[-5].minor.yy490->affinity = (char)yymsp[-3].minor.yy96;
}
}
break;
- case 259: /* raisetype ::= ROLLBACK */
-{yymsp[0].minor.yy70 = OE_Rollback;}
+ case 261: /* raisetype ::= ROLLBACK */
+{yymsp[0].minor.yy96 = OE_Rollback;}
break;
- case 261: /* raisetype ::= FAIL */
-{yymsp[0].minor.yy70 = OE_Fail;}
+ case 263: /* raisetype ::= FAIL */
+{yymsp[0].minor.yy96 = OE_Fail;}
break;
- case 262: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 264: /* cmd ::= DROP TRIGGER ifexists fullname */
{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy135,yymsp[-1].minor.yy70);
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy167,yymsp[-1].minor.yy96);
}
break;
- case 263: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 265: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
- sqlite3Attach(pParse, yymsp[-3].minor.yy18, yymsp[-1].minor.yy18, yymsp[0].minor.yy18);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy490, yymsp[-1].minor.yy490, yymsp[0].minor.yy490);
}
break;
- case 264: /* cmd ::= DETACH database_kw_opt expr */
+ case 266: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy18);
+ sqlite3Detach(pParse, yymsp[0].minor.yy490);
}
break;
- case 267: /* cmd ::= REINDEX */
+ case 269: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 268: /* cmd ::= REINDEX nm dbnm */
+ case 270: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 269: /* cmd ::= ANALYZE */
+ case 271: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 270: /* cmd ::= ANALYZE nm dbnm */
+ case 272: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 271: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 273: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy135,&yymsp[0].minor.yy0);
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy167,&yymsp[0].minor.yy0);
}
break;
- case 272: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ case 274: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
{
yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
}
break;
- case 273: /* add_column_fullname ::= fullname */
+ case 275: /* add_column_fullname ::= fullname */
{
disableLookaside(pParse);
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy135);
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy167);
}
break;
- case 274: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ case 276: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
{
- sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy135, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
+ sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy167, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 275: /* cmd ::= create_vtab */
+ case 277: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 276: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 278: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 277: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 279: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
- sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy70);
+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy96);
}
break;
- case 278: /* vtabarg ::= */
+ case 280: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 279: /* vtabargtoken ::= ANY */
- case 280: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==280);
- case 281: /* lp ::= LP */ yytestcase(yyruleno==281);
+ case 281: /* vtabargtoken ::= ANY */
+ case 282: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==282);
+ case 283: /* lp ::= LP */ yytestcase(yyruleno==283);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
- case 282: /* with ::= WITH wqlist */
- case 283: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==283);
-{ sqlite3WithPush(pParse, yymsp[0].minor.yy449, 1); }
+ case 284: /* with ::= WITH wqlist */
+ case 285: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==285);
+{ sqlite3WithPush(pParse, yymsp[0].minor.yy499, 1); }
break;
- case 284: /* wqlist ::= nm eidlist_opt AS LP select RP */
+ case 286: /* wqlist ::= nm eidlist_opt AS LP select RP */
{
- yymsp[-5].minor.yy449 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489); /*A-overwrites-X*/
+ yymsp[-5].minor.yy499 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy42, yymsp[-1].minor.yy423); /*A-overwrites-X*/
}
break;
- case 285: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ case 287: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
{
- yymsp[-7].minor.yy449 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy449, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489);
+ yymsp[-7].minor.yy499 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy499, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy42, yymsp[-1].minor.yy423);
}
break;
- case 286: /* windowdefn_list ::= windowdefn */
-{ yylhsminor.yy327 = yymsp[0].minor.yy327; }
- yymsp[0].minor.yy327 = yylhsminor.yy327;
+ case 288: /* windowdefn_list ::= windowdefn */
+{ yylhsminor.yy147 = yymsp[0].minor.yy147; }
+ yymsp[0].minor.yy147 = yylhsminor.yy147;
break;
- case 287: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ case 289: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
{
- assert( yymsp[0].minor.yy327!=0 );
- yymsp[0].minor.yy327->pNextWin = yymsp[-2].minor.yy327;
- yylhsminor.yy327 = yymsp[0].minor.yy327;
+ assert( yymsp[0].minor.yy147!=0 );
+ yymsp[0].minor.yy147->pNextWin = yymsp[-2].minor.yy147;
+ yylhsminor.yy147 = yymsp[0].minor.yy147;
}
- yymsp[-2].minor.yy327 = yylhsminor.yy327;
+ yymsp[-2].minor.yy147 = yylhsminor.yy147;
break;
- case 288: /* windowdefn ::= nm AS window */
+ case 290: /* windowdefn ::= nm AS window */
{
- if( ALWAYS(yymsp[0].minor.yy327) ){
- yymsp[0].minor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[-2].minor.yy0.z, yymsp[-2].minor.yy0.n);
+ if( ALWAYS(yymsp[0].minor.yy147) ){
+ yymsp[0].minor.yy147->zName = sqlite3DbStrNDup(pParse->db, yymsp[-2].minor.yy0.z, yymsp[-2].minor.yy0.n);
}
- yylhsminor.yy327 = yymsp[0].minor.yy327;
+ yylhsminor.yy147 = yymsp[0].minor.yy147;
}
- yymsp[-2].minor.yy327 = yylhsminor.yy327;
+ yymsp[-2].minor.yy147 = yylhsminor.yy147;
break;
- case 289: /* window ::= LP part_opt orderby_opt frame_opt RP */
+ case 291: /* window ::= LP part_opt orderby_opt frame_opt RP */
{
- yymsp[-4].minor.yy327 = yymsp[-1].minor.yy327;
- if( ALWAYS(yymsp[-4].minor.yy327) ){
- yymsp[-4].minor.yy327->pPartition = yymsp[-3].minor.yy420;
- yymsp[-4].minor.yy327->pOrderBy = yymsp[-2].minor.yy420;
+ yymsp[-4].minor.yy147 = yymsp[-1].minor.yy147;
+ if( ALWAYS(yymsp[-4].minor.yy147) ){
+ yymsp[-4].minor.yy147->pPartition = yymsp[-3].minor.yy42;
+ yymsp[-4].minor.yy147->pOrderBy = yymsp[-2].minor.yy42;
}
}
break;
- case 290: /* part_opt ::= PARTITION BY nexprlist */
-{ yymsp[-2].minor.yy420 = yymsp[0].minor.yy420; }
+ case 292: /* part_opt ::= PARTITION BY nexprlist */
+{ yymsp[-2].minor.yy42 = yymsp[0].minor.yy42; }
break;
- case 291: /* part_opt ::= */
-{ yymsp[1].minor.yy420 = 0; }
+ case 293: /* part_opt ::= */
+{ yymsp[1].minor.yy42 = 0; }
break;
- case 292: /* frame_opt ::= */
+ case 294: /* frame_opt ::= */
{
- yymsp[1].minor.yy327 = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
+ yymsp[1].minor.yy147 = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
}
break;
- case 293: /* frame_opt ::= range_or_rows frame_bound_s */
+ case 295: /* frame_opt ::= range_or_rows frame_bound_s */
{
- yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-1].minor.yy70, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr, TK_CURRENT, 0);
+ yylhsminor.yy147 = sqlite3WindowAlloc(pParse, yymsp[-1].minor.yy96, yymsp[0].minor.yy317.eType, yymsp[0].minor.yy317.pExpr, TK_CURRENT, 0);
}
- yymsp[-1].minor.yy327 = yylhsminor.yy327;
+ yymsp[-1].minor.yy147 = yylhsminor.yy147;
break;
- case 294: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
+ case 296: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
{
- yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-4].minor.yy70, yymsp[-2].minor.yy119.eType, yymsp[-2].minor.yy119.pExpr, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr);
+ yylhsminor.yy147 = sqlite3WindowAlloc(pParse, yymsp[-4].minor.yy96, yymsp[-2].minor.yy317.eType, yymsp[-2].minor.yy317.pExpr, yymsp[0].minor.yy317.eType, yymsp[0].minor.yy317.pExpr);
}
- yymsp[-4].minor.yy327 = yylhsminor.yy327;
+ yymsp[-4].minor.yy147 = yylhsminor.yy147;
break;
- case 295: /* range_or_rows ::= RANGE */
-{ yymsp[0].minor.yy70 = TK_RANGE; }
+ case 297: /* range_or_rows ::= RANGE */
+{ yymsp[0].minor.yy96 = TK_RANGE; }
break;
- case 296: /* range_or_rows ::= ROWS */
-{ yymsp[0].minor.yy70 = TK_ROWS; }
+ case 298: /* range_or_rows ::= ROWS */
+{ yymsp[0].minor.yy96 = TK_ROWS; }
break;
- case 297: /* frame_bound_s ::= frame_bound */
- case 299: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==299);
-{ yylhsminor.yy119 = yymsp[0].minor.yy119; }
- yymsp[0].minor.yy119 = yylhsminor.yy119;
+ case 299: /* frame_bound_s ::= frame_bound */
+ case 301: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==301);
+{ yylhsminor.yy317 = yymsp[0].minor.yy317; }
+ yymsp[0].minor.yy317 = yylhsminor.yy317;
break;
- case 298: /* frame_bound_s ::= UNBOUNDED PRECEDING */
- case 300: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==300);
-{yymsp[-1].minor.yy119.eType = TK_UNBOUNDED; yymsp[-1].minor.yy119.pExpr = 0;}
+ case 300: /* frame_bound_s ::= UNBOUNDED PRECEDING */
+ case 302: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==302);
+{yymsp[-1].minor.yy317.eType = TK_UNBOUNDED; yymsp[-1].minor.yy317.pExpr = 0;}
break;
- case 301: /* frame_bound ::= expr PRECEDING */
-{ yylhsminor.yy119.eType = TK_PRECEDING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; }
- yymsp[-1].minor.yy119 = yylhsminor.yy119;
+ case 303: /* frame_bound ::= expr PRECEDING */
+{ yylhsminor.yy317.eType = TK_PRECEDING; yylhsminor.yy317.pExpr = yymsp[-1].minor.yy490; }
+ yymsp[-1].minor.yy317 = yylhsminor.yy317;
break;
- case 302: /* frame_bound ::= CURRENT ROW */
-{ yymsp[-1].minor.yy119.eType = TK_CURRENT ; yymsp[-1].minor.yy119.pExpr = 0; }
+ case 304: /* frame_bound ::= CURRENT ROW */
+{ yymsp[-1].minor.yy317.eType = TK_CURRENT ; yymsp[-1].minor.yy317.pExpr = 0; }
break;
- case 303: /* frame_bound ::= expr FOLLOWING */
-{ yylhsminor.yy119.eType = TK_FOLLOWING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; }
- yymsp[-1].minor.yy119 = yylhsminor.yy119;
+ case 305: /* frame_bound ::= expr FOLLOWING */
+{ yylhsminor.yy317.eType = TK_FOLLOWING; yylhsminor.yy317.pExpr = yymsp[-1].minor.yy490; }
+ yymsp[-1].minor.yy317 = yylhsminor.yy317;
break;
- case 304: /* window_clause ::= WINDOW windowdefn_list */
-{ yymsp[-1].minor.yy327 = yymsp[0].minor.yy327; }
+ case 306: /* window_clause ::= WINDOW windowdefn_list */
+{ yymsp[-1].minor.yy147 = yymsp[0].minor.yy147; }
break;
- case 305: /* over_clause ::= filter_opt OVER window */
+ case 307: /* over_clause ::= filter_opt OVER window */
{
- yylhsminor.yy327 = yymsp[0].minor.yy327;
- assert( yylhsminor.yy327!=0 );
- yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18;
+ yylhsminor.yy147 = yymsp[0].minor.yy147;
+ assert( yylhsminor.yy147!=0 );
+ yylhsminor.yy147->pFilter = yymsp[-2].minor.yy490;
}
- yymsp[-2].minor.yy327 = yylhsminor.yy327;
+ yymsp[-2].minor.yy147 = yylhsminor.yy147;
break;
- case 306: /* over_clause ::= filter_opt OVER nm */
+ case 308: /* over_clause ::= filter_opt OVER nm */
{
- yylhsminor.yy327 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
- if( yylhsminor.yy327 ){
- yylhsminor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
- yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18;
+ yylhsminor.yy147 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
+ if( yylhsminor.yy147 ){
+ yylhsminor.yy147->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
+ yylhsminor.yy147->pFilter = yymsp[-2].minor.yy490;
}else{
- sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy18);
+ sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy490);
}
}
- yymsp[-2].minor.yy327 = yylhsminor.yy327;
+ yymsp[-2].minor.yy147 = yylhsminor.yy147;
break;
- case 308: /* filter_opt ::= FILTER LP WHERE expr RP */
-{ yymsp[-4].minor.yy18 = yymsp[-1].minor.yy18; }
+ case 310: /* filter_opt ::= FILTER LP WHERE expr RP */
+{ yymsp[-4].minor.yy490 = yymsp[-1].minor.yy490; }
break;
default:
- /* (309) input ::= cmdlist */ yytestcase(yyruleno==309);
- /* (310) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==310);
- /* (311) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=311);
- /* (312) ecmd ::= SEMI */ yytestcase(yyruleno==312);
- /* (313) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==313);
- /* (314) ecmd ::= explain cmdx */ yytestcase(yyruleno==314);
- /* (315) trans_opt ::= */ yytestcase(yyruleno==315);
- /* (316) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==316);
- /* (317) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==317);
- /* (318) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==318);
- /* (319) savepoint_opt ::= */ yytestcase(yyruleno==319);
- /* (320) cmd ::= create_table create_table_args */ yytestcase(yyruleno==320);
- /* (321) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==321);
- /* (322) columnlist ::= columnname carglist */ yytestcase(yyruleno==322);
- /* (323) nm ::= ID|INDEXED */ yytestcase(yyruleno==323);
- /* (324) nm ::= STRING */ yytestcase(yyruleno==324);
- /* (325) nm ::= JOIN_KW */ yytestcase(yyruleno==325);
- /* (326) typetoken ::= typename */ yytestcase(yyruleno==326);
- /* (327) typename ::= ID|STRING */ yytestcase(yyruleno==327);
- /* (328) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=328);
- /* (329) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=329);
- /* (330) carglist ::= carglist ccons */ yytestcase(yyruleno==330);
- /* (331) carglist ::= */ yytestcase(yyruleno==331);
- /* (332) ccons ::= NULL onconf */ yytestcase(yyruleno==332);
- /* (333) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==333);
- /* (334) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==334);
- /* (335) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=335);
- /* (336) tconscomma ::= */ yytestcase(yyruleno==336);
- /* (337) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=337);
- /* (338) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=338);
- /* (339) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=339);
- /* (340) oneselect ::= values */ yytestcase(yyruleno==340);
- /* (341) sclp ::= selcollist COMMA */ yytestcase(yyruleno==341);
- /* (342) as ::= ID|STRING */ yytestcase(yyruleno==342);
- /* (343) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=343);
- /* (344) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==344);
- /* (345) exprlist ::= nexprlist */ yytestcase(yyruleno==345);
- /* (346) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=346);
- /* (347) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=347);
- /* (348) nmnum ::= ON */ yytestcase(yyruleno==348);
- /* (349) nmnum ::= DELETE */ yytestcase(yyruleno==349);
- /* (350) nmnum ::= DEFAULT */ yytestcase(yyruleno==350);
- /* (351) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==351);
- /* (352) foreach_clause ::= */ yytestcase(yyruleno==352);
- /* (353) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==353);
- /* (354) trnm ::= nm */ yytestcase(yyruleno==354);
- /* (355) tridxby ::= */ yytestcase(yyruleno==355);
- /* (356) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==356);
- /* (357) database_kw_opt ::= */ yytestcase(yyruleno==357);
- /* (358) kwcolumn_opt ::= */ yytestcase(yyruleno==358);
- /* (359) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==359);
- /* (360) vtabarglist ::= vtabarg */ yytestcase(yyruleno==360);
- /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==361);
- /* (362) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==362);
- /* (363) anylist ::= */ yytestcase(yyruleno==363);
- /* (364) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==364);
- /* (365) anylist ::= anylist ANY */ yytestcase(yyruleno==365);
- /* (366) with ::= */ yytestcase(yyruleno==366);
+ /* (311) input ::= cmdlist */ yytestcase(yyruleno==311);
+ /* (312) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==312);
+ /* (313) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=313);
+ /* (314) ecmd ::= SEMI */ yytestcase(yyruleno==314);
+ /* (315) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==315);
+ /* (316) ecmd ::= explain cmdx */ yytestcase(yyruleno==316);
+ /* (317) trans_opt ::= */ yytestcase(yyruleno==317);
+ /* (318) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==318);
+ /* (319) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==319);
+ /* (320) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==320);
+ /* (321) savepoint_opt ::= */ yytestcase(yyruleno==321);
+ /* (322) cmd ::= create_table create_table_args */ yytestcase(yyruleno==322);
+ /* (323) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==323);
+ /* (324) columnlist ::= columnname carglist */ yytestcase(yyruleno==324);
+ /* (325) nm ::= ID|INDEXED */ yytestcase(yyruleno==325);
+ /* (326) nm ::= STRING */ yytestcase(yyruleno==326);
+ /* (327) nm ::= JOIN_KW */ yytestcase(yyruleno==327);
+ /* (328) typetoken ::= typename */ yytestcase(yyruleno==328);
+ /* (329) typename ::= ID|STRING */ yytestcase(yyruleno==329);
+ /* (330) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=330);
+ /* (331) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=331);
+ /* (332) carglist ::= carglist ccons */ yytestcase(yyruleno==332);
+ /* (333) carglist ::= */ yytestcase(yyruleno==333);
+ /* (334) ccons ::= NULL onconf */ yytestcase(yyruleno==334);
+ /* (335) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==335);
+ /* (336) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==336);
+ /* (337) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=337);
+ /* (338) tconscomma ::= */ yytestcase(yyruleno==338);
+ /* (339) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=339);
+ /* (340) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=340);
+ /* (341) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=341);
+ /* (342) oneselect ::= values */ yytestcase(yyruleno==342);
+ /* (343) sclp ::= selcollist COMMA */ yytestcase(yyruleno==343);
+ /* (344) as ::= ID|STRING */ yytestcase(yyruleno==344);
+ /* (345) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=345);
+ /* (346) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==346);
+ /* (347) exprlist ::= nexprlist */ yytestcase(yyruleno==347);
+ /* (348) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=348);
+ /* (349) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=349);
+ /* (350) nmnum ::= ON */ yytestcase(yyruleno==350);
+ /* (351) nmnum ::= DELETE */ yytestcase(yyruleno==351);
+ /* (352) nmnum ::= DEFAULT */ yytestcase(yyruleno==352);
+ /* (353) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==353);
+ /* (354) foreach_clause ::= */ yytestcase(yyruleno==354);
+ /* (355) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==355);
+ /* (356) trnm ::= nm */ yytestcase(yyruleno==356);
+ /* (357) tridxby ::= */ yytestcase(yyruleno==357);
+ /* (358) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==358);
+ /* (359) database_kw_opt ::= */ yytestcase(yyruleno==359);
+ /* (360) kwcolumn_opt ::= */ yytestcase(yyruleno==360);
+ /* (361) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==361);
+ /* (362) vtabarglist ::= vtabarg */ yytestcase(yyruleno==362);
+ /* (363) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==363);
+ /* (364) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==364);
+ /* (365) anylist ::= */ yytestcase(yyruleno==365);
+ /* (366) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==366);
+ /* (367) anylist ::= anylist ANY */ yytestcase(yyruleno==367);
+ /* (368) with ::= */ yytestcase(yyruleno==368);
break;
/********** End reduce actions ************************************************/
};
- assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
- yygoto = yyRuleInfo[yyruleno].lhs;
- yysize = yyRuleInfo[yyruleno].nrhs;
+ assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
+ yygoto = yyRuleInfoLhs[yyruleno];
+ yysize = yyRuleInfoNRhs[yyruleno];
yyact = yy_find_reduce_action(yymsp[yysize].stateno,(YYCODETYPE)yygoto);
/* There are no SHIFTREDUCE actions on nonterminals because the table
@@ -152095,73 +152996,6 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
return i;
}
-#ifdef SQLITE_ENABLE_NORMALIZE
-/*
-** Return the length (in bytes) of the token that begins at z[0].
-** Store the token type in *tokenType before returning. If flags has
-** SQLITE_TOKEN_NORMALIZE flag enabled, use the identifier token type
-** for keywords. Add SQLITE_TOKEN_QUOTED to flags if the token was
-** actually a quoted identifier. Add SQLITE_TOKEN_KEYWORD to flags
-** if the token was recognized as a keyword; this is useful when the
-** SQLITE_TOKEN_NORMALIZE flag is used, because it enables the caller
-** to differentiate between a keyword being treated as an identifier
-** (for normalization purposes) and an actual identifier.
-*/
-SQLITE_PRIVATE int sqlite3GetTokenNormalized(
- const unsigned char *z,
- int *tokenType,
- int *flags
-){
- int n;
- unsigned char iClass = aiClass[*z];
- if( iClass==CC_KYWD ){
- int i;
- for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
- if( IdChar(z[i]) ){
- /* This token started out using characters that can appear in keywords,
- ** but z[i] is a character not allowed within keywords, so this must
- ** be an identifier instead */
- i++;
- while( IdChar(z[i]) ){ i++; }
- *tokenType = TK_ID;
- return i;
- }
- *tokenType = TK_ID;
- n = keywordCode((char*)z, i, tokenType);
- /* If the token is no longer considered to be an identifier, then it is a
- ** keyword of some kind. Make the token back into an identifier and then
- ** set the SQLITE_TOKEN_KEYWORD flag. Several non-identifier tokens are
- ** used verbatim, including IN, IS, NOT, and NULL. */
- switch( *tokenType ){
- case TK_ID: {
- /* do nothing, handled by caller */
- break;
- }
- case TK_IN:
- case TK_IS:
- case TK_NOT:
- case TK_NULL: {
- *flags |= SQLITE_TOKEN_KEYWORD;
- break;
- }
- default: {
- *tokenType = TK_ID;
- *flags |= SQLITE_TOKEN_KEYWORD;
- break;
- }
- }
- }else{
- n = sqlite3GetToken(z, tokenType);
- /* If the token is considered to be an identifier and the character class
- ** of the first character is a quote, set the SQLITE_TOKEN_QUOTED flag. */
- if( *tokenType==TK_ID && (iClass==CC_QUOTE || iClass==CC_QUOTE2) ){
- *flags |= SQLITE_TOKEN_QUOTED;
- }
- }
- return n;
-}
-#endif /* SQLITE_ENABLE_NORMALIZE */
-
/*
** Run the parser on the given SQL string. The parser structure is
** passed in. An SQLITE_ status code is returned. If an error occurs
@@ -152189,7 +153023,14 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
pParse->rc = SQLITE_OK;
pParse->zTail = zSql;
assert( pzErrMsg!=0 );
- /* sqlite3ParserTrace(stdout, "parser: "); */
+#ifdef SQLITE_DEBUG
+ if( db->flags & SQLITE_ParserTrace ){
+ printf("parser: [[[%s]]]\n", zSql);
+ sqlite3ParserTrace(stdout, "parser: ");
+ }else{
+ sqlite3ParserTrace(0, 0);
+ }
+#endif
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
pEngine = &sEngine;
sqlite3ParserInit(pEngine, pParse);
@@ -152332,6 +153173,141 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
return nErr;
}
+
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** Insert a single space character into pStr if the current string
+** ends with an identifier
+*/
+static void addSpaceSeparator(sqlite3_str *pStr){
+ if( pStr->nChar && sqlite3IsIdChar(pStr->zText[pStr->nChar-1]) ){
+ sqlite3_str_append(pStr, " ", 1);
+ }
+}
+
+/*
+** Compute a normalization of the SQL given by zSql[0..nSql-1]. Return
+** the normalization in space obtained from sqlite3DbMalloc(). Or return
+** NULL if anything goes wrong or if zSql is NULL.
+*/
+SQLITE_PRIVATE char *sqlite3Normalize(
+ Vdbe *pVdbe, /* VM being reprepared */
+ const char *zSql /* The original SQL string */
+){
+ sqlite3 *db; /* The database connection */
+ int i; /* Next unread byte of zSql[] */
+ int n; /* length of current token */
+ int tokenType; /* type of current token */
+ int prevType = 0; /* Previous non-whitespace token */
+ int nParen; /* Number of nested levels of parentheses */
+ int iStartIN; /* Start of RHS of IN operator in z[] */
+ int nParenAtIN; /* Value of nParent at start of RHS of IN operator */
+ int j; /* Bytes of normalized SQL generated so far */
+ sqlite3_str *pStr; /* The normalized SQL string under construction */
+
+ db = sqlite3VdbeDb(pVdbe);
+ tokenType = -1;
+ nParen = iStartIN = nParenAtIN = 0;
+ pStr = sqlite3_str_new(db);
+ assert( pStr!=0 ); /* sqlite3_str_new() never returns NULL */
+ for(i=0; zSql[i] && pStr->accError==0; i+=n){
+ if( tokenType!=TK_SPACE ){
+ prevType = tokenType;
+ }
+ n = sqlite3GetToken((unsigned char*)zSql+i, &tokenType);
+ if( NEVER(n<=0) ) break;
+ switch( tokenType ){
+ case TK_SPACE: {
+ break;
+ }
+ case TK_NULL: {
+ if( prevType==TK_IS || prevType==TK_NOT ){
+ sqlite3_str_append(pStr, " NULL", 5);
+ break;
+ }
+ /* Fall through */
+ }
+ case TK_STRING:
+ case TK_INTEGER:
+ case TK_FLOAT:
+ case TK_VARIABLE:
+ case TK_BLOB: {
+ sqlite3_str_append(pStr, "?", 1);
+ break;
+ }
+ case TK_LP: {
+ nParen++;
+ if( prevType==TK_IN ){
+ iStartIN = pStr->nChar;
+ nParenAtIN = nParen;
+ }
+ sqlite3_str_append(pStr, "(", 1);
+ break;
+ }
+ case TK_RP: {
+ if( iStartIN>0 && nParen==nParenAtIN ){
+ assert( pStr->nChar>=iStartIN );
+ pStr->nChar = iStartIN+1;
+ sqlite3_str_append(pStr, "?,?,?", 5);
+ iStartIN = 0;
+ }
+ nParen--;
+ sqlite3_str_append(pStr, ")", 1);
+ break;
+ }
+ case TK_ID: {
+ iStartIN = 0;
+ j = pStr->nChar;
+ if( sqlite3Isquote(zSql[i]) ){
+ char *zId = sqlite3DbStrNDup(db, zSql+i, n);
+ int nId;
+ int eType = 0;
+ if( zId==0 ) break;
+ sqlite3Dequote(zId);
+ if( zSql[i]=='"' && sqlite3VdbeUsesDoubleQuotedString(pVdbe, zId) ){
+ sqlite3_str_append(pStr, "?", 1);
+ sqlite3DbFree(db, zId);
+ break;
+ }
+ nId = sqlite3Strlen30(zId);
+ if( sqlite3GetToken((u8*)zId, &eType)==nId && eType==TK_ID ){
+ addSpaceSeparator(pStr);
+ sqlite3_str_append(pStr, zId, nId);
+ }else{
+ sqlite3_str_appendf(pStr, "\"%w\"", zId);
+ }
+ sqlite3DbFree(db, zId);
+ }else{
+ addSpaceSeparator(pStr);
+ sqlite3_str_append(pStr, zSql+i, n);
+ }
+ while( j<pStr->nChar ){
+ pStr->zText[j] = sqlite3Tolower(pStr->zText[j]);
+ j++;
+ }
+ break;
+ }
+ case TK_SELECT: {
+ iStartIN = 0;
+ /* fall through */
+ }
+ default: {
+ if( sqlite3IsIdChar(zSql[i]) ) addSpaceSeparator(pStr);
+ j = pStr->nChar;
+ sqlite3_str_append(pStr, zSql+i, n);
+ while( j<pStr->nChar ){
+ pStr->zText[j] = sqlite3Toupper(pStr->zText[j]);
+ j++;
+ }
+ break;
+ }
+ }
+ }
+ if( tokenType!=TK_SEMI ) sqlite3_str_append(pStr, ";", 1);
+ return sqlite3_str_finish(pStr);
+}
+#endif /* SQLITE_ENABLE_NORMALIZE */
+
/************** End of tokenize.c ********************************************/
/************** Begin file complete.c ****************************************/
/*
@@ -153377,6 +154353,13 @@ SQLITE_API int sqlite3_config(int op, ...){
}
#endif /* SQLITE_ENABLE_SORTER_REFERENCES */
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ case SQLITE_CONFIG_MEMDB_MAXSIZE: {
+ sqlite3GlobalConfig.mxMemdbSize = va_arg(ap, sqlite3_int64);
+ break;
+ }
+#endif /* SQLITE_ENABLE_DESERIALIZE */
+
default: {
rc = SQLITE_ERROR;
break;
@@ -153567,11 +154550,11 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
if( aFlagOp[i].op==op ){
int onoff = va_arg(ap, int);
int *pRes = va_arg(ap, int*);
- u32 oldFlags = db->flags;
+ u64 oldFlags = db->flags;
if( onoff>0 ){
db->flags |= aFlagOp[i].mask;
}else if( onoff==0 ){
- db->flags &= ~aFlagOp[i].mask;
+ db->flags &= ~(u64)aFlagOp[i].mask;
}
if( oldFlags!=db->flags ){
sqlite3ExpirePreparedStatements(db, 0);
@@ -154034,7 +155017,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
/* Any deferred constraint violations have now been resolved. */
db->nDeferredCons = 0;
db->nDeferredImmCons = 0;
- db->flags &= ~SQLITE_DeferFKs;
+ db->flags &= ~(u64)SQLITE_DeferFKs;
/* If one has been configured, invoke the rollback-hook callback */
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
@@ -154776,6 +155759,8 @@ SQLITE_API void *sqlite3_profile(
pOld = db->pProfileArg;
db->xProfile = xProfile;
db->pProfileArg = pArg;
+ db->mTrace &= SQLITE_TRACE_NONLEGACY_MASK;
+ if( db->xProfile ) db->mTrace |= SQLITE_TRACE_XPROFILE;
sqlite3_mutex_leave(db->mutex);
return pOld;
}
@@ -155127,7 +156112,7 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
z = sqlite3ErrStr(SQLITE_NOMEM_BKPT);
}else{
testcase( db->pErr==0 );
- z = (char*)sqlite3_value_text(db->pErr);
+ z = db->errCode ? (char*)sqlite3_value_text(db->pErr) : 0;
assert( !db->mallocFailed );
if( z==0 ){
z = sqlite3ErrStr(db->errCode);
@@ -155657,6 +156642,40 @@ SQLITE_PRIVATE int sqlite3ParseUri(
return rc;
}
+#if defined(SQLITE_HAS_CODEC)
+/*
+** Process URI filename query parameters relevant to the SQLite Encryption
+** Extension. Return true if any of the relevant query parameters are
+** seen and return false if not.
+*/
+SQLITE_PRIVATE int sqlite3CodecQueryParameters(
+ sqlite3 *db, /* Database connection */
+ const char *zDb, /* Which schema is being created/attached */
+ const char *zUri /* URI filename */
+){
+ const char *zKey;
+ if( (zKey = sqlite3_uri_parameter(zUri, "hexkey"))!=0 && zKey[0] ){
+ u8 iByte;
+ int i;
+ char zDecoded[40];
+ for(i=0, iByte=0; i<sizeof(zDecoded)*2 && sqlite3Isxdigit(zKey[i]); i++){
+ iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]);
+ if( (i&1)!=0 ) zDecoded[i/2] = iByte;
+ }
+ sqlite3_key_v2(db, zDb, zDecoded, i/2);
+ return 1;
+ }else if( (zKey = sqlite3_uri_parameter(zUri, "key"))!=0 ){
+ sqlite3_key_v2(db, zDb, zKey, sqlite3Strlen30(zKey));
+ return 1;
+ }else if( (zKey = sqlite3_uri_parameter(zUri, "textkey"))!=0 ){
+ sqlite3_key_v2(db, zDb, zKey, -1);
+ return 1;
+ }else{
+ return 0;
+ }
+}
+#endif
+
/*
** This routine does the work of opening a database on behalf of
@@ -156002,26 +157021,13 @@ opendb_out:
}
#endif
#if defined(SQLITE_HAS_CODEC)
- if( rc==SQLITE_OK ){
- const char *zKey;
- if( (zKey = sqlite3_uri_parameter(zOpen, "hexkey"))!=0 && zKey[0] ){
- u8 iByte;
- int i;
- char zDecoded[40];
- for(i=0, iByte=0; i<sizeof(zDecoded)*2 && sqlite3Isxdigit(zKey[i]); i++){
- iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]);
- if( (i&1)!=0 ) zDecoded[i/2] = iByte;
- }
- sqlite3_key_v2(db, 0, zDecoded, i/2);
- }else if( (zKey = sqlite3_uri_parameter(zOpen, "key"))!=0 ){
- sqlite3_key_v2(db, 0, zKey, sqlite3Strlen30(zKey));
- }
- }
+ if( rc==SQLITE_OK ) sqlite3CodecQueryParameters(db, 0, zOpen);
#endif
sqlite3_free(zOpen);
return rc & 0xff;
}
+
/*
** Open a new database handle.
*/
@@ -158082,6 +159088,8 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi
*/
#define FTS3_VARINT_MAX 10
+#define FTS3_BUFFER_PADDING 8
+
/*
** FTS4 virtual tables may maintain multiple indexes - one index of all terms
** in the document set and zero or more prefix indexes. All indexes are stored
@@ -158115,6 +159123,18 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi
#define POS_END (0) /* Position-list terminator */
/*
+** The assert_fts3_nc() macro is similar to the assert() macro, except that it
+** is used for assert() conditions that are true only if it can be
+** guranteed that the database is not corrupt.
+*/
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+SQLITE_API extern int sqlite3_fts3_may_be_corrupt;
+# define assert_fts3_nc(x) assert(sqlite3_fts3_may_be_corrupt || (x))
+#else
+# define assert_fts3_nc(x) assert(x)
+#endif
+
+/*
** This section provides definitions to allow the
** FTS3 extension to be compiled outside of the
** amalgamation.
@@ -158638,6 +159658,14 @@ SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; }
# endif
#endif
+/*
+** This variable is set to false when running tests for which the on disk
+** structures should not be corrupt. Otherwise, true. If it is false, extra
+** assert() conditions in the fts3 code are activated - conditions that are
+** only true if it is guaranteed that the fts3 database is not corrupt.
+*/
+SQLITE_API int sqlite3_fts3_may_be_corrupt = 1;
+
/*
** Write a 64-bit variable-length integer to memory starting at p[0].
** The length of data written will be between 1 and FTS3_VARINT_MAX bytes.
@@ -158656,7 +159684,7 @@ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
}
#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \
- v = (v & mask1) | ( (*ptr++) << shift ); \
+ v = (v & mask1) | ( (*(const unsigned char*)(ptr++)) << shift ); \
if( (v & mask2)==0 ){ var = v; return ret; }
#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \
v = (*ptr++); \
@@ -158694,20 +159722,21 @@ SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){
** a non-negative 32-bit integer before it is returned.
*/
SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){
+ const unsigned char *ptr = (const unsigned char*)p;
u32 a;
#ifndef fts3GetVarint32
- GETVARINT_INIT(a, p, 0, 0x00, 0x80, *pi, 1);
+ GETVARINT_INIT(a, ptr, 0, 0x00, 0x80, *pi, 1);
#else
- a = (*p++);
+ a = (*ptr++);
assert( a & 0x80 );
#endif
- GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *pi, 2);
- GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3);
- GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4);
+ GETVARINT_STEP(a, ptr, 7, 0x7F, 0x4000, *pi, 2);
+ GETVARINT_STEP(a, ptr, 14, 0x3FFF, 0x200000, *pi, 3);
+ GETVARINT_STEP(a, ptr, 21, 0x1FFFFF, 0x10000000, *pi, 4);
a = (a & 0x0FFFFFFF );
- *pi = (int)(a | ((u32)(*p & 0x07) << 28));
+ *pi = (int)(a | ((u32)(*ptr & 0x07) << 28));
assert( 0==(a & 0x80000000) );
assert( *pi>=0 );
return 5;
@@ -158878,13 +159907,18 @@ static int fts3DestroyMethod(sqlite3_vtab *pVtab){
sqlite3 *db = p->db; /* Database handle */
/* Drop the shadow tables */
- if( p->zContentTbl==0 ){
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName);
- }
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName);
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName);
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName);
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName);
+ fts3DbExec(&rc, db,
+ "DROP TABLE IF EXISTS %Q.'%q_segments';"
+ "DROP TABLE IF EXISTS %Q.'%q_segdir';"
+ "DROP TABLE IF EXISTS %Q.'%q_docsize';"
+ "DROP TABLE IF EXISTS %Q.'%q_stat';"
+ "%s DROP TABLE IF EXISTS %Q.'%q_content';",
+ zDb, p->zName,
+ zDb, p->zName,
+ zDb, p->zName,
+ zDb, p->zName,
+ (p->zContentTbl ? "--" : ""), zDb,p->zName
+ );
/* If everything has worked, invoke fts3DisconnectMethod() to free the
** memory associated with the Fts3Table structure and return SQLITE_OK.
@@ -159116,10 +160150,10 @@ static void fts3Appendf(
** memory.
*/
static char *fts3QuoteId(char const *zInput){
- int nRet;
+ sqlite3_int64 nRet;
char *zRet;
nRet = 2 + (int)strlen(zInput)*2 + 1;
- zRet = sqlite3_malloc(nRet);
+ zRet = sqlite3_malloc64(nRet);
if( zRet ){
int i;
char *z = zRet;
@@ -159300,7 +160334,7 @@ static int fts3PrefixParameter(
}
}
- aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex);
+ aIndex = sqlite3_malloc64(sizeof(struct Fts3Index) * nIndex);
*apIndex = aIndex;
if( !aIndex ){
return SQLITE_NOMEM;
@@ -159379,7 +160413,7 @@ static int fts3ContentColumns(
if( rc==SQLITE_OK ){
const char **azCol; /* Output array */
- int nStr = 0; /* Size of all column names (incl. 0x00) */
+ sqlite3_int64 nStr = 0; /* Size of all column names (incl. 0x00) */
int nCol; /* Number of table columns */
int i; /* Used to iterate through columns */
@@ -159389,11 +160423,11 @@ static int fts3ContentColumns(
nCol = sqlite3_column_count(pStmt);
for(i=0; i<nCol; i++){
const char *zCol = sqlite3_column_name(pStmt, i);
- nStr += (int)strlen(zCol) + 1;
+ nStr += strlen(zCol) + 1;
}
/* Allocate and populate the array to return. */
- azCol = (const char **)sqlite3_malloc(sizeof(char *) * nCol + nStr);
+ azCol = (const char **)sqlite3_malloc64(sizeof(char *) * nCol + nStr);
if( azCol==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -159441,7 +160475,7 @@ static int fts3InitVtab(
Fts3Table *p = 0; /* Pointer to allocated vtab */
int rc = SQLITE_OK; /* Return code */
int i; /* Iterator variable */
- int nByte; /* Size of allocation used for *p */
+ sqlite3_int64 nByte; /* Size of allocation used for *p */
int iCol; /* Column index */
int nString = 0; /* Bytes required to hold all column names */
int nCol = 0; /* Number of columns in the FTS table */
@@ -159475,10 +160509,10 @@ static int fts3InitVtab(
nName = (int)strlen(argv[2]) + 1;
nByte = sizeof(const char *) * (argc-2);
- aCol = (const char **)sqlite3_malloc(nByte);
+ aCol = (const char **)sqlite3_malloc64(nByte);
if( aCol ){
memset((void*)aCol, 0, nByte);
- azNotindexed = (char **)sqlite3_malloc(nByte);
+ azNotindexed = (char **)sqlite3_malloc64(nByte);
}
if( azNotindexed ){
memset(azNotindexed, 0, nByte);
@@ -159673,7 +160707,7 @@ static int fts3InitVtab(
nName + /* zName */
nDb + /* zDb */
nString; /* Space for azColumn strings */
- p = (Fts3Table*)sqlite3_malloc(nByte);
+ p = (Fts3Table*)sqlite3_malloc64(nByte);
if( p==0 ){
rc = SQLITE_NOMEM;
goto fts3_init_out;
@@ -160452,7 +161486,7 @@ static int fts3PutColNumber(char **pp, int iCol){
** updated appropriately. The caller is responsible for insuring
** that there is enough space in *pp to hold the complete output.
*/
-static void fts3PoslistMerge(
+static int fts3PoslistMerge(
char **pp, /* Output buffer */
char **pp1, /* Left input list */
char **pp2 /* Right input list */
@@ -160465,11 +161499,17 @@ static void fts3PoslistMerge(
int iCol1; /* The current column index in pp1 */
int iCol2; /* The current column index in pp2 */
- if( *p1==POS_COLUMN ) fts3GetVarint32(&p1[1], &iCol1);
+ if( *p1==POS_COLUMN ){
+ fts3GetVarint32(&p1[1], &iCol1);
+ if( iCol1==0 ) return FTS_CORRUPT_VTAB;
+ }
else if( *p1==POS_END ) iCol1 = POSITION_LIST_END;
else iCol1 = 0;
- if( *p2==POS_COLUMN ) fts3GetVarint32(&p2[1], &iCol2);
+ if( *p2==POS_COLUMN ){
+ fts3GetVarint32(&p2[1], &iCol2);
+ if( iCol2==0 ) return FTS_CORRUPT_VTAB;
+ }
else if( *p2==POS_END ) iCol2 = POSITION_LIST_END;
else iCol2 = 0;
@@ -160517,6 +161557,7 @@ static void fts3PoslistMerge(
*pp = p;
*pp1 = p1 + 1;
*pp2 = p2 + 1;
+ return SQLITE_OK;
}
/*
@@ -160581,10 +161622,9 @@ static int fts3PoslistPhraseMerge(
p += sqlite3Fts3PutVarint(p, iCol1);
}
- assert( *p1!=POS_END && *p1!=POS_COLUMN );
- assert( *p2!=POS_END && *p2!=POS_COLUMN );
fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2;
fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2;
+ if( iPos1<0 || iPos2<0 ) break;
while( 1 ){
if( iPos2==iPos1+nToken
@@ -160810,6 +161850,7 @@ static int fts3DoclistOrMerge(
char *a2, int n2, /* Second doclist */
char **paOut, int *pnOut /* OUT: Malloc'd doclist */
){
+ int rc = SQLITE_OK;
sqlite3_int64 i1 = 0;
sqlite3_int64 i2 = 0;
sqlite3_int64 iPrev = 0;
@@ -160853,7 +161894,7 @@ static int fts3DoclistOrMerge(
** A symetric argument may be made if the doclists are in descending
** order.
*/
- aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1);
+ aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING);
if( !aOut ) return SQLITE_NOMEM;
p = aOut;
@@ -160864,7 +161905,8 @@ static int fts3DoclistOrMerge(
if( p2 && p1 && iDiff==0 ){
fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1);
- fts3PoslistMerge(&p, &p1, &p2);
+ rc = fts3PoslistMerge(&p, &p1, &p2);
+ if( rc ) break;
fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1);
fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
}else if( !p2 || (p1 && iDiff<0) ){
@@ -160878,10 +161920,16 @@ static int fts3DoclistOrMerge(
}
}
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(aOut);
+ p = aOut = 0;
+ }else{
+ assert( (p-aOut)<=n1+n2+FTS3_VARINT_MAX-1 );
+ memset(&aOut[(p-aOut)], 0, FTS3_BUFFER_PADDING);
+ }
*paOut = aOut;
*pnOut = (int)(p-aOut);
- assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 );
- return SQLITE_OK;
+ return rc;
}
/*
@@ -160916,7 +161964,7 @@ static int fts3DoclistPhraseMerge(
assert( nDist>0 );
if( bDescDoclist ){
- aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX);
+ aOut = sqlite3_malloc64((sqlite3_int64)*pnRight + FTS3_VARINT_MAX);
if( aOut==0 ) return SQLITE_NOMEM;
}else{
aOut = aRight;
@@ -161100,6 +162148,7 @@ static int fts3TermSelectMerge(
pTS->anOutput[0] = nDoclist;
if( pTS->aaOutput[0] ){
memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
+ memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX);
}else{
return SQLITE_NOMEM;
}
@@ -161151,8 +162200,8 @@ static int fts3SegReaderCursorAppend(
){
if( (pCsr->nSegment%16)==0 ){
Fts3SegReader **apNew;
- int nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*);
- apNew = (Fts3SegReader **)sqlite3_realloc(pCsr->apSegment, nByte);
+ sqlite3_int64 nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*);
+ apNew = (Fts3SegReader **)sqlite3_realloc64(pCsr->apSegment, nByte);
if( !apNew ){
sqlite3Fts3SegReaderFree(pNew);
return SQLITE_NOMEM;
@@ -161216,7 +162265,7 @@ static int fts3SegReaderCursor(
/* If zTerm is not NULL, and this segment is not stored entirely on its
** root node, the range of leaves scanned can be reduced. Do this. */
- if( iStartBlock && zTerm ){
+ if( iStartBlock && zTerm && zRoot ){
sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0);
rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi);
if( rc!=SQLITE_OK ) goto finished;
@@ -162158,7 +163207,6 @@ static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
Fts3Table *p = (Fts3Table*)pVtab;
UNUSED_PARAMETER(iSavepoint);
assert( p->inTransaction );
- assert( p->mxSavepoint >= iSavepoint );
TESTONLY( p->mxSavepoint = iSavepoint );
sqlite3Fts3PendingTermsClear(p);
return SQLITE_OK;
@@ -162933,9 +163981,10 @@ static int fts3EvalIncrPhraseNext(
if( bEof==0 ){
int nList = 0;
int nByte = a[p->nToken-1].nList;
- char *aDoclist = sqlite3_malloc(nByte+1);
+ char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING);
if( !aDoclist ) return SQLITE_NOMEM;
memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
+ memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING);
for(i=0; i<(p->nToken-1); i++){
if( a[i].bIgnore==0 ){
@@ -163326,7 +164375,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){
if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){
Fts3TokenAndCost *aTC;
Fts3Expr **apOr;
- aTC = (Fts3TokenAndCost *)sqlite3_malloc(
+ aTC = (Fts3TokenAndCost *)sqlite3_malloc64(
sizeof(Fts3TokenAndCost) * nToken
+ sizeof(Fts3Expr *) * nOr * 2
);
@@ -163637,7 +164686,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
&& (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR)
){
Fts3Expr *p;
- int nTmp = 0; /* Bytes of temp space */
+ sqlite3_int64 nTmp = 0; /* Bytes of temp space */
char *aTmp; /* Temp space for PoslistNearMerge() */
/* Allocate temporary working space. */
@@ -163646,7 +164695,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
nTmp += p->pRight->pPhrase->doclist.nList;
}
nTmp += p->pPhrase->doclist.nList;
- aTmp = sqlite3_malloc(nTmp*2);
+ aTmp = sqlite3_malloc64(nTmp*2);
if( !aTmp ){
*pRc = SQLITE_NOMEM;
res = 0;
@@ -163916,15 +164965,14 @@ static void fts3EvalRestart(
** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase
** expression nodes.
*/
-static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
+static void fts3EvalUpdateCounts(Fts3Expr *pExpr, int nCol){
if( pExpr ){
Fts3Phrase *pPhrase = pExpr->pPhrase;
if( pPhrase && pPhrase->doclist.pList ){
int iCol = 0;
char *p = pPhrase->doclist.pList;
- assert( *p );
- while( 1 ){
+ do{
u8 c = 0;
int iCnt = 0;
while( 0xFE & (*p | c) ){
@@ -163940,11 +164988,11 @@ static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
if( *p==0x00 ) break;
p++;
p += fts3GetVarint32(p, &iCol);
- }
+ }while( iCol<nCol );
}
- fts3EvalUpdateCounts(pExpr->pLeft);
- fts3EvalUpdateCounts(pExpr->pRight);
+ fts3EvalUpdateCounts(pExpr->pLeft, nCol);
+ fts3EvalUpdateCounts(pExpr->pRight, nCol);
}
}
@@ -163988,7 +165036,7 @@ static int fts3EvalGatherStats(
for(p=pRoot; p; p=p->pLeft){
Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight);
assert( pE->aMI==0 );
- pE->aMI = (u32 *)sqlite3_malloc(pTab->nColumn * 3 * sizeof(u32));
+ pE->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32));
if( !pE->aMI ) return SQLITE_NOMEM;
memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32));
}
@@ -164014,7 +165062,7 @@ static int fts3EvalGatherStats(
);
if( rc==SQLITE_OK && pCsr->isEof==0 ){
- fts3EvalUpdateCounts(pRoot);
+ fts3EvalUpdateCounts(pRoot, pTab->nColumn);
}
}
@@ -164364,7 +165412,7 @@ static int fts3auxConnectMethod(
char const *zFts3; /* Name of fts3 table */
int nDb; /* Result of strlen(zDb) */
int nFts3; /* Result of strlen(zFts3) */
- int nByte; /* Bytes of space to allocate here */
+ sqlite3_int64 nByte; /* Bytes of space to allocate here */
int rc; /* value returned by declare_vtab() */
Fts3auxTable *p; /* Virtual table object to return */
@@ -164396,7 +165444,7 @@ static int fts3auxConnectMethod(
if( rc!=SQLITE_OK ) return rc;
nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
- p = (Fts3auxTable *)sqlite3_malloc(nByte);
+ p = (Fts3auxTable *)sqlite3_malloc64(nByte);
if( !p ) return SQLITE_NOMEM;
memset(p, 0, nByte);
@@ -164546,7 +165594,7 @@ static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){
static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){
if( nSize>pCsr->nStat ){
struct Fts3auxColstats *aNew;
- aNew = (struct Fts3auxColstats *)sqlite3_realloc(pCsr->aStat,
+ aNew = (struct Fts3auxColstats *)sqlite3_realloc64(pCsr->aStat,
sizeof(struct Fts3auxColstats) * nSize
);
if( aNew==0 ) return SQLITE_NOMEM;
@@ -164714,15 +165762,15 @@ static int fts3auxFilterMethod(
assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) );
if( zStr ){
pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr);
- pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]);
if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM;
+ pCsr->filter.nTerm = (int)strlen(pCsr->filter.zTerm);
}
}
if( iLe>=0 ){
pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe]));
- pCsr->nStop = sqlite3_value_bytes(apVal[iLe]);
if( pCsr->zStop==0 ) return SQLITE_NOMEM;
+ pCsr->nStop = (int)strlen(pCsr->zStop);
}
if( iLangid>=0 ){
@@ -164974,8 +166022,8 @@ static int fts3isspace(char c){
** zero the memory before returning a pointer to it. If unsuccessful,
** return NULL.
*/
-static void *fts3MallocZero(int nByte){
- void *pRet = sqlite3_malloc(nByte);
+static void *fts3MallocZero(sqlite3_int64 nByte){
+ void *pRet = sqlite3_malloc64(nByte);
if( pRet ) memset(pRet, 0, nByte);
return pRet;
}
@@ -165050,7 +166098,7 @@ static int getNextToken(
if( rc==SQLITE_OK ){
const char *zToken;
int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
- int nByte; /* total space to allocate */
+ sqlite3_int64 nByte; /* total space to allocate */
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
if( rc==SQLITE_OK ){
@@ -165104,8 +166152,8 @@ static int getNextToken(
** Enlarge a memory allocation. If an out-of-memory allocation occurs,
** then free the old allocation.
*/
-static void *fts3ReallocOrFree(void *pOrig, int nNew){
- void *pRet = sqlite3_realloc(pOrig, nNew);
+static void *fts3ReallocOrFree(void *pOrig, sqlite3_int64 nNew){
+ void *pRet = sqlite3_realloc64(pOrig, nNew);
if( !pRet ){
sqlite3_free(pOrig);
}
@@ -165349,7 +166397,6 @@ static int getNextNode(
int nConsumed = 0;
pParse->nNest++;
rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed);
- if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; }
*pnConsumed = (int)(zInput - z) + 1 + nConsumed;
return rc;
}else if( *zInput==')' ){
@@ -165648,7 +166695,7 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){
if( rc==SQLITE_OK ){
if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
Fts3Expr **apLeaf;
- apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
+ apLeaf = (Fts3Expr **)sqlite3_malloc64(sizeof(Fts3Expr *) * nMaxDepth);
if( 0==apLeaf ){
rc = SQLITE_NOMEM;
}else{
@@ -166068,7 +167115,7 @@ static void fts3ExprTestCommon(
zExpr = (const char *)sqlite3_value_text(argv[1]);
nExpr = sqlite3_value_bytes(argv[1]);
nCol = argc-2;
- azCol = (char **)sqlite3_malloc(nCol*sizeof(char *));
+ azCol = (char **)sqlite3_malloc64(nCol*sizeof(char *));
if( !azCol ){
sqlite3_result_error_nomem(context);
goto exprtest_out;
@@ -166182,8 +167229,8 @@ SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash
/*
** Malloc and Free functions
*/
-static void *fts3HashMalloc(int n){
- void *p = sqlite3_malloc(n);
+static void *fts3HashMalloc(sqlite3_int64 n){
+ void *p = sqlite3_malloc64(n);
if( p ){
memset(p, 0, n);
}
@@ -168076,7 +169123,7 @@ static int fts3tokDequoteArray(
nByte += (int)(strlen(argv[i]) + 1);
}
- *pazDequote = azDequote = sqlite3_malloc(sizeof(char *)*argc + nByte);
+ *pazDequote = azDequote = sqlite3_malloc64(sizeof(char *)*argc + nByte);
if( azDequote==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -168808,10 +169855,12 @@ static int fts3SqlStmt(
pStmt = p->aStmt[eStmt];
if( !pStmt ){
+ int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;
char *zSql;
if( eStmt==SQL_CONTENT_INSERT ){
zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
}else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
+ f &= ~SQLITE_PREPARE_NO_VTAB;
zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
}else{
zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
@@ -168819,8 +169868,7 @@ static int fts3SqlStmt(
if( !zSql ){
rc = SQLITE_NOMEM;
}else{
- rc = sqlite3_prepare_v3(p->db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
- &pStmt, NULL);
+ rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL);
sqlite3_free(zSql);
assert( rc==SQLITE_OK || pStmt==0 );
p->aStmt[eStmt] = pStmt;
@@ -168978,7 +170026,7 @@ static sqlite3_int64 getAbsoluteLevel(
int iLevel /* Level of segments */
){
sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */
- assert( iLangid>=0 );
+ assert_fts3_nc( iLangid>=0 );
assert( p->nIndex>0 );
assert( iIndex>=0 && iIndex<p->nIndex );
@@ -169820,7 +170868,7 @@ static int fts3SegReaderNext(
** b-tree node. And that the final byte of the doclist is 0x00. If either
** of these statements is untrue, then the data structure is corrupt.
*/
- if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
+ if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode)
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
){
return FTS_CORRUPT_VTAB;
@@ -170020,8 +171068,13 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(
Fts3SegReader *pReader; /* Newly allocated SegReader object */
int nExtra = 0; /* Bytes to allocate segment root node */
- assert( iStartLeaf<=iEndLeaf );
+ assert( zRoot!=0 || nRoot==0 );
+#ifdef CORRUPT_DB
+ assert( zRoot!=0 || CORRUPT_DB );
+#endif
+
if( iStartLeaf==0 ){
+ if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB;
nExtra = nRoot + FTS3_NODE_PADDING;
}
@@ -170041,7 +171094,7 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(
pReader->aNode = (char *)&pReader[1];
pReader->rootOnly = 1;
pReader->nNode = nRoot;
- memcpy(pReader->aNode, zRoot, nRoot);
+ if( nRoot ) memcpy(pReader->aNode, zRoot, nRoot);
memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
}else{
pReader->iCurrentBlock = iStartLeaf-1;
@@ -170661,6 +171714,11 @@ static int fts3SegWriterAdd(
nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm);
nSuffix = nTerm-nPrefix;
+ /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of
+ ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when
+ ** compared with BINARY collation. This indicates corruption. */
+ if( nSuffix<=0 ) return FTS_CORRUPT_VTAB;
+
/* Figure out how many bytes are required by this new entry */
nReq = sqlite3Fts3VarintLen(nPrefix) + /* varint containing prefix size */
sqlite3Fts3VarintLen(nSuffix) + /* varint containing suffix size */
@@ -171368,7 +172426,9 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(
}else{
iDelta = iDocid - iPrev;
}
- assert( iDelta>0 || (nDoclist==0 && iDelta==iDocid) );
+ if( iDelta<=0 && (nDoclist>0 || iDelta!=iDocid) ){
+ return FTS_CORRUPT_VTAB;
+ }
assert( nDoclist>0 || iDelta==iDocid );
nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
@@ -171734,14 +172794,16 @@ static void fts3DecodeIntArray(
const char *zBuf, /* The BLOB containing the varints */
int nBuf /* size of the BLOB */
){
- int i, j;
- UNUSED_PARAMETER(nBuf);
- for(i=j=0; i<N; i++){
- sqlite3_int64 x;
- j += sqlite3Fts3GetVarint(&zBuf[j], &x);
- assert(j<=nBuf);
- a[i] = (u32)(x & 0xffffffff);
+ int i = 0;
+ if( nBuf && (zBuf[nBuf-1]&0x80)==0 ){
+ int j;
+ for(i=j=0; i<N && j<nBuf; i++){
+ sqlite3_int64 x;
+ j += sqlite3Fts3GetVarint(&zBuf[j], &x);
+ a[i] = (u32)(x & 0xffffffff);
+ }
}
+ while( i<N ) a[i++] = 0;
}
/*
@@ -172147,7 +173209,7 @@ static int nodeReaderNext(NodeReader *p){
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
- return SQLITE_CORRUPT_VTAB;
+ return FTS_CORRUPT_VTAB;
}
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
if( rc==SQLITE_OK ){
@@ -172157,7 +173219,7 @@ static int nodeReaderNext(NodeReader *p){
if( p->iChild==0 ){
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
if( (p->nNode-p->iOff)<p->nDoclist ){
- return SQLITE_CORRUPT_VTAB;
+ return FTS_CORRUPT_VTAB;
}
p->aDoclist = &p->aNode[p->iOff];
p->iOff += p->nDoclist;
@@ -174287,7 +175349,7 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
aOut = &p->aMatchinfo[p->nElem+2];
xRet = fts3MIBufferFree;
}else{
- aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32));
+ aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32));
if( aOut ){
xRet = sqlite3_free;
if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
@@ -174542,7 +175604,8 @@ static void fts3SnippetDetails(
int j;
u64 mPhrase = (u64)1 << i;
u64 mPos = (u64)1 << (iCsr - iStart);
- assert( iCsr>=iStart );
+ assert( iCsr>=iStart && (iCsr - iStart)<=64 );
+ assert( i>=0 && i<=64 );
if( (mCover|mCovered)&mPhrase ){
iScore++;
}else{
@@ -174584,11 +175647,14 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
int iFirst = 0;
pPhrase->pList = pCsr;
fts3GetDeltaPosition(&pCsr, &iFirst);
- assert( iFirst>=0 );
- pPhrase->pHead = pCsr;
- pPhrase->pTail = pCsr;
- pPhrase->iHead = iFirst;
- pPhrase->iTail = iFirst;
+ if( iFirst<0 ){
+ rc = FTS_CORRUPT_VTAB;
+ }else{
+ pPhrase->pHead = pCsr;
+ pPhrase->pTail = pCsr;
+ pPhrase->iHead = iFirst;
+ pPhrase->iTail = iFirst;
+ }
}else{
assert( rc!=SQLITE_OK || (
pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0
@@ -174625,7 +175691,7 @@ static int fts3BestSnippet(
int rc; /* Return Code */
int nList; /* Number of phrases in expression */
SnippetIter sIter; /* Iterates through snippet candidates */
- int nByte; /* Number of bytes of space to allocate */
+ sqlite3_int64 nByte; /* Number of bytes of space to allocate */
int iBestScore = -1; /* Best snippet score found so far */
int i; /* Loop counter */
@@ -174643,7 +175709,7 @@ static int fts3BestSnippet(
** the required space using malloc().
*/
nByte = sizeof(SnippetPhrase) * nList;
- sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc(nByte);
+ sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc64(nByte);
if( !sIter.aPhrase ){
return SQLITE_NOMEM;
}
@@ -174713,8 +175779,8 @@ static int fts3StringAppend(
** appended data.
*/
if( pStr->n+nAppend+1>=pStr->nAlloc ){
- int nAlloc = pStr->nAlloc+nAppend+100;
- char *zNew = sqlite3_realloc(pStr->z, nAlloc);
+ sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100;
+ char *zNew = sqlite3_realloc64(pStr->z, nAlloc);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -174769,6 +175835,7 @@ static int fts3SnippetShift(
for(nLeft=0; !(hlmask & ((u64)1 << nLeft)); nLeft++);
for(nRight=0; !(hlmask & ((u64)1 << (nSnippet-1-nRight))); nRight++);
+ assert( (nSnippet-1-nRight)<=63 && (nSnippet-1-nRight)>=0 );
nDesired = (nLeft-nRight)/2;
/* Ideally, the start of the snippet should be pushed forward in the
@@ -174961,7 +176028,7 @@ static int fts3ColumnlistCount(char **ppCollist){
/*
** This function gathers 'y' or 'b' data for a single phrase.
*/
-static void fts3ExprLHits(
+static int fts3ExprLHits(
Fts3Expr *pExpr, /* Phrase expression node */
MatchInfo *p /* Matchinfo context */
){
@@ -174991,25 +176058,29 @@ static void fts3ExprLHits(
if( *pIter!=0x01 ) break;
pIter++;
pIter += fts3GetVarint32(pIter, &iCol);
+ if( iCol>=p->nCol ) return FTS_CORRUPT_VTAB;
}
+ return SQLITE_OK;
}
/*
** Gather the results for matchinfo directives 'y' and 'b'.
*/
-static void fts3ExprLHitGather(
+static int fts3ExprLHitGather(
Fts3Expr *pExpr,
MatchInfo *p
){
+ int rc = SQLITE_OK;
assert( (pExpr->pLeft==0)==(pExpr->pRight==0) );
if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
if( pExpr->pLeft ){
- fts3ExprLHitGather(pExpr->pLeft, p);
- fts3ExprLHitGather(pExpr->pRight, p);
+ rc = fts3ExprLHitGather(pExpr->pLeft, p);
+ if( rc==SQLITE_OK ) rc = fts3ExprLHitGather(pExpr->pRight, p);
}else{
- fts3ExprLHits(pExpr, p);
+ rc = fts3ExprLHits(pExpr, p);
}
}
+ return rc;
}
/*
@@ -175226,11 +176297,12 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
int i;
int iCol;
int nToken = 0;
+ int rc = SQLITE_OK;
/* Allocate and populate the array of LcsIterator objects. The array
** contains one element for each matchable phrase in the query.
**/
- aIter = sqlite3_malloc(sizeof(LcsIterator) * pCsr->nPhrase);
+ aIter = sqlite3_malloc64(sizeof(LcsIterator) * pCsr->nPhrase);
if( !aIter ) return SQLITE_NOMEM;
memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase);
(void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);
@@ -175246,13 +176318,16 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
int nLive = 0; /* Number of iterators in aIter not at EOF */
for(i=0; i<pInfo->nPhrase; i++){
- int rc;
LcsIterator *pIt = &aIter[i];
rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead);
- if( rc!=SQLITE_OK ) return rc;
+ if( rc!=SQLITE_OK ) goto matchinfo_lcs_out;
if( pIt->pRead ){
pIt->iPos = pIt->iPosOffset;
- fts3LcsIteratorAdvance(&aIter[i]);
+ fts3LcsIteratorAdvance(pIt);
+ if( pIt->pRead==0 ){
+ rc = FTS_CORRUPT_VTAB;
+ goto matchinfo_lcs_out;
+ }
nLive++;
}
}
@@ -175284,8 +176359,9 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
pInfo->aMatchinfo[iCol] = nLcs;
}
+ matchinfo_lcs_out:
sqlite3_free(aIter);
- return SQLITE_OK;
+ return rc;
}
/*
@@ -175381,7 +176457,7 @@ static int fts3MatchinfoValues(
case FTS3_MATCHINFO_LHITS: {
int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
memset(pInfo->aMatchinfo, 0, nZero);
- fts3ExprLHitGather(pCsr->pExpr, pInfo);
+ rc = fts3ExprLHitGather(pCsr->pExpr, pInfo);
break;
}
@@ -175533,6 +176609,10 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet(
return;
}
+ /* Limit the snippet length to 64 tokens. */
+ if( nToken<-64 ) nToken = -64;
+ if( nToken>+64 ) nToken = +64;
+
for(nSnippet=1; 1; nSnippet++){
int iSnip; /* Loop counter 0..nSnippet-1 */
@@ -175675,7 +176755,7 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets(
if( rc!=SQLITE_OK ) goto offsets_out;
/* Allocate the array of TermOffset iterators. */
- sCtx.aTerm = (TermOffset *)sqlite3_malloc(sizeof(TermOffset)*nToken);
+ sCtx.aTerm = (TermOffset *)sqlite3_malloc64(sizeof(TermOffset)*nToken);
if( 0==sCtx.aTerm ){
rc = SQLITE_NOMEM;
goto offsets_out;
@@ -175900,7 +176980,7 @@ typedef struct unicode_cursor unicode_cursor;
struct unicode_tokenizer {
sqlite3_tokenizer base;
- int bRemoveDiacritic;
+ int eRemoveDiacritic;
int nException;
int *aiException;
};
@@ -175973,7 +177053,7 @@ static int unicodeAddExceptions(
int *aNew; /* New aiException[] array */
int nNew; /* Number of valid entries in array aNew[] */
- aNew = sqlite3_realloc(p->aiException, (p->nException+nEntry)*sizeof(int));
+ aNew = sqlite3_realloc64(p->aiException,(p->nException+nEntry)*sizeof(int));
if( aNew==0 ) return SQLITE_NOMEM;
nNew = p->nException;
@@ -176045,17 +177125,20 @@ static int unicodeCreate(
pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer));
if( pNew==NULL ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(unicode_tokenizer));
- pNew->bRemoveDiacritic = 1;
+ pNew->eRemoveDiacritic = 1;
for(i=0; rc==SQLITE_OK && i<nArg; i++){
const char *z = azArg[i];
int n = (int)strlen(z);
if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){
- pNew->bRemoveDiacritic = 1;
+ pNew->eRemoveDiacritic = 1;
}
else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){
- pNew->bRemoveDiacritic = 0;
+ pNew->eRemoveDiacritic = 0;
+ }
+ else if( n==19 && memcmp("remove_diacritics=2", z, 19)==0 ){
+ pNew->eRemoveDiacritic = 2;
}
else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){
rc = unicodeAddExceptions(pNew, 1, &z[11], n-11);
@@ -176159,7 +177242,7 @@ static int unicodeNext(
/* Grow the output buffer if required. */
if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){
- char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64);
+ char *zNew = sqlite3_realloc64(pCsr->zToken, pCsr->nAlloc+64);
if( !zNew ) return SQLITE_NOMEM;
zOut = &zNew[zOut - pCsr->zToken];
pCsr->zToken = zNew;
@@ -176168,7 +177251,7 @@ static int unicodeNext(
/* Write the folded case of the last character read to the output */
zEnd = z;
- iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic);
+ iOut = sqlite3FtsUnicodeFold((int)iCode, p->eRemoveDiacritic);
if( iOut ){
WRITE_UTF8(zOut, iOut);
}
@@ -176213,7 +177296,7 @@ SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const *
/************** End of fts3_unicode.c ****************************************/
/************** Begin file fts3_unicode2.c ***********************************/
/*
-** 2012 May 25
+** 2012-05-25
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -176373,32 +177456,48 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
** E"). The resuls of passing a codepoint that corresponds to an
** uppercase letter are undefined.
*/
-static int remove_diacritic(int c){
+static int remove_diacritic(int c, int bComplex){
unsigned short aDia[] = {
0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336,
- 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928,
- 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234,
- 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504,
- 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529,
- 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
- 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122,
- 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536,
- 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730,
- 62924, 63050, 63082, 63274, 63390,
+ 3456, 3696, 3712, 3728, 3744, 3766, 3832, 3896,
+ 3912, 3928, 3944, 3968, 4008, 4040, 4056, 4106,
+ 4138, 4170, 4202, 4234, 4266, 4296, 4312, 4344,
+ 4408, 4424, 4442, 4472, 4488, 4504, 6148, 6198,
+ 6264, 6280, 6360, 6429, 6505, 6529, 61448, 61468,
+ 61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704,
+ 61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914,
+ 61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218,
+ 62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554,
+ 62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766,
+ 62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118,
+ 63182, 63242, 63274, 63310, 63368, 63390,
};
- char aChar[] = {
- '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c',
- 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
- 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
- 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
- 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
- '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
- 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
- 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
- 'e', 'i', 'o', 'u', 'y',
+#define HIBIT ((unsigned char)0x80)
+ unsigned char aChar[] = {
+ '\0', 'a', 'c', 'e', 'i', 'n',
+ 'o', 'u', 'y', 'y', 'a', 'c',
+ 'd', 'e', 'e', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'n', 'o', 'r',
+ 's', 't', 'u', 'u', 'w', 'y',
+ 'z', 'o', 'u', 'a', 'i', 'o',
+ 'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o',
+ 'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a',
+ 'e', 'i', 'o', 'r', 'u', 's',
+ 't', 'h', 'a', 'e', 'o'|HIBIT, 'o',
+ 'o'|HIBIT, 'y', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', 'a', 'b',
+ 'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT,
+ 'f', 'g', 'h', 'h', 'i', 'i'|HIBIT,
+ 'k', 'l', 'l'|HIBIT, 'l', 'm', 'n',
+ 'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's',
+ 's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w',
+ 'w', 'x', 'y', 'z', 'h', 't',
+ 'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT,
+ 'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT,
+ 'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y',
};
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
@@ -176415,7 +177514,8 @@ static int remove_diacritic(int c){
}
}
assert( key>=aDia[iRes] );
- return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
+ if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
+ return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);
}
@@ -176428,8 +177528,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){
unsigned int mask1 = 0x000361F8;
if( c<768 || c>817 ) return 0;
return (c < 768+32) ?
- (mask0 & (1 << (c-768))) :
- (mask1 & (1 << (c-768-32)));
+ (mask0 & ((unsigned int)1 << (c-768))) :
+ (mask1 & ((unsigned int)1 << (c-768-32)));
}
@@ -176442,7 +177542,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){
** The results are undefined if the value passed to this function
** is less than zero.
*/
-SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
+SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){
/* Each entry in the following array defines a rule for folding a range
** of codepoints to lower case. The rule applies to a range of nRange
** codepoints starting at codepoint iCode.
@@ -176565,7 +177665,9 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
assert( ret>0 );
}
- if( bRemoveDiacritic ) ret = remove_diacritic(ret);
+ if( eRemoveDiacritic ){
+ ret = remove_diacritic(ret, eRemoveDiacritic==2);
+ }
}
else if( c>=66560 && c<66600 ){
@@ -177272,7 +178374,7 @@ static JSON_NOINLINE int jsonParseAddNodeExpand(
assert( pParse->nNode>=pParse->nAlloc );
if( pParse->oom ) return -1;
nNew = pParse->nAlloc*2 + 10;
- pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
+ pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew);
if( pNew==0 ){
pParse->oom = 1;
return -1;
@@ -177546,7 +178648,7 @@ static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
static int jsonParseFindParents(JsonParse *pParse){
u32 *aUp;
assert( pParse->aUp==0 );
- aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
+ aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode );
if( aUp==0 ){
pParse->oom = 1;
return SQLITE_NOMEM;
@@ -177608,7 +178710,7 @@ static JsonParse *jsonParseCached(
pMatch->iHold = iMaxHold+1;
return pMatch;
}
- p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
+ p = sqlite3_malloc64( sizeof(*p) + nJson + 1 );
if( p==0 ){
sqlite3_result_error_nomem(pCtx);
return 0;
@@ -179253,6 +180355,9 @@ struct Rtree {
u8 inWrTrans; /* True if inside write transaction */
u8 nAux; /* # of auxiliary columns in %_rowid */
u8 nAuxNotNull; /* Number of initial not-null aux columns */
+#ifdef SQLITE_DEBUG
+ u8 bCorrupt; /* Shadow table corruption detected */
+#endif
int iDepth; /* Current depth of the r-tree structure */
char *zDb; /* Name of database containing r-tree table */
char *zName; /* Name of r-tree table */
@@ -179313,6 +180418,15 @@ struct Rtree {
#endif
/*
+** Set the Rtree.bCorrupt flag
+*/
+#ifdef SQLITE_DEBUG
+# define RTREE_IS_CORRUPT(X) ((X)->bCorrupt = 1)
+#else
+# define RTREE_IS_CORRUPT(X)
+#endif
+
+/*
** When doing a search of an r-tree, instances of the following structure
** record intermediate results from the tree walk.
**
@@ -179678,8 +180792,8 @@ static void nodeZero(Rtree *pRtree, RtreeNode *p){
** Given a node number iNode, return the corresponding key to use
** in the Rtree.aHash table.
*/
-static int nodeHash(i64 iNode){
- return iNode % HASHSIZE;
+static unsigned int nodeHash(i64 iNode){
+ return ((unsigned)iNode) % HASHSIZE;
}
/*
@@ -179724,7 +180838,7 @@ static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){
*/
static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
RtreeNode *pNode;
- pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
+ pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode) + pRtree->iNodeSize);
if( pNode ){
memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize);
pNode->zData = (u8 *)&pNode[1];
@@ -179749,6 +180863,18 @@ static void nodeBlobReset(Rtree *pRtree){
}
/*
+** Check to see if pNode is the same as pParent or any of the parents
+** of pParent.
+*/
+static int nodeInParentChain(const RtreeNode *pNode, const RtreeNode *pParent){
+ do{
+ if( pNode==pParent ) return 1;
+ pParent = pParent->pParent;
+ }while( pParent );
+ return 0;
+}
+
+/*
** Obtain a reference to an r-tree node.
*/
static int nodeAcquire(
@@ -179766,6 +180892,10 @@ static int nodeAcquire(
if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
if( pParent && !pNode->pParent ){
+ if( nodeInParentChain(pNode, pParent) ){
+ RTREE_IS_CORRUPT(pRtree);
+ return SQLITE_CORRUPT_VTAB;
+ }
pParent->nRef++;
pNode->pParent = pParent;
}
@@ -179796,9 +180926,12 @@ static int nodeAcquire(
*ppNode = 0;
/* If unable to open an sqlite3_blob on the desired row, that can only
** be because the shadow tables hold erroneous data. */
- if( rc==SQLITE_ERROR ) rc = SQLITE_CORRUPT_VTAB;
+ if( rc==SQLITE_ERROR ){
+ rc = SQLITE_CORRUPT_VTAB;
+ RTREE_IS_CORRUPT(pRtree);
+ }
}else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
- pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
+ pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize);
if( !pNode ){
rc = SQLITE_NOMEM;
}else{
@@ -179811,7 +180944,6 @@ static int nodeAcquire(
pNode->pNext = 0;
rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData,
pRtree->iNodeSize, 0);
- nodeReference(pParent);
}
}
@@ -179825,6 +180957,7 @@ static int nodeAcquire(
pRtree->iDepth = readInt16(pNode->zData);
if( pRtree->iDepth>RTREE_MAX_DEPTH ){
rc = SQLITE_CORRUPT_VTAB;
+ RTREE_IS_CORRUPT(pRtree);
}
}
@@ -179835,14 +180968,17 @@ static int nodeAcquire(
if( pNode && rc==SQLITE_OK ){
if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){
rc = SQLITE_CORRUPT_VTAB;
+ RTREE_IS_CORRUPT(pRtree);
}
}
if( rc==SQLITE_OK ){
if( pNode!=0 ){
+ nodeReference(pParent);
nodeHashInsert(pRtree, pNode);
}else{
rc = SQLITE_CORRUPT_VTAB;
+ RTREE_IS_CORRUPT(pRtree);
}
*ppNode = pNode;
}else{
@@ -180068,7 +181204,7 @@ static void rtreeRelease(Rtree *pRtree){
pRtree->inWrTrans = 0;
assert( pRtree->nCursor==0 );
nodeBlobReset(pRtree);
- assert( pRtree->nNodeRef==0 );
+ assert( pRtree->nNodeRef==0 || pRtree->bCorrupt );
sqlite3_finalize(pRtree->pWriteNode);
sqlite3_finalize(pRtree->pDeleteNode);
sqlite3_finalize(pRtree->pReadRowid);
@@ -180127,7 +181263,7 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
Rtree *pRtree = (Rtree *)pVTab;
RtreeCursor *pCsr;
- pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor));
+ pCsr = (RtreeCursor *)sqlite3_malloc64(sizeof(RtreeCursor));
if( pCsr ){
memset(pCsr, 0, sizeof(RtreeCursor));
pCsr->base.pVtab = pVTab;
@@ -180400,6 +181536,7 @@ static int nodeRowidIndex(
return SQLITE_OK;
}
}
+ RTREE_IS_CORRUPT(pRtree);
return SQLITE_CORRUPT_VTAB;
}
@@ -180493,7 +181630,7 @@ static RtreeSearchPoint *rtreeEnqueue(
RtreeSearchPoint *pNew;
if( pCur->nPoint>=pCur->nPointAlloc ){
int nNew = pCur->nPointAlloc*2 + 8;
- pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0]));
+ pNew = sqlite3_realloc64(pCur->aPoint, nNew*sizeof(pCur->aPoint[0]));
if( pNew==0 ) return 0;
pCur->aPoint = pNew;
pCur->nPointAlloc = nNew;
@@ -180895,7 +182032,7 @@ static int rtreeFilter(
*/
rc = nodeAcquire(pRtree, 1, 0, &pRoot);
if( rc==SQLITE_OK && argc>0 ){
- pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc);
+ pCsr->aConstraint = sqlite3_malloc64(sizeof(RtreeConstraint)*argc);
pCsr->nConstraint = argc;
if( !pCsr->aConstraint ){
rc = SQLITE_NOMEM;
@@ -181040,20 +182177,20 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
){
u8 op;
switch( p->op ){
- case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
- case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
- case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
- case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
- case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
- default:
- assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH );
- op = RTREE_MATCH;
- break;
+ case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
+ case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
+ case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
+ case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
+ case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
+ case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break;
+ default: op = 0; break;
+ }
+ if( op ){
+ zIdxStr[iIdx++] = op;
+ zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
+ pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
+ pIdxInfo->aConstraintUsage[ii].omit = 1;
}
- zIdxStr[iIdx++] = op;
- zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
- pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
- pIdxInfo->aConstraintUsage[ii].omit = 1;
}
}
@@ -181089,11 +182226,11 @@ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
#endif
{
switch( pRtree->nDim ){
- case 5: area = p->aCoord[9].i - p->aCoord[8].i;
- case 4: area *= p->aCoord[7].i - p->aCoord[6].i;
- case 3: area *= p->aCoord[5].i - p->aCoord[4].i;
- case 2: area *= p->aCoord[3].i - p->aCoord[2].i;
- default: area *= p->aCoord[1].i - p->aCoord[0].i;
+ case 5: area = (i64)p->aCoord[9].i - (i64)p->aCoord[8].i;
+ case 4: area *= (i64)p->aCoord[7].i - (i64)p->aCoord[6].i;
+ case 3: area *= (i64)p->aCoord[5].i - (i64)p->aCoord[4].i;
+ case 2: area *= (i64)p->aCoord[3].i - (i64)p->aCoord[2].i;
+ default: area *= (i64)p->aCoord[1].i - (i64)p->aCoord[0].i;
}
}
return area;
@@ -181262,12 +182399,14 @@ static int AdjustTree(
RtreeCell *pCell /* This cell was just inserted */
){
RtreeNode *p = pNode;
+ int cnt = 0;
while( p->pParent ){
RtreeNode *pParent = p->pParent;
RtreeCell cell;
int iCell;
- if( nodeParentIndex(pRtree, p, &iCell) ){
+ if( (++cnt)>1000 || nodeParentIndex(pRtree, p, &iCell) ){
+ RTREE_IS_CORRUPT(pRtree);
return SQLITE_CORRUPT_VTAB;
}
@@ -181464,9 +182603,9 @@ static int splitNodeStartree(
int iBestSplit = 0;
RtreeDValue fBestMargin = RTREE_ZERO;
- int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
+ sqlite3_int64 nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
- aaSorted = (int **)sqlite3_malloc(nByte);
+ aaSorted = (int **)sqlite3_malloc64(nByte);
if( !aaSorted ){
return SQLITE_NOMEM;
}
@@ -181587,7 +182726,7 @@ static int SplitNode(
/* Allocate an array and populate it with a copy of pCell and
** all cells from node pLeft. Then zero the original node.
*/
- aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1));
+ aCell = sqlite3_malloc64((sizeof(RtreeCell)+sizeof(int))*(nCell+1));
if( !aCell ){
rc = SQLITE_NOMEM;
goto splitnode_out;
@@ -181735,7 +182874,10 @@ static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){
}
rc = sqlite3_reset(pRtree->pReadParent);
if( rc==SQLITE_OK ) rc = rc2;
- if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB;
+ if( rc==SQLITE_OK && !pChild->pParent ){
+ RTREE_IS_CORRUPT(pRtree);
+ rc = SQLITE_CORRUPT_VTAB;
+ }
pChild = pChild->pParent;
}
return rc;
@@ -181875,7 +183017,7 @@ static int Reinsert(
/* Allocate the buffers used by this operation. The allocation is
** relinquished before this function returns.
*/
- aCell = (RtreeCell *)sqlite3_malloc(n * (
+ aCell = (RtreeCell *)sqlite3_malloc64(n * (
sizeof(RtreeCell) + /* aCell array */
sizeof(int) + /* aOrder array */
sizeof(int) + /* aSpare array */
@@ -182049,8 +183191,12 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
rc = findLeafNode(pRtree, iDelete, &pLeaf, 0);
}
+#ifdef CORRUPT_DB
+ assert( pLeaf!=0 || rc!=SQLITE_OK || CORRUPT_DB );
+#endif
+
/* Delete the cell in question from the leaf node. */
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK && pLeaf ){
int rc2;
rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell);
if( rc==SQLITE_OK ){
@@ -182322,7 +183468,7 @@ static int rtreeUpdate(
rc = rc2;
}
}
- if( pRtree->nAux ){
+ if( rc==SQLITE_OK && pRtree->nAux ){
sqlite3_stmt *pUp = pRtree->pWriteAux;
int jj;
sqlite3_bind_int64(pUp, 1, *pRowid);
@@ -182520,6 +183666,7 @@ static int rtreeSqlInit(
};
sqlite3_stmt **appStmt[N_STATEMENT];
int i;
+ const int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;
pRtree->db = db;
@@ -182576,8 +183723,7 @@ static int rtreeSqlInit(
}
zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
if( zSql ){
- rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
- appStmt[i], 0);
+ rc = sqlite3_prepare_v3(db, zSql, -1, f, appStmt[i], 0);
}else{
rc = SQLITE_NOMEM;
}
@@ -182607,8 +183753,7 @@ static int rtreeSqlInit(
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
- rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
- &pRtree->pWriteAux, 0);
+ rc = sqlite3_prepare_v3(db, zSql, -1, f, &pRtree->pWriteAux, 0);
sqlite3_free(zSql);
}
}
@@ -182684,6 +183829,7 @@ static int getNodeSize(
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
}else if( pRtree->iNodeSize<(512-64) ){
rc = SQLITE_CORRUPT_VTAB;
+ RTREE_IS_CORRUPT(pRtree);
*pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
pRtree->zName);
}
@@ -182739,7 +183885,7 @@ static int rtreeInit(
/* Allocate the sqlite3_vtab structure */
nDb = (int)strlen(argv[1]);
nName = (int)strlen(argv[2]);
- pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
+ pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2);
if( !pRtree ){
return SQLITE_NOMEM;
}
@@ -183007,8 +184153,7 @@ static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){
static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
u8 *pRet = 0; /* Return value */
- assert( pCheck->rc==SQLITE_OK );
- if( pCheck->pGetNode==0 ){
+ if( pCheck->rc==SQLITE_OK && pCheck->pGetNode==0 ){
pCheck->pGetNode = rtreeCheckPrepare(pCheck,
"SELECT data FROM %Q.'%q_node' WHERE nodeno=?",
pCheck->zDb, pCheck->zTab
@@ -183020,7 +184165,7 @@ static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){
int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0);
const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0);
- pRet = sqlite3_malloc(nNode);
+ pRet = sqlite3_malloc64(nNode);
if( pRet==0 ){
pCheck->rc = SQLITE_NOMEM;
}else{
@@ -183499,6 +184644,14 @@ struct GeoPoly {
*/
#define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4))
+/* Macros to access coordinates of a GeoPoly.
+** We have to use these macros, rather than just say p->a[i] in order
+** to silence (incorrect) UBSAN warnings if the array index is too large.
+*/
+#define GeoX(P,I) (((GeoCoord*)(P)->a)[(I)*2])
+#define GeoY(P,I) (((GeoCoord*)(P)->a)[(I)*2+1])
+
+
/*
** State of a parse of a GeoJSON input.
*/
@@ -183691,8 +184844,9 @@ static GeoPoly *geopolyFuncParam(
memcpy(p->hdr, a, nByte);
if( a[0] != *(unsigned char*)&x ){
int ii;
- for(ii=0; ii<nVertex*2; ii++){
- geopolySwab32((unsigned char*)&p->a[ii]);
+ for(ii=0; ii<nVertex; ii++){
+ geopolySwab32((unsigned char*)&GeoX(p,ii));
+ geopolySwab32((unsigned char*)&GeoY(p,ii));
}
p->hdr[0] ^= 1;
}
@@ -183751,9 +184905,9 @@ static void geopolyJsonFunc(
int i;
sqlite3_str_append(x, "[", 1);
for(i=0; i<p->nVertex; i++){
- sqlite3_str_appendf(x, "[%!g,%!g],", p->a[i*2], p->a[i*2+1]);
+ sqlite3_str_appendf(x, "[%!g,%!g],", GeoX(p,i), GeoY(p,i));
}
- sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]);
+ sqlite3_str_appendf(x, "[%!g,%!g]]", GeoX(p,0), GeoY(p,0));
sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
sqlite3_free(p);
}
@@ -183770,7 +184924,9 @@ static void geopolySvgFunc(
int argc,
sqlite3_value **argv
){
- GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+ GeoPoly *p;
+ if( argc<1 ) return;
+ p = geopolyFuncParam(context, argv[0], 0);
if( p ){
sqlite3 *db = sqlite3_context_db_handle(context);
sqlite3_str *x = sqlite3_str_new(db);
@@ -183778,10 +184934,10 @@ static void geopolySvgFunc(
char cSep = '\'';
sqlite3_str_appendf(x, "<polyline points=");
for(i=0; i<p->nVertex; i++){
- sqlite3_str_appendf(x, "%c%g,%g", cSep, p->a[i*2], p->a[i*2+1]);
+ sqlite3_str_appendf(x, "%c%g,%g", cSep, GeoX(p,i), GeoY(p,i));
cSep = ' ';
}
- sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]);
+ sqlite3_str_appendf(x, " %g,%g'", GeoX(p,0), GeoY(p,0));
for(i=1; i<argc; i++){
const char *z = (const char*)sqlite3_value_text(argv[i]);
if( z && z[0] ){
@@ -183826,12 +184982,12 @@ static void geopolyXformFunc(
int ii;
if( p ){
for(ii=0; ii<p->nVertex; ii++){
- x0 = p->a[ii*2];
- y0 = p->a[ii*2+1];
+ x0 = GeoX(p,ii);
+ y0 = GeoY(p,ii);
x1 = (GeoCoord)(A*x0 + B*y0 + E);
y1 = (GeoCoord)(C*x0 + D*y0 + F);
- p->a[ii*2] = x1;
- p->a[ii*2+1] = y1;
+ GeoX(p,ii) = x1;
+ GeoY(p,ii) = y1;
}
sqlite3_result_blob(context, p->hdr,
4+8*p->nVertex, SQLITE_TRANSIENT);
@@ -183850,12 +185006,12 @@ static double geopolyArea(GeoPoly *p){
double rArea = 0.0;
int ii;
for(ii=0; ii<p->nVertex-1; ii++){
- rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
- * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
+ rArea += (GeoX(p,ii) - GeoX(p,ii+1)) /* (x0 - x1) */
+ * (GeoY(p,ii) + GeoY(p,ii+1)) /* (y0 + y1) */
* 0.5;
}
- rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
- * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
+ rArea += (GeoX(p,ii) - GeoX(p,0)) /* (xN - x0) */
+ * (GeoY(p,ii) + GeoY(p,0)) /* (yN + y0) */
* 0.5;
return rArea;
}
@@ -183902,13 +185058,13 @@ static void geopolyCcwFunc(
if( p ){
if( geopolyArea(p)<0.0 ){
int ii, jj;
- for(ii=2, jj=p->nVertex*2 - 2; ii<jj; ii+=2, jj-=2){
- GeoCoord t = p->a[ii];
- p->a[ii] = p->a[jj];
- p->a[jj] = t;
- t = p->a[ii+1];
- p->a[ii+1] = p->a[jj+1];
- p->a[jj+1] = t;
+ for(ii=1, jj=p->nVertex-1; ii<jj; ii++, jj--){
+ GeoCoord t = GeoX(p,ii);
+ GeoX(p,ii) = GeoX(p,jj);
+ GeoX(p,jj) = t;
+ t = GeoY(p,ii);
+ GeoY(p,ii) = GeoY(p,jj);
+ GeoY(p,jj) = t;
}
}
sqlite3_result_blob(context, p->hdr,
@@ -183968,8 +185124,8 @@ static void geopolyRegularFunc(
p->hdr[3] = n&0xff;
for(i=0; i<n; i++){
double rAngle = 2.0*GEOPOLY_PI*i/n;
- p->a[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
- p->a[i*2+1] = y + r*geopolySine(rAngle);
+ GeoX(p,i) = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
+ GeoY(p,i) = y + r*geopolySine(rAngle);
}
sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
sqlite3_free(p);
@@ -184006,13 +185162,13 @@ static GeoPoly *geopolyBBox(
}
if( p ){
int ii;
- mnX = mxX = p->a[0];
- mnY = mxY = p->a[1];
+ mnX = mxX = GeoX(p,0);
+ mnY = mxY = GeoY(p,0);
for(ii=1; ii<p->nVertex; ii++){
- double r = p->a[ii*2];
+ double r = GeoX(p,ii);
if( r<mnX ) mnX = (float)r;
else if( r>mxX ) mxX = (float)r;
- r = p->a[ii*2+1];
+ r = GeoY(p,ii);
if( r<mnY ) mnY = (float)r;
else if( r>mxY ) mxY = (float)r;
}
@@ -184032,14 +185188,14 @@ static GeoPoly *geopolyBBox(
pOut->hdr[1] = 0;
pOut->hdr[2] = 0;
pOut->hdr[3] = 4;
- pOut->a[0] = mnX;
- pOut->a[1] = mnY;
- pOut->a[2] = mxX;
- pOut->a[3] = mnY;
- pOut->a[4] = mxX;
- pOut->a[5] = mxY;
- pOut->a[6] = mnX;
- pOut->a[7] = mxY;
+ GeoX(pOut,0) = mnX;
+ GeoY(pOut,0) = mnY;
+ GeoX(pOut,1) = mxX;
+ GeoY(pOut,1) = mnY;
+ GeoX(pOut,2) = mxX;
+ GeoY(pOut,2) = mxY;
+ GeoX(pOut,3) = mnX;
+ GeoY(pOut,3) = mxY;
}else{
sqlite3_free(p);
aCoord[0].f = mnX;
@@ -184177,14 +185333,14 @@ static void geopolyContainsPointFunc(
int ii;
if( p1==0 ) return;
for(ii=0; ii<p1->nVertex-1; ii++){
- v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
- p1->a[ii*2+2],p1->a[ii*2+3]);
+ v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii),
+ GeoX(p1,ii+1),GeoY(p1,ii+1));
if( v==2 ) break;
cnt += v;
}
if( v!=2 ){
- v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
- p1->a[0],p1->a[1]);
+ v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii),
+ GeoX(p1,0), GeoY(p1,0));
}
if( v==2 ){
sqlite3_result_int(context, 1);
@@ -184306,10 +185462,10 @@ static void geopolyAddSegments(
unsigned int i;
GeoCoord *x;
for(i=0; i<(unsigned)pPoly->nVertex-1; i++){
- x = pPoly->a + (i*2);
+ x = &GeoX(pPoly,i);
geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i);
}
- x = pPoly->a + (i*2);
+ x = &GeoX(pPoly,i);
geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i);
}
@@ -185254,12 +186410,12 @@ static void rtreeMatchArgFree(void *pArg){
static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
RtreeMatchArg *pBlob;
- int nBlob;
+ sqlite3_int64 nBlob;
int memErr = 0;
nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue)
+ nArg*sizeof(sqlite3_value*);
- pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
+ pBlob = (RtreeMatchArg *)sqlite3_malloc64(nBlob);
if( !pBlob ){
sqlite3_result_error_nomem(ctx);
}else{
@@ -185970,7 +187126,7 @@ static int icuCreate(
if( argc>0 ){
n = strlen(argv[0])+1;
}
- p = (IcuTokenizer *)sqlite3_malloc(sizeof(IcuTokenizer)+n);
+ p = (IcuTokenizer *)sqlite3_malloc64(sizeof(IcuTokenizer)+n);
if( !p ){
return SQLITE_NOMEM;
}
@@ -186027,7 +187183,7 @@ static int icuOpen(
nInput = strlen(zInput);
}
nChar = nInput+1;
- pCsr = (IcuCursor *)sqlite3_malloc(
+ pCsr = (IcuCursor *)sqlite3_malloc64(
sizeof(IcuCursor) + /* IcuCursor */
((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */
(nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */
@@ -186599,7 +187755,11 @@ SQLITE_API sqlite3rbu *sqlite3rbu_open(
** name of the state database is "<database>-vacuum", where <database>
** is the name of the target database file. In this case, on UNIX, if the
** state database is not already present in the file-system, it is created
-** with the same permissions as the target db is made.
+** with the same permissions as the target db is made.
+**
+** With an RBU vacuum, it is an SQLITE_MISUSE error if the name of the
+** state database ends with "-vactmp". This name is reserved for internal
+** use.
**
** This function does not delete the state database after an RBU vacuum
** is completed, even if it created it. However, if the call to
@@ -189257,7 +190417,7 @@ static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
if( *zExtra=='\0' ) zExtra = 0;
}
- zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1%s%s",
+ zTarget = sqlite3_mprintf("file:%s-vactmp?rbu_memory=1%s%s",
sqlite3_db_filename(p->dbRbu, "main"),
(zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra)
);
@@ -190523,6 +191683,12 @@ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
const char *zState
){
if( zTarget==0 ){ return rbuMisuseError(); }
+ if( zState ){
+ int n = strlen(zState);
+ if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){
+ return rbuMisuseError();
+ }
+ }
/* TODO: Check that both arguments are non-NULL */
return openRbuHandle(0, zTarget, zState);
}
@@ -190719,7 +191885,10 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){
if( p->eStage==RBU_STAGE_OAL ){
assert( rc!=SQLITE_DONE );
if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
- if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, 0);
+ if( rc==SQLITE_OK ){
+ const char *zBegin = rbuIsVacuum(p) ? "BEGIN" : "BEGIN IMMEDIATE";
+ rc = sqlite3_exec(p->dbRbu, zBegin, 0, 0, 0);
+ }
if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0,0);
}
@@ -192250,6 +193419,10 @@ statNextRestart:
goto statNextRestart; /* Tail recursion */
}
pCsr->iPage++;
+ if( pCsr->iPage>=ArraySize(pCsr->aPage) ){
+ statResetCsr(pCsr);
+ return SQLITE_CORRUPT_BKPT;
+ }
assert( p==&pCsr->aPage[pCsr->iPage-1] );
if( p->iCell==p->nCell ){
@@ -192321,7 +193494,6 @@ static int statFilter(
StatTable *pTab = (StatTable*)(pCursor->pVtab);
char *zSql;
int rc = SQLITE_OK;
- char *zMaster;
if( idxNum==1 ){
const char *zDbase = (const char*)sqlite3_value_text(argv[0]);
@@ -192337,13 +193509,12 @@ static int statFilter(
statResetCsr(pCsr);
sqlite3_finalize(pCsr->pStmt);
pCsr->pStmt = 0;
- zMaster = pCsr->iDb==1 ? "sqlite_temp_master" : "sqlite_master";
zSql = sqlite3_mprintf(
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
" UNION ALL "
"SELECT name, rootpage, type"
- " FROM \"%w\".%s WHERE rootpage!=0"
- " ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName, zMaster);
+ " FROM \"%w\".sqlite_master WHERE rootpage!=0"
+ " ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName);
if( zSql==0 ){
return SQLITE_NOMEM_BKPT;
}else{
@@ -193231,7 +194402,7 @@ static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){
static int sessionSerializeValue(
u8 *aBuf, /* If non-NULL, write serialized value here */
sqlite3_value *pValue, /* Value to serialize */
- int *pnWrite /* IN/OUT: Increment by bytes written */
+ sqlite3_int64 *pnWrite /* IN/OUT: Increment by bytes written */
){
int nByte; /* Size of serialized value in bytes */
@@ -193772,7 +194943,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){
SessionChange **apNew;
int nNew = (pTab->nChange ? pTab->nChange : 128) * 2;
- apNew = (SessionChange **)sqlite3_malloc(sizeof(SessionChange *) * nNew);
+ apNew = (SessionChange **)sqlite3_malloc64(sizeof(SessionChange *) * nNew);
if( apNew==0 ){
if( pTab->nChange==0 ){
return SQLITE_ERROR;
@@ -193838,7 +195009,7 @@ static int sessionTableInfo(
char *zPragma;
sqlite3_stmt *pStmt;
int rc;
- int nByte;
+ sqlite3_int64 nByte;
int nDbCol = 0;
int nThis;
int i;
@@ -193881,7 +195052,7 @@ static int sessionTableInfo(
if( rc==SQLITE_OK ){
nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1);
- pAlloc = sqlite3_malloc(nByte);
+ pAlloc = sqlite3_malloc64(nByte);
if( pAlloc==0 ){
rc = SQLITE_NOMEM;
}
@@ -194022,7 +195193,7 @@ static void sessionPreupdateOneChange(
int iHash;
int bNull = 0;
int rc = SQLITE_OK;
- SessionStat1Ctx stat1 = {0};
+ SessionStat1Ctx stat1 = {{0,0,0,0,0},0};
if( pSession->rc ) return;
@@ -194079,7 +195250,7 @@ static void sessionPreupdateOneChange(
** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK
** values (if this is an INSERT). */
SessionChange *pChange; /* New change object */
- int nByte; /* Number of bytes to allocate */
+ sqlite3_int64 nByte; /* Number of bytes to allocate */
int i; /* Used to iterate through columns */
assert( rc==SQLITE_OK );
@@ -194104,7 +195275,7 @@ static void sessionPreupdateOneChange(
}
/* Allocate the change object */
- pChange = (SessionChange *)sqlite3_malloc(nByte);
+ pChange = (SessionChange *)sqlite3_malloc64(nByte);
if( !pChange ){
rc = SQLITE_NOMEM;
goto error_out;
@@ -194548,7 +195719,7 @@ SQLITE_API int sqlite3session_create(
*ppSession = 0;
/* Allocate and populate the new session object. */
- pNew = (sqlite3_session *)sqlite3_malloc(sizeof(sqlite3_session) + nDb + 1);
+ pNew = (sqlite3_session *)sqlite3_malloc64(sizeof(sqlite3_session) + nDb + 1);
if( !pNew ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(sqlite3_session));
pNew->db = db;
@@ -194667,7 +195838,7 @@ SQLITE_API int sqlite3session_attach(
if( !pTab ){
/* Allocate new SessionTable object. */
- pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1);
+ pTab = (SessionTable *)sqlite3_malloc64(sizeof(SessionTable) + nName + 1);
if( !pTab ){
rc = SQLITE_NOMEM;
}else{
@@ -194727,7 +195898,7 @@ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){
int rc = *pRc;
if( rc==SQLITE_OK ){
- int nByte = 0;
+ sqlite3_int64 nByte = 0;
rc = sessionSerializeValue(0, pVal, &nByte);
sessionBufferGrow(p, nByte, &rc);
if( rc==SQLITE_OK ){
@@ -195603,7 +196774,7 @@ static int sessionValueSetStr(
** argument to sqlite3ValueSetStr() and have the copy created
** automatically. But doing so makes it difficult to detect any OOM
** error. Hence the code to create the copy externally. */
- u8 *aCopy = sqlite3_malloc(nData+1);
+ u8 *aCopy = sqlite3_malloc64((sqlite3_int64)nData+1);
if( aCopy==0 ) return SQLITE_NOMEM;
memcpy(aCopy, aData, nData);
sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free);
@@ -196216,7 +197387,7 @@ static int sessionChangesetInvert(
int iCol;
if( 0==apVal ){
- apVal = (sqlite3_value **)sqlite3_malloc(sizeof(apVal[0])*nCol*2);
+ apVal = (sqlite3_value **)sqlite3_malloc64(sizeof(apVal[0])*nCol*2);
if( 0==apVal ){
rc = SQLITE_NOMEM;
goto finished_invert;
@@ -197489,7 +198660,7 @@ static int sessionChangeMerge(
int rc = SQLITE_OK;
if( !pExist ){
- pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec);
+ pNew = (SessionChange *)sqlite3_malloc64(sizeof(SessionChange) + nRec);
if( !pNew ){
return SQLITE_NOMEM;
}
@@ -197522,8 +198693,8 @@ static int sessionChangeMerge(
if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){
*ppNew = pExist;
}else{
- int nByte = nRec + pExist->nRecord + sizeof(SessionChange);
- pNew = (SessionChange*)sqlite3_malloc(nByte);
+ sqlite3_int64 nByte = nRec + pExist->nRecord + sizeof(SessionChange);
+ pNew = (SessionChange*)sqlite3_malloc64(nByte);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -197583,14 +198754,14 @@ static int sessionChangeMerge(
assert( pNew==0 );
}else{
u8 *aExist = pExist->aRecord;
- int nByte;
+ sqlite3_int64 nByte;
u8 *aCsr;
/* Allocate a new SessionChange object. Ensure that the aRecord[]
** buffer of the new object is large enough to hold any record that
** may be generated by combining the input records. */
nByte = sizeof(SessionChange) + pExist->nRecord + nRec;
- pNew = (SessionChange *)sqlite3_malloc(nByte);
+ pNew = (SessionChange *)sqlite3_malloc64(nByte);
if( !pNew ){
sqlite3_free(pExist);
return SQLITE_NOMEM;
@@ -197696,7 +198867,7 @@ static int sessionChangesetToHash(
if( !pTab ){
SessionTable **ppTab;
- pTab = sqlite3_malloc(sizeof(SessionTable) + nCol + nNew+1);
+ pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1);
if( !pTab ){
rc = SQLITE_NOMEM;
break;
@@ -198470,12 +199641,8 @@ struct Fts5PhraseIter {
**
** Usually, output parameter *piPhrase is set to the phrase number, *piCol
** to the column in which it occurs and *piOff the token offset of the
-** first token of the phrase. The exception is if the table was created
-** with the offsets=0 option specified. In this case *piOff is always
-** set to -1.
-**
-** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
-** if an error occurs.
+** first token of the phrase. Returns SQLITE_OK if successful, or an error
+** code (i.e. SQLITE_NOMEM) if an error occurs.
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
@@ -198764,11 +199931,11 @@ struct Fts5ExtensionApi {
** the tokenizer substitutes "first" for "1st" and the query works
** as expected.
**
-** <li> By adding multiple synonyms for a single term to the FTS index.
-** In this case, when tokenizing query text, the tokenizer may
-** provide multiple synonyms for a single term within the document.
-** FTS5 then queries the index for each synonym individually. For
-** example, faced with the query:
+** <li> By querying the index for all synonyms of each query term
+** separately. In this case, when tokenizing query text, the
+** tokenizer may provide multiple synonyms for a single term
+** within the document. FTS5 then queries the index for each
+** synonym individually. For example, faced with the query:
**
** <codeblock>
** ... MATCH 'first place'</codeblock>
@@ -198792,7 +199959,7 @@ struct Fts5ExtensionApi {
** "place".
**
** This way, even if the tokenizer does not provide synonyms
-** when tokenizing query text (it should not - to do would be
+** when tokenizing query text (it should not - to do so would be
** inefficient), it doesn't matter if the user queries for
** 'first + place' or '1st + place', as there are entries in the
** FTS index corresponding to both forms of the first token.
@@ -199017,6 +200184,12 @@ SQLITE_API extern int sqlite3_fts5_may_be_corrupt;
# define assert_nc(x) assert(x)
#endif
+/*
+** A version of memcmp() that does not cause asan errors if one of the pointer
+** parameters is NULL and the number of bytes to compare is zero.
+*/
+#define fts5Memcmp(s1, s2, n) ((n)==0 ? 0 : memcmp((s1), (s2), (n)))
+
/* Mark a function parameter as unused, to suppress nuisance compiler
** warnings. */
#ifndef UNUSED_PARAM
@@ -199204,7 +200377,7 @@ static void sqlite3Fts5Put32(u8*, int);
static int sqlite3Fts5Get32(const u8*);
#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
-#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF)
+#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF)
typedef struct Fts5PoslistReader Fts5PoslistReader;
struct Fts5PoslistReader {
@@ -199239,7 +200412,7 @@ static int sqlite3Fts5PoslistNext64(
);
/* Malloc utility */
-static void *sqlite3Fts5MallocZero(int *pRc, int nByte);
+static void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte);
static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn);
/* Character set tests (like isspace(), isalpha() etc.) */
@@ -199450,9 +200623,19 @@ static int sqlite3Fts5PutVarint(unsigned char *p, u64 v);
/**************************************************************************
-** Interface to code in fts5.c.
+** Interface to code in fts5_main.c.
*/
+/*
+** Virtual-table object.
+*/
+typedef struct Fts5Table Fts5Table;
+struct Fts5Table {
+ sqlite3_vtab base; /* Base class used by SQLite core */
+ Fts5Config *pConfig; /* Virtual table configuration */
+ Fts5Index *pIndex; /* Full-text index */
+};
+
static int sqlite3Fts5GetTokenizer(
Fts5Global*,
const char **azArg,
@@ -199462,7 +200645,9 @@ static int sqlite3Fts5GetTokenizer(
char **pzErr
);
-static Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, Fts5Config **);
+static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
+
+static int sqlite3Fts5FlushToDisk(Fts5Table*);
/*
** End of interface to code in fts5.c.
@@ -199718,7 +200903,7 @@ static int sqlite3Fts5UnicodeIsdiacritic(int c);
static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
static int sqlite3Fts5UnicodeCatParse(const char*, u8*);
-static int sqlite3Fts5UnicodeCategory(int iCode);
+static int sqlite3Fts5UnicodeCategory(u32 iCode);
static void sqlite3Fts5UnicodeAscii(u8*, u8*);
/*
** End of interface to code in fts5_unicode2.c.
@@ -200622,41 +201807,70 @@ static void fts5yy_shift(
fts5yyTraceShift(fts5yypParser, fts5yyNewState, "Shift");
}
-/* The following table contains information about every rule that
-** is used during the reduce.
-*/
-static const struct {
- fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
- signed char nrhs; /* Negative of the number of RHS symbols in the rule */
-} fts5yyRuleInfo[] = {
- { 16, -1 }, /* (0) input ::= expr */
- { 20, -4 }, /* (1) colset ::= MINUS LCP colsetlist RCP */
- { 20, -3 }, /* (2) colset ::= LCP colsetlist RCP */
- { 20, -1 }, /* (3) colset ::= STRING */
- { 20, -2 }, /* (4) colset ::= MINUS STRING */
- { 21, -2 }, /* (5) colsetlist ::= colsetlist STRING */
- { 21, -1 }, /* (6) colsetlist ::= STRING */
- { 17, -3 }, /* (7) expr ::= expr AND expr */
- { 17, -3 }, /* (8) expr ::= expr OR expr */
- { 17, -3 }, /* (9) expr ::= expr NOT expr */
- { 17, -5 }, /* (10) expr ::= colset COLON LP expr RP */
- { 17, -3 }, /* (11) expr ::= LP expr RP */
- { 17, -1 }, /* (12) expr ::= exprlist */
- { 19, -1 }, /* (13) exprlist ::= cnearset */
- { 19, -2 }, /* (14) exprlist ::= exprlist cnearset */
- { 18, -1 }, /* (15) cnearset ::= nearset */
- { 18, -3 }, /* (16) cnearset ::= colset COLON nearset */
- { 22, -1 }, /* (17) nearset ::= phrase */
- { 22, -2 }, /* (18) nearset ::= CARET phrase */
- { 22, -5 }, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */
- { 23, -1 }, /* (20) nearphrases ::= phrase */
- { 23, -2 }, /* (21) nearphrases ::= nearphrases phrase */
- { 25, 0 }, /* (22) neardist_opt ::= */
- { 25, -2 }, /* (23) neardist_opt ::= COMMA STRING */
- { 24, -4 }, /* (24) phrase ::= phrase PLUS STRING star_opt */
- { 24, -2 }, /* (25) phrase ::= STRING star_opt */
- { 26, -1 }, /* (26) star_opt ::= STAR */
- { 26, 0 }, /* (27) star_opt ::= */
+/* For rule J, fts5yyRuleInfoLhs[J] contains the symbol on the left-hand side
+** of that rule */
+static const fts5YYCODETYPE fts5yyRuleInfoLhs[] = {
+ 16, /* (0) input ::= expr */
+ 20, /* (1) colset ::= MINUS LCP colsetlist RCP */
+ 20, /* (2) colset ::= LCP colsetlist RCP */
+ 20, /* (3) colset ::= STRING */
+ 20, /* (4) colset ::= MINUS STRING */
+ 21, /* (5) colsetlist ::= colsetlist STRING */
+ 21, /* (6) colsetlist ::= STRING */
+ 17, /* (7) expr ::= expr AND expr */
+ 17, /* (8) expr ::= expr OR expr */
+ 17, /* (9) expr ::= expr NOT expr */
+ 17, /* (10) expr ::= colset COLON LP expr RP */
+ 17, /* (11) expr ::= LP expr RP */
+ 17, /* (12) expr ::= exprlist */
+ 19, /* (13) exprlist ::= cnearset */
+ 19, /* (14) exprlist ::= exprlist cnearset */
+ 18, /* (15) cnearset ::= nearset */
+ 18, /* (16) cnearset ::= colset COLON nearset */
+ 22, /* (17) nearset ::= phrase */
+ 22, /* (18) nearset ::= CARET phrase */
+ 22, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */
+ 23, /* (20) nearphrases ::= phrase */
+ 23, /* (21) nearphrases ::= nearphrases phrase */
+ 25, /* (22) neardist_opt ::= */
+ 25, /* (23) neardist_opt ::= COMMA STRING */
+ 24, /* (24) phrase ::= phrase PLUS STRING star_opt */
+ 24, /* (25) phrase ::= STRING star_opt */
+ 26, /* (26) star_opt ::= STAR */
+ 26, /* (27) star_opt ::= */
+};
+
+/* For rule J, fts5yyRuleInfoNRhs[J] contains the negative of the number
+** of symbols on the right-hand side of that rule. */
+static const signed char fts5yyRuleInfoNRhs[] = {
+ -1, /* (0) input ::= expr */
+ -4, /* (1) colset ::= MINUS LCP colsetlist RCP */
+ -3, /* (2) colset ::= LCP colsetlist RCP */
+ -1, /* (3) colset ::= STRING */
+ -2, /* (4) colset ::= MINUS STRING */
+ -2, /* (5) colsetlist ::= colsetlist STRING */
+ -1, /* (6) colsetlist ::= STRING */
+ -3, /* (7) expr ::= expr AND expr */
+ -3, /* (8) expr ::= expr OR expr */
+ -3, /* (9) expr ::= expr NOT expr */
+ -5, /* (10) expr ::= colset COLON LP expr RP */
+ -3, /* (11) expr ::= LP expr RP */
+ -1, /* (12) expr ::= exprlist */
+ -1, /* (13) exprlist ::= cnearset */
+ -2, /* (14) exprlist ::= exprlist cnearset */
+ -1, /* (15) cnearset ::= nearset */
+ -3, /* (16) cnearset ::= colset COLON nearset */
+ -1, /* (17) nearset ::= phrase */
+ -2, /* (18) nearset ::= CARET phrase */
+ -5, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */
+ -1, /* (20) nearphrases ::= phrase */
+ -2, /* (21) nearphrases ::= nearphrases phrase */
+ 0, /* (22) neardist_opt ::= */
+ -2, /* (23) neardist_opt ::= COMMA STRING */
+ -4, /* (24) phrase ::= phrase PLUS STRING star_opt */
+ -2, /* (25) phrase ::= STRING star_opt */
+ -1, /* (26) star_opt ::= STAR */
+ 0, /* (27) star_opt ::= */
};
static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */
@@ -200688,7 +201902,7 @@ static fts5YYACTIONTYPE fts5yy_reduce(
fts5yymsp = fts5yypParser->fts5yytos;
#ifndef NDEBUG
if( fts5yyTraceFILE && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){
- fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
+ fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
if( fts5yysize ){
fprintf(fts5yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
fts5yyTracePrompt,
@@ -200703,7 +201917,7 @@ static fts5YYACTIONTYPE fts5yy_reduce(
/* Check that the stack is large enough to grow by a single entry
** if the RHS of the rule is empty. This ensures that there is room
** enough on the stack to push the LHS value */
- if( fts5yyRuleInfo[fts5yyruleno].nrhs==0 ){
+ if( fts5yyRuleInfoNRhs[fts5yyruleno]==0 ){
#ifdef fts5YYTRACKMAXSTACKDEPTH
if( (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)>fts5yypParser->fts5yyhwm ){
fts5yypParser->fts5yyhwm++;
@@ -200887,9 +202101,9 @@ static fts5YYACTIONTYPE fts5yy_reduce(
break;
/********** End reduce actions ************************************************/
};
- assert( fts5yyruleno<sizeof(fts5yyRuleInfo)/sizeof(fts5yyRuleInfo[0]) );
- fts5yygoto = fts5yyRuleInfo[fts5yyruleno].lhs;
- fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
+ assert( fts5yyruleno<sizeof(fts5yyRuleInfoLhs)/sizeof(fts5yyRuleInfoLhs[0]) );
+ fts5yygoto = fts5yyRuleInfoLhs[fts5yyruleno];
+ fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
fts5yyact = fts5yy_find_reduce_action(fts5yymsp[fts5yysize].stateno,(fts5YYCODETYPE)fts5yygoto);
/* There are no SHIFTREDUCE actions on nonterminals because the table
@@ -201320,7 +202534,7 @@ static void fts5HighlightAppend(
HighlightContext *p,
const char *z, int n
){
- if( *pRc==SQLITE_OK ){
+ if( *pRc==SQLITE_OK && z ){
if( n<0 ) n = (int)strlen(z);
p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z);
if( p->zOut==0 ) *pRc = SQLITE_NOMEM;
@@ -201452,7 +202666,7 @@ static int fts5SentenceFinderAdd(Fts5SFinder *p, int iAdd){
int nNew = p->nFirstAlloc ? p->nFirstAlloc*2 : 64;
int *aNew;
- aNew = (int*)sqlite3_realloc(p->aFirst, nNew*sizeof(int));
+ aNew = (int*)sqlite3_realloc64(p->aFirst, nNew*sizeof(int));
if( aNew==0 ) return SQLITE_NOMEM;
p->aFirst = aNew;
p->nFirstAlloc = nNew;
@@ -201519,11 +202733,12 @@ static int fts5SnippetScore(
int nInst;
int nScore = 0;
int iLast = 0;
+ sqlite3_int64 iEnd = (sqlite3_int64)iPos + nToken;
rc = pApi->xInstCount(pFts, &nInst);
for(i=0; i<nInst && rc==SQLITE_OK; i++){
rc = pApi->xInst(pFts, i, &ip, &ic, &iOff);
- if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<(iPos+nToken) ){
+ if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<iEnd ){
nScore += (aSeen[ip] ? 1 : 1000);
aSeen[ip] = 1;
if( iFirst<0 ) iFirst = iOff;
@@ -201533,7 +202748,7 @@ static int fts5SnippetScore(
*pnScore = nScore;
if( piPos ){
- int iAdj = iFirst - (nToken - (iLast-iFirst)) / 2;
+ sqlite3_int64 iAdj = iFirst - (nToken - (iLast-iFirst)) / 2;
if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken;
if( iAdj<0 ) iAdj = 0;
*piPos = iAdj;
@@ -201626,7 +202841,9 @@ static void fts5SnippetFunction(
int jj;
rc = pApi->xInst(pFts, ii, &ip, &ic, &io);
- if( ic!=i || rc!=SQLITE_OK ) continue;
+ if( ic!=i ) continue;
+ if( io>nDocsize ) rc = FTS5_CORRUPT;
+ if( rc!=SQLITE_OK ) continue;
memset(aSeen, 0, nPhrase);
rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
io, nToken, &nScore, &iAdj
@@ -201752,13 +202969,13 @@ static int fts5Bm25GetData(
int nPhrase; /* Number of phrases in query */
sqlite3_int64 nRow = 0; /* Number of rows in table */
sqlite3_int64 nToken = 0; /* Number of tokens in table */
- int nByte; /* Bytes of space to allocate */
+ sqlite3_int64 nByte; /* Bytes of space to allocate */
int i;
/* Allocate the Fts5Bm25Data object */
nPhrase = pApi->xPhraseCount(pFts);
nByte = sizeof(Fts5Bm25Data) + nPhrase*2*sizeof(double);
- p = (Fts5Bm25Data*)sqlite3_malloc(nByte);
+ p = (Fts5Bm25Data*)sqlite3_malloc64(nByte);
if( p==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -201770,6 +202987,7 @@ static int fts5Bm25GetData(
/* Calculate the average document length for this FTS5 table */
if( rc==SQLITE_OK ) rc = pApi->xRowCount(pFts, &nRow);
+ assert( rc!=SQLITE_OK || nRow>0 );
if( rc==SQLITE_OK ) rc = pApi->xColumnTotalSize(pFts, -1, &nToken);
if( rc==SQLITE_OK ) p->avgdl = (double)nToken / (double)nRow;
@@ -201895,8 +203113,6 @@ static int sqlite3Fts5AuxInit(fts5_api *pApi){
return rc;
}
-
-
/*
** 2014 May 31
**
@@ -201916,12 +203132,12 @@ static int sqlite3Fts5AuxInit(fts5_api *pApi){
static int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){
if( (u32)pBuf->nSpace<nByte ){
- u32 nNew = pBuf->nSpace ? pBuf->nSpace : 64;
+ u64 nNew = pBuf->nSpace ? pBuf->nSpace : 64;
u8 *pNew;
while( nNew<nByte ){
nNew = nNew * 2;
}
- pNew = sqlite3_realloc(pBuf->p, nNew);
+ pNew = sqlite3_realloc64(pBuf->p, nNew);
if( pNew==0 ){
*pRc = SQLITE_NOMEM;
return 1;
@@ -201951,7 +203167,7 @@ static void sqlite3Fts5Put32(u8 *aBuf, int iVal){
}
static int sqlite3Fts5Get32(const u8 *aBuf){
- return (aBuf[0] << 24) + (aBuf[1] << 16) + (aBuf[2] << 8) + aBuf[3];
+ return (int)((((u32)aBuf[0])<<24) + (aBuf[1]<<16) + (aBuf[2]<<8) + aBuf[3]);
}
/*
@@ -202082,7 +203298,7 @@ static int sqlite3Fts5PoslistNext64(
iOff = ((i64)iVal) << 32;
fts5FastGetVarint32(a, i, iVal);
}
- *piOff = iOff + (iVal-2);
+ *piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
*pi = i;
return 0;
}
@@ -202143,10 +203359,10 @@ static int sqlite3Fts5PoslistWriterAppend(
return SQLITE_OK;
}
-static void *sqlite3Fts5MallocZero(int *pRc, int nByte){
+static void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte){
void *pRet = 0;
if( *pRc==SQLITE_OK ){
- pRet = sqlite3_malloc(nByte);
+ pRet = sqlite3_malloc64(nByte);
if( pRet==0 ){
if( nByte>0 ) *pRc = SQLITE_NOMEM;
}else{
@@ -202589,7 +203805,7 @@ static int fts5ConfigParseSpecial(
if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
const char *p = (const char*)zArg;
- int nArg = (int)strlen(zArg) + 1;
+ sqlite3_int64 nArg = strlen(zArg) + 1;
char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
char *pSpace = pDel;
@@ -202719,8 +203935,8 @@ static const char *fts5ConfigGobbleWord(
){
const char *zRet = 0;
- int nIn = (int)strlen(zIn);
- char *zOut = sqlite3_malloc(nIn+1);
+ sqlite3_int64 nIn = strlen(zIn);
+ char *zOut = sqlite3_malloc64(nIn+1);
assert( *pRc==SQLITE_OK );
*pbQuoted = 0;
@@ -202823,7 +204039,7 @@ static int sqlite3Fts5ConfigParse(
int rc = SQLITE_OK; /* Return code */
Fts5Config *pRet; /* New object to return */
int i;
- int nByte;
+ sqlite3_int64 nByte;
*ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
if( pRet==0 ) return SQLITE_NOMEM;
@@ -203467,7 +204683,7 @@ static int fts5ExprGetToken(
return tok;
}
-static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc((int)t); }
+static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc64((sqlite3_int64)t);}
static void fts5ParseFree(void *p){ sqlite3_free(p); }
static int sqlite3Fts5ExprNew(
@@ -203612,8 +204828,8 @@ static int fts5ExprSynonymList(
if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){
if( pIter->nData==0 ) continue;
if( nIter==nAlloc ){
- int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
- Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
+ sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
+ Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
if( aNew==0 ){
rc = SQLITE_NOMEM;
goto synonym_poslist_out;
@@ -203693,8 +204909,8 @@ static int fts5ExprPhraseIsMatch(
/* If the aStatic[] array is not large enough, allocate a large array
** using sqlite3_malloc(). This approach could be improved upon. */
if( pPhrase->nTerm>ArraySize(aStatic) ){
- int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
- aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
+ sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
+ aIter = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
if( !aIter ) return SQLITE_NOMEM;
}
memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
@@ -203828,7 +205044,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
/* If the aStatic[] array is not large enough, allocate a large array
** using sqlite3_malloc(). This approach could be improved upon. */
if( pNear->nPhrase>ArraySize(aStatic) ){
- int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
+ sqlite3_int64 nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
}else{
memset(aStatic, 0, sizeof(aStatic));
@@ -204737,8 +205953,9 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset(
return pNear;
}
if( pNear==0 ){
- int nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
- pRet = sqlite3_malloc(nByte);
+ sqlite3_int64 nByte;
+ nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
+ pRet = sqlite3_malloc64(nByte);
if( pRet==0 ){
pParse->rc = SQLITE_NOMEM;
}else{
@@ -204746,9 +205963,10 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset(
}
}else if( (pNear->nPhrase % SZALLOC)==0 ){
int nNew = pNear->nPhrase + SZALLOC;
- int nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
+ sqlite3_int64 nByte;
- pRet = (Fts5ExprNearset*)sqlite3_realloc(pNear, nByte);
+ nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
+ pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte);
if( pRet==0 ){
pParse->rc = SQLITE_NOMEM;
}
@@ -204812,8 +206030,8 @@ static int fts5ParseTokenize(
if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){
Fts5ExprTerm *pSyn;
- int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
- pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
+ sqlite3_int64 nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
+ pSyn = (Fts5ExprTerm*)sqlite3_malloc64(nByte);
if( pSyn==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -204829,7 +206047,7 @@ static int fts5ParseTokenize(
Fts5ExprPhrase *pNew;
int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
- pNew = (Fts5ExprPhrase*)sqlite3_realloc(pPhrase,
+ pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase,
sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
);
if( pNew==0 ){
@@ -204915,9 +206133,9 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
if( pAppend==0 ){
if( (pParse->nPhrase % 8)==0 ){
- int nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
+ sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
Fts5ExprPhrase **apNew;
- apNew = (Fts5ExprPhrase**)sqlite3_realloc(pParse->apPhrase, nByte);
+ apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte);
if( apNew==0 ){
pParse->rc = SQLITE_NOMEM;
fts5ExprPhraseFree(sCtx.pPhrase);
@@ -204972,8 +206190,10 @@ static int sqlite3Fts5ExprClonePhrase(
if( rc==SQLITE_OK ){
Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
if( pColsetOrig ){
- int nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
- Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
+ sqlite3_int64 nByte;
+ Fts5Colset *pColset;
+ nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
+ pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
if( pColset ){
memcpy(pColset, pColsetOrig, nByte);
}
@@ -205093,7 +206313,7 @@ static Fts5Colset *fts5ParseColset(
assert( pParse->rc==SQLITE_OK );
assert( iCol>=0 && iCol<pParse->pConfig->nCol );
- pNew = sqlite3_realloc(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
+ pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
if( pNew==0 ){
pParse->rc = SQLITE_NOMEM;
}else{
@@ -205189,7 +206409,7 @@ static Fts5Colset *sqlite3Fts5ParseColset(
static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
Fts5Colset *pRet;
if( pOrig ){
- int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
+ sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
if( pRet ){
memcpy(pRet, pOrig, nByte);
@@ -205343,7 +206563,7 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
if( pParse->rc==SQLITE_OK ){
int nChild = 0; /* Number of children of returned node */
- int nByte; /* Bytes of space to allocate for this node */
+ sqlite3_int64 nByte; /* Bytes of space to allocate for this node */
assert( (eType!=FTS5_STRING && !pNear)
|| (eType==FTS5_STRING && !pLeft && !pRight)
@@ -205475,7 +206695,7 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
}
static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
- int nByte = 0;
+ sqlite3_int64 nByte = 0;
Fts5ExprTerm *p;
char *zQuoted;
@@ -205483,7 +206703,7 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
for(p=pTerm; p; p=p->pSynonym){
nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
}
- zQuoted = sqlite3_malloc(nByte);
+ zQuoted = sqlite3_malloc64(nByte);
if( zQuoted ){
int i = 0;
@@ -205723,7 +206943,7 @@ static void fts5ExprFunction(
}
nConfig = 3 + (nArg-iArg);
- azConfig = (const char**)sqlite3_malloc(sizeof(char*) * nConfig);
+ azConfig = (const char**)sqlite3_malloc64(sizeof(char*) * nConfig);
if( azConfig==0 ){
sqlite3_result_error_nomem(pCtx);
return;
@@ -205809,7 +207029,7 @@ static void fts5ExprIsAlnum(
sqlite3Fts5UnicodeCatParse("N*", aArr);
sqlite3Fts5UnicodeCatParse("Co", aArr);
iCode = sqlite3_value_int(apVal[0]);
- sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]);
+ sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory((u32)iCode)]);
}
static void fts5ExprFold(
@@ -205904,7 +207124,7 @@ struct Fts5PoslistPopulator {
static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
Fts5PoslistPopulator *pRet;
- pRet = sqlite3_malloc(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
+ pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
if( pRet ){
int i;
memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
@@ -206104,7 +207324,6 @@ static int sqlite3Fts5ExprPhraseCollist(
return rc;
}
-
/*
** 2014 August 11
**
@@ -206197,14 +207416,14 @@ static int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
- int nByte;
+ sqlite3_int64 nByte;
memset(pNew, 0, sizeof(Fts5Hash));
pNew->pnByte = pnByte;
pNew->eDetail = pConfig->eDetail;
pNew->nSlot = 1024;
nByte = sizeof(Fts5HashEntry*) * pNew->nSlot;
- pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc(nByte);
+ pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc64(nByte);
if( pNew->aSlot==0 ){
sqlite3_free(pNew);
*ppNew = 0;
@@ -206272,7 +207491,7 @@ static int fts5HashResize(Fts5Hash *pHash){
Fts5HashEntry **apNew;
Fts5HashEntry **apOld = pHash->aSlot;
- apNew = (Fts5HashEntry**)sqlite3_malloc(nNew*sizeof(Fts5HashEntry*));
+ apNew = (Fts5HashEntry**)sqlite3_malloc64(nNew*sizeof(Fts5HashEntry*));
if( !apNew ) return SQLITE_NOMEM;
memset(apNew, 0, nNew*sizeof(Fts5HashEntry*));
@@ -206366,7 +207585,7 @@ static int sqlite3Fts5HashWrite(
if( p==0 ){
/* Figure out how much space to allocate */
char *zKey;
- int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
+ sqlite3_int64 nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
if( nByte<128 ) nByte = 128;
/* Grow the Fts5Hash.aSlot[] array if necessary. */
@@ -206377,7 +207596,7 @@ static int sqlite3Fts5HashWrite(
}
/* Allocate new Fts5HashEntry and add it to the hash table. */
- p = (Fts5HashEntry*)sqlite3_malloc(nByte);
+ p = (Fts5HashEntry*)sqlite3_malloc64(nByte);
if( !p ) return SQLITE_NOMEM;
memset(p, 0, sizeof(Fts5HashEntry));
p->nAlloc = nByte;
@@ -206416,12 +207635,12 @@ static int sqlite3Fts5HashWrite(
** + 5 bytes for the new position offset (32-bit max).
*/
if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){
- int nNew = p->nAlloc * 2;
+ sqlite3_int64 nNew = p->nAlloc * 2;
Fts5HashEntry *pNew;
Fts5HashEntry **pp;
- pNew = (Fts5HashEntry*)sqlite3_realloc(p, nNew);
+ pNew = (Fts5HashEntry*)sqlite3_realloc64(p, nNew);
if( pNew==0 ) return SQLITE_NOMEM;
- pNew->nAlloc = nNew;
+ pNew->nAlloc = (int)nNew;
for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext);
*pp = pNew;
p = pNew;
@@ -206545,7 +207764,7 @@ static int fts5HashEntrySort(
int i;
*ppSorted = 0;
- ap = sqlite3_malloc(sizeof(Fts5HashEntry*) * nMergeSlot);
+ ap = sqlite3_malloc64(sizeof(Fts5HashEntry*) * nMergeSlot);
if( !ap ) return SQLITE_NOMEM;
memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot);
@@ -206590,7 +207809,8 @@ static int sqlite3Fts5HashQuery(
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
zKey = fts5EntryKey(p);
- if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break;
+ assert( p->nKey+1==(int)strlen(zKey) );
+ if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break;
}
if( p ){
@@ -206642,7 +207862,6 @@ static void sqlite3Fts5HashScanEntry(
}
}
-
/*
** 2014 May 31
**
@@ -207157,7 +208376,6 @@ struct Fts5Iter {
Fts5IndexIter base; /* Base class containing output vars */
Fts5Index *pIndex; /* Index that owns this iterator */
- Fts5Structure *pStruct; /* Database structure for this iterator */
Fts5Buffer poslist; /* Buffer containing current poslist */
Fts5Colset *pColset; /* Restrict matches to these columns */
@@ -207218,7 +208436,7 @@ static u16 fts5GetU16(const u8 *aIn){
** If an OOM error is encountered, return NULL and set the error code in
** the Fts5Index handle passed as the first argument.
*/
-static void *fts5IdxMalloc(Fts5Index *p, int nByte){
+static void *fts5IdxMalloc(Fts5Index *p, sqlite3_int64 nByte){
return sqlite3Fts5MallocZero(&p->rc, nByte);
}
@@ -207252,7 +208470,7 @@ static int fts5BufferCompareBlob(
*/
static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
int nCmp = MIN(pLeft->n, pRight->n);
- int res = memcmp(pLeft->p, pRight->p, nCmp);
+ int res = fts5Memcmp(pLeft->p, pRight->p, nCmp);
return (res==0 ? (pLeft->n - pRight->n) : res);
}
@@ -207318,8 +208536,8 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
if( rc==SQLITE_OK ){
u8 *aOut = 0; /* Read blob data into this buffer */
int nByte = sqlite3_blob_bytes(p->pReader);
- int nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
- pRet = (Fts5Data*)sqlite3_malloc(nAlloc);
+ sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
+ pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
if( pRet ){
pRet->nn = nByte;
aOut = pRet->p = (u8*)&pRet[1];
@@ -207335,6 +208553,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
pRet = 0;
}else{
/* TODO1: Fix this */
+ pRet->p[nByte] = 0x00;
pRet->szLeaf = fts5GetU16(&pRet->p[2]);
}
}
@@ -207374,7 +208593,8 @@ static int fts5IndexPrepareStmt(
if( p->rc==SQLITE_OK ){
if( zSql ){
p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
- SQLITE_PREPARE_PERSISTENT, ppStmt, 0);
+ SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB,
+ ppStmt, 0);
}else{
p->rc = SQLITE_NOMEM;
}
@@ -207415,23 +208635,12 @@ static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){
if( p->rc!=SQLITE_OK ) return;
if( p->pDeleter==0 ){
- int rc;
Fts5Config *pConfig = p->pConfig;
char *zSql = sqlite3_mprintf(
"DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?",
pConfig->zDb, pConfig->zName
);
- if( zSql==0 ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
- SQLITE_PREPARE_PERSISTENT, &p->pDeleter, 0);
- sqlite3_free(zSql);
- }
- if( rc!=SQLITE_OK ){
- p->rc = rc;
- return;
- }
+ if( fts5IndexPrepareStmt(p, &p->pDeleter, zSql) ) return;
}
sqlite3_bind_int64(p->pDeleter, 1, iFirst);
@@ -207503,7 +208712,7 @@ static int fts5StructureDecode(
int iLvl;
int nLevel = 0;
int nSegment = 0;
- int nByte; /* Bytes of space to allocate at pRet */
+ sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */
Fts5Structure *pRet = 0; /* Structure object to return */
/* Grab the cookie value */
@@ -207514,6 +208723,11 @@ static int fts5StructureDecode(
** structure record. */
i += fts5GetVarint32(&pData[i], nLevel);
i += fts5GetVarint32(&pData[i], nSegment);
+ if( nLevel>FTS5_MAX_SEGMENT || nLevel<0
+ || nSegment>FTS5_MAX_SEGMENT || nSegment<0
+ ){
+ return FTS5_CORRUPT;
+ }
nByte = (
sizeof(Fts5Structure) + /* Main structure */
sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */
@@ -207536,25 +208750,35 @@ static int fts5StructureDecode(
}else{
i += fts5GetVarint32(&pData[i], pLvl->nMerge);
i += fts5GetVarint32(&pData[i], nTotal);
- assert( nTotal>=pLvl->nMerge );
+ if( nTotal<pLvl->nMerge ) rc = FTS5_CORRUPT;
pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc,
nTotal * sizeof(Fts5StructureSegment)
);
+ nSegment -= nTotal;
}
if( rc==SQLITE_OK ){
pLvl->nSeg = nTotal;
for(iSeg=0; iSeg<nTotal; iSeg++){
+ Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
if( i>=nData ){
rc = FTS5_CORRUPT;
break;
}
- i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].iSegid);
- i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoFirst);
- i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoLast);
+ i += fts5GetVarint32(&pData[i], pSeg->iSegid);
+ i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst);
+ i += fts5GetVarint32(&pData[i], pSeg->pgnoLast);
+ if( pSeg->pgnoLast<pSeg->pgnoFirst ){
+ rc = FTS5_CORRUPT;
+ break;
+ }
}
+ if( iLvl>0 && pLvl[-1].nMerge && nTotal==0 ) rc = FTS5_CORRUPT;
+ if( iLvl==nLevel-1 && pLvl->nMerge ) rc = FTS5_CORRUPT;
}
}
+ if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT;
+
if( rc!=SQLITE_OK ){
fts5StructureRelease(pRet);
pRet = 0;
@@ -207572,12 +208796,12 @@ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
if( *pRc==SQLITE_OK ){
Fts5Structure *pStruct = *ppStruct;
int nLevel = pStruct->nLevel;
- int nByte = (
+ sqlite3_int64 nByte = (
sizeof(Fts5Structure) + /* Main structure */
sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */
);
- pStruct = sqlite3_realloc(pStruct, nByte);
+ pStruct = sqlite3_realloc64(pStruct, nByte);
if( pStruct ){
memset(&pStruct->aLevel[nLevel], 0, sizeof(Fts5StructureLevel));
pStruct->nLevel++;
@@ -207602,10 +208826,10 @@ static void fts5StructureExtendLevel(
if( *pRc==SQLITE_OK ){
Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
Fts5StructureSegment *aNew;
- int nByte;
+ sqlite3_int64 nByte;
nByte = (pLvl->nSeg + nExtra) * sizeof(Fts5StructureSegment);
- aNew = sqlite3_realloc(pLvl->aSeg, nByte);
+ aNew = sqlite3_realloc64(pLvl->aSeg, nByte);
if( aNew ){
if( bInsert==0 ){
memset(&aNew[pLvl->nSeg], 0, sizeof(Fts5StructureSegment) * nExtra);
@@ -208119,10 +209343,10 @@ static Fts5DlidxIter *fts5DlidxIterInit(
int bDone = 0;
for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
- int nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl);
+ sqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl);
Fts5DlidxIter *pNew;
- pNew = (Fts5DlidxIter*)sqlite3_realloc(pIter, nByte);
+ pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte);
if( pNew==0 ){
p->rc = SQLITE_NOMEM;
}else{
@@ -208292,12 +209516,13 @@ static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
int nNew; /* Bytes of new data */
iOff += fts5GetVarint32(&a[iOff], nNew);
- if( iOff+nNew>pIter->pLeaf->nn ){
+ if( iOff+nNew>pIter->pLeaf->szLeaf || nKeep>pIter->term.n || nNew==0 ){
p->rc = FTS5_CORRUPT;
return;
}
pIter->term.n = nKeep;
fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
+ assert( pIter->term.n<=pIter->term.nSpace );
iOff += nNew;
pIter->iTermLeafOffset = iOff;
pIter->iTermLeafPgno = pIter->iLeafPgno;
@@ -208362,7 +209587,7 @@ static void fts5SegIterInit(
if( p->rc==SQLITE_OK ){
pIter->iLeafOffset = 4;
assert_nc( pIter->pLeaf->nn>4 );
- assert( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
+ assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
fts5SegIterLoadTerm(p, pIter, 0);
fts5SegIterLoadNPos(p, pIter);
@@ -208418,7 +209643,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
/* If necessary, grow the pIter->aRowidOffset[] array. */
if( iRowidOffset>=pIter->nRowidOffset ){
int nNew = pIter->nRowidOffset + 8;
- int *aNew = (int*)sqlite3_realloc(pIter->aRowidOffset, nNew*sizeof(int));
+ int *aNew = (int*)sqlite3_realloc64(pIter->aRowidOffset,nNew*sizeof(int));
if( aNew==0 ){
p->rc = SQLITE_NOMEM;
break;
@@ -208872,10 +210097,10 @@ static void fts5LeafSeek(
int szLeaf = pIter->pLeaf->szLeaf;
int n = pIter->pLeaf->nn;
- int nMatch = 0;
- int nKeep = 0;
- int nNew = 0;
- int iTermOff;
+ u32 nMatch = 0;
+ u32 nKeep = 0;
+ u32 nNew = 0;
+ u32 iTermOff;
int iPgidx; /* Current offset in pgidx */
int bEndOfPage = 0;
@@ -208899,15 +210124,15 @@ static void fts5LeafSeek(
assert( nKeep>=nMatch );
if( nKeep==nMatch ){
- int nCmp;
- int i;
- nCmp = MIN(nNew, nTerm-nMatch);
+ u32 nCmp;
+ u32 i;
+ nCmp = (u32)MIN(nNew, nTerm-nMatch);
for(i=0; i<nCmp; i++){
if( a[iOff+i]!=pTerm[nMatch+i] ) break;
}
nMatch += i;
- if( nTerm==nMatch ){
+ if( (u32)nTerm==nMatch ){
if( i==nNew ){
goto search_success;
}else{
@@ -208951,6 +210176,7 @@ static void fts5LeafSeek(
iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
+ return;
}else{
nKeep = 0;
iTermOff = iOff;
@@ -208963,8 +210189,11 @@ static void fts5LeafSeek(
}
search_success:
-
pIter->iLeafOffset = iOff + nNew;
+ if( pIter->iLeafOffset>n || nNew<1 ){
+ p->rc = FTS5_CORRUPT;
+ return;
+ }
pIter->iTermLeafOffset = pIter->iLeafOffset;
pIter->iTermLeafPgno = pIter->iLeafPgno;
@@ -209071,7 +210300,7 @@ static void fts5SegIterSeekInit(
** 4) the FTS5INDEX_QUERY_SCAN flag was set and the iterator points
** to an entry with a term greater than or equal to (pTerm/nTerm).
*/
- assert( p->rc!=SQLITE_OK /* 1 */
+ assert_nc( p->rc!=SQLITE_OK /* 1 */
|| pIter->pLeaf==0 /* 2 */
|| fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)==0 /* 3 */
|| (bGe && fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)>0) /* 4 */
@@ -209169,7 +210398,7 @@ static void fts5AssertComparisonResult(
assert( pRes->iFirst==i1 );
}else{
int nMin = MIN(p1->term.n, p2->term.n);
- int res = memcmp(p1->term.p, p2->term.p, nMin);
+ int res = fts5Memcmp(p1->term.p, p2->term.p, nMin);
if( res==0 ) res = p1->term.n - p2->term.n;
if( res==0 ){
@@ -209392,7 +210621,6 @@ static void fts5MultiIterFree(Fts5Iter *pIter){
for(i=0; i<pIter->nSeg; i++){
fts5SegIterClear(&pIter->aSeg[i]);
}
- fts5StructureRelease(pIter->pStruct);
fts5BufferFree(&pIter->poslist);
sqlite3_free(pIter);
}
@@ -209740,7 +210968,8 @@ static void fts5SegiterPoslist(
Fts5Colset *pColset,
Fts5Buffer *pBuf
){
- if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){
+ if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+FTS5_DATA_ZERO_PADDING) ){
+ memset(&pBuf->p[pBuf->n+pSeg->nPos], 0, FTS5_DATA_ZERO_PADDING);
if( pColset==0 ){
fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
}else{
@@ -210038,9 +211267,7 @@ static void fts5MultiIterNew(
if( pNew==0 ) return;
pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY));
- pNew->pStruct = pStruct;
pNew->pColset = pColset;
- fts5StructureRef(pStruct);
if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){
fts5IterSetOutputCb(&p->rc, pNew);
}
@@ -210218,24 +211445,24 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid;
- if( iId<=FTS5_MAX_SEGMENT ){
- aUsed[(iId-1) / 32] |= 1 << ((iId-1) % 32);
+ if( iId<=FTS5_MAX_SEGMENT && iId>0 ){
+ aUsed[(iId-1) / 32] |= (u32)1 << ((iId-1) % 32);
}
}
}
for(i=0; aUsed[i]==0xFFFFFFFF; i++);
mask = aUsed[i];
- for(iSegid=0; mask & (1 << iSegid); iSegid++);
+ for(iSegid=0; mask & ((u32)1 << iSegid); iSegid++);
iSegid += 1 + i*32;
#ifdef SQLITE_DEBUG
for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
- assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
+ assert_nc( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
}
}
- assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
+ assert_nc( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
{
sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
@@ -210243,7 +211470,7 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
u8 aBlob[2] = {0xff, 0xff};
sqlite3_bind_int(pIdxSelect, 1, iSegid);
sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
- assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
+ assert_nc( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
p->rc = sqlite3_reset(pIdxSelect);
sqlite3_bind_null(pIdxSelect, 2);
}
@@ -210313,7 +211540,7 @@ static int fts5WriteDlidxGrow(
int nLvl
){
if( p->rc==SQLITE_OK && nLvl>=pWriter->nDlidx ){
- Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc(
+ Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc64(
pWriter->aDlidx, sizeof(Fts5DlidxWriter) * nLvl
);
if( aDlidx==0 ){
@@ -210392,8 +211619,10 @@ static void fts5WriteBtreeTerm(
int nTerm, const u8 *pTerm /* First term on new page */
){
fts5WriteFlushBtree(p, pWriter);
- fts5BufferSet(&p->rc, &pWriter->btterm, nTerm, pTerm);
- pWriter->iBtPage = pWriter->writer.pgno;
+ if( p->rc==SQLITE_OK ){
+ fts5BufferSet(&p->rc, &pWriter->btterm, nTerm, pTerm);
+ pWriter->iBtPage = pWriter->writer.pgno;
+ }
}
/*
@@ -210544,6 +211773,7 @@ static void fts5WriteAppendTerm(
int nPrefix; /* Bytes of prefix compression for term */
Fts5PageWriter *pPage = &pWriter->writer;
Fts5Buffer *pPgidx = &pWriter->writer.pgidx;
+ int nMin = MIN(pPage->term.n, nTerm);
assert( p->rc==SQLITE_OK );
assert( pPage->buf.n>=4 );
@@ -210553,6 +211783,7 @@ static void fts5WriteAppendTerm(
if( (pPage->buf.n + pPgidx->n + nTerm + 2)>=p->pConfig->pgsz ){
if( pPage->buf.n>4 ){
fts5WriteFlushLeaf(p, pWriter);
+ if( p->rc!=SQLITE_OK ) return;
}
fts5BufferGrow(&p->rc, &pPage->buf, nTerm+FTS5_DATA_PADDING);
}
@@ -210585,13 +211816,14 @@ static void fts5WriteAppendTerm(
** inefficient, but still correct. */
int n = nTerm;
if( pPage->term.n ){
- n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
+ n = 1 + fts5PrefixCompress(nMin, pPage->term.p, pTerm);
}
fts5WriteBtreeTerm(p, pWriter, n, pTerm);
+ if( p->rc!=SQLITE_OK ) return;
pPage = &pWriter->writer;
}
}else{
- nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
+ nPrefix = fts5PrefixCompress(nMin, pPage->term.p, pTerm);
fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
}
@@ -210638,7 +211870,7 @@ static void fts5WriteAppendRowid(
if( pWriter->bFirstRowidInDoclist || pWriter->bFirstRowidInPage ){
fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid);
}else{
- assert( p->rc || iRowid>pWriter->iPrevRowid );
+ assert_nc( p->rc || iRowid>pWriter->iPrevRowid );
fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid);
}
pWriter->iPrevRowid = iRowid;
@@ -210760,7 +211992,7 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
int i;
Fts5Buffer buf;
memset(&buf, 0, sizeof(Fts5Buffer));
- for(i=0; i<pIter->nSeg; i++){
+ for(i=0; i<pIter->nSeg && p->rc==SQLITE_OK; i++){
Fts5SegIter *pSeg = &pIter->aSeg[i];
if( pSeg->pSeg==0 ){
/* no-op */
@@ -210778,35 +212010,43 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
u8 aHdr[4] = {0x00, 0x00, 0x00, 0x00};
iLeafRowid = FTS5_SEGMENT_ROWID(iId, pSeg->iTermLeafPgno);
- pData = fts5DataRead(p, iLeafRowid);
+ pData = fts5LeafRead(p, iLeafRowid);
if( pData ){
- fts5BufferZero(&buf);
- fts5BufferGrow(&p->rc, &buf, pData->nn);
- fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr);
- fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n);
- fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p);
- fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff, &pData->p[iOff]);
- if( p->rc==SQLITE_OK ){
- /* Set the szLeaf field */
- fts5PutU16(&buf.p[2], (u16)buf.n);
- }
+ if( iOff>pData->szLeaf ){
+ /* This can occur if the pages that the segments occupy overlap - if
+ ** a single page has been assigned to more than one segment. In
+ ** this case a prior iteration of this loop may have corrupted the
+ ** segment currently being trimmed. */
+ p->rc = FTS5_CORRUPT;
+ }else{
+ fts5BufferZero(&buf);
+ fts5BufferGrow(&p->rc, &buf, pData->nn);
+ fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr);
+ fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n);
+ fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p);
+ fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff,&pData->p[iOff]);
+ if( p->rc==SQLITE_OK ){
+ /* Set the szLeaf field */
+ fts5PutU16(&buf.p[2], (u16)buf.n);
+ }
- /* Set up the new page-index array */
- fts5BufferAppendVarint(&p->rc, &buf, 4);
- if( pSeg->iLeafPgno==pSeg->iTermLeafPgno
- && pSeg->iEndofDoclist<pData->szLeaf
- ){
- int nDiff = pData->szLeaf - pSeg->iEndofDoclist;
- fts5BufferAppendVarint(&p->rc, &buf, buf.n - 1 - nDiff - 4);
- fts5BufferAppendBlob(&p->rc, &buf,
- pData->nn - pSeg->iPgidxOff, &pData->p[pSeg->iPgidxOff]
- );
- }
+ /* Set up the new page-index array */
+ fts5BufferAppendVarint(&p->rc, &buf, 4);
+ if( pSeg->iLeafPgno==pSeg->iTermLeafPgno
+ && pSeg->iEndofDoclist<pData->szLeaf
+ ){
+ int nDiff = pData->szLeaf - pSeg->iEndofDoclist;
+ fts5BufferAppendVarint(&p->rc, &buf, buf.n - 1 - nDiff - 4);
+ fts5BufferAppendBlob(&p->rc, &buf,
+ pData->nn - pSeg->iPgidxOff, &pData->p[pSeg->iPgidxOff]
+ );
+ }
+ pSeg->pSeg->pgnoFirst = pSeg->iTermLeafPgno;
+ fts5DataDelete(p, FTS5_SEGMENT_ROWID(iId, 1), iLeafRowid);
+ fts5DataWrite(p, iLeafRowid, buf.p, buf.n);
+ }
fts5DataRelease(pData);
- pSeg->pSeg->pgnoFirst = pSeg->iTermLeafPgno;
- fts5DataDelete(p, FTS5_SEGMENT_ROWID(iId, 1), iLeafRowid);
- fts5DataWrite(p, iLeafRowid, buf.p, buf.n);
}
}
}
@@ -210898,7 +212138,7 @@ static void fts5IndexMergeLevel(
const u8 *pTerm;
pTerm = fts5MultiIterTerm(pIter, &nTerm);
- if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){
+ if( nTerm!=term.n || fts5Memcmp(pTerm, term.p, nTerm) ){
if( pnRem && writer.nLeafWritten>nRem ){
break;
}
@@ -211153,6 +212393,7 @@ static void fts5FlushOneHash(Fts5Index *p){
/* Write the term for this entry to disk. */
sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm);
+ if( p->rc!=SQLITE_OK ) break;
assert( writer.bFirstRowidInPage==0 );
if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
@@ -211175,6 +212416,7 @@ static void fts5FlushOneHash(Fts5Index *p){
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
writer.bFirstRowidInPage = 0;
fts5WriteDlidxAppend(p, &writer, iRowid);
+ if( p->rc!=SQLITE_OK ) break;
}else{
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta);
}
@@ -211232,7 +212474,7 @@ static void fts5FlushOneHash(Fts5Index *p){
/* TODO2: Doclist terminator written here. */
/* pBuf->p[pBuf->n++] = '\0'; */
assert( pBuf->n<=pBuf->nSpace );
- sqlite3Fts5HashScanNext(pHash);
+ if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash);
}
sqlite3Fts5HashClear(pHash);
fts5WriteFinish(p, &writer, &pgnoLast);
@@ -211276,7 +212518,7 @@ static Fts5Structure *fts5IndexOptimizeStruct(
Fts5Structure *pStruct
){
Fts5Structure *pNew = 0;
- int nByte = sizeof(Fts5Structure);
+ sqlite3_int64 nByte = sizeof(Fts5Structure);
int nSeg = pStruct->nSegment;
int i;
@@ -211406,11 +212648,13 @@ static void fts5AppendPoslist(
Fts5Buffer *pBuf
){
int nData = pMulti->base.nData;
+ int nByte = nData + 9 + 9 + FTS5_DATA_ZERO_PADDING;
assert( nData>0 );
- if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nData+9+9) ){
+ if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nByte) ){
fts5BufferSafeAppendVarint(pBuf, iDelta);
fts5BufferSafeAppendVarint(pBuf, nData*2);
fts5BufferSafeAppendBlob(pBuf, pMulti->base.pData, nData);
+ memset(&pBuf->p[pBuf->n], 0, FTS5_DATA_ZERO_PADDING);
}
}
@@ -211591,6 +212835,8 @@ static void fts5MergePrefixLists(
int iOff2 = 0;
u8 *a1 = &i1.aPoslist[i1.nSize];
u8 *a2 = &i2.aPoslist[i2.nSize];
+ int nCopy;
+ u8 *aCopy;
i64 iPrev = 0;
Fts5PoslistWriter writer;
@@ -211622,7 +212868,7 @@ static void fts5MergePrefixLists(
sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
if( iPos1<0 ) break;
}else{
- assert( iPos2!=iPrev );
+ assert_nc( iPos2!=iPrev );
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
if( iPos2<0 ) break;
@@ -211634,11 +212880,16 @@ static void fts5MergePrefixLists(
if( iPos1!=iPrev ){
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
}
- fts5BufferSafeAppendBlob(&tmp, &a1[iOff1], i1.nPoslist-iOff1);
+ aCopy = &a1[iOff1];
+ nCopy = i1.nPoslist - iOff1;
}else{
assert( iPos2>=0 && iPos2!=iPrev );
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
- fts5BufferSafeAppendBlob(&tmp, &a2[iOff2], i2.nPoslist-iOff2);
+ aCopy = &a2[iOff2];
+ nCopy = i2.nPoslist - iOff2;
+ }
+ if( nCopy>0 ){
+ fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy);
}
/* WRITEPOSLISTSIZE */
@@ -211646,6 +212897,7 @@ static void fts5MergePrefixLists(
fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
fts5DoclistIterNext(&i1);
fts5DoclistIterNext(&i2);
+ assert( out.n<=(p1->n+p2->n+9) );
if( i1.aPoslist==0 || i2.aPoslist==0 ) break;
}
}
@@ -211747,7 +212999,7 @@ static void fts5SetupPrefixIter(
}
fts5MultiIterFree(p1);
- pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n);
+ pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING);
if( pData ){
pData->p = (u8*)&pData[1];
pData->nn = pData->szLeaf = doclist.n;
@@ -212509,11 +213761,11 @@ static void fts5IndexIntegrityCheckSegment(
iOff = fts5LeafFirstTermOff(pLeaf);
iRowidOff = fts5LeafFirstRowidOff(pLeaf);
- if( iRowidOff>=iOff ){
+ if( iRowidOff>=iOff || iOff>=pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
}else{
iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
- res = memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
+ res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
if( res==0 ) res = nTerm - nIdxTerm;
if( res<0 ) p->rc = FTS5_CORRUPT;
}
@@ -212908,7 +214160,7 @@ static void fts5DecodeFunction(
u8 *a = 0;
Fts5Buffer s; /* Build up text to return here */
int rc = SQLITE_OK; /* Return code */
- int nSpace = 0;
+ sqlite3_int64 nSpace = 0;
int eDetailNone = (sqlite3_user_data(pCtx)!=0);
assert( nArg==2 );
@@ -212924,8 +214176,7 @@ static void fts5DecodeFunction(
nSpace = n + FTS5_DATA_ZERO_PADDING;
a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
if( a==0 ) goto decode_out;
- memcpy(a, aBlob, n);
-
+ if( n>0 ) memcpy(a, aBlob, n);
fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);
@@ -213020,6 +214271,9 @@ static void fts5DecodeFunction(
iPgidxOff = szLeaf = fts5GetU16(&a[2]);
if( iPgidxOff<n ){
fts5GetVarint32(&a[iPgidxOff], iTermOff);
+ }else if( iPgidxOff>n ){
+ rc = FTS5_CORRUPT;
+ goto decode_out;
}
}
@@ -213031,14 +214285,22 @@ static void fts5DecodeFunction(
}else{
iOff = szLeaf;
}
+ if( iOff>n ){
+ rc = FTS5_CORRUPT;
+ goto decode_out;
+ }
fts5DecodePoslist(&rc, &s, &a[4], iOff-4);
/* Decode any more doclist data that appears on the page before the
** first term. */
nDoclist = (iTermOff ? iTermOff : szLeaf) - iOff;
+ if( nDoclist+iOff>n ){
+ rc = FTS5_CORRUPT;
+ goto decode_out;
+ }
fts5DecodeDoclist(&rc, &s, &a[iOff], nDoclist);
- while( iPgidxOff<n ){
+ while( iPgidxOff<n && rc==SQLITE_OK ){
int bFirst = (iPgidxOff==szLeaf); /* True for first term on page */
int nByte; /* Bytes of data */
int iEnd;
@@ -213053,12 +214315,24 @@ static void fts5DecodeFunction(
}else{
iEnd = szLeaf;
}
+ if( iEnd>szLeaf ){
+ rc = FTS5_CORRUPT;
+ break;
+ }
if( bFirst==0 ){
iOff += fts5GetVarint32(&a[iOff], nByte);
+ if( nByte>term.n ){
+ rc = FTS5_CORRUPT;
+ break;
+ }
term.n = nByte;
}
iOff += fts5GetVarint32(&a[iOff], nByte);
+ if( iOff+nByte>n ){
+ rc = FTS5_CORRUPT;
+ break;
+ }
fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]);
iOff += nByte;
@@ -213182,8 +214456,8 @@ SQLITE_API int sqlite3_fts5_may_be_corrupt = 1;
typedef struct Fts5Auxdata Fts5Auxdata;
typedef struct Fts5Auxiliary Fts5Auxiliary;
typedef struct Fts5Cursor Fts5Cursor;
+typedef struct Fts5FullTable Fts5FullTable;
typedef struct Fts5Sorter Fts5Sorter;
-typedef struct Fts5Table Fts5Table;
typedef struct Fts5TokenizerModule Fts5TokenizerModule;
/*
@@ -213264,13 +214538,8 @@ struct Fts5TokenizerModule {
Fts5TokenizerModule *pNext; /* Next registered tokenizer module */
};
-/*
-** Virtual-table object.
-*/
-struct Fts5Table {
- sqlite3_vtab base; /* Base class used by SQLite core */
- Fts5Config *pConfig; /* Virtual table configuration */
- Fts5Index *pIndex; /* Full-text index */
+struct Fts5FullTable {
+ Fts5Table p; /* Public class members from fts5Int.h */
Fts5Storage *pStorage; /* Document store */
Fts5Global *pGlobal; /* Global (connection wide) data */
Fts5Cursor *pSortCsr; /* Sort data from this cursor */
@@ -213408,7 +214677,7 @@ struct Fts5Auxdata {
#define FTS5_SAVEPOINT 5
#define FTS5_RELEASE 6
#define FTS5_ROLLBACKTO 7
-static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
+static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){
switch( op ){
case FTS5_BEGIN:
assert( p->ts.eState==0 );
@@ -213447,7 +214716,7 @@ static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
case FTS5_ROLLBACKTO:
assert( p->ts.eState==1 );
- assert( iSavepoint>=0 );
+ assert( iSavepoint>=-1 );
assert( iSavepoint<=p->ts.iSavepoint );
p->ts.iSavepoint = iSavepoint;
break;
@@ -213460,18 +214729,18 @@ static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
/*
** Return true if pTab is a contentless table.
*/
-static int fts5IsContentless(Fts5Table *pTab){
- return pTab->pConfig->eContent==FTS5_CONTENT_NONE;
+static int fts5IsContentless(Fts5FullTable *pTab){
+ return pTab->p.pConfig->eContent==FTS5_CONTENT_NONE;
}
/*
** Delete a virtual table handle allocated by fts5InitVtab().
*/
-static void fts5FreeVtab(Fts5Table *pTab){
+static void fts5FreeVtab(Fts5FullTable *pTab){
if( pTab ){
- sqlite3Fts5IndexClose(pTab->pIndex);
+ sqlite3Fts5IndexClose(pTab->p.pIndex);
sqlite3Fts5StorageClose(pTab->pStorage);
- sqlite3Fts5ConfigFree(pTab->pConfig);
+ sqlite3Fts5ConfigFree(pTab->p.pConfig);
sqlite3_free(pTab);
}
}
@@ -213480,7 +214749,7 @@ static void fts5FreeVtab(Fts5Table *pTab){
** The xDisconnect() virtual table method.
*/
static int fts5DisconnectMethod(sqlite3_vtab *pVtab){
- fts5FreeVtab((Fts5Table*)pVtab);
+ fts5FreeVtab((Fts5FullTable*)pVtab);
return SQLITE_OK;
}
@@ -213491,7 +214760,7 @@ static int fts5DestroyMethod(sqlite3_vtab *pVtab){
Fts5Table *pTab = (Fts5Table*)pVtab;
int rc = sqlite3Fts5DropAll(pTab->pConfig);
if( rc==SQLITE_OK ){
- fts5FreeVtab((Fts5Table*)pVtab);
+ fts5FreeVtab((Fts5FullTable*)pVtab);
}
return rc;
}
@@ -213520,28 +214789,28 @@ static int fts5InitVtab(
const char **azConfig = (const char**)argv;
int rc = SQLITE_OK; /* Return code */
Fts5Config *pConfig = 0; /* Results of parsing argc/argv */
- Fts5Table *pTab = 0; /* New virtual table object */
+ Fts5FullTable *pTab = 0; /* New virtual table object */
/* Allocate the new vtab object and parse the configuration */
- pTab = (Fts5Table*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Table));
+ pTab = (Fts5FullTable*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5FullTable));
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr);
assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 );
}
if( rc==SQLITE_OK ){
- pTab->pConfig = pConfig;
+ pTab->p.pConfig = pConfig;
pTab->pGlobal = pGlobal;
}
/* Open the index sub-system */
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->pIndex, pzErr);
+ rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->p.pIndex, pzErr);
}
/* Open the storage sub-system */
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageOpen(
- pConfig, pTab->pIndex, bCreate, &pTab->pStorage, pzErr
+ pConfig, pTab->p.pIndex, bCreate, &pTab->pStorage, pzErr
);
}
@@ -213554,8 +214823,8 @@ static int fts5InitVtab(
if( rc==SQLITE_OK ){
assert( pConfig->pzErrmsg==0 );
pConfig->pzErrmsg = pzErr;
- rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
- sqlite3Fts5IndexRollback(pTab->pIndex);
+ rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
+ sqlite3Fts5IndexRollback(pTab->p.pIndex);
pConfig->pzErrmsg = 0;
}
@@ -213768,7 +215037,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
return SQLITE_OK;
}
-static int fts5NewTransaction(Fts5Table *pTab){
+static int fts5NewTransaction(Fts5FullTable *pTab){
Fts5Cursor *pCsr;
for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK;
@@ -213780,16 +215049,16 @@ static int fts5NewTransaction(Fts5Table *pTab){
** Implementation of xOpen method.
*/
static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
- Fts5Table *pTab = (Fts5Table*)pVTab;
- Fts5Config *pConfig = pTab->pConfig;
+ Fts5FullTable *pTab = (Fts5FullTable*)pVTab;
+ Fts5Config *pConfig = pTab->p.pConfig;
Fts5Cursor *pCsr = 0; /* New cursor object */
- int nByte; /* Bytes of space to allocate */
+ sqlite3_int64 nByte; /* Bytes of space to allocate */
int rc; /* Return code */
rc = fts5NewTransaction(pTab);
if( rc==SQLITE_OK ){
nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
- pCsr = (Fts5Cursor*)sqlite3_malloc(nByte);
+ pCsr = (Fts5Cursor*)sqlite3_malloc64(nByte);
if( pCsr ){
Fts5Global *pGlobal = pTab->pGlobal;
memset(pCsr, 0, nByte);
@@ -213827,7 +215096,7 @@ static void fts5CsrNewrow(Fts5Cursor *pCsr){
}
static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
- Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
Fts5Auxdata *pData;
Fts5Auxdata *pNext;
@@ -213871,7 +215140,7 @@ static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
*/
static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){
if( pCursor ){
- Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
+ Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
Fts5Cursor **pp;
@@ -213928,7 +215197,7 @@ static int fts5SorterNext(Fts5Cursor *pCsr){
** Set the FTS5CSR_REQUIRE_RESEEK flag on all FTS5_PLAN_MATCH cursors
** open on table pTab.
*/
-static void fts5TripCursors(Fts5Table *pTab){
+static void fts5TripCursors(Fts5FullTable *pTab){
Fts5Cursor *pCsr;
for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
if( pCsr->ePlan==FTS5_PLAN_MATCH
@@ -213955,11 +215224,11 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
int rc = SQLITE_OK;
assert( *pbSkip==0 );
if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
- Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
int bDesc = pCsr->bDesc;
i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
- rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->pIndex, iRowid, bDesc);
+ rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->p.pIndex, iRowid, bDesc);
if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
*pbSkip = 1;
}
@@ -214056,18 +215325,22 @@ static int fts5PrepareStatement(
return rc;
}
-static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
- Fts5Config *pConfig = pTab->pConfig;
+static int fts5CursorFirstSorted(
+ Fts5FullTable *pTab,
+ Fts5Cursor *pCsr,
+ int bDesc
+){
+ Fts5Config *pConfig = pTab->p.pConfig;
Fts5Sorter *pSorter;
int nPhrase;
- int nByte;
+ sqlite3_int64 nByte;
int rc;
const char *zRank = pCsr->zRank;
const char *zRankArgs = pCsr->zRankArgs;
nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1);
- pSorter = (Fts5Sorter*)sqlite3_malloc(nByte);
+ pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte);
if( pSorter==0 ) return SQLITE_NOMEM;
memset(pSorter, 0, nByte);
pSorter->nIdx = nPhrase;
@@ -214104,10 +215377,10 @@ static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
return rc;
}
-static int fts5CursorFirst(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
+static int fts5CursorFirst(Fts5FullTable *pTab, Fts5Cursor *pCsr, int bDesc){
int rc;
Fts5Expr *pExpr = pCsr->pExpr;
- rc = sqlite3Fts5ExprFirst(pExpr, pTab->pIndex, pCsr->iFirstRowid, bDesc);
+ rc = sqlite3Fts5ExprFirst(pExpr, pTab->p.pIndex, pCsr->iFirstRowid, bDesc);
if( sqlite3Fts5ExprEof(pExpr) ){
CsrFlagSet(pCsr, FTS5CSR_EOF);
}
@@ -214122,7 +215395,7 @@ static int fts5CursorFirst(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
** parameters.
*/
static int fts5SpecialMatch(
- Fts5Table *pTab,
+ Fts5FullTable *pTab,
Fts5Cursor *pCsr,
const char *zQuery
){
@@ -214133,18 +215406,18 @@ static int fts5SpecialMatch(
while( z[0]==' ' ) z++;
for(n=0; z[n] && z[n]!=' '; n++);
- assert( pTab->base.zErrMsg==0 );
+ assert( pTab->p.base.zErrMsg==0 );
pCsr->ePlan = FTS5_PLAN_SPECIAL;
if( 0==sqlite3_strnicmp("reads", z, n) ){
- pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->pIndex);
+ pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex);
}
else if( 0==sqlite3_strnicmp("id", z, n) ){
pCsr->iSpecial = pCsr->iCsrId;
}
else{
/* An unrecognized directive. Return an error message. */
- pTab->base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
+ pTab->p.base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
rc = SQLITE_ERROR;
}
@@ -214156,7 +215429,7 @@ static int fts5SpecialMatch(
** pTab. If one is found, return a pointer to the corresponding Fts5Auxiliary
** structure. Otherwise, if no such function exists, return NULL.
*/
-static Fts5Auxiliary *fts5FindAuxiliary(Fts5Table *pTab, const char *zName){
+static Fts5Auxiliary *fts5FindAuxiliary(Fts5FullTable *pTab, const char *zName){
Fts5Auxiliary *pAux;
for(pAux=pTab->pGlobal->pAux; pAux; pAux=pAux->pNext){
@@ -214169,8 +215442,8 @@ static Fts5Auxiliary *fts5FindAuxiliary(Fts5Table *pTab, const char *zName){
static int fts5FindRankFunction(Fts5Cursor *pCsr){
- Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
- Fts5Config *pConfig = pTab->pConfig;
+ Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
+ Fts5Config *pConfig = pTab->p.pConfig;
int rc = SQLITE_OK;
Fts5Auxiliary *pAux = 0;
const char *zRank = pCsr->zRank;
@@ -214186,7 +215459,7 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){
assert( rc==SQLITE_OK || pCsr->pRankArgStmt==0 );
if( rc==SQLITE_OK ){
if( SQLITE_ROW==sqlite3_step(pStmt) ){
- int nByte;
+ sqlite3_int64 nByte;
pCsr->nRankArg = sqlite3_column_count(pStmt);
nByte = sizeof(sqlite3_value*)*pCsr->nRankArg;
pCsr->apRankArg = (sqlite3_value**)sqlite3Fts5MallocZero(&rc, nByte);
@@ -214208,8 +215481,8 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){
if( rc==SQLITE_OK ){
pAux = fts5FindAuxiliary(pTab, zRank);
if( pAux==0 ){
- assert( pTab->base.zErrMsg==0 );
- pTab->base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank);
+ assert( pTab->p.base.zErrMsg==0 );
+ pTab->p.base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank);
rc = SQLITE_ERROR;
}
}
@@ -214284,8 +215557,8 @@ static int fts5FilterMethod(
int nVal, /* Number of elements in apVal */
sqlite3_value **apVal /* Arguments for the indexing scheme */
){
- Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
- Fts5Config *pConfig = pTab->pConfig;
+ Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
+ Fts5Config *pConfig = pTab->p.pConfig;
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
int rc = SQLITE_OK; /* Error code */
int iVal = 0; /* Counter for apVal[] */
@@ -214314,8 +215587,8 @@ static int fts5FilterMethod(
assert( pCsr->zRank==0 );
assert( pCsr->zRankArgs==0 );
- assert( pzErrmsg==0 || pzErrmsg==&pTab->base.zErrMsg );
- pConfig->pzErrmsg = &pTab->base.zErrMsg;
+ assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg );
+ pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
/* Decode the arguments passed through to this function.
**
@@ -214381,7 +215654,7 @@ static int fts5FilterMethod(
** but a request for an internal parameter. */
rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
}else{
- char **pzErr = &pTab->base.zErrMsg;
+ char **pzErr = &pTab->p.base.zErrMsg;
rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
if( rc==SQLITE_OK ){
if( bOrderByRank ){
@@ -214404,7 +215677,7 @@ static int fts5FilterMethod(
** by rowid (ePlan==FTS5_PLAN_ROWID). */
pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
rc = sqlite3Fts5StorageStmt(
- pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->base.zErrMsg
+ pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg
);
if( rc==SQLITE_OK ){
if( pCsr->ePlan==FTS5_PLAN_ROWID ){
@@ -214487,12 +215760,12 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
/* If the cursor does not yet have a statement handle, obtain one now. */
if( pCsr->pStmt==0 ){
- Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
int eStmt = fts5StmtType(pCsr);
rc = sqlite3Fts5StorageStmt(
- pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->base.zErrMsg:0)
+ pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->p.base.zErrMsg:0)
);
- assert( rc!=SQLITE_OK || pTab->base.zErrMsg==0 );
+ assert( rc!=SQLITE_OK || pTab->p.base.zErrMsg==0 );
assert( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) );
}
@@ -214514,11 +215787,11 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
return rc;
}
-static void fts5SetVtabError(Fts5Table *p, const char *zFormat, ...){
+static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){
va_list ap; /* ... printf arguments */
va_start(ap, zFormat);
- assert( p->base.zErrMsg==0 );
- p->base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
+ assert( p->p.base.zErrMsg==0 );
+ p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
}
@@ -214538,11 +215811,11 @@ static void fts5SetVtabError(Fts5Table *p, const char *zFormat, ...){
** more commands are added to this function.
*/
static int fts5SpecialInsert(
- Fts5Table *pTab, /* Fts5 table object */
+ Fts5FullTable *pTab, /* Fts5 table object */
const char *zCmd, /* Text inserted into table-name column */
sqlite3_value *pVal /* Value inserted into rank column */
){
- Fts5Config *pConfig = pTab->pConfig;
+ Fts5Config *pConfig = pTab->p.pConfig;
int rc = SQLITE_OK;
int bError = 0;
@@ -214577,9 +215850,9 @@ static int fts5SpecialInsert(
pConfig->bPrefixIndex = sqlite3_value_int(pVal);
#endif
}else{
- rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
+ rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5ConfigSetValue(pTab->pConfig, zCmd, pVal, &bError);
+ rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError);
}
if( rc==SQLITE_OK ){
if( bError ){
@@ -214593,7 +215866,7 @@ static int fts5SpecialInsert(
}
static int fts5SpecialDelete(
- Fts5Table *pTab,
+ Fts5FullTable *pTab,
sqlite3_value **apVal
){
int rc = SQLITE_OK;
@@ -214607,7 +215880,7 @@ static int fts5SpecialDelete(
static void fts5StorageInsert(
int *pRc,
- Fts5Table *pTab,
+ Fts5FullTable *pTab,
sqlite3_value **apVal,
i64 *piRowid
){
@@ -214641,8 +215914,8 @@ static int fts5UpdateMethod(
sqlite3_value **apVal, /* Array of arguments */
sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
){
- Fts5Table *pTab = (Fts5Table*)pVtab;
- Fts5Config *pConfig = pTab->pConfig;
+ Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
+ Fts5Config *pConfig = pTab->p.pConfig;
int eType0; /* value_type() of apVal[0] */
int rc = SQLITE_OK; /* Return code */
@@ -214651,12 +215924,11 @@ static int fts5UpdateMethod(
assert( pVtab->zErrMsg==0 );
assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
- assert( nArg==1
- || sqlite3_value_type(apVal[1])==SQLITE_INTEGER
- || sqlite3_value_type(apVal[1])==SQLITE_NULL
+ assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER
+ || sqlite3_value_type(apVal[0])==SQLITE_NULL
);
- assert( pTab->pConfig->pzErrmsg==0 );
- pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
+ assert( pTab->p.pConfig->pzErrmsg==0 );
+ pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
/* Put any active cursors into REQUIRE_SEEK state. */
fts5TripCursors(pTab);
@@ -214697,7 +215969,7 @@ static int fts5UpdateMethod(
/* Filter out attempts to run UPDATE or DELETE on contentless tables.
** This is not suported. */
if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){
- pTab->base.zErrMsg = sqlite3_mprintf(
+ pTab->p.base.zErrMsg = sqlite3_mprintf(
"cannot %s contentless fts5 table: %s",
(nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
);
@@ -214710,46 +215982,52 @@ static int fts5UpdateMethod(
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
}
- /* INSERT */
- else if( eType0!=SQLITE_INTEGER ){
- /* If this is a REPLACE, first remove the current entry (if any) */
- if( eConflict==SQLITE_REPLACE
- && sqlite3_value_type(apVal[1])==SQLITE_INTEGER
- ){
- i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
+ /* INSERT or UPDATE */
+ else{
+ int eType1 = sqlite3_value_numeric_type(apVal[1]);
+
+ if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){
+ rc = SQLITE_MISMATCH;
}
- fts5StorageInsert(&rc, pTab, apVal, pRowid);
- }
- /* UPDATE */
- else{
- i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
- i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
- if( iOld!=iNew ){
- if( eConflict==SQLITE_REPLACE ){
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
- }
- fts5StorageInsert(&rc, pTab, apVal, pRowid);
- }else{
- rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
- if( rc==SQLITE_OK ){
+ else if( eType0!=SQLITE_INTEGER ){
+ /* If this is a REPLACE, first remove the current entry (if any) */
+ if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
+ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
+ }
+ fts5StorageInsert(&rc, pTab, apVal, pRowid);
+ }
+
+ /* UPDATE */
+ else{
+ i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
+ i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
+ if( eType1==SQLITE_INTEGER && iOld!=iNew ){
+ if( eConflict==SQLITE_REPLACE ){
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
+ }
+ fts5StorageInsert(&rc, pTab, apVal, pRowid);
+ }else{
+ rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid);
+ }
}
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *pRowid);
- }
+ }else{
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
+ fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
- }else{
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
- fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
}
}
- pTab->pConfig->pzErrmsg = 0;
+ pTab->p.pConfig->pzErrmsg = 0;
return rc;
}
@@ -214758,12 +216036,12 @@ static int fts5UpdateMethod(
*/
static int fts5SyncMethod(sqlite3_vtab *pVtab){
int rc;
- Fts5Table *pTab = (Fts5Table*)pVtab;
+ Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
- pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
+ pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
fts5TripCursors(pTab);
rc = sqlite3Fts5StorageSync(pTab->pStorage);
- pTab->pConfig->pzErrmsg = 0;
+ pTab->p.pConfig->pzErrmsg = 0;
return rc;
}
@@ -214771,8 +216049,8 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
** Implementation of xBegin() method.
*/
static int fts5BeginMethod(sqlite3_vtab *pVtab){
- fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0);
- fts5NewTransaction((Fts5Table*)pVtab);
+ fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
+ fts5NewTransaction((Fts5FullTable*)pVtab);
return SQLITE_OK;
}
@@ -214783,7 +216061,7 @@ static int fts5BeginMethod(sqlite3_vtab *pVtab){
*/
static int fts5CommitMethod(sqlite3_vtab *pVtab){
UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */
- fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_COMMIT, 0);
+ fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_COMMIT, 0);
return SQLITE_OK;
}
@@ -214793,7 +216071,7 @@ static int fts5CommitMethod(sqlite3_vtab *pVtab){
*/
static int fts5RollbackMethod(sqlite3_vtab *pVtab){
int rc;
- Fts5Table *pTab = (Fts5Table*)pVtab;
+ Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0);
rc = sqlite3Fts5StorageRollback(pTab->pStorage);
return rc;
@@ -214817,13 +216095,13 @@ static int fts5ApiColumnTotalSize(
sqlite3_int64 *pnToken
){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
return sqlite3Fts5StorageSize(pTab->pStorage, iCol, pnToken);
}
static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
}
@@ -214858,7 +216136,9 @@ static int fts5ApiColumnText(
){
int rc = SQLITE_OK;
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- if( fts5IsContentless((Fts5Table*)(pCsr->base.pVtab)) ){
+ if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab))
+ || pCsr->ePlan==FTS5_PLAN_SPECIAL
+ ){
*pz = 0;
*pn = 0;
}else{
@@ -214927,10 +216207,11 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
int rc = SQLITE_OK;
Fts5PoslistReader *aIter; /* One iterator for each phrase */
int nIter; /* Number of iterators/phrases */
+ int nCol = ((Fts5Table*)pCsr->base.pVtab)->pConfig->nCol;
nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
if( pCsr->aInstIter==0 ){
- int nByte = sizeof(Fts5PoslistReader) * nIter;
+ sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nIter;
pCsr->aInstIter = (Fts5PoslistReader*)sqlite3Fts5MallocZero(&rc, nByte);
}
aIter = pCsr->aInstIter;
@@ -214965,7 +216246,7 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
nInst++;
if( nInst>=pCsr->nInstAlloc ){
pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
- aInst = (int*)sqlite3_realloc(
+ aInst = (int*)sqlite3_realloc64(
pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3
);
if( aInst ){
@@ -214980,6 +216261,10 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
aInst[0] = iBest;
aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
+ if( aInst[1]<0 || aInst[1]>=nCol ){
+ rc = FTS5_CORRUPT;
+ break;
+ }
sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
}
}
@@ -215052,8 +216337,8 @@ static int fts5ColumnSizeCb(
static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
- Fts5Config *pConfig = pTab->pConfig;
+ Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
+ Fts5Config *pConfig = pTab->p.pConfig;
int rc = SQLITE_OK;
if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_DOCSIZE) ){
@@ -215309,7 +216594,7 @@ static int fts5ApiQueryPhrase(
int(*xCallback)(const Fts5ExtensionApi*, Fts5Context*, void*)
){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
- Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
int rc;
Fts5Cursor *pNew = 0;
@@ -215386,25 +216671,19 @@ static void fts5ApiCallback(
/*
-** Given cursor id iId, return a pointer to the corresponding Fts5Index
+** Given cursor id iId, return a pointer to the corresponding Fts5Table
** object. Or NULL If the cursor id does not exist.
-**
-** If successful, set *ppConfig to point to the associated config object
-** before returning.
*/
-static Fts5Index *sqlite3Fts5IndexFromCsrid(
+static Fts5Table *sqlite3Fts5TableFromCsrid(
Fts5Global *pGlobal, /* FTS5 global context for db handle */
- i64 iCsrId, /* Id of cursor to find */
- Fts5Config **ppConfig /* OUT: Configuration object */
+ i64 iCsrId /* Id of cursor to find */
){
Fts5Cursor *pCsr;
- Fts5Table *pTab;
-
pCsr = fts5CursorFromCsrid(pGlobal, iCsrId);
- pTab = (Fts5Table*)pCsr->base.pVtab;
- *ppConfig = pTab->pConfig;
-
- return pTab->pIndex;
+ if( pCsr ){
+ return (Fts5Table*)pCsr->base.pVtab;
+ }
+ return 0;
}
/*
@@ -215484,8 +216763,8 @@ static int fts5ColumnMethod(
sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */
int iCol /* Index of column to read value from */
){
- Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
- Fts5Config *pConfig = pTab->pConfig;
+ Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
+ Fts5Config *pConfig = pTab->p.pConfig;
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
int rc = SQLITE_OK;
@@ -215537,7 +216816,7 @@ static int fts5FindFunctionMethod(
void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
void **ppArg /* OUT: User data for *pxFunc */
){
- Fts5Table *pTab = (Fts5Table*)pVtab;
+ Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
Fts5Auxiliary *pAux;
UNUSED_PARAM(nUnused);
@@ -215559,21 +216838,24 @@ static int fts5RenameMethod(
sqlite3_vtab *pVtab, /* Virtual table handle */
const char *zName /* New name of table */
){
- Fts5Table *pTab = (Fts5Table*)pVtab;
+ Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
return sqlite3Fts5StorageRename(pTab->pStorage, zName);
}
+static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){
+ fts5TripCursors((Fts5FullTable*)pTab);
+ return sqlite3Fts5StorageSync(((Fts5FullTable*)pTab)->pStorage);
+}
+
/*
** The xSavepoint() method.
**
** Flush the contents of the pending-terms table to disk.
*/
static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
- Fts5Table *pTab = (Fts5Table*)pVtab;
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
- fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
- fts5TripCursors(pTab);
- return sqlite3Fts5StorageSync(pTab->pStorage);
+ fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_SAVEPOINT, iSavepoint);
+ return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
}
/*
@@ -215582,11 +216864,9 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
** This is a no-op.
*/
static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
- Fts5Table *pTab = (Fts5Table*)pVtab;
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
- fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
- fts5TripCursors(pTab);
- return sqlite3Fts5StorageSync(pTab->pStorage);
+ fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_RELEASE, iSavepoint);
+ return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
}
/*
@@ -215595,7 +216875,7 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
** Discard the contents of the pending terms table.
*/
static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
- Fts5Table *pTab = (Fts5Table*)pVtab;
+ Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
fts5TripCursors(pTab);
@@ -215796,7 +217076,7 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2019-02-08 13:17:39 0eca3dd3d38b31c92b49ca2d311128b74584714d9e7de895b1a6286ef959a1dd", -1, SQLITE_TRANSIENT);
}
/*
@@ -216045,7 +217325,7 @@ static int fts5StorageGetStmt(
char *zBind;
int i;
- zBind = sqlite3_malloc(1 + nCol*2);
+ zBind = sqlite3_malloc64(1 + nCol*2);
if( zBind ){
for(i=0; i<nCol; i++){
zBind[i*2] = '?';
@@ -216066,8 +217346,9 @@ static int fts5StorageGetStmt(
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
- rc = sqlite3_prepare_v3(pC->db, zSql, -1,
- SQLITE_PREPARE_PERSISTENT, &p->aStmt[eStmt], 0);
+ int f = SQLITE_PREPARE_PERSISTENT;
+ if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
+ rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
sqlite3_free(zSql);
if( rc!=SQLITE_OK && pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
@@ -216211,11 +217492,11 @@ static int sqlite3Fts5StorageOpen(
){
int rc = SQLITE_OK;
Fts5Storage *p; /* New object */
- int nByte; /* Bytes of space to allocate */
+ sqlite3_int64 nByte; /* Bytes of space to allocate */
nByte = sizeof(Fts5Storage) /* Fts5Storage object */
+ pConfig->nCol * sizeof(i64); /* Fts5Storage.aTotalSize[] */
- *pp = p = (Fts5Storage*)sqlite3_malloc(nByte);
+ *pp = p = (Fts5Storage*)sqlite3_malloc64(nByte);
if( !p ) return SQLITE_NOMEM;
memset(p, 0, nByte);
@@ -216226,7 +217507,7 @@ static int sqlite3Fts5StorageOpen(
if( bCreate ){
if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
int nDefn = 32 + pConfig->nCol*10;
- char *zDefn = sqlite3_malloc(32 + pConfig->nCol * 10);
+ char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10);
if( zDefn==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -216517,7 +217798,7 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){
Fts5Config *pConfig = p->pConfig;
sqlite3_stmt *pScan = 0;
Fts5InsertCtx ctx;
- int rc;
+ int rc, rc2;
memset(&ctx, 0, sizeof(Fts5InsertCtx));
ctx.pStorage = p;
@@ -216556,6 +217837,8 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){
}
}
sqlite3_free(buf.p);
+ rc2 = sqlite3_reset(pScan);
+ if( rc==SQLITE_OK ) rc = rc2;
/* Write the averages record */
if( rc==SQLITE_OK ){
@@ -216805,7 +218088,7 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
memset(&ctx, 0, sizeof(Fts5IntegrityCtx));
ctx.pConfig = p->pConfig;
- aTotalSize = (i64*)sqlite3_malloc(pConfig->nCol * (sizeof(int)+sizeof(i64)));
+ aTotalSize = (i64*)sqlite3_malloc64(pConfig->nCol*(sizeof(int)+sizeof(i64)));
if( !aTotalSize ) return SQLITE_NOMEM;
aColSize = (int*)&aTotalSize[pConfig->nCol];
memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol);
@@ -217005,7 +218288,13 @@ static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){
static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
int rc = fts5StorageLoadTotals(p, 0);
if( rc==SQLITE_OK ){
+ /* nTotalRow being zero does not necessarily indicate a corrupt
+ ** database - it might be that the FTS5 table really does contain zero
+ ** rows. However this function is only called from the xRowCount() API,
+ ** and there is no way for that API to be invoked if the table contains
+ ** no rows. Hence the FTS5_CORRUPT return. */
*pnRow = p->nTotalRow;
+ if( p->nTotalRow<=0 ) rc = FTS5_CORRUPT;
}
return rc;
}
@@ -217215,7 +218504,7 @@ static int fts5AsciiTokenize(
nByte = ie-is;
if( nByte>nFold ){
if( pFold!=aFold ) sqlite3_free(pFold);
- pFold = sqlite3_malloc(nByte*2);
+ pFold = sqlite3_malloc64((sqlite3_int64)nByte*2);
if( pFold==0 ){
rc = SQLITE_NOMEM;
break;
@@ -217297,13 +218586,18 @@ struct Unicode61Tokenizer {
unsigned char aTokenChar[128]; /* ASCII range token characters */
char *aFold; /* Buffer to fold text into */
int nFold; /* Size of aFold[] in bytes */
- int bRemoveDiacritic; /* True if remove_diacritics=1 is set */
+ int eRemoveDiacritic; /* True if remove_diacritics=1 is set */
int nException;
int *aiException;
unsigned char aCategory[32]; /* True for token char categories */
};
+/* Values for eRemoveDiacritic (must match internals of fts5_unicode2.c) */
+#define FTS5_REMOVE_DIACRITICS_NONE 0
+#define FTS5_REMOVE_DIACRITICS_SIMPLE 1
+#define FTS5_REMOVE_DIACRITICS_COMPLEX 2
+
static int fts5UnicodeAddExceptions(
Unicode61Tokenizer *p, /* Tokenizer object */
const char *z, /* Characters to treat as exceptions */
@@ -217314,13 +218608,14 @@ static int fts5UnicodeAddExceptions(
int *aNew;
if( n>0 ){
- aNew = (int*)sqlite3_realloc(p->aiException, (n+p->nException)*sizeof(int));
+ aNew = (int*)sqlite3_realloc64(p->aiException,
+ (n+p->nException)*sizeof(int));
if( aNew ){
int nNew = p->nException;
const unsigned char *zCsr = (const unsigned char*)z;
const unsigned char *zTerm = (const unsigned char*)&z[n];
while( zCsr<zTerm ){
- int iCode;
+ u32 iCode;
int bToken;
READ_UTF8(zCsr, zTerm, iCode);
if( iCode<128 ){
@@ -217332,7 +218627,7 @@ static int fts5UnicodeAddExceptions(
if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
int i;
for(i=0; i<nNew; i++){
- if( aNew[i]>iCode ) break;
+ if( (u32)aNew[i]>iCode ) break;
}
memmove(&aNew[i+1], &aNew[i], (nNew-i)*sizeof(int));
aNew[i] = iCode;
@@ -217424,7 +218719,7 @@ static int fts5UnicodeCreate(
int i;
memset(p, 0, sizeof(Unicode61Tokenizer));
- p->bRemoveDiacritic = 1;
+ p->eRemoveDiacritic = FTS5_REMOVE_DIACRITICS_SIMPLE;
p->nFold = 64;
p->aFold = sqlite3_malloc(p->nFold * sizeof(char));
if( p->aFold==0 ){
@@ -217445,10 +218740,15 @@ static int fts5UnicodeCreate(
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
const char *zArg = azArg[i+1];
if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
- if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
+ if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
rc = SQLITE_ERROR;
+ }else{
+ p->eRemoveDiacritic = (zArg[0] - '0');
+ assert( p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_NONE
+ || p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_SIMPLE
+ || p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_COMPLEX
+ );
}
- p->bRemoveDiacritic = (zArg[0]=='1');
}else
if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
rc = fts5UnicodeAddExceptions(p, zArg, 1);
@@ -217482,7 +218782,7 @@ static int fts5UnicodeCreate(
*/
static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
return (
- p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]
+ p->aCategory[sqlite3Fts5UnicodeCategory((u32)iCode)]
^ fts5UnicodeIsException(p, iCode)
);
}
@@ -217511,7 +218811,7 @@ static int fts5UnicodeTokenize(
/* Each iteration of this loop gobbles up a contiguous run of separators,
** then the next token. */
while( rc==SQLITE_OK ){
- int iCode; /* non-ASCII codepoint read from input */
+ u32 iCode; /* non-ASCII codepoint read from input */
char *zOut = aFold;
int is;
int ie;
@@ -217543,7 +218843,7 @@ static int fts5UnicodeTokenize(
/* Grow the output buffer so that there is sufficient space to fit the
** largest possible utf-8 character. */
if( zOut>pEnd ){
- aFold = sqlite3_malloc(nFold*2);
+ aFold = sqlite3_malloc64((sqlite3_int64)nFold*2);
if( aFold==0 ){
rc = SQLITE_NOMEM;
goto tokenize_done;
@@ -217562,7 +218862,7 @@ static int fts5UnicodeTokenize(
READ_UTF8(zCsr, zTerm, iCode);
if( fts5UnicodeIsAlnum(p,iCode)||sqlite3Fts5UnicodeIsdiacritic(iCode) ){
non_ascii_tokenchar:
- iCode = sqlite3Fts5UnicodeFold(iCode, p->bRemoveDiacritic);
+ iCode = sqlite3Fts5UnicodeFold(iCode, p->eRemoveDiacritic);
if( iCode ) WRITE_UTF8(zOut, iCode);
}else{
break;
@@ -218338,10 +219638,8 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
return rc;
}
-
-
/*
-** 2012 May 25
+** 2012-05-25
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -218370,32 +219668,48 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
** E"). The resuls of passing a codepoint that corresponds to an
** uppercase letter are undefined.
*/
-static int fts5_remove_diacritic(int c){
+static int fts5_remove_diacritic(int c, int bComplex){
unsigned short aDia[] = {
0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336,
- 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928,
- 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234,
- 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504,
- 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529,
- 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
- 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122,
- 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536,
- 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730,
- 62924, 63050, 63082, 63274, 63390,
+ 3456, 3696, 3712, 3728, 3744, 3766, 3832, 3896,
+ 3912, 3928, 3944, 3968, 4008, 4040, 4056, 4106,
+ 4138, 4170, 4202, 4234, 4266, 4296, 4312, 4344,
+ 4408, 4424, 4442, 4472, 4488, 4504, 6148, 6198,
+ 6264, 6280, 6360, 6429, 6505, 6529, 61448, 61468,
+ 61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704,
+ 61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914,
+ 61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218,
+ 62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554,
+ 62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766,
+ 62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118,
+ 63182, 63242, 63274, 63310, 63368, 63390,
};
- char aChar[] = {
- '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c',
- 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
- 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
- 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
- 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
- '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
- 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
- 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
- 'e', 'i', 'o', 'u', 'y',
+#define HIBIT ((unsigned char)0x80)
+ unsigned char aChar[] = {
+ '\0', 'a', 'c', 'e', 'i', 'n',
+ 'o', 'u', 'y', 'y', 'a', 'c',
+ 'd', 'e', 'e', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'n', 'o', 'r',
+ 's', 't', 'u', 'u', 'w', 'y',
+ 'z', 'o', 'u', 'a', 'i', 'o',
+ 'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o',
+ 'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a',
+ 'e', 'i', 'o', 'r', 'u', 's',
+ 't', 'h', 'a', 'e', 'o'|HIBIT, 'o',
+ 'o'|HIBIT, 'y', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', 'a', 'b',
+ 'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT,
+ 'f', 'g', 'h', 'h', 'i', 'i'|HIBIT,
+ 'k', 'l', 'l'|HIBIT, 'l', 'm', 'n',
+ 'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's',
+ 's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w',
+ 'w', 'x', 'y', 'z', 'h', 't',
+ 'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT,
+ 'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT,
+ 'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y',
};
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
@@ -218412,7 +219726,8 @@ static int fts5_remove_diacritic(int c){
}
}
assert( key>=aDia[iRes] );
- return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
+ if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
+ return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);
}
@@ -218425,8 +219740,8 @@ static int sqlite3Fts5UnicodeIsdiacritic(int c){
unsigned int mask1 = 0x000361F8;
if( c<768 || c>817 ) return 0;
return (c < 768+32) ?
- (mask0 & (1 << (c-768))) :
- (mask1 & (1 << (c-768-32)));
+ (mask0 & ((unsigned int)1 << (c-768))) :
+ (mask1 & ((unsigned int)1 << (c-768-32)));
}
@@ -218439,7 +219754,7 @@ static int sqlite3Fts5UnicodeIsdiacritic(int c){
** The results are undefined if the value passed to this function
** is less than zero.
*/
-static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
+static int sqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){
/* Each entry in the following array defines a rule for folding a range
** of codepoints to lower case. The rule applies to a range of nRange
** codepoints starting at codepoint iCode.
@@ -218562,7 +219877,9 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
assert( ret>0 );
}
- if( bRemoveDiacritic ) ret = fts5_remove_diacritic(ret);
+ if( eRemoveDiacritic ){
+ ret = fts5_remove_diacritic(ret, eRemoveDiacritic==2);
+ }
}
else if( c>=66560 && c<66600 ){
@@ -218573,12 +219890,6 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
}
-#if 0
-static int sqlite3Fts5UnicodeNCat(void) {
- return 32;
-}
-#endif
-
static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){
aArray[0] = 1;
switch( zCat[0] ){
@@ -219060,7 +220371,7 @@ static u16 aFts5UnicodeData[] = {
34, 3074, 7692, 63, 63,
};
-static int sqlite3Fts5UnicodeCategory(int iCode) {
+static int sqlite3Fts5UnicodeCategory(u32 iCode) {
int iRes = -1;
int iHi;
int iLo;
@@ -219098,13 +220409,12 @@ static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ];
int n = (aFts5UnicodeData[iTbl] >> 5) + i;
for(; i<128 && i<n; i++){
- aAscii[i] = (u8)bToken;
+ aAscii[i] = bToken;
}
iTbl++;
}
}
-
/*
** 2015 May 30
**
@@ -219183,7 +220493,7 @@ static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){
u8 n;
p -= 2;
n = sqlite3Fts5GetVarint(p, &v64);
- *v = (u32)v64;
+ *v = ((u32)v64) & 0x7FFFFFFF;
assert( n>3 && n<=9 );
return n;
}
@@ -219450,7 +220760,6 @@ static int sqlite3Fts5GetVarintLen(u32 iVal){
return 5;
}
-
/*
** 2015 May 08
**
@@ -219508,7 +220817,7 @@ struct Fts5VocabTable {
struct Fts5VocabCursor {
sqlite3_vtab_cursor base;
sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */
- Fts5Index *pIndex; /* Associated FTS5 index */
+ Fts5Table *pFts5; /* Associated FTS5 table */
int bEof; /* True if this cursor is at EOF */
Fts5IndexIter *pIter; /* Term/rowid iterator object */
@@ -219517,7 +220826,6 @@ struct Fts5VocabCursor {
char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
/* These are used by 'col' tables only */
- Fts5Config *pConfig; /* Fts5 table configuration */
int iCol;
i64 *aCnt;
i64 *aDoc;
@@ -219780,8 +221088,7 @@ static int fts5VocabOpenMethod(
sqlite3_vtab_cursor **ppCsr
){
Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
- Fts5Index *pIndex = 0;
- Fts5Config *pConfig = 0;
+ Fts5Table *pFts5 = 0;
Fts5VocabCursor *pCsr = 0;
int rc = SQLITE_OK;
sqlite3_stmt *pStmt = 0;
@@ -219800,31 +221107,34 @@ static int fts5VocabOpenMethod(
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
i64 iId = sqlite3_column_int64(pStmt, 0);
- pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig);
+ pFts5 = sqlite3Fts5TableFromCsrid(pTab->pGlobal, iId);
}
- if( rc==SQLITE_OK && pIndex==0 ){
- rc = sqlite3_finalize(pStmt);
- pStmt = 0;
- if( rc==SQLITE_OK ){
- pVTab->zErrMsg = sqlite3_mprintf(
- "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
- );
- rc = SQLITE_ERROR;
+ if( rc==SQLITE_OK ){
+ if( pFts5==0 ){
+ rc = sqlite3_finalize(pStmt);
+ pStmt = 0;
+ if( rc==SQLITE_OK ){
+ pVTab->zErrMsg = sqlite3_mprintf(
+ "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
+ );
+ rc = SQLITE_ERROR;
+ }
+ }else{
+ rc = sqlite3Fts5FlushToDisk(pFts5);
}
}
if( rc==SQLITE_OK ){
- int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
+ int nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor);
pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
}
if( pCsr ){
- pCsr->pIndex = pIndex;
+ pCsr->pFts5 = pFts5;
pCsr->pStmt = pStmt;
- pCsr->pConfig = pConfig;
pCsr->aCnt = (i64*)&pCsr[1];
- pCsr->aDoc = &pCsr->aCnt[pConfig->nCol];
+ pCsr->aDoc = &pCsr->aCnt[pFts5->pConfig->nCol];
}else{
sqlite3_finalize(pStmt);
}
@@ -219840,6 +221150,7 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
sqlite3_free(pCsr->zLeTerm);
pCsr->nLeTerm = -1;
pCsr->zLeTerm = 0;
+ pCsr->bEof = 0;
}
/*
@@ -219878,7 +221189,7 @@ static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){
}
static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
- int eDetail = pCsr->pConfig->eDetail;
+ int eDetail = pCsr->pFts5->pConfig->eDetail;
int rc = SQLITE_OK;
Fts5IndexIter *pIter = pCsr->pIter;
i64 *pp = &pCsr->iInstPos;
@@ -219913,7 +221224,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
int rc = SQLITE_OK;
- int nCol = pCsr->pConfig->nCol;
+ int nCol = pCsr->pFts5->pConfig->nCol;
pCsr->rowid++;
@@ -219935,6 +221246,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
int nTerm;
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
+ assert( nTerm>=0 );
if( pCsr->nLeTerm>=0 ){
int nCmp = MIN(nTerm, pCsr->nLeTerm);
int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
@@ -219951,7 +221263,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
while( rc==SQLITE_OK ){
- int eDetail = pCsr->pConfig->eDetail;
+ int eDetail = pCsr->pFts5->pConfig->eDetail;
const u8 *pPos; int nPos; /* Position list */
i64 iPos = 0; /* 64-bit position read from poslist */
int iOff = 0; /* Current offset within position list */
@@ -219974,7 +221286,6 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
int iCol = -1;
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
int ii = FTS5_POS2COLUMN(iPos);
- pCsr->aCnt[ii]++;
if( iCol!=ii ){
if( ii>=nCol ){
rc = FTS5_CORRUPT;
@@ -219983,6 +221294,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
pCsr->aDoc[ii]++;
iCol = ii;
}
+ pCsr->aCnt[ii]++;
}
}else if( eDetail==FTS5_DETAIL_COLUMNS ){
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
@@ -220011,7 +221323,9 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
if( rc==SQLITE_OK ){
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
- if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){
+ if( nTerm!=pCsr->term.n
+ || (nTerm>0 && memcmp(zTerm, pCsr->term.p, nTerm))
+ ){
break;
}
if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
@@ -220022,7 +221336,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++;
- assert( pCsr->iCol<pCsr->pConfig->nCol );
+ assert( pCsr->iCol<pCsr->pFts5->pConfig->nCol );
}
return rc;
}
@@ -220069,6 +221383,7 @@ static int fts5VocabFilterMethod(
}
if( pLe ){
const char *zCopy = (const char *)sqlite3_value_text(pLe);
+ if( zCopy==0 ) zCopy = "";
pCsr->nLeTerm = sqlite3_value_bytes(pLe);
pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
if( pCsr->zLeTerm==0 ){
@@ -220080,14 +221395,15 @@ static int fts5VocabFilterMethod(
}
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
+ Fts5Index *pIndex = pCsr->pFts5->pIndex;
+ rc = sqlite3Fts5IndexQuery(pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
}
if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){
rc = fts5VocabInstanceNewTerm(pCsr);
}
- if( rc==SQLITE_OK
- && !pCsr->bEof
- && (eType!=FTS5_VOCAB_INSTANCE || pCsr->pConfig->eDetail!=FTS5_DETAIL_NONE)
+ if( rc==SQLITE_OK && !pCsr->bEof
+ && (eType!=FTS5_VOCAB_INSTANCE
+ || pCsr->pFts5->pConfig->eDetail!=FTS5_DETAIL_NONE)
){
rc = fts5VocabNextMethod(pCursor);
}
@@ -220110,7 +221426,7 @@ static int fts5VocabColumnMethod(
int iCol /* Index of column to read value from */
){
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
- int eDetail = pCsr->pConfig->eDetail;
+ int eDetail = pCsr->pFts5->pConfig->eDetail;
int eType = ((Fts5VocabTable*)(pCursor->pVtab))->eType;
i64 iVal = 0;
@@ -220122,7 +221438,7 @@ static int fts5VocabColumnMethod(
assert( iCol==1 || iCol==2 || iCol==3 );
if( iCol==1 ){
if( eDetail!=FTS5_DETAIL_NONE ){
- const char *z = pCsr->pConfig->azCol[pCsr->iCol];
+ const char *z = pCsr->pFts5->pConfig->azCol[pCsr->iCol];
sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
}
}else if( iCol==2 ){
@@ -220150,8 +221466,8 @@ static int fts5VocabColumnMethod(
}else if( eDetail==FTS5_DETAIL_COLUMNS ){
ii = (int)pCsr->iInstPos;
}
- if( ii>=0 && ii<pCsr->pConfig->nCol ){
- const char *z = pCsr->pConfig->azCol[ii];
+ if( ii>=0 && ii<pCsr->pFts5->pConfig->nCol ){
+ const char *z = pCsr->pFts5->pConfig->azCol[ii];
sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
}
break;
@@ -220524,9 +221840,9 @@ SQLITE_API int sqlite3_stmt_init(
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
-#if __LINE__!=220527
+#if __LINE__!=221843
#undef SQLITE_SOURCE_ID
-#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238alt2"
+#define SQLITE_SOURCE_ID "2019-02-08 13:17:39 0eca3dd3d38b31c92b49ca2d311128b74584714d9e7de895b1a6286ef959alt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h
index f36ae57a64..686aa8b739 100644
--- a/src/3rdparty/sqlite/sqlite3.h
+++ b/src/3rdparty/sqlite/sqlite3.h
@@ -123,9 +123,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.26.0"
-#define SQLITE_VERSION_NUMBER 3026000
-#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
+#define SQLITE_VERSION "3.27.1"
+#define SQLITE_VERSION_NUMBER 3027001
+#define SQLITE_SOURCE_ID "2019-02-08 13:17:39 0eca3dd3d38b31c92b49ca2d311128b74584714d9e7de895b1a6286ef959a1dd"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -823,6 +823,15 @@ struct sqlite3_io_methods {
** file space based on this hint in order to help writes to the database
** file run faster.
**
+** <li>[[SQLITE_FCNTL_SIZE_LIMIT]]
+** The [SQLITE_FCNTL_SIZE_LIMIT] opcode is used by in-memory VFS that
+** implements [sqlite3_deserialize()] to set an upper bound on the size
+** of the in-memory database. The argument is a pointer to a [sqlite3_int64].
+** If the integer pointed to is negative, then it is filled in with the
+** current limit. Otherwise the limit is set to the larger of the value
+** of the integer pointed to and the current database size. The integer
+** pointed to is set to the new limit.
+**
** <li>[[SQLITE_FCNTL_CHUNK_SIZE]]
** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
** extends and truncates the database file in chunks of a size specified
@@ -1131,6 +1140,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
#define SQLITE_FCNTL_DATA_VERSION 35
+#define SQLITE_FCNTL_SIZE_LIMIT 36
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -1972,6 +1982,17 @@ struct sqlite3_mem_methods {
** negative value for this option restores the default behaviour.
** This option is only available if SQLite is compiled with the
** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
+**
+** [[SQLITE_CONFIG_MEMDB_MAXSIZE]]
+** <dt>SQLITE_CONFIG_MEMDB_MAXSIZE
+** <dd>The SQLITE_CONFIG_MEMDB_MAXSIZE option accepts a single parameter
+** [sqlite3_int64] parameter which is the default maximum size for an in-memory
+** database created using [sqlite3_deserialize()]. This default maximum
+** size can be adjusted up or down for individual databases using the
+** [SQLITE_FCNTL_SIZE_LIMIT] [sqlite3_file_control|file-control]. If this
+** configuration setting is never used, then the default maximum is determined
+** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that
+** compile-time option is not set, then the default maximum is 1073741824.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -2002,6 +2023,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
+#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -2991,9 +3013,9 @@ SQLITE_API int sqlite3_set_authorizer(
** time is in units of nanoseconds, however the current implementation
** is only capable of millisecond resolution so the six least significant
** digits in the time are meaningless. Future versions of SQLite
-** might provide greater resolution on the profiler callback. The
-** sqlite3_profile() function is considered experimental and is
-** subject to change in future versions of SQLite.
+** might provide greater resolution on the profiler callback. Invoking
+** either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the
+** profile callback.
*/
SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
void(*xTrace)(void*,const char*), void*);
@@ -3407,6 +3429,8 @@ SQLITE_API int sqlite3_open_v2(
** is not a database file pathname pointer that SQLite passed into the xOpen
** VFS method, then the behavior of this routine is undefined and probably
** undesirable.
+**
+** See the [URI filename] documentation for additional information.
*/
SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
@@ -3629,18 +3653,23 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** deplete the limited store of lookaside memory. Future versions of
** SQLite may act on this hint differently.
**
-** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
-** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
-** representation of the SQL statement should be calculated and then
-** associated with the prepared statement, which can be obtained via
-** the [sqlite3_normalized_sql()] interface.)^ The semantics used to
-** normalize a SQL statement are unspecified and subject to change.
-** At a minimum, literal values will be replaced with suitable
-** placeholders.
+** [[SQLITE_PREPARE_NORMALIZE]] <dt>SQLITE_PREPARE_NORMALIZE</dt>
+** <dd>The SQLITE_PREPARE_NORMALIZE flag is a no-op. This flag used
+** to be required for any prepared statement that wanted to use the
+** [sqlite3_normalized_sql()] interface. However, the
+** [sqlite3_normalized_sql()] interface is now available to all
+** prepared statements, regardless of whether or not they use this
+** flag.
+**
+** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
+** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
+** to return an error (error code SQLITE_ERROR) if the statement uses
+** any virtual tables.
** </dl>
*/
#define SQLITE_PREPARE_PERSISTENT 0x01
#define SQLITE_PREPARE_NORMALIZE 0x02
+#define SQLITE_PREPARE_NO_VTAB 0x04
/*
** CAPI3REF: Compiling An SQL Statement
@@ -9996,7 +10025,7 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
** sqlite3changeset_next() is called on the iterator or until the
** conflict-handler function returns. If pnCol is not NULL, then *pnCol is
** set to the number of columns in the table affected by the change. If
-** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
+** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
** is an indirect change, or false (0) otherwise. See the documentation for
** [sqlite3session_indirect()] for a description of direct and indirect
** changes. Finally, if pOp is not NULL, then *pOp is set to one of
@@ -11230,12 +11259,8 @@ struct Fts5PhraseIter {
**
** Usually, output parameter *piPhrase is set to the phrase number, *piCol
** to the column in which it occurs and *piOff the token offset of the
-** first token of the phrase. The exception is if the table was created
-** with the offsets=0 option specified. In this case *piOff is always
-** set to -1.
-**
-** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
-** if an error occurs.
+** first token of the phrase. Returns SQLITE_OK if successful, or an error
+** code (i.e. SQLITE_NOMEM) if an error occurs.
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
@@ -11524,11 +11549,11 @@ struct Fts5ExtensionApi {
** the tokenizer substitutes "first" for "1st" and the query works
** as expected.
**
-** <li> By adding multiple synonyms for a single term to the FTS index.
-** In this case, when tokenizing query text, the tokenizer may
-** provide multiple synonyms for a single term within the document.
-** FTS5 then queries the index for each synonym individually. For
-** example, faced with the query:
+** <li> By querying the index for all synonyms of each query term
+** separately. In this case, when tokenizing query text, the
+** tokenizer may provide multiple synonyms for a single term
+** within the document. FTS5 then queries the index for each
+** synonym individually. For example, faced with the query:
**
** <codeblock>
** ... MATCH 'first place'</codeblock>
@@ -11552,7 +11577,7 @@ struct Fts5ExtensionApi {
** "place".
**
** This way, even if the tokenizer does not provide synonyms
-** when tokenizing query text (it should not - to do would be
+** when tokenizing query text (it should not - to do so would be
** inefficient), it doesn't matter if the user queries for
** 'first + place' or '1st + place', as there are entries in the
** FTS index corresponding to both forms of the first token.
diff --git a/src/android/jar/jar.pro b/src/android/jar/jar.pro
index bda15a0a00..ac6fc79968 100644
--- a/src/android/jar/jar.pro
+++ b/src/android/jar/jar.pro
@@ -2,7 +2,6 @@ TARGET = QtAndroid
CONFIG += java
DESTDIR = $$[QT_INSTALL_PREFIX/get]/jar
-API_VERSION = android-16
PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/
diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
index 3f74383a82..e6de354ac4 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
@@ -89,8 +89,6 @@ import android.view.inputmethod.EditorInfo;
public class ExtractStyle {
- native static int[] extractChunkInfo(byte[] chunkData);
- native static int[] extractNativeChunkInfo(int nativeChunk);
native static int[] extractChunkInfo20(byte[] chunkData);
native static int[] extractNativeChunkInfo20(long nativeChunk);
@@ -345,10 +343,7 @@ public class ExtractStyle {
}
public void drawPatch(Bitmap bmp, byte[] chunks, RectF dst, Paint paint) {
- if (Build.VERSION.SDK_INT > 19)
- chunkData = extractChunkInfo20(chunks);
- else
- chunkData = extractChunkInfo(chunks);
+ chunkData = extractChunkInfo20(chunks);
}
}
@@ -698,10 +693,6 @@ public class ExtractStyle {
json.put("thicknessRatio",gradientStateClass.getField("mThicknessRatio").getFloat(obj));
json.put("innerRadius",gradientStateClass.getField("mInnerRadius").getInt(obj));
json.put("thickness",gradientStateClass.getField("mThickness").getInt(obj));
- if (Build.VERSION.SDK_INT < 20) {
- json.put("solidColor",gradientStateClass.getField("mSolidColor").getInt(obj));
- json.put("strokeColor",gradientStateClass.getField("mStrokeColor").getInt(obj));
- }
} catch (Exception e) {
e.printStackTrace();
}
@@ -802,14 +793,7 @@ public class ExtractStyle {
Object state = getAccessibleField(NinePatchDrawable.class, "mNinePatchState").get(d);
np = (NinePatch) getAccessibleField(state.getClass(), "mNinePatch").get(state);
}
- if (Build.VERSION.SDK_INT < 19)
- return getJsonChunkInfo(extractChunkInfo((byte[]) getAccessibleField(np.getClass(), "mChunk").get(np)));
- else
- {
- if (Build.VERSION.SDK_INT > 19)
- return getJsonChunkInfo(extractNativeChunkInfo20(getAccessibleField(np.getClass(), "mNativeChunk").getLong(np)));
- return getJsonChunkInfo(extractNativeChunkInfo(getAccessibleField(np.getClass(), "mNativeChunk").getInt(np)));
- }
+ return getJsonChunkInfo(extractNativeChunkInfo20(getAccessibleField(np.getClass(), "mNativeChunk").getLong(np)));
}
class DrawableCache
@@ -1016,16 +1000,12 @@ public class ExtractStyle {
json.put("gravity", bitmapDrawable.getGravity());
json.put("tileModeX", bitmapDrawable.getTileModeX());
json.put("tileModeY", bitmapDrawable.getTileModeY());
- if (Build.VERSION.SDK_INT >= 18) {
- json.put("antialias", (Boolean) BitmapDrawable.class.getMethod("hasAntiAlias").invoke(bitmapDrawable));
- json.put("mipMap", (Boolean) BitmapDrawable.class.getMethod("hasMipMap").invoke(bitmapDrawable));
- }
- if (Build.VERSION.SDK_INT >= 21) {
- json.put("tintMode", (PorterDuff.Mode) BitmapDrawable.class.getMethod("getTintMode").invoke(bitmapDrawable));
- ColorStateList tintList = (ColorStateList) BitmapDrawable.class.getMethod("getTint").invoke(bitmapDrawable);
- if (tintList != null)
- json.put("tintList", getColorStateList(tintList));
- }
+ json.put("antialias", (Boolean) BitmapDrawable.class.getMethod("hasAntiAlias").invoke(bitmapDrawable));
+ json.put("mipMap", (Boolean) BitmapDrawable.class.getMethod("hasMipMap").invoke(bitmapDrawable));
+ json.put("tintMode", (PorterDuff.Mode) BitmapDrawable.class.getMethod("getTintMode").invoke(bitmapDrawable));
+ ColorStateList tintList = (ColorStateList) BitmapDrawable.class.getMethod("getTint").invoke(bitmapDrawable);
+ if (tintList != null)
+ json.put("tintList", getColorStateList(tintList));
} catch (Exception e) {
e.printStackTrace();
}
@@ -1758,10 +1738,8 @@ public class ExtractStyle {
json.put("Switch_switchPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_switchPadding"), 0));
json.put("Switch_thumbTextPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_thumbTextPadding"), 0));
- if (Build.VERSION.SDK_INT >= 21) {
- json.put("Switch_showText", a.getBoolean(getField(styleableClass, "Switch_showText"), true));
- json.put("Switch_splitTrack", a.getBoolean(getField(styleableClass, "Switch_splitTrack"), false));
- }
+ json.put("Switch_showText", a.getBoolean(getField(styleableClass, "Switch_showText"), true));
+ json.put("Switch_splitTrack", a.getBoolean(getField(styleableClass, "Switch_splitTrack"), false));
a.recycle();
jsonWriter.name(styleName).value(json);
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index 5fef1eccad..8fa889fa31 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -82,6 +82,7 @@ import android.view.inputmethod.InputMethodManager;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.PopupMenu;
+import android.hardware.display.DisplayManager;
import java.io.BufferedReader;
import java.io.DataOutputStream;
@@ -161,15 +162,13 @@ public class QtActivityDelegate
m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
try {
- if (Build.VERSION.SDK_INT >= 19) {
- int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
- flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
- flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
- flags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
- flags |= View.SYSTEM_UI_FLAG_FULLSCREEN;
- flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY").getInt(null);
- m_activity.getWindow().getDecorView().setSystemUiVisibility(flags | View.INVISIBLE);
- }
+ int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+ flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
+ flags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ flags |= View.SYSTEM_UI_FLAG_FULLSCREEN;
+ flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY").getInt(null);
+ m_activity.getWindow().getDecorView().setSystemUiVisibility(flags | View.INVISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
@@ -669,6 +668,28 @@ public class QtActivityDelegate
} catch (Exception e) {
e.printStackTrace();
}
+
+ DisplayManager.DisplayListener displayListener = new DisplayManager.DisplayListener() {
+ @Override
+ public void onDisplayAdded(int displayId) { }
+
+ @Override
+ public void onDisplayChanged(int displayId) {
+ m_currentRotation = m_activity.getWindowManager().getDefaultDisplay().getRotation();
+ QtNative.handleOrientationChanged(m_currentRotation, m_nativeOrientation);
+ }
+
+ @Override
+ public void onDisplayRemoved(int displayId) { }
+ };
+
+ try {
+ DisplayManager displayManager = (DisplayManager) m_activity.getSystemService(Context.DISPLAY_SERVICE);
+ displayManager.registerDisplayListener(displayListener, null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
m_mainLib = QtNative.loadMainLibrary(m_mainLib, nativeLibsDir);
return m_mainLib != null;
}
@@ -865,13 +886,6 @@ public class QtActivityDelegate
} catch (Exception e) {
e.printStackTrace();
}
-
- int rotation = m_activity.getWindowManager().getDefaultDisplay().getRotation();
- if (rotation != m_currentRotation) {
- QtNative.handleOrientationChanged(rotation, m_nativeOrientation);
- }
-
- m_currentRotation = rotation;
}
public void onDestroy()
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 1d2b70ab5f..9679fd40f4 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -41,6 +41,7 @@
package org.qtproject.qt5.android;
import java.io.File;
+import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;
@@ -59,6 +60,7 @@ import android.os.Looper;
import android.content.ClipboardManager;
import android.content.ClipboardManager.OnPrimaryClipChangedListener;
import android.content.ClipData;
+import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
@@ -168,6 +170,17 @@ public class QtNative
return ok;
}
+ public static int openFdForContentUrl(Context context, String contentUrl, String openMode)
+ {
+ try {
+ ContentResolver resolver = context.getContentResolver();
+ ParcelFileDescriptor fdDesc = resolver.openFileDescriptor(Uri.parse(contentUrl), openMode);
+ return fdDesc.detachFd();
+ } catch (FileNotFoundException e) {
+ return -1;
+ }
+ }
+
// this method loads full path libs
public static void loadQtLibraries(final ArrayList<String> libraries)
{
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java
index 759daf4393..6beb5e3161 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java
@@ -132,7 +132,7 @@ public class QtActivityLoader extends QtLoader {
return;
}
- if (Build.VERSION.SDK_INT < 16) {
+ if (Build.VERSION.SDK_INT < 21) {
// fatal error, show the error and quit
AlertDialog errorDialog = new AlertDialog.Builder(m_activity).create();
if (m_contextInfo.metaData.containsKey("android.app.unsupported_android_version"))
diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml
index b5b26758d9..aed8a3c888 100644
--- a/src/android/templates/AndroidManifest.xml
+++ b/src/android/templates/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="-- %%INSERT_VERSION_NAME%% --" android:versionCode="-- %%INSERT_VERSION_CODE%% --" android:installLocation="auto">
- <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="28"/>
+ <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
Remove the comment if you do not require these default permissions. -->
diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake
index 7ae5e4fd16..78b99f5bfe 100644
--- a/src/corelib/Qt5CoreMacros.cmake
+++ b/src/corelib/Qt5CoreMacros.cmake
@@ -370,7 +370,7 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.9)
if (NOT Qt5${_module}_FOUND)
find_package(Qt5${_module} PATHS "${_Qt5_COMPONENT_PATH}" NO_DEFAULT_PATH)
if (NOT Qt5${_module}_FOUND)
- message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.")
+ message(FATAL_ERROR "Cannot use \"${_module}\" module which has not yet been found.")
endif()
endif()
target_link_libraries(${_target} ${_qt5_link_type} ${Qt5${_module}_LIBRARIES})
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 78b79e574a..b507049cc4 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -773,6 +773,7 @@ QAnimationDriver::~QAnimationDriver()
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Sets the time at which an animation driver should start at.
@@ -799,6 +800,7 @@ qint64 QAnimationDriver::startTime() const
{
return 0;
}
+#endif
/*!
diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h
index 25b5726d56..7f2577d7f7 100644
--- a/src/corelib/animation/qabstractanimation.h
+++ b/src/corelib/animation/qabstractanimation.h
@@ -147,9 +147,10 @@ public:
virtual qint64 elapsed() const;
- // ### Qt6: Remove these two functions
- void setStartTime(qint64 startTime);
- qint64 startTime() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED void setStartTime(qint64 startTime);
+ QT_DEPRECATED qint64 startTime() const;
+#endif
Q_SIGNALS:
void started();
diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp
index 28c03553c5..271be248ec 100644
--- a/src/corelib/animation/qpropertyanimation.cpp
+++ b/src/corelib/animation/qpropertyanimation.cpp
@@ -303,6 +303,6 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State newState,
}
}
-#include "moc_qpropertyanimation.cpp"
-
QT_END_NAMESPACE
+
+#include "moc_qpropertyanimation.cpp"
diff --git a/src/corelib/codecs/qbig5codec_p.h b/src/corelib/codecs/qbig5codec_p.h
index 2db8377ee3..c17afae1c4 100644
--- a/src/corelib/codecs/qbig5codec_p.h
+++ b/src/corelib/codecs/qbig5codec_p.h
@@ -69,12 +69,12 @@ public:
static QList<QByteArray> _aliases();
static int _mibEnum();
- QByteArray name() const { return _name(); }
- QList<QByteArray> aliases() const { return _aliases(); }
- int mibEnum() const { return _mibEnum(); }
+ QByteArray name() const override { return _name(); }
+ QList<QByteArray> aliases() const override { return _aliases(); }
+ int mibEnum() const override { return _mibEnum(); }
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
};
class QBig5hkscsCodec : public QTextCodec {
@@ -83,12 +83,12 @@ public:
static QList<QByteArray> _aliases() { return QList<QByteArray>(); }
static int _mibEnum();
- QByteArray name() const { return _name(); }
- QList<QByteArray> aliases() const { return _aliases(); }
- int mibEnum() const { return _mibEnum(); }
+ QByteArray name() const override { return _name(); }
+ QList<QByteArray> aliases() const override { return _aliases(); }
+ int mibEnum() const override { return _mibEnum(); }
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
};
QT_END_NAMESPACE
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index eb05446beb..ffd8a2ce93 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -505,9 +505,9 @@ QTextCodec::~QTextCodec()
globalData->allCodecs.removeOne(this);
- auto it = globalData->codecCache.cbegin();
+ auto it = globalData->codecCache.begin();
- while (it != globalData->codecCache.cend()) {
+ while (it != globalData->codecCache.end()) {
if (it.value() == this)
it = globalData->codecCache.erase(it);
else
@@ -695,11 +695,9 @@ void QTextCodec::setCodecForLocale(QTextCodec *c)
\threadsafe
Returns a pointer to the codec most suitable for this locale.
- On Windows, the codec will be based on a system locale. On Unix
- systems, the codec will might fall back to using the \e iconv
- library if no builtin codec for the locale can be found.
-
- Note that in these cases the codec's name will be "System".
+ The codec will be retrieved from ICU where that backend is in use, otherwise
+ it may be obtained from an OS-specific API. In the latter case, the codec's
+ name may be "System".
*/
QTextCodec* QTextCodec::codecForLocale()
@@ -766,7 +764,7 @@ QList<QByteArray> QTextCodec::aliases() const
encoding of the subclass to Unicode, and returns the result in a
QString.
- \a state can be 0, in which case the conversion is stateless and
+ \a state can be \nullptr, in which case the conversion is stateless and
default conversion rules should be used. If state is not 0, the
codec should save the state after the conversion in \a state, and
adjust the \c remainingChars and \c invalidChars members of the struct.
@@ -782,7 +780,7 @@ QList<QByteArray> QTextCodec::aliases() const
from Unicode to the encoding of the subclass, and returns the result
in a QByteArray.
- \a state can be 0 in which case the conversion is stateless and
+ \a state can be \nullptr in which case the conversion is stateless and
default conversion rules should be used. If state is not 0, the
codec should save the state after the conversion in \a state, and
adjust the \c remainingChars and \c invalidChars members of the struct.
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index 5f5a00a64f..b7eefb58c8 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -11,6 +11,7 @@
"icu": "boolean",
"inotify": "boolean",
"journald": "boolean",
+ "mimetype-database": "boolean",
"pcre": { "type": "enum", "values": [ "qt", "system" ] },
"posix-ipc": { "type": "boolean", "name": "ipc_posix" },
"pps": { "type": "boolean", "name": "qqnx_pps" },
@@ -678,6 +679,11 @@
"condition": "features.textcodec",
"output": [ "publicFeature", "feature" ]
},
+ "mimetype-database": {
+ "label": "Built-in copy of the MIME database",
+ "condition": "features.mimetype",
+ "output": [ "privateFeature" ]
+ },
"system-pcre2": {
"label": "Using system PCRE2",
"disable": "input.pcre == 'qt'",
@@ -892,6 +898,20 @@
"condition": "features.proxymodel",
"output": [ "publicFeature", "feature" ]
},
+ "transposeproxymodel": {
+ "label": "QTransposeProxyModel",
+ "purpose": "Provides a proxy to swap rows and columns of a model.",
+ "section": "ItemViews",
+ "condition": "features.proxymodel",
+ "output": [ "publicFeature", "feature" ]
+ },
+ "concatenatetablesproxymodel": {
+ "label": "QConcatenateTablesProxyModel",
+ "purpose": "Supports concatenating source models.",
+ "section": "ItemViews",
+ "condition": "features.proxymodel",
+ "output": [ "publicFeature", "feature" ]
+ },
"stringlistmodel": {
"label": "QStringListModel",
"purpose": "Provides a model that supplies strings to views.",
@@ -1034,6 +1054,7 @@ Please apply the patch corresponding to your Standard Library vendor, found in
"glib",
"iconv",
"icu",
+ "mimetype-database",
{
"message": "Tracing backend",
"type": "firstAvailableFeature",
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 181780c475..4b758532e6 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -44,6 +44,7 @@ include(codecs/codecs.pri)
include(serialization/serialization.pri)
include(statemachine/statemachine.pri)
include(mimetypes/mimetypes.pri)
+include(platform/platform.pri)
win32 {
LIBS_PRIVATE += -lws2_32
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
index 03904659f5..eb75a29ca2 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
@@ -773,16 +773,16 @@ bool readConfiguration(const QFile &file)
//! [qdecloverride]
// generate error if this doesn't actually override anything:
- virtual void MyWidget::paintEvent(QPaintEvent*) Q_DECL_OVERRIDE;
+ virtual void MyWidget::paintEvent(QPaintEvent*) override;
//! [qdecloverride]
//! [qdeclfinal-1]
// more-derived classes no longer permitted to override this:
- virtual void MyWidget::paintEvent(QPaintEvent*) Q_DECL_FINAL;
+ virtual void MyWidget::paintEvent(QPaintEvent*) final;
//! [qdeclfinal-1]
//! [qdeclfinal-2]
- class QRect Q_DECL_FINAL { // cannot be derived from
+ class QRect final { // cannot be derived from
// ...
};
//! [qdeclfinal-2]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
index cc3f689710..0e746cd6e6 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
@@ -146,7 +146,7 @@ list.move(1, 4);
//! [12]
QList<QString> list;
list << "A" << "B" << "C" << "D" << "E" << "F";
-list.swap(1, 4);
+list.swapItemsAt(1, 4);
// list: ["A", "E", "C", "D", "B", "F"]
//! [12]
diff --git a/src/corelib/doc/snippets/resource-system/mainwindow.cpp b/src/corelib/doc/snippets/resource-system/mainwindow.cpp
index bbeeec64ac..86e93aaa62 100644
--- a/src/corelib/doc/snippets/resource-system/mainwindow.cpp
+++ b/src/corelib/doc/snippets/resource-system/mainwindow.cpp
@@ -338,11 +338,11 @@ void MainWindow::loadFile(const QString &fileName)
QTextStream in(&file);
#ifndef QT_NO_CURSOR
- QApplication::setOverrideCursor(Qt::WaitCursor);
+ QGuiApplication::setOverrideCursor(Qt::WaitCursor);
#endif
textEdit->setPlainText(in.readAll());
#ifndef QT_NO_CURSOR
- QApplication::restoreOverrideCursor();
+ QGuiApplication::restoreOverrideCursor();
#endif
setCurrentFile(fileName);
@@ -365,11 +365,11 @@ bool MainWindow::saveFile(const QString &fileName)
QTextStream out(&file);
#ifndef QT_NO_CURSOR
- QApplication::setOverrideCursor(Qt::WaitCursor);
+ QGuiApplication::setOverrideCursor(Qt::WaitCursor);
#endif
out << textEdit->toPlainText();
#ifndef QT_NO_CURSOR
- QApplication::restoreOverrideCursor();
+ QGuiApplication::restoreOverrideCursor();
#endif
setCurrentFile(fileName);
diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc
index a1c32bb007..e6c95129db 100644
--- a/src/corelib/doc/src/containers.qdoc
+++ b/src/corelib/doc/src/containers.qdoc
@@ -171,8 +171,9 @@
The values stored in the various containers can be of any
\e{assignable data type}. To qualify, a type must provide a
- default constructor, a copy constructor, and an assignment
- operator. This covers most data types you are likely to want to
+ copy constructor, and an assignment operator. For some
+ operations a default constructor is also required. This
+ covers most data types you are likely to want to
store in a container, including basic types such as \c int and \c
double, pointer types, and Qt data types such as QString, QDate,
and QTime, but it doesn't cover QObject or any QObject subclass
diff --git a/src/corelib/doc/src/datastreamformat.qdoc b/src/corelib/doc/src/datastreamformat.qdoc
index 73ca51974d..d6b60f10ce 100644
--- a/src/corelib/doc/src/datastreamformat.qdoc
+++ b/src/corelib/doc/src/datastreamformat.qdoc
@@ -28,357 +28,71 @@
/*!
\page datastreamformat.html
\title Serializing Qt Data Types
- \brief Representations of data types that can be serialized by QDataStream.
+ \brief List of data types that can be serialized by QDataStream.
- The \l QDataStream allows you to serialize some of the Qt data types.
- The table below lists the data types that QDataStream can serialize
- and how they are represented. The format described below is
- \l{QDataStream::setVersion()}{version 13}.
+ The \l QDataStream class allows you to serialize the Qt data types
+ listed in this section as of \l{QDataStream::setVersion()}{version 18}.
It is always best to cast integers to a Qt integer type, such as
- qint16 or quint32, when reading and writing. This ensures that
+ \l{qint16} or \l{quint32}, when reading and writing. This ensures that
you always know exactly what size integers you are reading and
writing, no matter what the underlying platform and architecture
the application happens to be running on.
- \table
- \row \li bool
- \li \list
- \li boolean
- \endlist
- \row \li qint8
- \li \list
- \li signed byte
- \endlist
- \row \li qint16
- \li \list
- \li signed 16-bit integer
- \endlist
- \row \li qint32
- \li \list
- \li signed 32-bit integer
- \endlist
- \row \li qint64
- \li \list
- \li signed 64-bit integer
- \endlist
- \row \li quint8
- \li \list
- \li unsigned byte
- \endlist
- \row \li quint16
- \li \list
- \li unsigned 16-bit integer
- \endlist
- \row \li quint32
- \li \list
- \li unsigned 32-bit integer
- \endlist
- \row \li quint64
- \li \list
- \li unsigned 64-bit integer
- \endlist
- \row \li \c float
- \li \list
- \li 32-bit floating point number using the standard IEEE 754 format
- \endlist
- \row \li \c double
- \li \list
- \li 64-bit floating point number using the standard IEEE 754 format
- \endlist
- \row \li \c {const char *}
- \li \list
- \li The string length (quint32)
- \li The string bytes, excluding the terminating 0
- \endlist
- \row \li QBitArray
- \li \list
- \li The array size (quint32)
- \li The array bits, i.e. (size + 7)/8 bytes
- \endlist
- \row \li QBrush
- \li \list
- \li The brush style (quint8)
- \li The brush color (QColor)
- \li If style is CustomPattern, the brush pixmap (QPixmap)
- \endlist
- \row \li QByteArray
- \li \list
- \li If the byte array is null: 0xFFFFFFFF (quint32)
- \li Otherwise: the array size (quint32) followed by the array bytes, i.e. size bytes
- \endlist
- \row \li \l QColor
- \li \list
- \li Color spec (qint8)
- \li Alpha value (quint16)
- \li Red value (quint16)
- \li Green value (quint16)
- \li Blue value (quint16)
- \li Pad value (quint16)
- \endlist
- \row \li QCursor
- \li \list
- \li Shape ID (qint16)
- \li If shape is BitmapCursor: The bitmap (QPixmap), mask (QPixmap), and hot spot (QPoint)
- \endlist
- \row \li QDate
- \li \list
- \li Julian day (quint32)
- \endlist
- \row \li QDateTime
- \li \list
- \li Date (QDate)
- \li Time (QTime)
- \li The \l{Qt::TimeSpec}{time spec}
- offsetFromUtc (qint32) if Qt::TimeSpec is offsetFromUtc
- TimeZone(QTimeZone) if Qt::TimeSpec is TimeZone
- \endlist
- \row \li QEasingCurve
- \li \list
- \li type (quint8)
- \li func (quint64)
- \li hasConfig (bool)
- \li If hasConfig is true then these fields follow:
- \li list
- \li period (double)
- \li amplitude (double)
- \li overshoot (double)
- \endlist
- \row \li QFont
- \li \list
- \li The family (QString)
- \li The style name (QString)
- \li The point size (double)
- \li The pixel size (qint32)
- \li The style hint (quint8)
- \li The style strategy (quint16)
- \li The char set (quint8)
- \li The weight (quint8)
- \li The font bits (quint8)
- \li The font stretch (quint16)
- \li The extended font bits (quint8)
- \li The letter spacing (double)
- \li The word spacing (double)
- \li The hinting preference (quint8)
- \endlist
- \row \li QHash<Key, T>
- \li \list
- \li The number of items (quint32)
- \li For all items, the key (Key) and value (T)
- \endlist
- \row \li QIcon
- \li \list
- \li The number of pixmap entries (quint32)
- \li For all pixmap entries:
- \list
- \li The pixmap (QPixmap)
- \li The file name (QString)
- \li The pixmap size (QSize)
- \li The \l{QIcon::Mode}{mode} (quint32)
- \li The \l{QIcon::State}{state} (quint32)
- \endlist
- \endlist
- \row \li QImage
- \li \list
- \li If the image is null a "null image" marker is saved;
- otherwise the image is saved in PNG or BMP format (depending
- on the stream version). If you want control of the format,
- stream the image into a QBuffer (using QImageIOHandler/QImageIOPlugin) and stream
- that.
- \endlist
- \row \li QKeySequence
- \li \list
- \li A QList<int>, where each integer is a key in the key sequence
- \endlist
- \row \li QLinkedList<T>
- \li \list
- \li The number of items (quint32)
- \li The items (T)
- \endlist
- \row \li QList<T>
- \li \list
- \li The number of items (quint32)
- \li The items (T)
- \endlist
- \row \li QMap<Key, T>
- \li \list
- \li The number of items (quint32)
- \li For all items, the key (Key) and value (T)
- \endlist
- \row \li QMargins
- \li \list
- \li left (int)
- \li top (int)
- \li right (int)
- \li bottom (int)
- \endlist
- \row \li QMatrix
- \li \list
- \li m11 (double)
- \li m12 (double)
- \li m21 (double)
- \li m22 (double)
- \li dx (double)
- \li dy (double)
- \endlist
- \row \li QMatrix4x4
- \li \list
- \li m11 (float)
- \li m12 (float)
- \li m13 (float)
- \li m14 (float)
- \li m21 (float)
- \li m22 (float)
- \li m23 (float)
- \li m24 (float)
- \li m31 (float)
- \li m32 (float)
- \li m33 (float)
- \li m34 (float)
- \li m41 (float)
- \li m42 (float)
- \li m43 (float)
- \li m44 (float)
- \endlist
- \row \li QPair<T1, T2>
- \li \list
- \li first (T1)
- \li second (T2)
- \endlist
- \row \li QPalette
- \li The disabled, active, and inactive color groups, each of which consists
- of the following:
- \list
- \li foreground (QBrush)
- \li button (QBrush)
- \li light (QBrush)
- \li midlight (QBrush)
- \li dark (QBrush)
- \li mid (QBrush)
- \li text (QBrush)
- \li brightText (QBrush)
- \li buttonText (QBrush)
- \li base (QBrush)
- \li background (QBrush)
- \li shadow (QBrush)
- \li highlight (QBrush)
- \li highlightedText (QBrush)
- \li link (QBrush)
- \li linkVisited (QBrush)
- \endlist
- \row \li QPen
- \li \list
- \li The pen styles (quint8)
- \li The pen width (quint16)
- \li The pen color (QColor)
- \endlist
- \row \li QPicture
- \li \list
- \li The size of the picture data (quint32)
- \li The raw bytes of picture data (char)
- \endlist
- \row \li QPixmap
- \li \list
- \li Save it as a PNG image.
- \endlist
- \row \li QPoint
- \li \list
- \li The x coordinate (qint32)
- \li The y coordinate (qint32)
- \endlist
- \row \li QQuaternion
- \li \list
- \li The scalar component (float)
- \li The x coordinate (float)
- \li The y coordinate (float)
- \li The z coordinate (float)
- \endlist
- \row \li QRect
- \li \list
- \li left (qint32)
- \li top (qint32)
- \li right (qint32)
- \li bottom (qint32)
- \endlist
- \row \li QRegExp
- \li \list
- \li The regexp pattern (QString)
- \li Case sensitivity (quint8)
- \li Regular expression syntax (quint8)
- \li Minimal matching (quint8)
- \endlist
- \row \li QRegularExpression
- \li \list
- \li The regular expression pattern (QString)
- \li The pattern options (quint32)
- \endlist
- \row \li QRegion
- \li \list
- \li The size of the data, i.e. 8 + 16 * (number of rectangles) (quint32)
- \li 10 (qint32)
- \li The number of rectangles (quint32)
- \li The rectangles in sequential order (QRect)
- \endlist
- \row \li QSize
- \li \list
- \li width (qint32)
- \li height (qint32)
- \endlist
- \row \li QString
- \li \list
- \li If the string is null: 0xFFFFFFFF (quint32)
- \li Otherwise: The string length in bytes (quint32) followed by the data in UTF-16
- \endlist
- \row \li QTime
- \li \list
- \li Milliseconds since midnight (quint32)
- \endlist
- \row \li QTransform
- \li \list
- \li m11 (double)
- \li m12 (double)
- \li m13 (double)
- \li m21 (double)
- \li m22 (double)
- \li m23 (double)
- \li m31 (double)
- \li m32 (double)
- \li m33 (double)
- \endlist
- \row \li QUrl
- \li \list
- \li Holds an URL (QString)
- \endlist
- \row \li QVariant
- \li \list
- \li The type of the data (quint32)
- \li The null flag (qint8)
- \li The data of the specified type
- \endlist
- \row \li QVector2D
- \li \list
- \li the x coordinate (float)
- \li the y coordinate (float)
- \endlist
- \row \li QVector3D
- \li \list
- \li the x coordinate (float)
- \li the y coordinate (float)
- \li the z coordinate (float)
- \endlist
- \row \li QVector4D
- \li \list
- \li the x coordinate (float)
- \li the y coordinate (float)
- \li the z coordinate (float)
- \li the w coordinate (float)
- \endlist
- \row \li QVector<T>
- \li \list
- \li The number of items (quint32)
- \li The items (T)
- \endlist
- \endtable
+ \list
+ \li bool
+ \li \l{qint8}
+ \li \l{qint16}
+ \li \l{qint32}
+ \li \l{qint64}
+ \li \l{quint8}
+ \li \l{quint16}
+ \li \l{quint32}
+ \li \l{quint64}
+ \li \c float
+ \li \c double
+ \li \c {const char *}
+ \li QBitArray
+ \li QBrush
+ \li QByteArray
+ \li QColor
+ \li QCursor
+ \li QDate
+ \li QDateTime
+ \li QEasingCurve
+ \li QFont
+ \li QGenericMatrix
+ \li QHash<Key, T>
+ \li QIcon
+ \li QImage
+ \li QKeySequence
+ \li QLinkedList<T>
+ \li QList<T>
+ \li QMap<Key, T>
+ \li QMargins
+ \li QMatrix4x4
+ \li QPair<T1, T2>
+ \li QPalette
+ \li QPen
+ \li QPicture
+ \li QPixmap
+ \li QPoint
+ \li QQuaternion
+ \li QRect
+ \li QRegExp
+ \li QRegularExpression
+ \li QRegion
+ \li QSize
+ \li QString
+ \li QTime
+ \li QTransform
+ \li QUrl
+ \li QVariant
+ \li QVector2D
+ \li QVector3D
+ \li QVector4D
+ \li QVector<T>
+ \endlist
\sa {JSON Support in Qt}
*/
diff --git a/src/corelib/doc/src/objectmodel/metaobjects.qdoc b/src/corelib/doc/src/objectmodel/metaobjects.qdoc
index 5b3d8f9863..53b34fe120 100644
--- a/src/corelib/doc/src/objectmodel/metaobjects.qdoc
+++ b/src/corelib/doc/src/objectmodel/metaobjects.qdoc
@@ -86,7 +86,7 @@
that it doesn't require RTTI support and it works across dynamic
library boundaries. It attempts to cast its argument to the pointer
type specified in angle-brackets, returning a non-zero pointer if the
- object is of the correct type (determined at run-time), or 0
+ object is of the correct type (determined at run-time), or \nullptr
if the object's type is incompatible.
For example, let's assume \c MyWidget inherits from QWidget and
diff --git a/src/corelib/doc/src/resource-system.qdoc b/src/corelib/doc/src/resource-system.qdoc
index 9b6b613f79..69ec5e556b 100644
--- a/src/corelib/doc/src/resource-system.qdoc
+++ b/src/corelib/doc/src/resource-system.qdoc
@@ -100,6 +100,9 @@
See the QLocale documentation for a description of the format to use
for locale strings.
+ See QFileSelector for an additional mechanism to select locale-specific
+ resources, in addition to the ability to select OS-specific and other
+ features.
\section2 External Binary Resources
@@ -143,24 +146,70 @@
\section1 Compression
- Resources are compressed by default (in the \c ZIP format). It is
- possible to turn off compression. This can be useful if your
- resources already contain a compressed format, such as \c .png
- files. You do this by giving the \c {-no-compress} command line
- argument.
+ \c rcc attempts to compress the content to optimize disk space usage in the
+ final binaries. By default, it will perform a heuristic check to determine
+ whether compressing is worth it and will store the content uncompressed if
+ it fails to sufficiently compress. To control the threshold, you can use
+ the \c {-threshold} option, which tells \c rcc the percentage of the
+ original file size that must be gained for it to store the file in
+ compressed form.
+
+ \code
+ rcc -threshold 25 myresources.qrc
+ \endcode
+
+ The default value is "70", indicating that the compressed file must be 70%
+ smaller than the original (no more than 30% of the original file size).
+
+ It is possible to turn off compression, if desired. This can be useful if
+ your resources already contain a compressed format, such as \c .png files,
+ and you do not want to incur the CPU cost at build time to confirm that it
+ can't be compressed. Another reason is if disk usage is not a problem and
+ the application would prefer to keep the content as clean memory pages at
+ runtime. You do this by giving the \c {-no-compress} command line argument.
\code
rcc -no-compress myresources.qrc
\endcode
- \c rcc also gives you some control over the compression. You can
- specify the compression level and the threshold level to consider
- while compressing files, for example:
+ \c rcc also gives you some control over the compression level and
+ compression algorithm, for example:
\code
- rcc -compress 2 -threshold 3 myresources.qrc
+ rcc -compress 2 -compress-algo zlib myresources.qrc
\endcode
+ \c rcc supports the following compression algorithms and compression
+ levels:
+
+ \list
+ \li \c{best}: use the best algorithm among the ones below, at its highest
+ compression level, to achieve the most compression at the expense of
+ using a lot of CPU time during compilation. This value is useful in the
+ XML file to indicate a file should be most compressed, regardless of
+ which algorithms \c rcc supports.
+
+ \li \c{zstd}: use the \l{Zstandard}{https://zstd.net} library to compress
+ contents. Valid compression levels range from 1 to 19, 1 is least
+ compression (least CPU time) and 19 is the most compression (most CPU
+ time). The default level is 14. A special value of 0 tells the \c{zstd}
+ library to choose an implementation-defined default.
+
+ \li \c{zlib}: use the \l{zlib}{https://zlib.net} library to compress
+ contents. Valid compression levels range from 1 to 9, with 1the least
+ compression (least CPU time) and 9 the most compression (most CPU time).
+ The special value 0 means "no compression" and should not be used. The
+ default is implementation-defined, but usually is level 6.
+
+ \li \c{none}: no compression. This is the same as the \c{-no-compress}
+ option.
+ \endlist
+
+ Support for both Zstandard and zlib are optional. If a given library was
+ not detected at compile time, attempting to pass \c {-compress-algo} for
+ that library will result in an error. The default compression algorithm is
+ \c zstd if it is enabled, \c zlib if not.
+
\section1 Using Resources in the Application
In the application, resource paths can be used in most places
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index dfcc3c9c7f..10458e41d7 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -122,6 +122,11 @@
#define QT_NO_TRANSLATION
#define QT_FEATURE_translation -1
+// rcc.pro will DEFINES+= this
+#ifndef QT_FEATURE_zstd
+#define QT_FEATURE_zstd -1
+#endif
+
#ifdef QT_BUILD_QMAKE
#define QT_FEATURE_commandlineparser -1
#define QT_NO_COMPRESS
diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h
index 3e50ad8467..42cb1357f1 100644
--- a/src/corelib/global/qfloat16.h
+++ b/src/corelib/global/qfloat16.h
@@ -67,11 +67,9 @@ QT_BEGIN_NAMESPACE
class qfloat16
{
public:
-#ifndef Q_QDOC
Q_DECL_CONSTEXPR inline qfloat16() Q_DECL_NOTHROW : b16(0) { }
inline qfloat16(float f) Q_DECL_NOTHROW;
inline operator float() const Q_DECL_NOTHROW;
-#endif
private:
quint16 b16;
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 8d80a32ad5..7879109930 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -525,6 +525,31 @@ Q_STATIC_ASSERT((std::is_same<qsizetype, qptrdiff>::value));
made private. In that case, no error would be reported, but your
application would probably crash when you called a member function
of \c{w}.
+
+ \sa Q_DISABLE_COPY_MOVE, Q_DISABLE_MOVE
+*/
+
+/*!
+ \macro Q_DISABLE_MOVE(Class)
+ \relates QObject
+
+ Disables the use of move constructors and move assignment operators
+ for the given \a Class.
+
+ \sa Q_DISABLE_COPY, Q_DISABLE_COPY_MOVE
+ \since 5.13
+*/
+
+/*!
+ \macro Q_DISABLE_COPY_MOVE(Class)
+ \relates QObject
+
+ A convenience macro that disables the use of copy constructors, assignment
+ operators, move constructors and move assignment operators for the given
+ \a Class, combining Q_DISABLE_COPY and Q_DISABLE_MOVE.
+
+ \sa Q_DISABLE_COPY, Q_DISABLE_MOVE
+ \since 5.13
*/
/*!
@@ -1954,11 +1979,11 @@ bool qSharedBuild() Q_DECL_NOTHROW
a specified version of Qt or any earlier version. The default version number is 5.0,
meaning that functions deprecated in or before Qt 5.0 will not be included.
- Examples:
- When using a future release of Qt 5, set QT_DISABLE_DEPRECATED_BEFORE=0x050100 to
- disable functions deprecated in Qt 5.1 and earlier. In any release, set
- QT_DISABLE_DEPRECATED_BEFORE=0x000000 to enable any functions, including the ones
- deprecated in Qt 5.0
+ For instance, when using a future release of Qt 5, set
+ \c{QT_DISABLE_DEPRECATED_BEFORE=0x050100} to disable functions deprecated in
+ Qt 5.1 and earlier. In any release, set
+ \c{QT_DISABLE_DEPRECATED_BEFORE=0x000000} to enable all functions, including
+ the ones deprecated in Qt 5.0.
\sa QT_DEPRECATED_WARNINGS
*/
@@ -1968,12 +1993,24 @@ bool qSharedBuild() Q_DECL_NOTHROW
\macro QT_DEPRECATED_WARNINGS
\relates <QtGlobal>
- If this macro is defined, the compiler will generate warnings if API declared as
+ Since Qt 5.13, this macro has no effect. In Qt 5.12 and before, if this macro
+ is defined, the compiler will generate warnings if any API declared as
deprecated by Qt is used.
- \sa QT_DISABLE_DEPRECATED_BEFORE
+ \sa QT_DISABLE_DEPRECATED_BEFORE, QT_NO_DEPRECATED_WARNINGS
*/
+/*!
+ \macro QT_NO_DEPRECATED_WARNINGS
+ \relates <QtGlobal>
+ \since 5.13
+
+ This macro can be used to suppress deprecation warnings that would otherwise
+ be generated when using deprecated APIs.
+
+ \sa QT_DISABLE_DEPRECATED_BEFORE
+*/
+
#if defined(QT_BUILD_QMAKE)
// needed to bootstrap qmake
static const unsigned int qt_one = 1;
@@ -2144,11 +2181,20 @@ struct QUnixOSVersion
static QString unquote(const char *begin, const char *end)
{
+ // man os-release says:
+ // Variable assignment values must be enclosed in double
+ // or single quotes if they include spaces, semicolons or
+ // other special characters outside of A–Z, a–z, 0–9. Shell
+ // special characters ("$", quotes, backslash, backtick)
+ // must be escaped with backslashes, following shell style.
+ // All strings should be in UTF-8 format, and non-printable
+ // characters should not be used. It is not supported to
+ // concatenate multiple individually quoted strings.
if (*begin == '"') {
Q_ASSERT(end[-1] == '"');
- return QString::fromLatin1(begin + 1, end - begin - 2);
+ return QString::fromUtf8(begin + 1, end - begin - 2);
}
- return QString::fromLatin1(begin, end - begin);
+ return QString::fromUtf8(begin, end - begin);
}
static QByteArray getEtcFileContent(const char *filename)
{
@@ -3245,6 +3291,34 @@ void *qMemSet(void *dest, int c, size_t n) { return memset(dest, c, n); }
// add thread-safety for the Qt wrappers.
static QBasicMutex environmentMutex;
+/*
+ Wraps tzset(), which accesses the environment, so should only be called while
+ we hold the lock on the environment mutex.
+*/
+void qTzSet()
+{
+ QMutexLocker locker(&environmentMutex);
+#if defined(Q_OS_WIN)
+ _tzset();
+#else
+ tzset();
+#endif // Q_OS_WIN
+}
+
+/*
+ Wrap mktime(), which is specified to behave as if it called tzset(), hence
+ shares its implicit environment-dependence.
+*/
+time_t qMkTime(struct tm *when)
+{
+ QMutexLocker locker(&environmentMutex);
+ return mktime(when);
+}
+
+// Also specified to behave as if they call tzset():
+// localtime() -- but not localtime_r(), which we use when threaded
+// strftime() -- not used (except in tests)
+
/*!
\relates <QtGlobal>
\threadsafe
@@ -4043,6 +4117,13 @@ bool qunsetenv(const char *varName)
Example of a movable type:
\snippet code/src_corelib_global_qglobal.cpp 39
+
+ Qt will try to detect the class of a type using std::is_trivial or
+ std::is_trivially_copyable. Use this macro to tune the behavior.
+ For instance many types would be candidates for Q_MOVABLE_TYPE despite
+ not being trivially-copyable. For binary compatibility reasons, QList
+ optimizations are only enabled if there is an explicit
+ Q_DECLARE_TYPEINFO even for trivially-copyable types.
*/
/*!
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index ccab228804..223ebbcabe 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -287,7 +287,7 @@ typedef double qreal;
# undef QT_DEPRECATED_X
# undef QT_DEPRECATED_VARIABLE
# undef QT_DEPRECATED_CONSTRUCTOR
-#elif defined(QT_DEPRECATED_WARNINGS)
+#elif !defined(QT_NO_DEPRECATED_WARNINGS)
# undef QT_DEPRECATED
# define QT_DEPRECATED Q_DECL_DEPRECATED
# undef QT_DEPRECATED_X
@@ -372,6 +372,14 @@ typedef double qreal;
Class(const Class &) Q_DECL_EQ_DELETE;\
Class &operator=(const Class &) Q_DECL_EQ_DELETE;
+#define Q_DISABLE_MOVE(Class) \
+ Class(Class &&) = delete; \
+ Class &operator=(Class &&) = delete;
+
+#define Q_DISABLE_COPY_MOVE(Class) \
+ Q_DISABLE_COPY(Class) \
+ Q_DISABLE_MOVE(Class)
+
/*
No, this is not an evil backdoor. QT_BUILD_INTERNAL just exports more symbols
for Qt's internal unit tests. If you want slower loading times and more
@@ -591,11 +599,11 @@ Q_DECL_CONSTEXPR inline qint64 qRound64(float d)
{ return d >= 0.0f ? qint64(d + 0.5f) : qint64(d - float(qint64(d-1)) + 0.5f) + qint64(d-1); }
template <typename T>
-Q_DECL_CONSTEXPR inline const T &qMin(const T &a, const T &b) { return (a < b) ? a : b; }
+constexpr inline const T &qMin(const T &a, const T &b) { return (a < b) ? a : b; }
template <typename T>
-Q_DECL_CONSTEXPR inline const T &qMax(const T &a, const T &b) { return (a < b) ? b : a; }
+constexpr inline const T &qMax(const T &a, const T &b) { return (a < b) ? b : a; }
template <typename T>
-Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max)
+constexpr inline const T &qBound(const T &min, const T &val, const T &max)
{ return qMax(min, qMin(max, val)); }
#ifndef Q_FORWARD_DECLARE_OBJC_CLASS
@@ -1005,6 +1013,15 @@ QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t)
}
}
+
+#if __cplusplus >= 201703L
+// Use C++17 if statement with initializer. User's code ends up in a else so
+// scoping of different ifs is not broken
+#define Q_FOREACH(variable, container) \
+for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \
+ _container_.i != _container_.e; ++_container_.i) \
+ if (variable = *_container_.i; false) {} else
+#else
// Explanation of the control word:
// - it's initialized to 1
// - that means both the inner and outer loops start
@@ -1019,7 +1036,7 @@ for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \
_container_.control && _container_.i != _container_.e; \
++_container_.i, _container_.control ^= 1) \
for (variable = *_container_.i; _container_.control; _container_.control = 0)
-
+#endif
#endif // QT_NO_FOREACH
#define Q_FOREVER for(;;)
@@ -1192,9 +1209,6 @@ namespace QtPrivate {
//like std::enable_if
template <bool B, typename T = void> struct QEnableIf;
template <typename T> struct QEnableIf<true, T> { typedef T Type; };
-
-template <bool B, typename T, typename F> struct QConditional { typedef T Type; };
-template <typename T, typename F> struct QConditional<false, T, F> { typedef F Type; };
}
QT_END_NAMESPACE
diff --git a/src/corelib/global/qglobal_p.h b/src/corelib/global/qglobal_p.h
index 0f092e9006..d52f6268e4 100644
--- a/src/corelib/global/qglobal_p.h
+++ b/src/corelib/global/qglobal_p.h
@@ -61,6 +61,16 @@
#endif
#if defined(__cplusplus)
+#include <time.h>
+
+QT_BEGIN_NAMESPACE
+
+// These behave as if they consult the environment, so need to share its locking:
+Q_CORE_EXPORT void qTzSet();
+Q_CORE_EXPORT time_t qMkTime(struct tm *when);
+
+QT_END_NAMESPACE
+
#if !QT_HAS_BUILTIN(__builtin_available)
#include <initializer_list>
#include <QtCore/qoperatingsystemversion.h>
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 168934c202..b2093101fa 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -239,7 +239,7 @@ static bool systemHasStderr()
\note Qt Creator does not implement a pseudo TTY, nor does it launch apps with
the override environment variable set, but it will read stderr and print it to
- the user, so in effect this function can not be used to conclude that stderr
+ the user, so in effect this function cannot be used to conclude that stderr
output will _not_ be visible to the user, as even if this function returns false,
the output might still end up visible to the user. For this reason, we don't guard
the stderr output in the default message handler with stderrHasConsoleAttached().
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
index 16e01183bd..dded09999b 100644
--- a/src/corelib/global/qlogging.h
+++ b/src/corelib/global/qlogging.h
@@ -153,9 +153,9 @@ private:
#endif
#ifdef QT_MESSAGELOGCONTEXT
- #define QT_MESSAGELOG_FILE __FILE__
+ #define QT_MESSAGELOG_FILE static_cast<const char *>(__FILE__)
#define QT_MESSAGELOG_LINE __LINE__
- #define QT_MESSAGELOG_FUNC Q_FUNC_INFO
+ #define QT_MESSAGELOG_FUNC static_cast<const char *>(Q_FUNC_INFO)
#else
#define QT_MESSAGELOG_FILE nullptr
#define QT_MESSAGELOG_LINE 0
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index dec2c44637..6488426e64 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -500,7 +500,9 @@ public:
AA_NativeWindows = 3,
AA_DontCreateNativeWidgetSiblings = 4,
AA_PluginApplication = 5,
- AA_MacPluginApplication = AA_PluginApplication, // ### Qt 6: remove me
+#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove me
+ AA_MacPluginApplication Q_DECL_ENUMERATOR_DEPRECATED = AA_PluginApplication,
+#endif
AA_DontUseNativeMenuBar = 6,
AA_MacDontSwapCtrlAndMeta = 7,
AA_Use96Dpi = 8,
@@ -516,7 +518,7 @@ public:
AA_SetPalette = 19,
AA_EnableHighDpiScaling = 20,
AA_DisableHighDpiScaling = 21,
- AA_UseStyleSheetPropagationInWidgetStyles = 22, // ### Qt 6: remove me
+ AA_UseStyleSheetPropagationInWidgetStyles = 22,
AA_DontUseNativeDialogs = 23,
AA_SynthesizeMouseForUnhandledTabletEvents = 24,
AA_CompressHighFrequencyEvents = 25,
@@ -1504,10 +1506,12 @@ public:
// Metadata
FontRole = 6,
TextAlignmentRole = 7,
- BackgroundColorRole = 8,
BackgroundRole = 8,
- TextColorRole = 9,
ForegroundRole = 9,
+#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove me
+ BackgroundColorRole Q_DECL_ENUMERATOR_DEPRECATED = BackgroundRole,
+ TextColorRole Q_DECL_ENUMERATOR_DEPRECATED = ForegroundRole,
+#endif
CheckStateRole = 10,
// Accessibility
AccessibleTextRole = 11,
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index 77b3ba36b0..1f327c352e 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -324,7 +324,6 @@
// -- Web Assembly --
#elif defined(__EMSCRIPTEN__)
# define Q_PROCESSOR_WASM
-# define Q_PROCESSOR_X86 6 // enables SIMD support
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
# define Q_PROCESSOR_WORDSIZE 8
#endif
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index 4f79c48c51..567ff5c08e 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -49,6 +49,26 @@ QT_BEGIN_NAMESPACE
QTypeInfo - type trait functionality
*/
+template <typename T>
+static constexpr bool qIsRelocatable()
+{
+#if defined(Q_CC_CLANG) || !defined(Q_CC_GNU) || Q_CC_GNU >= 501
+ return std::is_trivially_copyable<T>::value && std::is_trivially_destructible<T>::value;
+#else
+ return std::is_enum<T>::value || std::is_integral<T>::value;
+#endif
+}
+
+template <typename T>
+static constexpr bool qIsTrivial()
+{
+#if defined(Q_CC_CLANG) || !defined(Q_CC_GNU) || Q_CC_GNU >= 501
+ return std::is_trivial<T>::value;
+#else
+ return std::is_enum<T>::value || std::is_integral<T>::value;
+#endif
+}
+
/*
The catch-all template.
*/
@@ -61,9 +81,9 @@ public:
isSpecialized = std::is_enum<T>::value, // don't require every enum to be marked manually
isPointer = false,
isIntegral = std::is_integral<T>::value,
- isComplex = !isIntegral && !std::is_enum<T>::value,
+ isComplex = !qIsTrivial<T>(),
isStatic = true,
- isRelocatable = std::is_enum<T>::value,
+ isRelocatable = qIsRelocatable<T>(),
isLarge = (sizeof(T)>sizeof(void*)),
isDummy = false, //### Qt6: remove
sizeOf = sizeof(T)
@@ -248,9 +268,9 @@ class QTypeInfo<TYPE > \
public: \
enum { \
isSpecialized = true, \
- isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \
+ isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0) && !qIsTrivial<TYPE>(), \
isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \
- isRelocatable = !isStatic || ((FLAGS) & Q_RELOCATABLE_TYPE), \
+ isRelocatable = !isStatic || ((FLAGS) & Q_RELOCATABLE_TYPE) || qIsRelocatable<TYPE>(), \
isLarge = (sizeof(TYPE)>sizeof(void*)), \
isPointer = false, \
isIntegral = std::is_integral< TYPE >::value, \
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index 086d642c26..9b6044752f 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -79,6 +79,8 @@ SOURCES += \
io/qloggingcategory.cpp \
io/qloggingregistry.cpp
+qtConfig(zstd): QMAKE_USE_PRIVATE += zstd
+
qtConfig(filesystemwatcher) {
HEADERS += \
io/qfilesystemwatcher.h \
diff --git a/src/corelib/io/qabstractfileengine_p.h b/src/corelib/io/qabstractfileengine_p.h
index 00c415b521..4a7fe7bff5 100644
--- a/src/corelib/io/qabstractfileengine_p.h
+++ b/src/corelib/io/qabstractfileengine_p.h
@@ -208,7 +208,7 @@ protected:
QScopedPointer<QAbstractFileEnginePrivate> d_ptr;
private:
Q_DECLARE_PRIVATE(QAbstractFileEngine)
- Q_DISABLE_COPY(QAbstractFileEngine)
+ Q_DISABLE_COPY_MOVE(QAbstractFileEngine)
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractFileEngine::FileFlags)
@@ -245,7 +245,7 @@ protected:
virtual QVariant entryInfo(EntryInfoType type) const;
private:
- Q_DISABLE_COPY(QAbstractFileEngineIterator)
+ Q_DISABLE_COPY_MOVE(QAbstractFileEngineIterator)
friend class QDirIterator;
friend class QDirIteratorPrivate;
void setPath(const QString &path);
diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp
index e0b9c41323..7b3fa2ccad 100644
--- a/src/corelib/io/qbuffer.cpp
+++ b/src/corelib/io/qbuffer.cpp
@@ -60,8 +60,8 @@ public:
QByteArray *buf;
QByteArray defaultBuf;
- virtual qint64 peek(char *data, qint64 maxSize) override;
- virtual QByteArray peek(qint64 maxSize) override;
+ qint64 peek(char *data, qint64 maxSize) override;
+ QByteArray peek(qint64 maxSize) override;
#ifndef QT_NO_QOBJECT
// private slots
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 4d56d1a179..15c5e0ce96 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -356,7 +356,7 @@ QDebug &QDebug::resetFormat()
stream->space = true;
if (stream->context.version > 1)
stream->flags = 0;
- stream->setVerbosity(Stream::DefaultVerbosity);
+ stream->setVerbosity(DefaultVerbosity);
return *this;
}
@@ -461,7 +461,7 @@ QDebug &QDebug::resetFormat()
The allowed range is from 0 to 7. The default value is 2.
- \sa setVerbosity()
+ \sa setVerbosity(), VerbosityLevel
*/
/*!
@@ -472,7 +472,31 @@ QDebug &QDebug::resetFormat()
The allowed range is from 0 to 7. The default value is 2.
- \sa verbosity()
+ \sa verbosity(), VerbosityLevel
+*/
+
+/*!
+ \fn QDebug &QDebug::verbosity(int verbosityLevel)
+ \since 5.13
+
+ Sets the verbosity of the stream to \a verbosityLevel and returns a reference to the stream.
+
+ The allowed range is from 0 to 7. The default value is 2.
+
+ \sa verbosity(), setVerbosity(), VerbosityLevel
+*/
+
+/*!
+ \enum QDebug::VerbosityLevel
+ \since 5.13
+
+ This enum describes the range of verbosity levels.
+
+ \value MinimumVerbosity
+ \value DefaultVerbosity
+ \value MaximumVerbosity
+
+ \sa verbosity(), setVerbosity()
*/
/*!
@@ -892,37 +916,127 @@ void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, int value)
#ifndef QT_NO_QOBJECT
/*!
+ \fn QDebug qt_QMetaEnum_debugOperator(QDebug &, int value, const QMetaObject *, const char *name)
\internal
+
+ Formats the given enum \a value for debug output.
+
+ The supported verbosity are:
+
+ 0: Just the key, or value with enum name if no key is found:
+
+ MyEnum2
+ MyEnum(123)
+ MyScopedEnum::Enum3
+ MyScopedEnum(456)
+
+ 1: Same as 0, but treating all enums as scoped:
+
+ MyEnum::MyEnum2
+ MyEnum(123)
+ MyScopedEnum::Enum3
+ MyScopedEnum(456)
+
+ 2: The QDebug default. Same as 0, and includes class/namespace scope:
+
+ MyNamespace::MyClass::MyEnum2
+ MyNamespace::MyClass::MyEnum(123)
+ MyNamespace::MyClass::MyScopedEnum::Enum3
+ MyNamespace::MyClass::MyScopedEnum(456)
+
+ 3: Same as 2, but treating all enums as scoped:
+
+ MyNamespace::MyClass::MyEnum::MyEnum2
+ MyNamespace::MyClass::MyEnum(123)
+ MyNamespace::MyClass::MyScopedEnum::Enum3
+ MyNamespace::MyClass::MyScopedEnum(456)
*/
QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, int value, const QMetaObject *meta, const char *name)
{
QDebugStateSaver saver(dbg);
dbg.nospace();
QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));
- const char *key = me.valueToKey(value);
- if (key) {
+
+ const int verbosity = dbg.verbosity();
+ if (verbosity >= QDebug::DefaultVerbosity) {
if (const char *scope = me.scope())
dbg << scope << "::";
- if (me.isScoped())
- dbg << me.enumName() << "::";
- dbg << key;
- } else {
- dbg << meta->className() << "::" << name << "(" << value << ")";
}
+
+ const char *key = me.valueToKey(value);
+ const bool scoped = me.isScoped() || verbosity & 1;
+ if (scoped || !key)
+ dbg << me.enumName() << (!key ? "(" : "::");
+
+ if (key)
+ dbg << key;
+ else
+ dbg << value << ")";
+
return dbg;
}
+/*!
+ \fn QDebug qt_QMetaEnum_flagDebugOperator(QDebug &, quint64 value, const QMetaObject *, const char *name)
+ \internal
+
+ Formats the given flag \a value for debug output.
+
+ The supported verbosity are:
+
+ 0: Just the key(s):
+
+ MyFlag1
+ MyFlag2|MyFlag3
+ MyScopedFlag(MyFlag2)
+ MyScopedFlag(MyFlag2|MyFlag3)
+
+ 1: Same as 0, but treating all flags as scoped:
+
+ MyFlag(MyFlag1)
+ MyFlag(MyFlag2|MyFlag3)
+ MyScopedFlag(MyFlag2)
+ MyScopedFlag(MyFlag2|MyFlag3)
+
+ 2: The QDebug default. Same as 1, and includes class/namespace scope:
+
+ QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1)
+ QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)
+ QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)
+ QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)
+ */
QDebug qt_QMetaEnum_flagDebugOperator(QDebug &debug, quint64 value, const QMetaObject *meta, const char *name)
{
+ const int verbosity = debug.verbosity();
+
QDebugStateSaver saver(debug);
debug.resetFormat();
debug.noquote();
debug.nospace();
- debug << "QFlags<";
+
const QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));
- if (const char *scope = me.scope())
- debug << scope << "::";
- debug << me.enumName() << ">(" << me.valueToKeys(value) << ')';
+
+ const bool classScope = verbosity >= QDebug::DefaultVerbosity;
+ if (classScope) {
+ debug << "QFlags<";
+
+ if (const char *scope = me.scope())
+ debug << scope << "::";
+ }
+
+ const bool enumScope = me.isScoped() || verbosity > QDebug::MinimumVerbosity;
+ if (enumScope) {
+ debug << me.enumName();
+ if (classScope)
+ debug << ">";
+ debug << "(";
+ }
+
+ debug << me.valueToKeys(value);
+
+ if (enumScope)
+ debug << ')';
+
return debug;
}
#endif // !QT_NO_QOBJECT
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 9d1ce51da5..91fde75fa5 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -67,7 +67,7 @@ class Q_CORE_EXPORT QDebug
friend class QMessageLogger;
friend class QDebugStateSaverPrivate;
struct Stream {
- enum { DefaultVerbosity = 2, VerbosityShift = 29, VerbosityMask = 0x7 };
+ enum { VerbosityShift = 29, VerbosityMask = 0x7 };
Stream(QIODevice *device) : ts(device), ref(1), type(QtDebugMsg),
space(true), message_output(false), flags(DefaultVerbosity << VerbosityShift) {}
@@ -92,7 +92,7 @@ class Q_CORE_EXPORT QDebug
void setFlag(FormatFlag flag) { if (context.version > 1) { flags |= flag; } }
void unsetFlag(FormatFlag flag) { if (context.version > 1) { flags &= ~flag; } }
int verbosity() const
- { return context.version > 1 ? (flags >> VerbosityShift) & VerbosityMask : int(Stream::DefaultVerbosity); }
+ { return context.version > 1 ? (flags >> VerbosityShift) & VerbosityMask : int(DefaultVerbosity); }
void setVerbosity(int v)
{
if (context.version > 1) {
@@ -123,8 +123,10 @@ public:
inline QDebug &space() { stream->space = true; stream->ts << ' '; return *this; }
inline QDebug &nospace() { stream->space = false; return *this; }
inline QDebug &maybeSpace() { if (stream->space) stream->ts << ' '; return *this; }
+ inline QDebug &verbosity(int verbosityLevel) { setVerbosity(verbosityLevel); return *this; }
int verbosity() const { return stream->verbosity(); }
void setVerbosity(int verbosityLevel) { stream->setVerbosity(verbosityLevel); }
+ enum VerbosityLevel { MinimumVerbosity = 0, DefaultVerbosity = 2, MaximumVerbosity = 7 };
bool autoInsertSpaces() const { return stream->space; }
void setAutoInsertSpaces(bool b) { stream->space = b; }
@@ -195,6 +197,7 @@ public:
inline QNoDebug &quote() { return *this; }
inline QNoDebug &noquote() { return *this; }
inline QNoDebug &maybeQuote(const char = '"') { return *this; }
+ inline QNoDebug &verbosity(int) { return *this; }
template<typename T>
inline QNoDebug &operator<<(const T &) { return *this; }
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index f7778943c9..671913e92f 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -1069,6 +1069,7 @@ void QDir::setNameFilters(const QStringList &nameFilters)
d->nameFilters = nameFilters;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -1083,11 +1084,15 @@ void QDir::setNameFilters(const QStringList &nameFilters)
void QDir::addResourceSearchPath(const QString &path)
{
#ifdef QT_BUILD_CORE_LIB
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
QResource::addSearchPath(path);
+QT_WARNING_POP
#else
Q_UNUSED(path)
#endif
}
+#endif
#ifdef QT_BUILD_CORE_LIB
/*!
@@ -1815,6 +1820,7 @@ QDir &QDir::operator=(const QDir &dir)
return *this;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\overload
\obsolete
@@ -1828,6 +1834,7 @@ QDir &QDir::operator=(const QString &path)
d_ptr->setPath(path);
return *this;
}
+#endif
/*!
\fn void QDir::swap(QDir &other)
diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h
index 45c59d9e1d..9abb833ab1 100644
--- a/src/corelib/io/qdir.h
+++ b/src/corelib/io/qdir.h
@@ -105,7 +105,10 @@ public:
~QDir();
QDir &operator=(const QDir &);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QDir::setPath() instead")
QDir &operator=(const QString &path);
+#endif
#ifdef Q_COMPILER_RVALUE_REFS
QDir &operator=(QDir &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
@@ -118,7 +121,10 @@ public:
QString absolutePath() const;
QString canonicalPath() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QDir::addSearchPath() instead")
static void addResourceSearchPath(const QString &path);
+#endif
static void setSearchPaths(const QString &prefix, const QStringList &searchPaths);
static void addSearchPath(const QString &prefix, const QString &path);
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 3166fa1b83..ef97d67653 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -454,7 +454,13 @@ QFile::exists(const QString &fileName)
\sa fileName(), setFileName()
*/
+QString QFile::symLinkTarget() const
+{
+ Q_D(const QFile);
+ return d->engine()->fileName(QAbstractFileEngine::LinkName);
+}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -463,9 +469,9 @@ QFile::exists(const QString &fileName)
QString
QFile::readLink() const
{
- Q_D(const QFile);
- return d->engine()->fileName(QAbstractFileEngine::LinkName);
+ return symLinkTarget();
}
+#endif
/*!
\fn static QString QFile::symLinkTarget(const QString &fileName)
@@ -478,7 +484,12 @@ QFile::readLink() const
This name may not represent an existing file; it is only a string.
QFile::exists() returns \c true if the symlink points to an existing file.
*/
+QString QFile::symLinkTarget(const QString &fileName)
+{
+ return QFileInfo(fileName).symLinkTarget();
+}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -487,8 +498,9 @@ QFile::readLink() const
QString
QFile::readLink(const QString &fileName)
{
- return QFileInfo(fileName).readLink();
+ return symLinkTarget(fileName);
}
+#endif
/*!
Removes the file specified by fileName(). Returns \c true if successful;
@@ -808,7 +820,7 @@ QFile::copy(const QString &newName)
if (error) {
out.close();
close();
- d->setError(QFile::CopyError, tr("Cannot open for output"));
+ d->setError(QFile::CopyError, tr("Cannot open for output: %1").arg(out.errorString()));
} else {
if (!d->engine()->cloneTo(out.d_func()->engine())) {
char block[4096];
diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h
index e6f3d942fe..cf1465ec70 100644
--- a/src/corelib/io/qfile.h
+++ b/src/corelib/io/qfile.h
@@ -107,10 +107,14 @@ public:
bool exists() const;
static bool exists(const QString &fileName);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QFile::symLinkTarget() instead")
QString readLink() const;
+ QT_DEPRECATED_X("Use QFile::symLinkTarget(QString) instead")
static QString readLink(const QString &fileName);
- inline QString symLinkTarget() const { return readLink(); }
- inline static QString symLinkTarget(const QString &fileName) { return readLink(fileName); }
+#endif
+ QString symLinkTarget() const;
+ static QString symLinkTarget(const QString &fileName);
bool remove();
static bool remove(const QString &fileName);
diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp
index 2f99775c65..0689118f3e 100644
--- a/src/corelib/io/qfiledevice.cpp
+++ b/src/corelib/io/qfiledevice.cpp
@@ -700,7 +700,7 @@ bool QFileDevice::setPermissions(Permissions permissions)
Any mapping options can be passed through \a flags.
- Returns a pointer to the memory or 0 if there is an error.
+ Returns a pointer to the memory or \nullptr if there is an error.
\sa unmap()
*/
@@ -711,11 +711,11 @@ uchar *QFileDevice::map(qint64 offset, qint64 size, MemoryMapFlags flags)
&& d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) {
unsetError();
uchar *address = d->fileEngine->map(offset, size, flags);
- if (address == 0)
+ if (address == nullptr)
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
return address;
}
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/corelib/io/qfiledevice.h b/src/corelib/io/qfiledevice.h
index af41bec2f6..2d524193c5 100644
--- a/src/corelib/io/qfiledevice.h
+++ b/src/corelib/io/qfiledevice.h
@@ -100,7 +100,7 @@ public:
FileError error() const;
void unsetError();
- virtual void close() override;
+ void close() override;
bool isSequential() const override;
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 185e061d8f..998382021d 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -1107,6 +1107,7 @@ bool QFileInfo::isRoot() const
\sa exists(), isSymLink(), isDir(), isFile()
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -1114,6 +1115,12 @@ bool QFileInfo::isRoot() const
*/
QString QFileInfo::readLink() const
{
+ return symLinkTarget();
+}
+#endif
+
+QString QFileInfo::symLinkTarget() const
+{
Q_D(const QFileInfo);
if (d->isDefaultConstructed)
return QLatin1String("");
diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h
index f295a86015..baea18fab1 100644
--- a/src/corelib/io/qfileinfo.h
+++ b/src/corelib/io/qfileinfo.h
@@ -116,8 +116,11 @@ public:
bool isRoot() const;
bool isBundle() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QFileInfo::symLinkTarget() instead")
QString readLink() const;
- inline QString symLinkTarget() const { return readLink(); }
+#endif
+ QString symLinkTarget() const;
QString owner() const;
uint ownerId() const;
diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h
index 081487e66e..5e4e424e69 100644
--- a/src/corelib/io/qfilesystemiterator_p.h
+++ b/src/corelib/io/qfilesystemiterator_p.h
@@ -96,7 +96,7 @@ private:
int lastError;
#endif
- Q_DISABLE_COPY(QFileSystemIterator)
+ Q_DISABLE_COPY_MOVE(QFileSystemIterator)
};
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfilesystemwatcher_win_p.h b/src/corelib/io/qfilesystemwatcher_win_p.h
index 1d3224614c..272591ce7a 100644
--- a/src/corelib/io/qfilesystemwatcher_win_p.h
+++ b/src/corelib/io/qfilesystemwatcher_win_p.h
@@ -77,8 +77,8 @@ public:
explicit QWindowsFileSystemWatcherEngine(QObject *parent);
~QWindowsFileSystemWatcherEngine();
- QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories);
- QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories);
+ QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories) override;
+ QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories) override;
class Handle
{
@@ -154,7 +154,7 @@ public:
QWindowsFileSystemWatcherEngineThread();
~QWindowsFileSystemWatcherEngineThread();
- void run();
+ void run() override;
void stop();
void wakeup();
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 86e21f0a66..74df0f71ef 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -194,7 +194,7 @@ QIODevicePrivate::~QIODevicePrivate()
QIODevice provides both a common implementation and an abstract
interface for devices that support reading and writing of blocks
of data, such as QFile, QBuffer and QTcpSocket. QIODevice is
- abstract and can not be instantiated, but it is common to use the
+ abstract and cannot be instantiated, but it is common to use the
interface it defines to provide device-independent I/O features.
For example, Qt's XML classes operate on a QIODevice pointer,
allowing them to be used with various devices (such as files and
diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h
index ebed1120db..bbc4ea5ae2 100644
--- a/src/corelib/io/qnoncontiguousbytedevice_p.h
+++ b/src/corelib/io/qnoncontiguousbytedevice_p.h
@@ -179,13 +179,13 @@ class QByteDeviceWrappingIoDevice : public QIODevice
public:
QByteDeviceWrappingIoDevice (QNonContiguousByteDevice *bd);
~QByteDeviceWrappingIoDevice ();
- virtual bool isSequential () const override;
- virtual bool atEnd () const override;
- virtual bool reset () override;
- virtual qint64 size () const override;
+ bool isSequential() const override;
+ bool atEnd() const override;
+ bool reset() override;
+ qint64 size() const override;
protected:
- virtual qint64 readData ( char * data, qint64 maxSize ) override;
- virtual qint64 writeData ( const char * data, qint64 maxSize ) override;
+ qint64 readData(char *data, qint64 maxSize) override;
+ qint64 writeData(const char *data, qint64 maxSize) override;
QNonContiguousByteDevice *byteDevice;
};
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index e1f4a3a311..d5d67d86f3 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -813,6 +813,7 @@ void QProcessPrivate::Channel::clear()
\a newState argument is the state QProcess changed to.
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn void QProcess::finished(int exitCode)
\obsolete
@@ -820,6 +821,7 @@ void QProcessPrivate::Channel::clear()
Use finished(int exitCode, QProcess::ExitStatus status) instead.
*/
+#endif
/*!
\fn void QProcess::finished(int exitCode, QProcess::ExitStatus exitStatus)
@@ -1172,7 +1174,12 @@ bool QProcessPrivate::_q_processDied()
//emit q->standardOutputClosed();
//emit q->standardErrorClosed();
+#if QT_DEPRECATED_SINCE(5, 13)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit q->finished(exitCode);
+QT_WARNING_POP
+#endif
emit q->finished(exitCode, exitStatus);
}
#if defined QPROCESS_DEBUG
@@ -1264,6 +1271,7 @@ QProcess::~QProcess()
d->cleanup();
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
Returns the read channel mode of the QProcess. This function is
@@ -1287,6 +1295,7 @@ void QProcess::setReadChannelMode(ProcessChannelMode mode)
{
setProcessChannelMode(mode);
}
+#endif
/*!
\since 4.2
@@ -2473,7 +2482,7 @@ QProcess::ExitStatus QProcess::exitStatus() const
int QProcess::execute(const QString &program, const QStringList &arguments)
{
QProcess process;
- process.setReadChannelMode(ForwardedChannels);
+ process.setProcessChannelMode(ForwardedChannels);
process.start(program, arguments);
if (!process.waitForFinished(-1) || process.error() == FailedToStart)
return -2;
@@ -2496,7 +2505,7 @@ int QProcess::execute(const QString &program, const QStringList &arguments)
int QProcess::execute(const QString &command)
{
QProcess process;
- process.setReadChannelMode(ForwardedChannels);
+ process.setProcessChannelMode(ForwardedChannels);
process.start(command);
if (!process.waitForFinished(-1) || process.error() == FailedToStart)
return -2;
diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h
index 474fc87de8..a2e3c01f7c 100644
--- a/src/corelib/io/qprocess.h
+++ b/src/corelib/io/qprocess.h
@@ -48,22 +48,24 @@
QT_REQUIRE_CONFIG(processenvironment);
-QT_BEGIN_NAMESPACE
-
-class QProcessPrivate;
-
-#if !defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)
-typedef qint64 Q_PID;
-#else
-QT_END_NAMESPACE
+#ifdef Q_OS_WIN
typedef struct _PROCESS_INFORMATION *Q_PID;
+#endif
+
+#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)
typedef struct _SECURITY_ATTRIBUTES Q_SECURITY_ATTRIBUTES;
typedef struct _STARTUPINFOW Q_STARTUPINFO;
-QT_BEGIN_NAMESPACE
#endif
+QT_BEGIN_NAMESPACE
+
+class QProcessPrivate;
class QProcessEnvironmentPrivate;
+#ifndef Q_OS_WIN
+typedef qint64 Q_PID;
+#endif
+
class Q_CORE_EXPORT QProcessEnvironment
{
public:
@@ -172,8 +174,12 @@ public:
QStringList arguments() const;
void setArguments(const QStringList & arguments);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QProcess::processChannelMode() instead")
ProcessChannelMode readChannelMode() const;
+ QT_DEPRECATED_X("Use QProcess::setProcessChannelMode() instead")
void setReadChannelMode(ProcessChannelMode mode);
+#endif
ProcessChannelMode processChannelMode() const;
void setProcessChannelMode(ProcessChannelMode mode);
InputChannelMode inputChannelMode() const;
@@ -269,7 +275,10 @@ public Q_SLOTS:
Q_SIGNALS:
void started(QPrivateSignal);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QProcess::finished(int, QProcess::ExitStatus) instead")
void finished(int exitCode); // ### Qt 6: merge the two signals with a default value
+#endif
void finished(int exitCode, QProcess::ExitStatus exitStatus);
#if QT_DEPRECATED_SINCE(5,6)
void error(QProcess::ProcessError error);
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 564a3e5f51..e7d739b4dc 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -56,16 +57,46 @@
#include "private/qabstractfileengine_p.h"
#include "private/qnumeric_p.h"
#include "private/qsimd_p.h"
+#include "private/qtools_p.h"
#include "private/qsystemerror_p.h"
+#if QT_CONFIG(zstd)
+# include <zstd.h>
+#endif
+
#ifdef Q_OS_UNIX
# include "private/qcore_unix_p.h"
#endif
+#if defined(Q_OS_UNIX) && !defined(Q_OS_NACL) && !defined(Q_OS_INTEGRITY)
+# define QT_USE_MMAP
+# include <sys/mman.h>
+#endif
+
//#define DEBUG_RESOURCE_MATCH
QT_BEGIN_NAMESPACE
+// Symbols used by code generated by RCC.
+// They cause compilation errors if the RCC content couldn't
+// be interpreted by this QtCore version.
+#if defined(__ELF__) || defined(__APPLE__) // same as RCC generates
+# define RCC_FEATURE_SYMBOL(feature) \
+ extern Q_CORE_EXPORT const quint8 qt_resourceFeature ## feature; \
+ const quint8 qt_resourceFeature ## feature = 0;
+#else
+# define RCC_FEATURE_SYMBOL(feature) \
+ Q_CORE_EXPORT quint8 qResourceFeature ## feature() { return 0; }
+#endif
+
+#ifndef QT_NO_COMPRESS
+RCC_FEATURE_SYMBOL(Zlib)
+#endif
+#if QT_CONFIG(zstd)
+RCC_FEATURE_SYMBOL(Zstd)
+#endif
+
+#undef RCC_FEATURE_SYMBOL
class QStringSplitter
{
@@ -98,11 +129,15 @@ public:
//resource glue
class QResourceRoot
{
+public:
enum Flags
{
+ // must match rcc.h
Compressed = 0x01,
- Directory = 0x02
+ Directory = 0x02,
+ CompressedZstd = 0x04
};
+private:
const uchar *tree, *names, *payloads;
int version;
inline int findOffset(int node) const { return node * (14 + (version >= 0x02 ? 8 : 0)); } //sizeof each tree element
@@ -117,7 +152,15 @@ public:
virtual ~QResourceRoot() { }
int findNode(const QString &path, const QLocale &locale=QLocale()) const;
inline bool isContainer(int node) const { return flags(node) & Directory; }
- inline bool isCompressed(int node) const { return flags(node) & Compressed; }
+ QResource::Compression compressionAlgo(int node)
+ {
+ uint compressionFlags = flags(node) & (Compressed | CompressedZstd);
+ if (compressionFlags == Compressed)
+ return QResource::ZlibCompression;
+ if (compressionFlags == CompressedZstd)
+ return QResource::ZstdCompression;
+ return QResource::NoCompression;
+ }
const uchar *data(int node, qint64 *size) const;
quint64 lastModified(int node) const;
QStringList children(int node) const;
@@ -229,6 +272,23 @@ static inline QStringList *resourceSearchPaths()
\sa {The Qt Resource System}, QFile, QDir, QFileInfo
*/
+/*!
+ \enum QResource::Compression
+ \since 5.13
+
+ This enum is used by compressionAlgorithm() to indicate which algorithm the
+ RCC tool used to compress the payload.
+
+ \value NoCompression Contents are not compressed (isCompressed() is false).
+ \value ZlibCompression Contents are compressed using \l{zlib}{https://zlib.net} and can
+ be decompressed using the qUncompress() function.
+ \value ZstdCompression Contents are compressed using \l{zstd}{https://zstd.net}. To
+ decompress, use the \c{ZSTD_decompress} function from the zstd
+ library.
+
+ \sa compressionAlgorithm(), isCompressed()
+*/
+
class QResourcePrivate {
public:
inline QResourcePrivate(QResource *_q) : q_ptr(_q) { clear(); }
@@ -243,12 +303,13 @@ public:
QLocale locale;
QString fileName, absoluteFilePath;
QList<QResourceRoot*> related;
- uint container : 1;
- mutable uint compressed : 1;
mutable qint64 size;
+ mutable quint64 lastModified;
mutable const uchar *data;
mutable QStringList children;
- mutable quint64 lastModified;
+ mutable quint8 compressionAlgo;
+ bool container;
+ /* 2 or 6 padding bytes */
QResource *q_ptr;
Q_DECLARE_PUBLIC(QResource)
@@ -258,7 +319,7 @@ void
QResourcePrivate::clear()
{
absoluteFilePath.clear();
- compressed = 0;
+ compressionAlgo = QResource::NoCompression;
data = 0;
size = 0;
children.clear();
@@ -287,11 +348,11 @@ QResourcePrivate::load(const QString &file)
container = res->isContainer(node);
if(!container) {
data = res->data(node, &size);
- compressed = res->isCompressed(node);
+ compressionAlgo = res->compressionAlgo(node);
} else {
- data = 0;
+ data = nullptr;
size = 0;
- compressed = 0;
+ compressionAlgo = QResource::NoCompression;
}
lastModified = res->lastModified(node);
} else if(res->isContainer(node) != container) {
@@ -301,9 +362,9 @@ QResourcePrivate::load(const QString &file)
related.append(res);
} else if(res->mappingRootSubdir(file)) {
container = true;
- data = 0;
+ data = nullptr;
size = 0;
- compressed = 0;
+ compressionAlgo = QResource::NoCompression;
lastModified = 0;
res->ref.ref();
related.append(res);
@@ -493,16 +554,41 @@ bool QResource::isValid() const
/*!
Returns \c true if the resource represents a file and the data backing it
- is in a compressed format, false otherwise.
+ is in a compressed format, false otherwise. If the data is compressed,
+ check compressionAlgorithm() to verify what algorithm to use to decompress
+ the data.
- \sa data(), isFile()
+ \sa data(), compressionAlgorithm(), isFile()
*/
bool QResource::isCompressed() const
{
+ return compressionAlgorithm() != NoCompression;
+}
+
+/*!
+ \since 5.13
+
+ Returns the compression type that this resource is compressed with, if any.
+ If it is not compressed, this function returns QResource::NoCompression.
+
+ If this function returns QResource::ZlibCompression, you may decompress the
+ data using the qUncompress() function. Up until Qt 5.13, this was the only
+ possible compression algorithm.
+
+ If this function returns QResource::ZstdCompression, you need to use the
+ Zstandard library functios (\c{<zstd.h> header). Qt does not provide a
+ wrapper.
+
+ See \l{http://facebook.github.io/zstd/zstd_manual.html}{Zstandard manual}.
+
+ \sa isCompressed(), data(), isFile()
+*/
+QResource::Compression QResource::compressionAlgorithm() const
+{
Q_D(const QResource);
d->ensureInitialized();
- return d->compressed;
+ return Compression(d->compressionAlgo);
}
/*!
@@ -522,7 +608,7 @@ qint64 QResource::size() const
Returns direct access to a read only segment of data that this resource
represents. If the resource is compressed the data returns is
compressed and qUncompress() must be used to access the data. If the
- resource is a directory 0 is returned.
+ resource is a directory \nullptr is returned.
\sa size(), isCompressed(), isFile()
*/
@@ -573,6 +659,7 @@ QStringList QResource::children() const
return d->children;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -614,6 +701,7 @@ QResource::searchPaths()
QMutexLocker lock(resourceMutex());
return *resourceSearchPaths();
}
+#endif
inline uint QResourceRoot::hash(int node) const
{
@@ -853,7 +941,7 @@ Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree,
const unsigned char *name, const unsigned char *data)
{
QMutexLocker lock(resourceMutex());
- if ((version == 0x01 || version == 0x2) && resourceList()) {
+ if (version >= 0x01 && version <= 0x3 && resourceList()) {
bool found = false;
QResourceRoot res(version, tree, name, data);
for(int i = 0; i < resourceList()->size(); ++i) {
@@ -879,7 +967,7 @@ Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tre
return false;
QMutexLocker lock(resourceMutex());
- if ((version == 0x01 || version == 0x02) && resourceList()) {
+ if (version >= 0x01 && version <= 0x3 && resourceList()) {
QResourceRoot res(version, tree, name, data);
for(int i = 0; i < resourceList()->size(); ) {
if(*resourceList()->at(i) == res) {
@@ -906,11 +994,11 @@ public:
inline QDynamicBufferResourceRoot(const QString &_root) : root(_root), buffer(0) { }
inline ~QDynamicBufferResourceRoot() { }
inline const uchar *mappingBuffer() const { return buffer; }
- virtual QString mappingRoot() const override { return root; }
- virtual ResourceRootType type() const override { return Resource_Buffer; }
+ QString mappingRoot() const override { return root; }
+ ResourceRootType type() const override { return Resource_Buffer; }
// size == -1 means "unknown"
- bool registerSelf(const uchar *b, int size)
+ bool registerSelf(const uchar *b, qsizetype size)
{
// 5 int "pointers"
if (size >= 0 && size < 20)
@@ -938,11 +1026,27 @@ public:
const int name_offset = qFromBigEndian<qint32>(b + offset);
offset += 4;
+ quint32 file_flags = 0;
+ if (version >= 3) {
+ file_flags = qFromBigEndian<qint32>(b + offset);
+ offset += 4;
+ }
+
// Some sanity checking for sizes. This is _not_ a security measure.
if (size >= 0 && (tree_offset >= size || data_offset >= size || name_offset >= size))
return false;
- if (version == 0x01 || version == 0x02) {
+ // And some sanity checking for features
+ quint32 acceptableFlags = 0;
+#ifndef QT_NO_COMPRESS
+ acceptableFlags |= Compressed;
+#endif
+ if (QT_CONFIG(zstd))
+ acceptableFlags |= CompressedZstd;
+ if (file_flags & ~acceptableFlags)
+ return false;
+
+ if (version >= 0x01 && version <= 0x03) {
buffer = b;
setSource(version, b+tree_offset, b+name_offset, b+data_offset);
return true;
@@ -951,28 +1055,12 @@ public:
}
};
-#if defined(Q_OS_UNIX) && !defined (Q_OS_NACL) && !defined(Q_OS_INTEGRITY)
-#define QT_USE_MMAP
-#endif
-
-// most of the headers below are already included in qplatformdefs.h
-// also this lacks Large File support but that's probably irrelevant
-#if defined(QT_USE_MMAP)
-// for mmap
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <sys/mman.h>
-#include <errno.h>
-QT_END_INCLUDE_NAMESPACE
-#endif
-
-
-
class QDynamicFileResourceRoot: public QDynamicBufferResourceRoot
{
QString fileName;
// for mmap'ed files, this is what needs to be unmapped.
uchar *unmapPointer;
- unsigned int unmapLength;
+ qsizetype unmapLength;
public:
inline QDynamicFileResourceRoot(const QString &_root) : QDynamicBufferResourceRoot(_root), unmapPointer(0), unmapLength(0) { }
@@ -989,76 +1077,78 @@ public:
}
}
QString mappingFile() const { return fileName; }
- virtual ResourceRootType type() const override { return Resource_File; }
-
- bool registerSelf(const QString &f) {
- bool fromMM = false;
- uchar *data = 0;
- unsigned int data_len = 0;
+ ResourceRootType type() const override { return Resource_File; }
-#ifdef QT_USE_MMAP
+ bool registerSelf(const QString &f);
+};
#ifndef MAP_FILE
-#define MAP_FILE 0
+# define MAP_FILE 0
#endif
#ifndef MAP_FAILED
-#define MAP_FAILED -1
+# define MAP_FAILED reinterpret_cast<void *>(-1)
#endif
- int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY,
+bool QDynamicFileResourceRoot::registerSelf(const QString &f)
+{
+ bool fromMM = false;
+ uchar *data = nullptr;
+ qsizetype data_len = 0;
+
+#ifdef QT_USE_MMAP
+ int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY,
#if defined(Q_OS_WIN)
- _S_IREAD | _S_IWRITE
+ _S_IREAD | _S_IWRITE
#else
- 0666
+ 0666
#endif
- );
- if (fd >= 0) {
- QT_STATBUF st;
- if (!QT_FSTAT(fd, &st)) {
- uchar *ptr;
- ptr = reinterpret_cast<uchar *>(
- mmap(0, st.st_size, // any address, whole file
- PROT_READ, // read-only memory
- MAP_FILE | MAP_PRIVATE, // swap-backed map from file
- fd, 0)); // from offset 0 of fd
- if (ptr && ptr != reinterpret_cast<uchar *>(MAP_FAILED)) {
- data = ptr;
- data_len = st.st_size;
- fromMM = true;
- }
+ );
+ if (fd >= 0) {
+ QT_STATBUF st;
+ if (!QT_FSTAT(fd, &st) && st.st_size <= std::numeric_limits<qsizetype>::max()) {
+ int protection = PROT_READ; // read-only memory
+ int flags = MAP_FILE | MAP_PRIVATE; // swap-backed map from file
+ void *ptr = QT_MMAP(nullptr, st.st_size, // any address, whole file
+ protection, flags,
+ fd, 0); // from offset 0 of fd
+ if (ptr != MAP_FAILED) {
+ data = static_cast<uchar *>(ptr);
+ data_len = st.st_size;
+ fromMM = true;
}
- ::close(fd);
}
+ QT_CLOSE(fd);
+ }
#endif // QT_USE_MMAP
- if(!data) {
- QFile file(f);
- if (!file.exists())
- return false;
- data_len = file.size();
- data = new uchar[data_len];
-
- bool ok = false;
- if (file.open(QIODevice::ReadOnly))
- ok = (data_len == (uint)file.read((char*)data, data_len));
- if (!ok) {
- delete [] data;
- data = 0;
- data_len = 0;
- return false;
+ if (!data) {
+ QFile file(f);
+ bool ok = false;
+ if (file.open(QIODevice::ReadOnly)) {
+ qint64 fsize = file.size();
+ if (fsize <= std::numeric_limits<qsizetype>::max()) {
+ data_len = file.size();
+ data = new uchar[data_len];
+ ok = (data_len == file.read((char*)data, data_len));
}
- fromMM = false;
}
- if (data && QDynamicBufferResourceRoot::registerSelf(data, data_len)) {
- if(fromMM) {
- unmapPointer = data;
- unmapLength = data_len;
- }
- fileName = f;
- return true;
+ if (!ok) {
+ delete [] data;
+ data = nullptr;
+ data_len = 0;
+ return false;
}
- return false;
+ fromMM = false;
}
-};
+ if (data && QDynamicBufferResourceRoot::registerSelf(data, data_len)) {
+ if (fromMM) {
+ unmapPointer = data;
+ unmapLength = data_len;
+ }
+ fileName = f;
+ return true;
+ }
+ return false;
+}
static QString qt_resource_fixResourceRoot(QString r) {
if(!r.isEmpty()) {
@@ -1531,12 +1621,40 @@ bool QResourceFileEnginePrivate::unmap(uchar *ptr)
void QResourceFileEnginePrivate::uncompress() const
{
- if (resource.isCompressed() && uncompressed.isEmpty() && resource.size()) {
+ if (uncompressed.isEmpty() && resource.size()) {
+ quint64 size;
+ switch (resource.compressionAlgorithm()) {
+ case QResource::NoCompression:
+ return; // nothing to do
+
+ case QResource::ZlibCompression:
#ifndef QT_NO_COMPRESS
- uncompressed = qUncompress(resource.data(), resource.size());
+ uncompressed = qUncompress(resource.data(), resource.size());
#else
- Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for compression");
+ Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for Zlib compression");
#endif
+ break;
+
+ case QResource::ZstdCompression:
+#if QT_CONFIG(zstd)
+ size = ZSTD_getFrameContentSize(resource.data(), resource.size());
+ if (!ZSTD_isError(size)) {
+ if (size >= MaxAllocSize) {
+ qWarning("QResourceFileEngine::open: content bigger than memory (size %lld)", size);
+ } else {
+ uncompressed = QByteArray(size, Qt::Uninitialized);
+ size = ZSTD_decompress(const_cast<char *>(uncompressed.data()), size,
+ resource.data(), resource.size());
+ }
+ }
+ if (ZSTD_isError(size))
+ qWarning("QResourceFileEngine::open: error decoding: %s", ZSTD_getErrorName(size));
+#else
+ Q_UNUSED(size);
+ Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for Zstd compression");
+#endif
+ break;
+ }
}
}
diff --git a/src/corelib/io/qresource.h b/src/corelib/io/qresource.h
index 895cf0456e..5e798de436 100644
--- a/src/corelib/io/qresource.h
+++ b/src/corelib/io/qresource.h
@@ -54,6 +54,12 @@ class QResourcePrivate;
class Q_CORE_EXPORT QResource
{
public:
+ enum Compression {
+ NoCompression,
+ ZlibCompression,
+ ZstdCompression
+ };
+
QResource(const QString &file=QString(), const QLocale &locale=QLocale());
~QResource();
@@ -67,12 +73,17 @@ public:
bool isValid() const;
bool isCompressed() const;
+ Compression compressionAlgorithm() const;
qint64 size() const;
const uchar *data() const;
QDateTime lastModified() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QDir::addSearchPath() instead")
static void addSearchPath(const QString &path);
+ QT_DEPRECATED_X("Use QDir::searchPaths() instead")
static QStringList searchPaths();
+#endif
static bool registerResource(const QString &rccFilename, const QString &resourceRoot=QString());
static bool unregisterResource(const QString &rccFilename, const QString &resourceRoot=QString());
diff --git a/src/corelib/io/qresource_p.h b/src/corelib/io/qresource_p.h
index dcfe46704c..7451de8809 100644
--- a/src/corelib/io/qresource_p.h
+++ b/src/corelib/io/qresource_p.h
@@ -64,49 +64,49 @@ public:
explicit QResourceFileEngine(const QString &path);
~QResourceFileEngine();
- virtual void setFileName(const QString &file) override;
+ void setFileName(const QString &file) override;
- virtual bool open(QIODevice::OpenMode flags) override ;
- virtual bool close() override;
- virtual bool flush() override;
- virtual qint64 size() const override;
- virtual qint64 pos() const override;
+ bool open(QIODevice::OpenMode flags) override;
+ bool close() override;
+ bool flush() override;
+ qint64 size() const override;
+ qint64 pos() const override;
virtual bool atEnd() const;
- virtual bool seek(qint64) override;
- virtual qint64 read(char *data, qint64 maxlen) override;
- virtual qint64 write(const char *data, qint64 len) override;
+ bool seek(qint64) override;
+ qint64 read(char *data, qint64 maxlen) override;
+ qint64 write(const char *data, qint64 len) override;
- virtual bool remove() override;
- virtual bool copy(const QString &newName) override;
- virtual bool rename(const QString &newName) override;
- virtual bool link(const QString &newName) override;
+ bool remove() override;
+ bool copy(const QString &newName) override;
+ bool rename(const QString &newName) override;
+ bool link(const QString &newName) override;
- virtual bool isSequential() const override;
+ bool isSequential() const override;
- virtual bool isRelativePath() const override;
+ bool isRelativePath() const override;
- virtual bool mkdir(const QString &dirName, bool createParentDirectories) const override;
- virtual bool rmdir(const QString &dirName, bool recurseParentDirectories) const override;
+ bool mkdir(const QString &dirName, bool createParentDirectories) const override;
+ bool rmdir(const QString &dirName, bool recurseParentDirectories) const override;
- virtual bool setSize(qint64 size) override;
+ bool setSize(qint64 size) override;
- virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const override;
+ QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const override;
- virtual bool caseSensitive() const override;
+ bool caseSensitive() const override;
- virtual FileFlags fileFlags(FileFlags type) const override;
+ FileFlags fileFlags(FileFlags type) const override;
- virtual bool setPermissions(uint perms) override;
+ bool setPermissions(uint perms) override;
- virtual QString fileName(QAbstractFileEngine::FileName file) const override;
+ QString fileName(QAbstractFileEngine::FileName file) const override;
- virtual uint ownerId(FileOwner) const override;
- virtual QString owner(FileOwner) const override;
+ uint ownerId(FileOwner) const override;
+ QString owner(FileOwner) const override;
- virtual QDateTime fileTime(FileTime time) const override;
+ QDateTime fileTime(FileTime time) const override;
- virtual Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override;
- virtual Iterator *endEntryList() override;
+ Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override;
+ Iterator *endEntryList() override;
bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0) override;
bool supportsExtension(Extension extension) const override;
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index ed61c4aca0..f14229896f 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -62,8 +62,8 @@
#include "qrect.h"
#endif // !QT_NO_GEOM_VARIANT
-#ifndef QT_NO_QOBJECT
-#include "qcoreapplication.h"
+#ifndef QT_BUILD_QMAKE
+# include "qcoreapplication.h"
#endif
#ifndef QT_BOOTSTRAPPED
@@ -2667,9 +2667,10 @@ QSettings::QSettings(const QString &fileName, Format format, QObject *parent)
called, the QSettings object will not be able to read or write
any settings, and status() will return AccessError.
- On \macos and iOS, if both a name and an Internet domain are specified
- for the organization, the domain is preferred over the name. On
- other platforms, the name is preferred over the domain.
+ You should supply both the domain (used by default on \macos and iOS) and
+ the name (used by default elsewhere), although the code will cope if you
+ supply only one, which will then be used (on all platforms), at odds with
+ the usual naming of the file on platforms for which it isn't the default.
\sa QCoreApplication::setOrganizationName(),
QCoreApplication::setOrganizationDomain(),
@@ -2677,8 +2678,21 @@ QSettings::QSettings(const QString &fileName, Format format, QObject *parent)
setDefaultFormat()
*/
QSettings::QSettings(QObject *parent)
- : QObject(*QSettingsPrivate::create(globalDefaultFormat, UserScope,
-#ifdef Q_OS_MAC
+ : QSettings(UserScope, parent)
+{
+}
+
+/*!
+ \since 5.13
+
+ Constructs a QSettings object in the same way as
+ QSettings(QObject *parent) but with the given \a scope.
+
+ \sa QSettings(QObject *parent)
+*/
+QSettings::QSettings(Scope scope, QObject *parent)
+ : QObject(*QSettingsPrivate::create(globalDefaultFormat, scope,
+#ifdef Q_OS_DARWIN
QCoreApplication::organizationDomain().isEmpty()
? QCoreApplication::organizationName()
: QCoreApplication::organizationDomain()
@@ -2717,6 +2731,25 @@ QSettings::QSettings(const QString &fileName, Format format)
{
d_ptr->q_ptr = this;
}
+
+# ifndef QT_BUILD_QMAKE
+QSettings::QSettings(Scope scope)
+ : d_ptr(QSettingsPrivate::create(globalDefaultFormat, scope,
+# ifdef Q_OS_DARWIN
+ QCoreApplication::organizationDomain().isEmpty()
+ ? QCoreApplication::organizationName()
+ : QCoreApplication::organizationDomain()
+# else
+ QCoreApplication::organizationName().isEmpty()
+ ? QCoreApplication::organizationDomain()
+ : QCoreApplication::organizationName()
+# endif
+ , QCoreApplication::applicationName())
+ )
+{
+ d_ptr->q_ptr = this;
+}
+# endif
#endif
/*!
@@ -3417,6 +3450,7 @@ QSettings::Format QSettings::defaultFormat()
return globalDefaultFormat;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -3450,7 +3484,7 @@ void QSettings::setUserIniPath(const QString &dir)
setPath(NativeFormat, UserScope, dir);
#endif
}
-
+#endif
/*!
\since 4.1
diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h
index 7a9eebe11b..07c746d043 100644
--- a/src/corelib/io/qsettings.h
+++ b/src/corelib/io/qsettings.h
@@ -129,6 +129,7 @@ public:
const QString &application = QString(), QObject *parent = nullptr);
QSettings(const QString &fileName, Format format, QObject *parent = nullptr);
explicit QSettings(QObject *parent = nullptr);
+ explicit QSettings(Scope scope, QObject *parent = nullptr);
#else
explicit QSettings(const QString &organization,
const QString &application = QString());
@@ -137,6 +138,9 @@ public:
QSettings(Format format, Scope scope, const QString &organization,
const QString &application = QString());
QSettings(const QString &fileName, Format format);
+# ifndef QT_BUILD_QMAKE
+ explicit QSettings(Scope scope = UserScope);
+# endif
#endif
~QSettings();
@@ -183,8 +187,12 @@ public:
static void setDefaultFormat(Format format);
static Format defaultFormat();
- static void setSystemIniPath(const QString &dir); // ### Qt 6: remove (use setPath() instead)
- static void setUserIniPath(const QString &dir); // ### Qt 6: remove (use setPath() instead)
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QSettings::setPath() instead")
+ static void setSystemIniPath(const QString &dir);
+ QT_DEPRECATED_X("Use QSettings::setPath() instead")
+ static void setUserIniPath(const QString &dir);
+#endif
static void setPath(Format format, Scope scope, const QString &path);
typedef QMap<QString, QVariant> SettingsMap;
diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp
index 0667d170c7..83108e4387 100644
--- a/src/corelib/io/qstandardpaths_android.cpp
+++ b/src/corelib/io/qstandardpaths_android.cpp
@@ -239,10 +239,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case QStandardPaths::PicturesLocation:
return getExternalStoragePublicDirectory("DIRECTORY_PICTURES");
case QStandardPaths::DocumentsLocation:
- if (QtAndroidPrivate::androidSdkVersion() > 18)
- return getExternalStoragePublicDirectory("DIRECTORY_DOCUMENTS");
- else
- return getExternalStorageDirectory() + QLatin1String("/Documents");
+ return getExternalStoragePublicDirectory("DIRECTORY_DOCUMENTS");
case QStandardPaths::DownloadLocation:
return getExternalStoragePublicDirectory("DIRECTORY_DOWNLOADS");
case QStandardPaths::GenericConfigLocation:
@@ -295,13 +292,8 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
}
if (type == DocumentsLocation) {
- if (QtAndroidPrivate::androidSdkVersion() > 18) {
- return QStringList() << writableLocation(type)
- << getExternalFilesDir("DIRECTORY_DOCUMENTS");
- } else {
- return QStringList() << writableLocation(type)
- << getExternalFilesDir() + QLatin1String("/Documents");
- }
+ return QStringList() << writableLocation(type)
+ << getExternalFilesDir("DIRECTORY_DOCUMENTS");
}
if (type == DownloadLocation) {
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index 748ce67dac..eaa545b4fd 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -134,7 +134,9 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return QString();
}
}
+#ifndef Q_OS_WASM
qWarning("QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '%s'", qPrintable(xdgRuntimeDir));
+#endif
} else {
fileInfo.setFile(xdgRuntimeDir);
if (!fileInfo.exists()) {
diff --git a/src/corelib/io/qt_attribution.json b/src/corelib/io/qt_attribution.json
index e9eb9c85e4..9b7dcc6b54 100644
--- a/src/corelib/io/qt_attribution.json
+++ b/src/corelib/io/qt_attribution.json
@@ -2,7 +2,7 @@
"Id": "psl",
"Name": "The Public Suffix List",
"QDocModule": "qtcore",
- "Description": "The Public Suffix List is an initiative of the Mozilla Project,
+ "Description": "The Public Suffix List is an initiative of Mozilla,
but is maintained as a community resource. It is available for use in any software,
but was originally created to meet the needs of browser manufacturers.
It allows browsers to, for example:
@@ -14,11 +14,13 @@ It allows browsers to, for example:
- Accurately sort history entries by site",
"Files": "qurltlds_p.h",
- "QtUsage": "Used in Qt Core to avoid \"supercookies\" being set in the cookie jar
+ "QtUsage": "See util/corelib/qurl-generateTLDs/ for code-generator",
+ "QtUsage": "Used in Qt Core to avoid setting \"supercookies\" in the cookie jar
supported by Qt (by the QNetworkCookieJar class).",
+ "Homepage": "Consult https://github.com/publicsuffix/list for the sha1 but download from ...",
"Homepage": "http://publicsuffix.org/",
- "Version": "Generated on 2018-01-04",
+ "Version": "d6331e2b65fffbe9fe299dae1689db8de8fd6190, fetched on 2019-02-20",
"License": "Mozilla Public License 2.0",
"LicenseFile": "PSL-LICENSE.txt",
"LicenseId": "MPL-2.0",
diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp
index 97e7b8a4eb..10c3f836c8 100644
--- a/src/corelib/io/qurlquery.cpp
+++ b/src/corelib/io/qurlquery.cpp
@@ -145,6 +145,14 @@ QT_BEGIN_NAMESPACE
\since 5.2
*/
+/*!
+ \fn QUrlQuery(std::initializer_list<QPair<QString, QString>> list)
+
+ \since 5.13
+
+ Constructs a QUrlQuery object from the \a list of key/value pair.
+*/
+
typedef QList<QPair<QString, QString> > Map;
class QUrlQueryPrivate : public QSharedData
diff --git a/src/corelib/io/qurlquery.h b/src/corelib/io/qurlquery.h
index 092d002543..e3688aae2c 100644
--- a/src/corelib/io/qurlquery.h
+++ b/src/corelib/io/qurlquery.h
@@ -48,6 +48,8 @@
#include <QtCore/qstringlist.h>
#endif
+#include <initializer_list>
+
QT_BEGIN_NAMESPACE
Q_CORE_EXPORT uint qHash(const QUrlQuery &key, uint seed = 0) Q_DECL_NOTHROW;
@@ -59,6 +61,13 @@ public:
QUrlQuery();
explicit QUrlQuery(const QUrl &url);
explicit QUrlQuery(const QString &queryString);
+ QUrlQuery(std::initializer_list<QPair<QString, QString>> list)
+ : QUrlQuery()
+ {
+ for (const QPair<QString, QString> &item : list)
+ addQueryItem(item.first, item.second);
+ }
+
QUrlQuery(const QUrlQuery &other);
QUrlQuery &operator=(const QUrlQuery &other);
#ifdef Q_COMPILER_RVALUE_REFS
diff --git a/src/corelib/io/qurltlds_p.h b/src/corelib/io/qurltlds_p.h
index 5453644225..043e84e5ab 100644
--- a/src/corelib/io/qurltlds_p.h
+++ b/src/corelib/io/qurltlds_p.h
@@ -1,7 +1,7 @@
-// Version: MPL 1.1/GPL 2.0/LGPL 2.1
+// License: MPL 2.0/GPL 2.0/LGPL 3
//
// The contents of this file are subject to the Mozilla Public License Version
-// 1.1 (the "License"); you may not use this file except in compliance with
+// 2.0 (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
@@ -59,14106 +59,14139 @@ QT_BEGIN_NAMESPACE
// note to maintainer:
// this file should be updated before each release ->
// for instructions see the program at
-// util/corelib/qurl-generateTLDs
+// util/corelib/qurl-generateTLDs/
-static const quint16 tldCount = 8621;
+static const quint16 tldCount = 8666;
static const quint32 tldIndices[] = {
0,
-0,
-26,
-26,
-26,
-26,
-40,
-40,
-54,
-54,
-54,
-59,
+7,
+24,
+31,
+58,
65,
-75,
-75,
-109,
-117,
-132,
-149,
-149,
-149,
-159,
-166,
-193,
-193,
-235,
-235,
-235,
-241,
-276,
-282,
-287,
-309,
-339,
-349,
-349,
-390,
-402,
-420,
-452,
-468,
-489,
-489,
-503,
-508,
-531,
-551,
-551,
-574,
-605,
-605,
-605,
-615,
-615,
-615,
-633,
-655,
-661,
-661,
-684,
-702,
-714,
-736,
+79,
+103,
+137,
+137,
+158,
+194,
+220,
+255,
+255,
+298,
+298,
+298,
+298,
+298,
+311,
+311,
+311,
+311,
+323,
+359,
+383,
+383,
+400,
+400,
+421,
+421,
+441,
+441,
+448,
+490,
+490,
+497,
+502,
+520,
+542,
+549,
+597,
+611,
+611,
+635,
+642,
+649,
+668,
+683,
+683,
+683,
+700,
+705,
+712,
+724,
+724,
+740,
765,
765,
776,
-794,
-826,
-847,
-866,
-866,
-882,
-895,
-901,
-960,
-994,
-994,
-1012,
-1012,
-1012,
-1032,
-1048,
-1048,
-1068,
-1090,
-1090,
-1090,
-1101,
-1114,
-1114,
-1133,
-1133,
-1140,
-1140,
-1147,
-1147,
-1156,
-1163,
-1163,
-1163,
-1173,
-1185,
-1185,
-1201,
-1201,
-1208,
-1225,
-1230,
-1285,
-1316,
-1374,
-1394,
-1417,
-1417,
-1417,
-1424,
-1438,
-1476,
-1532,
-1549,
-1556,
-1563,
-1570,
-1590,
-1590,
-1597,
-1604,
-1617,
-1617,
-1629,
-1629,
-1641,
-1648,
-1662,
-1662,
-1680,
-1706,
-1722,
+787,
+802,
+810,
+820,
+841,
+848,
+848,
+858,
+858,
+864,
+871,
+871,
+871,
+881,
+898,
+930,
+958,
+972,
+985,
+999,
+1006,
+1013,
+1030,
+1056,
+1063,
+1086,
+1086,
+1086,
+1093,
+1100,
+1107,
+1117,
+1117,
+1117,
+1117,
+1128,
+1153,
+1153,
+1180,
+1186,
+1186,
+1193,
+1221,
+1239,
+1239,
+1252,
+1279,
+1286,
+1286,
+1293,
+1307,
+1325,
+1348,
+1348,
+1348,
+1355,
+1355,
+1355,
+1355,
+1373,
+1395,
+1395,
+1413,
+1440,
+1440,
+1440,
+1440,
+1447,
+1457,
+1464,
+1498,
+1498,
+1498,
+1572,
+1606,
+1613,
+1613,
+1613,
+1620,
+1625,
+1632,
+1651,
+1658,
+1672,
+1688,
+1704,
+1712,
+1712,
1729,
-1745,
-1745,
+1751,
1757,
-1779,
-1779,
-1786,
-1835,
-1848,
+1771,
+1787,
+1831,
+1831,
+1831,
+1831,
1848,
-1875,
-1895,
-1895,
-1923,
-1943,
-1943,
-1950,
-2004,
-2023,
-2023,
-2030,
-2051,
-2068,
-2083,
-2100,
+1919,
+1926,
+1926,
+1926,
+1949,
+1961,
+1961,
+1981,
+2001,
+2001,
+2001,
+2009,
+2028,
+2028,
+2035,
+2054,
+2054,
+2077,
2107,
-2142,
-2155,
-2155,
-2155,
-2162,
-2174,
-2174,
-2174,
+2121,
+2137,
+2157,
2196,
2196,
-2218,
-2254,
-2281,
-2287,
-2303,
-2313,
-2313,
-2313,
-2333,
-2354,
-2367,
-2367,
-2367,
-2420,
-2442,
-2460,
-2483,
-2494,
-2513,
-2521,
-2521,
-2538,
-2545,
-2555,
-2583,
-2610,
-2610,
-2617,
-2631,
-2638,
+2217,
+2235,
+2235,
+2243,
+2243,
+2259,
+2259,
+2283,
+2290,
+2290,
+2316,
+2329,
+2356,
+2356,
+2356,
+2356,
+2356,
+2393,
+2414,
+2428,
+2428,
+2440,
+2481,
+2487,
+2487,
+2487,
+2507,
+2507,
+2507,
+2546,
+2562,
+2562,
+2580,
+2607,
+2614,
+2626,
+2649,
2649,
-2661,
-2661,
-2668,
-2699,
-2705,
-2705,
-2705,
-2712,
+2665,
+2675,
+2682,
2721,
+2731,
2737,
-2749,
-2768,
-2775,
-2792,
-2815,
-2825,
-2841,
-2841,
-2868,
-2868,
-2905,
-2905,
-2934,
-2957,
-2957,
-2975,
-3005,
-3012,
-3037,
-3046,
-3046,
-3053,
-3053,
-3066,
-3073,
-3083,
-3083,
-3105,
-3123,
-3123,
-3181,
-3226,
-3245,
-3245,
-3301,
-3323,
-3332,
-3360,
-3370,
-3370,
-3370,
-3380,
-3380,
-3387,
-3387,
-3394,
-3394,
-3394,
-3402,
-3409,
-3416,
-3431,
-3448,
+2765,
+2770,
+2770,
+2803,
+2803,
+2813,
+2833,
+2855,
+2855,
+2855,
+2863,
+2863,
+2863,
+2880,
+2888,
+2896,
+2896,
+2903,
+2903,
+2910,
+2910,
+2928,
+2928,
+2935,
+2999,
+2999,
+3031,
+3031,
+3050,
+3100,
+3141,
+3141,
+3141,
+3147,
+3185,
+3185,
+3197,
+3197,
+3234,
+3241,
+3248,
+3257,
+3272,
+3272,
+3272,
+3309,
+3328,
+3328,
+3346,
+3356,
+3356,
+3356,
+3356,
+3364,
+3392,
+3392,
+3413,
+3441,
+3465,
+3465,
+3465,
+3465,
+3482,
+3482,
+3487,
+3487,
+3487,
+3487,
+3487,
+3497,
+3497,
+3510,
+3510,
+3519,
+3519,
3519,
-3543,
-3569,
-3607,
-3607,
-3613,
-3625,
-3625,
-3682,
-3689,
-3696,
-3734,
-3750,
-3750,
-3760,
-3760,
-3769,
-3786,
-3786,
-3786,
-3793,
-3809,
-3816,
-3822,
-3829,
-3829,
-3836,
-3852,
-3852,
-3867,
-3874,
-3892,
-3892,
-3902,
-3935,
-3960,
-3980,
-4005,
-4019,
-4032,
-4059,
-4089,
-4089,
-4122,
-4122,
-4151,
-4151,
-4151,
-4151,
-4158,
-4158,
-4158,
-4158,
-4158,
-4158,
-4158,
-4173,
-4191,
-4200,
-4200,
-4224,
-4232,
-4265,
-4281,
-4288,
-4309,
-4348,
-4370,
-4377,
-4396,
-4396,
-4403,
-4403,
-4419,
-4439,
-4446,
-4462,
-4469,
-4469,
-4469,
-4476,
-4483,
-4511,
-4518,
+3519,
+3519,
+3519,
+3530,
+3530,
+3541,
+3568,
+3568,
+3568,
+3586,
+3586,
+3606,
+3627,
+3637,
+3637,
+3645,
+3667,
+3667,
+3708,
+3721,
+3740,
+3762,
+3762,
+3762,
+3762,
+3762,
+3762,
+3775,
+3775,
+3790,
+3812,
+3812,
+3818,
+3818,
+3834,
+3845,
+3881,
+3904,
+3904,
+3910,
+3937,
+3937,
+3937,
+3943,
+3950,
+3950,
+3969,
+3999,
+4017,
+4017,
+4017,
+4017,
+4033,
+4033,
+4033,
+4033,
+4098,
+4135,
+4159,
+4159,
+4159,
+4159,
+4159,
+4169,
+4189,
+4205,
+4239,
+4261,
+4261,
+4261,
+4261,
+4261,
+4261,
+4278,
+4278,
+4293,
+4308,
+4317,
+4336,
+4343,
+4371,
+4371,
+4376,
+4376,
+4376,
+4399,
+4409,
+4424,
+4451,
+4473,
+4473,
+4473,
+4489,
+4489,
+4526,
+4532,
+4532,
4538,
-4563,
-4580,
-4580,
-4587,
-4608,
-4608,
-4624,
-4640,
-4664,
-4664,
-4664,
-4680,
-4690,
-4699,
-4707,
-4707,
-4707,
-4717,
-4717,
-4741,
-4741,
-4741,
-4741,
-4766,
-4778,
-4778,
-4794,
-4801,
-4834,
-4854,
-4867,
-4874,
-4874,
-4888,
-4888,
-4888,
-4936,
-4942,
-4963,
-5001,
-5008,
-5008,
-5008,
-5008,
-5008,
-5017,
-5024,
-5062,
-5069,
-5074,
-5095,
-5139,
-5146,
-5156,
-5175,
-5182,
-5193,
+4570,
+4570,
+4570,
+4613,
+4632,
+4643,
+4688,
+4688,
+4726,
+4771,
+4783,
+4799,
+4799,
+4865,
+4865,
+4865,
+4885,
+4909,
+4909,
+4926,
+4926,
+4956,
+4994,
+5010,
+5010,
+5020,
+5041,
+5056,
+5075,
+5092,
+5122,
+5122,
+5122,
+5122,
+5130,
+5157,
+5164,
+5177,
+5194,
5200,
-5212,
-5225,
-5238,
-5261,
-5268,
-5298,
-5298,
-5305,
-5305,
-5315,
-5315,
-5329,
-5329,
-5349,
-5363,
-5363,
-5399,
-5399,
-5418,
-5445,
-5466,
+5200,
+5211,
+5224,
+5241,
+5241,
+5273,
+5273,
+5273,
+5294,
+5294,
+5294,
+5343,
+5343,
+5350,
+5386,
+5396,
+5403,
+5417,
+5449,
+5463,
+5463,
+5480,
5490,
-5505,
-5505,
-5505,
-5530,
-5530,
-5546,
-5546,
-5582,
-5610,
-5610,
-5634,
-5676,
-5676,
-5722,
-5735,
-5774,
-5774,
-5828,
-5828,
-5828,
-5828,
-5851,
-5881,
-5894,
-5894,
-5901,
-5901,
-5906,
-5906,
-5937,
+5541,
+5591,
+5597,
+5604,
+5604,
+5625,
+5639,
+5649,
+5649,
+5649,
+5666,
+5685,
+5705,
+5705,
+5705,
+5723,
+5772,
+5783,
+5790,
+5804,
+5837,
+5878,
+5915,
+5915,
+5915,
5937,
-5950,
-5950,
-5950,
-5956,
-5956,
-5956,
-5998,
-5998,
-6030,
-6055,
-6074,
-6090,
-6090,
-6103,
-6103,
-6155,
-6177,
+5984,
+5989,
+5989,
+5989,
+6006,
+6051,
+6051,
+6073,
+6080,
+6080,
+6089,
+6100,
+6149,
+6164,
+6169,
6207,
-6207,
-6214,
6214,
-6226,
-6244,
-6266,
-6303,
+6242,
+6278,
+6284,
+6290,
6303,
-6330,
-6330,
-6344,
-6360,
-6387,
-6410,
-6410,
-6410,
-6410,
-6438,
-6451,
-6451,
-6451,
-6465,
-6477,
-6477,
+6326,
+6383,
+6399,
+6416,
+6416,
+6437,
+6444,
+6457,
+6463,
+6463,
6477,
-6484,
-6500,
-6500,
-6519,
-6519,
-6530,
-6548,
-6567,
-6567,
-6567,
-6586,
-6604,
+6520,
+6535,
+6555,
+6555,
+6555,
+6555,
+6603,
6652,
6652,
-6672,
-6683,
-6716,
-6716,
-6727,
-6727,
-6727,
-6727,
-6727,
-6747,
-6747,
-6781,
-6781,
-6791,
-6821,
-6821,
-6827,
-6827,
-6843,
+6670,
+6691,
+6698,
+6698,
+6712,
+6712,
+6719,
+6719,
+6726,
+6739,
+6778,
+6778,
+6797,
+6797,
+6807,
+6807,
+6830,
+6830,
+6842,
+6865,
+6865,
+6865,
6869,
-6877,
-6877,
-6877,
-6877,
-6896,
-6896,
-6903,
-6919,
-6919,
-6919,
-6935,
-6935,
-6935,
-6935,
-6935,
-6935,
-6935,
-6966,
-6983,
-6983,
-6999,
-6999,
-6999,
-7013,
-7022,
-7022,
-7022,
-7022,
-7022,
-7022,
-7070,
-7085,
-7105,
-7105,
-7122,
-7139,
-7148,
-7162,
-7162,
-7172,
-7172,
-7210,
-7210,
-7230,
-7242,
-7242,
-7249,
-7259,
-7259,
-7279,
-7279,
-7294,
-7311,
-7317,
-7353,
-7369,
-7375,
-7395,
-7395,
-7431,
-7496,
-7496,
-7505,
-7505,
-7505,
-7505,
-7511,
-7539,
-7551,
+6875,
+6888,
+6888,
+6888,
+6910,
+6926,
+6933,
+6944,
+6964,
+6980,
+6980,
+7024,
+7024,
+7024,
+7024,
+7036,
+7058,
+7068,
+7068,
+7083,
+7087,
+7109,
+7117,
+7124,
+7143,
+7159,
+7194,
+7194,
+7194,
+7201,
+7208,
+7224,
+7231,
+7262,
+7309,
+7323,
+7352,
+7352,
+7359,
+7366,
+7366,
+7381,
+7381,
+7412,
+7412,
+7449,
+7459,
+7459,
+7487,
+7487,
+7487,
+7487,
+7527,
+7545,
+7559,
+7559,
+7559,
+7559,
+7559,
+7564,
7564,
-7583,
-7595,
-7595,
7595,
-7628,
-7628,
-7628,
-7665,
-7674,
-7686,
-7711,
-7737,
-7755,
-7755,
-7794,
-7805,
-7811,
-7811,
-7831,
-7831,
-7850,
-7850,
-7858,
-7874,
-7879,
-7903,
-7923,
-7958,
-7958,
-7972,
-7987,
-7987,
-7998,
-8008,
-8008,
-8042,
-8042,
-8059,
-8059,
-8076,
-8096,
-8096,
-8096,
-8114,
-8114,
-8132,
-8132,
-8148,
-8163,
-8175,
-8194,
-8194,
-8205,
-8214,
-8218,
-8246,
-8246,
-8246,
-8286,
-8286,
-8286,
-8286,
-8286,
+7602,
+7626,
+7643,
+7655,
+7655,
+7682,
+7701,
+7725,
+7736,
+7751,
+7765,
+7832,
+7852,
+7906,
+7965,
+7965,
+7976,
+7976,
+8024,
+8041,
+8058,
+8071,
+8084,
+8105,
+8105,
+8115,
+8144,
+8160,
+8182,
+8210,
+8216,
+8229,
+8229,
+8234,
+8282,
+8282,
+8282,
+8289,
8305,
8312,
8312,
8312,
8312,
-8335,
-8357,
-8357,
-8366,
-8382,
-8390,
-8394,
-8394,
-8407,
-8414,
-8446,
-8453,
-8466,
-8466,
-8500,
-8500,
-8522,
+8319,
+8363,
+8401,
+8408,
+8415,
+8415,
+8425,
+8454,
+8464,
+8464,
+8482,
+8505,
8542,
-8554,
-8577,
-8588,
-8608,
-8614,
-8621,
-8652,
-8675,
-8675,
-8687,
-8687,
-8712,
-8712,
-8734,
-8744,
-8798,
-8808,
-8827,
-8827,
-8827,
+8542,
+8557,
+8603,
+8629,
+8629,
+8643,
+8643,
+8667,
+8690,
+8690,
+8714,
+8721,
+8721,
+8726,
+8746,
+8766,
+8783,
+8790,
+8804,
+8833,
8840,
-8855,
-8855,
-8880,
-8880,
-8897,
-8897,
-8897,
-8930,
-8968,
-8968,
-8968,
-8968,
-8992,
-9055,
+8863,
+8870,
+8884,
+8934,
+8956,
+8956,
+8956,
+8956,
+8965,
+8991,
+8991,
+8997,
+9007,
+9007,
+9013,
+9031,
+9031,
+9038,
+9059,
+9066,
9073,
-9085,
-9094,
-9116,
+9090,
+9105,
+9109,
9116,
-9145,
-9164,
-9175,
-9187,
-9214,
-9214,
-9226,
-9242,
-9272,
-9291,
-9305,
-9324,
-9324,
-9324,
-9324,
-9331,
-9368,
-9374,
-9393,
-9415,
-9415,
-9415,
-9428,
-9428,
-9434,
-9451,
-9451,
-9451,
-9486,
-9486,
-9486,
-9486,
-9503,
-9503,
-9503,
-9509,
-9509,
-9541,
-9548,
-9548,
-9548,
-9597,
-9597,
-9604,
-9619,
-9646,
-9657,
-9664,
-9701,
-9730,
-9737,
-9743,
-9755,
-9774,
-9795,
-9802,
-9816,
-9816,
-9824,
-9847,
-9865,
-9865,
+9120,
+9120,
+9178,
+9233,
+9241,
+9259,
+9275,
+9275,
+9275,
+9292,
+9299,
+9299,
+9318,
+9332,
+9351,
+9358,
+9400,
+9422,
+9497,
+9513,
+9517,
+9517,
+9530,
+9537,
+9552,
+9592,
+9592,
+9608,
+9627,
+9643,
+9643,
+9643,
+9653,
+9653,
+9683,
+9691,
+9723,
+9733,
+9758,
+9762,
+9762,
+9762,
+9842,
+9842,
+9871,
+9871,
9890,
9904,
9911,
-9931,
-9955,
+9918,
+9932,
+9949,
9969,
-10008,
-10015,
-10032,
-10032,
-10039,
-10046,
-10065,
-10065,
-10113,
-10120,
-10128,
-10135,
-10142,
-10142,
-10167,
-10178,
-10198,
-10232,
-10251,
-10307,
-10325,
-10325,
-10325,
-10332,
-10338,
-10360,
-10372,
-10379,
-10412,
-10443,
-10443,
-10460,
-10468,
-10490,
-10490,
-10500,
-10519,
-10534,
-10541,
-10574,
-10598,
-10633,
-10653,
-10673,
-10694,
-10694,
-10694,
+10000,
+10024,
+10024,
+10055,
+10055,
+10082,
+10098,
+10098,
+10126,
+10126,
+10138,
+10138,
+10147,
+10174,
+10174,
+10174,
+10174,
+10196,
+10203,
+10210,
+10210,
+10210,
+10233,
+10245,
+10252,
+10252,
+10282,
+10289,
+10300,
+10346,
+10369,
+10375,
+10402,
+10402,
+10402,
+10402,
+10423,
+10444,
+10453,
+10473,
+10497,
+10503,
+10513,
+10531,
+10579,
+10595,
+10602,
+10602,
+10602,
+10627,
+10648,
+10659,
+10659,
+10674,
+10674,
+10681,
10706,
10706,
-10715,
-10725,
-10725,
-10736,
-10743,
-10750,
-10782,
-10798,
-10814,
-10833,
-10833,
-10848,
-10858,
-10858,
-10858,
-10863,
+10722,
+10760,
+10760,
+10772,
+10785,
+10785,
+10785,
+10796,
+10815,
+10836,
+10836,
+10844,
10875,
-10900,
-10907,
-10930,
-10961,
-10989,
-11020,
-11068,
-11075,
-11082,
-11114,
-11131,
-11156,
-11176,
-11184,
-11212,
-11218,
-11235,
-11235,
-11247,
-11247,
-11254,
-11265,
-11269,
-11304,
-11311,
-11340,
-11340,
-11354,
-11384,
-11384,
-11409,
-11409,
-11422,
-11439,
-11449,
-11449,
-11462,
-11469,
-11469,
-11477,
-11488,
-11488,
-11502,
-11522,
-11589,
-11628,
-11657,
-11670,
-11670,
+10875,
+10875,
+10875,
+10885,
+10885,
+10892,
+10892,
+10892,
+10892,
+10920,
+10920,
+10963,
+10963,
+10963,
+10970,
+10977,
+11007,
+11007,
+11007,
+11007,
+11007,
+11031,
+11041,
+11051,
+11070,
+11078,
+11078,
+11078,
+11091,
+11101,
+11101,
+11123,
+11129,
+11139,
+11155,
+11191,
+11233,
+11233,
+11233,
+11244,
+11244,
+11256,
+11262,
+11262,
+11262,
+11262,
+11278,
+11285,
+11285,
+11314,
+11335,
+11341,
+11359,
+11359,
+11387,
+11401,
+11408,
+11442,
+11442,
+11463,
+11463,
+11470,
+11492,
+11492,
+11492,
+11492,
+11503,
+11537,
+11547,
+11572,
+11572,
+11591,
+11610,
+11610,
+11618,
+11636,
+11652,
+11652,
+11652,
+11675,
+11675,
+11675,
+11675,
11699,
-11706,
-11723,
-11723,
-11763,
-11763,
-11763,
-11790,
-11825,
-11844,
-11875,
-11875,
-11891,
-11891,
-11898,
-11898,
-11898,
-11898,
-11898,
-11911,
-11911,
-11932,
-11939,
-11939,
-11946,
-11946,
-11957,
-11957,
-11964,
-11988,
-11995,
-12047,
-12110,
-12117,
-12124,
-12131,
-12131,
-12147,
-12173,
-12192,
-12228,
-12235,
-12252,
-12252,
-12284,
-12284,
-12299,
-12299,
-12312,
-12336,
-12343,
-12367,
-12374,
-12400,
-12417,
-12417,
-12437,
-12437,
-12444,
-12479,
-12513,
-12527,
-12541,
-12541,
-12564,
-12607,
-12614,
-12625,
-12632,
-12670,
-12698,
-12739,
-12753,
-12760,
-12791,
-12791,
-12791,
-12791,
-12818,
-12818,
-12818,
-12839,
-12851,
-12851,
-12851,
-12861,
+11710,
+11710,
+11738,
+11748,
+11748,
+11748,
+11768,
+11768,
+11768,
+11768,
+11768,
+11778,
+11778,
+11788,
+11812,
+11820,
+11820,
+11835,
+11852,
+11872,
+11872,
+11929,
+11929,
+11933,
+11952,
+11962,
+11962,
+11979,
+11979,
+11979,
+11992,
+11999,
+12014,
+12014,
+12023,
+12023,
+12023,
+12023,
+12023,
+12023,
+12041,
+12041,
+12066,
+12066,
+12076,
+12076,
+12076,
+12076,
+12087,
+12099,
+12114,
+12137,
+12137,
+12146,
+12166,
+12175,
+12185,
+12201,
+12220,
+12239,
+12253,
+12291,
+12304,
+12304,
+12315,
+12323,
+12342,
+12342,
+12351,
+12357,
+12361,
+12381,
+12381,
+12397,
+12424,
+12452,
+12475,
+12481,
+12481,
+12481,
+12485,
+12502,
+12535,
+12535,
+12552,
+12566,
+12570,
+12601,
+12605,
+12605,
+12611,
+12623,
+12633,
+12633,
+12642,
+12642,
+12642,
+12642,
+12646,
+12656,
+12656,
+12656,
+12656,
+12677,
+12677,
+12714,
+12720,
+12734,
+12734,
+12734,
+12751,
+12774,
+12794,
+12806,
+12806,
+12819,
+12819,
+12819,
+12819,
+12836,
+12836,
+12877,
+12877,
12877,
-12899,
-12899,
-12906,
-12906,
-12918,
-12925,
-12925,
-12925,
-12925,
-12945,
-12949,
-12968,
-12968,
-12980,
-12996,
-12996,
-13003,
-13030,
-13037,
-13044,
-13080,
-13084,
-13137,
-13156,
-13175,
-13197,
-13213,
-13220,
-13227,
-13227,
-13245,
-13245,
-13245,
-13262,
-13277,
-13304,
-13311,
-13311,
-13319,
-13319,
-13319,
-13324,
-13324,
-13324,
-13324,
-13335,
-13342,
-13342,
-13347,
-13378,
-13390,
-13408,
-13413,
-13413,
-13413,
-13420,
+12893,
+12909,
+12936,
+12936,
+12936,
+12936,
+12950,
+12950,
+12950,
+12950,
+12969,
+12974,
+13000,
+13000,
+13028,
+13034,
+13051,
+13051,
+13051,
+13051,
+13051,
+13067,
+13067,
+13071,
+13071,
+13087,
+13113,
+13164,
+13204,
+13204,
+13211,
+13226,
+13226,
+13230,
+13230,
+13260,
+13276,
+13301,
+13332,
+13340,
+13357,
+13357,
+13357,
+13374,
+13397,
+13410,
13433,
-13440,
-13447,
-13466,
-13511,
-13525,
-13537,
-13555,
-13600,
-13600,
-13618,
-13629,
-13636,
-13636,
-13679,
-13686,
-13725,
-13757,
-13757,
-13800,
-13826,
-13836,
-13847,
-13867,
-13867,
-13882,
-13911,
-13925,
-13925,
-13942,
-13954,
-13991,
-14001,
-14016,
-14057,
-14073,
-14095,
-14095,
-14104,
-14118,
-14124,
-14124,
-14130,
-14156,
-14156,
-14179,
-14201,
-14201,
+13445,
+13481,
+13503,
+13532,
+13532,
+13584,
+13602,
+13622,
+13650,
+13675,
+13682,
+13682,
+13701,
+13710,
+13721,
+13721,
+13735,
+13735,
+13771,
+13777,
+13797,
+13817,
+13817,
+13817,
+13837,
+13837,
+13842,
+13861,
+13892,
+13892,
+13937,
+13955,
+13994,
+13994,
+13994,
+14023,
+14035,
+14042,
+14052,
+14052,
+14052,
+14074,
+14074,
+14074,
+14074,
+14074,
+14082,
+14116,
+14123,
+14160,
+14174,
+14191,
+14197,
+14197,
14205,
14205,
-14209,
-14216,
-14224,
-14231,
-14249,
-14253,
+14205,
+14205,
+14205,
+14243,
+14256,
+14256,
+14256,
+14256,
+14256,
+14291,
+14291,
14291,
-14338,
-14366,
+14302,
+14302,
+14316,
+14330,
+14330,
14370,
-14375,
-14407,
-14427,
-14427,
-14434,
-14447,
-14463,
-14473,
-14473,
-14484,
-14484,
-14501,
-14501,
-14501,
-14510,
-14529,
-14543,
-14543,
-14555,
-14559,
-14585,
-14585,
-14601,
-14614,
-14618,
+14370,
+14370,
+14370,
+14387,
+14399,
+14433,
+14441,
+14458,
+14458,
+14458,
+14458,
+14458,
+14458,
+14476,
+14514,
+14527,
+14527,
+14537,
+14560,
+14590,
+14590,
+14590,
+14590,
14622,
-14642,
-14711,
-14711,
-14730,
-14730,
-14730,
-14730,
-14743,
-14764,
-14764,
-14782,
-14817,
-14829,
-14829,
-14829,
-14835,
-14839,
-14839,
-14839,
-14839,
-14851,
-14859,
-14859,
-14888,
-14888,
-14888,
+14622,
+14648,
+14648,
+14648,
+14656,
+14667,
+14687,
+14705,
+14705,
+14705,
+14705,
+14718,
+14733,
+14759,
+14766,
+14795,
+14795,
+14795,
+14795,
+14801,
+14801,
+14824,
+14832,
+14832,
+14832,
+14832,
+14832,
+14848,
+14860,
+14870,
14888,
-14927,
-14939,
-14951,
-14951,
-14971,
+14934,
+14952,
+14959,
+14977,
+14977,
+14994,
+14994,
15007,
15007,
-15018,
-15034,
-15034,
-15045,
+15007,
+15007,
+15017,
15045,
-15067,
-15106,
-15106,
-15141,
-15147,
-15163,
-15195,
-15195,
-15209,
-15209,
-15216,
-15216,
-15224,
-15224,
-15224,
-15243,
-15243,
-15243,
-15253,
-15285,
-15285,
-15306,
-15324,
-15382,
-15403,
-15403,
-15407,
-15407,
-15435,
-15435,
-15468,
-15472,
-15499,
-15516,
-15516,
+15052,
+15062,
+15072,
+15094,
+15101,
+15101,
+15125,
+15125,
+15133,
+15140,
+15164,
+15183,
+15201,
+15201,
+15207,
+15211,
+15228,
+15228,
+15242,
+15251,
+15260,
+15260,
+15266,
+15266,
+15266,
+15290,
+15290,
+15290,
+15290,
+15303,
+15317,
+15317,
+15317,
+15323,
+15323,
+15330,
+15343,
+15383,
+15390,
+15390,
+15397,
+15397,
+15397,
+15412,
+15420,
+15427,
+15451,
+15467,
+15467,
+15503,
+15509,
15528,
-15533,
-15533,
-15538,
-15538,
-15550,
-15568,
-15579,
-15603,
+15528,
+15537,
+15537,
+15537,
+15542,
+15542,
+15542,
+15558,
+15558,
+15558,
+15580,
+15580,
+15580,
15603,
-15611,
-15621,
-15621,
-15621,
-15621,
-15631,
-15647,
-15655,
-15655,
-15655,
-15655,
-15655,
-15707,
-15707,
-15713,
-15713,
-15733,
-15774,
-15774,
-15784,
-15784,
-15784,
-15784,
-15784,
-15795,
-15795,
-15800,
-15800,
-15800,
-15825,
-15825,
-15825,
-15857,
-15884,
-15884,
-15884,
-15884,
-15884,
-15903,
-15922,
-15937,
-15937,
+15615,
+15615,
+15615,
+15657,
+15690,
+15712,
+15741,
+15741,
+15757,
+15757,
+15792,
+15792,
+15819,
+15819,
+15839,
+15860,
+15867,
+15874,
+15888,
+15888,
+15900,
+15913,
+15927,
+15938,
+15938,
+15956,
+15971,
+15993,
+15993,
+15993,
+15993,
15997,
-16004,
-16019,
-16065,
-16065,
-16065,
-16086,
-16100,
-16112,
-16112,
-16129,
-16138,
-16138,
-16138,
-16153,
-16169,
+16020,
+16020,
+16033,
+16033,
+16033,
+16069,
+16069,
+16097,
+16109,
+16109,
+16109,
+16145,
+16145,
+16145,
16186,
-16186,
-16228,
-16228,
-16228,
-16259,
-16270,
-16306,
-16316,
-16322,
-16322,
-16383,
-16393,
-16393,
-16423,
-16423,
-16423,
-16433,
-16448,
-16448,
-16472,
-16472,
-16477,
-16487,
-16528,
-16537,
-16547,
-16552,
-16574,
+16230,
+16250,
+16269,
+16276,
+16283,
+16295,
+16329,
+16359,
+16391,
+16404,
+16404,
+16453,
+16470,
+16480,
+16480,
+16480,
+16499,
+16512,
+16530,
+16530,
+16541,
+16541,
+16563,
16579,
+16586,
16596,
-16603,
-16651,
-16686,
-16686,
-16686,
-16703,
-16703,
-16753,
-16753,
-16753,
-16767,
-16767,
+16618,
+16633,
+16665,
+16665,
+16690,
+16721,
+16733,
+16733,
+16740,
+16762,
+16762,
+16762,
+16762,
+16762,
+16762,
+16762,
+16762,
+16777,
+16777,
16784,
-16825,
-16832,
-16843,
-16843,
+16812,
+16830,
16851,
-16862,
-16879,
-16898,
-16898,
-16917,
-16917,
-16924,
-16932,
-16970,
-17008,
-17016,
-17034,
-17034,
-17034,
-17034,
-17063,
-17098,
-17127,
-17142,
-17142,
-17160,
-17160,
-17160,
-17160,
-17186,
-17213,
-17240,
-17254,
-17259,
-17259,
-17259,
+16870,
+16870,
+16901,
+16908,
+16908,
+16908,
+16929,
+16953,
+16953,
+16959,
+16959,
+16986,
+16986,
+16986,
+16996,
+16996,
+16996,
+16996,
+17010,
+17030,
+17050,
+17057,
+17057,
+17057,
+17057,
+17066,
+17076,
+17093,
+17093,
+17122,
+17122,
+17138,
+17138,
+17157,
+17164,
+17179,
+17179,
+17198,
+17198,
+17218,
+17236,
+17236,
+17266,
+17283,
+17294,
17294,
-17350,
-17376,
-17414,
-17443,
-17459,
-17459,
-17477,
-17482,
-17495,
-17508,
-17508,
-17515,
-17521,
-17544,
-17544,
-17544,
-17544,
-17550,
-17573,
-17580,
-17587,
-17631,
-17673,
-17673,
-17691,
-17733,
-17743,
-17762,
-17762,
-17771,
-17771,
-17771,
-17780,
-17807,
-17807,
-17840,
-17847,
-17847,
-17855,
-17867,
-17883,
-17900,
-17900,
-17924,
-17964,
-17964,
-17970,
-17970,
-17998,
-18006,
-18006,
-18006,
-18006,
-18006,
-18035,
-18084,
-18110,
-18110,
-18127,
-18135,
-18167,
-18167,
-18203,
-18203,
-18208,
-18208,
-18238,
-18238,
-18255,
-18267,
-18267,
-18298,
-18314,
-18344,
-18344,
-18352,
-18352,
-18352,
-18352,
-18392,
-18398,
-18437,
-18437,
-18449,
-18463,
-18497,
-18497,
-18546,
-18553,
-18566,
-18616,
-18647,
-18647,
-18663,
-18663,
-18663,
-18696,
-18730,
-18749,
-18749,
-18759,
-18771,
-18771,
+17294,
+17311,
+17321,
+17336,
+17336,
+17336,
+17336,
+17336,
+17347,
+17353,
+17353,
+17353,
+17353,
+17361,
+17361,
+17361,
+17361,
+17374,
+17374,
+17374,
+17388,
+17388,
+17388,
+17395,
+17411,
+17411,
+17411,
+17428,
+17440,
+17457,
+17471,
+17492,
+17492,
+17529,
+17533,
+17546,
+17546,
+17558,
+17566,
+17566,
+17566,
+17578,
+17604,
+17620,
+17650,
+17650,
+17669,
+17695,
+17695,
+17741,
+17741,
+17741,
+17769,
+17774,
+17774,
+17779,
+17785,
+17795,
+17795,
+17803,
+17819,
+17859,
+17859,
+17916,
+17916,
+17955,
+17963,
+17977,
+17977,
+18009,
+18009,
+18021,
+18044,
+18044,
+18044,
+18044,
+18044,
+18044,
+18064,
+18079,
+18079,
+18096,
+18096,
+18132,
+18138,
+18138,
+18171,
+18171,
+18171,
+18171,
+18177,
+18200,
+18220,
+18220,
+18220,
+18234,
+18234,
+18234,
+18270,
+18286,
+18332,
+18343,
+18343,
+18348,
+18367,
+18409,
+18464,
+18486,
+18493,
+18544,
+18544,
+18544,
+18550,
+18575,
+18580,
+18634,
+18646,
+18672,
+18695,
+18695,
+18695,
+18713,
+18744,
+18762,
+18762,
+18770,
+18770,
+18777,
+18781,
18785,
18785,
18785,
18785,
-18803,
-18803,
-18803,
-18803,
-18803,
-18826,
-18832,
-18832,
-18861,
-18861,
-18870,
-18887,
-18897,
+18791,
+18839,
+18850,
+18864,
+18864,
+18881,
+18881,
18897,
-18903,
+18912,
+18919,
18926,
-18933,
-18933,
-18941,
-18957,
-18983,
-19025,
-19034,
-19034,
-19055,
-19122,
-19122,
-19152,
+18944,
+18944,
+18944,
+18951,
+18951,
+18958,
+18969,
+18994,
+19010,
+19054,
+19054,
+19086,
+19097,
+19115,
+19129,
+19129,
19152,
-19163,
-19163,
-19198,
-19198,
-19198,
-19198,
-19198,
-19210,
-19218,
-19238,
-19238,
+19183,
+19189,
+19226,
+19226,
+19226,
+19226,
+19236,
+19260,
19266,
-19274,
-19303,
-19317,
-19317,
-19329,
-19329,
-19329,
-19329,
-19355,
-19355,
-19410,
-19410,
-19410,
-19433,
-19450,
-19450,
-19450,
-19463,
-19463,
-19490,
-19524,
-19531,
-19558,
-19597,
-19609,
-19609,
+19273,
+19291,
+19298,
+19298,
+19298,
+19335,
+19352,
+19352,
+19363,
+19383,
+19383,
+19399,
+19409,
+19430,
+19430,
+19447,
+19469,
+19485,
+19485,
+19493,
+19499,
+19499,
+19506,
+19506,
+19516,
+19537,
+19549,
+19588,
+19588,
19633,
-19642,
-19642,
-19642,
-19642,
-19658,
-19671,
-19703,
-19710,
-19710,
-19727,
-19741,
-19741,
-19748,
-19748,
-19748,
-19755,
-19791,
-19808,
-19827,
-19835,
-19859,
-19869,
-19869,
+19655,
+19676,
+19676,
+19720,
+19723,
+19739,
+19742,
+19745,
+19768,
+19768,
+19771,
+19788,
+19795,
+19823,
+19843,
+19850,
19869,
-19886,
-19900,
+19893,
19919,
-19931,
-19940,
-19960,
-19974,
-19983,
-20002,
-20002,
-20002,
-20002,
-20011,
-20011,
-20011,
-20018,
-20031,
-20049,
-20049,
-20049,
-20065,
+19936,
+19939,
+19942,
+19963,
+19966,
+19982,
+19995,
+20004,
+20010,
+20010,
+20045,
+20048,
+20062,
+20071,
+20071,
+20074,
20084,
-20139,
-20152,
-20159,
-20177,
-20191,
-20202,
-20202,
-20229,
-20248,
-20248,
-20254,
-20254,
-20265,
-20265,
-20275,
-20275,
-20295,
-20322,
-20322,
-20347,
-20377,
-20377,
-20377,
-20401,
-20412,
-20412,
-20419,
-20419,
-20419,
+20090,
+20108,
+20108,
+20114,
+20120,
+20147,
+20153,
+20156,
+20166,
+20169,
+20184,
+20187,
+20195,
+20210,
+20221,
+20246,
+20246,
+20246,
+20273,
+20293,
+20296,
+20313,
+20331,
+20337,
+20346,
+20362,
+20395,
+20395,
+20423,
+20423,
+20429,
+20429,
20432,
-20455,
-20462,
-20514,
-20514,
-20514,
-20582,
-20588,
-20603,
-20603,
-20603,
-20615,
-20657,
+20443,
+20465,
+20465,
+20468,
+20479,
+20479,
+20497,
+20537,
+20546,
+20558,
+20614,
+20621,
+20639,
+20639,
+20658,
+20661,
+20671,
20674,
-20691,
+20674,
+20674,
+20674,
+20677,
+20677,
+20677,
+20696,
+20699,
+20699,
+20702,
+20702,
20705,
20711,
-20711,
-20711,
+20724,
20727,
-20727,
-20727,
-20747,
-20769,
-20775,
-20775,
-20790,
-20790,
-20807,
-20826,
-20834,
-20843,
-20856,
-20859,
-20862,
-20873,
-20903,
-20926,
-20926,
-20929,
-20948,
-20982,
-21012,
-21012,
-21018,
-21024,
-21046,
-21062,
-21087,
-21117,
-21151,
-21157,
-21160,
-21166,
-21182,
-21193,
+20730,
+20753,
+20763,
+20766,
+20783,
+20783,
+20783,
+20806,
+20809,
+20819,
+20819,
+20822,
+20911,
+20944,
+20961,
+20992,
+21004,
+21014,
+21017,
+21033,
+21036,
+21036,
+21067,
+21074,
+21094,
+21119,
+21162,
+21179,
21204,
-21207,
-21223,
-21223,
-21283,
-21304,
-21310,
-21316,
-21316,
-21358,
-21364,
-21371,
-21377,
-21386,
-21386,
-21389,
-21427,
-21490,
-21493,
-21493,
-21517,
-21539,
-21545,
-21545,
+21230,
+21239,
+21250,
+21256,
+21290,
+21297,
+21297,
+21297,
+21333,
+21333,
+21349,
+21352,
+21378,
+21393,
+21411,
+21414,
+21424,
+21435,
+21438,
+21461,
+21461,
+21489,
+21504,
+21511,
+21511,
+21511,
+21511,
+21516,
+21516,
+21526,
+21529,
+21538,
+21538,
21551,
-21554,
-21592,
-21608,
-21611,
-21617,
-21636,
-21636,
-21646,
-21650,
+21606,
+21609,
+21609,
+21612,
+21634,
21662,
-21688,
-21700,
-21736,
-21739,
-21766,
+21737,
+21737,
+21756,
+21759,
21787,
-21805,
+21808,
+21811,
21814,
-21831,
-21852,
-21871,
-21884,
-21901,
-21901,
-21924,
-21932,
-21932,
-21964,
-21964,
-21967,
-21970,
-21973,
-21973,
-21973,
-22007,
-22026,
-22039,
-22056,
-22063,
-22076,
-22115,
-22152,
-22152,
-22155,
-22179,
-22179,
-22182,
-22185,
-22201,
-22204,
-22237,
-22240,
-22257,
-22257,
+21820,
+21841,
+21860,
+21860,
+21867,
+21875,
+21894,
+21900,
+21921,
+21936,
+21936,
+21945,
+21945,
+21945,
+21986,
+22001,
+22021,
+22027,
+22033,
+22059,
+22080,
+22105,
+22127,
+22130,
+22146,
+22171,
+22174,
+22202,
+22222,
+22244,
+22253,
22285,
-22288,
-22306,
-22306,
-22309,
-22322,
22325,
-22328,
-22331,
-22334,
-22334,
+22347,
22359,
-22366,
-22386,
-22399,
-22414,
-22437,
-22440,
-22450,
-22459,
-22475,
-22485,
-22488,
-22495,
+22371,
+22395,
+22401,
+22404,
+22433,
+22465,
+22465,
+22468,
+22468,
22507,
-22513,
-22513,
-22513,
-22513,
-22518,
-22518,
-22530,
-22533,
-22536,
-22539,
-22556,
-22587,
-22590,
-22605,
-22620,
-22641,
-22644,
-22644,
-22644,
-22674,
-22674,
-22685,
-22716,
-22732,
-22748,
-22748,
-22764,
+22522,
+22546,
+22546,
+22580,
+22580,
+22612,
+22615,
+22622,
+22622,
+22622,
+22634,
+22655,
+22655,
+22687,
+22699,
+22711,
+22711,
+22731,
+22734,
+22740,
22767,
-22783,
-22799,
-22799,
-22799,
-22813,
-22825,
-22838,
-22851,
-22854,
-22854,
-22854,
-22899,
-22918,
-22921,
-22921,
-22924,
-22927,
-22975,
-22978,
-22988,
-22988,
+22795,
+22798,
+22801,
+22822,
+22845,
+22883,
+22883,
+22886,
+22916,
+22919,
+22938,
+22947,
+22947,
+22962,
22994,
22997,
-23004,
-23010,
+23000,
23013,
-23016,
-23016,
-23024,
-23024,
-23035,
-23070,
-23073,
+23026,
+23029,
+23029,
+23032,
+23042,
+23042,
+23069,
+23076,
23087,
-23104,
-23119,
-23150,
-23153,
-23156,
-23173,
-23198,
-23225,
-23241,
-23256,
-23256,
-23259,
-23284,
-23324,
-23340,
-23374,
-23380,
-23383,
-23389,
-23415,
-23421,
-23429,
-23450,
-23453,
-23453,
-23456,
-23456,
-23456,
-23468,
-23485,
-23498,
-23517,
-23529,
-23536,
-23539,
-23553,
-23565,
-23571,
-23571,
-23589,
-23611,
-23611,
-23631,
-23647,
-23670,
-23670,
-23673,
-23700,
-23700,
-23706,
-23709,
-23712,
-23712,
-23715,
-23732,
-23743,
-23746,
-23761,
-23774,
-23777,
-23783,
-23783,
-23800,
-23803,
-23806,
+23094,
+23107,
+23124,
+23142,
+23149,
+23149,
+23152,
+23159,
+23159,
+23181,
+23181,
+23212,
+23219,
+23233,
+23233,
+23255,
+23265,
+23265,
+23279,
+23307,
+23339,
+23349,
+23376,
+23401,
+23451,
+23514,
+23524,
+23552,
+23555,
+23575,
+23591,
+23601,
+23604,
+23620,
+23627,
+23630,
+23640,
+23659,
+23674,
+23714,
+23747,
+23776,
+23786,
+23802,
+23809,
+23812,
23827,
-23827,
-23837,
-23844,
+23863,
+23882,
23882,
-23891,
-23907,
-23914,
-23938,
-23948,
-23948,
-23948,
-23948,
-23948,
-23948,
-23963,
-23963,
-23980,
-23989,
-24003,
-24012,
-24030,
-24036,
-24065,
+23892,
+23917,
+23949,
+23974,
+23974,
+24009,
+24039,
+24039,
+24052,
+24060,
24081,
-24102,
-24102,
-24134,
-24134,
-24137,
-24158,
-24185,
-24255,
+24100,
+24131,
+24131,
+24138,
+24138,
+24148,
+24169,
+24175,
+24233,
+24262,
+24262,
+24265,
+24272,
24278,
-24287,
-24320,
-24333,
-24350,
-24357,
-24399,
-24425,
-24464,
-24467,
-24470,
-24470,
-24470,
-24488,
-24491,
-24497,
-24500,
-24506,
-24529,
-24535,
-24563,
-24576,
-24579,
-24582,
+24300,
+24321,
+24332,
+24339,
+24349,
+24349,
+24349,
+24353,
+24370,
+24370,
+24370,
+24373,
+24376,
+24405,
+24405,
+24414,
+24454,
+24461,
+24461,
+24461,
+24461,
+24484,
+24504,
+24511,
+24543,
+24558,
+24558,
+24558,
+24571,
+24584,
24591,
-24594,
-24614,
-24614,
-24617,
-24620,
-24620,
-24623,
-24629,
-24647,
-24669,
-24669,
-24669,
-24711,
-24734,
-24753,
-24758,
-24781,
-24781,
-24805,
-24828,
-24871,
-24895,
-24895,
-24911,
-24911,
-24942,
-24952,
-24984,
-25004,
-25016,
-25029,
-25036,
-25039,
-25039,
-25039,
-25061,
-25061,
-25067,
-25094,
-25118,
-25121,
-25121,
-25121,
-25126,
-25126,
+24619,
+24626,
+24626,
+24678,
+24703,
+24714,
+24729,
+24757,
+24765,
+24769,
+24794,
+24794,
+24827,
+24827,
+24827,
+24834,
+24834,
+24834,
+24834,
+24834,
+24834,
+24852,
+24894,
+24912,
+24919,
+24919,
+24919,
+24922,
+24932,
+24966,
+24982,
+25019,
+25044,
+25059,
+25081,
+25096,
25145,
25145,
-25145,
-25145,
-25145,
-25176,
-25196,
+25162,
+25168,
+25188,
+25188,
+25188,
+25200,
+25200,
25218,
-25259,
-25259,
-25259,
-25259,
-25259,
-25269,
-25306,
-25306,
-25306,
-25313,
-25313,
-25336,
-25346,
-25356,
-25366,
-25366,
-25386,
-25386,
-25397,
-25397,
-25411,
-25439,
-25439,
-25439,
-25439,
+25226,
+25226,
+25233,
+25250,
+25250,
+25250,
+25250,
+25264,
+25264,
+25293,
+25300,
+25311,
+25333,
+25347,
+25347,
+25347,
+25364,
+25403,
+25414,
+25443,
+25460,
+25477,
+25494,
25511,
-25515,
-25515,
-25521,
-25521,
-25521,
-25521,
-25536,
-25539,
-25549,
-25549,
-25573,
-25608,
-25608,
-25608,
-25608,
-25643,
-25646,
-25646,
-25646,
-25656,
-25656,
-25656,
-25672,
-25672,
-25692,
-25709,
-25729,
-25729,
-25746,
-25766,
-25766,
-25766,
-25793,
-25793,
-25806,
-25806,
-25817,
-25847,
-25847,
-25873,
-25873,
-25884,
-25892,
-25892,
-25892,
-25892,
-25902,
-25909,
-25917,
-25917,
-25949,
-25949,
-25949,
-25953,
-25953,
-25959,
-25959,
-25974,
-25974,
-25974,
-25985,
-25992,
-26003,
-26003,
-26003,
-26003,
-26003,
-26003,
-26003,
-26019,
-26025,
-26033,
-26041,
-26053,
-26053,
-26067,
+25511,
+25522,
+25555,
+25576,
+25583,
+25623,
+25630,
+25630,
+25630,
+25630,
+25630,
+25645,
+25652,
+25659,
+25666,
+25693,
+25723,
+25763,
+25780,
+25788,
+25801,
+25801,
+25821,
+25828,
+25828,
+25835,
+25852,
+25852,
+25859,
+25859,
+25878,
+25896,
+25920,
+25937,
+25969,
+25998,
+26012,
+26049,
+26070,
26076,
-26092,
-26105,
-26105,
-26105,
-26105,
-26138,
-26163,
-26163,
-26169,
-26182,
-26200,
-26200,
-26205,
-26215,
+26088,
+26088,
+26088,
+26088,
+26088,
+26101,
+26128,
+26149,
+26158,
+26177,
+26183,
26219,
-26231,
-26231,
-26231,
-26256,
-26277,
-26277,
-26295,
-26295,
-26299,
-26329,
-26336,
-26342,
-26342,
-26366,
-26413,
-26413,
-26413,
-26434,
-26455,
-26455,
-26472,
-26472,
-26483,
-26497,
-26497,
-26497,
-26508,
-26508,
-26512,
-26532,
-26532,
-26532,
-26536,
-26536,
-26545,
-26545,
-26565,
-26565,
-26565,
-26576,
-26586,
-26595,
-26595,
-26608,
-26612,
-26612,
-26639,
-26639,
-26639,
-26639,
-26655,
-26655,
-26676,
-26676,
-26692,
-26707,
-26707,
-26707,
-26707,
-26722,
-26722,
-26730,
-26739,
-26739,
-26739,
-26739,
-26759,
-26759,
-26759,
-26769,
-26769,
-26769,
-26781,
-26796,
-26815,
-26815,
-26815,
-26826,
-26839,
-26839,
-26869,
-26873,
-26914,
-26921,
-26933,
-26950,
-26975,
-26980,
-27007,
-27007,
-27007,
-27042,
-27042,
-27042,
-27046,
-27046,
-27062,
-27070,
-27086,
-27086,
-27086,
-27098,
-27098,
-27105,
-27105,
-27133,
-27133,
-27138,
-27147,
-27147,
-27154,
-27154,
-27154,
-27154,
-27170,
-27170,
-27192,
-27269,
-27269,
-27269,
-27312,
-27312,
-27319,
-27332,
-27345,
-27393,
-27410,
-27410,
-27432,
-27452,
-27452,
-27452,
-27452,
-27452,
-27479,
-27479,
-27507,
-27507,
-27513,
-27513,
-27530,
-27535,
-27535,
-27535,
-27535,
-27535,
-27548,
-27563,
-27579,
-27601,
-27601,
-27611,
-27611,
-27624,
-27624,
-27624,
-27629,
-27648,
-27648,
-27648,
-27656,
-27656,
-27666,
-27683,
-27683,
-27683,
-27704,
-27723,
-27729,
-27729,
-27762,
-27798,
-27798,
+26236,
+26243,
+26253,
+26261,
+26268,
+26278,
+26278,
+26296,
+26307,
+26307,
+26307,
+26315,
+26378,
+26385,
+26402,
+26409,
+26439,
+26459,
+26466,
+26485,
+26485,
+26492,
+26499,
+26499,
+26511,
+26556,
+26572,
+26596,
+26621,
+26621,
+26621,
+26621,
+26659,
+26659,
+26675,
+26700,
+26716,
+26741,
+26755,
+26755,
+26755,
+26785,
+26785,
+26785,
+26825,
+26825,
+26846,
+26864,
+26891,
+26898,
+26936,
+26936,
+26951,
+26951,
+26971,
+26978,
+27008,
+27054,
+27068,
+27075,
+27089,
+27089,
+27120,
+27127,
+27127,
+27127,
+27144,
+27151,
+27169,
+27176,
+27183,
+27208,
+27225,
+27272,
+27272,
+27279,
+27308,
+27354,
+27358,
+27358,
+27374,
+27388,
+27388,
+27388,
+27395,
+27419,
+27426,
+27430,
+27465,
+27472,
+27508,
+27515,
+27529,
+27558,
+27580,
+27590,
+27590,
+27590,
+27605,
+27605,
+27615,
+27615,
+27625,
+27625,
+27625,
+27631,
+27681,
+27681,
+27688,
+27688,
+27707,
+27711,
+27742,
+27749,
+27749,
+27765,
+27793,
+27839,
+27839,
+27839,
+27849,
+27849,
27864,
27864,
-27877,
-27907,
-27946,
-27972,
-27972,
-27972,
-27983,
-27983,
-27983,
-27991,
-27998,
-28014,
+27871,
+27871,
+27871,
+27871,
+27871,
+27871,
+27884,
+27903,
+27928,
+27949,
+27949,
+27963,
+27963,
+27975,
+27982,
+27982,
+27982,
+27982,
+27982,
+28019,
+28019,
28040,
28040,
-28064,
-28064,
-28080,
-28092,
-28101,
-28101,
-28123,
-28141,
-28161,
-28168,
-28185,
-28196,
-28209,
-28238,
-28259,
-28259,
-28286,
-28304,
-28304,
-28331,
-28348,
-28348,
-28366,
-28379,
-28389,
-28398,
-28398,
-28398,
-28423,
-28449,
-28472,
-28514,
-28523,
-28523,
-28542,
-28542,
-28551,
-28551,
-28565,
-28579,
-28579,
-28589,
-28597,
-28601,
-28633,
-28633,
-28651,
-28679,
-28696,
-28759,
-28759,
-28759,
-28759,
-28759,
-28778,
-28793,
-28836,
-28842,
-28852,
-28859,
-28859,
-28885,
-28885,
-28915,
-28915,
-28915,
-28919,
-28923,
-28971,
-28971,
-28978,
-28982,
-28987,
-28991,
+28040,
+28040,
+28108,
+28134,
+28134,
+28134,
+28174,
+28183,
+28197,
+28197,
+28197,
+28220,
+28230,
+28241,
+28241,
+28257,
+28257,
+28263,
+28290,
+28290,
+28361,
+28368,
+28368,
+28368,
+28373,
+28397,
+28421,
+28433,
+28440,
+28440,
+28450,
+28450,
+28466,
+28481,
+28481,
+28490,
+28532,
+28532,
+28539,
+28548,
+28555,
+28573,
+28573,
+28603,
+28627,
+28645,
+28645,
+28658,
+28684,
+28684,
+28722,
+28749,
+28767,
+28774,
+28774,
+28788,
+28801,
+28844,
+28844,
+28844,
+28850,
+28870,
+28870,
+28877,
+28883,
+28893,
+28893,
+28893,
+28918,
+28918,
+28931,
+28931,
+28931,
+28959,
+28973,
+28973,
28991,
-29008,
-29031,
-29041,
-29081,
-29081,
-29081,
-29081,
-29088,
-29088,
-29088,
-29100,
-29110,
-29124,
-29147,
-29147,
-29147,
-29153,
-29153,
-29153,
-29175,
-29185,
-29190,
-29214,
-29231,
-29231,
-29231,
-29231,
-29237,
-29265,
+29010,
+29029,
+29038,
+29048,
+29099,
+29099,
+29109,
+29109,
+29109,
+29109,
+29109,
+29109,
+29128,
+29139,
+29162,
+29162,
+29176,
+29176,
+29194,
+29194,
+29194,
+29205,
+29205,
+29227,
+29227,
+29227,
+29227,
+29248,
+29254,
+29270,
+29270,
29302,
-29333,
-29333,
-29374,
-29421,
-29446,
-29446,
-29456,
-29456,
-29473,
-29489,
-29497,
-29497,
-29530,
-29538,
-29571,
-29602,
-29623,
-29631,
-29631,
-29642,
-29655,
-29702,
-29702,
-29702,
-29702,
-29720,
-29720,
-29731,
-29753,
-29753,
-29753,
-29765,
+29309,
+29326,
+29343,
+29359,
+29369,
+29369,
+29386,
+29411,
+29411,
+29411,
+29411,
+29452,
+29463,
+29463,
+29468,
+29468,
+29492,
+29492,
+29523,
+29535,
+29535,
+29539,
+29539,
+29546,
+29557,
+29557,
+29564,
+29570,
+29579,
+29595,
+29601,
+29608,
+29608,
+29608,
+29664,
+29683,
+29698,
+29698,
+29698,
+29698,
+29706,
+29706,
+29721,
+29746,
+29775,
29793,
-29800,
-29849,
-29884,
-29884,
-29884,
-29894,
-29919,
-29940,
-29973,
-30037,
-30037,
-30054,
-30054,
-30054,
-30054,
-30054,
-30066,
-30090,
-30103,
-30144,
-30144,
-30144,
-30165,
-30189,
-30189,
-30189,
-30189,
-30189,
-30208,
-30222,
+29813,
+29831,
+29831,
+29852,
+29852,
+29897,
+29916,
+29955,
+29971,
+29971,
+30000,
+30040,
+30040,
+30055,
+30064,
+30071,
+30071,
+30071,
+30071,
+30071,
+30088,
+30088,
+30118,
+30118,
+30130,
+30130,
+30141,
+30164,
+30171,
+30178,
+30194,
+30194,
+30204,
+30223,
30231,
-30241,
-30241,
-30259,
30269,
-30276,
-30298,
-30298,
-30298,
-30304,
-30304,
-30314,
-30314,
-30314,
-30314,
-30314,
-30314,
-30321,
-30321,
-30321,
-30321,
-30327,
-30327,
-30334,
-30340,
-30340,
-30362,
-30378,
-30385,
-30385,
-30385,
-30385,
+30308,
+30308,
+30308,
+30352,
+30374,
+30394,
+30394,
+30406,
30406,
-30412,
-30424,
-30464,
+30406,
+30414,
+30431,
+30431,
+30437,
+30443,
+30461,
+30483,
30483,
30483,
-30492,
-30498,
-30522,
-30529,
-30554,
-30554,
-30554,
-30554,
-30572,
-30572,
-30584,
-30584,
-30606,
-30626,
-30665,
-30678,
-30678,
-30697,
-30725,
+30514,
+30519,
+30553,
+30553,
+30558,
+30563,
+30563,
+30604,
+30604,
+30610,
+30610,
+30610,
+30631,
+30642,
+30646,
+30646,
+30646,
+30650,
+30650,
+30681,
+30681,
+30681,
+30698,
+30714,
+30714,
+30714,
+30714,
+30714,
+30721,
+30732,
+30732,
+30732,
+30745,
+30745,
+30751,
30765,
-30771,
-30771,
-30771,
-30791,
-30791,
-30824,
-30840,
-30844,
-30872,
-30896,
-30896,
-30922,
-30946,
-30946,
-30970,
+30782,
+30805,
+30805,
+30821,
+30821,
+30842,
+30855,
+30881,
+30881,
+30903,
+30903,
+30912,
+30965,
+30965,
+30980,
+30980,
+30980,
+30987,
30998,
-30998,
-31028,
-31047,
-31070,
-31070,
-31070,
-31076,
-31113,
-31134,
-31140,
-31151,
-31158,
+31002,
+31064,
+31075,
+31087,
+31103,
+31109,
+31109,
+31109,
+31122,
+31122,
+31122,
+31135,
+31150,
+31150,
+31165,
31165,
-31185,
-31185,
-31185,
-31203,
-31218,
-31233,
-31233,
-31233,
-31256,
-31263,
-31263,
-31287,
-31287,
-31287,
-31297,
-31309,
-31317,
-31327,
-31343,
-31353,
-31353,
-31389,
-31389,
-31389,
-31406,
-31406,
-31406,
-31423,
-31439,
-31439,
-31459,
-31469,
-31476,
-31493,
-31499,
-31515,
-31515,
-31534,
-31534,
+31175,
+31175,
+31175,
+31189,
+31220,
+31220,
+31230,
+31240,
+31274,
+31281,
+31307,
+31307,
+31313,
+31342,
+31349,
+31372,
+31413,
+31413,
+31429,
+31435,
+31435,
+31435,
+31447,
+31454,
+31454,
+31454,
+31461,
+31461,
+31488,
+31488,
+31488,
+31488,
+31488,
+31507,
+31537,
+31546,
+31546,
+31546,
31566,
-31585,
-31608,
-31608,
-31626,
-31641,
-31648,
+31590,
+31602,
+31602,
+31602,
+31622,
+31622,
31648,
-31665,
-31665,
-31665,
-31665,
-31681,
-31705,
-31746,
-31768,
-31841,
-31851,
-31927,
-31927,
-31934,
-31962,
-31986,
-31992,
-32008,
-32021,
-32021,
-32021,
-32021,
-32027,
-32027,
-32053,
-32053,
-32057,
-32088,
-32088,
-32098,
-32098,
-32098,
-32129,
-32172,
-32193,
-32208,
-32208,
-32228,
-32228,
-32248,
-32254,
-32274,
-32274,
-32287,
-32309,
-32319,
-32350,
-32355,
-32391,
-32397,
-32397,
-32412,
-32412,
-32419,
-32461,
-32468,
-32468,
-32468,
-32485,
-32485,
-32510,
-32553,
-32565,
-32578,
-32586,
-32591,
-32591,
-32595,
-32608,
-32608,
-32636,
-32636,
-32636,
-32658,
-32676,
+31677,
+31692,
+31701,
+31717,
+31728,
+31728,
+31744,
+31744,
+31754,
+31783,
+31816,
+31827,
+31827,
+31834,
+31834,
+31863,
+31884,
+31884,
+31898,
+31954,
+32001,
+32023,
+32023,
+32041,
+32054,
+32076,
+32086,
+32121,
+32128,
+32135,
+32135,
+32158,
+32188,
+32203,
+32203,
+32255,
+32255,
+32255,
+32279,
+32308,
+32346,
+32374,
+32394,
+32394,
+32394,
+32394,
+32414,
+32431,
+32431,
+32447,
+32447,
+32447,
+32462,
+32462,
+32462,
+32462,
+32505,
+32522,
+32522,
+32522,
+32539,
+32544,
+32569,
+32569,
+32569,
+32598,
+32614,
+32633,
+32633,
+32633,
+32648,
+32648,
+32659,
32680,
32680,
-32695,
-32695,
-32695,
-32695,
-32695,
+32720,
+32720,
+32726,
+32726,
32726,
32726,
-32768,
-32779,
-32804,
-32821,
-32835,
-32835,
-32835,
-32851,
-32866,
-32881,
-32881,
-32886,
-32886,
-32886,
-32893,
-32893,
-32912,
-32924,
-32935,
-32935,
-32955,
-32975,
-32993,
+32769,
+32803,
+32803,
+32803,
+32803,
+32803,
+32819,
+32819,
+32836,
+32836,
+32836,
+32856,
+32856,
+32871,
+32871,
+32889,
+32913,
+32919,
+32919,
+32919,
+32919,
+32942,
+32942,
+32942,
+32942,
+32942,
+32963,
+32984,
33012,
-33020,
-33038,
-33046,
-33069,
-33069,
-33118,
-33131,
-33131,
-33157,
-33157,
-33172,
-33177,
-33182,
-33197,
-33204,
+33018,
+33018,
+33018,
+33018,
+33034,
+33060,
+33060,
+33077,
+33110,
+33110,
+33120,
+33120,
+33144,
+33181,
+33195,
+33195,
+33195,
+33212,
+33225,
33238,
-33254,
-33281,
-33294,
-33309,
-33320,
-33360,
-33360,
-33364,
-33379,
-33379,
-33397,
-33415,
-33415,
-33415,
-33415,
-33415,
-33415,
-33441,
-33465,
+33248,
+33248,
+33248,
+33248,
+33259,
+33259,
+33259,
+33273,
+33273,
+33273,
+33273,
+33273,
+33273,
+33273,
+33273,
+33273,
+33273,
+33293,
+33303,
+33303,
+33313,
+33325,
+33325,
+33325,
+33336,
+33342,
+33347,
+33347,
+33357,
+33370,
+33403,
+33442,
+33467,
+33477,
+33477,
+33491,
+33491,
33508,
33508,
-33508,
-33525,
-33531,
-33558,
-33572,
-33572,
-33579,
-33579,
-33607,
-33636,
-33642,
-33642,
-33663,
-33663,
-33663,
-33663,
-33670,
-33670,
-33670,
-33670,
-33677,
-33677,
-33677,
-33688,
-33688,
-33688,
-33709,
-33723,
-33741,
-33741,
-33741,
-33741,
-33741,
-33741,
-33752,
-33752,
-33752,
-33771,
-33771,
-33771,
-33790,
+33560,
+33569,
+33569,
+33569,
+33589,
+33628,
+33654,
+33665,
+33681,
+33700,
+33719,
+33719,
+33742,
+33760,
+33760,
+33760,
+33760,
+33760,
+33788,
+33788,
+33804,
33804,
-33824,
-33864,
-33875,
-33886,
-33903,
-33903,
-33916,
-33928,
-33948,
-33961,
-34011,
-34048,
-34065,
-34097,
-34112,
-34112,
-34112,
-34112,
-34130,
-34148,
-34148,
-34148,
-34178,
-34191,
-34223,
-34228,
-34228,
-34260,
-34260,
-34260,
-34260,
-34282,
-34305,
-34315,
-34315,
-34336,
-34356,
-34373,
-34373,
-34379,
-34401,
-34419,
-34419,
-34419,
-34419,
-34432,
-34432,
-34438,
-34460,
-34489,
-34508,
-34515,
-34515,
-34515,
-34515,
-34537,
-34546,
-34546,
-34546,
-34546,
-34546,
-34562,
-34573,
-34573,
-34583,
-34621,
+33804,
+33830,
+33854,
+33854,
+33854,
+33860,
+33860,
+33878,
+33898,
+33898,
+33898,
+33898,
+33898,
+33941,
+33941,
+33955,
+33982,
+33982,
+34002,
+34002,
+34017,
+34030,
+34090,
+34104,
+34104,
+34140,
+34180,
+34195,
+34214,
+34214,
+34214,
+34244,
+34244,
+34263,
+34263,
+34263,
+34263,
+34263,
+34263,
+34263,
+34263,
+34279,
+34312,
+34341,
+34345,
+34351,
+34374,
+34386,
+34407,
+34407,
+34407,
+34417,
+34437,
+34437,
+34449,
+34459,
+34465,
+34484,
+34484,
+34494,
+34534,
+34556,
+34556,
+34556,
+34566,
+34576,
+34576,
+34582,
+34607,
+34607,
+34628,
34634,
-34644,
-34664,
-34664,
-34695,
-34719,
-34719,
-34762,
-34762,
-34762,
-34805,
-34811,
-34832,
-34836,
-34836,
-34836,
-34836,
-34865,
+34646,
+34646,
+34655,
+34673,
+34673,
+34686,
+34686,
+34697,
+34697,
+34714,
+34714,
+34714,
+34714,
+34714,
+34731,
+34731,
+34731,
+34731,
+34731,
+34741,
+34767,
+34767,
+34767,
+34783,
+34783,
+34792,
+34792,
+34847,
+34862,
+34876,
+34876,
+34891,
34891,
-34911,
-34916,
-34916,
-34916,
-34916,
-34933,
-34963,
-34979,
-34979,
-35021,
-35035,
-35035,
-35044,
-35055,
-35092,
-35120,
-35120,
-35120,
-35120,
-35120,
-35139,
-35179,
-35208,
-35218,
+34902,
+34919,
+34919,
+34939,
+34939,
+34939,
+34954,
+34954,
+34954,
+34954,
+34971,
+34971,
+34988,
+34988,
+34998,
+35006,
+35006,
+35006,
+35017,
+35023,
+35023,
+35028,
+35028,
+35047,
+35066,
+35066,
+35076,
+35128,
+35137,
+35158,
+35174,
+35174,
+35181,
+35181,
+35223,
35233,
-35249,
-35249,
-35298,
-35309,
-35325,
+35248,
+35258,
+35277,
+35277,
+35282,
+35300,
+35316,
+35335,
+35335,
35344,
-35344,
-35358,
-35358,
-35395,
-35410,
-35410,
-35419,
-35419,
-35419,
-35419,
+35378,
+35400,
35419,
-35451,
-35470,
-35470,
-35494,
-35523,
-35523,
-35573,
-35573,
-35597,
-35609,
-35644,
-35662,
-35662,
-35676,
-35680,
-35680,
-35680,
-35680,
-35685,
-35694,
-35694,
-35694,
-35729,
-35747,
-35747,
-35754,
-35761,
-35761,
-35771,
-35793,
-35802,
-35837,
-35889,
-35889,
-35889,
-35889,
-35899,
-35915,
-35947,
-35947,
-35947,
-35957,
-35957,
-35980,
-35986,
-35986,
-35986,
-36002,
-36050,
-36050,
-36074,
-36084,
-36092,
-36092,
-36117,
-36117,
+35433,
+35433,
+35448,
+35461,
+35477,
+35498,
+35522,
+35533,
+35554,
+35569,
+35569,
+35586,
+35595,
+35608,
+35608,
+35608,
+35618,
+35623,
+35635,
+35645,
+35645,
+35645,
+35682,
+35682,
+35682,
+35682,
+35687,
+35701,
+35705,
+35705,
+35705,
+35715,
+35715,
+35715,
+35753,
+35766,
+35808,
+35821,
+35825,
+35835,
+35857,
+35877,
+35877,
+35877,
+35888,
+35888,
+35905,
+35967,
+35967,
+35974,
+35974,
+36001,
+36027,
+36027,
+36038,
+36038,
+36054,
+36064,
+36064,
+36064,
+36083,
+36111,
+36133,
36133,
36156,
-36171,
-36184,
-36227,
-36247,
-36288,
-36288,
-36317,
-36325,
-36342,
-36342,
-36342,
-36349,
-36349,
-36369,
-36378,
-36397,
-36410,
-36410,
-36449,
-36473,
-36473,
-36488,
-36488,
-36500,
-36527,
-36538,
-36538,
-36578,
-36610,
-36632,
-36651,
-36651,
-36651,
-36651,
-36664,
-36664,
-36682,
-36682,
-36682,
-36713,
-36732,
-36732,
-36732,
-36732,
-36732,
-36745,
-36745,
-36751,
-36751,
-36770,
+36178,
+36198,
+36198,
+36198,
+36202,
+36255,
+36276,
+36282,
+36290,
+36290,
+36313,
+36334,
+36334,
+36334,
+36345,
+36411,
+36424,
+36450,
+36472,
+36472,
+36472,
+36479,
+36495,
+36511,
+36575,
+36575,
+36593,
+36593,
+36593,
+36593,
+36602,
+36616,
+36628,
+36628,
+36656,
+36672,
+36719,
+36719,
+36719,
+36719,
+36719,
+36737,
+36737,
+36737,
+36750,
+36750,
+36750,
+36758,
36770,
36770,
-36776,
-36807,
-36827,
-36827,
-36844,
-36844,
-36853,
-36863,
-36873,
-36873,
-36880,
-36880,
-36880,
-36884,
-36897,
-36928,
-36928,
-36950,
-36968,
-36973,
-36973,
-36989,
-37055,
-37055,
-37073,
-37085,
-37094,
-37106,
-37157,
-37163,
+36778,
+36778,
+36778,
+36778,
+36826,
+36835,
+36835,
+36835,
+36850,
+36850,
+36855,
+36872,
+36872,
+36903,
+36919,
+36934,
+36939,
+36939,
+36954,
+36954,
+36986,
+37016,
+37043,
+37051,
+37062,
+37062,
+37062,
+37069,
+37069,
+37069,
+37069,
+37069,
+37069,
+37069,
+37069,
+37096,
+37096,
+37115,
+37115,
+37149,
+37177,
37193,
-37232,
+37214,
+37228,
+37228,
+37228,
+37228,
+37228,
37241,
-37265,
-37265,
-37272,
-37281,
-37324,
-37359,
-37391,
-37415,
-37429,
-37429,
-37457,
-37457,
-37463,
-37463,
-37469,
-37469,
-37498,
-37498,
-37498,
-37498,
-37498,
-37498,
-37498,
-37498,
-37498,
-37515,
-37526,
-37541,
-37559,
-37597,
-37617,
-37627,
-37634,
-37668,
-37668,
-37668,
-37668,
-37699,
-37706,
-37706,
-37706,
+37245,
+37245,
+37245,
+37250,
+37250,
+37268,
+37294,
+37299,
+37314,
+37328,
+37335,
+37335,
+37372,
+37380,
+37396,
+37410,
+37416,
+37428,
+37468,
+37490,
+37511,
+37516,
+37516,
+37528,
+37528,
+37528,
+37528,
+37534,
+37534,
+37562,
+37589,
+37589,
+37589,
+37611,
+37611,
+37611,
+37625,
+37631,
+37654,
+37654,
+37654,
+37658,
+37685,
+37685,
37706,
-37715,
-37724,
-37733,
-37751,
-37767,
-37767,
+37717,
+37717,
+37717,
+37732,
+37732,
+37732,
+37758,
37783,
-37783,
-37793,
-37793,
-37793,
-37806,
-37806,
-37828,
-37841,
-37841,
-37841,
-37841,
-37866,
-37879,
-37879,
-37896,
-37903,
-37910,
-37910,
+37803,
+37822,
+37840,
+37840,
+37840,
+37840,
+37863,
+37881,
+37894,
37926,
-37971,
-37971,
-37981,
-38033,
-38082,
-38113,
-38122,
-38122,
-38122,
-38122,
-38144,
-38144,
-38144,
-38169,
-38210,
-38244,
-38284,
+37949,
+37949,
+37949,
+37970,
+37970,
+37991,
+37991,
+37991,
+37991,
+38025,
+38025,
+38025,
+38025,
+38045,
+38058,
+38058,
+38080,
+38080,
+38095,
+38095,
+38142,
+38179,
+38187,
+38211,
+38218,
+38225,
+38232,
+38277,
+38298,
+38298,
38328,
-38339,
-38339,
-38377,
-38402,
-38412,
-38429,
-38429,
-38452,
-38474,
-38481,
-38488,
-38488,
-38488,
-38488,
-38511,
-38525,
-38568,
-38568,
-38575,
-38592,
-38613,
-38629,
-38629,
-38654,
-38684,
-38684,
-38703,
-38710,
-38710,
-38735,
-38748,
-38755,
-38762,
-38776,
-38776,
-38776,
-38776,
-38776,
-38812,
-38819,
-38834,
-38847,
-38854,
-38861,
-38868,
-38868,
-38888,
-38888,
-38908,
-38908,
+38352,
+38352,
+38371,
+38371,
+38378,
+38407,
+38428,
+38448,
+38448,
+38458,
+38458,
+38458,
+38489,
+38489,
+38489,
+38489,
+38499,
+38515,
+38532,
+38532,
+38578,
+38578,
+38586,
+38606,
+38606,
+38624,
+38624,
+38624,
+38642,
+38647,
+38647,
+38658,
+38665,
+38682,
+38723,
+38767,
+38767,
+38795,
+38795,
+38801,
+38801,
+38801,
+38837,
+38837,
+38856,
+38856,
+38894,
38915,
-38926,
-38942,
-38949,
-38956,
-38956,
-38956,
-38963,
-38980,
-38980,
-39003,
-39009,
+38941,
+38965,
+38965,
+38965,
+38965,
+38992,
+39015,
39039,
-39052,
-39059,
-39077,
-39084,
-39084,
-39091,
-39091,
-39108,
-39115,
-39115,
-39150,
-39150,
-39179,
-39184,
-39184,
-39240,
-39240,
-39277,
-39284,
-39284,
-39284,
-39309,
-39351,
+39045,
+39045,
+39053,
+39058,
+39058,
+39088,
+39088,
+39118,
+39118,
+39129,
+39129,
+39129,
+39147,
+39155,
+39155,
+39178,
+39182,
+39222,
+39222,
+39230,
+39230,
+39230,
+39230,
+39238,
+39238,
+39260,
+39260,
+39260,
+39281,
+39295,
+39310,
+39328,
+39335,
+39342,
39358,
-39363,
-39395,
-39408,
-39421,
-39421,
-39427,
-39427,
-39440,
-39453,
-39461,
-39461,
-39473,
-39473,
-39473,
-39490,
-39497,
-39510,
-39510,
-39516,
-39516,
-39523,
-39523,
-39535,
-39544,
-39551,
-39561,
-39561,
-39568,
+39371,
+39386,
+39386,
+39415,
+39415,
+39422,
+39454,
+39471,
+39471,
+39471,
+39478,
+39520,
+39520,
+39534,
+39541,
+39541,
+39548,
+39548,
+39548,
39568,
-39585,
-39585,
-39592,
-39592,
-39599,
-39622,
-39622,
-39637,
-39677,
-39715,
-39736,
-39765,
-39765,
-39775,
-39793,
-39793,
-39814,
-39850,
-39864,
-39889,
-39893,
-39917,
-39927,
-39934,
-39934,
-39952,
-39959,
-39977,
-39984,
-39991,
-40009,
-40009,
-40013,
-40013,
-40032,
-40032,
-40032,
-40032,
-40032,
-40032,
-40047,
-40062,
-40078,
-40078,
-40095,
-40131,
-40137,
-40151,
-40186,
-40201,
-40208,
-40227,
-40236,
-40236,
-40243,
-40250,
-40250,
-40359,
-40366,
-40373,
+39581,
+39605,
+39613,
+39627,
+39634,
+39672,
+39699,
+39705,
+39712,
+39728,
+39741,
+39748,
+39755,
+39762,
+39799,
+39843,
+39884,
+39891,
+39905,
+39922,
+39922,
+39929,
+39936,
+39943,
+39970,
+39970,
+39970,
+39988,
+40002,
+40022,
+40026,
+40026,
+40043,
+40073,
+40097,
+40107,
+40107,
+40166,
+40178,
+40184,
+40211,
+40234,
+40260,
+40260,
+40285,
+40310,
+40310,
+40331,
+40348,
+40348,
+40362,
40380,
-40404,
-40404,
-40415,
-40422,
-40434,
-40458,
-40465,
-40472,
-40472,
-40472,
+40380,
+40394,
+40414,
+40414,
+40421,
+40421,
+40460,
40472,
+40483,
+40490,
40497,
-40502,
-40509,
-40527,
+40512,
40527,
-40540,
-40547,
-40562,
-40569,
-40584,
-40591,
-40591,
-40598,
-40605,
-40605,
-40612,
-40619,
-40630,
-40660,
-40667,
-40674,
-40690,
-40714,
-40721,
-40748,
-40763,
-40770,
-40784,
-40795,
-40827,
-40827,
-40841,
-40841,
-40870,
-40870,
-40889,
-40889,
-40889,
+40546,
+40587,
+40587,
+40587,
+40587,
+40607,
+40614,
+40614,
+40614,
+40614,
+40614,
+40635,
+40635,
+40635,
+40653,
+40673,
+40673,
+40673,
+40673,
+40673,
+40680,
+40680,
+40694,
+40708,
+40731,
+40731,
+40738,
+40757,
+40757,
+40764,
+40803,
+40812,
+40825,
+40825,
+40832,
+40838,
+40869,
+40922,
40936,
-40942,
-40952,
-40982,
-40991,
-41001,
-41017,
-41033,
-41040,
-41060,
-41073,
-41104,
-41114,
-41114,
-41149,
-41149,
-41149,
-41149,
-41149,
-41156,
-41221,
-41244,
-41266,
-41292,
-41292,
-41309,
-41309,
+40955,
+40990,
+40997,
+41010,
+41053,
+41071,
+41101,
+41107,
+41119,
+41194,
+41208,
+41208,
+41208,
+41215,
+41233,
+41265,
+41285,
+41295,
41318,
-41325,
-41361,
-41389,
-41415,
-41415,
-41442,
-41457,
-41471,
-41478,
-41478,
-41478,
-41487,
-41487,
-41502,
-41518,
-41553,
-41553,
-41575,
-41575,
-41575,
-41596,
-41596,
-41596,
-41596,
-41603,
-41603,
-41603,
-41603,
-41617,
-41625,
-41638,
-41671,
-41704,
-41721,
-41752,
-41788,
-41810,
-41828,
-41842,
-41849,
-41849,
-41859,
-41874,
-41881,
-41881,
-41881,
-41881,
-41881,
-41906,
-41919,
-41935,
-41942,
-41942,
-41959,
-41959,
-41966,
-41973,
-41980,
-41980,
-41987,
-42017,
-42024,
-42031,
-42031,
-42038,
-42045,
-42055,
-42092,
-42125,
-42144,
-42151,
-42162,
-42181,
-42192,
-42215,
-42215,
-42241,
-42255,
-42255,
-42255,
-42255,
-42255,
-42279,
+41318,
+41336,
+41356,
+41356,
+41363,
+41379,
+41407,
+41439,
+41469,
+41500,
+41500,
+41524,
+41524,
+41524,
+41524,
+41529,
+41578,
+41616,
+41616,
+41631,
+41672,
+41677,
+41711,
+41726,
+41787,
+41787,
+41787,
+41818,
+41845,
+41845,
+41845,
+41900,
+41930,
+41937,
+41937,
+41937,
+41937,
+41986,
+42025,
+42037,
+42059,
+42073,
+42080,
+42148,
+42148,
+42163,
+42179,
+42186,
+42197,
+42219,
+42226,
+42240,
+42240,
+42240,
+42259,
+42264,
+42280,
42290,
-42297,
-42315,
-42315,
-42315,
-42356,
-42356,
-42356,
-42382,
-42382,
-42389,
-42398,
-42398,
-42398,
-42408,
-42426,
-42426,
-42437,
-42443,
-42448,
-42448,
-42448,
-42470,
-42470,
-42478,
-42520,
-42546,
+42313,
+42313,
+42328,
+42346,
+42373,
+42380,
+42399,
+42406,
+42406,
+42413,
+42427,
+42476,
+42494,
+42533,
+42533,
+42540,
+42540,
42556,
-42571,
-42588,
-42594,
-42645,
-42656,
-42656,
-42656,
-42656,
-42673,
-42680,
-42680,
-42680,
-42688,
-42688,
-42719,
-42758,
-42758,
-42758,
-42768,
-42794,
-42794,
-42794,
-42806,
-42822,
-42846,
-42865,
-42865,
-42874,
-42874,
-42887,
-42887,
-42894,
-42920,
-42932,
-42932,
-42966,
-42987,
-42987,
-42987,
-43015,
-43030,
-43041,
-43041,
-43049,
-43069,
-43082,
-43082,
-43082,
-43082,
-43108,
-43125,
-43147,
-43155,
-43174,
-43180,
-43193,
-43193,
-43193,
-43193,
-43193,
-43193,
-43220,
-43232,
-43232,
-43232,
-43246,
-43262,
-43270,
-43278,
-43278,
-43278,
-43278,
-43301,
-43301,
-43320,
-43320,
-43366,
-43370,
-43388,
-43388,
-43388,
-43433,
+42567,
+42587,
+42601,
+42615,
+42622,
+42643,
+42664,
+42664,
+42664,
+42702,
+42718,
+42718,
+42734,
+42746,
+42761,
+42781,
+42793,
+42810,
+42815,
+42841,
+42890,
+42897,
+42905,
+42917,
+42924,
+42931,
+42936,
+42941,
+42951,
+42967,
+42988,
+42988,
+43012,
+43028,
+43054,
+43070,
+43123,
+43127,
+43144,
+43175,
+43199,
+43199,
+43236,
+43244,
+43244,
+43273,
+43280,
+43287,
+43302,
+43318,
+43318,
+43318,
+43331,
+43353,
+43373,
+43373,
+43390,
+43390,
+43390,
+43390,
+43425,
+43437,
+43437,
43447,
-43462,
-43462,
-43462,
-43462,
-43462,
-43495,
-43495,
-43521,
-43528,
-43528,
-43552,
-43612,
-43612,
-43632,
-43648,
-43659,
-43666,
-43693,
-43710,
-43723,
-43728,
-43757,
-43768,
-43780,
-43797,
-43797,
-43797,
-43809,
-43816,
-43821,
-43849,
-43871,
-43890,
-43923,
-43923,
-43932,
-43940,
-43940,
-43958,
-43979,
-43979,
-43979,
-43979,
-44002,
-44002,
-44002,
-44002,
-44058,
-44077,
-44099,
-44129,
-44140,
-44146,
-44146,
-44146,
-44165,
-44178,
-44178,
-44202,
-44202,
-44220,
-44238,
-44255,
-44255,
-44263,
+43464,
+43504,
+43504,
+43504,
+43504,
+43504,
+43504,
+43512,
+43587,
+43587,
+43613,
+43620,
+43620,
+43669,
+43684,
+43698,
+43711,
+43732,
+43752,
+43766,
+43773,
+43796,
+43811,
+43820,
+43840,
+43840,
+43856,
+43876,
+43891,
+43922,
+43922,
+43945,
+43970,
+43984,
+44011,
+44024,
+44024,
+44048,
+44055,
+44055,
+44060,
+44067,
+44074,
+44094,
+44094,
+44106,
+44126,
+44136,
+44149,
+44149,
+44149,
+44190,
+44232,
+44232,
+44250,
+44264,
+44264,
+44264,
44280,
-44298,
-44302,
-44302,
-44330,
-44351,
-44351,
-44363,
-44363,
-44363,
-44378,
-44385,
-44406,
+44280,
+44280,
+44303,
+44335,
+44361,
+44361,
+44398,
44406,
-44434,
-44444,
-44472,
-44472,
-44472,
-44488,
-44492,
-44523,
-44561,
-44592,
-44611,
-44611,
-44632,
-44644,
-44644,
-44651,
-44651,
-44651,
+44425,
+44425,
+44452,
+44459,
+44459,
+44459,
+44459,
+44466,
+44481,
+44516,
+44550,
+44556,
+44576,
+44576,
+44583,
+44583,
+44599,
+44621,
+44642,
44651,
-44651,
-44684,
-44684,
-44690,
-44706,
-44725,
-44731,
-44731,
-44731,
-44731,
-44746,
-44746,
-44757,
-44757,
-44757,
-44757,
-44787,
-44787,
-44787,
-44787,
-44787,
-44799,
-44812,
-44812,
-44827,
-44847,
-44856,
-44856,
-44856,
-44856,
-44884,
+44661,
+44661,
+44661,
+44679,
+44679,
+44710,
+44728,
+44740,
+44747,
+44761,
+44772,
+44795,
+44804,
+44804,
+44804,
+44804,
+44804,
+44808,
+44814,
+44814,
+44814,
+44832,
+44832,
+44832,
+44844,
+44872,
44899,
-44911,
-44911,
-44911,
-44928,
-44958,
-44958,
-44981,
-44981,
-44990,
-45012,
-45037,
-45037,
-45046,
-45046,
-45073,
-45073,
-45085,
-45096,
-45096,
-45100,
-45113,
-45123,
-45158,
+44924,
+44931,
+44931,
+44939,
+44983,
+44988,
+44988,
+44998,
+45008,
+45015,
+45015,
+45028,
+45028,
+45045,
+45045,
+45074,
+45091,
+45091,
+45091,
+45091,
+45095,
+45141,
+45141,
+45155,
+45155,
+45155,
45173,
-45206,
-45214,
-45230,
-45230,
-45258,
-45268,
-45295,
-45307,
-45307,
-45307,
-45307,
-45307,
-45307,
-45338,
-45338,
-45355,
-45372,
-45372,
-45393,
-45393,
-45393,
-45403,
-45403,
-45403,
-45414,
-45455,
-45455,
-45455,
-45455,
+45196,
+45209,
+45226,
+45238,
+45266,
+45266,
+45266,
+45266,
+45302,
+45308,
+45312,
+45312,
+45333,
+45365,
+45377,
+45386,
+45409,
+45409,
+45409,
+45409,
+45445,
45455,
-45463,
-45463,
45478,
-45497,
-45514,
-45514,
-45524,
-45540,
-45540,
-45540,
-45558,
-45558,
-45558,
-45558,
-45574,
-45574,
-45574,
-45590,
-45654,
-45674,
-45686,
-45686,
-45686,
-45705,
-45705,
-45711,
-45721,
-45732,
-45732,
-45732,
-45732,
-45732,
-45738,
-45748,
-45748,
-45769,
-45789,
-45789,
-45800,
-45837,
-45856,
-45868,
-45876,
-45885,
-45902,
-45908,
-45918,
-45918,
-45918,
-45948,
-45976,
+45478,
+45494,
+45511,
+45511,
+45511,
+45523,
+45523,
+45538,
+45538,
+45553,
+45553,
+45589,
+45589,
+45600,
+45610,
+45629,
+45657,
+45720,
+45725,
+45725,
+45755,
+45777,
+45777,
+45791,
+45814,
+45840,
+45890,
+45890,
+45890,
+45927,
+45927,
+45934,
+45934,
+45954,
+45954,
45976,
45976,
45976,
-45981,
-46009,
+45998,
+46007,
+46016,
46016,
-46027,
-46027,
-46027,
46034,
-46050,
-46090,
-46108,
-46108,
-46112,
-46119,
-46126,
-46149,
-46149,
-46149,
-46149,
+46034,
+46066,
+46081,
+46102,
+46117,
+46146,
+46146,
+46162,
+46162,
46169,
-46193,
-46193,
-46193,
-46204,
-46213,
-46222,
-46222,
-46238,
-46245,
-46257,
-46257,
-46301,
-46301,
-46322,
-46322,
-46322,
-46327,
-46345,
-46359,
+46174,
+46215,
+46215,
+46234,
+46239,
+46286,
+46286,
+46300,
+46313,
+46370,
+46370,
+46370,
46374,
-46384,
-46417,
-46417,
-46428,
-46458,
-46458,
-46458,
-46493,
-46493,
-46500,
-46505,
-46555,
-46567,
-46567,
-46580,
-46580,
-46580,
-46595,
-46595,
-46595,
-46595,
-46628,
-46628,
-46652,
-46652,
-46669,
-46669,
-46698,
-46718,
-46718,
-46718,
-46738,
-46753,
-46761,
-46776,
-46776,
-46776,
+46379,
+46393,
+46401,
+46416,
+46416,
+46446,
+46467,
+46482,
+46482,
+46496,
+46538,
+46538,
+46581,
+46581,
+46629,
+46629,
+46629,
+46640,
+46644,
+46649,
+46649,
+46659,
+46659,
+46673,
+46700,
+46731,
+46731,
+46731,
+46741,
+46766,
+46766,
+46771,
+46771,
+46782,
46794,
46794,
-46802,
-46816,
-46846,
-46863,
-46899,
-46899,
-46899,
-46907,
-46907,
-46917,
-46930,
-46957,
-46957,
-46961,
-46961,
-46969,
-46975,
-46975,
-46975,
-46991,
-46999,
-46999,
-47012,
-47018,
-47018,
-47048,
-47058,
-47076,
-47145,
-47145,
-47162,
-47183,
-47228,
-47244,
-47267,
-47267,
-47295,
-47295,
-47295,
-47316,
-47316,
-47316,
-47353,
-47361,
-47385,
-47385,
-47415,
-47419,
-47430,
-47450,
-47465,
-47470,
-47470,
-47470,
-47470,
-47479,
-47501,
-47521,
-47529,
-47536,
-47554,
-47572,
-47572,
-47597,
-47606,
-47614,
-47614,
-47614,
-47623,
-47623,
-47660,
-47660,
-47669,
-47681,
-47694,
-47694,
-47694,
-47698,
-47702,
-47720,
-47720,
-47730,
-47749,
-47767,
-47790,
-47808,
-47824,
-47824,
-47824,
-47830,
-47830,
-47836,
-47869,
-47869,
-47875,
-47898,
-47898,
-47958,
-47962,
-47978,
-47978,
-47985,
-48019,
-48023,
-48023,
-48023,
-48023,
-48043,
-48043,
-48058,
-48058,
-48058,
-48058,
+46812,
+46812,
+46828,
+46851,
+46851,
+46851,
+46851,
+46851,
+46855,
+46868,
+46875,
+46875,
+46886,
+46890,
+46925,
+46925,
+46925,
+46936,
+46954,
+46972,
+46972,
+46972,
+46998,
+47068,
+47068,
+47068,
+47098,
+47107,
+47122,
+47128,
+47151,
+47156,
+47156,
+47170,
+47177,
+47182,
+47193,
+47200,
+47226,
+47226,
+47253,
+47273,
+47283,
+47283,
+47290,
+47303,
+47303,
+47303,
+47320,
+47327,
+47327,
+47335,
+47335,
+47344,
+47344,
+47356,
+47356,
+47360,
+47360,
+47369,
+47394,
+47425,
+47425,
+47425,
+47443,
+47466,
+47466,
+47481,
+47495,
+47513,
+47513,
+47532,
+47532,
+47543,
+47590,
+47603,
+47613,
+47618,
+47618,
+47635,
+47641,
+47641,
+47679,
+47727,
+47740,
+47753,
+47769,
+47779,
+47801,
+47809,
+47829,
+47859,
+47859,
+47878,
+47885,
+47906,
+47906,
+47906,
+47940,
+47950,
+47950,
+47950,
+47950,
+47984,
+47991,
+47991,
+47991,
+47991,
+48029,
+48029,
+48029,
+48038,
+48038,
+48038,
+48055,
+48055,
48065,
-48070,
-48101,
-48101,
-48116,
-48127,
-48127,
-48139,
-48139,
-48163,
-48163,
-48177,
-48177,
-48204,
-48218,
-48246,
-48262,
-48262,
-48262,
-48283,
-48283,
-48306,
-48306,
-48312,
-48312,
-48317,
-48331,
-48347,
-48354,
-48364,
-48364,
-48364,
-48394,
-48447,
-48452,
-48452,
-48476,
-48476,
-48476,
-48542,
-48572,
-48582,
-48622,
-48658,
-48669,
-48669,
-48669,
-48686,
-48686,
-48686,
-48693,
-48693,
-48699,
-48724,
-48741,
+48065,
+48065,
+48065,
+48105,
+48105,
+48123,
+48138,
+48164,
+48179,
+48179,
+48179,
+48205,
+48211,
+48250,
+48310,
+48343,
+48368,
+48368,
+48374,
+48381,
+48397,
+48397,
+48397,
+48406,
+48426,
+48426,
+48439,
+48458,
+48458,
+48485,
+48485,
+48494,
+48520,
+48532,
+48578,
+48595,
+48608,
+48608,
+48608,
+48623,
+48636,
+48636,
+48636,
+48636,
+48648,
+48687,
+48703,
+48711,
+48727,
48741,
-48752,
-48764,
-48784,
-48784,
-48794,
-48799,
-48799,
-48799,
-48799,
-48820,
-48830,
-48866,
-48884,
-48894,
-48913,
-48913,
-48913,
-48913,
-48925,
-48966,
-48975,
+48746,
+48746,
+48746,
+48746,
+48746,
+48746,
+48771,
+48771,
+48771,
+48806,
+48847,
+48847,
+48847,
+48847,
+48847,
+48886,
+48886,
+48886,
+48886,
+48886,
+48886,
+48899,
+48933,
+48933,
+48933,
48975,
-48975,
-48980,
-48987,
-49020,
-49028,
-49054,
-49060,
-49060,
-49086,
-49110,
-49110,
-49121,
-49121,
-49121,
-49134,
-49134,
-49134,
-49141,
+48979,
+48986,
+48986,
+49019,
+49019,
+49019,
+49040,
+49040,
+49040,
+49059,
+49076,
+49103,
+49103,
+49132,
+49132,
+49132,
+49132,
+49132,
+49132,
+49154,
49171,
-49185,
-49197,
-49228,
-49254,
-49254,
-49286,
-49302,
-49315,
-49315,
-49353,
-49362,
+49191,
+49216,
+49226,
+49264,
+49264,
+49278,
+49278,
+49301,
+49340,
+49340,
+49360,
+49370,
+49370,
49374,
-49385,
-49412,
+49381,
+49381,
+49399,
+49406,
49419,
-49447,
-49447,
-49489,
-49514,
-49526,
-49526,
-49559,
-49559,
-49603,
-49615,
-49655,
-49667,
-49667,
-49682,
-49699,
-49743,
-49743,
-49755,
+49428,
+49428,
+49464,
+49464,
+49497,
+49497,
+49497,
+49497,
+49501,
+49501,
+49501,
+49518,
+49548,
+49548,
+49579,
+49594,
+49619,
+49619,
+49639,
+49665,
+49665,
+49665,
+49665,
+49671,
+49671,
+49671,
+49686,
+49686,
+49686,
+49701,
+49701,
+49701,
+49724,
+49738,
49755,
49755,
-49768,
-49778,
-49799,
-49816,
-49816,
-49816,
-49822,
-49822,
-49835,
-49854,
-49872,
-49872,
-49872,
-49882,
-49882,
-49945,
-49969,
-49978,
-49993,
-49993,
+49765,
+49785,
+49795,
+49807,
+49807,
+49842,
+49862,
+49862,
+49876,
+49899,
+49899,
+49899,
+49929,
+49929,
+49929,
+49959,
+49959,
+49959,
+49990,
+49994,
+50012,
50028,
-50044,
-50054,
-50076,
-50083,
-50108,
-50108,
-50120,
-50120,
-50143,
-50143,
-50202,
-50202,
-50214,
+50071,
+50071,
+50081,
+50081,
+50081,
+50091,
+50099,
+50139,
+50139,
+50139,
+50139,
+50156,
+50184,
+50209,
+50209,
+50209,
+50216,
+50216,
+50223,
+50231,
+50231,
+50231,
+50231,
+50251,
50265,
-50279,
-50279,
-50291,
-50291,
-50316,
-50366,
-50366,
-50387,
-50387,
-50387,
-50387,
-50387,
-50405,
-50405,
-50425,
-50425,
-50432,
-50432,
-50432,
-50439,
-50439,
-50463,
-50470,
-50470,
-50470,
-50470,
-50474,
-50486,
-50495,
-50495,
-50518,
-50518,
-50518,
-50533,
-50558,
-50579,
-50579,
-50601,
-50611,
-50645,
-50674,
-50674,
-50692,
-50729,
-50748,
-50784,
-50784,
-50801,
-50814,
-50831,
-50831,
-50831,
-50831,
-50844,
+50273,
+50295,
+50311,
+50311,
+50330,
+50330,
+50339,
+50348,
+50373,
+50373,
+50406,
+50406,
+50406,
+50422,
+50422,
+50433,
+50494,
+50526,
+50542,
+50542,
+50542,
+50542,
+50542,
+50552,
+50552,
+50586,
+50586,
+50586,
+50612,
+50619,
+50619,
+50644,
+50659,
+50659,
+50676,
+50676,
+50676,
+50676,
+50676,
+50723,
+50736,
+50736,
+50736,
+50736,
+50755,
+50778,
+50778,
+50778,
+50785,
+50785,
+50793,
+50815,
+50856,
50856,
-50860,
-50872,
+50874,
+50886,
50909,
-50921,
-50921,
-50964,
-50964,
-50986,
-51006,
-51006,
-51006,
-51021,
-51021,
-51029,
-51035,
-51047,
-51058,
-51058,
-51062,
-51089,
-51089,
-51120,
-51120,
-51120,
-51126,
-51126,
-51139,
-51139,
-51153,
-51153,
-51153,
-51153,
-51165,
-51186,
-51186,
-51208,
-51247,
-51247,
-51247,
-51261,
-51273,
-51273,
-51298,
-51298,
-51298,
-51321,
-51321,
-51321,
-51338,
-51343,
-51371,
-51395,
-51417,
-51417,
-51417,
-51426,
-51426,
-51426,
-51445,
-51455,
-51469,
-51469,
-51488,
-51492,
-51492,
-51511,
-51529,
-51529,
-51549,
-51549,
-51564,
-51583,
-51611,
-51622,
-51644,
-51644,
-51644,
-51656,
-51674,
-51674,
+50918,
+50973,
+50998,
+51014,
+51030,
+51030,
+51030,
+51036,
+51036,
+51046,
+51072,
+51072,
+51078,
+51118,
+51118,
+51118,
+51118,
+51134,
+51182,
+51203,
+51219,
+51219,
+51230,
+51240,
+51240,
+51260,
+51260,
+51260,
+51260,
+51260,
+51260,
+51260,
+51275,
+51275,
+51301,
+51358,
+51374,
+51386,
+51393,
+51402,
+51402,
+51402,
+51441,
+51471,
+51507,
+51507,
+51531,
+51547,
+51547,
+51571,
+51571,
+51571,
+51571,
+51571,
+51571,
+51587,
+51612,
+51626,
+51642,
+51665,
+51681,
+51681,
+51681,
+51681,
51700,
-51733,
-51741,
-51768,
-51822,
-51829,
-51850,
-51850,
-51857,
-51857,
+51713,
+51734,
+51742,
+51746,
+51746,
+51746,
+51759,
+51759,
+51799,
+51799,
+51811,
+51811,
+51816,
+51816,
+51851,
+51851,
51867,
-51874,
-51874,
-51874,
-51874,
-51888,
-51910,
-51938,
-51945,
-51958,
-51976,
-51990,
-51990,
+51879,
+51879,
+51885,
+51902,
+51918,
+51940,
+51940,
+51946,
+51966,
+51997,
52007,
-52033,
-52043,
-52055,
-52055,
-52095,
-52111,
-52123,
-52128,
-52128,
-52147,
-52153,
-52175,
-52199,
-52223,
-52223,
-52223,
-52223,
-52223,
-52223,
-52262,
-52283,
-52324,
-52346,
-52346,
-52380,
-52380,
+52018,
+52018,
+52049,
+52049,
+52049,
+52064,
+52064,
+52084,
+52104,
+52130,
+52168,
+52204,
+52236,
+52249,
+52249,
+52276,
+52276,
+52309,
+52328,
+52328,
+52338,
+52364,
+52364,
+52377,
52395,
-52395,
-52407,
-52407,
-52419,
-52426,
-52439,
-52483,
-52495,
-52495,
-52514,
-52514,
-52523,
-52523,
-52535,
-52559,
-52559,
-52563,
-52563,
-52582,
-52594,
-52644,
-52661,
-52661,
-52720,
-52732,
-52740,
-52740,
-52740,
-52740,
-52759,
-52782,
-52809,
-52809,
-52821,
-52833,
-52853,
-52853,
-52853,
-52887,
-52899,
-52903,
-52930,
-52930,
-52942,
-52942,
-52972,
-53012,
-53012,
-53054,
-53066,
+52402,
+52418,
+52441,
+52441,
+52485,
+52524,
+52524,
+52567,
+52567,
+52567,
+52567,
+52614,
+52628,
+52628,
+52642,
+52654,
+52680,
+52699,
+52760,
+52765,
+52765,
+52765,
+52785,
+52785,
+52785,
+52785,
+52806,
+52832,
+52832,
+52871,
+52871,
+52885,
+52885,
+52892,
+52911,
+52935,
+52958,
+52976,
+52996,
+53005,
+53005,
+53022,
+53022,
+53022,
53066,
-53066,
-53092,
-53106,
-53124,
+53081,
+53088,
+53102,
+53109,
+53109,
+53120,
53124,
-53131,
-53171,
-53176,
-53176,
-53176,
-53176,
-53186,
-53186,
-53210,
-53230,
-53230,
-53230,
-53240,
-53277,
-53291,
-53291,
-53291,
-53302,
-53320,
-53320,
-53347,
-53347,
-53364,
-53378,
-53382,
-53399,
-53424,
-53437,
-53437,
-53437,
-53470,
-53470,
-53470,
-53477,
-53477,
-53484,
-53484,
-53484,
-53499,
-53499,
-53499,
-53504,
-53510,
-53528,
-53528,
-53528,
-53537,
-53537,
-53537,
-53542,
+53158,
+53174,
+53174,
+53185,
+53185,
+53221,
+53249,
+53256,
+53256,
+53285,
+53290,
+53309,
+53309,
+53309,
+53317,
+53322,
+53322,
+53322,
+53360,
+53369,
+53369,
+53369,
+53386,
+53405,
+53405,
+53405,
+53412,
+53432,
+53444,
+53464,
+53472,
+53494,
+53494,
+53494,
+53531,
53547,
-53570,
-53576,
-53601,
-53601,
-53606,
+53547,
+53547,
+53547,
+53556,
+53556,
+53556,
+53556,
+53556,
+53564,
+53587,
53606,
-53625,
-53625,
-53643,
-53650,
-53686,
-53686,
-53693,
-53724,
-53743,
-53759,
-53764,
-53764,
-53774,
+53610,
+53628,
+53651,
+53651,
+53667,
+53667,
+53674,
+53674,
+53681,
+53697,
+53701,
+53701,
+53722,
+53722,
+53729,
+53741,
+53749,
+53749,
+53749,
+53749,
+53765,
53774,
-53794,
-53800,
-53835,
-53851,
-53851,
-53871,
-53892,
-53917,
-53917,
-53925,
-53925,
-53925,
-53973,
-53973,
-53977,
+53785,
+53799,
+53799,
+53821,
+53831,
+53847,
+53902,
+53902,
+53902,
+53902,
+53941,
+53962,
+53972,
+53972,
53998,
-54018,
-54036,
-54054,
-54062,
-54123,
-54123,
-54123,
-54142,
-54194,
-54194,
-54208,
+54016,
+54033,
+54049,
+54066,
+54066,
+54079,
+54089,
+54089,
+54089,
+54096,
+54118,
+54139,
+54163,
+54179,
+54184,
+54210,
54232,
-54242,
-54259,
-54259,
-54268,
-54275,
-54282,
-54305,
-54312,
-54335,
-54348,
-54355,
-54369,
-54369,
-54369,
-54382,
-54382,
-54382,
-54410,
-54436,
-54456,
-54456,
-54456,
-54463,
-54463,
-54472,
-54497,
-54537,
+54254,
+54278,
+54278,
+54292,
+54325,
+54337,
+54371,
+54396,
+54421,
+54434,
+54455,
+54462,
+54495,
+54507,
+54507,
+54523,
+54542,
+54552,
+54552,
+54552,
+54552,
+54552,
+54559,
+54559,
54569,
-54591,
-54591,
-54591,
-54591,
-54617,
-54617,
-54664,
-54664,
-54664,
-54664,
-54693,
-54700,
-54700,
-54736,
-54746,
-54771,
-54782,
-54804,
-54850,
-54868,
-54901,
-54901,
-54921,
-54921,
-54921,
-54960,
-54987,
-54993,
-55000,
-55000,
-55028,
+54620,
+54692,
+54710,
+54721,
+54721,
+54759,
+54773,
+54787,
+54787,
+54803,
+54808,
+54834,
+54834,
+54848,
+54848,
+54848,
+54855,
+54855,
+54879,
+54891,
+54891,
+54891,
+54891,
+54900,
+54910,
+54949,
+54962,
+54978,
+54978,
+54985,
+55005,
+55018,
+55037,
55037,
+55044,
+55049,
+55049,
+55056,
55066,
-55118,
-55133,
-55133,
-55133,
-55138,
-55138,
-55138,
-55138,
-55138,
-55159,
-55191,
-55191,
-55191,
-55226,
-55232,
-55232,
-55242,
-55257,
-55257,
-55270,
-55270,
-55270,
-55298,
-55317,
-55317,
-55317,
-55317,
-55317,
-55317,
-55331,
-55350,
-55350,
-55350,
+55073,
+55081,
+55143,
+55151,
+55161,
+55168,
+55190,
+55196,
+55213,
+55213,
+55230,
+55237,
+55247,
+55267,
+55272,
+55279,
+55279,
+55286,
+55306,
+55334,
+55341,
+55348,
+55354,
55363,
-55387,
-55387,
-55411,
-55411,
-55422,
-55435,
-55481,
-55490,
-55502,
-55502,
+55363,
+55378,
+55386,
+55395,
+55432,
+55432,
+55437,
+55446,
+55458,
+55479,
55502,
-55520,
+55512,
+55512,
55532,
-55554,
-55563,
-55570,
-55585,
-55585,
-55603,
-55610,
-55610,
-55662,
-55662,
-55684,
-55700,
-55707,
-55707,
-55749,
-55765,
-55784,
-55784,
-55784,
-55791,
-55791,
-55791,
-55816,
-55823,
-55852,
-55852,
-55906,
-55941,
-55971,
-55971,
-55978,
-55978,
-55978,
-55987,
-56011,
-56018,
-56024,
-56024,
-56024,
-56055,
-56071,
-56071,
-56078,
-56078,
-56085,
-56092,
-56122,
-56141,
-56141,
-56141,
-56141,
-56146,
-56146,
-56155,
-56178,
-56209,
-56238,
-56257,
-56257,
-56257,
-56262,
-56275,
-56275,
-56275,
-56275,
-56290,
-56307,
-56323,
-56341,
-56341,
-56347,
-56366,
-56375,
-56375,
-56375,
-56375,
-56413,
-56445,
-56450,
-56450,
-56450,
-56454,
+55543,
+55565,
+55573,
+55580,
+55580,
+55618,
+55638,
+55645,
+55657,
+55657,
+55657,
+55691,
+55708,
+55708,
+55708,
+55708,
+55729,
+55735,
+55758,
+55758,
+55767,
+55772,
+55820,
+55830,
+55830,
+55854,
+55854,
+55866,
+55886,
+55886,
+55886,
+55886,
+55910,
+55910,
+55914,
+55929,
+55939,
+55965,
+56006,
+56025,
+56037,
+56037,
+56037,
+56064,
+56115,
+56115,
+56128,
+56133,
+56133,
+56133,
+56133,
+56133,
+56140,
+56140,
+56140,
+56151,
+56177,
+56205,
+56205,
+56219,
+56219,
+56219,
+56236,
+56250,
+56250,
+56250,
+56260,
+56264,
+56271,
+56271,
+56283,
+56292,
+56312,
+56329,
+56338,
+56338,
+56338,
+56364,
+56371,
+56382,
+56382,
+56389,
+56389,
+56389,
+56417,
+56417,
+56417,
+56417,
+56417,
+56437,
+56437,
+56444,
+56460,
56460,
-56467,
-56490,
-56510,
-56517,
-56527,
-56534,
-56534,
-56534,
-56565,
-56577,
-56577,
-56584,
-56608,
-56608,
-56615,
-56615,
-56640,
-56658,
-56658,
-56658,
-56677,
-56677,
-56701,
-56701,
-56722,
-56750,
-56757,
-56757,
-56802,
-56802,
-56802,
-56821,
-56839,
-56863,
-56863,
+56474,
+56503,
+56511,
+56524,
+56594,
+56599,
+56659,
+56685,
+56700,
+56707,
+56707,
+56738,
+56761,
+56774,
+56785,
+56792,
+56805,
+56829,
+56829,
+56840,
+56868,
+56868,
+56868,
+56868,
56874,
56874,
-56905,
-56941,
-56976,
-57006,
-57006,
-57025,
-57032,
-57037,
-57037,
-57061,
-57061,
-57067,
-57067,
-57074,
-57093,
-57131,
-57138,
+56874,
+56874,
+56881,
+56881,
+56893,
+56922,
+56934,
+56934,
+56944,
+56944,
+56944,
+56944,
+56965,
+56973,
+57005,
+57081,
+57126,
57138,
-57158,
-57158,
-57158,
-57169,
-57169,
-57177,
-57191,
-57191,
-57191,
-57191,
-57226,
-57248,
-57261,
-57278,
-57306,
-57306,
-57329,
-57329,
-57349,
-57349,
-57356,
-57356,
-57409,
-57416,
-57422,
-57422,
-57446,
-57463,
-57463,
-57463,
-57487,
-57507,
-57507,
-57507,
-57528,
-57528,
-57528,
-57535,
-57542,
-57542,
-57578,
-57578,
-57592,
-57592,
-57598,
-57598,
-57645,
+57159,
+57175,
+57199,
+57216,
+57216,
+57222,
+57222,
+57222,
+57237,
+57259,
+57282,
+57282,
+57296,
+57312,
+57312,
+57341,
+57397,
+57405,
+57442,
+57442,
+57442,
+57456,
+57466,
+57482,
+57500,
+57512,
+57537,
+57537,
+57575,
+57575,
+57575,
+57582,
+57609,
+57633,
57651,
-57665,
-57665,
-57684,
-57684,
-57692,
-57692,
-57692,
-57709,
-57724,
-57724,
-57766,
-57766,
-57773,
-57773,
-57780,
-57780,
-57797,
-57842,
-57842,
-57842,
-57842,
-57852,
-57852,
-57852,
+57688,
+57714,
+57767,
+57775,
+57783,
+57783,
+57810,
+57849,
+57856,
57869,
-57882,
-57899,
-57899,
-57936,
-57943,
-57943,
-57973,
-57989,
-58001,
-58001,
-58001,
-58001,
-58024,
-58024,
-58024,
-58024,
-58051,
-58051,
-58051,
-58082,
-58091,
-58091,
-58091,
-58097,
-58097,
-58097,
-58130,
-58130,
-58130,
-58130,
-58130,
-58150,
-58150,
-58166,
-58166,
-58171,
-58171,
-58203,
-58209,
-58216,
-58229,
-58235,
-58242,
-58249,
-58260,
-58267,
-58322,
-58332,
-58372,
-58372,
-58384,
-58384,
-58384,
-58405,
-58430,
-58449,
-58476,
-58492,
-58492,
-58499,
-58506,
-58520,
-58554,
-58560,
-58579,
-58595,
-58627,
-58651,
-58651,
-58651,
+57889,
+57916,
+57941,
+57941,
+57941,
+57948,
+57956,
+57974,
+57996,
+58017,
+58048,
+58048,
+58048,
+58048,
+58070,
+58070,
+58094,
+58151,
+58192,
+58224,
+58224,
+58224,
+58224,
+58263,
+58263,
+58273,
+58283,
+58314,
+58356,
+58356,
+58363,
+58363,
+58363,
+58380,
+58396,
+58396,
+58417,
+58417,
+58417,
+58423,
+58423,
+58450,
+58461,
+58461,
+58470,
+58470,
+58514,
+58514,
+58537,
+58544,
+58557,
+58557,
+58557,
+58557,
+58557,
+58591,
+58615,
+58636,
+58636,
58658,
58679,
58686,
58686,
58686,
-58714,
-58714,
-58728,
-58735,
-58753,
-58753,
-58770,
-58777,
-58842,
-58842,
-58859,
-58879,
-58886,
-58886,
-58940,
-58940,
-58964,
-58964,
-58982,
-58988,
-59002,
-59032,
-59056,
-59067,
-59083,
-59112,
-59112,
-59121,
-59152,
-59152,
+58700,
+58717,
+58732,
+58739,
+58739,
+58745,
+58752,
+58762,
+58784,
+58811,
+58825,
+58832,
+58839,
+58863,
+58899,
+58905,
+58912,
+58912,
+58912,
+58939,
+58939,
+58939,
+58960,
+58973,
+58973,
+58973,
+58973,
+58973,
+58980,
+58980,
+58987,
+58994,
+59012,
+59012,
+59019,
+59055,
+59110,
+59110,
+59110,
+59110,
+59135,
+59153,
+59153,
59180,
-59185,
-59192,
-59192,
-59192,
-59219,
-59229,
-59229,
-59229,
-59229,
-59229,
-59239,
-59239,
-59250,
-59265,
-59288,
-59306,
-59306,
-59318,
-59329,
-59329,
-59350,
-59368,
-59377,
-59394,
-59417,
+59186,
+59196,
+59210,
+59236,
+59244,
+59244,
+59244,
+59276,
+59282,
+59300,
+59300,
+59342,
+59351,
+59372,
+59390,
+59402,
+59418,
+59444,
+59444,
59444,
-59465,
-59465,
-59472,
-59472,
-59472,
-59479,
-59479,
-59479,
-59497,
-59514,
-59514,
-59514,
-59528,
-59528,
-59554,
-59554,
-59592,
-59597,
-59628,
-59669,
-59676,
-59683,
-59690,
-59690,
-59719,
-59757,
-59757,
-59764,
+59444,
+59482,
+59495,
+59495,
+59525,
+59545,
+59568,
+59578,
+59584,
+59584,
+59596,
+59596,
+59596,
+59596,
+59615,
+59625,
+59663,
+59663,
+59670,
+59711,
+59731,
+59731,
+59761,
59782,
-59793,
-59819,
-59823,
-59835,
-59850,
-59879,
-59886,
-59893,
-59903,
-59903,
-59918,
-59918,
-59935,
-59963,
-59963,
-60006,
-60030,
-60034,
-60041,
-60041,
-60060,
-60060,
-60074,
-60074,
-60103,
-60103,
-60110,
-60124,
-60138,
-60138,
-60138,
-60152,
-60162,
-60171,
-60186,
-60186,
-60192,
-60240,
-60260,
-60298,
-60298,
-60298,
-60340,
-60354,
-60361,
-60390,
-60390,
-60408,
-60446,
-60452,
-60452,
-60475,
-60482,
-60489,
-60509,
-60509,
-60509,
-60524,
-60531,
-60531,
-60557,
-60564,
-60581,
-60586,
-60629,
-60629,
-60629,
-60629,
-60629,
-60636,
-60663,
-60675,
-60675,
-60682,
-60704,
-60704,
-60724,
-60776,
-60809,
-60832,
-60849,
-60870,
-60877,
-60907,
-60956,
-60956,
-60989,
+59837,
+59837,
+59862,
+59904,
+59931,
+59931,
+59931,
+59931,
+59946,
+59958,
+59958,
+59958,
+59958,
+59958,
+59981,
+60003,
+60003,
+60003,
+60012,
+60012,
+60012,
+60039,
+60047,
+60088,
+60116,
+60161,
+60195,
+60195,
+60227,
+60238,
+60256,
+60283,
+60292,
+60296,
+60301,
+60325,
+60325,
+60325,
+60335,
+60335,
+60368,
+60368,
+60368,
+60399,
+60440,
+60449,
+60470,
+60485,
+60499,
+60535,
+60535,
+60542,
+60550,
+60550,
+60562,
+60562,
+60569,
+60614,
+60614,
+60614,
+60634,
+60634,
+60648,
+60648,
+60648,
+60669,
+60669,
+60690,
+60698,
+60698,
+60723,
+60752,
+60772,
+60772,
+60772,
+60788,
+60788,
+60810,
+60821,
+60846,
+60869,
+60899,
+60916,
+60916,
+60916,
+60916,
+60925,
+60931,
+60931,
+60931,
+60931,
+60938,
+60972,
+60972,
+60972,
+60985,
+60985,
+61003,
+61003,
+61003,
+61003,
+61003,
+61003,
61003,
-61024,
-61048,
-61062,
-61069,
-61101,
-61101,
-61101,
-61101,
-61125,
-61138,
-61155,
-61162,
-61162,
-61184,
-61184,
-61184,
-61184,
-61184,
-61184,
-61216,
-61242,
-61296,
-61296,
-61296,
-61303,
-61303,
-61303,
-61334,
-61360,
-61360,
-61397,
-61416,
-61423,
-61448,
-61476,
-61483,
-61483,
+61003,
+61003,
+61031,
+61031,
+61044,
+61056,
+61072,
+61108,
+61146,
+61146,
+61146,
+61146,
+61207,
+61231,
+61231,
+61250,
+61257,
+61257,
+61288,
+61288,
+61322,
+61322,
+61338,
+61338,
+61343,
+61352,
+61352,
+61373,
+61383,
+61389,
+61436,
+61443,
+61449,
+61503,
+61520,
+61520,
+61520,
+61520,
61532,
-61539,
-61560,
-61578,
-61578,
-61578,
-61617,
-61624,
+61544,
+61557,
+61557,
+61557,
+61557,
+61563,
+61563,
+61591,
+61610,
+61631,
61631,
-61681,
-61706,
-61721,
-61721,
-61729,
-61729,
-61764,
-61776,
-61776,
-61776,
-61808,
-61831,
-61831,
-61837,
-61846,
-61846,
+61631,
+61651,
+61659,
+61691,
+61726,
+61744,
+61744,
+61748,
+61758,
+61794,
+61829,
+61836,
+61856,
+61856,
61864,
-61883,
-61890,
-61910,
-61910,
-61910,
-61917,
-61917,
-61954,
-61954,
-61954,
-61961,
-61968,
-61978,
-62000,
-62007,
-62014,
-62028,
-62042,
-62077,
-62102,
-62109,
-62109,
-62116,
-62116,
-62123,
-62156,
-62163,
-62197,
-62197,
-62197,
-62218,
-62218,
-62232,
-62250,
-62257,
-62286,
-62286,
-62293,
-62300,
-62320,
-62382,
-62430,
-62437,
-62484,
-62484,
-62498,
-62540,
-62552,
-62559,
-62559,
-62559,
-62573,
-62583,
-62592,
-62592,
-62596,
-62628,
-62649,
-62674,
-62674,
-62694,
-62699,
-62699,
-62734,
+61897,
+61924,
+61924,
+61924,
+61924,
+61924,
+61946,
+61946,
+61962,
+61977,
+62005,
+62015,
+62015,
+62033,
+62033,
+62033,
+62065,
+62075,
+62075,
+62087,
+62104,
+62104,
+62104,
+62104,
+62138,
+62138,
+62165,
+62165,
+62193,
+62220,
+62235,
+62235,
+62255,
+62262,
+62269,
+62269,
+62269,
+62269,
+62269,
+62282,
+62282,
+62291,
+62307,
+62307,
+62307,
+62316,
+62316,
+62333,
+62333,
+62344,
+62370,
+62392,
+62392,
+62392,
+62396,
+62411,
+62411,
+62411,
+62418,
+62422,
+62463,
+62463,
+62486,
+62500,
+62504,
+62512,
+62512,
+62522,
+62539,
+62544,
+62557,
+62567,
+62567,
+62567,
+62571,
+62571,
+62571,
+62575,
+62575,
+62575,
+62575,
+62591,
+62591,
+62632,
+62638,
+62638,
+62638,
+62648,
+62675,
+62675,
+62675,
+62675,
+62696,
+62696,
+62715,
+62715,
+62732,
62745,
-62752,
-62759,
-62773,
-62773,
-62804,
-62821,
-62821,
-62825,
-62836,
-62874,
+62801,
+62828,
+62853,
+62853,
+62863,
+62863,
+62879,
62884,
-62911,
-62923,
-62923,
-62935,
-62941,
-62963,
-62987,
-63002,
-63002,
-63027,
-63027,
-63027,
-63027,
+62884,
+62893,
+62929,
+62949,
+62949,
+62961,
+62980,
+62998,
+63007,
+63017,
63027,
-63045,
-63045,
-63057,
-63064,
-63064,
-63108,
-63121,
-63136,
-63136,
-63136,
-63136,
-63136,
-63136,
-63143,
-63143,
-63178,
-63178,
-63178,
-63215,
-63238,
-63264,
-63279,
-63315,
-63337,
-63337,
-63360,
-63360,
-63364,
-63378,
-63378,
-63426,
-63440,
-63460,
-63460,
-63460,
-63460,
+63034,
+63034,
+63050,
+63050,
+63050,
+63050,
+63088,
+63111,
+63111,
+63111,
+63111,
+63111,
+63111,
+63111,
+63111,
+63142,
+63155,
+63155,
+63165,
+63165,
+63165,
+63172,
+63172,
+63172,
+63172,
+63172,
+63172,
+63172,
+63191,
+63191,
+63201,
+63221,
+63230,
+63230,
+63230,
+63230,
+63249,
+63254,
+63254,
+63266,
+63266,
+63287,
+63287,
+63313,
+63327,
+63327,
+63327,
+63327,
+63346,
+63377,
+63377,
+63377,
+63392,
+63392,
+63392,
+63392,
+63392,
+63412,
+63412,
+63431,
+63437,
+63437,
63464,
-63468,
-63491,
-63517,
-63517,
-63535,
-63548,
-63548,
-63601,
-63624,
-63643,
-63660,
-63660,
-63702,
-63714,
-63714,
-63714,
-63723,
-63742,
-63742,
-63742,
-63761,
-63779,
-63790,
-63805,
-63805,
-63805,
+63473,
+63479,
+63494,
+63509,
+63509,
+63520,
+63520,
+63520,
+63520,
+63520,
+63547,
+63547,
+63547,
+63547,
+63547,
+63582,
+63614,
+63632,
+63632,
+63640,
+63640,
+63664,
+63664,
+63664,
+63677,
+63690,
+63690,
+63713,
+63738,
+63738,
+63771,
+63788,
+63788,
+63811,
+63811,
+63818,
+63818,
+63818,
+63818,
+63830,
63852,
-63858,
-63880,
-63910,
-63927,
-63938,
-63938,
-63985,
-63985,
-64010,
-64010,
-64010,
-64017,
-64017,
-64049,
-64049,
-64065,
-64083,
-64083,
-64102,
-64102,
-64102,
-64110,
-64110,
-64122,
-64122,
-64156,
-64186,
-64186,
+63863,
+63863,
+63883,
+63883,
+63887,
+63887,
+63920,
+63931,
+63956,
+63956,
+63956,
+63975,
+64026,
+64030,
+64067,
+64067,
+64067,
+64080,
+64080,
+64097,
+64124,
+64124,
+64139,
+64139,
+64139,
+64139,
+64148,
+64148,
+64148,
+64148,
+64173,
64193,
-64232,
-64249,
-64269,
-64287,
-64287,
-64330,
-64361,
-64379,
-64407,
-64412,
-64412,
-64431,
-64453,
-64461,
-64498,
-64512,
-64512,
-64512,
-64553,
-64558,
-64558,
-64614,
+64200,
+64217,
+64231,
+64235,
+64241,
+64241,
+64279,
+64313,
+64332,
+64345,
+64368,
+64424,
+64430,
+64448,
+64479,
+64496,
+64514,
+64574,
+64574,
+64595,
+64599,
+64618,
+64643,
64657,
-64657,
-64657,
-64694,
-64694,
-64694,
-64710,
-64710,
-64717,
-64735,
-64735,
-64745,
-64755,
-64763,
-64782,
-64782,
-64782,
-64782,
-64782,
-64796,
-64796,
-64796,
-64822,
-64822,
-64839,
-64839,
-64855,
-64866,
+64672,
+64691,
+64691,
+64691,
+64691,
+64728,
+64742,
+64760,
+64760,
+64787,
+64819,
+64819,
+64837,
+64844,
+64860,
64874,
-64889,
-64906,
-64934,
-64963,
-64963,
-64963,
-64963,
-64969,
-64982,
-64982,
-64982,
-64996,
-64996,
-64996,
-65008,
-65033,
-65045,
-65045,
-65045,
-65060,
-65075,
-65075,
-65075,
-65075,
-65100,
-65121,
-65121,
-65126,
+64885,
+64885,
+64891,
+64901,
+64953,
+64953,
+64953,
+64967,
+64997,
+64997,
+64997,
+65020,
+65027,
+65044,
+65051,
+65062,
+65078,
+65099,
+65099,
+65099,
65126,
-65126,
-65150,
-65159,
-65159,
-65184,
-65184,
-65206,
-65206,
-65222,
-65228,
-65247,
-65256,
-65263,
-65275,
-65275,
-65294,
-65308,
+65133,
+65162,
+65209,
+65217,
+65234,
+65265,
+65265,
+65265,
+65285,
+65285,
+65291,
+65291,
+65291,
65308,
-65359,
-65359,
-65359,
-65381,
-65381,
-65397,
-65415,
-65465,
-65476,
-65482,
-65490,
-65490,
+65328,
+65335,
+65341,
+65353,
+65366,
+65390,
+65408,
+65418,
+65429,
+65440,
+65440,
+65457,
+65466,
65496,
-65532,
-65559,
-65603,
+65502,
+65508,
+65508,
+65517,
+65535,
+65554,
+65558,
+65564,
+65564,
+65570,
+65581,
65607,
-65607,
-65633,
-65643,
-65715,
-65721,
-65782,
-65782,
-65782,
-65810,
-65825,
-65825,
-65831,
-65831,
-65831,
-65831,
-65845,
-65850,
-65863,
-65873,
-65882,
-65882,
-65886,
-65904,
-65923,
-65923,
-65939,
-65983,
-65995,
-65995,
-66004,
-66035,
-66061,
-66092,
-66112,
-66112,
-66121,
-66150,
-66162,
-66166,
-66166,
-66175,
-66175,
-66200,
-66230,
-66249,
-66275,
-66292,
-66313,
-66317,
-66317,
-66337,
-66344,
-66344,
-66351,
+65627,
+65635,
+65635,
+65635,
+65635,
+65647,
+65685,
+65693,
+65712,
+65729,
+65729,
+65734,
+65734,
+65734,
+65755,
+65776,
+65776,
+65793,
+65808,
+65828,
+65842,
+65878,
+65891,
+65891,
+65891,
+65982,
+65989,
+66003,
+66003,
+66003,
+66023,
+66057,
+66088,
+66101,
+66132,
+66139,
+66146,
+66146,
+66159,
+66159,
+66182,
+66182,
+66182,
+66189,
+66217,
+66259,
+66271,
+66271,
+66285,
+66297,
+66332,
+66349,
+66349,
66364,
66364,
-66381,
-66391,
-66391,
-66391,
-66400,
-66400,
-66411,
-66411,
-66416,
-66416,
-66436,
-66448,
-66455,
-66469,
-66478,
-66478,
-66478,
-66482,
-66482,
-66482,
-66482,
-66492,
-66492,
-66501,
-66511,
-66518,
-66531,
-66541,
-66541,
-66561,
-66561,
-66561,
-66576,
-66576,
-66576,
-66576,
-66576,
-66576,
-66602,
-66602,
-66614,
-66619,
-66619,
-66619,
-66680,
-66685,
-66685,
-66685,
-66707,
-66716,
-66716,
-66716,
-66716,
-66716,
-66729,
-66748,
-66748,
-66804,
-66814,
-66814,
-66814,
-66822,
-66832,
-66876,
-66876,
-66895,
-66895,
-66905,
-66914,
-66933,
-66942,
-66967,
-66987,
-66987,
-66998,
+66421,
+66449,
+66463,
+66503,
+66535,
+66548,
+66555,
+66555,
+66570,
+66570,
+66580,
+66580,
+66587,
+66587,
+66587,
+66603,
+66631,
+66631,
+66650,
+66650,
+66675,
+66695,
+66702,
+66702,
+66702,
+66702,
+66709,
+66709,
+66739,
+66755,
+66762,
+66762,
+66775,
+66805,
+66823,
+66835,
+66841,
+66841,
+66841,
+66841,
+66841,
+66841,
+66861,
+66907,
+66907,
+66907,
+66907,
+66907,
+66922,
+66940,
+66940,
+66940,
+66940,
+66975,
+66975,
+66975,
+67002,
67016,
-67024,
-67034,
-67034,
-67043,
-67043,
-67043,
-67062,
-67103,
-67103,
-67112,
-67145,
-67145,
-67160,
-67168,
-67168,
-67168,
-67176,
-67205,
-67242,
-67242,
-67242,
-67256,
-67276,
-67276,
-67276,
-67276,
-67297,
-67345,
-67345,
-67345,
-67345,
-67345,
-67358,
-67362,
-67382,
-67382,
-67382,
-67388,
-67422,
-67422,
-67454,
-67454,
-67472,
-67488,
-67506,
-67506,
-67506,
-67506,
-67525,
-67525,
-67544,
-67560,
-67578,
-67578,
-67578,
-67583,
-67600,
-67614,
-67641,
-67659,
-67675,
-67706,
+67032,
+67032,
+67039,
+67069,
+67075,
+67086,
+67119,
+67146,
+67146,
+67151,
+67167,
+67197,
+67197,
+67214,
+67214,
+67221,
+67236,
+67236,
+67249,
+67265,
+67279,
+67306,
+67313,
+67336,
+67353,
+67404,
+67420,
+67420,
+67420,
+67420,
+67420,
+67420,
+67429,
+67429,
+67446,
+67446,
+67462,
+67462,
+67473,
+67480,
+67490,
+67511,
+67511,
+67568,
+67605,
+67639,
+67646,
+67682,
+67689,
+67696,
+67702,
+67720,
67744,
-67761,
-67801,
-67801,
-67837,
-67837,
-67844,
-67844,
-67844,
-67844,
-67844,
-67854,
-67873,
-67907,
-67907,
-67922,
-67922,
-67929,
-67947,
-67947,
-67977,
-67984,
-67994,
-67994,
-67994,
-68022,
-68038,
-68038,
-68046,
-68087,
-68098,
-68104,
-68104,
-68120,
-68120,
-68120,
-68126,
-68126,
-68138,
-68143,
-68169,
-68169,
-68199,
-68241,
-68256,
-68279,
-68279,
-68279,
+67763,
+67763,
+67782,
+67806,
+67806,
+67806,
+67810,
+67817,
+67817,
+67827,
+67840,
+67840,
+67840,
+67840,
+67840,
+67847,
+67867,
+67874,
+67874,
+67886,
+67886,
+67920,
+67927,
+67932,
+67960,
+67967,
+67974,
+67992,
+67992,
+68004,
+68004,
+68031,
+68031,
+68063,
+68088,
+68095,
+68112,
+68112,
+68112,
+68127,
+68135,
+68146,
+68176,
+68193,
+68200,
+68221,
+68228,
+68245,
+68245,
+68280,
+68280,
68320,
-68330,
-68330,
-68335,
-68335,
-68356,
-68390,
-68390,
-68407,
-68434,
-68434,
+68345,
+68352,
+68383,
+68425,
+68445,
+68445,
68452,
-68475,
-68484,
-68514,
-68524,
-68524,
-68524,
-68524,
-68524,
-68532,
-68532,
-68532,
-68556,
-68572,
-68587,
-68587,
-68594,
-68594,
-68604,
-68604,
-68621,
-68693,
-68703,
-68737,
-68759,
-68784,
-68784,
-68808,
-68808,
-68808,
-68822,
-68822,
-68881,
-68881,
-68881,
-68919,
-68919,
+68479,
+68503,
+68510,
+68517,
+68576,
+68583,
+68628,
+68642,
+68646,
+68662,
+68701,
+68717,
+68724,
+68724,
+68733,
+68740,
+68756,
+68777,
+68777,
+68777,
+68777,
+68791,
+68803,
+68803,
+68825,
+68843,
+68857,
+68879,
+68907,
+68907,
+68907,
68919,
-68934,
-68934,
-68934,
-68951,
-68969,
-68991,
-69022,
-69022,
-69022,
-69022,
-69043,
-69052,
-69052,
-69123,
-69141,
-69141,
-69155,
-69177,
-69194,
-69194,
-69194,
-69212,
-69223,
-69223,
-69241,
-69257,
-69271,
-69300,
-69300,
-69300,
-69300,
-69332,
-69367,
-69377,
-69377,
-69381,
-69427,
-69427,
-69427,
-69459,
-69476,
-69524,
-69543,
-69573,
-69573,
-69585,
-69585,
-69585,
+68959,
+68994,
+69006,
+69023,
+69023,
+69040,
+69055,
+69055,
+69076,
+69102,
+69102,
+69140,
+69149,
+69165,
+69183,
+69221,
+69228,
+69235,
+69256,
+69256,
+69256,
+69268,
+69292,
+69326,
+69363,
+69380,
+69380,
+69380,
+69380,
+69405,
+69417,
+69445,
+69445,
+69464,
+69464,
+69464,
+69464,
+69464,
+69480,
+69508,
+69544,
+69544,
+69557,
+69557,
+69557,
+69587,
69607,
-69683,
-69698,
-69698,
-69698,
-69698,
-69756,
-69778,
-69792,
-69818,
-69828,
-69853,
-69853,
-69876,
+69628,
+69655,
+69725,
+69749,
+69760,
+69796,
+69803,
+69847,
+69872,
+69872,
69893,
-69916,
-69916,
-69916,
-69916,
-69931,
-69944,
-69952,
-69952,
-69982,
-69982,
-69987,
-70026,
-70042,
-70042,
-70059,
-70078,
-70078,
-70135,
-70143,
-70143,
-70158,
-70167,
-70167,
-70167,
-70188,
-70224,
-70260,
-70260,
-70260,
-70287,
-70298,
-70298,
-70314,
-70323,
-70351,
-70382,
-70382,
-70393,
-70402,
-70440,
-70440,
-70440,
-70440,
-70440,
-70448,
-70448,
-70448,
-70472,
-70472,
-70472,
-70472,
-70503,
-70503,
-70503,
+69893,
+69893,
+69893,
+69893,
+69902,
+69926,
+69941,
+69948,
+69948,
+69965,
+69979,
+69986,
+69993,
+70000,
+70005,
+70030,
+70050,
+70057,
+70064,
+70091,
+70117,
+70163,
+70163,
+70170,
+70180,
+70211,
+70218,
+70264,
+70264,
+70278,
+70285,
+70285,
+70332,
+70332,
+70337,
+70337,
+70337,
+70361,
+70368,
+70385,
+70392,
+70410,
+70429,
+70435,
+70435,
+70435,
+70435,
+70442,
+70442,
+70456,
+70485,
70503,
-70551,
-70551,
-70564,
-70564,
-70564,
-70564,
-70564,
+70512,
+70521,
+70521,
+70525,
+70525,
+70563,
+70575,
+70586,
+70586,
+70586,
+70603,
70609,
-70609,
-70620,
-70620,
-70627,
-70634,
-70651,
-70651,
-70657,
-70663,
-70663,
-70681,
-70687,
-70694,
-70694,
-70701,
-70714,
-70724,
-70724,
-70724,
-70755,
-70755,
-70755,
-70755,
-70755,
-70755,
-70755,
-70755,
-70786,
-70786,
-70808,
-70808,
-70826,
-70826,
-70826,
-70852,
-70852,
-70852,
-70852,
-70852,
-70852,
-70852,
-70852,
-70860,
-70908,
-70918,
-70926,
-70943,
-70943,
-71014,
-71014,
-71014,
-71023,
-71031,
-71049,
-71049,
-71073,
-71073,
-71094,
-71094,
-71103,
-71103,
-71132,
-71149,
-71149,
-71167,
+70640,
+70656,
+70664,
+70664,
+70670,
+70685,
+70692,
+70710,
+70731,
+70750,
+70767,
+70785,
+70816,
+70823,
+70839,
+70839,
+70853,
+70853,
+70853,
+70871,
+70889,
+70889,
+70889,
+70907,
+70916,
+70955,
+70955,
+70970,
+70970,
+70990,
+70998,
+70998,
+70998,
+71024,
+71045,
+71051,
+71058,
+71058,
+71058,
+71058,
+71058,
+71058,
+71058,
+71074,
+71096,
+71096,
+71105,
+71105,
+71112,
+71112,
+71119,
+71135,
+71135,
+71152,
+71152,
+71152,
+71152,
+71170,
71177,
-71195,
-71204,
-71204,
-71224,
-71248,
-71248,
-71252,
-71273,
-71279,
-71279,
-71279,
-71313,
-71319,
-71319,
-71319,
-71319,
-71336,
-71336,
-71336,
-71336,
-71336,
-71357,
-71367,
-71367,
-71391,
-71457,
-71457,
-71465,
-71465,
-71469,
+71199,
+71199,
+71199,
+71210,
+71210,
+71238,
+71238,
+71238,
+71238,
+71243,
+71243,
+71243,
+71261,
+71288,
+71302,
+71318,
+71361,
+71361,
+71361,
+71389,
+71389,
+71389,
+71410,
+71422,
+71439,
+71439,
+71439,
+71439,
+71439,
+71449,
+71449,
+71449,
71469,
-71487,
-71521,
-71521,
-71559,
-71559,
-71559,
-71559,
-71559,
-71591,
-71618,
-71618,
-71624,
-71650,
-71650,
-71650,
-71680,
-71680,
-71680,
-71680,
-71708,
-71720,
+71483,
+71490,
+71490,
+71494,
+71506,
+71544,
+71544,
+71571,
+71580,
+71580,
+71580,
+71580,
+71593,
+71611,
+71626,
+71626,
+71640,
+71653,
+71653,
+71653,
+71665,
+71684,
+71700,
+71729,
+71729,
+71729,
71729,
-71752,
-71752,
-71752,
-71752,
-71757,
-71757,
-71793,
-71805,
-71805,
-71805,
-71805,
-71805,
-71805,
-71805,
-71810,
-71810,
-71820,
-71840,
-71888,
-71911,
-71911,
-71921,
-71932,
-71968,
-71992,
-71992,
-72002,
-72002,
-72002,
-72013,
-72013,
+71741,
+71741,
+71748,
+71809,
+71818,
+71818,
+71836,
+71876,
+71926,
+71946,
+71946,
+71946,
+71946,
+71946,
+71971,
+71984,
+71984,
+71994,
+72010,
+72010,
+72010,
+72010,
+72010,
+72010,
72035,
-72046,
-72074,
-72099,
-72099,
-72135,
-72135,
-72135,
-72145,
-72202,
-72202,
-72202,
-72227,
-72234,
+72079,
+72079,
+72102,
+72129,
+72138,
+72151,
+72151,
+72151,
+72151,
+72162,
+72162,
+72166,
+72166,
+72166,
+72175,
+72175,
+72175,
+72191,
+72191,
+72191,
+72191,
+72191,
+72191,
72242,
-72247,
-72255,
-72255,
-72255,
-72277,
-72277,
-72277,
-72284,
-72284,
-72329,
+72242,
+72242,
+72248,
+72264,
+72282,
+72290,
+72308,
+72324,
+72345,
+72345,
+72345,
72345,
-72382,
-72382,
-72382,
-72393,
+72351,
+72370,
+72370,
+72401,
+72401,
72407,
72407,
-72428,
-72436,
-72436,
-72467,
-72495,
-72495,
-72504,
-72504,
-72504,
-72526,
-72553,
+72407,
+72407,
+72435,
+72453,
+72453,
+72453,
+72468,
+72486,
+72506,
+72512,
+72512,
+72537,
+72537,
+72556,
+72567,
72579,
-72585,
72601,
-72640,
-72650,
-72656,
-72661,
-72661,
-72669,
-72688,
-72688,
-72688,
-72730,
-72743,
-72743,
-72764,
-72779,
-72803,
-72813,
-72813,
-72813,
-72825,
-72825,
-72857,
-72866,
-72895,
-72895,
-72934,
-72969,
-72969,
-72969,
-72969,
-73020,
-73020,
-73033,
-73046,
-73057,
-73057,
-73057,
-73069,
-73078,
-73082,
-73082,
-73109,
-73129,
-73174,
-73180,
-73180,
-73180,
-73186,
-73186,
-73196,
-73196,
-73196,
-73212,
-73230,
-73230,
-73254,
-73260,
-73260,
-73274,
-73281,
-73311,
-73311,
-73311,
-73337,
-73368,
-73381,
+72613,
+72619,
+72625,
+72625,
+72631,
+72637,
+72667,
+72680,
+72692,
+72692,
+72692,
+72710,
+72720,
+72720,
+72733,
+72733,
+72741,
+72741,
+72752,
+72765,
+72771,
+72771,
+72771,
+72771,
+72785,
+72785,
+72807,
+72807,
+72827,
+72834,
+72843,
+72878,
+72878,
+72892,
+72901,
+72901,
+72901,
+72906,
+72916,
+72916,
+72916,
+72927,
+72927,
+72927,
+72927,
+72963,
+72963,
+72963,
+72963,
+72963,
+72963,
+72985,
+73029,
+73044,
+73064,
+73064,
+73064,
+73064,
+73064,
+73064,
+73073,
+73073,
+73093,
+73120,
+73126,
+73144,
+73144,
+73159,
+73159,
+73165,
+73165,
+73203,
+73213,
+73238,
+73258,
+73273,
+73273,
+73273,
+73273,
+73273,
+73287,
+73303,
+73335,
+73359,
+73365,
+73387,
+73402,
73402,
-73435,
-73456,
-73456,
-73456,
-73456,
-73472,
-73472,
-73488,
-73488,
-73488,
-73488,
-73488,
-73488,
+73402,
+73413,
+73413,
+73413,
+73423,
+73442,
+73468,
+73485,
+73485,
73503,
-73522,
-73522,
-73522,
-73530,
-73530,
-73559,
-73616,
-73637,
-73662,
-73685,
-73700,
-73700,
-73711,
-73745,
-73755,
-73790,
-73815,
-73815,
-73815,
-73815,
-73821,
-73844,
-73867,
-73883,
-73907,
-73907,
-73942,
-73974,
-73974,
-73974,
-74007,
-74026,
-74043,
-74043,
-74057,
-74063,
-74079,
-74079,
-74102,
-74102,
-74102,
-74125,
-74136,
-74136,
-74136,
-74136,
-74158,
-74164,
-74164,
-74164,
-74172,
-74188,
-74188,
-74210,
-74246,
-74256,
-74256,
-74256,
-74264,
-74300,
-74312,
-74320,
-74328,
-74360,
-74360,
+73537,
+73575,
+73575,
+73610,
+73629,
+73635,
+73635,
+73635,
+73635,
+73658,
+73658,
+73681,
+73687,
+73687,
+73712,
+73736,
+73753,
+73780,
+73797,
+73816,
+73838,
+73850,
+73850,
+73863,
+73909,
+73918,
+73930,
+73946,
+73976,
+73986,
+73986,
+73986,
+73986,
+73990,
+74017,
+74017,
+74017,
+74025,
+74025,
+74025,
+74025,
+74055,
+74073,
+74073,
+74073,
+74084,
+74095,
+74095,
+74095,
+74123,
+74150,
+74150,
+74155,
+74155,
+74155,
+74155,
+74161,
+74170,
+74176,
+74193,
+74216,
+74224,
+74266,
+74266,
+74277,
+74277,
+74289,
+74289,
+74295,
+74330,
+74330,
+74342,
+74348,
74383,
-74389,
-74401,
-74413,
-74430,
-74430,
-74430,
-74460,
-74486,
-74486,
-74486,
-74486,
-74486,
-74510,
-74531,
-74531,
-74561,
-74601,
-74620,
-74631,
-74631,
-74674,
-74674,
-74684,
-74684,
-74695,
-74710,
-74710,
-74719,
-74748,
-74773,
-74781,
-74789,
-74789,
-74809,
-74809,
-74809,
-74825,
-74845,
-74845,
-74857,
-74891,
-74891,
-74891,
-74891,
-74891,
-74925,
+74420,
+74420,
+74426,
+74426,
+74451,
+74469,
+74483,
+74500,
+74500,
+74515,
+74520,
+74520,
+74537,
+74547,
+74547,
+74547,
+74558,
+74558,
+74571,
+74578,
+74590,
+74590,
+74603,
+74619,
+74628,
+74628,
+74634,
+74634,
+74634,
+74655,
+74667,
+74691,
+74702,
+74725,
+74725,
+74725,
+74725,
+74730,
+74730,
+74730,
+74730,
+74736,
+74758,
+74764,
+74764,
+74764,
+74764,
+74784,
+74803,
+74803,
+74832,
+74832,
+74856,
+74867,
+74867,
+74885,
+74890,
+74890,
+74910,
74925,
74925,
-74943,
-74988,
-75011,
-75011,
-75011,
-75011,
-75011,
-75021,
-75021,
-75037,
-75037,
-75064,
-75097,
-75102,
-75102,
-75140,
-75140,
-75158,
-75158,
-75172,
-75172,
-75193,
-75193,
-75212,
-75227,
-75245,
-75256,
-75272,
+74939,
+74939,
+74954,
+74963,
+74989,
+74996,
+74996,
+75013,
+75013,
+75013,
+75042,
+75059,
+75067,
+75108,
+75128,
+75136,
+75155,
+75160,
+75160,
+75173,
+75173,
+75173,
+75173,
+75179,
+75179,
+75190,
+75213,
+75217,
+75236,
+75236,
+75265,
+75265,
75283,
-75293,
-75308,
-75315,
-75315,
-75341,
-75356,
-75367,
-75397,
-75397,
-75453,
-75471,
-75471,
-75471,
-75485,
-75534,
-75534,
-75534,
-75545,
-75551,
-75551,
-75551,
-75564,
-75576,
-75609,
-75621,
-75638,
-75671,
-75681,
-75696,
-75702,
-75702,
-75714,
-75714,
-75721,
-75736,
-75736,
-75743,
+75294,
+75311,
+75311,
+75317,
+75317,
+75325,
+75345,
+75370,
+75370,
+75382,
+75382,
+75382,
+75411,
+75417,
+75434,
+75443,
+75449,
+75455,
+75478,
+75484,
+75517,
+75542,
+75548,
+75561,
+75561,
+75567,
+75573,
+75573,
+75579,
+75579,
+75593,
+75593,
+75593,
+75593,
+75599,
+75615,
+75651,
+75685,
+75692,
+75713,
+75719,
+75725,
+75737,
+75746,
+75750,
+75750,
75761,
-75770,
-75778,
-75778,
-75778,
-75778,
-75778,
-75805,
-75805,
-75823,
-75834,
-75840,
-75857,
-75893,
-75893,
-75893,
-75893,
-75893,
+75783,
+75789,
+75804,
+75814,
+75814,
+75814,
+75833,
+75833,
+75867,
+75867,
+75867,
+75867,
75904,
+75909,
+75928,
+75928,
+75928,
+75928,
+75928,
75945,
-75945,
-75958,
-75958,
-75958,
-75977,
-76016,
-76031,
-76037,
-76037,
-76051,
-76051,
-76079,
-76084,
-76084,
-76102,
-76120,
+75959,
+75973,
+75973,
+75995,
+76066,
+76066,
+76066,
+76082,
+76082,
+76082,
+76098,
+76109,
76120,
76120,
76120,
-76134,
-76166,
-76175,
-76205,
-76216,
-76216,
-76227,
-76244,
-76275,
-76284,
-76318,
-76337,
-76343,
-76389,
-76389,
-76389,
-76389,
-76402,
-76416,
-76416,
-76434,
-76434,
-76444,
-76497,
-76497,
-76509,
-76519,
-76566,
-76604,
-76611,
-76611,
-76611,
-76640,
-76654,
-76654,
-76654,
-76654,
-76671,
-76671,
-76676,
-76676,
-76697,
-76697,
-76697,
-76697,
-76707,
-76751,
-76751,
-76751,
-76774,
-76778,
-76807,
-76807,
-76807,
-76830,
-76830,
-76848,
+76129,
+76149,
+76170,
+76170,
+76170,
+76170,
+76170,
+76186,
+76199,
+76199,
+76199,
+76218,
+76235,
+76249,
+76261,
+76300,
+76305,
+76328,
+76342,
+76366,
+76366,
+76399,
+76413,
+76413,
+76413,
+76431,
+76437,
+76459,
+76459,
+76475,
+76475,
+76475,
+76475,
+76475,
+76475,
+76482,
+76493,
+76493,
+76501,
+76501,
+76515,
+76532,
+76532,
+76544,
+76544,
+76578,
+76603,
+76603,
+76612,
+76628,
+76644,
+76657,
+76666,
+76705,
+76705,
+76730,
+76730,
+76740,
+76740,
+76757,
+76804,
+76816,
+76832,
+76832,
+76832,
+76832,
+76847,
76864,
-76897,
-76913,
-76932,
-76932,
-76944,
-76970,
-76986,
-76986,
-77002,
-77017,
-77022,
-77039,
-77049,
-77049,
-77049,
-77067,
-77067,
-77067,
-77081,
-77081,
-77081,
-77089,
-77089,
-77105,
-77121,
-77121,
-77156,
-77156,
-77156,
-77156,
-77156,
-77165,
-77173,
-77173,
-77173,
-77173,
-77191,
-77211,
-77211,
-77211,
-77218,
-77242,
+76871,
+76881,
+76881,
+76917,
+76929,
+76929,
+76938,
+76938,
+76938,
+76938,
+76960,
+76979,
+77000,
+77041,
+77058,
+77058,
+77066,
+77084,
+77084,
+77084,
+77106,
+77122,
+77122,
+77122,
+77122,
+77143,
+77152,
+77152,
+77152,
+77158,
+77158,
+77158,
+77158,
+77158,
+77158,
+77171,
+77183,
+77183,
+77188,
+77188,
+77188,
+77188,
+77188,
+77204,
+77204,
+77227,
+77251,
+77251,
+77251,
+77270,
+77290,
+77290,
+77290,
77290,
-77308,
-77308,
-77325,
-77343,
-77343,
-77376,
-77376,
-77376,
-77376,
-77386,
-77386,
-77386,
-77386,
+77311,
+77327,
+77327,
+77341,
+77341,
+77358,
+77358,
+77358,
77393,
-77399,
-77419,
-77428,
-77450,
+77393,
+77400,
+77407,
+77407,
+77436,
77450,
+77464,
+77464,
77492,
77492,
-77492,
-77492,
-77529,
-77529,
-77529,
-77540,
-77540,
-77540,
-77557,
-77570,
-77570,
-77570,
-77570,
-77570,
-77570,
-77587,
-77597,
+77508,
+77508,
+77533,
+77545,
+77545,
+77556,
+77578,
+77593,
+77610,
77620,
-77640,
-77640,
-77640,
-77661,
-77680,
-77680,
-77680,
-77680,
-77680,
-77680,
-77712,
-77732,
-77739,
-77739,
-77739,
-77748,
-77765,
-77824,
-77824,
-77834,
-77850,
-77860,
-77860,
-77872,
-77872,
-77889,
-77889,
-77889,
-77902,
-77920,
-77934,
-77962,
-77982,
-77982,
-77982,
-77982,
-78000,
-78000,
-78000,
-78009,
-78025,
-78036,
-78036,
-78043,
-78043,
-78062,
-78072,
-78123,
-78153,
-78167,
-78189,
-78211,
-78211,
-78211,
-78222,
-78222,
-78222,
-78230,
-78230,
-78236,
-78236,
-78236,
-78236,
-78254,
-78254,
-78254,
-78254,
-78254,
-78272,
-78296,
-78313,
-78332,
-78368,
-78384,
-78394,
-78404,
-78411,
-78423,
-78444,
-78451,
-78464,
-78485,
-78501,
-78501,
-78514,
-78514,
-78514,
-78514,
-78523,
-78532,
-78544,
-78544,
-78544,
-78544,
-78544,
-78544,
-78555,
-78575,
-78612,
-78612,
-78641,
-78672,
-78678,
-78678,
-78705,
-78705,
-78720,
-78737,
-78737,
-78753,
-78753,
-78757,
-78778,
-78778,
-78778,
-78819,
-78837,
-78837,
-78837,
-78843,
-78843,
-78853,
-78869,
-78869,
-78908,
-78908,
-78908,
-78908,
-78908,
-78913,
-78958,
-78958,
-78958,
-78969,
-78990,
-79019,
-79019,
-79025,
-79025,
-79025,
-79059,
-79079,
-79079,
-79079,
-79086,
-79086,
-79102,
-79102,
-79102,
-79109,
-79109,
-79109,
-79109,
-79109,
-79109,
-79109,
-79109,
-79109,
-79123,
-79136,
-79155,
+77657,
+77657,
+77693,
+77693,
+77693,
+77693,
+77705,
+77705,
+77705,
+77718,
+77718,
+77734,
+77742,
+77742,
+77781,
+77789,
+77819,
+77830,
+77830,
+77830,
+77830,
+77830,
+77847,
+77870,
+77870,
+77904,
+77904,
+77916,
+77916,
+77942,
+77958,
+77958,
+77958,
+77972,
+77972,
+77972,
+77988,
+77988,
+77994,
+78017,
+78031,
+78044,
+78089,
+78099,
+78129,
+78129,
+78129,
+78129,
+78135,
+78140,
+78155,
+78176,
+78214,
+78235,
+78243,
+78277,
+78277,
+78277,
+78285,
+78312,
+78312,
+78328,
+78339,
+78357,
+78373,
+78389,
+78389,
+78414,
+78432,
+78439,
+78455,
+78484,
+78492,
+78500,
+78536,
+78556,
+78582,
+78582,
+78615,
+78624,
+78664,
+78664,
+78675,
+78675,
+78694,
+78694,
+78709,
+78715,
+78715,
+78724,
+78724,
+78733,
+78733,
+78766,
+78766,
+78780,
+78791,
+78812,
+78812,
+78812,
+78821,
+78865,
+78865,
+78865,
+78865,
+78890,
+78890,
+78890,
+78890,
+78911,
+78911,
+78911,
+78933,
+78943,
+78943,
+78943,
+78943,
+78943,
+78978,
+78986,
+78986,
+78997,
+79027,
+79047,
+79047,
+79078,
+79078,
+79093,
+79093,
+79093,
+79093,
+79093,
+79131,
+79131,
+79152,
+79152,
+79152,
79180,
79180,
-79187,
-79187,
-79187,
-79187,
-79217,
-79217,
-79249,
-79249,
-79266,
+79180,
+79180,
+79202,
+79202,
+79202,
+79221,
+79221,
+79227,
+79233,
+79241,
+79260,
+79260,
+79260,
79266,
-79278,
+79274,
+79274,
79288,
-79288,
-79302,
-79311,
-79311,
-79341,
-79357,
-79357,
-79364,
-79382,
-79395,
-79395,
-79395,
-79395,
-79408,
-79427,
-79444,
-79444,
-79464,
-79484,
-79484,
-79491,
+79303,
+79319,
+79351,
+79374,
+79374,
+79380,
+79390,
+79390,
+79390,
+79396,
+79416,
+79416,
+79426,
+79426,
+79426,
+79443,
+79453,
+79453,
+79472,
+79503,
+79503,
+79508,
79514,
-79526,
-79526,
-79539,
-79571,
-79571,
-79591,
-79626,
-79626,
-79626,
-79656,
-79656,
-79671,
-79671,
-79671,
-79685,
-79685,
-79697,
-79705,
-79722,
-79748,
-79773,
-79773,
-79802,
-79802,
-79802,
-79808,
-79808,
-79818,
-79818,
-79841,
-79841,
-79841,
-79850,
+79530,
+79540,
+79540,
+79548,
+79563,
+79584,
+79636,
+79645,
+79675,
+79682,
+79682,
+79715,
+79725,
+79754,
+79754,
+79774,
+79793,
+79793,
+79816,
+79816,
+79816,
+79831,
+79831,
79850,
-79850,
-79850,
-79850,
-79859,
-79859,
-79876,
-79876,
-79906,
-79927,
-79952,
-79963,
-79974,
-79980,
-79996,
-79996,
-79996,
-79996,
-80014,
-80014,
+79867,
+79867,
+79867,
+79867,
+79875,
+79896,
+79896,
+79896,
+79896,
+79922,
+79922,
+79922,
+79934,
+79934,
+79947,
+79964,
+79964,
+80000,
80014,
80014,
-80014,
-80014,
-80014,
-80044,
-80067,
-80074,
-80090,
-80090,
-80090,
-80090,
-80090,
-80090,
-80123,
-80132,
-80137,
-80152,
-80152,
-80177,
-80194,
-80211,
-80211,
-80231,
-80248,
-80269,
+80025,
+80025,
+80037,
+80071,
+80105,
+80105,
+80111,
+80161,
+80171,
+80181,
+80197,
+80217,
+80227,
+80227,
+80227,
+80252,
+80264,
80276,
-80276,
-80283,
80293,
-80310,
-80310,
-80315,
-80332,
-80352,
-80352,
-80404,
-80415,
-80432,
-80464,
-80492,
-80524,
-80534,
-80541,
-80581,
-80581,
-80588,
-80588,
-80601,
-80618,
-80618,
-80634,
-80652,
-80675,
-80675,
-80682,
-80682,
-80682,
-80682,
-80682,
-80682,
-80704,
-80733,
-80733,
-80749,
-80796,
-80796,
-80812,
-80812,
-80819,
-80819,
-80829,
-80862,
-80885,
-80909,
-80917,
-80917,
+80293,
+80293,
+80293,
+80293,
+80333,
+80339,
+80353,
+80380,
+80421,
+80484,
+80484,
+80484,
+80498,
+80543,
+80543,
+80569,
+80569,
+80578,
+80578,
+80595,
+80616,
+80616,
+80623,
+80631,
+80631,
+80631,
+80649,
+80649,
+80649,
+80649,
+80659,
+80686,
+80703,
+80710,
+80726,
+80741,
+80741,
+80764,
+80764,
+80764,
+80783,
+80799,
+80799,
+80799,
+80833,
+80833,
+80872,
+80872,
+80872,
+80899,
+80916,
+80916,
+80937,
80937,
-80951,
-80951,
-80974,
-80992,
-81014,
-81032,
-81032,
-81032,
-81032,
-81061,
-81069,
-81106,
-81106,
-81111,
-81111,
-81167,
-81201,
-81219,
-81219,
-81219,
-81266,
-81266,
-81280,
-81280,
-81280,
-81287,
-81308,
-81314,
-81336,
-81354,
-81360,
-81360,
-81360,
-81389,
-81410,
-81410,
-81410,
-81410,
-81418,
-81437,
+80937,
+80937,
+80937,
+80947,
+80947,
+80965,
+80965,
+80977,
+80977,
+80986,
+80986,
+80986,
+81006,
+81013,
+81013,
+81023,
+81048,
+81066,
+81066,
+81097,
+81107,
+81118,
+81118,
+81118,
+81140,
+81175,
+81187,
+81187,
+81187,
+81192,
+81192,
+81192,
+81212,
+81240,
+81240,
+81298,
+81298,
+81298,
+81298,
+81310,
+81316,
+81316,
+81327,
+81335,
+81335,
+81342,
+81359,
+81359,
+81359,
+81359,
+81370,
+81370,
+81370,
+81381,
+81395,
+81405,
+81413,
+81447,
+81447,
81460,
81460,
-81485,
-81497,
-81513,
-81525,
-81525,
-81532,
-81543,
-81543,
-81558,
+81471,
+81471,
+81476,
+81495,
+81510,
+81510,
+81526,
+81526,
+81553,
+81571,
+81587,
+81587,
81592,
-81592,
-81613,
-81613,
-81630,
-81637,
-81680,
-81727,
-81727,
-81727,
-81727,
-81732,
-81732,
-81732,
-81732,
+81611,
+81638,
+81638,
+81664,
+81690,
+81696,
+81696,
+81696,
+81721,
+81721,
+81739,
81739,
81739,
-81751,
-81758,
-81758,
-81778,
-81778,
-81785,
-81785,
-81808,
-81830,
-81830,
-81838,
+81749,
+81766,
+81773,
+81773,
+81773,
+81791,
+81791,
+81815,
+81839,
+81846,
81855,
-81868,
-81885,
-81885,
-81892,
-81892,
-81905,
-81905,
-81921,
-81934,
-81959,
-81959,
-81966,
-82004,
+81855,
+81855,
+81879,
+81903,
+81915,
+81939,
+81939,
+81965,
+81985,
82004,
82004,
82021,
-82021,
-82048,
-82048,
-82048,
-82070,
-82093,
-82114,
-82114,
-82114,
-82136,
-82160,
-82182,
-82182,
-82191,
-82198,
-82198,
-82211,
-82245,
-82280,
-82287,
-82287,
-82287,
-82287,
-82308,
-82308,
-82308,
-82315,
-82336,
-82336,
-82336,
-82336,
-82365,
-82375,
-82375,
-82375,
-82375,
-82382,
-82382,
-82417,
-82433,
-82440,
-82474,
-82488,
-82531,
-82531,
-82552,
-82563,
-82581,
-82597,
-82597,
-82613,
-82634,
-82648,
-82654,
-82661,
-82661,
-82661,
-82668,
-82675,
-82690,
-82696,
+82037,
+82082,
+82082,
+82115,
+82154,
+82161,
+82169,
+82169,
+82207,
+82223,
+82233,
+82233,
+82233,
+82233,
+82249,
+82249,
+82249,
+82264,
+82270,
+82283,
+82309,
+82340,
+82353,
+82380,
+82380,
+82400,
+82425,
+82456,
+82462,
+82462,
+82481,
+82481,
+82499,
+82499,
+82499,
+82499,
+82499,
+82499,
+82499,
+82512,
+82547,
+82564,
+82607,
+82607,
+82607,
+82620,
+82629,
+82629,
+82629,
+82640,
+82640,
+82664,
+82664,
+82664,
+82664,
+82664,
+82674,
+82689,
+82689,
+82689,
+82689,
+82703,
82703,
-82717,
+82703,
+82719,
82724,
-82752,
-82752,
-82772,
-82788,
-82795,
-82802,
-82814,
-82837,
-82858,
-82865,
-82888,
-82895,
-82929,
-82948,
-82960,
-82967,
-82981,
-82981,
-82996,
-83015,
-83031,
-83038,
-83045,
-83081,
-83100,
-83149,
-83182,
-83182,
-83206,
-83213,
-83236,
-83236,
-83243,
-83243,
-83249,
-83261,
-83268,
-83268,
+82741,
+82750,
+82750,
+82757,
+82809,
+82821,
+82821,
+82821,
+82821,
+82833,
+82833,
+82863,
+82863,
+82879,
+82898,
+82906,
+82906,
+82923,
+82923,
+82942,
+82942,
+82966,
+83020,
+83020,
+83044,
+83044,
+83067,
+83067,
+83105,
+83105,
+83122,
+83143,
+83161,
+83178,
+83194,
+83210,
+83210,
+83210,
+83210,
+83210,
+83232,
83292,
-83306,
-83328,
-83328,
-83354,
-83361,
-83395,
-83401,
-83415,
-83425,
-83448,
-83454,
-83481,
-83510,
-83558,
-83565,
+83309,
+83323,
+83357,
+83357,
+83406,
+83406,
+83406,
+83406,
+83453,
+83468,
+83487,
+83513,
+83513,
+83513,
+83519,
+83567,
+83580,
83591,
-83607,
-83617,
-83645,
-83658,
-83665,
-83682,
-83682,
-83682,
-83699,
-83733,
-83743,
-83797,
-83813,
-83829,
+83606,
+83616,
+83653,
+83653,
+83670,
+83684,
+83684,
+83684,
+83684,
+83684,
+83695,
+83714,
+83714,
+83714,
+83759,
+83759,
+83759,
+83759,
+83759,
+83759,
+83791,
+83791,
+83791,
+83791,
+83791,
+83791,
+83791,
+83799,
+83799,
+83812,
+83812,
+83822,
+83822,
+83837,
+83837,
+83837,
+83837,
+83843,
83843,
-83855,
-83859,
-83873,
-83873,
-83873,
-83889,
-83904,
-83945,
-83974,
-84021,
-84021,
-84081,
-84092,
-84106,
-84123,
-84140,
-84212,
-84212,
-84212,
-84212,
-84241,
-84248,
-84255,
-84255,
-84262,
-84282,
-84308,
-84308,
-84308,
-84317,
-84317,
-84331,
-84360,
-84384,
-84401,
+83861,
+83861,
+83861,
+83874,
+83888,
+83936,
+83936,
+83950,
+83950,
+83950,
+83963,
+83963,
+83970,
+83995,
+83995,
+84018,
+84040,
+84040,
+84040,
+84040,
+84053,
+84053,
+84074,
+84105,
+84115,
+84154,
+84177,
+84194,
+84211,
+84211,
+84211,
+84211,
+84229,
+84229,
+84245,
+84266,
+84278,
+84285,
+84285,
+84285,
+84285,
+84285,
+84285,
+84285,
+84323,
+84348,
+84368,
+84368,
+84368,
+84368,
+84388,
+84388,
+84388,
+84388,
+84388,
+84388,
84408,
-84455,
-84488,
-84488,
-84530,
-84551,
-84577,
-84577,
-84586,
-84593,
-84612,
-84619,
-84619,
-84666,
+84421,
+84426,
+84433,
+84433,
+84433,
+84433,
+84433,
+84449,
+84472,
+84472,
+84472,
+84472,
+84492,
+84492,
+84499,
+84499,
+84506,
+84506,
+84524,
+84567,
+84585,
+84585,
+84585,
+84585,
+84585,
+84585,
+84608,
+84608,
+84618,
+84618,
+84618,
+84650,
+84670,
+84670,
84682,
-84697,
-84714,
-84766,
-84766,
-84766,
-84766,
-84778,
-84792,
-84799,
-84799,
-84799,
-84805,
-84817,
-84842,
-84842,
-84842,
-84849,
-84864,
-84876,
-84930,
-84936,
-84936,
-84948,
-84960,
-84960,
-84960,
-84983,
-84996,
-85003,
-85011,
-85046,
-85066,
-85111,
-85127,
-85149,
-85165,
-85210,
-85229,
-85229,
-85229,
-85235,
-85235,
-85253,
-85266,
-85285,
-85299,
-85329,
-85343,
-85361,
-85379,
-85413,
-85413,
-85446,
-85453,
-85482,
-85492,
-85514,
-85521,
-85521,
-85521,
-85561,
-85568,
-85585,
-85599,
-85654,
-85671,
-85685,
-85699,
-85699,
-85699,
-85699,
-85699,
-85709,
-85734,
-85734,
-85748,
-85748,
-85771,
-85787,
-85787,
-85820,
-85830,
-85830,
-85837,
-85837,
-85837,
-85860,
-85921,
-85944,
-85944,
-85962,
-85968,
-85982,
-86007,
-86014,
-86019,
-86034,
-86054,
-86061,
-86074,
-86112,
-86119,
-86125,
-86144,
-86163,
-86163,
-86170,
-86202,
-86253,
-86310,
-86310,
-86337,
-86344,
-86361,
-86376,
-86410,
-86428,
-86428,
-86444,
-86456,
-86456,
-86456,
-86474,
-86492,
-86500,
-86500,
-86528,
-86528,
-86541,
-86541,
-86562,
-86582,
-86602,
-86615,
-86615,
+84682,
+84689,
+84699,
+84699,
+84709,
+84709,
+84709,
+84709,
+84709,
+84709,
+84709,
+84724,
+84733,
+84733,
+84741,
+84741,
+84776,
+84776,
+84776,
+84795,
+84825,
+84834,
+84834,
+84841,
+84851,
+84861,
+84871,
+84871,
+84882,
+84882,
+84892,
+84927,
+84932,
+84966,
+84984,
+84984,
+85015,
+85039,
+85051,
+85088,
+85088,
+85088,
+85088,
+85108,
+85134,
+85163,
+85163,
+85163,
+85174,
+85180,
+85198,
+85198,
+85198,
+85198,
+85230,
+85257,
+85257,
+85278,
+85278,
+85278,
+85278,
+85324,
+85365,
+85377,
+85414,
+85420,
+85436,
+85465,
+85490,
+85490,
+85501,
+85501,
+85529,
+85553,
+85553,
+85560,
+85560,
+85571,
+85571,
+85571,
+85571,
+85571,
+85571,
+85598,
+85598,
+85598,
+85620,
+85649,
+85649,
+85664,
+85664,
+85675,
+85687,
+85687,
+85687,
+85687,
+85687,
+85687,
+85705,
+85705,
+85717,
+85755,
+85755,
+85765,
+85765,
+85784,
+85784,
+85784,
+85818,
+85848,
+85873,
+85904,
+85954,
+85954,
+85967,
+85974,
+85983,
+86022,
+86030,
+86050,
+86050,
+86050,
+86050,
+86087,
+86087,
+86087,
+86099,
+86099,
+86109,
+86127,
+86150,
+86161,
+86187,
+86187,
+86205,
+86217,
+86236,
+86243,
+86254,
+86254,
+86254,
+86270,
+86270,
+86282,
+86295,
+86304,
+86332,
+86332,
+86332,
+86332,
+86343,
+86343,
+86343,
+86343,
+86343,
+86354,
+86354,
+86354,
+86354,
+86354,
+86354,
+86372,
+86377,
+86398,
+86398,
+86421,
+86427,
+86427,
+86427,
+86427,
+86432,
+86454,
+86468,
+86468,
+86482,
+86482,
+86487,
+86498,
+86512,
+86512,
+86535,
+86544,
+86577,
86615,
-86645,
-86645,
-86666,
-86692,
-86720,
-86727,
-86734,
+86651,
+86672,
+86672,
+86672,
+86698,
+86698,
+86721,
+86721,
86757,
-86781,
-86801,
-86801,
-86801,
-86823,
-86853,
-86853,
-86870,
-86889,
-86895,
-86895,
+86757,
+86757,
+86778,
+86789,
+86789,
+86789,
+86809,
+86833,
+86833,
+86845,
+86867,
+86867,
+86867,
86895,
86920,
-86927,
-86939,
-86957,
-86981,
-86988,
-87009,
-87044,
-87044,
-87075,
-87108,
-87129,
-87146,
-87158,
-87176,
-87183,
-87213,
-87266,
-87284,
-87284,
-87291,
-87307,
-87307,
-87312,
-87339,
-87339,
-87346,
-87353,
-87385,
-87419,
-87419,
+86920,
+86920,
+86920,
+86982,
+86982,
+87000,
+87006,
+87067,
+87067,
+87067,
+87067,
+87077,
+87077,
+87085,
+87090,
+87106,
+87106,
+87112,
+87112,
+87112,
+87118,
+87127,
+87127,
+87127,
+87143,
+87143,
+87143,
+87143,
+87155,
+87155,
+87168,
+87168,
+87182,
+87182,
+87188,
+87188,
+87188,
+87188,
+87188,
+87204,
+87215,
+87236,
+87236,
+87236,
+87248,
+87257,
+87274,
+87282,
+87297,
+87297,
+87297,
+87297,
+87302,
+87321,
+87341,
+87341,
+87367,
+87367,
+87373,
+87379,
+87387,
+87406,
+87406,
+87406,
+87412,
+87426,
+87441,
+87441,
87441,
-87448,
-87470,
-87503,
-87503,
-87509,
-87509,
-87537,
-87561,
-87580,
-87580,
-87625,
-87632,
-87644,
-87656,
-87656,
-87656,
-87656,
-87656,
-87696,
-87713,
-87713,
-87713,
-87713,
-87713,
-87713,
+87449,
+87458,
+87458,
+87458,
+87467,
+87476,
+87541,
+87541,
+87541,
+87541,
+87577,
+87583,
+87583,
+87612,
+87612,
+87620,
+87626,
+87639,
+87639,
+87639,
+87661,
+87671,
+87686,
+87707,
+87707,
+87707,
87738,
-87746,
-87753,
-87753,
-87785,
-87800,
-87811,
-87823,
-87833,
+87738,
+87759,
+87770,
+87780,
+87797,
+87797,
+87810,
+87810,
+87819,
87833,
-87844,
-87844,
-87859,
-87878,
-87878,
-87889,
-87920,
-87925,
-87945,
-87945,
-87945,
-87964,
-87974,
-87974,
-87974,
-87980,
-87996,
-87996,
-87996,
-87996,
-88015,
-88015,
-88037,
-88037,
-88042,
-88054,
-88063,
-88070,
-88084,
-88084,
-88116,
-88125,
+87841,
+87869,
+87869,
+87869,
+87869,
+87885,
+87885,
+87899,
+87912,
+87929,
+87941,
+87955,
+87970,
+87984,
+87984,
+88000,
+88026,
+88026,
+88026,
+88026,
+88036,
+88051,
+88061,
+88104,
+88114,
+88114,
88125,
88125,
88125,
-88164,
-88164,
-88179,
-88179,
-88193,
-88193,
-88237,
-88237,
-88237,
-88237,
-88237,
-88237,
-88261,
-88270,
-88282,
-88293,
-88293,
-88310,
-88323,
-88345,
-88365,
-88385,
-88385,
-88385,
-88385,
-88385,
-88403,
-88403,
-88418,
-88418,
-88418,
-88453,
-88473,
-88483,
-88498,
-88508,
-88508,
-88529,
-88539,
-88550,
-88550,
-88550,
-88558,
-88581,
-88596,
-88596,
-88596,
-88596,
-88596,
-88596,
-88596,
+88132,
+88161,
+88166,
+88178,
+88178,
+88178,
+88178,
+88208,
+88213,
+88213,
+88220,
+88227,
+88227,
+88244,
+88260,
+88260,
+88266,
+88291,
+88297,
+88297,
+88297,
+88334,
+88334,
+88366,
+88398,
+88415,
+88432,
+88442,
+88456,
+88478,
+88520,
+88520,
+88520,
+88569,
88617,
-88641,
-88650,
-88678,
-88678,
-88678,
-88700,
-88700,
-88714,
-88756,
-88762,
-88773,
-88828,
-88855,
-88861,
-88861,
-88892,
-88952,
-88962,
-88962,
-88962,
-88968,
-88993,
-88993,
-89003,
-89033,
-89033,
-89078,
-89086,
-89091,
-89102,
-89102,
-89127,
-89138,
-89138,
-89155,
-89166,
-89188,
-89188,
-89205,
-89211,
-89211,
-89211,
-89221,
-89221,
-89268,
+88626,
+88632,
+88632,
+88649,
+88661,
+88661,
+88693,
+88705,
+88705,
+88705,
+88705,
+88705,
+88712,
+88734,
+88779,
+88779,
+88779,
+88785,
+88785,
+88800,
+88817,
+88817,
+88824,
+88824,
+88868,
+88868,
+88868,
+88868,
+88868,
+88913,
+88936,
+88977,
+88990,
+89019,
+89025,
+89044,
+89068,
+89068,
+89085,
+89085,
+89085,
+89085,
+89131,
+89143,
+89143,
+89158,
+89168,
+89197,
+89202,
+89202,
+89207,
+89278,
89290,
-89303,
-89316,
+89309,
+89319,
89324,
-89383,
+89324,
+89344,
+89354,
+89354,
+89386,
89393,
-89404,
-89421,
-89437,
-89466,
-89466,
-89502,
-89502,
-89515,
+89405,
+89430,
+89430,
+89430,
+89438,
+89438,
+89489,
+89496,
+89511,
+89529,
89545,
-89580,
-89586,
-89586,
-89586,
-89591,
-89591,
-89620,
-89633,
-89649,
-89654,
-89694,
-89694,
-89706,
-89706,
-89706,
-89721,
-89721,
-89727,
-89727,
-89727,
-89756,
-89756,
-89756,
-89763,
-89782,
+89563,
+89569,
+89569,
+89569,
+89592,
+89598,
+89598,
+89598,
+89653,
+89659,
+89659,
+89669,
+89669,
+89690,
+89714,
+89722,
+89732,
+89776,
+89776,
+89776,
89782,
-89804,
-89804,
-89826,
-89826,
-89831,
-89840,
-89847,
+89795,
+89795,
+89795,
+89795,
+89813,
+89824,
+89824,
+89841,
+89848,
+89848,
+89848,
89858,
-89885,
-89885,
-89885,
-89920,
-89942,
-89949,
-89949,
-89949,
-89959,
-89971,
-89978,
-89984,
-89984,
-89999,
-90035,
-90053,
-90064,
-90075,
-90083,
-90083,
-90083,
-90101,
-90101,
-90116,
-90116,
-90150,
-90157,
-90157,
-90157,
-90168,
-90205,
-90205,
-90212,
-90212,
-90242,
-90274,
-90280,
-90292,
-90302,
-90302,
-90302,
-90309,
-90309,
-90321,
-90327,
-90343,
-90399,
-90426,
-90435,
-90435,
-90453,
-90459,
-90459,
-90476,
-90476,
-90482,
-90502,
-90502,
+89858,
+89891,
+89891,
+89918,
+89928,
+89928,
+89947,
+89977,
+89977,
+89977,
+89977,
+89998,
+90025,
+90025,
+90065,
+90071,
+90086,
+90086,
+90086,
+90104,
+90104,
+90136,
+90163,
+90163,
+90163,
+90163,
+90169,
+90194,
+90194,
+90194,
+90194,
+90207,
+90224,
+90247,
+90256,
+90256,
+90262,
+90275,
+90275,
+90293,
+90303,
+90303,
+90303,
+90361,
+90376,
+90417,
+90428,
+90452,
+90491,
90502,
-90522,
-90522,
-90536,
-90563,
-90563,
-90583,
-90583,
-90583,
-90604,
-90604,
-90610,
-90610,
-90610,
-90610,
-90629,
-90629,
-90654,
-90663,
-90669,
-90690,
-90699,
-90699,
-90699,
-90729,
-90752,
-90752,
-90758,
-90758,
-90774,
-90780,
-90825,
-90845,
-90857,
-90857,
-90857,
-90857,
-90873,
-90905,
-90905,
-90905,
-90920,
-90920,
-90920,
-90963,
-90969,
-90987,
-90987,
+90509,
+90515,
+90538,
+90564,
+90594,
+90638,
+90638,
+90638,
+90638,
+90659,
+90668,
+90683,
+90691,
+90698,
+90706,
+90724,
+90735,
+90770,
+90770,
+90778,
+90778,
+90795,
+90795,
+90795,
+90795,
+90831,
+90831,
+90869,
+90883,
+90901,
+90907,
+90913,
+90929,
+90929,
+90959,
+90977,
90987,
-91004,
-91023,
-91029,
-91029,
-91061,
-91061,
-91061,
-91067,
-91073,
-91093,
-91093,
-91093,
-91101,
-91126,
-91126,
-91126,
-91126,
-91131,
-91178,
-91185,
-91195,
-91216,
+91007,
+91019,
+91033,
+91039,
+91104,
+91104,
+91110,
+91110,
+91110,
+91124,
+91130,
+91136,
+91157,
+91163,
+91163,
+91169,
+91209,
+91209,
+91225,
+91225,
+91225,
+91225,
91241,
-91268,
-91268,
-91268,
-91278,
-91288,
-91297,
-91297,
-91297,
-91314,
-91320,
-91320,
-91320,
-91328,
-91328,
-91345,
-91365,
-91365,
-91365,
-91365,
-91386,
-91422,
-91449,
-91458,
-91495,
-91533,
-91551,
-91579,
-91579,
-91579,
-91624,
-91631,
-91631,
-91631,
-91639,
-91657,
-91688,
-91709,
-91709,
-91709,
-91709,
-91709,
-91709,
-91709,
-91715,
-91743,
-91777,
-91777,
-91800,
-91817,
-91817,
-91848,
-91848,
-91858,
-91858,
-91867,
-91884,
-91884,
-91900,
-91900,
-91900,
-91913,
-91919,
-91926,
-91934,
-91947,
-91947,
-91947,
-91965,
-91965,
-91965,
-91972,
-91982,
-92009,
-92036,
+91241,
+91253,
+91273,
+91273,
+91283,
+91304,
+91310,
+91337,
+91354,
+91354,
+91354,
+91354,
+91368,
+91381,
+91381,
+91416,
+91435,
+91441,
+91441,
+91441,
+91441,
+91441,
+91463,
+91489,
+91504,
+91504,
+91520,
+91520,
+91520,
+91566,
+91566,
+91576,
+91576,
+91594,
+91599,
+91599,
+91610,
+91610,
+91619,
+91635,
+91641,
+91675,
+91683,
+91683,
+91683,
+91683,
+91683,
+91683,
+91683,
+91683,
+91749,
+91749,
+91749,
+91749,
+91760,
+91809,
+91814,
+91814,
+91814,
+91824,
+91824,
+91835,
+91847,
+91865,
+91879,
+91891,
+91935,
+91935,
+91955,
+91986,
+91996,
+91996,
+91996,
+92023,
+92057,
92057,
-92068,
-92068,
-92093,
-92107,
-92114,
-92120,
-92206,
-92218,
-92218,
-92218,
-92218,
-92233,
-92233,
-92290,
-92303,
-92303,
-92315,
-92315,
-92315,
-92326,
-92339,
-92360,
-92360,
-92372,
-92372,
-92387,
-92387,
-92387,
-92407,
-92431,
-92453,
-92453,
-92453,
-92471,
-92494,
-92494,
-92515,
-92539,
-92557,
-92557,
-92562,
-92573,
-92573,
-92595,
-92601,
-92633,
-92633,
-92633,
-92675,
-92706,
-92706,
-92723,
-92729,
-92729,
-92745,
-92745,
-92760,
-92760,
-92806,
-92831,
-92844,
-92844,
-92850,
-92850,
-92856,
-92856,
-92881,
-92913,
+92062,
+92103,
+92111,
+92117,
+92117,
+92117,
+92117,
+92117,
+92117,
+92117,
+92136,
+92157,
+92192,
+92203,
+92203,
+92223,
+92223,
+92241,
+92241,
+92241,
+92241,
+92241,
+92281,
+92319,
+92329,
+92329,
+92351,
+92358,
+92358,
+92358,
+92371,
+92390,
+92404,
+92410,
+92410,
+92423,
+92423,
+92449,
+92491,
+92532,
+92532,
+92540,
+92546,
+92552,
+92572,
+92572,
+92572,
+92592,
+92603,
+92603,
+92603,
+92626,
+92658,
+92666,
+92666,
+92666,
+92672,
+92714,
+92714,
+92724,
+92744,
+92776,
+92776,
+92797,
+92797,
+92828,
+92828,
+92847,
+92847,
+92874,
+92874,
+92874,
+92892,
+92900,
+92900,
+92900,
92930,
-92941,
-92956,
-92967,
-92967,
+92930,
+92936,
+92936,
+92944,
+92962,
+92977,
92977,
-93000,
-93006,
-93025,
-93051,
-93066,
-93079,
-93091,
-93091,
-93097,
-93103,
-93103,
-93133,
-93133,
-93133,
-93139,
-93139,
-93139,
-93158,
-93164,
-93191,
-93191,
-93191,
+92983,
+93027,
+93033,
+93033,
+93050,
+93082,
+93107,
+93125,
+93125,
+93125,
+93143,
+93143,
+93157,
+93157,
+93157,
+93157,
+93187,
+93187,
+93194,
+93194,
93206,
-93220,
-93235,
-93251,
-93251,
-93251,
-93257,
-93265,
-93265,
-93271,
-93323,
-93341,
-93358,
-93373,
-93390,
-93390,
-93390,
-93398,
-93398,
-93398,
-93407,
-93413,
-93422,
-93428,
-93428,
-93452,
-93477,
-93500,
-93508,
-93529,
-93535,
-93535,
-93561,
-93561,
-93561,
-93594,
-93601,
-93617,
-93617,
-93625,
-93642,
-93659,
-93669,
-93669,
-93675,
-93675,
-93691,
-93691,
-93703,
-93718,
-93718,
-93725,
-93725,
-93725,
-93725,
-93733,
-93733,
-93733,
-93733,
-93749,
-93772,
-93799,
-93814,
-93814,
-93839,
-93861,
-93861,
-93861,
-93861,
-93861,
-93883,
-93883,
-93883,
+93206,
+93212,
+93229,
+93258,
+93285,
+93297,
+93297,
+93297,
+93297,
+93343,
+93343,
+93343,
+93370,
+93387,
+93387,
+93387,
+93387,
+93387,
+93412,
+93417,
+93430,
+93430,
+93430,
+93430,
+93430,
+93430,
+93430,
+93436,
+93455,
+93464,
+93483,
+93496,
+93496,
+93513,
+93513,
+93513,
+93554,
+93584,
+93584,
+93584,
+93584,
+93592,
+93602,
+93607,
+93631,
+93657,
+93664,
+93672,
+93744,
+93753,
+93753,
+93761,
+93776,
+93776,
+93776,
+93776,
+93776,
+93776,
+93810,
+93822,
+93822,
+93852,
+93871,
+93884,
93897,
-93910,
-93917,
-93917,
-93940,
-93940,
-93956,
-93956,
-93968,
-93985,
-94005,
-94005,
-94005,
-94011,
-94035,
-94035,
-94066,
-94089,
-94089,
-94089,
-94108,
-94132,
-94157,
-94175,
-94175,
-94183,
-94212,
-94218,
+93914,
+93926,
+93939,
+93939,
+93954,
+93954,
+93954,
+93954,
+93969,
+93977,
+93977,
+93977,
+93990,
+93990,
+94031,
+94062,
+94068,
+94068,
+94068,
+94099,
+94123,
+94141,
+94191,
+94209,
+94209,
+94209,
94228,
-94234,
-94257,
-94270,
-94270,
-94270,
-94270,
-94292,
-94308,
-94314,
-94314,
-94331,
-94331,
-94355,
-94380,
-94424,
-94445,
-94445,
-94445,
-94445,
-94467,
-94473,
-94488,
-94497,
-94515,
-94524,
-94531,
-94571,
-94571,
-94587,
-94610,
-94620,
-94620,
-94627,
-94633,
-94643,
-94643,
-94643,
-94661,
-94661,
-94661,
-94661,
-94668,
-94668,
-94668,
-94668,
-94696,
-94696,
-94696,
-94696,
-94711,
+94263,
+94263,
+94298,
+94307,
+94321,
+94321,
+94327,
+94327,
+94358,
+94358,
+94358,
+94370,
+94370,
+94370,
+94370,
+94377,
+94410,
+94464,
+94496,
+94513,
+94542,
+94548,
+94548,
+94563,
+94569,
+94575,
+94593,
+94593,
+94593,
+94593,
+94613,
+94613,
+94618,
+94618,
+94618,
+94625,
+94637,
+94644,
+94650,
+94663,
+94682,
+94695,
+94728,
+94728,
+94734,
94734,
-94756,
-94756,
-94794,
-94807,
-94820,
-94837,
-94857,
-94857,
-94868,
-94878,
-94884,
-94884,
-94884,
-94915,
-94935,
-94935,
-94994,
-95020,
-95020,
-95028,
-95028,
-95028,
-95028,
-95042,
-95052,
-95062,
-95076,
-95099,
-95120,
-95126,
-95156,
-95165,
-95218,
-95218,
-95230,
-95230,
-95230,
-95230,
-95242,
-95284,
+94759,
+94789,
+94814,
+94826,
+94826,
+94826,
+94840,
+94840,
+94840,
+94871,
+94877,
+94877,
+94885,
+94885,
+94885,
+94892,
+94892,
+94904,
+94904,
+94904,
+94904,
+94904,
+94904,
+94904,
+94920,
+94920,
+94941,
+94959,
+94959,
+94959,
+94959,
+94959,
+94971,
+95005,
+95034,
+95034,
+95068,
+95073,
+95098,
+95098,
+95098,
+95115,
+95144,
+95153,
+95170,
+95170,
+95207,
+95227,
+95227,
+95250,
+95264,
+95264,
+95264,
+95280,
95303,
-95316,
-95329,
-95329,
-95329,
-95361,
-95398,
-95411,
-95411,
-95427,
-95427,
-95462,
-95481,
-95496,
-95496,
-95508,
-95540,
-95540,
-95558,
-95558,
-95585,
-95585,
-95597,
-95607,
-95643,
-95674,
-95688,
-95688,
-95688,
-95718,
-95718,
-95731,
-95750,
-95750,
-95750,
-95768,
-95768,
-95776,
-95776,
-95776,
-95776,
-95776,
-95776,
-95776,
-95804,
-95804,
-95822,
-95829,
-95836,
-95836,
-95836,
-95836,
-95849,
-95849,
-95861,
-95861,
-95861,
-95886,
-95886,
-95886,
-95893,
-95893,
-95911,
+95303,
+95303,
+95319,
+95319,
+95319,
+95342,
+95364,
+95407,
+95420,
+95420,
+95435,
+95435,
+95452,
+95452,
+95452,
+95470,
+95476,
+95505,
+95536,
+95536,
+95536,
+95536,
+95536,
+95536,
+95568,
+95568,
+95587,
+95629,
+95629,
+95640,
+95647,
+95660,
+95705,
+95742,
+95754,
+95825,
+95831,
+95848,
+95848,
+95848,
+95868,
+95888,
95911,
-95918,
-95918,
-95951,
-95951,
-95951,
-95961,
-95998,
-95998,
-95998,
-95998,
-96013,
-96013,
-96013,
-96013,
-96027,
-96057,
-96065,
-96065,
-96076,
-96076,
-96076,
-96076,
-96108,
-96120,
-96120,
-96120,
-96129,
-96156,
-96156,
+95936,
+95936,
+95979,
+96003,
+96016,
+96047,
+96047,
+96059,
+96082,
+96107,
+96107,
+96119,
+96133,
+96157,
+96169,
+96169,
+96169,
96177,
-96189,
-96201,
-96211,
-96211,
-96211,
-96211,
-96232,
-96232,
-96244,
-96263,
-96280,
-96280,
-96301,
-96301,
-96301,
-96321,
-96321,
-96321,
-96333,
-96351,
-96363,
-96363,
-96381,
-96387,
-96394,
-96394,
-96399,
-96399,
-96428,
-96441,
-96441,
-96441,
-96454,
-96463,
-96471,
-96471,
-96481,
-96521,
-96521,
-96534,
-96534,
-96544,
-96566,
-96566,
-96566,
-96566,
-96596,
-96596,
-96596,
-96596,
-96611,
-96611,
-96611,
-96611,
-96629,
-96629,
-96642,
+96177,
+96203,
+96234,
+96234,
+96234,
+96247,
+96268,
+96274,
+96274,
+96315,
+96354,
+96372,
+96372,
+96372,
+96392,
+96407,
+96444,
+96444,
+96470,
+96510,
+96527,
+96562,
+96583,
+96583,
+96599,
+96599,
+96599,
96642,
-96662,
-96662,
-96676,
-96689,
-96689,
-96699,
-96714,
-96725,
-96725,
-96741,
-96769,
-96769,
-96775,
-96775,
-96783,
-96783,
-96783,
-96801,
-96817,
-96834,
-96834,
-96834,
-96834,
-96844,
-96860,
-96889,
-96929,
-96929,
-96945,
-96945,
-96975,
-96985,
-97002,
+96657,
+96657,
+96657,
+96698,
+96720,
+96735,
+96735,
+96761,
+96802,
+96802,
+96814,
+96826,
+96826,
+96843,
+96855,
+96866,
+96884,
+96896,
+96896,
+96905,
+96905,
+96905,
+96905,
+96905,
+96933,
+96933,
+96933,
+96933,
+96950,
+96950,
+96950,
+96950,
+96965,
+96974,
+96992,
+96992,
+97012,
+97041,
97047,
-97062,
-97062,
-97069,
-97069,
-97082,
-97082,
-97093,
-97126,
-97150,
-97150,
-97150,
-97150,
-97150,
-97175,
-97175,
-97175,
-97175,
-97175,
-97175,
-97196,
-97196,
-97196,
+97091,
+97091,
+97091,
+97098,
+97098,
+97120,
+97138,
+97138,
97196,
-97213,
-97232,
-97249,
-97249,
-97276,
-97289,
-97296,
-97307,
-97307,
-97314,
-97338,
-97338,
-97338,
-97358,
-97375,
-97387,
-97408,
-97408,
-97408,
-97408,
-97425,
-97461,
-97483,
-97502,
-97502,
-97509,
-97509,
-97509,
-97518,
-97540,
-97553,
-97553,
-97553,
+97227,
+97227,
+97255,
+97267,
+97267,
+97292,
+97331,
+97355,
+97365,
+97373,
+97457,
+97457,
+97457,
+97519,
+97519,
+97534,
+97548,
+97548,
97570,
-97576,
-97576,
-97576,
-97610,
-97610,
-97618,
-97624,
-97630,
-97640,
-97674,
-97699,
-97699,
-97709,
-97709,
-97709,
-97709,
-97720,
-97740,
-97740,
-97740,
-97759,
-97759,
-97759,
-97769,
-97776,
-97829,
-97829,
-97829,
-97863,
-97863,
-97887,
-97904,
-97914,
-97914,
+97593,
+97613,
+97631,
+97661,
+97667,
+97689,
+97717,
+97717,
+97717,
+97735,
+97735,
+97735,
+97745,
+97771,
+97786,
+97798,
+97798,
+97839,
+97839,
+97839,
+97848,
+97848,
+97867,
+97918,
+97918,
+97918,
97927,
-97937,
-97947,
-97947,
-97947,
-97959,
-97959,
-97959,
-97977,
-98002,
-98016,
-98044,
-98044,
-98062,
-98062,
-98072,
-98072,
-98072,
-98072,
-98086,
-98105,
-98124,
-98132,
-98132,
-98148,
-98173,
-98185,
-98206,
-98240,
-98240,
-98259,
-98294,
-98320,
+97942,
+97942,
+97942,
+97942,
+97942,
+97967,
+97979,
+98012,
+98012,
+98054,
+98054,
+98078,
+98078,
+98106,
+98106,
+98115,
+98130,
+98130,
+98130,
+98130,
+98137,
+98137,
+98137,
+98144,
+98168,
+98188,
+98188,
+98202,
+98202,
+98220,
+98234,
+98266,
+98273,
+98292,
+98317,
+98328,
+98328,
98346,
98346,
98346,
-98379,
-98387,
-98415,
-98442,
-98469,
+98357,
+98357,
+98357,
+98365,
+98400,
+98412,
+98431,
+98438,
98477,
-98490,
-98528,
-98528,
-98528,
-98553,
-98562,
-98593,
-98608,
-98622,
-98630,
-98630,
-98637,
-98647,
+98488,
+98504,
+98504,
+98511,
+98540,
+98559,
+98566,
+98595,
+98601,
+98607,
+98615,
+98638,
+98651,
+98651,
+98651,
+98667,
+98667,
+98686,
98703,
-98733,
-98733,
-98733,
-98749,
-98749,
-98754,
-98759,
-98783,
-98783,
-98808,
-98827,
-98827,
+98703,
+98716,
+98728,
+98762,
+98762,
+98762,
+98779,
+98804,
98827,
-98853,
-98888,
-98888,
-98906,
-98906,
-98926,
-98954,
-98963,
-98963,
-98963,
-98973,
-98991,
-98997,
-98997,
-98997,
-98997,
-99014,
-99014,
-99014,
-99014,
-99022,
-99036,
-99036,
-99080,
-99096,
-99101,
-99101,
-99115,
-99125,
-99135,
-99135,
-99135,
-99163,
-99163,
-99163,
-99203,
-99203,
-99222,
-99222,
-99253,
-99253,
-99285,
-99308,
-99308,
-99308,
-99308,
-99333,
-99360,
-99394,
-99394,
-99408,
-99408,
-99414,
-99420,
-99420,
-99420,
-99469,
-99476,
-99476,
-99476,
-99498,
-99498,
-99498,
-99528,
-99528,
+98833,
+98847,
+98865,
+98865,
+98865,
+98865,
+98876,
+98876,
+98876,
+98895,
+98905,
+98905,
+98946,
+98946,
+98946,
+98946,
+98977,
+99002,
+99019,
+99026,
+99026,
+99038,
+99051,
+99078,
+99106,
+99113,
+99126,
+99144,
+99164,
+99164,
+99189,
+99238,
+99245,
+99257,
+99288,
+99306,
+99306,
+99334,
+99355,
+99383,
+99437,
+99437,
+99458,
+99485,
+99505,
+99517,
99528,
-99546,
-99552,
-99558,
-99576,
-99576,
-99576,
-99600,
-99611,
-99611,
-99621,
-99636,
-99636,
-99636,
-99636,
-99636,
-99636,
-99636,
-99687,
-99687,
-99721,
-99728,
+99553,
+99560,
+99573,
+99590,
+99602,
+99624,
+99624,
+99631,
+99638,
+99657,
+99688,
+99701,
+99708,
99747,
-99753,
-99753,
-99753,
-99796,
-99801,
-99817,
-99826,
-99858,
-99858,
-99873,
-99873,
-99873,
-99912,
-99912,
-99912,
-99912,
-99939,
-99939,
-99939,
-99939,
-99953,
-99963,
-100010,
-100045,
-100056,
-100056,
-100078,
-100078,
-100078,
-100093,
-100098,
-100098,
-100098,
-100106,
-100113,
-100126,
-100126,
-100126,
-100126,
-100126,
-100126,
-100131,
-100156,
-100156,
-100166,
-100166,
-100166,
-100186,
-100186,
-100186,
-100186,
-100219,
-100236,
-100236,
-100236,
-100236,
-100287,
-100305,
-100313,
-100313,
-100328,
-100328,
-100328,
-100328,
-100352,
-100352,
-100352,
-100352,
-100363,
-100399,
-100399,
-100399,
-100417,
-100433,
-100446,
-100446,
-100464,
-100464,
-100464,
-100521,
-100530,
-100539,
-100565,
-100583,
-100591,
-100601,
-100612,
-100612,
-100612,
-100612,
-100612,
-100618,
-100644,
-100644,
-100652,
-100685,
-100695,
-100695,
-100706,
-100712,
-100749,
-100766,
-100811,
-100834,
-100834,
-100860,
-100869,
-100869,
-100869,
-100889,
-100907,
-100907,
-100913,
-100932,
-100932,
-100932,
-100932,
-100932,
-100932,
+99759,
+99781,
+99781,
+99804,
+99822,
+99841,
+99841,
+99859,
+99859,
+99859,
+99877,
+99890,
+99913,
+99930,
+99944,
+99976,
+100005,
+100005,
+100018,
+100025,
+100025,
+100032,
+100032,
+100048,
+100059,
+100059,
+100086,
+100095,
+100111,
+100138,
+100153,
+100169,
+100214,
+100222,
+100230,
+100267,
+100274,
+100284,
+100293,
+100293,
+100329,
+100347,
+100357,
+100377,
+100387,
+100387,
+100397,
+100397,
+100409,
+100425,
+100425,
+100425,
+100441,
+100455,
+100472,
+100472,
+100479,
+100508,
+100508,
+100517,
+100549,
+100549,
+100568,
+100578,
+100603,
+100603,
+100610,
+100610,
+100641,
+100682,
+100690,
+100705,
+100723,
+100743,
+100743,
+100750,
+100763,
+100763,
+100822,
+100844,
+100865,
+100877,
+100877,
+100877,
+100884,
+100891,
+100903,
+100926,
100950,
100950,
-100963,
-100963,
-101015,
-101026,
+100968,
+100968,
+100987,
+101007,
+101027,
+101027,
+101027,
+101034,
+101034,
+101041,
101048,
-101048,
-101084,
-101090,
-101103,
-101119,
-101119,
-101119,
-101137,
-101160,
-101171,
-101180,
-101186,
-101194,
-101194,
-101212,
-101237,
-101260,
-101260,
-101260};
+101055,
+101105,
+101126,
+101142,
+101149,
+101156,
+101163,
+101163,
+101205,
+101205,
+101228,
+101228,
+101228,
+101228,
+101228,
+101228,
+101250,
+101275,
+101282,
+101282,
+101310,
+101316,
+101316,
+101316,
+101323,
+101344,
+101366,
+101392,
+101399,
+101424,
+101441,
+101441,
+101441,
+101441,
+101464,
+101500,
+101520,
+101537,
+101544,
+101552,
+101552,
+101580,
+101580,
+101610,
+101620,
+101627,
+101634,
+101649,
+101656,
+101663,
+101670,
+101670,
+101686,
+101686,
+101693,
+101720,
+101720,
+101748,
+101765,
+101786,
+101802,
+101809,
+101828};
static const char *tldData[] = {
-"ac.lk\0lu.eu.org\0me.eu.org\0"
-"hazu.aichi.jp\0"
-"ac.ma\0auto.pl\0"
-"meme\0"
-"ac.me\0"
-"kuokgroup\0"
-"trentinsu\xcc\x88""d-tirol.it\0holtalen.no\0"
-"alibaba\0"
-"\xd9\x85\xd9\x88\xd8\xa8\xd8\xa7\xd9\x8a\xd9\x84\xd9\x8a\0"
-"k12.ct.us\0hu.com\0"
-"lib.ar.us\0"
-"bbs.tr\0"
-"arao.kumamoto.jp\0no-ip.biz\0"
-"js.cn\0s3-fips-us-gov-west-1.amazonaws.com\0"
-"ac.mu\0"
-"bato.tochigi.jp\0agriculture.museum\0"
-"ac.mw\0"
-"h.se\0"
-"ac.ni\0home.dyndns.org\0"
-"umi.fukuoka.jp\0ac.mz\0varoy.no\0"
-"lv.eu.org\0"
-"slg.br\0bando.ibaraki.jp\0community.museum\0"
-"s\xc3\xb8rfold.no\0"
-"nysa.pl\0travelers\0"
-"krokstadelva.no\0is-a-lawyer.com\0"
-"baseball.museum\0"
-"southcarolina.museum\0"
-"menu\0verisign\0"
-"kddi\0"
-"fc.it\0docs\0nfshost.com\0"
-"outsystemscloud.com\0"
-"larsson.museum\0med.pro\0"
-"forli\xcc\x80""cesena.it\0arts.nf\0ac.nz\0"
-"\xe3\x82\xb9\xe3\x83\x88\xe3\x82\xa2\0"
-"tsuruta.aomori.jp\0"
-"sp.it\0ac.pa\0fhapp.xyz\0"
-"study\0"
-"misato.akita.jp\0rocher\0"
-"us-1.evennode.com\0"
-"ralingen.no\0"
-"nesna.no\0ddnsfree.com\0"
-"urakawa.hokkaido.jp\0tychy.pl\0"
-"webhop.org\0"
-"artgallery.museum\0"
-"saigawa.fukuoka.jp\0state.museum\0"
-"contagem.br\0snasa.no\0"
-"museum\0doomdns.org\0"
-"tone.ibaraki.jp\0"
-"bashkiria.ru\0"
-"ac.pr\0"
-"uchiko.ehime.jp\0sue.fukuoka.jp\0toyosato.shiga.jp\0es.leg.br\0"
-"asahi.nagano.jp\0es.kr\0from-wa.com\0"
-"ooshika.nagano.jp\0"
-"kasukabe.saitama.jp\0"
-"sumita.iwate.jp\0"
-"nannestad.no\0\xe5\x81\xa5\xe5\xba\xb7\0"
-"teshikaga.hokkaido.jp\0"
-"slattum.no\0"
-"bashkiria.su\0"
-"trentinos-tirol.it\0"
-"laz.it\0"
-"edu.ac\0"
-"memorial\0"
-"edu.af\0"
-"k12.id.us\0"
-"from-la.net\0"
-"edu.al\0feedback\0"
-"vik.no\0"
-"ketrzyn.pl\0ac.rs\0"
-"doha\0"
-"edu.ba\0okaya.nagano.jp\0ac.ru\0ac.se\0cloudcontrolled.com\0"
-"edu.ar\0edu.bb\0kunisaki.oita.jp\0"
-"ac.rw\0s3.dualstack.eu-central-1.amazonaws.com\0from-al.com\0"
-"kouzushima.tokyo.jp\0"
-"edu.au\0is-a-knight.org\0"
-"edu.bh\0"
-"edu.bi\0inc.hk\0"
-"edu.az\0yamashina.kyoto.jp\0time.museum\0"
-"ishikawa.fukushima.jp\0naruto.tokushima.jp\0myravendb.com\0"
-"stage.nodeart.io\0"
-"edu.bm\0"
-"edu.bn\0"
-"edu.bo\0"
-"lplfinancial\0ltd.ua\0"
-"edu.br\0"
-"edu.bs\0"
-"edu.bt\0ac.th\0"
-"ac.sz\0ac.tj\0"
-"taki.mie.jp\0"
-"edu.ci\0"
-"edu.bz\0ltd.uk\0"
-"github.io\0""32-b.it\0"
-"hidaka.hokkaido.jp\0school\0"
-"edu.cn\0acct.pro\0"
-"edu.co\0"
-"windmill.museum\0"
-"nittedal.no\0"
-"r\xc3\xb8st.no\0ac.ug\0unicom\0"
-"edu.cu\0"
-"latina.it\0oristano.it\0shakotan.hokkaido.jp\0ac.tz\0"
-"edu.cw\0ac.uk\0"
-"anan.nagano.jp\0notteroy.no\0"
-"miyawaka.fukuoka.jp\0"
-"accident-investigation.aero\0"
-"edu.dm\0gifu.gifu.jp\0"
-"edu.do\0"
-"kokubunji.tokyo.jp\0kawanishi.yamagata.jp\0thruhere.net\0"
-"zentsuji.kagawa.jp\0"
-"edu.ec\0"
-"\xc3\xa5seral.no\0mincom.tn\0"
-"edu.ee\0marine.ru\0"
-"equipment.aero\0"
-"edu.eg\0kr.eu.org\0"
-"arq.br\0"
-"tabuse.yamaguchi.jp\0hamburg.museum\0"
-"edu.dz\0ac.vn\0"
-"emr.it\0"
-"from-mi.com\0"
-"christiansburg.museum\0"
-"edu.es\0kami.miyagi.jp\0"
-"edu.et\0fitness\0*.kunden.ortsinfo.at\0"
-"tokoname.aichi.jp\0daegu.kr\0"
-"ck.ua\0"
-"mobara.chiba.jp\0"
-"hsbc\0icbc\0"
-"\xe5\xa5\x88\xe8\x89\xaf.jp\0k12.mt.us\0"
-"ven.it\0virgin\0yachts\0"
-"bjerkreim.no\0"
-"idv.hk\0namikata.ehime.jp\0tamatsukuri.ibaraki.jp\0luxe\0"
-"macerata.it\0microsoft\0"
-"minano.saitama.jp\0"
-"f.bg\0oseto.nagasaki.jp\0"
-"protection\0"
-"edu.ge\0from-ak.com\0"
-"aaa.pro\0"
-"edu.gh\0novara.it\0"
-"edu.gi\0"
-"maceio.br\0"
-"av.it\0turystyka.pl\0download\0"
-"edu.gl\0ringsaker.no\0africa\0"
-"edu.gn\0"
-"movimiento.bo\0"
-"edu.gp\0"
-"camdvr.org\0"
-"edu.gr\0skin\0"
-"edu.gt\0"
-"edu.gu\0usdecorativearts.museum\0"
-"pc.it\0"
-"edu.gy\0"
-"flora.no\0"
-"edu.hk\0perso.sn\0"
-"moskenes.no\0"
-"sk\xc3\xa5nland.no\0ac.za\0"
-"edu.hn\0"
-"annefrank.museum\0"
-"higashikurume.tokyo.jp\0"
-"powiat.pl\0"
-"sandnessjoen.no\0"
-"edu.ht\0yamagata.ibaraki.jp\0"
-"inzai.chiba.jp\0koto.shiga.jp\0godaddy\0"
-"niihama.ehime.jp\0flesberg.no\0"
-"ac.zm\0community\0viajes\0"
-"perso.tn\0observer\0"
-"cesenaforli.it\0cloudfront.net\0"
-"secure\0"
-"edu.in\0zamami.okinawa.jp\0"
-"volda.no\0"
-"edu.iq\0"
-"edu.is\0ac.zw\0"
-"edu.it\0"
-"fitjar.no\0"
-"sukagawa.fukushima.jp\0"
-"versailles.museum\0"
-"satsumasendai.kagoshima.jp\0educational.museum\0myphotos.cc\0"
-"shingu.fukuoka.jp\0shibata.miyagi.jp\0hemne.no\0"
-"oyamazaki.kyoto.jp\0"
-"nationalheritage.museum\0north-kazakhstan.su\0dscloud.biz\0"
-"edu.jo\0diskstation.me\0"
-"feira.br\0"
-"\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4\0vladikavkaz.ru\0"
-"tranby.no\0"
-"lib.ca.us\0"
-"edu.kg\0"
-"edu.ki\0"
-"windows\0"
-"edu.km\0"
-"edu.kn\0"
-"diskstation.eu\0"
-"edu.kp\0lib.pr.us\0"
-"kyonan.chiba.jp\0munakata.fukuoka.jp\0edu.la\0andasuolo.no\0vladikavkaz.su\0"
-"edu.lb\0schaeffler\0tushu\0"
-"takatsuki.shiga.jp\0edu.lc\0"
-"slz.br\0koya.wakayama.jp\0meeres.museum\0"
-"aetna\0"
-"edu.kw\0game\0"
-"hanamaki.iwate.jp\0kuroiso.tochigi.jp\0edu.ky\0dscloud.mobi\0"
-"edu.kz\0"
-"edu.lk\0"
-"in-addr.arpa\0soja.okayama.jp\0hamar.no\0"
-"mito.ibaraki.jp\0"
-"ic.gov.pl\0"
-"cc.ga.us\0"
-"edu.lr\0bindal.no\0"
-"edu.me\0"
-"edu.lv\0naroy.no\0"
-"edu.mg\0"
-"ts.it\0"
-"edu.ly\0"
-"edu.mk\0"
-"edu.ml\0cc.tn.us\0"
-"edu.mn\0cruises\0"
-"edu.mo\0"
-"hasuda.saitama.jp\0"
-"um.gov.pl\0"
-"edu.ms\0sande.m\xc3\xb8re-og-romsdal.no\0"
-"kitagawa.kochi.jp\0edu.mt\0"
-"spy.museum\0stryn.no\0"
-"kamijima.ehime.jp\0edu.mv\0"
-"edu.mw\0edu.ng\0"
-"edu.mx\0house\0"
-"saga.saga.jp\0edu.my\0edu.ni\0"
-"edu.mz\0boldlygoingnowhere.org\0"
-"yoshioka.gunma.jp\0lajolla.museum\0"
-"pc.pl\0pagespeedmobilizer.com\0"
-"edu.nr\0"
-"minoh.osaka.jp\0"
-"masuda.shimane.jp\0"
-"commbank\0"
-"oiso.kanagawa.jp\0edu.om\0"
-"banamex\0"
-"sobetsu.hokkaido.jp\0trust.museum\0"
-"nesoddtangen.no\0"
-"edu.pa\0"
-"chesapeakebay.museum\0"
-"trentino-su\xcc\x88""d-tirol.it\0pacific.museum\0"
-"dyn.home-webserver.de\0"
+"edu.mt\0"
+"off.ai\0k12.dc.us\0"
+"edu.mv\0"
+"edu.mw\0edu.ng\0berlev\xc3\xa5g.no\0"
+"edu.mx\0"
+"edu.my\0edu.ni\0"
+"edu.mz\0fastpanel.direct\0"
+"suzuki\0s3-eu-west-1.amazonaws.com\0"
+"livinghistory.museum\0"
+"trentinoalto-adige.it\0dontexist.net\0"
+"hamburg.museum\0muos\xc3\xa1t.no\0"
+"cn-northwest-1.eb.amazonaws.com.cn\0"
+"edu.nr\0\xe0\xb8\x98\xe0\xb8\xb8\xe0\xb8\xa3\xe0\xb8\x81\xe0\xb8\xb4\xe0\xb8\x88.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0direct\0"
+"fl.us\0agency\0"
+"from-ok.com\0"
+"nishiizu.shizuoka.jp\0komae.tokyo.jp\0"
+"edu.om\0team\0doomdns.com\0"
+"vestre-slidre.no\0"
+"sweden.museum\0edu.pa\0"
+"newhampshire.museum\0"
"edu.pe\0"
-"edu.pf\0duckdns.org\0"
+"pro.az\0ar.it\0nishihara.kumamoto.jp\0edu.pf\0"
"edu.ph\0"
-"\xe6\xa0\x83\xe6\x9c\xa8.jp\0mk.ua\0"
-"edu.pk\0myiphost.com\0"
+"page\0"
+"hikimi.shimane.jp\0"
+"santafe.museum\0edu.pk\0"
"edu.pl\0"
-"jdf.br\0\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0"
-"edu.pn\0"
+"s3-ap-southeast-1.amazonaws.com\0home.dyndns.org\0"
+"pro.br\0edu.pn\0"
+"kasai.hyogo.jp\0clan.rip\0"
"edu.qa\0"
"edu.pr\0"
-"kunneppu.hokkaido.jp\0edu.ps\0"
-"edu.pt\0"
-"yabuki.fukushima.jp\0"
-"kr\xc3\xb8""dsherad.no\0mel\xc3\xb8y.no\0"
-"plurinacional.bo\0"
+"edu.ps\0mordovia.ru\0"
+"nysa.pl\0edu.pt\0"
+"\xe7\xbd\x91\xe7\xbb\x9c.hk\0ing.pa\0"
+"tech\0"
"edu.py\0"
-"shikokuchuo.ehime.jp\0"
-"kiyose.tokyo.jp\0"
-"miho.ibaraki.jp\0"
-"bolzano.it\0versicherung\0"
-"shisui.chiba.jp\0"
-"us.gov.pl\0"
-"cc.la.us\0"
-"aure.no\0"
-"\xe9\xb3\xa5\xe5\x8f\x96.jp\0"
-"kawanishi.nara.jp\0av.tr\0"
-"government.aero\0jampa.br\0"
-"sortland.no\0"
-"mymailer.com.tw\0"
-"edu.sa\0"
-"aerobatic.aero\0edu.sb\0defense.tn\0"
-"in.na\0edu.rs\0edu.sc\0"
-"sn.cn\0edu.sd\0"
+"ugim.gov.pl\0"
+"kameyama.mie.jp\0"
+"madrid.museum\0gjesdal.no\0"
+"elverum.no\0"
+"saotome.st\0"
+"sveio.no\0iveco\0"
+"gifu.jp\0"
+"k12.me.us\0"
+"samsclub\0now-dns.top\0"
+"pro.cy\0"
+"solund.no\0"
+"store\0"
+"nym.gr\0"
+"gjovik.no\0"
+"miyoshi.aichi.jp\0"
+"pro.ec\0convent.museum\0hopto.org\0"
+"ichikawamisato.yamanashi.jp\0"
+"edu.sa\0nym.gy\0"
+"edu.sb\0lamer\0"
+"edu.rs\0edu.sc\0"
+"edu.sd\0"
"edu.ru\0"
-"edu.rw\0edu.sg\0"
-"okuizumo.shimane.jp\0sykkylven.no\0weatherchannel\0"
-"in.ni\0"
-"edu.sl\0idv.tw\0review\0"
-"higashitsuno.kochi.jp\0channelsdvr.net\0"
+"map.fastlylb.net\0"
+"langevag.no\0edu.rw\0edu.sg\0"
+"bmd.br\0"
+"brasil.museum\0cc.ar.us\0"
+"edu.sl\0"
+"nym.ie\0"
"edu.sn\0"
-"selje.no\0"
-"edu.st\0"
-"kawanishi.hyogo.jp\0\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88\0"
-"edu.sv\0"
-"free\0"
-"b\xc3\xa5""d\xc3\xa5""ddj\xc3\xa5.no\0azure\0"
-"kembuchi.hokkaido.jp\0edu.sy\0dev.static.land\0"
-"edu.tj\0"
-"k12.az.us\0"
-"sells-for-less.com\0"
-"edu.tm\0"
-"cloud66.ws\0"
+"muosat.no\0"
+"usa.museum\0"
+"oguni.kumamoto.jp\0edu.st\0"
+"friuli-ve-giulia.it\0edu.sv\0"
+"lg.ua\0"
+"edu.sy\0"
+"shiwa.iwate.jp\0edu.tj\0cheap\0"
+"tysfjord.no\0miami\0"
+"edu.tm\0apple\0"
+"kunimi.fukushima.jp\0iwi.nz\0"
"edu.to\0"
-"surnadal.no\0"
-"edu.ua\0dn.ua\0"
-"hi.cn\0edu.tr\0"
-"fukushima.fukushima.jp\0"
-"edu.tt\0"
-"kunstsammlung.museum\0bargains\0"
+"edu.ua\0"
+"cim.br\0edu.tr\0"
+"bindal.no\0arts.ve\0"
+"ikaruga.nara.jp\0edu.tt\0"
"edu.tw\0"
-"lib.ma.us\0"
-"yabu.hyogo.jp\0"
-"nagatoro.saitama.jp\0"
-"y.bg\0marriott\0"
-"associates\0builders\0diskstation.org\0"
-"okegawa.saitama.jp\0"
-"kikonai.hokkaido.jp\0edu.vc\0"
-"fujikawa.shizuoka.jp\0"
-"usculture.museum\0edu.ve\0"
-"ci.it\0bomlo.no\0"
-"omura.nagasaki.jp\0edu.uy\0"
-"hashima.gifu.jp\0"
-"casadelamoneda.museum\0hasura-app.io\0"
-"bulsan-su\xcc\x88""dtirol.it\0edu.vn\0"
-"friulivenezia-giulia.it\0"
-"pv.it\0childrensgarden.museum\0stj\xc3\xb8rdal.no\0"
-"shintoku.hokkaido.jp\0gs.va.no\0forgot.his.name\0"
-"familyds.com\0"
-"es.gov.br\0garden.museum\0edu.vu\0weather\0"
-"kudamatsu.yamaguchi.jp\0is-a-democrat.com\0crafting.xyz\0"
-"wa.gov.au\0taku.saga.jp\0"
-"mitane.akita.jp\0taka.hyogo.jp\0"
-"paris.museum\0"
-"\xd5\xb0\xd5\xa1\xd5\xb5\0"
-"f.se\0"
-"komoro.nagano.jp\0edu.ws\0george\0"
-"pmn.it\0in.rs\0"
-"aa.no\0"
-"kamisu.ibaraki.jp\0arai.shizuoka.jp\0iki.fi\0"
-"tokai.ibaraki.jp\0shiwa.iwate.jp\0"
-"telekommunikation.museum\0"
-"rokunohe.aomori.jp\0"
-"bounty-full.com\0"
-"cyber.museum\0"
-"chichibu.saitama.jp\0vantaa.museum\0jgora.pl\0hdfcbank\0"
-"is-a-conservative.com\0"
-"\xe9\xa6\x99\xe5\xb7\x9d.jp\0v\xc3\xa5gs\xc3\xb8y.no\0flights\0"
-"emp.br\0"
-"in.th\0movie\0"
-"mediocampidano.it\0"
-"frontdoor\0gbiz\0zappos\0"
-"fie.ee\0military.museum\0ovre-eiker.no\0"
-"shimosuwa.nagano.jp\0kep.tr\0"
-"edu.za\0\xe5\xae\xb6\xe9\x9b\xbb\0"
-"tajiri.osaka.jp\0"
-"abashiri.hokkaido.jp\0in.ua\0"
-"ikaruga.nara.jp\0\xc3\xa5s.no\0"
-"ribeirao.br\0aya.miyazaki.jp\0"
-"tokushima.jp\0"
-"assisi.museum\0"
-"edu.zm\0bofa\0"
-"sch.ae\0"
-"corvette.museum\0"
-"mikasa.hokkaido.jp\0"
-"in.us\0work\0"
-"iwata.shizuoka.jp\0"
-"amami.kagoshima.jp\0"
-"miyoshi.saitama.jp\0"
"eu-4.evennode.com\0"
-"flekkefjord.no\0kvalsund.no\0*.spectrum.myjino.ru\0"
-"ohtawara.tochigi.jp\0"
-"poltava.ua\0"
-"ikusaka.nagano.jp\0ikeda.osaka.jp\0"
-"\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0"
-"cc.va.us\0net.eu.org\0"
-"film.hu\0moscow.museum\0from-nh.com\0"
-"ris\xc3\xb8r.no\0"
-"nagahama.shiga.jp\0kv.ua\0trade\0"
-"e4.cz\0"
-"*.statics.cloud\0"
-"mitsue.nara.jp\0properties\0"
-"osen.no\0"
-"yoichi.hokkaido.jp\0"
-"fam.pk\0"
-"finearts.museum\0"
-"berkeley.museum\0"
-"furudono.fukushima.jp\0gs.ol.no\0"
-"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd9\x87\0"
-"monzabrianza.it\0"
-"dontexist.com\0"
-"penza.su\0"
-"takasu.hokkaido.jp\0gyeongbuk.kr\0cc.wy.us\0spb.ru\0"
-"motosu.gifu.jp\0"
-"imakane.hokkaido.jp\0"
-"servesarcasm.com\0"
-"yashiro.hyogo.jp\0"
-"naklo.pl\0"
-"kicks-ass.net\0"
-"equipment\0"
-"moroyama.saitama.jp\0eu-3.evennode.com\0"
-"avoues.fr\0lib.wa.us\0"
-"poa.br\0zara\0"
-"spb.su\0"
-"tozsde.hu\0"
-"homesecuritymac.com\0"
-"bitballoon.com\0"
-"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0"
-"tools\0"
-"aizumisato.fukushima.jp\0dvrcam.info\0"
-"nikaho.akita.jp\0"
-"mi.it\0"
-"is-a-linux-user.org\0"
-"semboku.akita.jp\0iwanai.hokkaido.jp\0"
-"himeshima.oita.jp\0house.museum\0vf.no\0unj\xc3\xa1rga.no\0cc.md.us\0gallup\0"
-"attorney\0"
-"gd.cn\0"
-"audible\0richardli\0gdynia.pl\0"
-"k\xc3\xa5""fjord.no\0"
-"depot.museum\0"
-"ashoro.hokkaido.jp\0"
-"homeftp.org\0"
-"friulivegiulia.it\0sakae.chiba.jp\0"
+"shirahama.wakayama.jp\0"
+"yoshioka.gunma.jp\0"
+"stuttgart.museum\0sn\xc3\xa5sa.no\0"
+"edu.vc\0"
+"sicily.it\0"
+"edu.ve\0"
+"sakahogi.gifu.jp\0daigo.ibaraki.jp\0"
+"indianapolis.museum\0edu.uy\0s3.dualstack.eu-central-1.amazonaws.com\0nym.la\0"
+"iwamizawa.hokkaido.jp\0buzz\0piaget\0"
+"nym.lc\0"
+"edu.vn\0"
+"o.bg\0"
+"pro.ht\0"
+"skanland.no\0nym.li\0"
+"nym.kz\0"
+"riik.ee\0audio\0"
+"adachi.tokyo.jp\0"
+"edu.vu\0exnet.su\0"
+"iselect\0"
+"sanjo.niigata.jp\0"
+"jamison.museum\0abbvie\0"
+"za.bz\0"
+"sor-aurdal.no\0"
+"adult.ht\0nym.lt\0"
+"miners.museum\0is-an-actor.com\0nym.lu\0nym.me\0"
+"*.cns.joyent.com\0"
+"sv.it\0mukawa.hokkaido.jp\0oshu.iwate.jp\0kawanehon.shizuoka.jp\0krakow.pl\0"
+"edu.ws\0"
+"asahi.toyama.jp\0nym.mn\0"
+"from-ak.com\0"
+"preservation.museum\0"
+"rec.br\0oga.akita.jp\0"
+"okinawa\0"
+"chikuho.fukuoka.jp\0"
+"nym.mx\0"
+"levanger.no\0living\0"
+"8.bg\0space-to-rent.com\0"
+"tokushima.jp\0wanouchi.gifu.jp\0"
+"lifeinsurance\0"
+"\xe7\xa6\x8f\xe5\xb3\xb6.jp\0jetzt\0"
+"rec.co\0bible.museum\0"
+"ibaraki.jp\0usui.fukuoka.jp\0chungbuk.kr\0"
+"takamori.kumamoto.jp\0"
+"eu-3.evennode.com\0"
+"arts.ro\0"
+"is-a-lawyer.com\0"
+"edu.za\0is-a-student.com\0"
+"nym.nz\0"
+"nishikatsura.yamanashi.jp\0"
+"app.lmpm.com\0"
+"po.it\0nishigo.fukushima.jp\0"
"s3.dualstack.us-east-2.amazonaws.com\0"
-"d.bg\0aaa\0"
-"limanowa.pl\0"
-"kimitsu.chiba.jp\0digital\0"
-"cust.testing.thingdust.io\0"
-"chuo.yamanashi.jp\0"
-"vic.edu.au\0dellogliastra.it\0war.museum\0"
-"mitsubishi\0"
-"at.it\0"
-"hashikami.aomori.jp\0"
-"geometre-expert.fr\0"
-"ferrari\0"
-"sch.id\0graphics\0"
-"bond\0"
-"nagareyama.chiba.jp\0abb\0"
-"b\xc3\xb8.nordland.no\0abc\0"
-"pa.it\0kanuma.tochigi.jp\0webhop.net\0"
-"webhosting.be\0"
-"tomi.nagano.jp\0"
-"g\xc3\xa1ls\xc3\xa1.no\0"
-"lib.ak.us\0"
-"vibovalentia.it\0eu-2.evennode.com\0"
-"sch.ir\0fujixerox\0"
-"kamioka.akita.jp\0"
-"saskatchewan.museum\0"
-"kamikawa.hyogo.jp\0"
-"asahi.yamagata.jp\0"
-"harstad.no\0book\0"
-"aisho.shiga.jp\0"
-"dali.museum\0"
-"sch.jo\0from-ks.com\0"
-"lebesby.no\0"
-"sampa.br\0"
-"aco\0"
-"cagliari.it\0olbia-tempio.it\0"
-"obihiro.hokkaido.jp\0r\xc3\xb8ros.no\0kozow.com\0"
-"kyotanabe.kyoto.jp\0"
-"int.ar\0"
-"ri.it\0imabari.ehime.jp\0"
-"nakaniikawa.toyama.jp\0"
-"vanguard\0"
-"int.az\0""4lima.de\0"
-"rost.no\0"
-"ads\0"
-"homeunix.net\0"
-"int.bo\0"
-"sch.lk\0snoasa.no\0aeg\0memset.net\0"
-"bharti\0"
-"batsfjord.no\0"
-"katsuura.chiba.jp\0kashiba.nara.jp\0"
-"niiza.saitama.jp\0y.se\0"
-"hagebostad.no\0za.bz\0"
-"flight.aero\0"
-"int.ci\0dyndns-work.com\0"
-"revista.bo\0"
-"solund.no\0daplie.me\0"
-"ubank\0"
-"\xe7\xbd\x91\xe5\x9d\x80\0"
-"sch.ly\0marburg.museum\0odesa.ua\0"
-"int.co\0meguro.tokyo.jp\0"
-"hi.us\0video\0"
-"online.museum\0dvrdns.org\0"
-"afl\0eu-1.evennode.com\0"
-"nt.edu.au\0"
-"wios.gov.pl\0beats\0ftpaccess.cc\0global.prod.fastly.net\0"
-"\xe6\x96\xb0\xe6\xbd\x9f.jp\0"
-"rindal.no\0""4lima.at\0"
-"nl.ca\0sch.ng\0"
-"blogspot.co.at\0"
-"niigata.jp\0sydney.museum\0"
-"pesaro-urbino.it\0"
-"shizuoka.shizuoka.jp\0nerdpol.ovh\0"
-"\xe5\x8d\x83\xe8\x91\x89.jp\0hemsedal.no\0sandvikcoromant\0"
-"barreau.bj\0ohi.fukui.jp\0"
-"viking.museum\0\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0from-wy.com\0synology-diskstation.de\0"
-"shinjo.okayama.jp\0"
-"from-co.net\0"
-"4lima.ch\0"
-"pharmacy.museum\0actor\0"
-"muenster.museum\0embaixada.st\0"
-"association.museum\0"
-"dyndns.org\0"
-"jessheim.no\0"
-"\xd0\xbe\xd0\xb4.\xd1\x81\xd1\x80\xd0\xb1\0ieee\0\xe6\xb7\xa1\xe9\xa9\xac\xe9\x94\xa1\0"
-"gyeonggi.kr\0"
-"consultant.aero\0"
-"s3-eu-central-1.amazonaws.com\0"
-"bulsan-sudtirol.it\0"
-"museet.museum\0"
-"ecn.br\0brindisi.it\0"
-"studio\0"
-"ami.ibaraki.jp\0h\xc3\xa1mm\xc3\xa1rfeasta.no\0aig\0"
-"cisco\0"
-"ebetsu.hokkaido.jp\0"
-"denmark.museum\0kr.com\0"
-"sch.qa\0promo\0"
-"mi.th\0"
-"tomiya.miyagi.jp\0"
-"vao.it\0kawasaki.miyagi.jp\0cc.vt.us\0"
-"hekinan.aichi.jp\0"
-"bd.se\0"
-"nagaokakyo.kyoto.jp\0bill.museum\0"
-"kinder\0"
-"org.ac\0lib.ut.us\0accountant\0allstate\0from-ne.com\0"
-"org.ae\0"
-"org.af\0asso.fr\0"
-"org.ag\0kakinoki.shimane.jp\0"
-"wiw.gov.pl\0"
-"org.ai\0"
-"loyalist.museum\0gloppen.no\0fresenius\0"
-"guam.gu\0miyoshi.hiroshima.jp\0"
-"org.al\0"
-"mi.us\0"
-"aarborte.no\0"
-"shimonita.gunma.jp\0"
-"sch.sa\0\xe8\x87\xba\xe7\x81\xa3\0\xe7\x82\xb9\xe7\x9c\x8b\0"
-"org.ba\0"
-"org.ar\0org.bb\0"
-"asso.gp\0"
-"org.au\0sannan.hyogo.jp\0"
-"miyama.fukuoka.jp\0"
-"org.bh\0kosai.shizuoka.jp\0"
-"org.bi\0etc.br\0"
-"org.az\0"
-"nakatsugawa.gifu.jp\0"
-"futsu.nagasaki.jp\0paris\0"
-"org.bm\0int.is\0"
-"org.bn\0s3-ap-southeast-2.amazonaws.com\0"
-"org.bo\0"
-"minokamo.gifu.jp\0"
-"org.br\0"
-"org.bs\0"
-"org.bt\0for-the.biz\0"
-"karasuyama.tochigi.jp\0plants.museum\0static.land\0"
-"org.bw\0"
-"asso.ht\0"
-"org.ci\0"
-"org.bz\0"
-"union.aero\0*.platform.sh\0"
-"erotica.hu\0"
-"org.cn\0ino.kochi.jp\0"
-"org.co\0randaberg.no\0vindafjord.no\0"
-"hiraizumi.iwate.jp\0"
-"railway.museum\0swidnica.pl\0\xe0\xb8\xad\xe0\xb8\x87\xe0\xb8\x84\xe0\xb9\x8c\xe0\xb8\x81\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0"
-"friuli-vgiulia.it\0"
-"org.cu\0"
-"pa.us\0"
-"org.cw\0blogspot.co.id\0"
-"accountants\0"
-"org.cy\0"
-"kamimine.saga.jp\0naumburg.museum\0"
-"int.la\0stor-elvdal.no\0property\0"
-"org.dm\0statebank\0"
-"asso.bj\0"
-"org.do\0blogspot.co.il\0"
-"d\xc3\xb8nna.no\0"
-"misato.wakayama.jp\0"
-"org.ec\0saga.jp\0"
-"isa.us\0"
-"org.ee\0int.lk\0rade.no\0bukhara.su\0"
-"\xe6\xbb\x8b\xe8\xb3\x80.jp\0herokuapp.com\0"
-"org.eg\0experts-comptables.fr\0lease\0"
-"takarazuka.hyogo.jp\0"
-"niyodogawa.kochi.jp\0"
-"org.dz\0yasu.shiga.jp\0"
-"asso.ci\0anz\0"
-"w.bg\0aol\0"
-"amsterdam\0"
-"unjarga.no\0"
-"org.es\0"
-"org.et\0"
-"s3.ap-northeast-2.amazonaws.com\0"
-"gojome.akita.jp\0"
-"nerima.tokyo.jp\0"
-"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa4\xae\xe0\xa5\x8d\0"
-"val-d-aosta.it\0"
-"jp.eu.org\0"
-"sncf\0"
-"ri.us\0dodge\0"
-"mima.tokushima.jp\0int.mv\0"
-"int.mw\0"
-"pt.it\0southwest.museum\0"
-"int.ni\0s\xc3\xb8r-fron.no\0app\0kindle\0"
-"nishihara.okinawa.jp\0yandex\0"
-"org.ge\0pisa.it\0doesntexist.com\0"
-"watari.miyagi.jp\0yono.saitama.jp\0kosei.shiga.jp\0"
-"org.gg\0"
-"org.gh\0"
-"org.gi\0zhitomir.ua\0karaganda.su\0"
-"satte.saitama.jp\0"
-"mitaka.tokyo.jp\0frogn.no\0"
-"org.gl\0h\xc3\xb8yanger.no\0"
-"systems\0"
-"asso.dz\0org.gn\0sarpsborg.no\0"
-"swiss\0"
-"org.gp\0\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\0"
-"org.gr\0d.se\0"
-"org.gt\0"
-"org.gu\0bar\0"
-"bbc\0"
-"tempio-olbia.it\0tobishima.aichi.jp\0"
-"elk.pl\0"
-"org.gy\0trentinoalto-adige.it\0"
-"aju.br\0org.hk\0"
-"tanabe.wakayama.jp\0apartments\0"
-"org.hn\0suginami.tokyo.jp\0"
-"pimienta.org\0"
-"fortworth.museum\0"
-"\xe7\x9f\xb3\xe5\xb7\x9d.jp\0"
-"org.ht\0nl.no\0"
-"org.hu\0"
-"art\0bbt\0"
-"barsy.info\0"
-"bcg\0education\0"
-"itoigawa.niigata.jp\0"
-"org.il\0hakusan.ishikawa.jp\0yamato.kanagawa.jp\0ina.nagano.jp\0sch.zm\0"
-"org.im\0ap-south-1.elasticbeanstalk.com\0"
-"org.in\0int.pt\0turen.tn\0chase\0"
-"l\xc3\xa4ns.museum\0"
-"org.iq\0valle\xcc\x81""edaoste.it\0bcn\0"
-"org.ir\0"
-"org.is\0byen.site\0"
-"org.je\0environmentalconservation.museum\0"
-"watchandclock.museum\0intel\0"
-"minamidaito.okinawa.jp\0bonn.museum\0"
-"doshi.yamanashi.jp\0"
-"daito.osaka.jp\0katano.osaka.jp\0"
-"taiwa.miyagi.jp\0"
-"org.jo\0"
-"a\xc3\xa9roport.ci\0"
-"miyake.nara.jp\0il.us\0"
-"org.kg\0"
-"org.ki\0"
-"q-a.eu.org\0"
-"org.km\0"
-"org.kn\0nuernberg.museum\0"
-"int.ru\0"
-"yamanashi.jp\0org.kp\0\xe0\xb8\x97\xe0\xb8\xab\xe0\xb8\xb2\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0pictures\0"
-"ueno.gunma.jp\0chiyoda.tokyo.jp\0org.la\0int.rw\0wi.us\0lamborghini\0"
-"org.lb\0"
-"org.lc\0"
-"eu.com\0"
-"sakura.chiba.jp\0"
-"org.kw\0bet\0virtualuser.de\0"
-"saroma.hokkaido.jp\0"
-"org.ky\0cincinnati.museum\0ybo.review\0"
-"org.kz\0"
-"org.lk\0gdansk.pl\0"
-"design.museum\0vlaanderen.museum\0"
-"society.museum\0"
-"org.ma\0smart\0"
-"org.lr\0australia.museum\0"
-"org.ls\0"
-"int.tj\0is-very-nice.org\0"
-"org.me\0"
-"marumori.miyagi.jp\0org.lv\0"
-"org.mg\0dnsup.net\0"
-"org.ly\0ddnsgeek.com\0"
-"org.mk\0"
-"org.ml\0\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0parts\0\xd8\xa8\xd8\xa7\xd8\xb2\xd8\xa7\xd8\xb1\0"
-"\xe5\x92\x8c\xe6\xad\x8c\xe5\xb1\xb1.jp\0omotego.fukushima.jp\0"
-"org.mn\0int.tt\0"
-"org.mo\0center\0"
-"freiburg.museum\0org.na\0"
-"journalist.aero\0chuo.tokyo.jp\0estate\0party\0"
-"org.ms\0"
-"org.mt\0axa\0"
-"org.mu\0"
-"calabria.it\0org.mv\0aws\0googleapis.com\0"
-"miners.museum\0org.mw\0org.ng\0"
-"niimi.okayama.jp\0toyama.toyama.jp\0org.mx\0"
-"org.my\0org.ni\0"
-"org.mz\0"
-"val-daosta.it\0oumu.hokkaido.jp\0"
-"naganohara.gunma.jp\0int.ve\0"
-"l\xc3\xb8renskog.no\0org.nr\0"
-"ens.tn\0\xd0\xb1\xd0\xb3\0"
-"\xe6\x9d\xb1\xe4\xba\xac.jp\0"
-"principe.st\0bid\0"
-"shiso.hyogo.jp\0int.vn\0"
-"org.nz\0"
-"olayangroup\0"
-"org.om\0"
-"org.pa\0\xd8\xa7\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\0"
-"bio\0"
-"musashino.tokyo.jp\0"
-"org.pe\0cafe\0"
-"org.pf\0mytis.ru\0"
-"org.ph\0"
-"village.museum\0from-pr.com\0"
-"\xe6\x9c\xba\xe6\x9e\x84\0"
-"org.pk\0"
-"name.hr\0org.pl\0browsersafetymark.io\0"
-"biz\0"
-"ogose.saitama.jp\0org.pn\0kicks-ass.org\0blogspot.co.uk\0"
-"okagaki.fukuoka.jp\0"
-"nayoro.hokkaido.jp\0"
-"openair.museum\0org.qa\0"
-"org.pr\0istanbul\0"
-"org.ps\0"
-"org.pt\0"
-"bibai.hokkaido.jp\0"
-"org.py\0k12.nh.us\0"
-"tsuno.kochi.jp\0"
-"tokamachi.niigata.jp\0wales\0"
-"cng.br\0"
-"name.et\0"
-"b.bg\0"
-"karpacz.pl\0"
-"otsuka\0"
-"mini\0"
-"ar.it\0hikawa.shimane.jp\0\xe5\x95\x86\xe5\x9f\x8e\0"
-"homeftp.net\0"
-"video.hu\0gs.fm.no\0"
-"b.br\0"
-"org.ro\0"
-"rennes\xc3\xb8y.no\0"
-"org.sa\0"
-"org.sb\0"
-"org.rs\0org.sc\0mint\0"
-"sayama.osaka.jp\0nirasaki.yamanashi.jp\0org.sd\0"
-"org.se\0org.ru\0"
-"gjerstad.no\0"
-"kommune.no\0org.sg\0"
-"takashima.shiga.jp\0fhs.no\0org.sh\0from-mn.com\0"
-"bsb.br\0\xc3\xb8rskog.no\0"
-"jfk.museum\0"
-"org.sl\0"
-"iwatsuki.saitama.jp\0nanto.toyama.jp\0org.sn\0"
-"org.so\0"
-"kurashiki.okayama.jp\0\xc3\xa5""fjord.no\0\xd2\x9b\xd0\xb0\xd0\xb7\0"
-"civilaviation.aero\0clock.museum\0"
-"name.cy\0traniandriabarletta.it\0pruszkow.pl\0"
-"org.st\0fastvps-server.com\0"
-"lib.mn.us\0"
-"org.sv\0bms\0"
-"mashiki.kumamoto.jp\0"
-"asso.re\0org.sy\0"
-"sogndal.no\0org.sz\0org.tj\0bmw\0"
-"balestrand.no\0"
-"org.tm\0insurance\0"
-"org.tn\0\xd0\xb5\xd1\x8e\0"
-"otofuke.hokkaido.jp\0org.to\0bnl\0citic\0"
-"\xc3\xa5rdal.no\0"
-"name.eg\0org.ua\0"
-"cz.it\0toyohashi.aichi.jp\0skaun.no\0org.tr\0"
-"mihama.aichi.jp\0"
-"jewelry.museum\0org.tt\0"
-"cc.de.us\0"
-"org.tw\0org.ug\0"
-"lupin\0"
-"shoes\0"
-"org.uk\0here-for-more.info\0"
-"rg.it\0matta-varjjat.no\0"
-"\xe5\x95\x86\xe6\xa5\xad.tw\0wedeploy.sh\0"
-"bom\0"
-"boo\0"
-"org.vc\0"
-"name.az\0"
-"org.ve\0"
-"tateyama.chiba.jp\0"
-"bot\0"
-"chungnam.kr\0blogspot.co.ke\0nhlfan.net\0"
-"kanie.aichi.jp\0miura.kanagawa.jp\0org.uy\0org.vi\0"
-"ishinomaki.miyagi.jp\0org.uz\0"
-"box\0"
-"call\0"
-"national.museum\0stavern.no\0w.se\0"
-"org.vn\0lima-city.de\0"
-"aip.ee\0"
-"kani.gifu.jp\0"
-"wake.okayama.jp\0"
-"\xe5\xbe\xb3\xe5\xb3\xb6.jp\0"
-"org.vu\0cab\0"
-"soeda.fukuoka.jp\0"
-"terni.it\0"
-"fr.it\0homeunix.org\0"
-"\xd0\xbe\xd0\xb1\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0"
-"from-sd.com\0"
-"cal\0"
-"cam\0camp\0blackbaudcdn.net\0"
-"hidaka.kochi.jp\0"
-"ut.us\0org.ws\0"
-"cba\0"
-"car\0"
-"to.it\0servebeer.com\0"
-"cat\0fukusaki.hyogo.jp\0takanezawa.tochigi.jp\0asso.nc\0*.ex.ortsinfo.at\0"
-"klabu.no\0k12.ga.us\0"
-"lima-city.at\0"
-"higashiyama.kyoto.jp\0"
-"shikatsu.aichi.jp\0"
-"gorizia.it\0cbn\0*.hosting.myjino.ru\0"
-"gjerdrum.no\0"
-"ikano\0"
-"cbs\0"
-"wakayama.jp\0"
-"mobi.gp\0"
-"hasvik.no\0sosnowiec.pl\0apple\0"
-"kaita.hiroshima.jp\0org.za\0lima-city.ch\0"
-"eidsvoll.no\0"
-"siracusa.it\0"
+"fj.cn\0tome.miyagi.jp\0"
+"edu.zm\0nym.pe\0"
+"v-info.info\0"
+"tomakomai.hokkaido.jp\0hosting-cluster.nl\0"
+"click\0"
"miharu.fukushima.jp\0"
-"palmsprings.museum\0teaches-yoga.com\0"
-"ibestad.no\0"
-"kagami.kochi.jp\0"
-"avocat.pro\0"
-"org.zm\0blogspot.co.nz\0"
-"foundation.museum\0style\0dattorelay.com\0"
-"air-surveillance.aero\0for-more.biz\0"
-"toray\0"
-"zaporizhzhia.ua\0"
-"sande.more-og-romsdal.no\0\xe7\xbd\x91\xe7\xab\x99\0"
-"lib.gu.us\0ceb\0"
-"org.zw\0"
-"jeju.kr\0"
-"haebaru.okinawa.jp\0"
-"police.uk\0"
-"nomi.ishikawa.jp\0is-a-green.com\0"
-"divttasvuotna.no\0ceo\0"
-"tree.museum\0zt.ua\0"
-"yugawara.kanagawa.jp\0v\xc3\xa5gan.no\0cfa\0engineering\0""001www.com\0"
-"choshi.chiba.jp\0care\0"
-"cfd\0"
-"usa.oita.jp\0lowicz.pl\0gifts\0"
-"uscountryestate.museum\0is.eu.org\0"
-"buy\0"
-"kr.it\0missoula.museum\0sohu\0"
-"iide.yamagata.jp\0"
-"from-sc.com\0"
-"casa\0"
-"cars\0"
-"per.la\0case\0"
-"soma.fukushima.jp\0"
-"romskog.no\0"
-"izumisano.osaka.jp\0cash\0"
-"booking\0"
-"k12.la.us\0"
-"\xe4\xbd\x90\xe8\xb3\x80.jp\0"
-"ibigawa.gifu.jp\0"
-"asso.km\0"
-"muni.il\0karatsu.saga.jp\0science-fiction.museum\0xbox\0"
+"r\xc3\xb8st.no\0s3.eu-central-1.amazonaws.com\0"
+"midori.chiba.jp\0"
+"moriyama.shiga.jp\0"
+"natuurwetenschappen.museum\0"
+"nym.pt\0"
+"pro.na\0moto\0"
+"aero.tt\0map.fastly.net\0"
+"hidaka.kochi.jp\0"
+"crew.aero\0"
+"pro.mv\0"
+"histoire.museum\0krokstadelva.no\0giving\0"
+"microsoft\0"
"ar.us\0"
-"valle\xcc\x81""e-d-aoste.it\0"
-"kozagawa.wakayama.jp\0it.eu.org\0myvnc.com\0"
-"cog.mi.us\0"
-"folldal.no\0"
-"\xd1\x80\xd1\x84\0"
-"honjo.saitama.jp\0asso.mc\0"
-"cultural.museum\0per.nf\0cc.ne.us\0"
-"tvedestrand.no\0wedeploy.me\0"
-"he.cn\0spydeberg.no\0"
-"kommunalforbund.se\0"
-"rifu.miyagi.jp\0"
-"inuyama.aichi.jp\0nishio.aichi.jp\0akagi.shimane.jp\0k12.ny.us\0"
-"mormon\0"
-"gs.svalbard.no\0"
-"jevnaker.no\0lib.me.us\0office\0myshopblocks.com\0"
-"shibecha.hokkaido.jp\0"
-"tj\xc3\xb8me.no\0bzh\0"
-"u.bg\0\xe9\xa3\x9f\xe5\x93\x81\0"
-"takatori.nara.jp\0"
-"czest.pl\0"
-"modelling.aero\0"
-"hammarfeasta.no\0"
-"ce.it\0gausdal.no\0"
-"\xd7\x99\xd7\xa8\xd7\x95\xd7\xa9\xd7\x9c\xd7\x99\xd7\x9d.museum\0square7.net\0edu.krd\0"
-"shinjo.nara.jp\0is-very-bad.org\0"
-"potenza.it\0"
-"jelenia-gora.pl\0localhost.daplie.me\0"
-"9guacu.br\0"
-"audio\0"
-"naples.it\0pr.it\0furano.hokkaido.jp\0kamikawa.hokkaido.jp\0song\0"
-"ask\xc3\xb8y.no\0"
-"orange\0telecity\0serveblog.net\0"
-"orland.no\0"
-"ikata.ehime.jp\0"
-"name.vn\0mozilla-iot.org\0"
-"fund\0"
-"in.eu.org\0"
-"matsushima.miyagi.jp\0c66.me\0dattoweb.com\0"
-"realm.cz\0"
-"\xe5\xba\x83\xe5\xb3\xb6.jp\0"
-"b.se\0"
-"myactivedirectory.com\0"
-"sony\0"
-"ookuwa.nagano.jp\0"
-"berlin\0"
-"xj.cn\0barletta-trani-andria.it\0is-a-painter.com\0"
-"annaka.gunma.jp\0tsukui.kanagawa.jp\0"
-"towada.aomori.jp\0"
-"deporte.bo\0fukuyama.hiroshima.jp\0gent\0does-it.net\0"
-"bieszczady.pl\0"
-"b\xc3\xa1hccavuotna.no\0"
-"kikuchi.kumamoto.jp\0surrey.museum\0piaget\0"
-"tos.it\0"
-"barsy.club\0"
-"name.tj\0"
-"republican\0"
-"aquarelle\0dunlop\0"
-"nakagawa.nagano.jp\0"
-"environment.museum\0"
-"per.sg\0"
-"name.tr\0"
-"verm\xc3\xb6gensberatung\0customer.enonic.io\0"
-"samukawa.kanagawa.jp\0name.tt\0ericsson\0"
-"compare\0"
-"katagami.akita.jp\0"
-"elburg.museum\0blogspot.co.za\0"
-"mashiko.tochigi.jp\0imizu.toyama.jp\0"
-"seika.kyoto.jp\0gildesk\xc3\xa5l.no\0"
-"station.museum\0"
-"elvendrell.museum\0"
-"kitashiobara.fukushima.jp\0"
-"nic.in\0iglesiascarbonia.it\0"
-"sunagawa.hokkaido.jp\0bu.no\0"
-"com\0\xe9\x9d\x92\xe6\xa3\xae.jp\0"
-"ollo\0"
-"kashiwa.chiba.jp\0otobe.hokkaido.jp\0"
-"shibuya.tokyo.jp\0halsa.no\0\xd0\xbc\xd0\xbe\xd1\x81\xd0\xba\xd0\xb2\xd0\xb0\0*.cns.joyent.com\0"
-"catering.aero\0dyn-ip24.de\0"
-"s3.dualstack.ap-south-1.amazonaws.com\0"
-"\xe7\xbd\x91\xe7\xb5\xa1.hk\0okoppe.hokkaido.jp\0"
-"chosei.chiba.jp\0"
-"agdenes.no\0\xe5\x85\xab\xe5\x8d\xa6\0"
-"vana\0"
-"riobranco.br\0"
-"cam.it\0canon\0"
-"airtel\0"
-"vb.it\0"
-"higashinaruse.akita.jp\0"
-"pizza\0"
-"fjell.no\0dad\0myjino.ru\0"
-"career\0"
-"\xe5\x8f\xb0\xe6\xb9\xbe\0"
-"kitaakita.akita.jp\0kr.ua\0*.quipelements.com\0"
-"nanmoku.gunma.jp\0musashimurayama.tokyo.jp\0"
-"joetsu.niigata.jp\0"
-"s3.dualstack.ap-southeast-1.amazonaws.com\0"
-"k12.va.us\0"
-"macapa.br\0ehime.jp\0"
+"sc.cn\0higashiosaka.osaka.jp\0"
+"pars\0"
+"philadelphia.museum\0lima-city.de\0"
+"lib.nv.us\0"
+"nakagawa.fukuoka.jp\0"
+"\xe4\xb8\xaa\xe4\xba\xba.hk\0nordkapp.no\0"
+"aero.mv\0"
+"baltimore.museum\0"
+"arts.nf\0"
+"shiksha\0"
+"nym.ro\0"
+"pro.om\0"
+"eu-2.evennode.com\0"
+"google\0"
+"nisshin.aichi.jp\0oyamazaki.kyoto.jp\0higashimatsuyama.saitama.jp\0"
+"vallee-d-aoste.it\0serveblog.net\0"
+"agro.pl\0agrinet.tn\0"
+"\xe3\x82\xb0\xe3\x83\xbc\xe3\x82\xb0\xe3\x83\xab\0verm\xc3\xb6gensberatung\0loginto.me\0nym.sk\0"
+"kiyokawa.kanagawa.jp\0kagamino.okayama.jp\0"
+"zt.ua\0"
+"barletta-trani-andria.it\0lima-city.at\0"
+"aeroport.fr\0"
+"kikonai.hokkaido.jp\0shell\0boomla.net\0"
+"nym.su\0"
+"pro.pr\0"
"yokohama\0"
-"radoy.no\0"
-"kiyama.saga.jp\0j\xc3\xb8lster.no\0"
-"estate.museum\0serveminecraft.net\0"
-"reg.dk\0"
-"name.qa\0"
-"name.pr\0day\0"
-"yoshino.nara.jp\0"
-"fedorapeople.org\0"
-"gunma.jp\0vestv\xc3\xa5g\xc3\xb8y.no\0"
-"lombardy.it\0gamo.shiga.jp\0my-gateway.de\0"
-"mango\0"
-"reisen\0is-an-accountant.com\0"
-"crs\0csc\0"
-"name.na\0fedorainfracloud.org\0"
-"nagara.chiba.jp\0utashinai.hokkaido.jp\0creditcard\0"
-"joyo.kyoto.jp\0katowice.pl\0"
-"s3.amazonaws.com\0"
-"name.mv\0"
-"mihama.fukui.jp\0name.ng\0support\0"
-"!city.kitakyushu.jp\0name.my\0company\0"
-"8.bg\0"
-"vix.br\0computerhistory.museum\0"
-"fujimi.nagano.jp\0"
-"contractors\0"
-"nakai.kanagawa.jp\0\xd9\x85\xd9\x84\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa7\0"
-"miyako.iwate.jp\0"
-"okawa.fukuoka.jp\0gujo.gifu.jp\0"
-"kids.us\0"
-"campidano-medio.it\0mishima.fukushima.jp\0"
-"nj.us\0"
-"karuizawa.nagano.jp\0dds\0groks-the.info\0"
-"lu.it\0me.it\0"
-"dyndns-ip.com\0"
-"campinagrande.br\0education.museum\0"
-"trentin-su\xcc\x88""dtirol.it\0sekigahara.gifu.jp\0moss.no\0"
-"makeup\0"
-"bible.museum\0"
-"parachuting.aero\0chikugo.fukuoka.jp\0chernivtsi.ua\0"
-"us-west-2.elasticbeanstalk.com\0"
-"ballooning.aero\0"
-"galsa.no\0gok.pk\0cbre\0wedeploy.io\0"
-"bjark\xc3\xb8y.no\0\xe3\x82\xbb\xe3\x83\xbc\xe3\x83\xab\0from-tx.com\0"
-"sumoto.kumamoto.jp\0"
-"me.ke\0dev\0"
-"grosseto.it\0"
-"sevastopol.ua\0"
-"yakage.okayama.jp\0"
-"abiko.chiba.jp\0name.mk\0"
+"jobs.tt\0nym.sx\0"
+"club.aero\0journalism.museum\0symantec\0"
+"takamori.nagano.jp\0"
+"kamigori.hyogo.jp\0"
+"github.io\0"
+"reviews\0"
+"ariake.saga.jp\0lima-city.ch\0"
+"trentinos\xc3\xbc""dtirol.it\0"
+"mysecuritycamera.org\0nym.tw\0"
+"inzai.chiba.jp\0verisign\0"
+"nakagyo.kyoto.jp\0"
+"surf\0"
+"k12.tn.us\0"
+"apps.lair.io\0"
+"risor.no\0"
+"finn\xc3\xb8y.no\0"
+"kafjord.no\0"
+"ujitawara.kyoto.jp\0""64-b.it\0"
+"eu-1.evennode.com\0"
+"hamburg\0dvrcam.info\0"
+"minamiaiki.nagano.jp\0"
+"mt.eu.org\0"
+"abogado\0"
+"shimokawa.hokkaido.jp\0"
+"ninomiya.kanagawa.jp\0hatogaya.saitama.jp\0"
+"batsfjord.no\0"
+"kamikoani.akita.jp\0"
+"\xd9\x85\xd9\x84\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa7\0lenug.su\0"
+"samnanger.no\0"
+"gs.ol.no\0glade\0"
+"pro.tt\0\xd9\xbe\xd8\xa7\xd9\x83\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0"
+"hn.cn\0"
+"mihama.chiba.jp\0"
+"stavern.no\0"
+"bs.it\0kuji.iwate.jp\0kisosaki.mie.jp\0"
+"tydal.no\0\xe5\x85\xac\xe5\x8f\xb8.\xe9\xa6\x99\xe6\xb8\xaf\0"
+"cv.ua\0"
+"sakado.saitama.jp\0hospital\0"
+"sc.ke\0"
+"rec.nf\0"
+"takatsuki.shiga.jp\0"
+"\xe7\xb5\x84\xe7\xb9\x94.\xe9\xa6\x99\xe6\xb8\xaf\0teva\0square7.de\0"
+"yuasa.wakayama.jp\0"
+"choshi.chiba.jp\0"
+"shiroishi.miyagi.jp\0tottori.tottori.jp\0sc.kr\0pro.vn\0thruhere.net\0"
+"balashov.su\0cust.disrec.thingdust.io\0"
+"tw.cn\0yawara.ibaraki.jp\0"
+"lib.pr.us\0"
+"kitamoto.saitama.jp\0"
+"hurdal.no\0sling\0"
+"chonan.chiba.jp\0endofinternet.net\0"
+"githubusercontent.com\0"
+"sc.ls\0sogndal.no\0"
+"judaica.museum\0"
+"heguri.nara.jp\0"
+"cc.sc.us\0"
+"wajima.ishikawa.jp\0"
+"sec.ps\0"
+"masaki.ehime.jp\0augustow.pl\0"
+"imdb\0"
+"\xd1\x83\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0hdfcbank\0"
+"landrover\0"
+"costume.museum\0"
+"*.compute.amazonaws.com.cn\0"
+"history.museum\0alsace\0"
+"karatsu.saga.jp\0"
+"fukushima.fukushima.jp\0nabari.mie.jp\0"
+"skype\0"
+"cc.na\0"
+"le.it\0rifu.miyagi.jp\0square7.ch\0"
+"fla.no\0watches\0backplaneapp.io\0definima.io\0"
+"mikasa.hokkaido.jp\0"
+"nyc.museum\0"
+"seranishi.hiroshima.jp\0nakatane.kagoshima.jp\0"
+"aya.miyazaki.jp\0custom.metacentrum.cz\0"
+"its.me\0harvestcelebration.museum\0abo.pa\0o.se\0"
+"limanowa.pl\0"
+"corvette.museum\0"
+"artsandcrafts.museum\0watchandclock.museum\0pors\xc3\xa1\xc5\x8bgu.no\0vard\xc3\xb8.no\0"
+"naruto.tokushima.jp\0"
+"devices.resinstaging.io\0"
+"rec.ro\0accenture\0"
+"boston.museum\0sciences.museum\0"
+"takayama.gifu.jp\0abashiri.hokkaido.jp\0"
+"dyndns-wiki.com\0"
+"solutions\0"
+"minamata.kumamoto.jp\0"
+"s\xc3\xb8r-aurdal.no\0"
+"ibaraki.ibaraki.jp\0"
+"fantasyleague.cc\0"
+"vet.br\0\xe5\xb2\xa9\xe6\x89\x8b.jp\0inabe.mie.jp\0"
+"pila.pl\0"
+"balestrand.no\0hornindal.no\0"
+"virgin\0"
+"hepforge.org\0"
+"ukiha.fukuoka.jp\0"
+"ol.no\0"
+"ufcfan.org\0"
+"ino.kochi.jp\0"
+"farmstead.museum\0"
+"community.museum\0land-4-sale.us\0"
+"kaneyama.yamagata.jp\0"
+"topology.museum\0\xc3\xa1laheadju.no\0aurskog-h\xc3\xb8land.no\0"
+"tec.ve\0"
+"kumakogen.ehime.jp\0ujiie.tochigi.jp\0"
+"idrett.no\0"
+"esp.br\0"
+"is-a-guru.com\0"
+"ikawa.akita.jp\0kamitsue.oita.jp\0"
+"\xe7\xb6\xb2\xe7\xb5\xa1.\xe9\xa6\x99\xe6\xb8\xaf\0"
+"alt.za\0xnbay.com\0"
+"ragusa.it\0"
+"scienceandindustry.museum\0holmestrand.no\0lib.wi.us\0"
+"minokamo.gifu.jp\0chikusei.ibaraki.jp\0definima.net\0"
+"uz.ua\0"
+"cal.it\0"
+"trento.it\0twmail.net\0"
+"aero\0halsa.no\0"
+"\xe5\xae\xae\xe5\xb4\x8e.jp\0"
+"rec.ve\0nohost.me\0"
+"mifune.kumamoto.jp\0"
+"skj\xc3\xa5k.no\0my.eu.org\0"
+"kuzumaki.iwate.jp\0"
+"net.ac\0academia.bo\0s3-ca-central-1.amazonaws.com\0"
+"dnsking.ch\0"
+"net.ae\0"
+"net.af\0umb.it\0"
+"net.ag\0alaheadju.no\0hobol.no\0aaa\0"
+"ojiya.niigata.jp\0yamanakako.yamanashi.jp\0"
+"net.ai\0communication.museum\0grong.no\0"
+"net.al\0imb.br\0cartier\0"
+"juif.museum\0bardu.no\0surnadal.no\0accesscam.org\0"
+"read\0"
+"net.ba\0kaluga.su\0"
+"net.ar\0net.bb\0aquila.it\0kuriyama.hokkaido.jp\0"
+"inazawa.aichi.jp\0chat\0"
+"net.au\0"
+"hemne.no\0"
+"net.bh\0abb\0"
+"windmill.museum\0spydeberg.no\0abc\0ditchyourip.com\0"
+"net.az\0citadel\0"
+"pccw\0"
+"okagaki.fukuoka.jp\0ginowan.okinawa.jp\0"
+"net.bm\0"
+"net.bn\0takazaki.miyazaki.jp\0"
+"net.bo\0askim.no\0l\xc3\xb8renskog.no\0sc.ug\0"
"ap.it\0"
-"tm.cy\0center.museum\0belau.pw\0"
-"cc.ak.us\0"
+"deals\0"
+"net.br\0sc.tz\0"
+"net.bs\0k12.al.us\0cc.ua\0"
+"net.bt\0tainai.niigata.jp\0kakinoki.shimane.jp\0pcloud.host\0"
+"stuff-4-sale.us\0"
"gobo.wakayama.jp\0"
-"ma.gov.br\0"
-"pr.us\0"
-"oshima.tokyo.jp\0no.com\0"
-"\xe5\x9c\xa8\xe7\xba\xbf\0"
-"taxi.br\0"
-"columbus.museum\0"
-"hamura.tokyo.jp\0utsira.no\0"
-"minami.fukuoka.jp\0swinoujscie.pl\0cc.oh.us\0"
-"bjugn.no\0"
-"is-a-libertarian.com\0"
-"name.jo\0s3-website-eu-west-1.amazonaws.com\0dattolocal.net\0sopot.pl\0"
-"noboribetsu.hokkaido.jp\0we.bs\0"
-"enebakk.no\0"
-"soka.saitama.jp\0mobi.tt\0dhl\0\xeb\x8b\xb7\xec\xbb\xb4\0"
-"krager\xc3\xb8.no\0"
-"mobi.tz\0"
-"minamiboso.chiba.jp\0"
-"taa.it\0omihachiman.shiga.jp\0"
-"flowers\0"
-"\xe5\xae\xae\xe5\xb4\x8e.jp\0nakijin.okinawa.jp\0"
-"kamo.kyoto.jp\0"
-"londrina.br\0"
-"tm.fr\0\xe9\xb9\xbf\xe5\x85\x90\xe5\xb3\xb6.jp\0\xe5\xa8\xb1\xe4\xb9\x90\0"
-"kosuge.yamanashi.jp\0eng.pro\0naturbruksgymn.se\0cc.dc.us\0"
-"oceanographique.museum\0"
-"myhome-server.de\0"
-"re.it\0nic.tj\0"
-"toki.gifu.jp\0hapmir.no\0diy\0"
-"akabira.hokkaido.jp\0\xe5\x85\xac\xe5\x8f\xb8\0\xe6\x97\xb6\xe5\xb0\x9a\0"
-"uk.com\0"
-"\xe3\x81\xbf\xe3\x82\x93\xe3\x81\xaa\0is-a-blogger.com\0"
-"yamagata.gifu.jp\0tosa.kochi.jp\0fusa.no\0"
-"psse.gov.pl\0"
-"valleaosta.it\0ma.leg.br\0"
-"stord.no\0"
-"settlers.museum\0"
-"gaivuotna.no\0"
-"u.se\0s3-eu-west-2.amazonaws.com\0"
-"nhs.uk\0"
-"cesenaforli\xcc\x80.it\0"
-"wolterskluwer\0"
-"events\0"
-"church\0"
-"tm.hu\0ushiku.ibaraki.jp\0glas.museum\0"
-"kafjord.no\0gu.us\0"
-"aejrie.no\0computer\0"
-"iselect\0"
-"como.it\0re.kr\0komvux.se\0"
-"utazas.hu\0"
-"kurobe.toyama.jp\0"
-"engineer.aero\0"
-"duck\0travelchannel\0"
-"from-ia.com\0"
-"*.s5y.io\0"
-"franziskaner.museum\0"
-"omasvuotna.no\0"
-"baseball\0"
-"tawaramoto.nara.jp\0"
-"lecce.it\0"
-"pub.sa\0"
-"mobi.na\0spot\0"
-"midtre-gauldal.no\0"
-"toyono.osaka.jp\0"
-"k12.tn.us\0catering\0"
-"asakawa.fukushima.jp\0pharmaciens.km\0nyc.museum\0mobi.ng\0"
-"freeboxos.fr\0"
-"realty\0"
-"yakumo.shimane.jp\0"
-"oshu.iwate.jp\0"
-"usa.museum\0"
-"trolley.museum\0skanland.no\0"
+"takikawa.hokkaido.jp\0"
+"net.ci\0"
+"net.bz\0my.id\0"
+"sc.us\0"
+"net.cm\0energy\0"
+"net.cn\0konan.aichi.jp\0biratori.hokkaido.jp\0"
+"net.co\0coupons\0"
+"ownip.net\0gotdns.ch\0"
+"gonohe.aomori.jp\0inawashiro.fukushima.jp\0jp.net\0"
+"net.cu\0coloradoplateau.museum\0giessen.museum\0aco\0"
+"act.edu.au\0net.cw\0"
+"shimodate.ibaraki.jp\0"
+"net.cy\0"
+"hjelmeland.no\0"
+"net.dm\0"
+"net.do\0"
+"joinville.br\0"
+"unj\xc3\xa1rga.no\0immo\0\xe5\xa4\xa7\xe6\x8b\xbf\0dyndns-web.com\0"
+"net.ec\0rennesoy.no\0"
+"komvux.se\0"
+"net.eg\0memorial.museum\0"
+"ads\0science\0"
+"net.dz\0minato.tokyo.jp\0"
+"aeg\0"
+"quest\0"
+"cymru.museum\0"
+"trentin-s\xc3\xbc""d-tirol.it\0"
+"muenchen.museum\0"
+"net.et\0"
+"h\xc3\xa1""bmer.no\0"
+"yonabaru.okinawa.jp\0"
+"loyalist.museum\0"
+"galsa.no\0s3-website-sa-east-1.amazonaws.com\0"
+"from-nv.com\0"
+"trentino-s\xc3\xbc""dtirol.it\0"
+"nl.eu.org\0"
+"england.museum\0"
+"afl\0"
+"comunica\xc3\xa7\xc3\xb5""es.museum\0"
+"theater\0"
+"net.ge\0"
+"yamaga.kumamoto.jp\0"
+"urn.arpa\0net.gg\0"
+"bozen-suedtirol.it\0honjyo.akita.jp\0"
+"vik.no\0"
+"net.gl\0"
+"rindal.no\0glass\0"
+"net.gn\0"
+"tvedestrand.no\0internet-dns.de\0"
+"net.gp\0kozaki.chiba.jp\0rzgw.gov.pl\0ravendb.run\0"
+"dontexist.org\0"
+"net.gr\0nishimera.miyazaki.jp\0"
+"net.gt\0"
+"net.gu\0"
+"alabama.museum\0"
+"net.gy\0asso.eu.org\0freeddns.us\0"
+"net.hk\0gs.st.no\0fairwinds\0africa.com\0"
+"morena.br\0"
+"net.hn\0minamimaki.nagano.jp\0"
+"tagami.niigata.jp\0nakagawa.tokushima.jp\0"
+"name\0my-router.de\0"
+"net.ht\0net.id\0"
+"m.bg\0"
+"eu-west-1.elasticbeanstalk.com\0"
+"net.il\0"
+"net.im\0stathelle.no\0aig\0"
+"net.in\0modena.it\0"
+"from-wv.com\0"
+"net.iq\0\xc3\xa5lg\xc3\xa5rd.no\0hoteles\0"
+"net.ir\0williamhill\0"
+"net.is\0newspaper.museum\0"
+"niteroi.br\0"
+"net.je\0jewelry\0"
+"chuo.osaka.jp\0"
+"ap-southeast-1.elasticbeanstalk.com\0us-west-1.elasticbeanstalk.com\0"
+"hirono.fukushima.jp\0"
+"uri.arpa\0guernsey.museum\0lancashire.museum\0sn\xc3\xa5""ase.no\0"
+"soma.fukushima.jp\0onomichi.hiroshima.jp\0urausu.hokkaido.jp\0"
+"barreau.bj\0"
+"fujioka.gunma.jp\0komatsushima.tokushima.jp\0reit\0"
+"net.jo\0police.uk\0"
+"niiza.saitama.jp\0"
+"isa-geek.org\0"
+"la-spezia.it\0"
+"sm\xc3\xb8la.no\0barsy.info\0"
+"travelers\0"
+"ct.it\0kitagata.gifu.jp\0crown\0"
+"net.kg\0valle.no\0"
+"samegawa.fukushima.jp\0"
+"net.ki\0is-an-accountant.com\0"
+"nowtv\0"
+"in-addr.arpa\0"
+"6.bg\0"
+"oamishirasato.chiba.jp\0tarama.okinawa.jp\0net.kn\0"
+"net.la\0"
+"lucca.it\0net.lb\0"
+"net.lc\0"
+"net.kw\0"
+"midori.gunma.jp\0sayama.saitama.jp\0mincom.tn\0"
+"net.ky\0encyclopedic.museum\0*.0emm.com\0"
+"net.kz\0"
+"net.lk\0"
+"dgca.aero\0"
+"shirataka.yamagata.jp\0kinder\0"
+"ng.eu.org\0"
+"net.ma\0air.museum\0"
+"ogawa.nagano.jp\0net.lr\0"
+"net.ls\0is-a-socialist.com\0co.network\0"
+"net.me\0courses\0"
+"ichinomiya.chiba.jp\0kishiwada.osaka.jp\0net.lv\0"
+"sa.au\0fortmissoula.museum\0"
+"emb.kw\0net.ly\0"
+"net.mk\0lib.as.us\0luxury\0"
+"osaki.miyagi.jp\0net.ml\0"
+"hamura.tokyo.jp\0capital\0"
+"net.mo\0"
+"info\0"
+"oishida.yamagata.jp\0"
+"net.ms\0eigersund.no\0"
+"biella.it\0net.mt\0"
+"net.mu\0"
+"net.mv\0net.nf\0"
+"virtual.museum\0net.mw\0net.ng\0"
+"net.mx\0"
+"net.my\0net.ni\0cc.ct.us\0"
+"net.mz\0"
+"torino.museum\0"
+"uruma.okinawa.jp\0stalowa-wola.pl\0azure-mobile.net\0"
+"aarborte.no\0dnsfor.me\0"
+"odesa.ua\0"
+"nanbu.yamanashi.jp\0net.nr\0"
+"sa.cr\0"
+"lib.oh.us\0"
+"st.no\0"
+"taiji.wakayama.jp\0"
+"net.nz\0"
+"couchpotatofries.org\0"
+"search\0"
+"net.om\0"
+"pinb.gov.pl\0rent\0"
+"game-server.cc\0"
+"anz\0"
+"net.pa\0"
+"aol\0"
+"friuli-veneziagiulia.it\0oiso.kanagawa.jp\0muika.niigata.jp\0"
+"artgallery.museum\0handson.museum\0net.pe\0on-aptible.com\0"
+"enna.it\0"
+"honefoss.no\0press\0"
+"net.ph\0etisalat\0"
+"s\xc3\xb8rum.no\0net.pk\0"
+"net.pl\0"
+"wios.gov.pl\0net.pn\0"
+"servepics.com\0"
+"marugame.kagawa.jp\0"
+"net.qa\0"
+"joso.ibaraki.jp\0tsubame.niigata.jp\0net.pr\0"
+"net.ps\0myfirewall.org\0"
+"bergamo.it\0rishirifuji.hokkaido.jp\0ina.nagano.jp\0kokubunji.tokyo.jp\0net.pt\0"
+"sweetpepper.org\0"
+"app\0"
+"benevento.it\0"
+"net.py\0"
+"akita.akita.jp\0"
+"s3-website-ap-northeast-1.amazonaws.com\0"
+"forgot.her.name\0"
"shinshiro.aichi.jp\0"
-"tm.km\0"
-"vistaprint\0"
+"scotland.museum\0"
+"\xe5\x85\xb5\xe5\xba\xab.jp\0"
+"sassari.it\0okuma.fukushima.jp\0"
+"mypi.co\0"
+"numazu.shizuoka.jp\0\xe7\xbb\x84\xe7\xbb\x87\xe6\x9c\xba\xe6\x9e\x84\0"
+"ris\xc3\xb8r.no\0"
+"fuefuki.yamanashi.jp\0bar\0"
+"bbc\0"
+"toscana.it\0atsugi.kanagawa.jp\0settsu.osaka.jp\0kusatsu.shiga.jp\0yamada.toyama.jp\0"
+"\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x90\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\xa5.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0"
+"omitama.ibaraki.jp\0"
+"net.sa\0kindle\0"
+"net.sb\0"
+"net.sc\0"
+"net.sd\0dunlop\0"
+"net.ru\0myftp.org\0"
+"sekikawa.niigata.jp\0"
+"hemsedal.no\0net.rw\0net.sg\0navy\0"
+"niimi.okayama.jp\0net.sh\0"
+"kamifurano.hokkaido.jp\0art\0bbt\0"
+"kumejima.okinawa.jp\0net.sl\0"
+"broker.aero\0bcg\0"
+"fet.no\0net.so\0nsupdate.info\0"
+"dagestan.ru\0"
+"property\0"
+"iki.nagasaki.jp\0net.st\0bcn\0"
+"prof.pr\0net.th\0walter\0"
+"net.sy\0"
+"net.tj\0"
+"sor-varanger.no\0net.tm\0"
+"net.tn\0rest\0"
+"net.to\0"
+"unjarga.no\0net.ua\0dagestan.su\0"
+"net.tr\0"
+"cargo.aero\0"
+"aizubange.fukushima.jp\0kamo.niigata.jp\0net.tt\0"
+"society.museum\0ebiz.tw\0"
+"sa.it\0"
+"net.tw\0localhost.daplie.me\0"
+"net.uk\0cards\0organic\0"
+"hl.cn\0\xd0\xba\xd0\xbe\xd0\xbc\0""32-b.it\0"
+"diamonds\0"
+"naganohara.gunma.jp\0"
+"vennesla.no\0blogdns.org\0"
+"ca.it\0"
+"lib.co.us\0"
+"kyotango.kyoto.jp\0"
+"safety.aero\0net.vc\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa4\xae\xe0\xa5\x8d\0cyon.link\0"
+"sandvikcoromant\0"
+"net.ve\0"
+"koge.tottori.jp\0guardian\0"
+"hof.no\0net.uy\0net.vi\0"
+"net.uz\0bet\0"
+"sakae.chiba.jp\0"
+"net.vn\0"
+"ekloges.cy\0bryne.no\0kpmg\0"
+"dyndns-home.com\0"
+"\xe5\xa4\xa7\xe5\x88\x86.jp\0higashimatsushima.miyagi.jp\0"
+"gmbh\0\xe7\xa7\xbb\xe5\x8a\xa8\0"
+"ct.us\0net.vu\0"
+"wsa.gov.pl\0"
+"gemological.museum\0"
+"pistoia.it\0travel.pl\0"
+"realtor\0"
+"vindafjord.no\0k12.mn.us\0viajes\0"
"tysnes.no\0"
-"pp.az\0pors\xc3\xa1\xc5\x8bgu.no\0"
-"even\xc3\xa1\xc5\xa1\xc5\xa1i.no\0dnp\0tickets\0"
-"datsun\0home-webserver.de\0"
-"valer.ostfold.no\0blogsite.xyz\0"
-"murmansk.su\0brasilia.me\0"
-"dog\0schule\0"
-"vic.au\0"
-"space.museum\0"
-"takata.fukuoka.jp\0zero\0"
-"sel.no\0"
-"shimokitayama.nara.jp\0tm.mc\0brandywinevalley.museum\0"
-"nuremberg.museum\0homegoods\0kiwi\0ap-northeast-2.elasticbeanstalk.com\0"
-"tm.mg\0"
-"bergamo.it\0dot\0"
-"from-tn.com\0"
-"yatomi.aichi.jp\0narita.chiba.jp\0drobak.no\0"
-"transport.museum\0"
-"carrara-massa.it\0"
-"me.tz\0wanggou\0"
-"me.uk\0"
-"gs.jan-mayen.no\0"
-"ichinomiya.chiba.jp\0"
-"uenohara.yamanashi.jp\0"
-"me.us\0"
-"ushuaia.museum\0"
-"bizen.okayama.jp\0"
-"koori.fukushima.jp\0"
-"ac\0aarp\0"
-"ad\0tm.no\0"
-"ae\0orskog.no\0"
+"net.ws\0"
+"axa\0place\0visa\0isa-geek.com\0"
+"civilisation.museum\0aws\0u2-local.xnbay.com\0"
+"ppg.br\0"
+"\xe5\x95\x86\xe5\xba\x97\0"
+"kami.kochi.jp\0sado.niigata.jp\0"
+"cc.ca.us\0kerrylogistics\0"
+"puglia.it\0"
+"siljan.no\0"
+"toyohashi.aichi.jp\0"
+"xfinity\0"
+"lomza.pl\0bid\0"
+"evenes.no\0"
+"monmouth.museum\0ca.na\0"
+"lc.it\0"
+"lib.nm.us\0"
+"cloudaccess.net\0"
+"gs.hl.no\0lv.ua\0net.za\0""1337.pictures\0"
+"iwafune.tochigi.jp\0tokushima.tokushima.jp\0"
+"bio\0inc.hk\0"
+"m.se\0online\0"
+"seven\0"
+"sukumo.kochi.jp\0"
+"net.zm\0"
+"rochester.museum\0dynserv.org\0"
+"biz\0watari.miyagi.jp\0"
+"tokyo\0"
+"yasuoka.nagano.jp\0"
+"koshigaya.saitama.jp\0tjmaxx\0"
+"democracia.bo\0"
+"tur.ar\0"
+"stavanger.no\0theatre\0viva\0myds.me\0"
+"bilbao.museum\0webcam\0"
+"tienda\0"
+"hashimoto.wakayama.jp\0"
+"cosenza.it\0"
+"louvre.museum\0askoy.no\0boxfuse.io\0"
+"travel.tt\0"
+"\xd0\xb1\xd0\xb3\0is-a-celticsfan.org\0"
+"vivo\0cleverapps.io\0"
+"riopreto.br\0tur.br\0"
+"walmart\0"
+"manchester.museum\0"
+"asahi.nagano.jp\0"
+"valer.hedmark.no\0fh.se\0"
+"wiki.bo\0cc.ks.us\0\xe8\xb4\xad\xe7\x89\xa9\0"
+"homeip.net\0"
+"wiki.br\0imakane.hokkaido.jp\0"
+"snoasa.no\0"
+"kumagaya.saitama.jp\0"
+"tromsa.no\0"
+"hob\xc3\xb8l.no\0"
+"ecn.br\0koza.wakayama.jp\0"
+"krym.ua\0"
+"filegear-de.me\0"
+"toyama.toyama.jp\0"
+"rygge.no\0istmein.de\0"
+"jewish.museum\0usgarden.museum\0raisa.no\0endofinternet.org\0"
+"bms\0"
+"ryokami.saitama.jp\0"
+"\xe0\xb8\x84\xe0\xb8\xad\xe0\xb8\xa1\0"
+"haugesund.no\0bmw\0"
+"homeunix.net\0"
+"asn.au\0"
+"messina.it\0bnl\0"
+"lazio.it\0"
+"*.in.futurecms.at\0"
+"val-d-aosta.it\0pa.leg.br\0"
+"\xe9\xa3\x9e\xe5\x88\xa9\xe6\xb5\xa6\0"
+"gorlice.pl\0"
+"assn.lk\0bom\0"
+"kanna.gunma.jp\0"
+"timekeeping.museum\0boo\0"
+"ardal.no\0"
+"monza.it\0fukuoka.jp\0"
+"tksat.bo\0"
+"an.it\0bot\0"
+"sandnessjoen.no\0"
+"calvinklein\0report\0"
+"hl.no\0\xe9\x9b\xbb\xe8\xa8\x8a\xe7\x9b\x88\xe7\xa7\x91\0"
+"genova.it\0box\0"
+"epilepsy.museum\0geology.museum\0casino\0"
+"pordenone.it\0"
+"ostroda.pl\0"
+"tana.no\0"
+"tochigi.tochigi.jp\0"
+"opole.pl\0"
+"sucks\0"
+"cab\0"
+"artanddesign.museum\0"
+"webredirect.org\0"
+"kashiwa.chiba.jp\0pb.leg.br\0"
+"tele.amune.org\0dnsalias.com\0"
+"kiwi.nz\0\xd0\xb5\xd1\x8e\0honeywell\0"
+"ca.us\0"
+"cal\0"
+"space.museum\0cam\0"
+"rankoshi.hokkaido.jp\0rawa-maz.pl\0"
+"zama.kanagawa.jp\0"
+"k12.mi.us\0cba\0"
+"car\0"
+"journalist.aero\0synology-ds.de\0"
+"cat\0"
+"rehab\0"
+"r\xc3\xb8mskog.no\0"
+"dynv6.net\0"
+"tychy.pl\0"
+"cbn\0"
+"\xe3\x82\xbb\xe3\x83\xbc\xe3\x83\xab\0"
+"cbs\0stuff-4-sale.org\0"
+"shell.museum\0cloud.fedoraproject.org\0"
+"sport\0"
+"rsc.cdn77.org\0"
+"omachi.nagano.jp\0"
+"biev\xc3\xa1t.no\0tennis\0tiaa\0"
+"ichinoseki.iwate.jp\0"
+"time.museum\0"
+"trading.aero\0"
+"citi\0from-ma.com\0"
+"ks.ua\0twmail.org\0synology-diskstation.de\0"
+"anani.br\0dupont\0"
+"\xd0\xb8\xd0\xba\xd0\xbe\xd0\xbc.museum\0"
+"jpmorgan\0router.management\0"
+"lincoln\0lixil\0"
+"valle-aosta.it\0ceb\0"
+"city\0"
+"nuoro.it\0iheya.okinawa.jp\0"
+"saitama.jp\0kamimine.saga.jp\0"
+"ks.us\0"
+"nakano.nagano.jp\0"
+"patria.bo\0md.ci\0"
+"ceo\0"
+"cfa\0from-pa.com\0"
+"tono.iwate.jp\0r.cdn77.net\0"
+"artdeco.museum\0civilization.museum\0bodo.no\0kiev.ua\0"
+"fujisato.akita.jp\0obama.nagasaki.jp\0cfd\0"
+"int.ar\0"
+"klabu.no\0radio\0"
+"buy\0"
+"ddnsgeek.com\0servesarcasm.com\0"
+"olbia-tempio.it\0"
+"k.bg\0\xc3\xb8rsta.no\0skodje.no\0"
+"int.az\0otsuki.kochi.jp\0""16-b.it\0"
+"mine.nu\0"
+"naie.hokkaido.jp\0"
+"int.bo\0algard.no\0"
+"trentino-s\xc3\xbc""d-tirol.it\0"
+"khakassia.su\0"
+"kure.hiroshima.jp\0land\0"
+"s\xc3\xb8rfold.no\0"
+"kaisei.kanagawa.jp\0ohira.tochigi.jp\0"
+"grane.no\0codespot.com\0"
+"shikabe.hokkaido.jp\0targi.pl\0"
+"takayama.nagano.jp\0itoigawa.niigata.jp\0zachpomor.pl\0"
+"empresa.bo\0int.ci\0"
+"mochizuki.nagano.jp\0"
+"is-very-good.org\0webhop.org\0"
+"fortal.br\0sr.it\0\xda\x80\xd8\xa7\xd8\xb1\xd8\xaa\0"
+"per.la\0"
+"int.co\0gjerdrum.no\0"
+"vanguard\0"
+"saltdal.no\0"
+"magazine.aero\0"
+"sciencesnaturelles.museum\0\xc3\xa5snes.no\0"
+"cr.it\0"
+"bievat.no\0lib.fl.us\0"
+"obihiro.hokkaido.jp\0"
+"ringebu.no\0cc.wi.us\0"
+"4.bg\0"
+"higashi.fukuoka.jp\0"
+"l\xc3\xb8""dingen.no\0est-le-patron.com\0"
+"mod.gi\0naturalhistorymuseum.museum\0hemnes.no\0"
+"tadotsu.kagawa.jp\0"
+"missoula.museum\0supply\0cable-modem.org\0"
+"schmidt\0dynu.net\0nerdpol.ovh\0"
+"getmyip.com\0"
+"asn.lv\0"
+"zapto.org\0"
+"kyowa.akita.jp\0now.sh\0"
+"lancome\0"
+"odo.br\0shunan.yamaguchi.jp\0per.nf\0"
+"nsn.us\0"
+"salvador.br\0omaezaki.shizuoka.jp\0bzh\0"
+"circus.museum\0"
+"unnan.shimane.jp\0"
+"gripe\0"
+"shriram\0"
+"cnt.br\0nikaho.akita.jp\0meiwa.gunma.jp\0"
+"omega\0otsuka\0"
+"toyoake.aichi.jp\0omura.nagasaki.jp\0"
+"extraspace\0"
+"game-host.org\0"
+"udine.it\0\xd1\x80\xd1\x84\0"
+"bulsan-suedtirol.it\0iglesiascarbonia.it\0"
+"niki.hokkaido.jp\0"
+"from-va.com\0"
+"noshiro.akita.jp\0agano.niigata.jp\0"
+"vega.no\0"
+"lt.it\0suwalki.pl\0"
+"yahiko.niigata.jp\0"
+"usarts.museum\0hoyanger.no\0from-wa.com\0"
+"oita.oita.jp\0"
+"\xe3\x81\xbf\xe3\x82\x93\xe3\x81\xaa\0"
+"childrensgarden.museum\0"
+"tarnobrzeg.pl\0\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0"
+"tajiri.osaka.jp\0toyono.osaka.jp\0"
+"auto.pl\0cloudycluster.net\0"
+"compare\0"
+"barsy.club\0"
+"r\xc3\xb8yrvik.no\0kids.us\0"
+"trentinoaadige.it\0"
+"saga.saga.jp\0"
+"gs.vf.no\0zp.ua\0"
+"tokyo.jp\0stargard.pl\0kred\0"
+"int.is\0"
+"nx.cn\0molise.it\0isa-geek.net\0"
+"im.it\0"
+"hyogo.jp\0toei.aichi.jp\0"
+"vaga.no\0"
+"jelenia-gora.pl\0"
+"kvalsund.no\0"
+"pi.leg.br\0"
+"pilot.aero\0per.sg\0"
+"trieste.it\0shimizu.hokkaido.jp\0seika.kyoto.jp\0"
+"television.museum\0"
+"coupon\0"
+"bykle.no\0cc.md.us\0"
+"com\0dscloud.mobi\0"
+"dattoweb.com\0"
+"tr.eu.org\0"
+"tamba.hyogo.jp\0dynalias.net\0"
+"int.la\0"
+"teramo.it\0"
+"lyngen.no\0"
+"shimotsuke.tochigi.jp\0"
+"secure\0"
+"americanantiques.museum\0"
+"cooking\0"
+"\xd0\xbc\xd0\xba\xd0\xb4\0"
+"int.lk\0ambulance.museum\0"
+"takashima.shiga.jp\0"
+"unusualperson.com\0"
+"tushu\0"
+"dad\0"
+"2000.hu\0luroy.no\0"
+"iamallama.com\0"
+"radio.br\0"
+"romsa.no\0"
+"wi.us\0"
+"noheji.aomori.jp\0nowruz\0"
+"ozu.ehime.jp\0"
+"arna.no\0ro.im\0"
+"xj.cn\0"
+"ato.br\0"
+"vagan.no\0day\0"
+"ro.it\0int.mv\0construction\0freebox-os.fr\0"
+"int.mw\0"
+"int.ni\0"
+"gz.cn\0capetown\0"
+"company\0"
+"qsl.br\0"
+"alfaromeo\0crs\0csc\0video\0"
+"sp.gov.br\0bo.it\0"
+"anamizu.ishikawa.jp\0sakae.nagano.jp\0"
+"cr.ua\0"
+"cloudfunctions.net\0"
+"siena.it\0"
+"tips\0"
+"ashiya.hyogo.jp\0"
+"myactivedirectory.com\0"
+"kaminoyama.yamagata.jp\0"
+"from-ca.com\0"
+"tobe.ehime.jp\0nikko.tochigi.jp\0sko.gov.pl\0"
+"otago.museum\0washingtondc.museum\0"
+"shiranuka.hokkaido.jp\0"
+"oceanographic.museum\0rana.no\0"
+"divtasvuodna.no\0"
+"vf.no\0meloy.no\0k12.mt.us\0insurance\0"
+"koebenhavn.museum\0aigo\0dds\0"
+"oyer.no\0netlify.com\0"
+"shakotan.hokkaido.jp\0"
+"\xd0\xbc\xd0\xbe\xd0\xbd\0"
+"int.pt\0"
+"\xe6\x95\x99\xe8\x82\xb2.\xe9\xa6\x99\xe6\xb8\xaf\0"
+"from-ia.com\0"
+"hita.oita.jp\0"
+"\xd0\xbe\xd0\xb1\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0"
+"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0"
+"seihi.nagasaki.jp\0"
+"geekgalaxy.com\0"
+"taketa.oita.jp\0mutual\0"
+"dev\0"
+"research.aero\0mytis.ru\0"
+"gratangen.no\0"
+"mihara.kochi.jp\0gyokuto.kumamoto.jp\0"
+"takaishi.osaka.jp\0so.gov.pl\0"
+"from-ga.com\0"
+"furubira.hokkaido.jp\0ayabe.kyoto.jp\0"
+"lt.ua\0s3-website.eu-west-3.amazonaws.com\0"
+"tateyama.chiba.jp\0ohira.miyagi.jp\0pe.leg.br\0"
+"larvik.no\0verdal.no\0"
+"geometre-expert.fr\0"
+"int.ru\0"
+"biz.bb\0"
+"int.rw\0k.se\0"
+"hakata.fukuoka.jp\0czest.pl\0biz.at\0"
+"wildlife.museum\0spreadbetting\0"
+"otaki.chiba.jp\0suzu.ishikawa.jp\0"
+"mydobiss.com\0"
+"stpetersburg.museum\0cc.oh.us\0zone\0diskstation.me\0"
+"biz.az\0miasta.pl\0"
+"ask\xc3\xb8y.no\0"
+"yoshimi.saitama.jp\0"
+"md.us\0physio\0"
+"maebashi.gunma.jp\0"
+"ferrara.it\0"
+"dhl\0scrapper-site.net\0"
+"ann-arbor.mi.us\0"
+"int.tj\0"
+"lifestyle\0"
+"ishikawa.fukushima.jp\0"
+"diskstation.eu\0"
+"toyooka.hyogo.jp\0oi.kanagawa.jp\0"
+"maringa.br\0\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86.ir\0"
+"kragero.no\0vinnica.ua\0co.place\0"
+"blogdns.net\0"
+"int.tt\0"
+"baidar.no\0\xd0\xbe\xd0\xb4.\xd1\x81\xd1\x80\xd0\xb1\0"
+"biz.cy\0law.pro\0"
+"biz.dk\0"
+"fuchu.tokyo.jp\0for-some.biz\0"
+"*.sch.uk\0cc.la.us\0"
+"shintoku.hokkaido.jp\0"
+"airport.aero\0study\0"
+"int.ve\0diy\0grocery\0certmgr.org\0"
+"hiphop\0"
+"booking\0homeunix.org\0"
+"matsushige.tokushima.jp\0"
+"ts.it\0"
+"wajiki.tokushima.jp\0int.vn\0"
+"ltd.co.im\0"
+"hawaii.museum\0"
+"chikuzen.fukuoka.jp\0"
+"est-a-la-masion.com\0"
+"biz.et\0"
+"marriott\0"
+"apigee.io\0"
+"yuu.yamaguchi.jp\0"
+"natal.br\0hachinohe.aomori.jp\0"
+"sayama.osaka.jp\0"
+"9guacu.br\0budapest\0"
+"camera\0"
+"showa.gunma.jp\0"
+"eating-organic.net\0"
+"hirata.fukushima.jp\0"
+"wales\0dnsdojo.org\0"
+"snasa.no\0stream\0dontexist.com\0"
+"kuokgroup\0\xd8\xb9\xd8\xb1\xd8\xa8\0"
+"m\xc3\xa5s\xc3\xb8y.no\0"
+"nishi.fukuoka.jp\0"
+"ddnss.org\0"
+"ritto.shiga.jp\0"
+"n\xc3\xa6r\xc3\xb8y.no\0"
+"al.it\0"
+"isla.pr\0"
+"ide.kyoto.jp\0"
+"tecnologia.bo\0"
+"biz.id\0"
+"zaporizhzhia.ua\0"
+"kppsp.gov.pl\0dnp\0"
+"birkenes.no\0"
+"omuta.fukuoka.jp\0"
+"\xe6\x94\xbf\xe5\xba\x9c.\xe9\xa6\x99\xe6\xb8\xaf\0"
+"carbonia-iglesias.it\0"
+"arai.shizuoka.jp\0hokuto.yamanashi.jp\0"
+"dog\0"
+"nara.nara.jp\0"
+"swidnica.pl\0"
+"storage\0"
+"from-ny.net\0"
+"brussel.museum\0stordal.no\0"
+"mitane.akita.jp\0"
+"botanicgarden.museum\0asker.no\0"
+"judygarland.museum\0"
+"ne.jp\0yono.saitama.jp\0dot\0"
+"hiji.oita.jp\0oshima.tokyo.jp\0futurehosting.at\0"
+"pri.ee\0ne.ke\0atlanta.museum\0"
+"gold\0"
+"golf\0"
+"oh.us\0"
+"sr.gov.pl\0"
+"como.it\0"
+"biz.ki\0cc.al.us\0"
+"sarufutsu.hokkaido.jp\0arida.wakayama.jp\0"
+"mashiko.tochigi.jp\0chizu.tottori.jp\0bosch\0global\0beep.pl\0"
+"izumizaki.fukushima.jp\0ne.kr\0pr.leg.br\0"
+"samsung\0"
+"realestate.pl\0"
+"daito.osaka.jp\0asaka.saitama.jp\0"
+"kiho.mie.jp\0"
+"gloppen.no\0porsangu.no\0"
+"snaase.no\0uk.eu.org\0"
+"bologna.it\0eat\0"
+"yaita.tochigi.jp\0"
+"kawagoe.mie.jp\0kalisz.pl\0tourism.tn\0"
+"al.no\0"
+"biz.ls\0cc.ne.us\0is-a-liberal.com\0"
+"mb.ca\0"
+"higashikurume.tokyo.jp\0"
+"kv\xc3\xa6nangen.no\0la.us\0"
+"ginan.gifu.jp\0"
+"*.hosting.myjino.ru\0lima-city.rocks\0"
+"!city.nagoya.jp\0"
+"k12.vi.us\0ap-northeast-2.elasticbeanstalk.com\0"
+"legnica.pl\0"
+"rich\0"
+"goog\0*.transurl.be\0"
+"oketo.hokkaido.jp\0biz.mv\0starostwo.gov.pl\0"
+"biz.mw\0vegarshei.no\0eco\0is-very-sweet.org\0blogsyte.com\0"
+"fujikawa.yamanashi.jp\0"
+"biz.ni\0"
+"lig.it\0napoli.it\0aioi.hyogo.jp\0okuizumo.shimane.jp\0"
+"gallo\0"
+"tohma.hokkaido.jp\0rep.kp\0"
+"i.bg\0"
+"taishin.fukushima.jp\0sumita.iwate.jp\0hamatama.saga.jp\0"
+"yk.ca\0reise\0"
+"iwaki.fukushima.jp\0biz.nr\0"
+"andebu.no\0karaganda.su\0"
+"hamada.shimane.jp\0"
+"finland.museum\0helsinki.museum\0"
+"onagawa.miyagi.jp\0"
+"zone.id\0"
+"gob.ar\0"
+"edu\0"
+"dtv\0"
+"sp.it\0"
+"lib.tn.us\0s3-eu-west-3.amazonaws.com\0""001www.com\0"
+"immobilien\0"
+"gwiddle.co.uk\0"
+"parachuting.aero\0"
+"ip6.arpa\0gob.bo\0"
+"chita.aichi.jp\0"
+"biz.pk\0"
+"biz.pl\0"
+"lindas.no\0avianca\0"
+"cri.br\0"
+"biz.pr\0"
+"2.bg\0ne.pw\0"
+"musashimurayama.tokyo.jp\0"
+"is-a-doctor.com\0"
+"gob.cl\0bari.it\0tsuwano.shimane.jp\0ug.gov.pl\0"
+"annaka.gunma.jp\0in-the-band.net\0"
+"ski.museum\0"
+"joyo.kyoto.jp\0dvr\0"
+"indian.museum\0"
+"servecounterstrike.com\0"
+"date.hokkaido.jp\0zao.miyagi.jp\0"
+"trade\0"
+"bozen-s\xc3\xbc""dtirol.it\0warabi.saitama.jp\0"
+"\xe4\xbd\x90\xe8\xb3\x80.jp\0"
+"nesset.no\0*.transurl.eu\0"
+"pi.it\0"
+"no.com\0"
+"yusuhara.kochi.jp\0"
+"gob.do\0"
+"yoshinogari.saga.jp\0johana.toyama.jp\0"
+"gob.ec\0grozny.su\0"
+"mad.museum\0"
+"online.th\0a.run.app\0"
+"nanto.toyama.jp\0"
+"d\xc3\xb8nna.no\0"
+"nhlfan.net\0myftp.biz\0"
+"aguni.okinawa.jp\0"
+"bergbau.museum\0rogers\0"
+"oyabe.toyama.jp\0"
+"univ.sn\0"
+"prime\0"
+"gob.es\0"
+"gamvik.no\0"
+"\xe7\xa6\x8f\xe4\xba\x95.jp\0memset.net\0"
+"indigena.bo\0"
+"okegawa.saitama.jp\0shimizu.shizuoka.jp\0"
+"vix.br\0kyowa.hokkaido.jp\0nagaokakyo.kyoto.jp\0"
+"al.us\0no-ip.org\0oy.lc\0"
+"kunitomi.miyazaki.jp\0"
+"balsan-suedtirol.it\0wakuya.miyagi.jp\0gb.net\0"
+"ac\0"
+"ad\0mb.it\0biz.tj\0"
+"ae\0"
"af\0"
-"ag\0"
-"perugia.it\0"
-"ai\0lewismiller.museum\0monster\0"
-"izumizaki.fukushima.jp\0"
-"al\0"
-"am\0karasjok.no\0eat\0"
-"tas.edu.au\0ferrero\0dyn-o-saur.com\0"
-"ao\0kiyokawa.kanagawa.jp\0cheap\0"
-"aq\0ba\0"
-"ar\0bb\0"
-"as\0dupont\0from-wi.com\0"
-"at\0leirfjord.no\0"
-"au\0be\0sh.cn\0kunst.museum\0"
-"bf\0shiojiri.nagano.jp\0mobi.ke\0"
-"asn.au\0aw\0bg\0wakkanai.hokkaido.jp\0"
-"ax\0bh\0"
-"bi\0"
+"ag\0yahoo\0dnsupdater.de\0"
+"ai\0"
+"tonami.toyama.jp\0"
+"biz.ua\0"
+"al\0kanuma.tochigi.jp\0biz.tr\0"
+"am\0seljord.no\0ne.ug\0"
+"biz.tt\0"
+"ao\0creation.museum\0"
+"otaru.hokkaido.jp\0ne.tz\0"
+"aq\0ba\0stj\xc3\xb8rdalshalsen.no\0"
+"ar\0bb\0schaeffler\0"
+"as\0"
+"at\0"
+"au\0be\0jewelry.museum\0"
+"bf\0"
+"aw\0bg\0grozny.ru\0"
+"ax\0bh\0gob.gt\0"
+"bi\0ne.us\0"
"az\0bj\0"
-"forli-cesena.it\0"
-"air.museum\0"
-"bm\0jewelry\0"
-"bn\0"
-"bo\0lorenskog.no\0"
-"ca\0kuroishi.aomori.jp\0hirono.fukushima.jp\0tm.pl\0credit\0ggee\0"
-"br\0yawara.ibaraki.jp\0"
+"*.yokohama.jp\0matsumae.hokkaido.jp\0"
+"bm\0"
+"bn\0webhop.net\0"
+"bo\0of.by\0"
+"ca\0"
+"br\0gob.hn\0"
"bs\0cc\0"
-"bt\0cd\0"
-"bv\0cf\0artsandcrafts.museum\0kosher\0neustar\0"
+"bt\0cd\0szczytno.pl\0"
+"bv\0cf\0"
"bw\0cg\0"
-"ch\0eco\0"
+"ch\0vall\xc3\xa9""e-aoste.it\0biz.vn\0"
"by\0ci\0"
-"bz\0total\0"
+"bz\0"
+"k12.gu.us\0"
"cl\0"
-"media.aero\0cm\0cc.ms.us\0cc.nc.us\0hyatt\0"
-"trading.aero\0cn\0isen.kagoshima.jp\0wegrow.pl\0northwesternmutual\0"
-"co\0"
-"mino.gifu.jp\0nflfan.org\0"
-"cr\0assabu.hokkaido.jp\0"
-"gs.cn\0"
-"cu\0de\0"
-"cv\0"
-"cw\0s3-website-us-west-1.amazonaws.com\0"
-"cx\0servebbs.net\0"
-"cy\0"
+"cm\0c.cdn77.org\0"
+"cn\0"
+"co\0java\0"
+"tempioolbia.it\0"
+"alesund.no\0"
+"cr\0fukuyama.hiroshima.jp\0"
+"cu\0de\0farmequipment.museum\0"
+"cv\0iruma.saitama.jp\0"
+"cw\0"
+"cx\0seto.aichi.jp\0"
+"cy\0ushuaia.museum\0"
"cz\0dj\0"
-"dk\0portland.museum\0"
-"fst.br\0dm\0"
-"edu\0"
-"s.bg\0do\0dtv\0"
-"hurum.no\0paroch.k12.ma.us\0"
-"casacam.net\0"
-"chihayaakasaka.osaka.jp\0cechire.com\0"
+"dk\0games\0"
+"mobara.chiba.jp\0"
+"dm\0gjerstad.no\0naamesjevuemie.no\0"
+"do\0lur\xc3\xb8y.no\0is-a-green.com\0"
+"tools\0"
"ec\0"
-"cargo.aero\0tm.ro\0mypsx.net\0"
-"ee\0historical.museum\0"
-"uonuma.niigata.jp\0"
-"eg\0bs.it\0"
-"misawa.aomori.jp\0"
-"\xe6\x95\x8e\xe8\x82\xb2.hk\0gs.oslo.no\0"
-"dz\0nagano.jp\0tm.se\0"
-"scrapping.cc\0"
-"nankoku.kochi.jp\0"
-"higashiyoshino.nara.jp\0"
-"kiev.ua\0"
-"miyazaki.jp\0kushiro.hokkaido.jp\0"
+"okinawa.jp\0"
+"ee\0vefsn.no\0k12.tx.us\0"
+"eg\0"
+"tourism.pl\0"
+"dz\0kin.okinawa.jp\0"
+"museumcenter.museum\0valley.museum\0bingo\0"
+"baseball\0"
+"noticias.bo\0"
+"inagawa.hyogo.jp\0abu.yamaguchi.jp\0global.ssl.fastly.net\0"
+"co.com\0"
+"takahama.aichi.jp\0"
+"kayabe.hokkaido.jp\0"
"es\0"
-"et\0"
+"et\0school\0"
"eu\0"
-"higashiizumo.shimane.jp\0lib.az.us\0"
-"fi\0is-uberleet.com\0"
-"intuit\0volvo\0"
-"dvr\0*.advisor.ws\0"
-"nagoya\0"
-"fm\0\xc3\xa5snes.no\0"
-"andriatranibarletta.it\0nes.akershus.no\0"
-"fo\0botany.museum\0alesund.no\0grane.no\0"
+"fi\0"
+"aikawa.kanagawa.jp\0"
+"fm\0"
+"fo\0"
"ga\0"
-"fr\0gb\0california.museum\0"
+"fr\0gb\0"
+"dep.no\0media\0"
"gd\0"
"ge\0"
-"gf\0mx.na\0\xe9\xa4\x90\xe5\x8e\x85\0"
-"gg\0"
-"gh\0sanagochi.tokushima.jp\0active\0"
-"gi\0"
-"zama.kanagawa.jp\0"
-"gl\0namegawa.saitama.jp\0duns\0"
+"gf\0rm.it\0*.transurl.nl\0"
+"gg\0biz.zm\0"
+"gh\0"
+"gi\0i.ng\0gs.of.no\0"
+"gx.cn\0gl\0ouchi.saga.jp\0"
"gm\0"
-"gn\0florida.museum\0"
+"adm.br\0gn\0"
"gp\0"
-"gq\0pt.eu.org\0"
-"gr\0"
-"gs\0"
-"gt\0"
-"gu\0"
-"gw\0\xe4\xb8\xaa\xe4\xba\xba.hk\0winb.gov.pl\0"
-"fed.us\0"
-"gy\0iwama.ibaraki.jp\0"
-"tr\xc3\xb8gstad.no\0"
-"riopreto.br\0hk\0"
-"student.aero\0lancaster\0"
-"hm\0"
-"hn\0madrid\0"
-"cc.sc.us\0"
-"futtsu.chiba.jp\0"
-"sicily.it\0"
-"hr\0"
-"\xe5\x98\x89\xe9\x87\x8c\0"
-"ht\0id\0cc.na\0"
+"recreation.aero\0gq\0lib.dc.us\0fitness\0s3.dualstack.ap-northeast-1.amazonaws.com\0mypets.ws\0"
+"gr\0saga.jp\0matsubushi.saitama.jp\0"
+"gs\0\xe5\x80\x8b\xe4\xba\xba.\xe9\xa6\x99\xe6\xb8\xaf\0"
+"gt\0trentino-aadige.it\0lukow.pl\0"
+"gu\0cc.ut.us\0"
+"to.gov.br\0"
+"gw\0"
+"miyazu.kyoto.jp\0"
+"gy\0"
+"hk\0elvendrell.museum\0mel\xc3\xb8y.no\0"
+"gob.mx\0"
+"hm\0gob.ni\0hadsel.no\0"
+"hn\0aridagawa.wakayama.jp\0"
+"ubank\0s3.dualstack.eu-west-3.amazonaws.com\0"
+"kep.tr\0coach\0fan\0"
+"wpdevcloud.com\0cyon.site\0"
+"hr\0saarland\0dynathome.net\0"
+"andoy.no\0"
+"ht\0id\0akdn\0"
"hu\0ie\0"
-"talk\0"
-"economia.bo\0"
-"il\0"
+"oarai.ibaraki.jp\0futuremailing.at\0"
+"bnr.la\0"
+"higashi.okinawa.jp\0i.ph\0winb.gov.pl\0"
+"il\0for-more.biz\0"
"im\0"
-"in\0"
-"io\0togo.aichi.jp\0"
-"noda.chiba.jp\0augustow.pl\0dvag\0"
+"in\0matsumoto.kagoshima.jp\0"
+"io\0from-al.com\0"
+"naka.hiroshima.jp\0"
"iq\0"
-"ir\0cody.museum\0"
-"is\0flakstad.no\0"
-"it\0misato.shimane.jp\0"
-"je\0"
-"aver\xc3\xb8y.no\0prochowice.pl\0able\0"
-"lucania.it\0"
-"fortmissoula.museum\0gleeze.com\0"
-"khmelnytskyi.ua\0"
-"hichiso.gifu.jp\0"
-"jo\0glass.museum\0"
+"ir\0cri.nz\0"
+"is\0oldnavy\0"
+"it\0"
+"je\0gob.pa\0togliatti.su\0"
+"varoy.no\0is-a-bruinsfan.org\0"
+"watarai.mie.jp\0"
+"gob.pe\0"
+"news\0"
+"jo\0gob.pk\0"
"jp\0"
-"chino.nagano.jp\0"
-"internet-dns.de\0"
-"ke\0opoczno.pl\0"
-"griw.gov.pl\0"
-"kg\0k12.il.us\0"
-"rakkestad.no\0"
-"ki\0"
-"kikugawa.shizuoka.jp\0nasushiobara.tochigi.jp\0"
-"km\0misconfused.org\0"
-"kn\0"
+"floro.no\0"
+"radoy.no\0esq\0"
+"treviso.it\0katori.chiba.jp\0toga.toyama.jp\0freeboxos.fr\0"
+"ke\0"
+"kg\0"
+"furudono.fukushima.jp\0"
+"ki\0tree.museum\0dynalias.org\0"
+"mobi.gp\0trentinoa-adige.it\0toba.mie.jp\0ooshika.nagano.jp\0nagai.yamagata.jp\0"
+"koshu.yamanashi.jp\0"
+"km\0"
+"kn\0club\0next\0blogspot.co.at\0"
+"folldal.no\0lib.ma.us\0"
"kp\0"
"la\0"
-"shimodate.ibaraki.jp\0nagasaki.nagasaki.jp\0kr\0lb\0"
-"lc\0"
-"tromso.no\0"
-"tm.za\0"
-"kw\0"
-"\xe5\x85\xac\xe7\x9b\x8a\0"
+"kr\0lb\0"
+"lc\0naturbruksgymn.se\0"
+"shonai.yamagata.jp\0"
+"\xe6\xbe\xb3\xe9\x96\x80\0"
+"kw\0i.se\0"
+"haboro.hokkaido.jp\0"
"ky\0li\0"
-"kz\0"
-"lk\0"
-"realtor\0"
-"storj.farm\0"
-"!city.yokohama.jp\0is-a-student.com\0"
-"ma\0"
-"lr\0elverum.no\0"
-"ls\0mc\0norddal.no\0"
-"lt\0md\0gs.of.no\0"
-"minamifurano.hokkaido.jp\0lu\0me\0"
-"lv\0"
-"mg\0"
-"asn.lv\0mh\0hughes\0"
-"tokorozawa.saitama.jp\0ly\0"
-"ainan.ehime.jp\0mydrobo.com\0"
-"airport.aero\0mk\0"
-"ml\0mordovia.su\0"
-"mn\0"
-"kobayashi.miyazaki.jp\0mo\0"
-"trainer.aero\0mp\0click\0technology\0\xe9\x9b\x86\xe5\x9b\xa2\0"
-"milano.it\0mq\0na\0"
-"workinggroup.aero\0mr\0togliatti.su\0"
-"ms\0nc\0"
-"mt\0"
-"mu\0ne\0"
-"togitsu.nagasaki.jp\0mv\0nf\0"
+"chikuma.nagano.jp\0kz\0"
+"lk\0motorcycles\0"
+"cc.nv.us\0"
+"kawamata.fukushima.jp\0nagasu.kumamoto.jp\0"
+"ma\0protonet.io\0"
+"friulivgiulia.it\0lr\0"
+"ls\0mc\0"
+"lt\0md\0"
+"lu\0me\0\xc4\x8d\xc3\xa1hcesuolo.no\0eus\0"
+"hachioji.tokyo.jp\0lv\0"
+"mg\0alpha-myqnapcloud.com\0"
+"takasu.hokkaido.jp\0mh\0"
+"ly\0"
+"soccer\0stcgroup\0"
+"mk\0flakstad.no\0k12.vt.us\0"
+"ml\0"
+"ssl.origin.cdn77-secure.org\0"
+"cesena-forl\xc3\xac.it\0mn\0"
+"mo\0eidfjord.no\0\xd0\xbe\xd1\x80\xd0\xb3\0"
+"mp\0dabur\0"
+"mq\0na\0edu.eu.org\0tselinograd.su\0"
+"anpachi.gifu.jp\0kamakura.kanagawa.jp\0mr\0"
+"ms\0nc\0myqnapcloud.com\0"
+"fermo.it\0mt\0"
+"mu\0ne\0of.no\0"
+"ranzan.saitama.jp\0mv\0nf\0"
"mw\0ng\0"
-"6.bg\0mx\0"
-"my\0ni\0rana.no\0\xe5\xb9\xbf\xe4\xb8\x9c\0"
-"mz\0"
+"mx\0"
+"z.bg\0my\0ni\0is-into-anime.com\0"
+"asahikawa.hokkaido.jp\0mz\0gob.sv\0"
"nl\0"
-"no\0helsinki\0"
-"uwajima.ehime.jp\0"
-"dnsalias.net\0"
-"tahara.aichi.jp\0nr\0"
-"pp.se\0pp.ru\0"
-"\xe5\x8f\xb0\xe7\x81\xa3\0"
+"miyama.fukuoka.jp\0yanaizu.fukushima.jp\0"
+"no\0from-il.com\0"
+"nagano.nagano.jp\0makeup\0"
+"aizumi.tokushima.jp\0nr\0nextdirect\0"
+"yokawa.hyogo.jp\0yoshino.nara.jp\0"
"nu\0"
-"realestate.pl\0"
-"medicina.bo\0"
-"nh.us\0"
-"awaji.hyogo.jp\0nz\0"
-"mc.it\0kiyosu.aichi.jp\0"
-"om\0is-a-teacher.com\0"
-"sumida.tokyo.jp\0"
-"sakai.osaka.jp\0avianca\0"
+"tos.it\0"
+"from-fl.com\0"
+"nz\0trafficplex.cloud\0"
+"sardegna.it\0oshima.yamaguchi.jp\0"
+"masoy.no\0om\0"
+"dnsdojo.net\0"
+"takahagi.ibaraki.jp\0"
"pa\0"
-"tsubata.ishikawa.jp\0""4u.com\0"
-"cc.ua\0"
+"jl.cn\0"
+"national.museum\0bygland.no\0"
+"shimoichi.nara.jp\0lebork.pl\0"
"pe\0"
"pf\0"
-"ph\0"
-"myoko.niigata.jp\0"
-"brescia.it\0"
+"fosnes.no\0syno-ds.de\0"
+"chitose.hokkaido.jp\0ph\0"
+"quebec.museum\0aurland.no\0gob.ve\0money\0"
"pk\0"
-"pl\0mordovia.ru\0"
-"\xe7\xbd\x91\xe7\xbb\x9c.cn\0pm\0"
-"pn\0"
-"pp.ua\0"
-"ouchi.saga.jp\0qa\0"
-"pr\0"
+"koya.wakayama.jp\0pl\0financial\0"
+"pm\0"
+"shoo.okayama.jp\0pn\0"
+"sogne.no\0"
+"qa\0ut.us\0we.bs\0"
+"taiki.mie.jp\0taiwa.miyagi.jp\0pr\0"
"ps\0"
-"takasago.hyogo.jp\0pt\0"
-"\xe8\xaf\xba\xe5\x9f\xba\xe4\xba\x9a\0"
-"pw\0fan\0"
-"hachinohe.aomori.jp\0tsugaru.aomori.jp\0"
-"an.it\0py\0"
-"muenchen.museum\0"
-"teo.br\0"
-"tsurugashima.saitama.jp\0"
-"\xe9\x9d\x99\xe5\xb2\xa1.jp\0"
-"bristol.museum\0"
-"miki.hyogo.jp\0re\0"
-"security\0"
-"lebtimnetz.de\0"
-"cc.nv.us\0"
-"flt.cloud.muni.cz\0"
-"yahoo\0"
-"floripa.br\0lezajsk.pl\0luxury\0"
-"adachi.tokyo.jp\0"
-"niikappu.hokkaido.jp\0"
-"nara.nara.jp\0hattfjelldal.no\0ro\0"
-"sa\0"
-"mg.gov.br\0sb\0netflix\0"
-"takamori.kumamoto.jp\0rs\0sc\0"
-"la-spezia.it\0nishiokoppe.hokkaido.jp\0barcelona.museum\0\xc3\xb8ygarden.no\0sd\0"
-"togura.nagano.jp\0ru\0se\0"
-"donna.no\0"
-"shiraoi.hokkaido.jp\0rw\0sg\0abbott\0"
-"sn\xc3\xa5sa.no\0sh\0"
-"si\0cleverapps.io\0"
-"sj\0esq\0"
-"usgarden.museum\0sk\0servecounterstrike.com\0"
-"tank.museum\0v\xc3\xa6r\xc3\xb8y.no\0sl\0"
-"tomigusuku.okinawa.jp\0sm\0azerbaijan.su\0"
-"sn\0"
+"pt\0"
+"basel.museum\0"
+"ulsan.kr\0fit\0"
+"pw\0"
+"py\0"
+"\xe6\x9d\xb1\xe4\xba\xac.jp\0"
+"shinto.gunma.jp\0gwangju.kr\0"
+"org.ac\0"
+"wif.gov.pl\0"
+"org.ae\0"
+"org.af\0pz.it\0"
+"org.ag\0lib.sd.us\0"
+"yaizu.shizuoka.jp\0"
+"org.ai\0"
+"re\0"
+"org.al\0"
+"kaminokawa.tochigi.jp\0"
+"kyotamba.kyoto.jp\0fastlylb.net\0"
+"org.ba\0"
+"org.ar\0org.bb\0"
+"\xe6\xbe\xb3\xe9\x97\xa8\0blogspot.co.id\0"
+"org.au\0ro\0"
+"tysv\xc3\xa6r.no\0sa\0"
+"org.bh\0ashiya.fukuoka.jp\0sb\0"
+"org.bi\0kopervik.no\0rs\0sc\0beauty\0"
+"org.az\0sd\0"
+"ru\0se\0fastly-terrarium.com\0"
+"balsan.it\0blogspot.co.il\0"
+"org.bm\0archaeological.museum\0trustee.museum\0rw\0sg\0"
+"org.bn\0toki.gifu.jp\0kahoku.ishikawa.jp\0yoshikawa.saitama.jp\0sh\0"
+"org.bo\0si\0"
+"kaszuby.pl\0sj\0on-the-web.tv\0"
+"sk\0"
+"org.br\0mielno.pl\0sl\0"
+"org.bs\0sm\0black\0"
+"org.bt\0sn\0"
"so\0"
-"british.museum\0sr\0"
-"tc\0"
-"st\0td\0"
-"su\0"
-"sv\0tf\0"
-"architecture.museum\0tg\0"
-"sx\0th\0"
-"pup.gov.pl\0sy\0*.transurl.be\0"
-"sz\0tj\0vuelos\0"
-"tk\0"
+"df.gov.br\0sn.cn\0"
+"org.bw\0"
+"sr\0"
+"org.ci\0tc\0"
+"org.bz\0ms.it\0st\0td\0"
+"b\xc3\xa1jddar.no\0su\0"
+"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86.ir\0asakuchi.okayama.jp\0sv\0tf\0"
+"karmoy.no\0lier.no\0tg\0redumbrella\0"
+"org.cn\0forl\xc3\xac""cesena.it\0sx\0th\0"
+"org.co\0sy\0"
+"slupsk.pl\0sz\0tj\0"
+"tk\0fly\0"
"tl\0"
-"rc.it\0tm\0"
-"tn\0"
-"westfalen.museum\0to\0"
-"ua\0"
-"tr\0"
-"tt\0"
-"yk.ca\0"
-"tv\0is-a-nurse.com\0"
-"tw\0ug\0taxi\0boxfuse.io\0"
-"\xe7\xbd\x91\xe7\xbb\x9c.hk\0arboretum.museum\0tz\0williamhill\0"
-"oishida.yamagata.jp\0uk\0"
-"profesional.bo\0eus\0"
-"s.se\0"
-"cooking\0cookingchannel\0"
-"arita.saga.jp\0lahppi.no\0"
-"riodejaneiro.museum\0va\0"
-"hiraya.nagano.jp\0cinema.museum\0nyny.museum\0"
-"kyotango.kyoto.jp\0us\0vc\0"
-"pordenone.it\0ve\0"
-"ontario.museum\0vg\0hepforge.org\0"
-"zapto.xyz\0"
-"fribourg.museum\0uy\0vi\0mg.leg.br\0"
-"beauxarts.museum\0uz\0"
-"no-ip.co.uk\0"
-"frosinone.it\0"
-"plc.ly\0"
-"vn\0"
-"trentino-suedtirol.it\0"
-"nf.ca\0"
-"nature.museum\0\xe9\x9b\xbb\xe8\xa8\x8a\xe7\x9b\x88\xe7\xa7\x91\0"
-"sciencecenter.museum\0vu\0"
-"wf\0"
-"qpon\0"
-"is-a-anarchist.com\0"
-"us-east-1.elasticbeanstalk.com\0"
-"tingvoll.no\0careers\0"
-"*.nom.br\0essex.museum\0"
-"kibichuo.okayama.jp\0birthplace.museum\0ws\0"
-"rovigo.it\0"
-"kagoshima.kagoshima.jp\0*.transurl.eu\0"
-"its.me\0"
-"oharu.aichi.jp\0brother\0"
-"reklam.hu\0"
-"rollag.no\0"
-"afjord.no\0"
-"yawatahama.ehime.jp\0"
-"vpnplus.to\0"
-"hino.tokyo.jp\0"
-"kamiichi.toyama.jp\0cc.ia.us\0"
-"leasing.aero\0yamato.fukushima.jp\0fuchu.toyama.jp\0media.museum\0logoip.de\0"
-"fit\0"
-"vs.it\0"
-"valledaosta.it\0"
-"yt\0"
-"lib.hi.us\0"
-"fuji.shizuoka.jp\0co.com\0"
-"mutsuzawa.chiba.jp\0gotpantheon.com\0"
-"showa.gunma.jp\0shimizu.shizuoka.jp\0"
-"zm\0"
-"teramo.it\0"
-"arezzo.it\0zp.ua\0"
-"aizumi.tokushima.jp\0"
-"br\xc3\xb8nn\xc3\xb8ysund.no\0"
-"nakagyo.kyoto.jp\0zw\0"
-"r\xc3\xa1hkker\xc3\xa1vju.no\0"
-"odawara.kanagawa.jp\0"
-"insurance.aero\0from-ut.com\0"
-"cloudapp.net\0"
-"l\xc3\xa6rdal.no\0"
-"aland.fi\0hachirogata.akita.jp\0"
-"yazu.tottori.jp\0wielun.pl\0"
-"bajddar.no\0"
-"website\0"
-"casino.hu\0"
-"vda.it\0"
-"lanxess\0"
-"federation.aero\0koga.fukuoka.jp\0"
-"fly\0"
-"legal\0"
-"ikawa.akita.jp\0"
-"etnedal.no\0"
-"gb.net\0"
-"uzs.gov.pl\0"
-"doesntexist.org\0"
-"ok.us\0"
-"starhub\0"
-"frogans\0"
-"linz.museum\0"
-"mydissent.net\0"
-"busan.kr\0"
-"nakano.tokyo.jp\0"
-"u2.xnbay.com\0"
-"stj\xc3\xb8rdalshalsen.no\0cv.ua\0plc.uk\0"
-"ha.cn\0hidaka.wakayama.jp\0"
-"dy.fi\0"
-"h\xc3\xb8nefoss.no\0"
-"endofinternet.net\0"
-"adac\0"
-"lib.mi.us\0"
+"tm\0brasilia.me\0"
+"ven.it\0shinagawa.tokyo.jp\0atm.pl\0tn\0"
+"org.cu\0to\0boutique\0"
+"org.cw\0ua\0"
+"shiga.jp\0gose.nara.jp\0tr\0"
+"org.cy\0is-a-personaltrainer.com\0"
+"tt\0olayan\0for-better.biz\0"
+"hakodate.hokkaido.jp\0jeonbuk.kr\0tv\0"
+"org.dm\0tw\0ug\0fedorapeople.org\0"
+"org.do\0nv.us\0"
+"tz\0hair\0"
+"losangeles.museum\0uk\0"
+"shimoji.okinawa.jp\0"
+"org.ec\0berg.no\0b\xc3\xb8.nordland.no\0"
+"org.ee\0"
+"org.eg\0va\0"
+"oto.fukuoka.jp\0ms.kr\0"
+"us\0vc\0"
+"org.dz\0sardinia.it\0trentins\xc3\xbc""dtirol.it\0kyotanabe.kyoto.jp\0"
+"ve\0whoswho\0home-webserver.de\0"
+"vg\0"
+"sos.pl\0"
+"uy\0vi\0"
+"uz\0freetls.fastly.net\0"
+"mysecuritycamera.com\0"
+"ptplus.fit\0"
+"org.es\0"
+"org.et\0vn\0"
"foo\0"
-"nagasaki.jp\0"
-"q.bg\0kannami.shizuoka.jp\0"
-"chungbuk.kr\0dyroy.no\0"
-"*.platformsh.site\0"
-"fox\0"
-"ohira.miyagi.jp\0onthewifi.com\0"
-"\xe9\xa6\x99\xe6\xb8\xaf\0"
-"ca.it\0"
-"museumvereniging.museum\0"
-"democracia.bo\0*.sendai.jp\0tachiarai.fukuoka.jp\0"
-"beta.bounty-full.com\0"
-"bauhaus\0apps.lair.io\0"
-"meldal.no\0\xe8\x81\x94\xe9\x80\x9a\0"
-"pn.it\0raid\0"
-"*.transurl.nl\0"
-"square7.de\0"
-"gal\0"
-"isehara.kanagawa.jp\0"
+"kasugai.aichi.jp\0"
+"vu\0"
+"wf\0"
+"cc.ms.us\0cc.nc.us\0mypep.link\0"
+"smola.no\0"
+"minamiawaji.hyogo.jp\0kami.miyagi.jp\0fox\0"
+"fie.ee\0"
+"org.ge\0mymailer.com.tw\0"
+"niyodogawa.kochi.jp\0"
+"org.gg\0"
+"org.gh\0anan.nagano.jp\0ac.leg.br\0"
+"org.gi\0ws\0lego\0"
+"org.gl\0cloud\0"
+"\xe9\xa6\x99\xe6\xa0\xbc\xe9\x87\x8c\xe6\x8b\x89\0"
+"org.gn\0"
+"bjerkreim.no\0filegear-au.me\0"
+"org.gp\0"
+"org.gr\0ge.it\0shikaoi.hokkaido.jp\0mitsuke.niigata.jp\0"
+"l\xc3\xb8ten.no\0readthedocs.io\0"
+"org.gt\0gal\0"
+"org.gu\0bar.pro\0"
+"mie.jp\0kunneppu.hokkaido.jp\0"
+"holiday\0"
"gap\0"
-"tydal.no\0"
-"yugawa.fukushima.jp\0"
-"uber.space\0"
-"sirdal.no\0"
-"shopping\0"
-"ddnsking.com\0"
-"frl\0"
-"\xe7\xb5\x84\xe7\xbb\x87.hk\0stuff-4-sale.org\0"
-"otsuki.kochi.jp\0"
-"couchpotatofries.org\0"
-"*.vps.myjino.ru\0"
-"asago.hyogo.jp\0"
-"damnserver.com\0"
-"zone.id\0"
-"symantec\0"
-"higashiomi.shiga.jp\0"
-"lib.ct.us\0"
-"ca.na\0if.ua\0"
-"kin.okinawa.jp\0"
-"cloudfunctions.net\0"
-"square7.ch\0"
-"gulen.no\0gdn\0"
-"lib.ri.us\0is-a-republican.com\0"
-"gea\0"
-"otaki.chiba.jp\0hole.no\0ftr\0dynathome.net\0"
-"\xe7\xbd\x91\xe7\xbb\x9c\0"
-"skiptvet.no\0"
-"nakano.nagano.jp\0"
-"warmia.pl\0bananarepublic\0"
-"gift\0"
-"ouda.nara.jp\0jur.pro\0tours\0"
-"shiroishi.miyagi.jp\0ritto.shiga.jp\0"
-"fun\0"
-"cards\0goldpoint\0"
-"port.fr\0"
-"joso.ibaraki.jp\0"
-"nesodden.no\0"
-"rec.br\0"
-"otaki.nagano.jp\0bahn.museum\0"
-"cern\0"
-"engineer\0"
-"lom.it\0"
-"sowa.ibaraki.jp\0"
-"rec.co\0umaji.kochi.jp\0"
-"varese.it\0sosa.chiba.jp\0minnesota.museum\0posts-and-telecommunications.museum\0"
-"modalen.no\0s3-ap-southeast-1.amazonaws.com\0"
-"rnu.tn\0"
-"asahi.mie.jp\0"
-"dynalias.com\0"
-"kamo.niigata.jp\0betainabox.com\0is-certified.com\0"
-"hanno.saitama.jp\0"
-"aridagawa.wakayama.jp\0"
-"kamikawa.saitama.jp\0"
-"trentinosuedtirol.it\0vegas\0"
-"katashina.gunma.jp\0gs.nt.no\0"
-"sf.no\0"
-"miyada.nagano.jp\0"
-"open\0"
-"servebbs.org\0"
-"otoyo.kochi.jp\0"
-"cologne\0toshiba\0"
-"hiratsuka.kanagawa.jp\0"
-"lib.id.us\0"
-"fyi\0hospital\0"
-"4.bg\0"
-"chikujo.fukuoka.jp\0"
-"origins\0"
-"lib.wi.us\0"
-"is-very-good.org\0"
-"biratori.hokkaido.jp\0"
-"aukra.no\0lindas.no\0"
-"ha.no\0"
-"yamatokoriyama.nara.jp\0ddnss.org\0"
-"suzu.ishikawa.jp\0yamagata.nagano.jp\0"
-"tokai.aichi.jp\0saikai.nagasaki.jp\0americana.museum\0bearalvahki.no\0"
-"plaza.museum\0"
-"nemuro.hokkaido.jp\0klodzko.pl\0"
-"itakura.gunma.jp\0nishihara.kumamoto.jp\0"
-"maniwa.okayama.jp\0de.cool\0"
-"salerno.it\0"
-"android\0"
-"lom.no\0"
-"misaki.osaka.jp\0"
-"nishinoomote.kagoshima.jp\0"
-"hammerfest.no\0k12.nj.us\0"
-"nago.okinawa.jp\0"
-"sandcats.io\0"
-"kutno.pl\0"
-"stange.no\0vladimir.su\0"
-"shika.ishikawa.jp\0"
-"gle\0dyndns-free.com\0"
-"k12.ec\0"
-"s\xc3\xb8r-varanger.no\0"
-"pointto.us\0"
-"id.au\0\xd0\xba\xd0\xbe\xd0\xbc\0"
-"kawaminami.miyazaki.jp\0ca.us\0"
-"kawaue.gifu.jp\0deals\0"
-"al.it\0tosashimizu.kochi.jp\0"
-"kumatori.osaka.jp\0"
-"iizuka.fukuoka.jp\0services\0"
-"discovery.museum\0"
-"ato.br\0twmail.net\0"
-"wa.au\0hol.no\0"
-"e164.arpa\0"
-"ddnss.de\0"
-"yokoshibahikari.chiba.jp\0"
-"uruma.okinawa.jp\0gs.st.no\0"
-"express.aero\0k12.as.us\0"
-"sasaguri.fukuoka.jp\0kushimoto.wakayama.jp\0"
-"rauma.no\0"
-"suwa.nagano.jp\0gmo\0"
-"wlocl.pl\0"
-"cahcesuolo.no\0"
-"masfjorden.no\0"
-"k12.or.us\0"
-"latrobe\0"
+"g.bg\0org.gy\0priv.hu\0pics\0"
+"org.hk\0computer.museum\0crimea.ua\0"
+"org.hn\0"
+"org.ht\0frl\0uk.net\0"
+"org.hu\0arboretum.museum\0is-a-rockstar.com\0"
+"sites.static.land\0"
+"eun.eg\0"
+"yt\0"
+"\xe5\xa4\xa9\xe4\xb8\xbb\xe6\x95\x99\0"
+"org.il\0tateshina.nagano.jp\0intuit\0"
+"org.im\0naroy.no\0"
+"org.in\0yawatahama.ehime.jp\0ms.leg.br\0"
+"aeroclub.aero\0qld.gov.au\0"
+"umi.fukuoka.jp\0"
+"org.iq\0nordre-land.no\0"
+"org.ir\0support\0"
+"org.is\0kunst.museum\0zm\0cust.testing.thingdust.io\0"
+"org.je\0ee.eu.org\0"
+"cn.it\0"
+"l\xc3\xa4ns.museum\0\xe4\xbd\x9b\xe5\xb1\xb1\0"
+"ribeirao.br\0"
+"miyako.fukuoka.jp\0"
+"0.bg\0zw\0"
+"org.jo\0"
+"shibuya.tokyo.jp\0"
+"saiki.oita.jp\0"
+"monza-e-della-brianza.it\0gdn\0"
+"org.kg\0"
+"ketrzyn.pl\0"
+"org.ki\0skedsmo.no\0gea\0"
+"\xe9\xab\x98\xe7\x9f\xa5.jp\0ftr\0"
+"org.km\0amsterdam\0"
+"alessandria.it\0org.kn\0church\0mt.leg.br\0"
+"cuisinella\0"
+"pg.it\0hannan.osaka.jp\0org.kp\0"
+"org.la\0lib.ri.us\0"
+"org.lb\0no-ip.net\0"
+"org.lc\0k12.ny.us\0"
+"nomi.ishikawa.jp\0"
+"waw.pl\0fun\0"
+"org.kw\0anthro.museum\0from-mo.com\0"
+"omihachiman.shiga.jp\0"
+"org.ky\0"
+"nahari.kochi.jp\0nagiso.nagano.jp\0org.kz\0"
+"org.lk\0"
+"chofu.tokyo.jp\0"
+"org.ma\0"
+"org.lr\0"
+"org.ls\0"
+"gen.in\0nobeoka.miyazaki.jp\0"
+"org.me\0naumburg.museum\0gos.pk\0"
+"belluno.it\0ashibetsu.hokkaido.jp\0org.lv\0"
+"org.mg\0\xe5\x95\x86\xe6\xa5\xad.tw\0"
+"priv.at\0"
+"org.ly\0gives\0"
+"org.mk\0field.museum\0"
+"org.ml\0"
+"org.mn\0"
+"org.mo\0lenvik.no\0"
+"org.na\0"
+"org.ms\0arts.museum\0"
+"caserta.it\0org.mt\0"
+"org.mu\0museum\0lib.mn.us\0"
+"\xe8\x8c\xa8\xe5\x9f\x8e.jp\0org.mv\0"
+"humanities.museum\0org.mw\0org.ng\0"
+"takko.aomori.jp\0org.mx\0nc.tr\0"
+"org.my\0org.ni\0"
+"mihama.wakayama.jp\0org.mz\0gniezno.pl\0"
+"nt.au\0blogspot.co.uk\0"
+"earth\0"
+"z.se\0iki.fi\0"
+"org.nr\0epost\0"
+"s3.eu-west-3.amazonaws.com\0"
+"trentins\xc3\xbc""d-tirol.it\0"
+"frana.no\0"
+"takatsuki.osaka.jp\0"
+"nt.ca\0"
+"kashihara.nara.jp\0verm\xc3\xb6gensberater\0"
+"ms.us\0nc.us\0itau\0"
+"org.nz\0"
+"hareid.no\0"
+"from.hr\0"
+"org.om\0"
+"miyagi.jp\0"
+"saito.miyazaki.jp\0"
+"org.pa\0fyi\0"
+"mobi.tt\0"
+"civilwar.museum\0rissa.no\0org.pe\0security\0\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\0remotewd.com\0"
+"org.pf\0"
+"filatelia.museum\0"
+"org.ph\0"
+"dolls.museum\0rodoy.no\0tinn.no\0"
+"mobi.tz\0creditunion\0"
+"org.pk\0"
+"org.pl\0vapor.cloud\0"
+"org.pn\0"
+"ski.no\0"
+"org.qa\0haus\0"
+"kumenan.okayama.jp\0yatsuka.shimane.jp\0org.pr\0"
+"gulen.no\0org.ps\0"
+"misawa.aomori.jp\0org.pt\0"
+"ally\0bugatti\0filegear.me\0"
+"usculture.museum\0org.py\0keymachine.de\0"
+"military.museum\0"
+"koto.shiga.jp\0restaurant\0"
+"nt.edu.au\0volvo\0"
+"sannan.hyogo.jp\0other.nf\0"
+"swiss\0youtube\0"
+"vb.it\0aizumisato.fukushima.jp\0"
+"s3-website.ap-northeast-2.amazonaws.com\0"
+"sch.ae\0panama.museum\0"
+"hyuga.miyazaki.jp\0"
+"s3-us-west-1.amazonaws.com\0"
+"agr.br\0"
+"s3-website.ca-central-1.amazonaws.com\0"
+"gv.ao\0gle\0ping\0"
+"org.ro\0pimienta.org\0"
+"gen.nz\0"
+"org.sa\0lexus\0pink\0nfshost.com\0"
+"gv.at\0hiroshima.jp\0kawajima.saitama.jp\0org.sb\0"
+"org.rs\0org.sc\0"
+"org.sd\0"
+"org.se\0org.ru\0"
+"omaha.museum\0org.sg\0nflfan.org\0"
+"org.sh\0"
+"sandnessj\xc3\xb8""en.no\0"
+"org.sl\0"
+"sande.vestfold.no\0"
+"org.sn\0"
+"org.so\0"
+"nakatombetsu.hokkaido.jp\0"
+"nesna.no\0country\0"
+"ancona.it\0kiryu.gunma.jp\0hitachiota.ibaraki.jp\0"
+"org.st\0"
+"karasjohka.no\0blogspot.co.ke\0"
+"kitagawa.miyazaki.jp\0hasuda.saitama.jp\0org.sv\0"
+"gmo\0"
+"gs.nt.no\0org.sy\0"
+"org.sz\0org.tj\0"
+"org.tm\0"
+"yorii.saitama.jp\0org.tn\0"
+"org.to\0"
"gmx\0"
-"lib.mt.us\0lib.nd.us\0from-nm.com\0"
-"tsuno.miyazaki.jp\0"
-"kawanehon.shizuoka.jp\0rv.ua\0"
-"artcenter.museum\0"
-"yamakita.kanagawa.jp\0ternopil.ua\0homeunix.com\0fantasyleague.cc\0"
-"tur.ar\0vladimir.ru\0"
-"hara.nagano.jp\0"
-"psi.br\0miyama.mie.jp\0katsuragi.wakayama.jp\0"
-"ct.it\0"
-"buzz\0star\0"
-"the.br\0"
-"abu.yamaguchi.jp\0cc.co.us\0"
-"s3.ca-central-1.amazonaws.com\0"
-"goo\0"
+"mobi.na\0and\xc3\xb8y.no\0org.ua\0lib.de.us\0"
+"org.tr\0"
+"entomology.museum\0moskenes.no\0cn.ua\0"
+"org.tt\0"
+"modern.museum\0"
+"\xe6\x96\xb0\xe6\xbd\x9f.jp\0hioki.kagoshima.jp\0"
+"mobi.ng\0org.tw\0org.ug\0"
+"olkusz.pl\0"
+"org.uk\0tickets\0"
+"1kapp.com\0"
+"lardal.no\0"
+"fedex\0"
+"moareke.no\0org.vc\0ap-south-1.elasticbeanstalk.com\0"
+"org.ve\0"
+"goo\0hobby-site.com\0"
"gop\0"
-"ra.it\0matsumoto.kagoshima.jp\0shibata.niigata.jp\0"
-"tur.br\0"
-"got\0"
-"mobi\0"
-"gov\0"
-"isleofman.museum\0"
-"yamanashi.yamanashi.jp\0"
-"osasco.br\0"
-"aomori.aomori.jp\0sor-varanger.no\0\xe6\xb8\xb8\xe6\x88\x8f\0"
-"k12.il\0"
-"enterprises\0"
-"is.gov.pl\0"
-"\xc3\xa1laheadju.no\0"
-"tranibarlettaandria.it\0"
-"al.no\0"
-"rec.nf\0americanfamily\0"
-"slupsk.pl\0"
-"moda\0"
-"luzern.museum\0fairwinds\0"
-"is-a-liberal.com\0"
-"crown\0"
-"museum.tt\0is-into-games.com\0"
-"bio.br\0nakagawa.hokkaido.jp\0ilawa.pl\0"
-"gliding.aero\0portlligat.museum\0"
-"nishikatsura.yamanashi.jp\0seaport.museum\0"
-"kasuya.fukuoka.jp\0hirado.nagasaki.jp\0barsy.net\0"
-"higashiyodogawa.osaka.jp\0"
-"lebork.pl\0"
-"official.academy\0"
-"mer\xc3\xa5ker.no\0hbo\0"
-"aca.pro\0"
-"aircraft.aero\0chattanooga.museum\0"
-"nara.jp\0"
-"\xe6\x94\xbf\xe5\xba\x9c.hk\0alaheadju.no\0\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\x9f\0"
-"issmarterthanyou.com\0al.eu.org\0"
-"*.nagoya.jp\0capetown\0"
-"rentals\0"
-"budejju.no\0"
-"construction\0"
-"lib.sd.us\0dnsalias.org\0from-mt.com\0from-nd.com\0"
-"tomisato.chiba.jp\0"
-"liguria.it\0"
-"tomakomai.hokkaido.jp\0"
-"cloudns.biz\0"
-"id.ir\0shinichi.hiroshima.jp\0"
-"hiphop\0"
-"showa.yamanashi.jp\0royrvik.no\0url.tw\0pcloud.host\0"
-"iris.arpa\0ferrara.it\0oxford.museum\0"
-"larvik.no\0"
-"konan.shiga.jp\0school.na\0"
-"yamanobe.yamagata.jp\0"
-"lucca.it\0handson.museum\0dedyn.io\0"
-"trentinsued-tirol.it\0kawaguchi.saitama.jp\0wv.us\0ann-arbor.mi.us\0"
-"yuu.yamaguchi.jp\0"
-"sor-odal.no\0"
-"eu.int\0astronomy.museum\0"
-"obu.aichi.jp\0"
-"muroto.kochi.jp\0newspaper.museum\0amli.no\0"
-"oum.gov.pl\0gotdns.ch\0"
-"koryo.nara.jp\0lyngen.no\0"
-"judygarland.museum\0"
-"rec.ro\0aramco\0"
-"olawa.pl\0"
-"school.nz\0"
-"oguni.yamagata.jp\0"
-"rimini.it\0"
-"now.sh\0"
-"torsken.no\0mmafan.biz\0"
-"ma.us\0"
-"pgfog.com\0"
-"gratis\0"
-"id.lv\0"
-"\xeb\x8b\xb7\xeb\x84\xb7\0"
-"id.ly\0"
-"k12.ks.us\0merseine.nu\0"
-"wazuka.kyoto.jp\0"
-"tattoo\0"
-"trentino-sudtirol.it\0"
-"sd.cn\0"
-"tonsberg.no\0"
-"tsunan.niigata.jp\0pl.eu.org\0protonet.io\0"
-"midatlantic.museum\0"
-"business\0"
-"al.us\0"
-"from-ms.com\0from-nc.com\0"
-"iwi.nz\0"
-"satosho.okayama.jp\0tires\0"
-"tanohata.iwate.jp\0"
-"is-leet.com\0"
-"monmouth.museum\0ny.us\0"
-"est-a-la-masion.com\0"
-"indian.museum\0settlement.museum\0""2ix.at\0"
-"mt.it\0rec.ve\0"
-"nagaoka.niigata.jp\0"
-"komforb.se\0linkitools.space\0"
-"shishikui.tokushima.jp\0cc.mo.us\0farmers\0"
-"go.ci\0"
-"toyota.yamaguchi.jp\0"
-"higashimatsushima.miyagi.jp\0page\0"
-"aogaki.hyogo.jp\0"
+"minnesota.museum\0org.uy\0org.vi\0"
+"org.uz\0"
+"got\0wedeploy.sh\0"
+"plantation.museum\0k12.nh.us\0"
+"gov\0fukui.fukui.jp\0matsuda.kanagawa.jp\0org.vn\0"
+"rad\xc3\xb8y.no\0"
+"readmyblog.org\0"
+"org.vu\0"
+"vic.au\0edeka\0"
+"sekigahara.gifu.jp\0"
+"telekommunikation.museum\0"
+"kembuchi.hokkaido.jp\0"
+"agakhan\0irish\0"
+"piedmont.it\0"
+"org.ws\0"
+"shima.mie.jp\0ogose.saitama.jp\0gen.tr\0"
+"qh.cn\0blogspot.co.nz\0"
+"yokosuka.kanagawa.jp\0minamisanriku.miyagi.jp\0katano.osaka.jp\0swatch\0"
+"overhalla.no\0baidu\0\xe9\x80\x9a\xe8\xb2\xa9\0"
+"kamikitayama.nara.jp\0kimino.wakayama.jp\0"
+"donna.no\0"
+"ah.cn\0kitchen\0"
+"berlin.museum\0g.se\0hbo\0"
+"al.leg.br\0"
+"int.eu.org\0"
+"american.museum\0"
+"toray\0"
+"haibara.shizuoka.jp\0""2ix.at\0"
+"aosta-valley.it\0oki.fukuoka.jp\0kitashiobara.fukushima.jp\0misugi.mie.jp\0"
+"org.za\0"
+"amex\0"
+"mobi.ke\0herad.no\0aramco\0"
+"sch.id\0bando.ibaraki.jp\0"
+"glug.org.uk\0"
+"madrid\0"
+"szkola.pl\0"
+"imizu.toyama.jp\0"
+"osen.no\0org.zm\0"
+"\xd8\xb4\xd8\xa8\xd9\x83\xd8\xa9\0"
+"trentin-sudtirol.it\0uenohara.yamanashi.jp\0"
+"2ix.ch\0"
+"fidelity\0"
+"sch.ir\0"
+"frog.museum\0nt.no\0"
+"org.zw\0cbg.ru\0stufftoread.com\0"
+"urasoe.okinawa.jp\0mopar\0"
+"council.aero\0x.bg\0"
+"soundcast.me\0"
+"savona.it\0kyuragi.saga.jp\0"
+"miyakonojo.miyazaki.jp\0cookingchannel\0"
+"is-an-anarchist.com\0""2ix.de\0"
+"kurate.fukuoka.jp\0"
+"sch.jo\0"
+"theworkpc.com\0"
+"lplfinancial\0"
+"karate.museum\0kommunalforbund.se\0cn.eu.org\0"
+"zj.cn\0"
+"hoylandet.no\0law.za\0"
+"family\0"
+"to.it\0"
+"lib.va.us\0"
+"shinshinotsu.hokkaido.jp\0"
+"ando.nara.jp\0"
+"cranbrook.museum\0r\xc3\xa5holt.no\0"
+"vald-aosta.it\0"
+"erimo.hokkaido.jp\0"
+"gs.ah.no\0k12.ca.us\0"
+"hitachi.ibaraki.jp\0"
+"cc.wv.us\0"
+"rj.gov.br\0"
+"sch.lk\0s3-website.eu-west-2.amazonaws.com\0hopto.me\0"
+"lerdal.no\0"
+"customer.enonic.io\0"
+"trapani.it\0"
+"vic.gov.au\0investments\0"
+"gc.ca\0domains\0"
+"sch.ly\0cloud66.ws\0"
+"volkswagen\0"
+"assedic.fr\0psp.gov.pl\0"
+"fujishiro.ibaraki.jp\0"
+"nt.ro\0"
+"toyone.aichi.jp\0"
+"nemuro.hokkaido.jp\0broke-it.net\0"
+"sch.ng\0"
+"okawa.fukuoka.jp\0"
+"guovdageaidnu.no\0"
+"kaho.fukuoka.jp\0"
+"fage\0vote\0"
+"wellbeingzone.eu\0"
+"valle-d-aosta.it\0priv.pl\0"
+"asaminami.hiroshima.jp\0notogawa.shiga.jp\0"
+"karm\xc3\xb8y.no\0"
+"voto\0"
+"kerryhotels\0wedeploy.me\0"
+"baghdad.museum\0amfam\0ro.eu.org\0"
+"wakayama.jp\0"
"hiv\0"
-"salvadordali.museum\0lapy.pl\0"
-"go.cr\0k12.ok.us\0gallery\0"
-"higashikagura.hokkaido.jp\0"
-"cnt.br\0itako.ibaraki.jp\0"
-"vestby.no\0\xe5\xa4\xa7\xe6\x8b\xbf\0""2ix.ch\0"
-"piemonte.it\0washtenaw.mi.us\0"
-"o.bg\0r\xc3\xb8mskog.no\0vestvagoy.no\0"
-"marugame.kagawa.jp\0"
-"kuchinotsu.nagasaki.jp\0"
-"ct.us\0"
-"pol.dz\0museum.mv\0dev-myqnapcloud.com\0"
-"museum.mw\0pomorze.pl\0"
-"bo.it\0"
-"dr\xc3\xb8""bak.no\0"
-"2ix.de\0"
-"\xe7\xbd\x91\xe5\xba\x97\0"
-"lugansk.ua\0cc.az.us\0"
-"museum.no\0bestbuy\0"
-"culture.museum\0"
-"quicksytes.com\0"
-"shingu.wakayama.jp\0hkt\0"
-"k12.tr\0"
-"kisofukushima.nagano.jp\0"
-"ancona.it\0"
-"rennesoy.no\0"
-"2038.io\0"
-"museum.om\0"
-"onna.okinawa.jp\0"
-"hvaler.no\0"
-"seihi.nagasaki.jp\0linkyard-cloud.ch\0"
-"publishproxy.com\0"
-"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xd8\xa9\0"
-"servehumour.com\0"
-"fosnes.no\0\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\0"
-"and\xc3\xb8y.no\0"
-"k12.vi\0"
-"traeumtgerade.de\0"
-"fl.us\0"
-"koga.ibaraki.jp\0"
-"moriyoshi.akita.jp\0"
-"toyota.aichi.jp\0bahccavuotna.no\0"
-"uchinomi.kagawa.jp\0"
-"\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0spiegel\0"
-"moriya.ibaraki.jp\0"
-"tempioolbia.it\0"
-"villas\0"
-"soo.kagoshima.jp\0"
-"naka.ibaraki.jp\0"
-"pol.ht\0murata.miyagi.jp\0"
-"cherkasy.ua\0\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x90\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\xa5.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0"
-"kusatsu.gunma.jp\0team\0"
-"tenei.fukushima.jp\0misugi.mie.jp\0s3-website-ap-southeast-1.amazonaws.com\0"
-"barsy.pro\0"
-"tsukigata.hokkaido.jp\0misato.miyagi.jp\0s3.dualstack.eu-west-3.amazonaws.com\0"
-"prd.fr\0"
-"ru.com\0is-not-certified.com\0"
-"matsushige.tokushima.jp\0"
-"go.id\0"
-"wakasa.fukui.jp\0"
-"vinnytsia.ua\0"
-"og.ao\0"
-"beppu.oita.jp\0town.museum\0"
-"hot\0"
-"eu-west-3.elasticbeanstalk.com\0"
-"id.us\0how\0"
-"go.it\0minamiyamashiro.kyoto.jp\0"
-"lodi.it\0shizuoka.jp\0cadaques.museum\0\xec\x82\xbc\xec\x84\xb1\0"
-"namerikawa.toyama.jp\0"
-"sa.edu.au\0tech\0"
-"bandai.fukushima.jp\0"
-"isahaya.nagasaki.jp\0"
-"wa.us\0"
-"hanawa.fukushima.jp\0"
-"homelink.one\0"
-"airtraffic.aero\0go.jp\0"
-"barsy.pub\0"
-"louvre.museum\0oystre-slidre.no\0"
-"aero\0"
-"sorocaba.br\0lakas.hu\0sydney\0i234.me\0"
-"go.ke\0"
-"oto.fukuoka.jp\0"
-"hu.net\0"
-"s3.dualstack.ap-northeast-1.amazonaws.com\0"
+"lel.br\0"
+"forsand.no\0"
+"\xd1\x80\xd1\x83\xd1\x81\0"
+"na.it\0"
+"bradesco\0"
+"ureshino.mie.jp\0"
+"od.ua\0"
"sic.it\0"
-"iheya.okinawa.jp\0"
-"hamatonbetsu.hokkaido.jp\0"
-"news.hu\0nakanoto.ishikawa.jp\0rns.tn\0za.com\0"
-"go.kr\0tirol\0"
-"uji.kyoto.jp\0"
-"organic\0"
-"moto\0"
-"ibm\0"
-"tara.saga.jp\0"
-"yurihonjo.akita.jp\0frana.no\0"
-"kerrylogistics\0locker\0"
-"chikuma.nagano.jp\0"
-"ice\0"
-"collegefan.org\0"
-"trentinsudtirol.it\0navuotna.no\0"
-"dnipropetrovsk.ua\0lilly\0endofinternet.org\0"
-"tran\xc3\xb8y.no\0"
-"forlicesena.it\0bievat.no\0"
-"kijo.miyazaki.jp\0"
-"prd.km\0nowruz\0"
-"film.museum\0icu\0"
-"kawagoe.mie.jp\0"
-"birdart.museum\0"
-"2.bg\0"
-"pvt.ge\0"
-"qld.au\0bridgestone\0"
-"ecologia.bo\0"
-"moareke.no\0"
-"fujimino.saitama.jp\0"
-"hikari.yamaguchi.jp\0"
-"tohma.hokkaido.jp\0"
-"numata.hokkaido.jp\0"
-"city.hu\0"
-"fujisato.akita.jp\0"
-"govt.nz\0"
-"vinnica.ua\0mt.us\0nd.us\0"
-"arte.bo\0kaisei.kanagawa.jp\0higashine.yamagata.jp\0"
-"lo.it\0prd.mg\0"
-"*.compute-1.amazonaws.com\0"
-"kanna.gunma.jp\0"
-"chat\0"
-"pars\0"
-"kongsvinger.no\0"
-"physio\0"
-"urayasu.chiba.jp\0echizen.fukui.jp\0"
-"fj.cn\0\xe6\x84\x9b\xe5\xaa\x9b.jp\0"
-"science\0dyndns-at-home.com\0"
-"kviteseid.no\0"
-"\xd8\xa7\xd8\xaa\xd8\xb5\xd8\xa7\xd9\x84\xd8\xa7\xd8\xaa\0"
-"varggat.no\0"
-"raisa.no\0temasek\0ae.org\0in-the-band.net\0"
-"ifm\0"
-"amot.no\0imamat\0"
-"oji.nara.jp\0pl.ua\0"
-"naka.hiroshima.jp\0"
-"kawakami.nara.jp\0esurance\0"
-"m\xc4\x81ori.nz\0imdb\0clan.rip\0"
-"gonohe.aomori.jp\0kariwa.niigata.jp\0jpn.com\0"
-"matsuno.ehime.jp\0"
-"go.pw\0"
-"s3-us-west-1.amazonaws.com\0"
-"snillfjord.no\0"
-"\xd0\xbc\xd0\xba\xd0\xb4\0"
-"alaska.museum\0isteingeek.de\0"
-"transporte.bo\0boleslawiec.pl\0"
-"og.it\0"
-"iwate.jp\0ybo.science\0"
-"n4t.co\0"
-"\xe5\x95\x86\xe5\xba\x97\0"
-"skedsmo.no\0"
-"kitagawa.miyazaki.jp\0"
-"yoka.hyogo.jp\0"
-"tohnosho.chiba.jp\0"
-"eidskog.no\0"
-"kahoku.ishikawa.jp\0"
-"cr.it\0otago.museum\0"
-"homelinux.com\0"
-"gs.hm.no\0capitalone\0"
-"hirogawa.wakayama.jp\0is-a-therapist.com\0"
-"\xd8\xb3\xd9\x88\xd8\xaf\xd8\xa7\xd9\x86\0"
-"ravenna.it\0"
-"biei.hokkaido.jp\0"
-"sd.us\0moscow\0"
-"curitiba.br\0"
-"arteducation.museum\0"
-"go.th\0pol.tr\0"
-"esan.hokkaido.jp\0hannan.osaka.jp\0gotsu.shimane.jp\0"
-"toyone.aichi.jp\0ostre-toten.no\0go.tj\0"
-"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xdb\x83\0"
-"kanmaki.nara.jp\0undersea.museum\0"
-"academy.museum\0"
-"sayama.saitama.jp\0"
-"fermo.it\0maori.nz\0"
-"iglesias-carbonia.it\0bryne.no\0"
-"ogliastra.it\0"
-"ando.nara.jp\0yao.osaka.jp\0go.ug\0"
-"o.se\0"
-"go.tz\0is-a-financialadvisor.com\0"
-"kawamata.fukushima.jp\0"
-"honjyo.akita.jp\0dealer\0"
-"orkdal.no\0"
-"lindesnes.no\0wedding\0"
-"trentinosudtirol.it\0"
-"namsos.no\0\xd0\xbc\xd0\xbe\xd0\xbd\0"
-"nokia\0"
-"onomichi.hiroshima.jp\0"
-"tagawa.fukuoka.jp\0"
-"blogspot.com\0"
-"nb.ca\0"
-"is-a-photographer.com\0"
-"qsl.br\0tarumizu.kagoshima.jp\0"
-"volkenkunde.museum\0"
-"fin.ec\0"
-"tuscany.it\0vicenza.it\0"
-"akita.jp\0"
-"brussels.museum\0"
-"jab.br\0inc\0"
-"k12.tx.us\0"
-"s3-website.eu-central-1.amazonaws.com\0"
-"ing\0barsy.me\0"
-"no.eu.org\0"
-"uchihara.ibaraki.jp\0"
-"fuso.aichi.jp\0v\xc3\xa1rgg\xc3\xa1t.no\0ink\0"
-"chuo.chiba.jp\0barsy.org\0"
-"oamishirasato.chiba.jp\0hokuryu.hokkaido.jp\0"
-"oz.au\0ogawa.saitama.jp\0oshino.yamanashi.jp\0"
-"bosch\0"
-"kamiizumi.saitama.jp\0"
-"int\0"
-"histoire.museum\0yolasite.com\0"
-"\xe7\xa6\x8f\xe5\xb3\xb6.jp\0lea\xc5\x8bgaviika.no\0"
-"schlesisches.museum\0"
-"surf\0"
-"smile\0pgafan.net\0"
-"toda.saitama.jp\0babia-gora.pl\0"
-"stuff-4-sale.us\0"
-"k12.ia.us\0apps.fbsbx.com\0flynnhosting.net\0"
-"sund.no\0phone\0"
-"skjak.no\0"
-"\xc3\xb8rland.no\0"
-"blanco\0whoswho\0alpha.bounty-full.com\0"
-"lombardia.it\0whaling.museum\0"
-"tomari.hokkaido.jp\0"
-"naturalhistorymuseum.museum\0from-fl.com\0"
-"brasil.museum\0sibenik.museum\0"
-"lib.tn.us\0"
-"castres.museum\0"
-"consulting.aero\0"
-"countryestate.museum\0olecko.pl\0immo\0appchizi.com\0"
-"twmail.org\0"
-"ohda.shimane.jp\0"
-"shimoji.okinawa.jp\0"
-"mus.br\0expert\0"
-"tatsuno.nagano.jp\0kawazu.shizuoka.jp\0"
-"santafe.museum\0"
-"lighting\0"
-"valleedaoste.it\0kazuno.akita.jp\0"
-"is-a-bulls-fan.com\0"
-"nishiawakura.okayama.jp\0"
-"livinghistory.museum\0bar.pro\0"
-"shirakawa.gifu.jp\0sanuki.kagawa.jp\0carrier.museum\0"
-"k12.ky.us\0\xe6\x94\xbf\xe5\xba\x9c.\xe9\xa6\x99\xe6\xb8\xaf\0"
-"now-dns.net\0"
-"cn-northwest-1.eb.amazonaws.com.cn\0"
-"tsuiki.fukuoka.jp\0"
-"fylkesbibl.no\0"
-"jcb\0"
-"teva\0"
-"tksat.bo\0"
-"saijo.ehime.jp\0kawajima.saitama.jp\0"
-"oguni.kumamoto.jp\0"
-"grp.lk\0"
-"hk.org\0"
-"bingo\0jcp\0"
-"narusawa.yamanashi.jp\0"
-"balat.no\0"
-"ujitawara.kyoto.jp\0\xc3\xb8stre-toten.no\0"
-"urbino-pesaro.it\0hamada.shimane.jp\0mo-i-rana.no\0ist\0"
-"nz.eu.org\0"
-"is-an-actor.com\0"
-"asker.no\0extraspace\0from-ri.com\0"
-"gaular.no\0"
-"aizubange.fukushima.jp\0"
-"cr.ua\0"
-"ashiya.hyogo.jp\0"
-"athleta\0s3.dualstack.ca-central-1.amazonaws.com\0"
-"akkeshi.hokkaido.jp\0itv\0"
-"solutions\0"
-"rome.it\0"
-"sagae.yamagata.jp\0atm.pl\0"
-"tanabe.kyoto.jp\0"
-"m.bg\0azurewebsites.net\0"
-"georgia.museum\0"
-"salem.museum\0"
-"shiranuka.hokkaido.jp\0yoshikawa.saitama.jp\0"
-"kumagaya.saitama.jp\0"
-"\xe7\xbe\xa4\xe9\xa6\xac.jp\0s3-us-gov-west-1.amazonaws.com\0"
-"rankoshi.hokkaido.jp\0hosting\0"
-"hotmail\0"
-"stockholm.museum\0"
-"flickr\0"
-"is-with-theband.com\0"
-"catholic\0"
-"snaase.no\0barsy.uk\0"
-"london\0photo\0"
-"minowa.nagano.jp\0skole.museum\0trana.no\0"
-"kiryu.gunma.jp\0orsta.no\0"
-"science.museum\0"
-"rendalen.no\0"
-"nozawaonsen.nagano.jp\0pccw\0"
+"interactive.museum\0norfolk.museum\0\xd7\x99\xd7\xa8\xd7\x95\xd7\xa9\xd7\x9c\xd7\x99\xd7\x9d.museum\0"
+"reggio-calabria.it\0"
+"gs.svalbard.no\0"
+"alibaba\0"
+"priv.no\0sch.qa\0"
+"sobetsu.hokkaido.jp\0fail\0"
+"dominic.ua\0cy.eu.org\0goip.de\0"
+"iz.hr\0square7.net\0"
+"pe.ca\0masfjorden.no\0"
+"tamayu.shimane.jp\0"
+"padua.it\0static.land\0"
+"marumori.miyagi.jp\0kamitonda.wakayama.jp\0hkt\0"
+"aure.no\0onyourside\0"
+"*.kobe.jp\0chihayaakasaka.osaka.jp\0lgbt\0"
+"misconfused.org\0"
+"canada.museum\0blogspot.co.za\0"
+"itoman.okinawa.jp\0nakaniikawa.toyama.jp\0"
+"avocat.fr\0jeep\0"
+"trana.no\0"
+"rel.ht\0"
+"meraker.no\0km.ua\0"
+"academy.museum\0miniserver.com\0"
+"jevnaker.no\0"
+"harstad.no\0"
+"abruzzo.it\0hashbang.sh\0"
+"sch.sa\0"
+"nic.in\0"
+"ah.no\0cz.eu.org\0"
+"tranby.no\0"
+"kunitachi.tokyo.jp\0"
+"priv.me\0"
+"kibichuo.okayama.jp\0mugi.tokushima.jp\0"
+"si.eu.org\0app.os.stg.fedoraproject.org\0"
+"minamiechizen.fukui.jp\0tsubetsu.hokkaido.jp\0"
+"ostre-toten.no\0orange\0"
+"nakatsugawa.gifu.jp\0"
+"vs.it\0smart\0"
+"cologne\0"
+"tsuruga.fukui.jp\0"
+"ln.cn\0"
+"loans\0"
+"fukusaki.hyogo.jp\0"
+"lavagis.no\0cloudns.eu\0"
+"itami.hyogo.jp\0wroclaw.pl\0cool\0"
+"nico\0"
+"udi.br\0tsuno.kochi.jp\0nowaruda.pl\0"
+"coop\0"
+"e.bg\0"
+"eu-west-2.elasticbeanstalk.com\0dk.eu.org\0"
+"wv.us\0"
+"namerikawa.toyama.jp\0"
"lyngdal.no\0"
-"pa.gov.br\0frosta.no\0vaga.no\0wskr.gov.pl\0"
-"shirosato.ibaraki.jp\0os\xc3\xb8yro.no\0"
-"rikubetsu.hokkaido.jp\0"
-"mihama.wakayama.jp\0"
-"porsgrunn.no\0"
-"unzen.nagasaki.jp\0"
-"*.yokohama.jp\0etne.no\0zgora.pl\0"
-"archaeology.museum\0"
-"agrigento.it\0"
-"watch\0"
-"hasami.nagasaki.jp\0"
-"mr.no\0"
-"kashiwara.osaka.jp\0rhcloud.com\0"
-"\xe7\xb6\xb2\xe7\xb5\xa1.\xe9\xa6\x99\xe6\xb8\xaf\0koeln\0"
-"orkanger.no\0read\0"
-"infiniti\0"
-"pb.gov.br\0"
-"horten.no\0"
-"us.org\0"
-"jio\0"
-"dlugoleka.pl\0"
-"osaki.miyagi.jp\0synology-ds.de\0"
-"industries\0gotdns.org\0"
-"pittsburgh.museum\0"
-"info\0"
-"kuki.saitama.jp\0"
-"trentinosued-tirol.it\0yokaichiba.chiba.jp\0nagano.nagano.jp\0taobao\0"
-"aeroport.fr\0linde\0"
-"dsmynas.org\0"
-"showtime\0"
-"farm.museum\0"
-"zj.cn\0osakikamijima.hiroshima.jp\0shari.hokkaido.jp\0"
-"solar\0"
-"ishigaki.okinawa.jp\0pa.leg.br\0"
-"mad.museum\0name\0degree\0myqnapcloud.com\0"
-"\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb8\0"
-"avellino.it\0c.cdn77.org\0"
-"coupon\0"
-"saarland\0"
-"ranzan.saitama.jp\0biev\xc3\xa1t.no\0freebox-os.fr\0"
-"itami.hyogo.jp\0hokuto.yamanashi.jp\0"
-"saka.hiroshima.jp\0palace.museum\0"
-"khmelnitskiy.ua\0capital\0"
-"kuji.iwate.jp\0"
-"koshimizu.hokkaido.jp\0green\0"
-"nu.ca\0"
-"ah.cn\0"
-"ofunato.iwate.jp\0jlc\0qa2.com\0"
-"jll\0familyds.net\0"
-"donetsk.ua\0"
-"\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0"
-"\xe7\xb6\xb2\xe7\xb5\xa1.cn\0samsung\0"
-"k12.vi.us\0verm\xc3\xb6gensberater\0pb.leg.br\0"
-"otsuki.yamanashi.jp\0"
-"biella.it\0"
-"fin.tn\0"
-"hirakata.osaka.jp\0database.museum\0"
-"airguard.museum\0loseyourip.com\0"
-"jor.br\0"
-"ip6.arpa\0"
-"genoa.it\0"
-"luroy.no\0"
-"usarts.museum\0jmp\0"
-"g\xc3\xa1\xc5\x8bgaviika.no\0"
-"domains\0""16-b.it\0"
-"b\xc3\xa6rum.no\0"
-"servebbs.com\0"
-"kamagaya.chiba.jp\0jnj\0"
-"my-router.de\0"
-"yaizu.shizuoka.jp\0walter\0"
-"hyllestad.no\0"
-"kai.yamanashi.jp\0"
-"beauty\0"
-"msk.ru\0"
-"0.bg\0vpndns.net\0"
-"tomioka.gunma.jp\0botanical.museum\0gjemnes.no\0"
-"\xe9\xa3\x9e\xe5\x88\xa9\xe6\xb5\xa6\0"
-"aisai.aichi.jp\0ayagawa.kagawa.jp\0mosjoen.no\0schmidt\0"
-"noshiro.akita.jp\0kunimi.fukushima.jp\0witd.gov.pl\0"
-"chieti.it\0fujisawa.kanagawa.jp\0"
-"cityeats\0"
-"naturalhistory.museum\0"
-"kobierzyce.pl\0jot\0msk.su\0"
-"yoshimi.saitama.jp\0giize.com\0forumz.info\0"
-"montreal.museum\0sherbrooke.museum\0"
-"kawahara.tottori.jp\0intelligence.museum\0"
-"rishirifuji.hokkaido.jp\0bern.museum\0statoil\0"
-"gov.ac\0joy\0"
-"gov.ae\0porsangu.no\0gmbh\0homelinux.net\0"
-"gov.af\0ilovecollege.info\0"
-"school.za\0"
-"iruma.saitama.jp\0"
-"hembygdsforbund.museum\0"
-"yufu.oita.jp\0zarow.pl\0"
-"gov.al\0"
-"rio.br\0"
-"gov.ba\0guernsey.museum\0"
-"gov.ar\0gov.bb\0"
-"aerodrome.aero\0gov.as\0beeldengeluid.museum\0"
-"gov.au\0"
-"gov.bf\0\xe7\xb6\xb2\xe7\xb5\xa1.hk\0"
-"matsumae.hokkaido.jp\0"
-"gov.bh\0\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82\0"
-"gov.az\0azurecontainer.io\0"
-"takaoka.toyama.jp\0calvinklein\0"
-"gov.bm\0pinb.gov.pl\0"
-"gov.bn\0"
-"reit\0wellbeingzone.co.uk\0"
-"\xe7\xa5\x9e\xe5\xa5\x88\xe5\xb7\x9d.jp\0"
-"gov.br\0"
-"gov.bs\0"
-"gov.bt\0gov.cd\0"
-"gov.by\0children.museum\0gorge.museum\0"
-"gov.bz\0"
-"scientist.aero\0"
-"gov.cl\0nu.it\0"
-"gov.cm\0"
-"gov.cn\0"
-"gov.co\0"
-"cloudcontrolapp.com\0"
-"legnica.pl\0barsy.bg\0"
-"gov.cu\0"
-"karacol.su\0"
-"aviation.museum\0"
-"gov.cx\0"
-"gov.cy\0"
-"ski.no\0"
-"gov.dm\0lib.nh.us\0"
-"gov.do\0oizumi.gunma.jp\0"
-"sb.ua\0"
-"kawagoe.saitama.jp\0seljord.no\0"
-"wloclawek.pl\0"
-"gov.ec\0"
-"yokoze.saitama.jp\0"
-"gov.ee\0"
-"gov.eg\0"
-"black\0armenia.su\0"
-"gov.dz\0"
-"kyowa.hokkaido.jp\0kurotaki.nara.jp\0"
-"kadogawa.miyazaki.jp\0network\0"
-"navy\0"
-"yokkaichi.mie.jp\0kounosu.saitama.jp\0mup.gov.pl\0barsy.de\0"
-"kihoku.ehime.jp\0takahata.yamagata.jp\0"
-"gov.et\0"
-"andria-trani-barletta.it\0"
-"botanicalgarden.museum\0askim.no\0k12.co.us\0"
-"leg.br\0"
-"kpmg\0"
-"automotive.museum\0hb.cldmail.ru\0"
-"catanzaro.it\0"
-"audnedaln.no\0"
-"jx.cn\0"
-"shima.mie.jp\0"
-"kfh\0ddns.net\0"
-"staples\0"
-"gov.ge\0m.se\0"
-"gov.gh\0umbria.it\0"
-"gov.gi\0"
-"blogsite.org\0"
-"ah.no\0"
-"gov.gn\0"
-"bas.it\0rent\0"
-"barsy.eu\0"
-"gov.gr\0"
-"pi.gov.br\0"
-"gov.gu\0"
+"hot\0"
+"how\0"
+"us-west-2.elasticbeanstalk.com\0"
"oyama.tochigi.jp\0"
-"gov.gy\0"
-"gov.hk\0"
-"eng.br\0mp.br\0krakow.pl\0"
-"te.it\0merckmsd\0"
-"yamada.fukuoka.jp\0iwamizawa.hokkaido.jp\0"
-"miyazu.kyoto.jp\0bungoono.oita.jp\0citi\0"
-"kouyama.kagoshima.jp\0"
-"evje-og-hornnes.no\0mt.eu.org\0"
-"aseral.no\0"
-"gov.ie\0utwente.io\0"
-"ryugasaki.ibaraki.jp\0"
-"togane.chiba.jp\0hirata.fukushima.jp\0"
-"sayo.hyogo.jp\0"
-"iki.nagasaki.jp\0pharmacy\0"
-"kia\0"
-"gov.il\0ambulance.museum\0"
-"\xe7\xbb\x84\xe7\xbb\x87.hk\0"
-"gov.in\0"
-"wales.museum\0city\0"
-"gov.iq\0"
-"gov.ir\0ise.mie.jp\0"
-"gov.is\0"
-"gov.it\0"
-"otaru.hokkaido.jp\0"
-"kim\0"
-"sklep.pl\0szkola.pl\0"
-"gov.jo\0gifu.jp\0"
-"farmers.museum\0"
-"kadoma.osaka.jp\0"
-"semine.miyagi.jp\0"
-"akiruno.tokyo.jp\0eating-organic.net\0"
-"glade\0"
-"anjo.aichi.jp\0"
-"piacenza.it\0gov.kg\0cable-modem.org\0"
-"kiso.nagano.jp\0"
-"gov.ki\0"
-"pi.leg.br\0barsy.in\0"
-"barsy.io\0"
-"gov.km\0"
-"gov.kn\0"
-"yaita.tochigi.jp\0tokushima.tokushima.jp\0gov.kp\0jan-mayen.no\0ap-northeast-1.elasticbeanstalk.com\0mytuleap.com\0"
-"gov.la\0"
-"gov.lb\0"
-"gov.lc\0"
-"\xe5\xb2\xa9\xe6\x89\x8b.jp\0landes.museum\0"
-"tourism.tn\0"
-"gov.kw\0"
-"v-info.info\0"
-"maizuru.kyoto.jp\0gov.ky\0"
-"gov.kz\0"
-"gov.lk\0"
-"barrel-of-knowledge.info\0"
-"rest\0"
-"gov.ma\0"
-"gov.lr\0finn\xc3\xb8y.no\0"
-"gov.lt\0baidu\0"
-"gov.me\0"
-"gov.lv\0tana.no\0"
-"gov.mg\0"
-"judaica.museum\0"
-"gov.ly\0"
-"gov.mk\0"
-"gov.ml\0"
-"gov.mn\0"
-"gov.mo\0"
-"ski.museum\0"
-"politica.bo\0tagami.niigata.jp\0"
-"gov.mr\0"
-"gov.ms\0"
-"ascolipiceno.it\0"
-"ujiie.tochigi.jp\0gov.mu\0"
-"gov.mv\0"
-"force.museum\0gov.mw\0gov.ng\0"
-"ogata.akita.jp\0"
-"gov.my\0"
-"gov.mz\0\xd0\xbe\xd1\x80\xd0\xb3\0"
-"sassari.it\0"
-"off.ai\0pueblo.bo\0dnsiskinky.com\0"
-"\xd1\x83\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0"
-"hellas.museum\0virtual.museum\0"
-"york.museum\0gov.nr\0"
-"s3-ap-northeast-1.amazonaws.com\0redirectme.net\0"
-"amfam\0"
-"toyama.jp\0"
-"baidar.no\0roan.no\0doomdns.com\0"
-"broadway\0"
-"aomori.jp\0"
-"carraramassa.it\0"
-"building.museum\0"
-"gov.om\0"
-"kumejima.okinawa.jp\0"
-"dolls.museum\0"
-"yamagata.yamagata.jp\0evenes.no\0"
-"k12.al.us\0"
-"pe.gov.br\0minami-alps.yamanashi.jp\0"
-"gov.ph\0"
-"shimada.shizuoka.jp\0nachikatsuura.wakayama.jp\0interactive.museum\0"
-"kamifurano.hokkaido.jp\0"
-"gov.pk\0coupons\0report\0"
-"gov.pl\0k12.mo.us\0exchange\0"
-"tysvar.no\0gov.pn\0"
-"frontier\0"
-"gov.qa\0"
-"misaki.okayama.jp\0gov.pr\0mlbfan.org\0"
-"shop.ht\0kvinesdal.no\0gov.ps\0"
-"k.bg\0shop.hu\0gov.pt\0fh.se\0"
-"tsukuba.ibaraki.jp\0lier.no\0"
-"brussel.museum\0"
-"\xe5\xa4\xa7\xe5\x88\x86.jp\0kpn\0"
-"gov.py\0"
-"lutsk.ua\0"
-"*.uberspace.de\0"
-"barsycenter.com\0"
-"mukawa.hokkaido.jp\0stalbans.museum\0"
-"okinoshima.shimane.jp\0"
+"bellevue.museum\0"
+"nyc.mn\0"
+"fans\0style\0"
+"\xd9\x81\xd9\x84\xd8\xb3\xd8\xb7\xd9\x8a\xd9\x86\0"
+"cl.it\0"
+"sevastopol.ua\0"
+"okutama.tokyo.jp\0"
+"stateofdelaware.museum\0"
+"dyndns-work.com\0"
+"sel.no\0co.technology\0"
+"kwpsp.gov.pl\0"
+"engine.aero\0design.museum\0"
+"sorreisa.no\0sk.eu.org\0"
+"vardo.no\0"
+"karumai.iwate.jp\0akishima.tokyo.jp\0itabashi.tokyo.jp\0"
+"sue.fukuoka.jp\0"
+"\xe6\x94\xbf\xe5\x8a\xa1\0"
+"cloudns.in\0"
+"ibm\0"
+"ba.gov.br\0cesena-forli.it\0hekinan.aichi.jp\0moriyoshi.akita.jp\0"
+"inderoy.no\0"
+"brindisi.it\0"
+"dyndns.ddnss.de\0"
+"pe.it\0"
+"dyroy.no\0ice\0"
+"\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4\0"
+"filegear-ie.me\0"
+"simple-url.com\0"
+"de.eu.org\0"
+"hazu.aichi.jp\0"
+"riodejaneiro.museum\0cloudns.cc\0"
+"beardu.no\0"
+"bulsan.it\0"
+"arendal.no\0icu\0dynamisches-dns.de\0"
+"rel.pl\0"
+"sa.gov.au\0barsycenter.com\0"
+"codes\0"
+"takayama.gunma.jp\0olsztyn.pl\0"
+"za.com\0"
+"mamurogawa.yamagata.jp\0"
+"intelligence.museum\0\xc3\xb8stre-toten.no\0farm\0"
+"\xc3\xa1k\xc5\x8boluokta.no\0"
+"pe.kr\0"
+"mer\xc3\xa5ker.no\0"
+"dental\0"
+"sch.zm\0"
+"yosemite.museum\0dyndns.org\0"
+"katsuyama.fukui.jp\0"
+"x.se\0afamilycompany\0vacations\0"
+"rieti.it\0"
+"ru.eu.org\0se.eu.org\0"
+"kounosu.saitama.jp\0fast\0"
+"bill.museum\0"
+"akabira.hokkaido.jp\0"
+"matsuno.ehime.jp\0fbxos.fr\0"
+"\xe6\x95\x8e\xe8\x82\xb2.hk\0\xd1\x81\xd1\x80\xd0\xb1\0wedeploy.io\0"
+"achi.nagano.jp\0"
+"ifm\0nike\0"
+"happou.akita.jp\0"
+"gleeze.com\0"
+"airforce\0hk.org\0"
+"k12.wy.us\0"
+"rr.gov.br\0tawaramoto.nara.jp\0"
+"mansion.museum\0ulvik.no\0tunk.org\0"
+"venezia.it\0"
+"tel.tr\0"
+"iwata.shizuoka.jp\0incheon.kr\0"
+"castle.museum\0bostik\0"
+"fhs.no\0h\xc3\xa5.no\0"
+"nishiawakura.okayama.jp\0tabuse.yamaguchi.jp\0wskr.gov.pl\0"
+"\xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\0*.compute.amazonaws.com\0webhop.me\0"
+"karasuyama.tochigi.jp\0"
+"zushi.kanagawa.jp\0"
+"homeunix.com\0"
+"trentino-sud-tirol.it\0"
+"christmas\0"
+"val-daosta.it\0iwakuni.yamaguchi.jp\0"
+"joburg\0"
+"nic.tj\0"
+"jab.br\0*.kitakyushu.jp\0"
+"donostia.museum\0kvinnherad.no\0"
+"\xd0\xba\xd0\xb0\xd1\x82\xd0\xbe\xd0\xbb\xd0\xb8\xd0\xba\0"
+"eti.br\0aizuwakamatsu.fukushima.jp\0kitakami.iwate.jp\0"
+"belau.pw\0philips\0sa.com\0"
+"cuiaba.br\0kamiichi.toyama.jp\0"
+"her\xc3\xb8y.m\xc3\xb8re-og-romsdal.no\0vaksdal.no\0"
+"rs.gov.br\0sc.gov.br\0asti.it\0"
+"historisches.museum\0"
+"nhs.uk\0flynnhub.com\0"
+"soo.kagoshima.jp\0"
+"pesarourbino.it\0"
+"flekkefjord.no\0"
+"americana.museum\0leangaviika.no\0torsken.no\0"
+"zp.gov.pl\0center\0"
+"myhome-server.de\0"
+"rmit\0"
+"hdfc\0\xe4\xb8\xad\xe4\xbf\xa1\0familyds.com\0"
+"srv.br\0milan.it\0tosu.saga.jp\0"
+"forgot.his.name\0"
+"am.gov.br\0turen.tn\0"
+"groks-the.info\0"
+"h\xc3\xa1pmir.no\0"
+"fujikawa.shizuoka.jp\0"
+"tsukuba.ibaraki.jp\0kitadaito.okinawa.jp\0"
+"ri.it\0"
+"*.nom.br\0okazaki.aichi.jp\0izumo.shimane.jp\0"
+"airline.aero\0ca.eu.org\0logoip.com\0"
+"bi.it\0museum.tt\0"
+"natori.miyagi.jp\0"
+"namsskogan.no\0macys\0"
+"sondre-land.no\0"
+"historisch.museum\0"
+"imari.saga.jp\0homedepot\0"
+"shoes\0"
+"kharkov.ua\0from-nj.com\0"
"kawakita.ishikawa.jp\0"
-"udi.br\0"
-"gwiddle.co.uk\0"
-"krd\0lat\0"
-"barsy.online\0"
-"hasama.oita.jp\0koebenhavn.museum\0"
-"higashiosaka.osaka.jp\0gov.sa\0law\0"
-"gov.sb\0my.eu.org\0"
-"sanjo.niigata.jp\0gov.rs\0gov.sc\0"
-"susaki.kochi.jp\0porsanger.no\0gov.sd\0"
-"aga.niigata.jp\0gov.ru\0"
-"obira.hokkaido.jp\0"
-"gov.rw\0gov.sg\0"
-"gov.sh\0"
-"pe.leg.br\0"
-"aichi.jp\0te.ua\0"
-"gov.sl\0"
-"okinawa.okinawa.jp\0coach\0"
-"tjeldsund.no\0"
-"shoo.okayama.jp\0"
-"gov.st\0"
-"valle\xcc\x81""eaoste.it\0"
-"gov.sx\0"
-"gov.sy\0"
-"gov.tj\0"
-"gov.tl\0"
-"laspezia.it\0kragero.no\0gov.tm\0"
-"gov.tn\0"
-"gov.to\0"
-"gov.ua\0"
-"gov.tr\0"
-"k12.fl.us\0"
-"davvenj\xc3\xa1rga.no\0konskowola.pl\0gov.tt\0"
-"fukushima.hokkaido.jp\0boomla.net\0"
+"fedorainfracloud.org\0"
+"osasco.br\0friuli-vgiulia.it\0"
+"cymru\0"
+"washtenaw.mi.us\0"
+"tsuyama.okayama.jp\0boston\0"
+"tokai.ibaraki.jp\0"
+"sherbrooke.museum\0virtuel.museum\0"
+"tm.cy\0inc\0"
+"scholarships\0bryansk.su\0"
+"komoro.nagano.jp\0kunigami.okinawa.jp\0"
+"lib.al.us\0ing\0"
+"uryu.hokkaido.jp\0"
+"cc.ri.us\0ink\0"
+"turystyka.pl\0"
+"directory\0"
+"cloudns.us\0"
+"rn.gov.br\0int\0"
+"kutchan.hokkaido.jp\0"
+"verran.no\0"
+"lib.me.us\0"
+"oristano.it\0"
+"bolivia.bo\0"
+"group\0"
+"play\0"
+"e.se\0erni\0"
+"ome.tokyo.jp\0"
+"chicago.museum\0steiermark.museum\0"
+"tm.fr\0yachimata.chiba.jp\0beppu.oita.jp\0"
+"camdvr.org\0hb.cldmail.ru\0"
+"ap.gov.br\0"
+"omi.nagano.jp\0"
+"eiheiji.fukui.jp\0"
+"ro.gov.br\0seirou.niigata.jp\0nishinoshima.shimane.jp\0"
+"somna.no\0"
+"setouchi.okayama.jp\0"
+"iris.arpa\0ravendb.community\0uklugs.org\0"
+"fuji.shizuoka.jp\0gmina.pl\0"
+"dvrdns.org\0"
+"joboji.iwate.jp\0"
+"gs.tm.no\0cd.eu.org\0"
+"kawazu.shizuoka.jp\0"
+"mo.cn\0chiyoda.tokyo.jp\0"
+"dh.bytemark.co.uk\0"
+"asahi.ibaraki.jp\0tsu.mie.jp\0"
+"ap.gov.pl\0total\0"
+"v.bg\0bus.museum\0namsos.no\0"
+"nanmoku.gunma.jp\0bel.tr\0"
+"tm.hu\0"
+"drobak.no\0mex.com\0"
+"hikone.shiga.jp\0jcb\0"
+"malvik.no\0agric.za\0wang\0fastvps-server.com\0"
+"is-a-chef.org\0"
+"prato.it\0*.cryptonomic.net\0"
+"!city.kitakyushu.jp\0"
+"\xd9\x85\xd9\x88\xd8\xa8\xd8\xa7\xd9\x8a\xd9\x84\xd9\x8a\0"
+"mayfirst.org\0"
+"shirosato.ibaraki.jp\0izumisano.osaka.jp\0kiyose.tokyo.jp\0jcp\0"
+"omasvuotna.no\0"
+"schokoladen.museum\0official.academy\0"
+"togane.chiba.jp\0yotsukaido.chiba.jp\0ist\0"
+"wa.au\0clothing\0"
+"hongo.hiroshima.jp\0"
+"services.aero\0tas.au\0rivne.ua\0"
"her\xc3\xb8y.nordland.no\0"
-"gov.tw\0"
-"mywire.org\0"
+"conference.aero\0"
+"andriatranibarletta.it\0museum.mv\0"
+"museum.mw\0is-a-therapist.com\0"
+"itv\0"
+"tm.km\0"
+"pomorskie.pl\0dyndns.tv\0"
+"bonn.museum\0"
+"kiyosato.hokkaido.jp\0"
+"museum.no\0"
+"nagato.yamaguchi.jp\0"
+"casacam.net\0"
+"bamble.no\0"
+"pv.it\0"
"is-a-candidate.org\0"
-"boehringer\0"
-"uto.kumamoto.jp\0gov.uk\0"
-"ena.gifu.jp\0pa.gov.pl\0lds\0"
-"kv\xc3\xa6nangen.no\0"
-"kvafjord.no\0gov.vc\0visa\0"
-"loginto.me\0"
-"gov.ve\0"
-"zoological.museum\0"
-"trentin-sud-tirol.it\0sandoy.no\0panasonic\0"
-"salat.no\0futuremailing.at\0"
-"gov.vn\0"
-"bardu.no\0"
-"scjohnson\0"
-"inabe.mie.jp\0aigo\0"
-"ibaraki.jp\0"
-"ns.ca\0"
-"land\0"
-"mandal.no\0now-dns.org\0"
-"bokn.no\0"
-"\xe7\xa7\xbb\xe5\x8a\xa8\0s3-website-sa-east-1.amazonaws.com\0"
-"fukumitsu.toyama.jp\0stada\0"
-"recht.pro\0"
-"asahi.chiba.jp\0"
-"vibo-valentia.it\0"
-"kh.ua\0"
-"nasu.tochigi.jp\0leka.no\0sorfold.no\0gov.ws\0yombo.me\0"
-"tourism.pl\0"
-"h\xc3\xa1""bmer.no\0onion\0"
-"abbvie\0"
-"yamaxun\0"
-"tra.kp\0gs.aa.no\0net-freaks.com\0"
-"kujukuri.chiba.jp\0fukagawa.hokkaido.jp\0"
-"nl.eu.org\0"
-"takaharu.miyazaki.jp\0viva\0"
-"mydatto.com\0"
-"is.it\0lifestyle\0"
-"yamanakako.yamanashi.jp\0"
-"itano.tokushima.jp\0"
-"cc.in.us\0"
-"zgorzelec.pl\0"
-"br.com\0"
-"far.br\0lib.ee\0notodden.no\0"
-"gov.za\0vivo\0"
-"act.au\0pr.gov.br\0nanbu.tottori.jp\0"
-"moseushi.hokkaido.jp\0"
-"padua.it\0susono.shizuoka.jp\0"
-"ciscofreak.com\0"
-"karm\xc3\xb8y.no\0"
-"vang.no\0"
-"haibara.shizuoka.jp\0"
-"gov.zm\0lotte\0"
-"kiho.mie.jp\0valley.museum\0"
-"cambridge.museum\0"
-"mol.it\0vagan.no\0glass\0"
-"info.gu\0"
-"takayama.nagano.jp\0"
-"ox.rs\0"
-"gov.zw\0lotto\0"
-"zlg.br\0bungotakada.oita.jp\0"
-"dabur\0kyoto\0"
-"hawaii.museum\0"
-"ninohe.iwate.jp\0"
-"info.ht\0"
-"info.hu\0"
-"makinohara.shizuoka.jp\0"
-"dazaifu.fukuoka.jp\0"
-"bellevue.museum\0nativeamerican.museum\0theater\0"
-"llc\0"
-"k12.md.us\0courses\0"
-"tas.gov.au\0shiki.saitama.jp\0eu.meteorapp.com\0"
-"educator.aero\0"
-"info.et\0sakura\0"
-"egersund.no\0homelinux.org\0js.org\0"
-"is-a-techie.com\0pr.leg.br\0"
-"mobile\0"
-"field.museum\0hamaroy.no\0"
-"production.aero\0takamatsu.kagawa.jp\0wallonie.museum\0philips\0"
-"ostroda.pl\0tgory.pl\0"
-"\xd0\xb8\xd0\xba\xd0\xbe\xd0\xbc.museum\0"
-"basketball\0"
-"emb.kw\0"
-"idf.il\0securitytactics.com\0"
-"manaus.br\0hof.no\0"
-"austrheim.no\0"
-"kred\0"
-"noheji.aomori.jp\0my-vigor.de\0"
-"firenze.it\0"
-"dnsdojo.com\0"
-"giehtavuoatna.no\0"
-"inder\xc3\xb8y.no\0"
-"mobily\0"
-"tiaa\0"
-"azumino.nagano.jp\0nesset.no\0"
-"ng.eu.org\0dsmynas.net\0"
-"hn.cn\0\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4\0"
-"\xe7\xa6\x8f\xe4\xba\x95.jp\0kashiwazaki.niigata.jp\0"
-"no-ip.ca\0"
-"info.cx\0"
-"hakata.fukuoka.jp\0"
-"m\xc3\xa5s\xc3\xb8y.no\0lib.nj.us\0"
-"trentinosu\xcc\x88""d-tirol.it\0"
-"info.ec\0higashimurayama.tokyo.jp\0stateofdelaware.museum\0"
-"yachiyo.ibaraki.jp\0"
-"tamakawa.fukushima.jp\0"
-"parma.it\0firewall-gateway.com\0"
-"psc.br\0lol\0"
-"cn.it\0"
-"cloud\0servemp3.com\0"
-"\xe7\xbb\x84\xe7\xbb\x87\xe6\x9c\xba\xe6\x9e\x84\0"
-"nsn.us\0azure-mobile.net\0"
-"aurskog-holand.no\0"
-"eniwa.hokkaido.jp\0"
-"info.bb\0parti.se\0"
-"info.at\0"
-"info.au\0gs.vf.no\0"
-"bari.it\0k12.de.us\0"
-"lpl\0"
-"palermo.it\0farmstead.museum\0"
-"info.az\0familyds.org\0"
-"engerdal.no\0"
-"info.bo\0inf.br\0"
-"\xd8\xb9\xd8\xb1\xd8\xa8\0"
-"nakadomari.aomori.jp\0"
-"minamiechizen.fukui.jp\0k.se\0"
-"lib.or.us\0"
-"north.museum\0rahkkeravju.no\0"
-"mallorca.museum\0"
-"man\0"
-"chonan.chiba.jp\0bo.nordland.no\0"
-"hayashima.okayama.jp\0map\0paris.eu.org\0"
-"lavagis.no\0\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0mba\0"
-"bifuka.hokkaido.jp\0"
-"info.co\0meiwa.mie.jp\0"
-"b\xc3\xa1id\xc3\xa1r.no\0"
-"inf.cu\0"
-"ozu.ehime.jp\0storage\0from-oh.com\0"
-"tx.us\0"
-"lima-city.rocks\0"
-"nagasu.kumamoto.jp\0"
-"ss.it\0"
-"okawa.kochi.jp\0"
-"trapani.it\0"
-"izumi.kagoshima.jp\0svelvik.no\0"
-"rightathome\0"
-"storfjord.no\0"
-"tajimi.gifu.jp\0"
-"otari.nagano.jp\0ltd\0"
-"lubin.pl\0"
-"yahaba.iwate.jp\0uzhgorod.ua\0"
-"davvenjarga.no\0"
-"engine.aero\0"
-"is-a-caterer.com\0"
-"huissier-justice.fr\0fjaler.no\0"
-"kasumigaura.ibaraki.jp\0"
-"cc.hi.us\0"
-"reggiocalabria.it\0med\0"
-"shimonoseki.yamaguchi.jp\0"
-"rygge.no\0"
-"press.cy\0static-access.net\0"
-"from-md.com\0"
-"mantova.it\0"
-"men\0"
-"l\xc3\xb8""dingen.no\0"
-"lib.ga.us\0"
-"valle\xcc\x81""e-aoste.it\0childrens.museum\0"
-"uozu.toyama.jp\0"
-"matsumoto.nagano.jp\0oita.oita.jp\0"
-"shop.ro\0"
-"dyndns-home.com\0"
-"balsan-suedtirol.it\0hyundai\0"
-"k12.vt.us\0"
-"natuurwetenschappen.museum\0"
-"kvits\xc3\xb8y.no\0"
-"sekikawa.niigata.jp\0piw.gov.pl\0"
-"stockholm\0tkmaxx\0"
-"santacruz.museum\0"
-"realestate\0dd-dns.de\0"
-"\xe7\xb6\xb2\xe7\xbb\x9c.hk\0"
-"sdn.gov.pl\0"
-"nowaruda.pl\0nat.tn\0cartier\0mangyshlak.su\0"
-"shop.pl\0"
-"emergency.aero\0"
-"shonai.yamagata.jp\0"
-"sakai.ibaraki.jp\0"
-"shangrila\0"
-"development.run\0"
-"office-on-the.net\0"
-"tenkawa.nara.jp\0"
-"sweetpepper.org\0"
-"yomitan.okinawa.jp\0bus.museum\0philadelphiaarea.museum\0po.gov.pl\0"
-"\xe5\xb1\xb1\xe5\x8f\xa3.jp\0bamble.no\0"
-"from-ca.com\0"
-"friuli-vegiulia.it\0"
-"tv.bb\0"
-"aquila.it\0"
-"art.br\0mil\0"
-"mn.it\0"
-"ponpes.id\0"
-"mit\0fastpanel.direct\0"
-"cc.mi.us\0vlaanderen\0"
-"tv.bo\0gold\0"
-"is-a-hard-worker.com\0pantheonsite.io\0"
-"zao.miyagi.jp\0golf\0"
-"tv.br\0cn.ua\0"
-"leclerc\0"
-"\xd8\xb4\xd8\xa8\xd9\x83\xd8\xa9\0"
-"johana.toyama.jp\0"
-"lipsy\0"
-"k12.ne.us\0"
-"roma.it\0jaworzno.pl\0lib.la.us\0"
-"kusu.oita.jp\0fuchu.tokyo.jp\0"
-"i.bg\0"
-"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0clinique\0beep.pl\0"
-"art.do\0"
-"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0"
-"inf.mk\0"
-"pesarourbino.it\0"
-"bi.it\0kitayama.wakayama.jp\0baths.museum\0"
-"saotome.st\0\xe4\xbd\x9b\xe5\xb1\xb1\0"
-"mlb\0"
-"jus.br\0"
-"art.dz\0"
-"trentino-sued-tirol.it\0"
-"coal.museum\0myds.me\0"
-"happou.akita.jp\0info.ve\0"
-"tysv\xc3\xa6r.no\0"
-"cc.pa.us\0"
-"greta.fr\0"
-"stargard.pl\0mma\0"
-"aid.pl\0"
-"info.vn\0mls\0"
-"friuli-veneziagiulia.it\0shunan.yamaguchi.jp\0"
-"elasticbeanstalk.com\0"
-"goog\0"
-"lib.ny.us\0pioneer\0"
-"chuo.osaka.jp\0"
-"ariake.saga.jp\0"
-"xnbay.com\0"
-"trentino-stirol.it\0usuki.oita.jp\0"
-"istmein.de\0"
-"shiraoka.saitama.jp\0olkusz.pl\0"
-"s3-website.us-east-2.amazonaws.com\0"
-"rep.kp\0"
-"tips\0"
-"ora.gunma.jp\0timekeeping.museum\0isa-hockeynut.com\0"
-"uvic.museum\0"
-"nord-odal.no\0"
-"ayabe.kyoto.jp\0"
-"rn.it\0gokase.miyazaki.jp\0info.tn\0"
-"folkebibl.no\0moe\0own.pm\0"
-"info.tr\0cc.ri.us\0"
-"caltanissetta.it\0info.tt\0moi\0"
-"shikabe.hokkaido.jp\0"
-"mom\0dyndns.ddnss.de\0"
-"art.ht\0intl.tn\0"
-"info.tz\0"
-"trustee.museum\0"
-"wakasa.tottori.jp\0"
-"theatre\0"
-"mov\0statefarm\0"
-"higashihiroshima.hiroshima.jp\0"
-"agano.niigata.jp\0"
-"hiranai.aomori.jp\0opencraft.hosting\0"
-"shiksha\0"
-"\xc3\xa1lt\xc3\xa1.no\0"
-"kolobrzeg.pl\0"
-"cci.fr\0fujieda.shizuoka.jp\0"
-"nab\0"
-"info.ro\0"
-"tv.im\0"
-"presidio.museum\0"
-"info.sd\0"
-"berlev\xc3\xa5g.no\0"
-"tv.it\0"
-"britishcolumbia.museum\0\xd1\x80\xd1\x83\xd1\x81\0"
-"ybo.party\0"
-"passagens\0trading\0"
-"date.fukushima.jp\0futaba.fukushima.jp\0tokashiki.okinawa.jp\0iveco\0nba\0"
-"alstom\0barcelona\0"
-"kamikitayama.nara.jp\0"
-"groundhandling.aero\0fujiyoshida.yamanashi.jp\0"
-"hikone.shiga.jp\0"
-"ushistory.museum\0rugby\0"
-"ssl.origin.cdn77-secure.org\0"
-"modern.museum\0energy\0"
-"mihama.chiba.jp\0tsuruoka.yamagata.jp\0"
-"info.pk\0"
-"info.pl\0forgot.her.name\0"
-"suli.hu\0sologne.museum\0inf.ua\0"
-"msd\0"
-"niteroi.br\0"
-"shimoda.shizuoka.jp\0"
-"abo.pa\0info.pr\0"
-"akdn\0"
-"gs.nl.no\0"
-"izunokuni.shizuoka.jp\0"
-"olsztyn.pl\0cc.il.us\0"
-"conf.au\0"
-"bmd.br\0"
-"iwade.wakayama.jp\0"
-"misasa.tottori.jp\0"
-"county.museum\0logoip.com\0"
-"agric.za\0"
-"info.na\0"
-"cc.wi.us\0"
-"belluno.it\0info.mv\0info.nf\0lib.il.us\0"
-"radom.pl\0"
-"info.ni\0mtn\0"
-"journal.aero\0"
-"mtr\0"
-"nec\0"
-"nanyo.yamagata.jp\0"
-"lib.va.us\0"
-"arendal.no\0info.nr\0"
-"hachioji.tokyo.jp\0"
-"machida.tokyo.jp\0tv.na\0"
-"kurogi.fukuoka.jp\0"
-"\xc4\x8d\xc3\xa1hcesuolo.no\0"
-"nadex\0"
-"mn.us\0"
-"trentino-su\xcc\x88""dtirol.it\0glogow.pl\0"
-"li.it\0"
-"net\0u2-local.xnbay.com\0"
-"ac.gov.br\0puglia.it\0gushikami.okinawa.jp\0info.la\0iveland.no\0"
-"new\0"
-"is-a-soxfan.org\0"
-"odo.br\0"
-"kitahiroshima.hokkaido.jp\0finance\0"
-"nfl\0"
-"preservation.museum\0"
-"meiwa.gunma.jp\0"
-"art.pl\0"
-"i.ng\0"
-"cn-north-1.eb.amazonaws.com.cn\0"
-"detroit.museum\0"
-"karelia.su\0"
-"nordkapp.no\0"
-"ichinomiya.aichi.jp\0ngo\0"
-"namsskogan.no\0"
-"massacarrara.it\0suwalki.pl\0"
-"living.museum\0"
-"tozawa.yamagata.jp\0press.se\0"
-"microlight.aero\0"
-"nsw.edu.au\0verona.it\0"
-"nhk\0from-in.com\0eu.org\0"
-"ad.jp\0"
-"club\0"
-"ullensaker.no\0"
-"kisosaki.mie.jp\0"
-"\xe8\xb4\xad\xe7\x89\xa9\0"
-"mw.gov.pl\0"
-"hl.cn\0cesena-forli\xcc\x80.it\0jetzt\0"
-"ishikari.hokkaido.jp\0java\0\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\0serveexchange.com\0"
-"i.ph\0"
-"info.ke\0asmatart.museum\0"
-"seirou.niigata.jp\0scienceandindustry.museum\0wiih.gov.pl\0ac.leg.br\0"
-"udine.it\0info.ki\0stadt.museum\0"
-"\xe5\x9f\xbc\xe7\x8e\x89.jp\0"
-"s3-website-ap-southeast-2.amazonaws.com\0"
-"minamiuonuma.niigata.jp\0blogspot.vn\0"
-"barsy.shop\0"
-"kitagata.gifu.jp\0"
-"art.sn\0"
-"cl.it\0"
-"higashiagatsuma.gunma.jp\0"
-"isernia.it\0tv.sd\0"
-"abruzzo.it\0"
-"roma.museum\0"
-"mihara.hiroshima.jp\0"
-"ntdll.top\0"
-"zone\0"
-"bolzano-altoadige.it\0"
-"k12.dc.us\0"
-"ms.gov.br\0chofu.tokyo.jp\0b\xc3\xa1l\xc3\xa1t.no\0"
-"seki.gifu.jp\0rich\0"
-"lib.as.us\0"
-"ichikai.tochigi.jp\0"
-"asso.eu.org\0"
-"ind.br\0nichinan.miyazaki.jp\0balsfjord.no\0"
-"reliance\0"
-"i.se\0"
-"cri.br\0"
-"naturhistorisches.museum\0grue.no\0"
-"zuerich\0"
-"hakui.ishikawa.jp\0tcp4.me\0"
-"tv.tr\0"
-"siena.it\0kodaira.tokyo.jp\0"
-"joinville.br\0caserta.it\0"
-"kharkiv.ua\0"
-"mie.jp\0tv.tz\0"
-"co.krd\0"
-"s\xc3\xb8r-aurdal.no\0service.gov.uk\0"
-"austin.museum\0"
-"blogspot.re\0"
-"mt.gov.br\0etajima.hiroshima.jp\0"
-"hachijo.tokyo.jp\0konin.pl\0"
-"london.museum\0cloudycluster.net\0"
-"chuo.fukuoka.jp\0"
-"ta.it\0\xd1\x81\xd1\x80\xd0\xb1\0"
-"shobara.hiroshima.jp\0sandnessj\xc3\xb8""en.no\0"
-"press.ma\0"
-"blogspot.ro\0"
-"goiania.br\0"
-"sport.hu\0notogawa.shiga.jp\0"
-"bel.tr\0"
-"haga.tochigi.jp\0blogspot.rs\0"
-"!city.kawasaki.jp\0blogspot.ru\0blogspot.se\0"
-"kmpsp.gov.pl\0from-wv.com\0"
-"blogspot.sg\0"
-"blogspot.si\0mysecuritycamera.net\0"
-"hanamigawa.chiba.jp\0blogspot.sk\0freeddns.us\0"
-"hjartdal.no\0"
-"miyako.fukuoka.jp\0zhytomyr.ua\0ms.leg.br\0"
-"blogspot.sn\0"
-"ueda.nagano.jp\0"
-"iwakura.aichi.jp\0"
-"nishiarita.saga.jp\0stat.no\0tr.eu.org\0ras.ru\0"
-"blogspot.td\0"
-"shiftedit.io\0"
-"hurdal.no\0"
-"matsuura.nagasaki.jp\0"
-"kasahara.gifu.jp\0"
-"amica\0"
-"myeffect.net\0"
-"kazimierz-dolny.pl\0"
-"hidaka.saitama.jp\0"
-"vi.it\0now\0"
-"takahashi.okayama.jp\0fujikawa.yamanashi.jp\0is-a-bookkeeper.com\0"
-"blogspot.tw\0blogspot.ug\0"
-"cc.ut.us\0"
-"game-server.cc\0"
-"sumoto.hyogo.jp\0tsuyama.okayama.jp\0"
-"midori.chiba.jp\0"
-"mt.leg.br\0"
-"trentinosu\xcc\x88""dtirol.it\0"
-"uk.net\0"
-"ind.gt\0heroy.nordland.no\0"
-"blogspot.mr\0"
-"hjelmeland.no\0tokke.no\0"
-"yoro.gifu.jp\0artanddesign.museum\0muncie.museum\0abkhazia.su\0"
-"blogspot.mx\0"
-"castle.museum\0monticello.museum\0soccer\0blogspot.my\0"
-"iamallama.com\0"
-"blogspot.nl\0"
-"lunner.no\0nra\0university\0"
-"pistoia.it\0mombetsu.hokkaido.jp\0ky.us\0blogspot.no\0"
-"hadsel.no\0swiftcover\0"
-"berlin.museum\0obi\0"
-"ashikaga.tochigi.jp\0"
-"ind.in\0"
-"pictet\0"
-"yuasa.wakayama.jp\0earth\0"
-"\xe1\x83\x92\xe1\x83\x94\0"
-"nrw\0"
-"blogspot.pe\0"
-"\xda\x80\xd8\xa7\xd8\xb1\xd8\xaa\0"
-"fauske.no\0serveftp.net\0"
-"likescandy.com\0"
-"international\0syno-ds.de\0"
-"lillehammer.no\0nikon\0"
-"health-carereform.com\0"
-"show.aero\0"
-"matsuzaki.shizuoka.jp\0blogspot.qa\0"
-"kawai.iwate.jp\0otsu.shiga.jp\0"
-"hl.no\0blogspot.pt\0"
-"s3.dualstack.eu-west-1.amazonaws.com\0"
-"shinagawa.tokyo.jp\0"
-"s3-website.ap-south-1.amazonaws.com\0"
+"k12.or.us\0"
+"shibetsu.hokkaido.jp\0shiojiri.nagano.jp\0"
+"surrey.museum\0forsale\0"
+"\xe5\xa4\xa7\xe9\x98\xaa.jp\0"
+"museum.om\0"
+"tm.mc\0"
+"tajimi.gifu.jp\0edunet.tn\0"
+"izumozaki.niigata.jp\0"
+"tm.mg\0"
+"hokkaido.jp\0"
+"bozen.it\0"
+"dyndns-remote.com\0"
+"ri.us\0hotels\0"
+"agdenes.no\0"
+"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd9\x87\0"
+"itakura.gunma.jp\0"
+"dyndns.ws\0"
+"mo.it\0toyoura.hokkaido.jp\0"
+"tm.no\0k12.la.us\0"
+"woodside\0"
+"delaware.museum\0h\xc3\xa1mm\xc3\xa1rfeasta.no\0lamborghini\0reliance\0"
+"cancerresearch\0"
+"is-a-chef.com\0"
+"arkhangelsk.su\0"
+"s\xc3\xa1l\xc3\xa1t.no\0"
+"hiraya.nagano.jp\0"
+"yamato.fukushima.jp\0"
+"webspace.rocks\0"
+"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0"
+"jio\0u2.xnbay.com\0"
+"gen.mi.us\0"
+"brother\0"
+"cloudns.pw\0"
+"tm.pl\0"
+"town\0"
+"kawanishi.hyogo.jp\0"
+"charter.aero\0vegas\0"
+"k12.id.us\0"
+"sanuki.kagawa.jp\0agematsu.nagano.jp\0haga.tochigi.jp\0"
+"holdings\0"
+"higashi.fukushima.jp\0"
+"nes.akershus.no\0"
+"\xe6\x9b\xb8\xe7\xb1\x8d\0"
+"profesional.bo\0lviv.ua\0homesecuritypc.com\0"
+"dnsup.net\0"
+"vossevangen.no\0"
+"m\xc4\x81ori.nz\0"
+"cc.mo.us\0pgfog.com\0"
+"guge\0"
+"kanonji.kagawa.jp\0"
+"nebraska.museum\0"
+"kawagoe.saitama.jp\0"
+"download\0"
+"southcarolina.museum\0bremanger.no\0"
+"grosseto.it\0\xe0\xa4\x95\xe0\xa5\x89\xe0\xa4\xae\0"
+"evje-og-hornnes.no\0"
+"oyodo.nara.jp\0"
+"hasama.oita.jp\0"
+"chernigov.ua\0"
+"sumoto.hyogo.jp\0"
+"insurance.aero\0tm.ro\0"
+"makurazaki.kagoshima.jp\0"
+"\xd9\x87\xd9\x85\xd8\xb1\xd8\xa7\xd9\x87\0"
+"aomori.aomori.jp\0jll\0"
+"homegoods\0toys\0"
+"tm.se\0cupcake.is\0"
+"seoul.kr\0"
+"neues.museum\0"
+"se.gov.br\0"
+"c.bg\0"
+"upow.gov.pl\0"
+"\xe6\xb7\xa1\xe9\xa9\xac\xe9\x94\xa1\0"
+"tsuruoka.yamagata.jp\0goodyear\0pictet\0"
+"lidl\0"
+"jdevcloud.com\0"
+"jmp\0"
+"s\xc3\xa1lat.no\0"
+"tahara.aichi.jp\0nakagusuku.okinawa.jp\0"
+"steinkjer.no\0"
+"yokoshibahikari.chiba.jp\0nanjo.okinawa.jp\0"
+"press.museum\0"
+"jnj\0"
+"lpages.co\0"
+"higashine.yamagata.jp\0"
+"illustration.museum\0"
+"mragowo.pl\0"
+"bz.it\0mmafan.biz\0"
+"amusement.aero\0s3.dualstack.ca-central-1.amazonaws.com\0cya.gg\0"
+"villas\0"
+"hyllestad.no\0cc.wa.us\0life\0"
+"tatsuno.hyogo.jp\0maori.nz\0"
+"kwp.gov.pl\0"
+"uto.kumamoto.jp\0"
+"dyr\xc3\xb8y.no\0"
+"atsuma.hokkaido.jp\0"
+"nsw.au\0inder\xc3\xb8y.no\0cc.ga.us\0"
+"sabae.fukui.jp\0design\0"
+"sasebo.nagasaki.jp\0jot\0"
+"gucci\0*.alces.network\0"
+"kannami.shizuoka.jp\0"
+"joy\0"
+"nanao.ishikawa.jp\0akagi.shimane.jp\0*.bzz.dapps.earth\0"
+"iraq.museum\0esurance\0"
+"pc.it\0"
+"guam.gu\0"
+"cust.prod.thingdust.io\0"
+"horonobe.hokkaido.jp\0"
+"ibestad.no\0"
+"abc.br\0novara.it\0nichinan.tottori.jp\0fujikawaguchiko.yamanashi.jp\0"
+"wales.museum\0"
+"shikokuchuo.ehime.jp\0help\0"
+"textile.museum\0c66.me\0"
+"\xd1\x83\xd0\xba\xd1\x80\0"
+"dyndns-free.com\0"
+"uki.kumamoto.jp\0"
+"anthropology.museum\0botanicalgarden.museum\0raholt.no\0gjemnes.no\0"
+"us-4.evennode.com\0"
+"deloitte\0"
+"mydissent.net\0"
+"kustanai.ru\0"
+"veg\xc3\xa5rshei.no\0leitungsen.de\0"
+"valleedaoste.it\0"
+"settlers.museum\0sa-east-1.elasticbeanstalk.com\0"
+"sa.gov.pl\0clubmed\0"
+"paleo.museum\0"
+"rnrt.tn\0"
+"kustanai.su\0"
+"kyiv.ua\0"
+"control.aero\0tm.za\0data\0lundbeck\0dattolocal.com\0"
+"chiba.jp\0"
+"rollag.no\0date\0"
+"plus\0"
"maibara.shiga.jp\0"
-"control.aero\0"
-"ascoli-piceno.it\0"
-"*.sapporo.jp\0"
+"trani-andria-barletta.it\0epson\0"
+"ruovat.no\0mo.us\0"
+"ueda.nagano.jp\0"
+"like\0"
+"birdart.museum\0"
+"gateway.museum\0pagefrontapp.com\0"
+"higashihiroshima.hiroshima.jp\0"
+"fribourg.museum\0etnedal.no\0"
+"port.fr\0"
+"union.aero\0"
+"aju.br\0"
+"higashichichibu.saitama.jp\0"
+"furano.hokkaido.jp\0"
+"yamanouchi.nagano.jp\0\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4\0"
+"stange.no\0us-3.evennode.com\0"
+"toda.saitama.jp\0"
+"newport.museum\0locus\0"
+"nose.osaka.jp\0"
+"north.museum\0"
+"kfh\0"
+"here\0"
+"bukhara.su\0ras.ru\0"
+"nishinoomote.kagoshima.jp\0"
+"c.la\0"
+"oe.yamagata.jp\0"
+"limo\0*.s5y.io\0"
+"rocher\0"
+"godo.gifu.jp\0shikama.miyagi.jp\0pc.pl\0"
+"jur.pro\0"
+"miasa.nagano.jp\0"
+"n\xc3\xb8tter\xc3\xb8y.no\0"
+"en.it\0"
"design.aero\0"
-"ntt\0"
-"upow.gov.pl\0"
-"ichihara.chiba.jp\0ind.kw\0blogspot.is\0"
-"blogspot.it\0"
-"shimizu.hokkaido.jp\0uslivinghistory.museum\0"
-"bedzin.pl\0webhop.info\0"
-"k12.ms.us\0k12.nc.us\0"
-"lib.ks.us\0news\0"
-"politie\0"
-"codes\0"
-"blogspot.jp\0"
-"g.bg\0gripe\0"
-"off\0"
-"philately.museum\0dnsfor.me\0"
-"ochi.kochi.jp\0democrat\0winners\0"
-"bg.it\0"
-"broke-it.net\0"
-"cc.ar.us\0next\0"
-"bale.museum\0"
-"\xc3\xb8yer.no\0blogspot.kr\0"
-"ot.it\0pd.it\0gitlab.io\0"
-"godo.gifu.jp\0iwanuma.miyagi.jp\0hangout\0"
-"toon.ehime.jp\0"
-"blogspot.li\0"
-"shinshinotsu.hokkaido.jp\0"
-"sakaiminato.tottori.jp\0"
-"omachi.nagano.jp\0"
-"hair\0"
-"al.gov.br\0toyokawa.aichi.jp\0"
-"blogspot.lt\0blogspot.md\0"
-"lib.ok.us\0blogspot.lu\0"
-"turin.it\0"
-"cri.nz\0blogspot.mk\0"
-"ragusa.it\0"
-"alto-adige.it\0"
-"info.zm\0restaurant\0"
-"nyc\0"
-"niigata.niigata.jp\0"
-"gallo\0filegear.me\0"
-"qld.edu.au\0hobol.no\0"
-"knx-server.net\0"
-"yamaga.kumamoto.jp\0"
-"epilepsy.museum\0blogspot.fi\0"
-"kherson.ua\0"
-"nishimera.miyazaki.jp\0"
-"blackfriday\0"
-"usantiques.museum\0"
-"umb.it\0aogashima.tokyo.jp\0"
-"media.hu\0rawa-maz.pl\0blogspot.fr\0"
-"geek.nz\0"
-"nom.ad\0trentin-sudtirol.it\0"
-"uhren.museum\0bykle.no\0nom.ae\0customer.speedpartner.de\0"
+"takinoue.hokkaido.jp\0shinjo.yamagata.jp\0"
+"barcelona.museum\0guru\0"
+"bas.it\0kita.kyoto.jp\0"
+"link\0"
+"nyny.museum\0"
+"wa.us\0"
+"show.aero\0usantiques.museum\0"
+"asago.hyogo.jp\0wiih.gov.pl\0"
+"heimatunduhren.museum\0"
+"ikoma.nara.jp\0"
+"ga.us\0"
+"gyeongbuk.kr\0ybo.faith\0"
+"kia\0"
+"rg.it\0shizukuishi.iwate.jp\0"
+"shobara.hiroshima.jp\0"
+"uber.space\0"
+"hb.cn\0store.nf\0"
+"bushey.museum\0ashgabad.su\0"
+"bg.it\0mimata.miyazaki.jp\0"
+"kim\0promo\0ch.eu.org\0"
+"matsubara.osaka.jp\0"
+"us-2.evennode.com\0"
+"logistics.aero\0windows\0"
+"minano.saitama.jp\0"
+"salem.museum\0"
+"cremona.it\0higashiyama.kyoto.jp\0"
+"watch-and-clock.museum\0"
+"shibecha.hokkaido.jp\0"
+"funagata.yamagata.jp\0"
+"motosu.gifu.jp\0kuroiso.tochigi.jp\0"
+"yoshida.shizuoka.jp\0"
+"paris.eu.org\0"
+"davvenj\xc3\xa1rga.no\0amica\0"
+"western.museum\0"
+"environmentalconservation.museum\0schule\0own.pm\0"
+"noto.ishikawa.jp\0iwatsuki.saitama.jp\0"
+"info.gu\0"
+"nom.ad\0yuza.yamagata.jp\0"
+"nom.ae\0"
"nom.af\0"
-"nom.ag\0kita.tokyo.jp\0"
-"nom.ai\0"
-"k12.sc.us\0"
-"nom.al\0"
-"aeroclub.aero\0"
-"biz.bb\0history.museum\0"
-"takino.hyogo.jp\0blogspot.gr\0"
-"biz.at\0"
-"altoadige.it\0"
-"author.aero\0rocks\0"
-"freesite.host\0"
-"ab.ca\0malbork.pl\0"
-"biz.az\0grandrapids.museum\0"
-"al.leg.br\0"
-"blogspot.hk\0"
-"s3-website-ap-northeast-1.amazonaws.com\0"
-"shingu.hyogo.jp\0"
-"tt.im\0space\0"
-"ally\0"
-"webcam\0blogspot.hr\0"
-"vi.us\0"
-"kaminokawa.tochigi.jp\0"
-"blogspot.hu\0blogspot.ie\0"
-"ud.it\0homeoffice.gov.uk\0"
-"yonago.tottori.jp\0mayfirst.info\0nom.cl\0"
-"yukuhashi.fukuoka.jp\0"
-"kitahata.saga.jp\0vennesla.no\0blogspot.in\0"
-"nom.co\0\xe6\xbe\xb3\xe9\x96\x80\0tiffany\0"
-"shimokawa.hokkaido.jp\0blogspot.ba\0"
-"homebuilt.aero\0"
-"blogspot.be\0"
-"blogspot.bg\0"
-"biz.cy\0"
-"bydgoszcz.pl\0"
-"unazuki.toyama.jp\0ind.tn\0biz.dk\0blogspot.bj\0"
-"ashgabad.su\0"
-"sakata.yamagata.jp\0"
-"plumbing\0"
-"blogspot.ca\0"
-"kushima.miyazaki.jp\0one\0"
-"ong\0"
-"tmp.br\0blogspot.cf\0"
-"zakopane.pl\0"
-"rl.no\0s3-ap-northeast-2.amazonaws.com\0blogspot.ch\0"
-"soni.nara.jp\0onl\0"
-"amsterdam.museum\0archaeological.museum\0edeka\0jdevcloud.com\0"
-"blogspot.cl\0"
-"conf.lv\0"
-"hongo.hiroshima.jp\0"
-"maryland.museum\0juegos\0"
-"nom.es\0biz.et\0for-some.biz\0"
-"blogspot.de\0"
-"blogspot.cv\0"
-"*.bd\0tele.amune.org\0"
-"oi.kanagawa.jp\0\xe4\xb8\xad\xe4\xbf\xa1\0blogspot.cz\0"
-"blogspot.dk\0"
-"ooo\0"
-"campinas.br\0miniserver.com\0"
-"lodingen.no\0"
-"valleeaoste.it\0mitake.gifu.jp\0"
-"nom.fr\0mizunami.gifu.jp\0kristiansund.no\0"
-"gs.bu.no\0broker\0freetls.fastly.net\0nom.gd\0"
-"lego\0nom.ge\0"
-"bihoro.hokkaido.jp\0gub.uy\0"
-"tobe.ehime.jp\0"
-"bozen-sudtirol.it\0"
+"nom.ag\0"
+"isumi.chiba.jp\0shirakawa.gifu.jp\0witd.gov.pl\0"
+"square.museum\0nom.ai\0"
+"astronomy.museum\0vinnytsia.ua\0"
+"kasahara.gifu.jp\0nom.al\0"
+"funabashi.chiba.jp\0"
+"\xe4\xb8\x96\xe7\x95\x8c\0"
+"nature.museum\0bo.nordland.no\0"
+"info.ht\0ono.fukui.jp\0"
+"info.hu\0tank.museum\0"
+"bloomberg\0"
+"kofu.yamanashi.jp\0co.education\0"
+"sp.leg.br\0"
+"freiburg.museum\0"
+"machida.tokyo.jp\0"
+"obu.aichi.jp\0gifu.gifu.jp\0ashikaga.tochigi.jp\0"
+"info.et\0"
+"arte.bo\0homeftp.org\0"
+"us-1.evennode.com\0"
+"shika.ishikawa.jp\0"
+"c.se\0"
+"erotica.hu\0"
+"nom.cl\0"
+"is-very-nice.org\0"
+"tagawa.fukuoka.jp\0shishikui.tokushima.jp\0"
+"air-traffic-control.aero\0nom.co\0from-ne.com\0"
+"colonialwilliamsburg.museum\0"
+"homes\0"
+"bifuka.hokkaido.jp\0ogawa.saitama.jp\0"
+"yamashina.kyoto.jp\0"
+"matsushima.miyagi.jp\0kodaira.tokyo.jp\0"
+"imageandsound.museum\0"
+"tado.mie.jp\0is-a-chef.net\0"
+"live\0\xe5\x95\x86\xe6\xa0\x87\0murmansk.su\0"
+"fr\xc3\xa6na.no\0nore-og-uvdal.no\0"
+"kasumigaura.ibaraki.jp\0"
+"niepce.museum\0s\xc3\xb8gne.no\0"
+"gr.it\0"
+"info.cx\0"
+"room\0"
+"nexus\0us-east-1.amazonaws.com\0"
+"t.bg\0is-found.org\0forumz.info\0"
+"ivanovo.su\0"
+"campinas.br\0gr.jp\0"
+"info.ec\0"
+"nom.es\0ulm.museum\0baby\0"
+"kpn\0"
+"barsy.me\0serveexchange.com\0homelink.one\0"
+"game.tw\0"
+"voss.no\0"
+"store.ve\0applinzi.com\0"
+"info.bb\0frosinone.it\0"
+"moscow.museum\0"
+"nom.fr\0info.at\0"
+"info.au\0at.eu.org\0"
+"nom.gd\0"
+"nom.ge\0"
+"!city.sendai.jp\0"
+"nannestad.no\0"
+"info.az\0social\0"
+"tsuchiura.ibaraki.jp\0krd\0lat\0"
"nom.gl\0"
-"trentino-s-tirol.it\0minami.tokushima.jp\0"
-"*.ck\0"
-"uk.eu.org\0"
-"yaese.okinawa.jp\0nom.gt\0"
-"iitate.fukushima.jp\0"
-"directory\0"
-"lg.jp\0kimobetsu.hokkaido.jp\0media.pl\0"
-"cdn77-ssl.net\0"
-"tatamotors\0"
-"bryansk.su\0nom.hn\0"
-"s3.eu-west-3.amazonaws.com\0"
-"monza-brianza.it\0"
-"biz.id\0shouji\0"
-"org\0"
-"urawa.saitama.jp\0"
-"minamiaiki.nagano.jp\0pay\0"
-"e12.ve\0games\0"
-"ppg.br\0higashisumiyoshi.osaka.jp\0"
-"nom.im\0"
-"\xed\x95\x9c\xea\xb5\xad\0"
-"fussa.tokyo.jp\0"
-"*.er\0"
-"no.it\0"
-"\xe6\xbe\xb3\xe9\x97\xa8\0barsy.site\0"
-"cc.nj.us\0"
-"*.fj\0"
-"*.fk\0"
-"flatanger.no\0f\xc3\xb8rde.no\0"
-"gz.cn\0"
-"labour.museum\0skierva.no\0"
-"haus\0"
-"blogspot.ae\0nom.ke\0"
-"\xc3\xb8ystre-slidre.no\0"
-"biz.ki\0"
-"nishiazai.shiga.jp\0cranbrook.museum\0"
-"pro.az\0"
-"z.bg\0celtic.museum\0blogspot.al\0"
-"nom.km\0blogspot.am\0"
-"virginia.museum\0"
-"amex\0"
-"ott\0rodeo\0"
-"airline.aero\0pro.br\0"
-"bz.it\0"
-"fukudomi.saga.jp\0tendo.yamagata.jp\0"
-"komaki.aichi.jp\0"
-"indiana.museum\0itau\0"
-"b\xc3\xa5tsfjord.no\0nom.li\0"
-"rockart.museum\0ybo.trade\0"
-"citadel\0"
-"m\xc3\xa1tta-v\xc3\xa1rjjat.no\0privatizehealthinsurance.net\0"
-"pet\0"
-"juif.museum\0football\0"
-"viterbo.it\0cc.pr.us\0"
-"choyo.kumamoto.jp\0"
-"krodsherad.no\0ovh\0"
-"szex.hu\0"
-"morioka.iwate.jp\0nom.mg\0s3.dualstack.us-east-1.amazonaws.com\0"
-"pro.cy\0gets-it.net\0"
-"tynset.no\0s3-website-us-east-1.amazonaws.com\0nom.mk\0"
-"gsm.pl\0nym.by\0"
-"frankfurt.museum\0nym.bz\0"
-"g.se\0pics\0"
-"group.aero\0epost\0"
-"stcgroup\0"
-"nom.nc\0"
-"pro.ec\0"
-"biz.mv\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8b\xe0\xa4\xa4\0"
-"biz.mw\0"
-"goshiki.hyogo.jp\0poker\0"
-"biz.ni\0lamer\0"
-"nom.ni\0"
-"sebastopol.ua\0"
-"yamaguchi.jp\0"
-"friuliveneziagiulia.it\0*.jm\0"
-"norfolk.museum\0biz.nr\0phd\0"
-"historisches.museum\0"
-"nom.nu\0"
-"redstone\0"
-"so.it\0kumenan.okayama.jp\0"
-"takamori.nagano.jp\0funagata.yamagata.jp\0"
-"natural.bo\0campobasso.it\0\xd1\x83\xd0\xba\xd1\x80\0"
-"ojiya.niigata.jp\0*.kh\0"
-"hirosaki.aomori.jp\0waw.pl\0"
-"nagato.yamaguchi.jp\0nom.pa\0americanexpress\0pid\0"
-"kr\xc3\xa5""anghke.no\0nom.pe\0agakhan\0"
-"giving\0"
-"tsuchiura.ibaraki.jp\0ina.saitama.jp\0"
-"club.aero\0"
-"historisch.museum\0biz.pk\0"
-"biz.pl\0pin\0"
-"pb.ao\0smola.no\0nom.pl\0"
-"matsuyama.ehime.jp\0ikeda.fukui.jp\0mydatto.net\0"
-"ikeda.hokkaido.jp\0"
-"university.museum\0user.party.eus\0"
-"or.at\0biz.pr\0nom.qa\0"
-"omitama.ibaraki.jp\0kanegasaki.iwate.jp\0"
-"higashichichibu.saitama.jp\0"
-"or.bi\0"
-"nom.pw\0"
-"kartuzy.pl\0dynamic-dns.info\0"
-"cc.gu.us\0"
-"lincoln.museum\0veg\xc3\xa5rshei.no\0"
-"sasebo.nagasaki.jp\0mysecuritycamera.org\0bloxcms.com\0"
-"achi.nagano.jp\0"
-"*.mm\0"
-"pro.ht\0sos.pl\0nom.re\0"
-"or.ci\0shimane.shimane.jp\0nym.gr\0"
-"nishiaizu.fukushima.jp\0tashkent.su\0"
-"lg.ua\0"
-"institute\0"
-"64-b.it\0nym.gy\0"
-"or.cr\0nom.ro\0"
-"verbania.it\0cloudaccess.net\0"
-"*.np\0travel\0nom.rs\0"
-"nym.ie\0nom.si\0"
-"wajima.ishikawa.jp\0"
-"mayfirst.org\0"
-"research.aero\0spdns.org\0"
-"nuoro.it\0pavia.it\0cymru\0"
-"toscana.it\0"
-"skjerv\xc3\xb8y.no\0"
-"yoshida.shizuoka.jp\0osaka\0\xd8\xa7\xd8\xa8\xd9\x88\xd8\xb8\xd8\xa8\xd9\x8a\0nom.st\0"
-"skien.no\0"
-"indigena.bo\0"
-"erotika.hu\0biz.tj\0"
-"*.pg\0nom.tj\0"
-"from.hr\0ikoma.nara.jp\0"
-"ulsan.kr\0"
-"nom.tm\0"
-"sabae.fukui.jp\0"
-"sci.eg\0pnc\0biz.ua\0"
-"biz.tr\0"
-"ozu.kumamoto.jp\0fujikawaguchiko.yamanashi.jp\0biz.tt\0"
-"chikushino.fukuoka.jp\0"
-"railroad.museum\0"
-"nom.ug\0"
-"nishinoshima.shimane.jp\0setagaya.tokyo.jp\0"
-"geisei.kochi.jp\0"
-"katsuyama.fukui.jp\0"
-"pug.it\0"
-"historicalsociety.museum\0"
-"natura\0"
-"tanagura.fukushima.jp\0nom.vc\0"
-"surgeonshall.museum\0bjarkoy.no\0nym.la\0virtual-user.de\0"
-"kameyama.mie.jp\0ryokami.saitama.jp\0"
-"grocery\0youtube\0nym.lc\0nom.vg\0"
-"nom.uy\0"
-"cc.me.us\0"
-"biz.vn\0dynns.com\0nym.li\0"
-"nym.kz\0"
-"tatar\0"
-"kasaoka.okayama.jp\0pro.na\0fage\0"
-"dyndns-wiki.com\0"
-"gop.pk\0"
-"pro.mv\0"
-"nym.lt\0"
-"kaho.fukuoka.jp\0nym.lu\0nym.me\0"
-"wa.edu.au\0ipiranga\0"
-"e.bg\0"
-"monza.it\0"
-"or.id\0dielddanuorri.no\0"
-"rel.ht\0iijima.nagano.jp\0nym.mn\0"
-"minamitane.kagoshima.jp\0ping\0"
-"\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa\0lasalle\0"
-"pink\0"
-"samnanger.no\0"
-"oldnavy\0nym.mx\0"
-"inazawa.aichi.jp\0"
-"bozen.it\0pro.om\0"
-"losangeles.museum\0"
-"or.it\0"
-"nango.fukushima.jp\0"
-"gs.tm.no\0"
-"americanantiques.museum\0wzmiuw.gov.pl\0"
-"certification.aero\0aki.kochi.jp\0"
-"fail\0"
-"pro\0"
-"or.jp\0"
-"nym.nz\0"
-"k12.pa.us\0\xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\0"
-"*.landing.myjino.ru\0"
-"nom.za\0"
-"or.ke\0pru\0"
-"pro.pr\0"
-"cool\0is-a-doctor.com\0half.host\0"
-"satx.museum\0"
-"nym.pe\0"
-"coop\0ostrowiec.pl\0fedex\0"
-"biz.zm\0"
-"naval.museum\0balashov.su\0"
-"or.kr\0stjordal.no\0"
-"is-a-socialist.com\0"
-"chippubetsu.hokkaido.jp\0"
-"minamimaki.nagano.jp\0"
-"historichouses.museum\0vista\0"
-"nym.pt\0"
-"kokonoe.oita.jp\0ringerike.no\0backplaneapp.io\0"
-"medio-campidano.it\0"
-"nogata.fukuoka.jp\0"
-"embetsu.hokkaido.jp\0pub\0"
-"dyndns1.de\0"
-"\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4\0a.prod.fastly.net\0"
-"agematsu.nagano.jp\0iizuna.nagano.jp\0"
-"takayama.gunma.jp\0paderborn.museum\0"
-"ichiba.tokushima.jp\0myftp.org\0"
-"toyako.hokkaido.jp\0"
-"doctor\0"
-"z.se\0"
-"homedns.org\0synology.me\0"
-"or.na\0"
-"tec.ve\0"
-"ulm.museum\0goip.de\0"
-"or.mu\0localhistory.museum\0playstation\0"
-"nym.ro\0"
-"hirokawa.fukuoka.jp\0"
-"ge.it\0*.ye\0"
-"bentley\0"
-"fhv.se\0\xe6\x94\xbf\xe5\x8a\xa1\0"
-"higashimatsuyama.saitama.jp\0nym.sk\0"
-"urasoe.okinawa.jp\0pwc\0"
-"ddnslive.com\0"
-"iiyama.nagano.jp\0"
-"tr.it\0shimotsuma.ibaraki.jp\0"
-"kozaki.chiba.jp\0pro.tt\0"
-"trentinsud-tirol.it\0"
-"nym.su\0"
-"harima.hyogo.jp\0serveftp.org\0cloud.fedoraproject.org\0"
-"nym.sx\0"
-"nm.cn\0"
-"ogaki.gifu.jp\0\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0"
-"\xc3\xa5lg\xc3\xa5rd.no\0fans\0"
-"ddr.museum\0is-slick.com\0"
-"froland.no\0sochi.su\0"
-"fukuchiyama.kyoto.jp\0"
-"rel.pl\0"
-"nym.tw\0"
-"trentino-a-adige.it\0moka.tochigi.jp\0"
-"eco.br\0pro.vn\0"
-"im.it\0"
-"owariasahi.aichi.jp\0jeep\0jp.net\0operaunite.com\0"
-"or.pw\0"
-"suisse.museum\0"
-"r\xc3\xb8""d\xc3\xb8y.no\0markets\0"
-"blog.bo\0"
-"blog.br\0lundbeck\0"
-"servequake.com\0"
-"yusui.kagoshima.jp\0k12.in.us\0\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86\0"
-"gen.in\0"
-"chanel\0"
-"dreamhosters.com\0"
-"mizuho.tokyo.jp\0os.hordaland.no\0freeddns.org\0"
-"k12.wy.us\0"
-"jondal.no\0alipay\0"
-"ine.kyoto.jp\0"
-"hamatama.saga.jp\0"
-"kamiamakusa.kumamoto.jp\0rackmaze.com\0"
-"gr.com\0"
-"tonami.toyama.jp\0kraanghke.no\0"
-"laakesvuemie.no\0"
-"hokkaido.jp\0"
-"le.it\0farm\0lgbt\0vision\0"
-"kanazawa.ishikawa.jp\0tr.no\0"
-"est-le-patron.com\0for-our.info\0"
-"targi.pl\0"
-"or.th\0"
-"yawata.kyoto.jp\0nagawa.nagano.jp\0"
-"wajiki.tokushima.jp\0"
-"conference.aero\0"
-"fast\0"
-"shonai.fukuoka.jp\0theworkpc.com\0"
-"or.ug\0"
+"info.bo\0law\0applicationcloud.io\0"
+"nankoku.kochi.jp\0"
"com.ac\0"
-"aparecida.br\0"
-"or.tz\0"
-"com.af\0"
+"ebetsu.hokkaido.jp\0*.elb.amazonaws.com.cn\0"
+"com.af\0nom.gt\0"
"com.ag\0"
-"jeonbuk.kr\0"
"com.ai\0"
-"heguri.nara.jp\0tochigi.tochigi.jp\0imageandsound.museum\0"
-"balsan.it\0"
-"com.al\0yamagata.jp\0andebu.no\0czeladz.pl\0"
-"or.us\0ninja\0"
-"com.ba\0nabari.mie.jp\0"
-"com.ar\0com.bb\0leirvik.no\0"
-"schoenbrunn.museum\0"
-"yamazoe.nara.jp\0stranda.no\0"
-"com.au\0cc.nh.us\0"
-"com.aw\0"
+"com.al\0aparecida.br\0"
+"ddnslive.com\0"
+"chippubetsu.hokkaido.jp\0"
+"info.co\0"
+"monash\0nom.hn\0"
+"com.ba\0"
+"com.ar\0com.bb\0art.br\0pesaro-urbino.it\0"
+"r\xc3\xa1hkker\xc3\xa1vju.no\0hisamitsu\0"
+"pt.it\0"
+"com.au\0"
+"kashima.saga.jp\0"
+"com.aw\0tours\0"
"com.bh\0"
-"com.bi\0suzuki\0"
-"com.az\0minamiashigara.kanagawa.jp\0"
-"gx.cn\0"
-"kumakogen.ehime.jp\0"
-"com.bm\0kochi.jp\0"
-"com.bn\0cust.disrec.thingdust.io\0"
-"com.bo\0shingo.aomori.jp\0"
+"com.bi\0"
+"com.az\0"
+"s3.dualstack.eu-west-1.amazonaws.com\0"
+"fukushima.hokkaido.jp\0tokorozawa.saitama.jp\0"
+"com.bm\0oregontrail.museum\0read-books.org\0"
+"com.bn\0"
+"com.bo\0nom.im\0"
+"ogano.saitama.jp\0"
"com.br\0"
-"com.bs\0bauern.museum\0"
+"com.bs\0"
"com.bt\0"
-"x.bg\0isla.pr\0map.fastly.net\0"
+"software.aero\0pubol.museum\0"
+"abira.hokkaido.jp\0"
"com.by\0com.ci\0"
-"com.bz\0"
-"gj\xc3\xb8vik.no\0gen.nz\0"
-"com.cm\0ee.eu.org\0"
-"com.cn\0"
-"com.co\0ch.it\0saku.nagano.jp\0s3.dualstack.sa-east-1.amazonaws.com\0"
-"association.aero\0"
-"philadelphia.museum\0"
-"safety\0"
-"com.cu\0chigasaki.kanagawa.jp\0com.de\0virtueeldomein.nl\0"
-"com.cw\0sakahogi.gifu.jp\0"
-"com.cy\0selfip.net\0"
-"pu.it\0"
-"keymachine.de\0"
-"hatogaya.saitama.jp\0jambyl.su\0"
-"com.dm\0massa-carrara.it\0"
-"agrinet.tn\0"
-"com.do\0dovre.no\0"
-"isumi.chiba.jp\0lifeinsurance\0"
-"lesja.no\0"
-"com.ec\0kamishihoro.hokkaido.jp\0"
-"com.ee\0hakodate.hokkaido.jp\0"
-"nico\0"
-"com.eg\0"
-"com.dz\0e.se\0dattolocal.com\0"
-"hisamitsu\0"
-"\xe7\xb5\x84\xe7\xb9\x94.tw\0"
-"messina.it\0"
-"com.es\0lancome\0"
-"com.et\0vestre-toten.no\0"
-"yuzawa.niigata.jp\0"
-"warszawa.pl\0"
-"shimane.jp\0"
-"murayama.yamagata.jp\0"
-"championship.aero\0"
-"meloy.no\0"
-"kusatsu.shiga.jp\0"
-"hemnes.no\0nord-fron.no\0"
-"pvt.k12.ma.us\0isa-geek.org\0"
-"botanicgarden.museum\0"
+"com.bz\0ad.jp\0flickr\0"
+"lds\0"
+"com.cm\0plc.co.im\0"
+"com.cn\0traniandriabarletta.it\0"
+"pueblo.bo\0com.co\0art.do\0"
+"\xe5\x85\xac\xe5\x8f\xb8.cn\0"
+"tohnosho.chiba.jp\0kawanabe.kagoshima.jp\0nakagawa.nagano.jp\0"
+"politica.bo\0"
+"sh.cn\0"
+"com.cu\0tr\xc3\xb8gstad.no\0com.de\0"
+"sanagochi.tokushima.jp\0"
+"com.cw\0karasjok.no\0nom.ke\0"
+"com.cy\0tolga.no\0store.ro\0"
+"art.dz\0lom.it\0mantova.it\0"
+"nakadomari.aomori.jp\0"
+"com.dm\0\xe5\x85\xac\xe5\x8f\xb8.hk\0"
+"com.do\0nom.km\0"
+"\xe6\xbb\x8b\xe8\xb3\x80.jp\0weather\0"
+"koka.shiga.jp\0"
+"com.ec\0bashkiria.ru\0"
+"com.ee\0"
+"com.eg\0settlement.museum\0herokussl.com\0"
+"gets-it.net\0"
+"works.aero\0"
+"com.dz\0"
+"nom.li\0"
+"omachi.saga.jp\0"
+"bearalvahki.no\0"
+"\xe7\xa7\x8b\xe7\x94\xb0.jp\0store.st\0"
+"mandal.no\0north-kazakhstan.su\0obninsk.su\0"
+"com.es\0bashkiria.su\0"
+"com.et\0"
+"nom.mg\0mein-iserv.de\0"
+"choyo.kumamoto.jp\0"
+"music.museum\0nom.mk\0"
"com.fr\0"
-"com.ge\0"
-"com.gh\0kaszuby.pl\0"
-"com.gi\0lib.co.us\0"
-"sld.do\0com.gl\0"
-"com.gn\0naoshima.kagawa.jp\0"
-"com.gp\0tsuruga.fukui.jp\0likes-pie.com\0"
-"hdfc\0"
-"med.br\0com.gr\0furniture.museum\0"
-"oyodo.nara.jp\0takaishi.osaka.jp\0woodside\0"
-"com.gt\0"
-"com.gu\0"
-"\xe4\xb8\x96\xe7\x95\x8c\0"
-"nakama.fukuoka.jp\0gangwon.kr\0"
-"com.gy\0aremark.no\0knightpoint.systems\0"
-"com.hk\0"
-"kashihara.nara.jp\0"
-"rennebu.no\0"
-"bc.ca\0com.hn\0hiji.oita.jp\0"
-"red\0"
-"uppo.gov.pl\0"
-"nishi.osaka.jp\0"
-"com.hr\0himeji.hyogo.jp\0adult\0"
-"gen.tr\0"
-"com.ht\0"
-"oksnes.no\0"
-"kyowa.akita.jp\0"
-"wodzislaw.pl\0ren\0"
-"nrw.museum\0stuttgart.museum\0"
-"ve.it\0fuefuki.yamanashi.jp\0scotland.museum\0"
-"com.im\0goto.nagasaki.jp\0"
-"qvc\0"
-"com.io\0"
-"com.iq\0honefoss.no\0"
-"med.ec\0com.is\0"
-"fnd.br\0med.ee\0arkhangelsk.su\0"
-"ass.km\0"
-"ardal.no\0vote\0"
-"is-a-guru.com\0"
-"vaporcloud.io\0"
-"lib.tx.us\0"
-"movistar\0"
-"com.jo\0country\0"
-"gives\0"
-"kamogawa.chiba.jp\0yokawa.hyogo.jp\0slask.pl\0voto\0"
-"tokigawa.saitama.jp\0"
-"yatsuka.shimane.jp\0erni\0tuxfamily.org\0"
-"sakaki.nagano.jp\0com.kg\0is-a-musician.com\0"
-"freeboxos.com\0"
+"anjo.aichi.jp\0"
+"com.ge\0nom.nc\0"
+"palmas.br\0\xd8\xa7\xd8\xb1\xd8\xa7\xd9\x85\xd9\x83\xd9\x88\0"
+"com.gh\0"
+"economia.bo\0com.gi\0"
+"nom.ni\0"
+"com.gl\0kawara.fukuoka.jp\0tenri.nara.jp\0"
+"barsy.uk\0"
+"com.gn\0email\0"
+"com.gp\0"
+"delta\0"
+"com.gr\0nagara.chiba.jp\0florist\0"
+"dovre.no\0porsanger.no\0s3-us-gov-west-1.amazonaws.com\0"
+"com.gt\0art.ht\0"
+"com.gu\0from-de.com\0"
+"towada.aomori.jp\0takata.fukuoka.jp\0"
+"nom.nu\0"
+"chambagri.fr\0"
+"com.gy\0ap-northeast-1.elasticbeanstalk.com\0"
+"iwanuma.miyagi.jp\0"
+"catering.aero\0com.hk\0roros.no\0"
+"watch\0"
+"vladimir.su\0"
+"com.hn\0semboku.akita.jp\0hanamigawa.chiba.jp\0chiyoda.gunma.jp\0kuwana.mie.jp\0"
+"cinema.museum\0"
+"com.hr\0"
+"nom.pa\0lug.org.uk\0"
+"com.ht\0higashishirakawa.gifu.jp\0"
+"lom.no\0vestvagoy.no\0"
+"ce.gov.br\0"
+"a.bg\0romskog.no\0nom.pe\0"
+"is-into-games.com\0"
+"inatsuki.fukuoka.jp\0"
+"tra.kp\0"
+"com.im\0abudhabi\0"
+"kudoyama.wakayama.jp\0nom.pl\0"
+"com.io\0aejrie.no\0davvenjarga.no\0"
+"nango.fukushima.jp\0band\0forex\0"
+"com.iq\0nationalfirearms.museum\0"
+"com.is\0bergen.no\0nom.qa\0"
+"bank\0"
+"kurashiki.okayama.jp\0musashino.tokyo.jp\0hotel.tz\0"
+"botany.museum\0newmexico.museum\0nom.pw\0"
+"llc\0university\0"
+"higashinaruse.akita.jp\0fujimi.saitama.jp\0"
+"dclk\0"
+"bunkyo.tokyo.jp\0office-on-the.net\0"
+"com.jo\0mycd.eu\0"
+"kawatana.nagasaki.jp\0satosho.okayama.jp\0kawaguchi.saitama.jp\0"
+"honda\0barrel-of-knowledge.info\0"
+"ch.it\0kanazawa.ishikawa.jp\0"
+"com.kg\0matta-varjjat.no\0nom.re\0mckinsey\0ciscofreak.com\0"
+"*.bd\0higashiagatsuma.gunma.jp\0"
"com.ki\0"
-"sciencehistory.museum\0\xe3\x82\xb3\xe3\x83\xa0\0"
-"naamesjevuemie.no\0"
-"mitou.yamaguchi.jp\0com.km\0sorreisa.no\0"
-"miami\0"
-"masaki.ehime.jp\0com.kp\0"
-"com.la\0"
+"com.km\0schoenbrunn.museum\0vladimir.ru\0ybo.review\0"
+"ichinomiya.aichi.jp\0numata.hokkaido.jp\0"
+"lans.museum\0"
+"mitake.gifu.jp\0com.kp\0"
+"com.la\0nom.ro\0"
"com.lb\0"
-"com.lc\0consulado.st\0"
-"seiyo.ehime.jp\0"
+"veterinaire.km\0com.lc\0uzhgorod.ua\0is-a-musician.com\0freedesktop.org\0"
+"info.ve\0nom.rs\0"
+"tanabe.kyoto.jp\0"
"com.kw\0"
-"com.ky\0ivano-frankivsk.ua\0"
+"pgafan.net\0"
+"com.ky\0missile.museum\0"
"com.kz\0"
-"com.lk\0beiarn.no\0"
-"nike\0"
-"\xe7\x86\x8a\xe6\x9c\xac.jp\0fukui.fukui.jp\0shinjuku.tokyo.jp\0"
-"com.lr\0"
-"discover\0router.management\0"
-"pokrovsk.su\0"
-"com.lv\0"
-"com.mg\0inderoy.no\0ril\0"
-"com.ly\0kv\xc3\xa6""fjord.no\0"
-"trader.aero\0kawanabe.kagoshima.jp\0saiki.oita.jp\0rio\0"
-"com.mk\0coastaldefence.museum\0rip\0"
-"kosaka.akita.jp\0com.ml\0"
-"jewishart.museum\0"
-"goodhands\0bplaced.de\0"
-"com.mo\0"
-"gc.ca\0tainai.niigata.jp\0nm.us\0"
-"kanonji.kagawa.jp\0com.na\0nore-og-uvdal.no\0est.pr\0"
-"ito.shizuoka.jp\0com.ms\0verdal.no\0"
-"med.ht\0com.mt\0"
-"com.mu\0family.museum\0"
-"com.mv\0com.nf\0cyon.link\0"
+"com.lk\0nom.si\0"
+"pa.it\0info.vn\0arab\0"
+"*.ck\0"
+"miyako.iwate.jp\0"
+"k12.ok.us\0"
+"com.lr\0wlocl.pl\0\xe5\xb7\xa5\xe8\xa1\x8c\0"
+"\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0"
+"isa-hockeynut.com\0"
+"com.lv\0ostrowiec.pl\0nom.st\0"
+"com.mg\0"
+"kawasaki.miyagi.jp\0"
+"com.ly\0"
+"com.mk\0"
+"com.ml\0nom.tj\0"
+"historyofscience.museum\0midtre-gauldal.no\0bir.ru\0"
+"minami.fukuoka.jp\0"
+"com.mo\0southwest.museum\0nom.tm\0drud.io\0"
+"com.na\0"
+"com.ms\0showtime\0"
+"com.mt\0lol\0"
+"com.mu\0plaza.museum\0"
+"com.mv\0com.nf\0"
"com.mw\0com.ng\0"
"com.mx\0"
-"kitakami.iwate.jp\0com.my\0com.ni\0"
-"iwate.iwate.jp\0maserati\0"
-"is-saved.org\0"
-"ogimi.okinawa.jp\0"
-"gon.pk\0"
-"com.nr\0\xd8\xa7\xd9\x84\xd8\xb9\xd9\x84\xd9\x8a\xd8\xa7\xd9\x86\0"
-"karate.museum\0dyndns-remote.com\0"
-"c.bg\0iwakuni.yamaguchi.jp\0"
-"hamamatsu.shizuoka.jp\0dinosaur.museum\0freedesktop.org\0"
+"com.my\0com.ni\0nom.ug\0"
+"yonezawa.yamagata.jp\0"
+"production.aero\0sciencecenters.museum\0"
+"lodi.it\0info.tn\0"
+"chiryu.aichi.jp\0"
+"blogdns.com\0"
+"com.nr\0info.tr\0"
+"lib.mt.us\0lib.nd.us\0"
+"info.tt\0lpl\0"
+"ooguy.com\0nom.vc\0"
+"*.er\0"
+"sande.m\xc3\xb8re-og-romsdal.no\0"
+"veterinaire.fr\0rikuzentakata.iwate.jp\0jeonnam.kr\0"
+"nom.vg\0"
+"info.tz\0"
+"t.se\0nom.uy\0"
+"art.pl\0"
"com.om\0"
-"campidanomedio.it\0tosu.saga.jp\0"
-"kashima.ibaraki.jp\0com.pa\0"
-"fukaya.saitama.jp\0numazu.shizuoka.jp\0"
-"kainan.wakayama.jp\0"
-"com.pe\0"
-"inami.wakayama.jp\0com.pf\0"
-"inagawa.hyogo.jp\0draydns.de\0"
-"com.ph\0"
-"reggioemilia.it\0yuki.ibaraki.jp\0starostwo.gov.pl\0"
-"com.pk\0"
-"com.pl\0\xe7\xb5\x84\xe7\xb9\x94.\xe9\xa6\x99\xe6\xb8\xaf\0"
-"sakado.saitama.jp\0"
-"exeter.museum\0s\xc3\xb8ndre-land.no\0cc.ok.us\0"
-"com.qa\0"
+"*.fj\0"
+"*.fk\0"
+"\xe4\xb8\x89\xe9\x87\x8d.jp\0"
+"com.pa\0cc.pa.us\0"
+"nishinomiya.hyogo.jp\0"
+"tsurugashima.saitama.jp\0"
+"aukra.no\0com.pe\0"
+"hara.nagano.jp\0com.pf\0man\0"
+"pharmacy.museum\0"
+"piemonte.it\0trentinosudtirol.it\0com.ph\0map\0zapto.xyz\0"
+"mba\0"
+"izena.okinawa.jp\0"
+"museumvereniging.museum\0com.pk\0"
+"tomioka.gunma.jp\0com.pl\0"
+"takasaki.gunma.jp\0hiraizumi.iwate.jp\0"
+"info.ro\0"
+"historichouses.museum\0com.qa\0"
"com.pr\0"
-"culturalcenter.museum\0sandefjord.no\0com.ps\0agency\0"
-"halloffame.museum\0com.pt\0"
-"leangaviika.no\0"
-"x443.pw\0"
-"nyuzen.toyama.jp\0com.py\0barsy.menu\0"
-"piedmont.it\0"
-"decorativearts.museum\0lib.mo.us\0"
-"gniezno.pl\0dyndns.info\0"
-"sm.ua\0"
-"risor.no\0"
-"sasayama.hyogo.jp\0"
-"saitama.saitama.jp\0"
-"com.re\0"
-"kanoya.kagoshima.jp\0"
-"med.ly\0"
-"hitachiota.ibaraki.jp\0atlanta.museum\0"
-"sld.pa\0"
+"com.ps\0"
+"com.pt\0info.sd\0"
+"g\xc3\xa1\xc5\x8bgaviika.no\0"
+"hida.gifu.jp\0"
+"hotel.lk\0com.py\0paris\0"
+"\xe5\xb1\xb1\xe5\x8f\xa3.jp\0fujixerox\0"
+"yachiyo.chiba.jp\0"
+"trentinosued-tirol.it\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4\0"
+"holtalen.no\0"
+"\xe7\xb5\x84\xe7\xb9\x94.tw\0"
+"soeda.fukuoka.jp\0"
+"gorge.museum\0com.re\0au.eu.org\0be.eu.org\0"
+"info.pk\0"
+"trentinosuedtirol.it\0tokamachi.niigata.jp\0gushikami.okinawa.jp\0info.pl\0ltd\0"
+"miyoshi.saitama.jp\0art.sn\0"
"com.ro\0"
-"yodobashi\0"
-"com.sa\0land-4-sale.us\0"
-"com.sb\0"
-"com.sc\0"
-"com.sd\0direct\0"
-"com.se\0com.ru\0"
-"s3-website-us-west-2.amazonaws.com\0"
-"h\xc3\xa1pmir.no\0com.rw\0com.sg\0"
+"denmark.museum\0uhren.museum\0com.sa\0servegame.com\0"
+"info.pr\0com.sb\0"
+"com.sc\0nom.za\0"
+"hs.kr\0com.sd\0"
+"\xc3\xa5l.no\0com.se\0com.ru\0"
+"mashiki.kumamoto.jp\0"
+"com.rw\0com.sg\0"
"com.sh\0"
-"\xe5\x95\x86\xe6\xa0\x87\0"
-"com.sl\0"
-"nishinomiya.hyogo.jp\0kustanai.ru\0"
-"com.sn\0"
-"passenger-association.aero\0com.so\0"
-"tsushima.nagasaki.jp\0"
-"com.st\0uy.com\0"
-"x.se\0isa-geek.com\0"
-"com.sv\0"
-"\xe8\x8c\xa8\xe5\x9f\x8e.jp\0otama.fukushima.jp\0"
-"com.sy\0"
+"rade.no\0americanfamily\0"
+"valledaosta.it\0"
+"froya.no\0"
+"store.bb\0com.sl\0med\0"
+"com.sn\0ericsson\0"
+"com.so\0git-repos.de\0"
+"ryuoh.shiga.jp\0"
+"*.jm\0info.na\0is-a-democrat.com\0"
+"britishcolumbia.museum\0"
+"motobu.okinawa.jp\0com.st\0"
+"myravendb.com\0"
+"info.mv\0info.nf\0com.sv\0men\0"
+"trainer.aero\0"
+"info.ni\0com.sy\0barsy.bg\0"
"com.tj\0"
-"crimea.ua\0ybo.faith\0"
-"jinsekikogen.hiroshima.jp\0nishikawa.yamagata.jp\0sor-aurdal.no\0"
-"\xc3\xa5mli.no\0t\xc3\xb8nsberg.no\0med.om\0com.tm\0kustanai.su\0"
+"*.kh\0"
+"com.tm\0"
"com.tn\0"
-"hatoyama.saitama.jp\0museumcenter.museum\0com.to\0"
-"med.pa\0com.ua\0"
-"charter.aero\0pvh.br\0com.tr\0simple-url.com\0"
-"salvador.br\0"
-"com.tt\0"
-"com.tw\0com.ug\0"
-"marche.it\0"
-"goodyear\0"
-"sap\0"
-"dyndns-office.com\0hzc.io\0med.pl\0"
-"kvitsoy.no\0cn.eu.org\0"
-"saobernardo.br\0tp.it\0sas\0"
-"carboniaiglesias.it\0"
-"rmit\0"
-"boavista.br\0kawaba.gunma.jp\0com.vc\0"
-"photos\0sbi\0"
-"com.ve\0"
-"vgs.no\0"
-"bialowieza.pl\0"
-"hakuba.nagano.jp\0com.uy\0com.vi\0"
-"l\xc3\xb8ten.no\0com.uz\0"
-"sca\0"
-"mod.gi\0scb\0"
-"aizuwakamatsu.fukushima.jp\0com.vn\0sbs\0"
-"\xe5\x85\xb5\xe5\xba\xab.jp\0"
-"tinn.no\0dynamisches-dns.de\0"
-"from-vt.com\0"
-"from-az.net\0"
-"delta\0"
-"lucerne.museum\0com.vu\0"
-"minamisanriku.miyagi.jp\0"
-"oki.fukuoka.jp\0"
-"hita.oita.jp\0fyresdal.no\0"
-"saito.miyazaki.jp\0"
-"ingatlan.hu\0"
-"med.sa\0"
-"com.ws\0s3.dualstack.eu-west-2.amazonaws.com\0"
-"qc.ca\0med.sd\0"
-"olbiatempio.it\0"
-"\xe6\x9b\xb8\xe7\xb1\x8d\0"
-"chirurgiens-dentistes-en-france.fr\0"
-"firestone\0*.compute.amazonaws.com.cn\0"
-"pilot.aero\0m\xc3\xa5lselv.no\0"
-"barrell-of-knowledge.info\0"
-"guge\0play\0c.la\0"
-"\xe7\xb5\x84\xe7\xb9\x94.hk\0iwaki.fukushima.jp\0law.za\0"
-"is-an-entertainer.com\0"
-"mamurogawa.yamagata.jp\0"
-"run\0"
-"se.net\0ru.net\0"
-"scienceandhistory.museum\0investments\0ravendb.me\0"
-"anthro.museum\0"
-"izu.shizuoka.jp\0ses\0"
-"sew\0"
-"sex\0"
-"coloradoplateau.museum\0"
-"lc.it\0\xe5\xae\xae\xe5\x9f\x8e.jp\0stokke.no\0"
-"kurume.fukuoka.jp\0"
-"gratangen.no\0"
-"kotohira.kagawa.jp\0ohkura.yamagata.jp\0gateway.museum\0"
-"canada.museum\0exnet.su\0"
-"shinonsen.hyogo.jp\0"
-"sk.ca\0com.zm\0sfr\0"
-"kitaura.miyazaki.jp\0githubusercontent.com\0"
-"oita.jp\0rwe\0"
-"dynu.net\0"
-"otake.hiroshima.jp\0"
-"kinko.kagoshima.jp\0"
-"pippu.hokkaido.jp\0"
-"gv.ao\0data\0"
-"skydiving.aero\0"
-"tsushima.aichi.jp\0date\0cy.eu.org\0servehttp.com\0"
-"gv.at\0"
-"nakatane.kagoshima.jp\0"
-"sakurai.nara.jp\0as.us\0academy\0"
-"tadaoka.osaka.jp\0"
-"steigen.no\0"
-"recreation.aero\0omachi.saga.jp\0aquarium.museum\0"
-"gouv.fr\0nanjo.okinawa.jp\0"
-"za.net\0"
-"etisalat\0dynalias.net\0sp.leg.br\0"
-"memorial.museum\0"
-"motobu.okinawa.jp\0"
-"gs.sf.no\0ro.eu.org\0"
-"lincoln\0"
-"selfip.info\0"
-"mielno.pl\0us-east-1.amazonaws.com\0"
-"kazo.saitama.jp\0on-the-web.tv\0"
-"sar.it\0"
-"omaezaki.shizuoka.jp\0is-into-anime.com\0"
-"newjersey.museum\0"
-"edunet.tn\0cz.eu.org\0"
-"ayase.kanagawa.jp\0"
-"kitanakagusuku.okinawa.jp\0rad\xc3\xb8y.no\0maison\0"
-"trentinoa-adige.it\0scrysec.com\0"
-"kamigori.hyogo.jp\0"
-"kashima.saga.jp\0notaires.km\0"
-"v.bg\0"
-"furukawa.miyagi.jp\0"
-"shirahama.wakayama.jp\0"
-"gouv.ht\0"
-"sodegaura.chiba.jp\0plantation.museum\0"
-"taifun-dns.de\0"
-"fujinomiya.shizuoka.jp\0luxembourg.museum\0"
-"help\0"
-"lans.museum\0askvoll.no\0cc.ca.us\0racing\0map.fastlylb.net\0"
-"koriyama.fukushima.jp\0communication.museum\0"
-"copenhagen.museum\0western.museum\0ski\0"
-"konsulat.gov.pl\0"
-"comsec\0"
-"ravendb.community\0"
-"savona.it\0"
-"dk.eu.org\0"
-"gouv.bj\0"
-"aurskog-h\xc3\xb8land.no\0"
-"skodje.no\0sky\0"
-"koshigaya.saitama.jp\0c.se\0"
-"monzaebrianza.it\0"
-"inami.toyama.jp\0"
-"ptplus.fit\0"
-"gouv.ci\0"
-"geekgalaxy.com\0"
-"pagefrontapp.com\0"
-"overhalla.no\0lidl\0si.eu.org\0"
-"sugito.saitama.jp\0grajewo.pl\0"
-"en.it\0"
-"cloudns.club\0"
-"crafts.museum\0"
-"axis.museum\0"
-"nakatombetsu.hokkaido.jp\0"
-"kumamoto.jp\0"
-"virtuel.museum\0"
-"convent.museum\0"
-"figueres.museum\0ustka.pl\0"
-"vardo.no\0blogdns.org\0"
-"life\0"
-"eastcoast.museum\0dep.no\0"
-"firmdale\0"
-"sunndal.no\0servepics.com\0"
-"durham.museum\0contact\0"
-"settsu.osaka.jp\0"
-"bv.nl\0"
-"akune.kagoshima.jp\0"
-"chiba.jp\0"
-"nid.io\0"
-"\xc3\xa5lesund.no\0"
-"komagane.nagano.jp\0"
-"tenri.nara.jp\0"
-"kasama.ibaraki.jp\0ullensvang.no\0\xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\0de.eu.org\0"
-"tondabayashi.osaka.jp\0"
-"aso.kumamoto.jp\0"
-"br\xc3\xb8nn\xc3\xb8y.no\0here\0"
-"kuromatsunai.hokkaido.jp\0everbank\0soy\0from-nv.com\0"
-"drammen.no\0"
-"on.ca\0"
-"univ.sn\0"
-"vc.it\0"
-"contemporary.museum\0farsund.no\0wang\0"
-,
-
-"obama.nagasaki.jp\0supplies\0"
-"s3-eu-west-1.amazonaws.com\0bci.dnstrace.pro\0"
-"tab\0"
-"krym.ua\0usr.cloud.muni.cz\0"
-"sk.eu.org\0"
-"\xe0\xb8\x98\xe0\xb8\xb8\xe0\xb8\xa3\xe0\xb8\x81\xe0\xb8\xb4\xe0\xb8\x88.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0fujitsu\0s3-ap-south-1.amazonaws.com\0cn.com\0"
-"ks.ua\0"
-"asahi.toyama.jp\0other.nf\0guru\0us-east-2.elasticbeanstalk.com\0"
-"nordre-land.no\0rackmaze.net\0"
-"kanan.osaka.jp\0"
-"autos\0"
-"gangaviika.no\0"
-"baby\0"
-"shell.museum\0"
-"melhus.no\0"
-"\xc3\xa5mot.no\0"
-"tax\0"
-"ugim.gov.pl\0ks.us\0"
-"hioki.kagoshima.jp\0"
-"srl\0from-va.com\0"
-"epson\0s3-website.ca-central-1.amazonaws.com\0"
-"dsmynas.com\0"
-"natal.br\0"
-"friulive-giulia.it\0photography\0"
-"\xe5\xaf\x8c\xe5\xb1\xb1.jp\0sano.tochigi.jp\0"
-"tselinograd.su\0lcube-server.de\0"
-"bunkyo.tokyo.jp\0srt\0"
-"grainger\0"
-"genkai.saga.jp\0meteorapp.com\0"
-"certmgr.org\0"
-"tci\0"
-"cc.wv.us\0"
-"mansion.museum\0lib.ia.us\0"
-"oppeg\xc3\xa5rd.no\0oster\xc3\xb8y.no\0like\0"
-"corporation.museum\0"
-"foz.br\0yamato.kumamoto.jp\0"
-"naie.hokkaido.jp\0"
-"9.bg\0yame.fukuoka.jp\0"
-"stc\0"
-"matsuda.kanagawa.jp\0"
-"gol.no\0"
-"\xe9\x80\x9a\xe8\xb2\xa9\0"
-"drayddns.com\0"
-"us.na\0caseih\0tdk\0"
-"narvik.no\0"
-"jpmorgan\0"
-"selfip.org\0"
-"town\0"
-"ru.eu.org\0se.eu.org\0"
-"langevag.no\0"
-"market\0"
-"su\xcc\x88""dtirol.it\0"
-"cc.ma.us\0"
-"tel\0"
-"bulsan.it\0"
-"masoy.no\0"
-"k12.nm.us\0"
-"sanofi\0"
-"cloudns.info\0"
-"lib.ky.us\0"
-"obama.fukui.jp\0limo\0"
-"a.bg\0r\xc3\xa1isa.no\0"
-"cymru.museum\0isa-geek.net\0"
-"aq.it\0ba.it\0"
-"link\0"
-"bozen-suedtirol.it\0minamiminowa.nagano.jp\0cc.al.us\0lima.zone\0"
-"toys\0"
-"sciencecenters.museum\0"
-"guardian\0"
-"kongsberg.no\0"
-"cc.ny.us\0ca.eu.org\0"
-"trentino-alto-adige.it\0kitaaiki.nagano.jp\0lib.al.us\0thd\0"
-"halden.no\0"
-"fashion\0"
-"myftp.biz\0"
-"moriyama.shiga.jp\0rsc.cdn77.org\0from-ky.com\0"
-"\xe4\xb8\x89\xe9\x87\x8d.jp\0fidelity\0"
-"\xe5\xb1\xb1\xe6\xa2\xa8.jp\0"
-"somna.no\0"
-"productions\0voting\0"
-"forde.no\0"
-"chikuzen.fukuoka.jp\0plus\0"
-"mashike.hokkaido.jp\0"
-"leksvik.no\0"
-"hagi.yamaguchi.jp\0"
-"publ.pt\0"
-"1kapp.com\0"
-"\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0"
-"showa.fukushima.jp\0"
-"yamatsuri.fukushima.jp\0is-a-designer.com\0"
-"cc.ct.us\0"
-"takikawa.hokkaido.jp\0*.stolos.io\0"
-"cpa.pro\0garden\0"
-"wiki.bo\0"
-"wiki.br\0"
-"itayanagi.aomori.jp\0store.nf\0"
-"asahikawa.hokkaido.jp\0fudai.iwate.jp\0"
-"dallas.museum\0"
-"is-an-anarchist.com\0"
-"sakegawa.yamagata.jp\0"
-"kanagawa.jp\0yamatotakada.nara.jp\0alabama.museum\0"
-"\xd0\xbe\xd0\xbd\xd0\xbb\xd0\xb0\xd0\xb9\xd0\xbd\0"
-"tjx\0"
-"est-a-la-maison.com\0"
-"yn.cn\0"
-"funahashi.toyama.jp\0torino.museum\0"
-"eiheiji.fukui.jp\0coldwar.museum\0"
-"podhale.pl\0airbus\0"
-"yamada.iwate.jp\0"
-"walmart\0on-web.fr\0"
-"friuli-v-giulia.it\0"
-"hareid.no\0cc.fl.us\0"
-"valled-aosta.it\0"
-"shiroishi.saga.jp\0"
-"band\0"
-"karumai.iwate.jp\0"
-"tn.it\0gouv.rw\0"
-"spjelkavik.no\0zachpomor.pl\0"
-"iwaizumi.iwate.jp\0"
-"turek.pl\0\xe5\xb7\xa5\xe8\xa1\x8c\0"
-"exhibition.museum\0serveftp.com\0"
-"otaki.saitama.jp\0m\xc3\xa1latvuopmi.no\0bank\0"
-"lib.fl.us\0social\0"
-"bronnoy.no\0hoyanger.no\0gouv.sn\0software\0"
-"stalowa-wola.pl\0consulting\0spdns.eu\0"
-"kaufen\0"
-"tromsa.no\0"
-"takatsuki.osaka.jp\0"
-"kagamiishi.fukushima.jp\0cd.eu.org\0"
-"sondre-land.no\0"
-"tennis\0"
-"ginoza.okinawa.jp\0"
-"s3.eu-central-1.amazonaws.com\0"
-"ngo.lk\0"
-"beardu.no\0"
-"rikuzentakata.iwate.jp\0live\0"
-"rotorcraft.aero\0"
-"frei.no\0"
-"sk\xc3\xa1nit.no\0mazowsze.pl\0cc.id.us\0tunk.org\0"
-"laquila.it\0"
-"ricoh\0"
-"nagi.okayama.jp\0"
-"vv.it\0"
-"shacknet.nu\0"
-"arab\0"
-"matsusaka.mie.jp\0cc.wa.us\0"
-"daiwa.hiroshima.jp\0dnsking.ch\0"
-"sardinia.it\0mihara.kochi.jp\0lanbib.se\0top\0"
-"prato.it\0lixil\0"
-"nosegawa.nara.jp\0lv.ua\0"
-"namegata.ibaraki.jp\0wolomin.pl\0christmas\0"
-"sp.gov.br\0"
-"dclk\0"
-"nesseby.no\0lib.vi.us\0"
-"trentinsuedtirol.it\0herokussl.com\0"
-"ham-radio-op.net\0"
-"shiogama.miyagi.jp\0jobs.tt\0"
-"kawara.fukuoka.jp\0"
-"nsw.au\0divtasvuodna.no\0"
-"res.aero\0"
-"kagamino.okayama.jp\0alvdal.no\0"
-"enonic.io\0"
-"mex.com\0"
-"devices.resinstaging.io\0"
-"nebraska.museum\0"
-"jamison.museum\0"
-"esp.br\0"
-"muosat.no\0"
-"chiyoda.gunma.jp\0"
-"monza-e-della-brianza.it\0okutama.tokyo.jp\0sn\xc3\xa5""ase.no\0s\xc3\xb8rreisa.no\0email\0"
-"cuiaba.br\0"
-"yasugi.shimane.jp\0ngo.ph\0store.ve\0"
-"shimabara.nagasaki.jp\0"
-"friuli-venezia-giulia.it\0"
-"zaporizhzhe.ua\0mortgage\0"
-"brunel.museum\0"
-"my.id\0kita.kyoto.jp\0kawatana.nagasaki.jp\0mugi.tokushima.jp\0"
-"ubs\0kalmykia.su\0cust.dev.thingdust.io\0"
-"newholland\0trv\0"
-"assn.lk\0spdns.de\0"
-"embroidery.museum\0"
-"shiriuchi.hokkaido.jp\0"
-"utah.museum\0forsand.no\0mycd.eu\0"
-"fukuoka.jp\0so.gov.pl\0"
-"romsa.no\0"
-"odate.akita.jp\0anamizu.ishikawa.jp\0tateyama.toyama.jp\0bodo.no\0holdings\0"
-"cc.mt.us\0cc.nd.us\0"
-"go.dyndns.org\0"
-"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86.ir\0alta.no\0"
-"ukiha.fukuoka.jp\0"
-"sites.static.land\0"
-"stordal.no\0"
-"katsuragi.nara.jp\0"
-"katori.chiba.jp\0"
-"firm.ht\0sener\0"
-"lib.md.us\0from-nj.com\0za.org\0"
-"tokyo.jp\0higashiizu.shizuoka.jp\0"
-"t.bg\0shimotsuke.tochigi.jp\0gouv.km\0"
-"verran.no\0"
-"tui\0"
-"uri.arpa\0firm.in\0ureshino.mie.jp\0flynnhub.com\0"
-"notaires.fr\0*.elb.amazonaws.com\0"
-"bt.it\0gjesdal.no\0"
-"*.kitakyushu.jp\0shijonawate.osaka.jp\0cloud.goog\0"
-"aikawa.kanagawa.jp\0"
-"edogawa.tokyo.jp\0\xe5\xa4\xa7\xe4\xbc\x97\xe6\xb1\xbd\xe8\xbd\xa6\0"
-"kalmykia.ru\0"
-"enna.it\0leitungsen.de\0"
-"morotsuka.miyazaki.jp\0nichinan.tottori.jp\0burghof.museum\0\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0"
-"ryuoh.shiga.jp\0"
-"fortal.br\0!city.nagoya.jp\0kamoenai.hokkaido.jp\0int.eu.org\0"
-"floro.no\0holt\xc3\xa5len.no\0"
-"condos\0stream\0"
-"supply\0bmoattachments.org\0"
-"to.leg.br\0"
-"kanzaki.saga.jp\0store.ro\0"
-"jl.cn\0taiki.mie.jp\0tvs\0"
-"jerusalem.museum\0"
-"gouv.ml\0""3utilities.com\0"
-"a.se\0pramerica\0"
-"money.museum\0"
-"firm.co\0"
-"ono.fukushima.jp\0nordreisa.no\0"
-"room\0"
-"paragliding.aero\0pri.ee\0hobby-site.com\0"
-"pasadena.museum\0"
-"newmexico.museum\0"
-"bremanger.no\0ga.us\0"
-"ostroleka.pl\0store.st\0s3-website.eu-west-3.amazonaws.com\0"
-"firm.dk\0"
-"fineart.museum\0"
-"osaka.jp\0"
-"trentinsu\xcc\x88""dtirol.it\0"
-"torahime.shiga.jp\0unusualperson.com\0"
-"priv.hu\0tn.us\0alpha-myqnapcloud.com\0"
-"si.it\0miyashiro.saitama.jp\0"
-"*.awdev.ca\0"
-"tsukumi.oita.jp\0"
-"cc.sd.us\0"
-"md.ci\0kaneyama.fukushima.jp\0"
-"kakamigahara.gifu.jp\0lib.dc.us\0"
-"vologda.su\0"
-"\xd8\xa8\xd8\xa7\xd8\xb1\xd8\xaa\0"
-"yotsukaido.chiba.jp\0motorcycle.museum\0"
-"bugatti\0"
-"ogawa.nagano.jp\0dentist\0"
-"chitose.hokkaido.jp\0debian.net\0"
-"chicago.museum\0newhampshire.museum\0stavanger.no\0"
-"n\xc3\xa1vuotna.no\0"
-"can.museum\0oceanographic.museum\0definima.net\0"
-"telefonica\0"
-"chrome\0"
-"cal.it\0"
-"living\0cyon.site\0"
-"va.it\0"
-"trust\0"
-"kakogawa.hyogo.jp\0"
-"group\0"
-"ngo.za\0"
-"ong.br\0"
-"\xe0\xa8\xad\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\xa4\0"
-"morena.br\0"
-"s3.cn-north-1.amazonaws.com.cn\0"
-"yura.wakayama.jp\0dnsupdater.de\0"
-"shirataka.yamagata.jp\0"
-"army\0dynalias.org\0"
-"fukuroi.shizuoka.jp\0la.us\0"
-"priv.at\0"
-"kira.aichi.jp\0nagai.yamagata.jp\0kristiansand.no\0"
-"sr.gov.pl\0"
-"abogado\0"
-"asahi.ibaraki.jp\0"
-"\xe7\xa7\x8b\xe7\x94\xb0.jp\0yakumo.hokkaido.jp\0higashikagawa.kagawa.jp\0dnepropetrovsk.ua\0"
-"askoy.no\0"
-"fishing\0"
+"depot.museum\0com.to\0"
+"com.ua\0safe\0"
+"info.nr\0com.tr\0pohl\0"
+"tysvar.no\0"
+"re.it\0com.tt\0"
+"muncie.museum\0com.tw\0cherkassy.ua\0com.ug\0"
+"geisei.kochi.jp\0izumi.osaka.jp\0swidnik.pl\0"
+"tomobe.ibaraki.jp\0"
+"exeter.museum\0"
+"monzabrianza.it\0"
+"info.la\0bitballoon.com\0"
+"\xe0\xb8\x97\xe0\xb8\xab\xe0\xb8\xb2\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0istanbul\0"
+"hotel.hu\0com.vc\0barcelona\0"
+"com.ve\0realestate\0store.dk\0bg.eu.org\0"
+"flog.br\0"
+"\xe7\xbb\x84\xe7\xb9\x94.hk\0barsy.de\0"
+"com.uy\0com.vi\0ddnsking.com\0"
+"com.uz\0"
+"com.vn\0"
+"bronnoysund.no\0"
+"toya.hokkaido.jp\0ebina.kanagawa.jp\0"
+"*.mm\0zoological.museum\0lind\xc3\xa5s.no\0"
+"re.kr\0"
+"info.ls\0no-ip.co.uk\0"
+"com.vu\0"
+"finearts.museum\0"
+"hiratsuka.kanagawa.jp\0"
+"media.hu\0iron.museum\0"
+"jampa.br\0"
+"k12.nj.us\0"
"tamano.okayama.jp\0"
-"arpa\0*.sensiosite.cloud\0"
-"birkenes.no\0sejny.pl\0"
-"7.bg\0uno\0"
-"hisayama.fukuoka.jp\0delivery\0"
-"adm.br\0skanit.no\0"
-"praxi\0getmyip.com\0"
-"lib.vt.us\0"
-"friuliv-giulia.it\0"
-"agrar.hu\0"
-"williamsburg.museum\0"
-"minamioguni.kumamoto.jp\0"
-"uol\0"
-"beskidy.pl\0df.leg.br\0"
-"archi\0"
-"2000.hu\0kyoto.jp\0mitoyo.kagawa.jp\0"
-"lt.it\0"
-"cosenza.it\0va.no\0"
-"musica.ar\0cuisinella\0"
-"mus.mi.us\0"
-"chiryu.aichi.jp\0kyiv.ua\0"
-"services.aero\0takahama.fukui.jp\0yanagawa.fukuoka.jp\0kautokeino.no\0"
-"fl\xc3\xa5.no\0"
-"ups\0"
-"tonosho.kagawa.jp\0"
-"forum.hu\0is-a-personaltrainer.com\0"
-"musica.bo\0otsuchi.iwate.jp\0adygeya.su\0"
-"broker.aero\0yonabaru.okinawa.jp\0"
-"s3-us-east-2.amazonaws.com\0"
-"ao.it\0"
-"firm.ve\0*.ex.futurecms.at\0"
-"shiiba.miyazaki.jp\0management\0"
-"ichinohe.iwate.jp\0lardal.no\0"
-"blogdns.net\0"
-"lazio.it\0"
-"trentinoaadige.it\0asda\0"
+"misaki.okayama.jp\0cloudns.club\0"
+"heroy.nordland.no\0"
+"homeftp.net\0"
+"com.ws\0"
+"mil\0*.np\0hgtv\0"
+"varggat.no\0"
+"vlog.br\0oharu.aichi.jp\0"
+"barsy.eu\0"
+"mit\0"
+"pa.us\0"
+"friulivegiulia.it\0"
+"town.museum\0"
+"\xe5\xb1\xb1\xe5\xbd\xa2.jp\0hidaka.saitama.jp\0"
+"ab.ca\0info.ke\0forum\0us.com\0"
+"chuo.fukuoka.jp\0sklep.pl\0"
+"qld.au\0"
+"info.ki\0"
+"jinsekikogen.hiroshima.jp\0yashio.saitama.jp\0"
+"*.pg\0"
+"lib.mi.us\0"
+"to.leg.br\0"
+"comsec\0"
+"jan-mayen.no\0"
+"loten.no\0drud.us\0"
+"a.se\0army\0east-kazakhstan.su\0"
+"tomiya.miyagi.jp\0"
+"mlb\0"
+"s3-website.ap-south-1.amazonaws.com\0kurgan.su\0"
+"sld.do\0com.zm\0"
+"campidanomedio.it\0"
+"luxembourg.museum\0sale\0"
+"ouda.nara.jp\0"
+"dynamic-dns.info\0"
+"griw.gov.pl\0"
+"s3-external-1.amazonaws.com\0"
+"karikatur.museum\0project.museum\0mma\0"
+"kg.kr\0"
+"mls\0"
+"arpa\0michigan.museum\0"
+"nanporo.hokkaido.jp\0uppo.gov.pl\0"
+"flesberg.no\0"
+"barsy.in\0"
+"it.ao\0time.no\0barsy.io\0"
+"freemasonry.museum\0africa\0hr.eu.org\0"
+"ntdll.top\0"
+"r.bg\0skierva.no\0qc.com\0"
+"r\xc3\xa1isa.no\0parts\0"
+"omiya.saitama.jp\0"
+"roma.museum\0"
+"res.aero\0party\0"
+"rockart.museum\0"
+"mj\xc3\xb8ndalen.no\0contractors\0passagens\0"
+"hamaroy.no\0"
+"go.gov.br\0"
+"educational.museum\0"
+"amagasaki.hyogo.jp\0frontier\0"
+"\xe7\xae\x87\xe4\xba\xba.hk\0ddr.museum\0s3.dualstack.ap-southeast-2.amazonaws.com\0"
+"weir\0"
+"feira.br\0asakawa.fukushima.jp\0"
+"fl\xc3\xa5.no\0k12.sc.us\0moe\0"
+"oregon.museum\0"
+"vercelli.it\0basketball\0"
+"aip.ee\0nedre-eiker.no\0moi\0"
+"togakushi.nagano.jp\0final\0barsy.support\0no-ip.biz\0"
+"consulting\0mom\0tires\0lcube-server.de\0"
+"voting\0"
+"is-a-landscaper.com\0"
+"conf.au\0suisse.museum\0"
+"kamikawa.hyogo.jp\0mov\0"
+"frogn.no\0"
+"media.pl\0"
+"bsb.br\0swiftcover\0"
+"koori.fukushima.jp\0porn\0noho.st\0"
+"b\xc3\xa5""d\xc3\xa5""ddj\xc3\xa5.no\0"
+"honbetsu.hokkaido.jp\0"
+"pacific.museum\0"
+"fm.br\0makinohara.shizuoka.jp\0"
+"nab\0myfritz.net\0"
+"co.krd\0"
+"asda\0"
+"pr.it\0kakamigahara.gifu.jp\0\xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\0deal\0"
+"aogashima.tokyo.jp\0"
"arte\0"
-"bulsan-suedtirol.it\0egyptian.museum\0"
-"kerryhotels\0"
-"hgtv\0"
-"\xe0\xb8\x84\xe0\xb8\xad\xe0\xb8\xa1\0"
-"lib.ms.us\0lib.nc.us\0"
-"valle-d-aosta.it\0komatsu.ishikawa.jp\0ringebu.no\0"
-"sagamihara.kanagawa.jp\0"
-"ug.gov.pl\0"
-"taranto.it\0"
-"ap-southeast-2.elasticbeanstalk.com\0"
-"ogi.saga.jp\0mill.museum\0"
-"health.nz\0"
-"adygeya.ru\0"
-"gru.br\0dyn.cosidns.de\0"
-"bbva\0tmall\0"
-"oshima.yamaguchi.jp\0sumy.ua\0"
-"shiga.jp\0sakawa.kochi.jp\0"
-"drive\0s3-ca-central-1.amazonaws.com\0"
-"mielec.pl\0"
-"minamiawaji.hyogo.jp\0okayama.okayama.jp\0baltimore.museum\0"
-"paleo.museum\0eidsberg.no\0"
-"hotels\0"
-"aero.tt\0"
-"deal\0"
-"drud.io\0"
-"alstahaug.no\0uconnect\0"
-"ryukyu\0"
-"suzuka.mie.jp\0ch.eu.org\0firewall-gateway.net\0"
-"naha.okinawa.jp\0"
-"entertainment.aero\0store.bb\0t.se\0vet\0"
+"reggioemilia.it\0ehime.jp\0teshikaga.hokkaido.jp\0"
+"santamaria.br\0"
+"cyber.museum\0"
+"nakagawa.hokkaido.jp\0yamato.kanagawa.jp\0ogimi.okinawa.jp\0"
+"nba\0"
+"post\0"
+"cahcesuolo.no\0"
+"android\0"
+"\xd9\x83\xd8\xa7\xd8\xab\xd9\x88\xd9\x84\xd9\x8a\xd9\x83\0"
+"s3-eu-central-1.amazonaws.com\0"
+"kawai.nara.jp\0\xe8\xb0\xb7\xe6\xad\x8c\0"
+"withgoogle.com\0"
+"nh-serv.co.uk\0"
+"iizuka.fukuoka.jp\0meiwa.mie.jp\0lezajsk.pl\0"
+"minamiboso.chiba.jp\0hashima.gifu.jp\0imamat\0"
+"manaus.br\0urbino-pesaro.it\0kariya.aichi.jp\0sarl\0"
+"vpnplus.to\0"
+"msd\0"
+"bbva\0"
+"meldal.no\0"
+"*.triton.zone\0"
+"crotone.it\0toho.fukuoka.jp\0"
+"portal.museum\0tr\xc3\xa6na.no\0\xd9\x82\xd8\xb7\xd8\xb1\0"
+"allfinanz\0"
+"heroy.more-og-romsdal.no\0"
+"*.ye\0"
+"nrw.museum\0"
+"does-it.net\0"
+"ginoza.okinawa.jp\0"
+"yahaba.iwate.jp\0"
+"cc.pr.us\0azerbaijan.su\0"
+"mtn\0"
+"cloudns.info\0"
+"abarth\0"
+"\xe1\x83\x92\xe1\x83\x94\0mtr\0"
+"nec\0"
+"yokote.akita.jp\0sodegaura.chiba.jp\0"
"l\xc3\xa1hppi.no\0"
-"brumunddal.no\0"
-"aero.mv\0kwpsp.gov.pl\0"
-"firm.ro\0"
-"eu-west-1.elasticbeanstalk.com\0"
-"keisen.fukuoka.jp\0dynv6.net\0"
-"klepp.no\0"
-"matsubushi.saitama.jp\0"
-"takazaki.miyazaki.jp\0irish\0"
-"taishi.hyogo.jp\0luster.no\0"
-"ol.no\0"
-"vallee-aoste.it\0"
-"sannohe.aomori.jp\0kumamoto.kumamoto.jp\0"
-"vacations\0"
-"va.us\0"
+"kitagawa.kochi.jp\0"
+"workinggroup.aero\0"
+"padova.it\0onga.fukuoka.jp\0"
+"stjordal.no\0us-east-1.elasticbeanstalk.com\0s3-sa-east-1.amazonaws.com\0"
+"\xe5\xbe\xb3\xe5\xb3\xb6.jp\0komatsu.ishikawa.jp\0"
+"gs.fm.no\0"
+"saobernardo.br\0"
+"globo\0"
+"okinawa.okinawa.jp\0net\0"
"asia\0"
-"hamburg\0"
-"agents.aero\0\xd9\x82\xd8\xb7\xd8\xb1\0"
-"sula.no\0\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xaa\xe0\xaf\x82\xe0\xae\xb0\xe0\xaf\x8d\0"
-"benevento.it\0"
-"yonezawa.yamagata.jp\0"
-"giessen.museum\0"
-"venezia.it\0serveirc.com\0"
-"dyr\xc3\xb8y.no\0"
-"toba.mie.jp\0"
-"higashi.fukushima.jp\0skoczow.pl\0"
-"store.dk\0"
-"esashi.hokkaido.jp\0lib.sc.us\0"
-"komae.tokyo.jp\0sells-it.net\0nalchik.ru\0"
-"daigo.ibaraki.jp\0kirkenes.no\0nowtv\0"
-"shiroi.chiba.jp\0kakegawa.shizuoka.jp\0mining.museum\0"
-"vig\0\xd8\xa8\xd9\x8a\xd8\xaa\xd9\x83\0"
-"myddns.rocks\0"
-"muos\xc3\xa1t.no\0"
-"oygarden.no\0"
-"gs.mr.no\0"
-"vin\0"
-"florence.it\0vip\0nalchik.su\0"
-"saitama.jp\0asnes.no\0"
-"tateshina.nagano.jp\0kamitsue.oita.jp\0firm.nf\0"
-"wy.us\0"
-"vt.it\0"
-"lerdal.no\0"
-"groks-this.info\0"
-"fujisawa.iwate.jp\0"
-"tas.au\0ibara.okayama.jp\0"
-"lt.ua\0"
-"health.museum\0"
-"pfizer\0"
-"toride.ibaraki.jp\0salangen.no\0"
-"toyonaka.osaka.jp\0charity\0"
-"izena.okinawa.jp\0school.museum\0"
-"l-o-g-i-n.de\0"
-"health.vn\0dyndns.biz\0"
-"friuli-ve-giulia.it\0vegarshei.no\0"
-"nahari.kochi.jp\0pohl\0"
-"dyndns-blog.com\0"
-"suldal.no\0md.us\0"
-"nord-aurdal.no\0"
-"higashi.fukuoka.jp\0"
-"gran.no\0"
-"app.os.stg.fedoraproject.org\0"
-"katsushika.tokyo.jp\0nanbu.yamanashi.jp\0anquan\0cloudns.eu\0"
-"honbetsu.hokkaido.jp\0"
-"salzburg.museum\0sorum.no\0"
-"asaminami.hiroshima.jp\0"
-"is-a-llama.com\0"
-"selfip.biz\0"
-"malatvuopmi.no\0rivne.ua\0lib.in.us\0"
-"\xe5\xb1\xb1\xe5\xbd\xa2.jp\0"
-"shikaoi.hokkaido.jp\0buyshouses.net\0"
-"lind\xc3\xa5s.no\0tarnobrzeg.pl\0"
-"forex\0"
-"andriabarlettatrani.it\0"
-"\xe0\xb9\x80\xe0\xb8\x99\xe0\xb9\x87\xe0\xb8\x95.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0"
-"toho.fukuoka.jp\0"
-"nationalfirearms.museum\0"
-"aioi.hyogo.jp\0at.eu.org\0georgia.su\0"
-"toei.aichi.jp\0onagawa.miyagi.jp\0"
-"to.gov.br\0\xe5\x80\x8b\xe4\xba\xba.hk\0blogsyte.com\0"
-"software.aero\0safe\0"
-"is-a-patsfan.org\0"
-"worse-than.tv\0"
-"gucci\0"
-"svizzera.museum\0"
-"cust.prod.thingdust.io\0"
-"contemporaryart.museum\0"
-"\xc3\xb8ksnes.no\0"
-"communications.museum\0"
-"hb.cn\0"
-"noho.st\0"
-"k12.oh.us\0today\0"
-"hayakawa.yamanashi.jp\0"
-"heroy.more-og-romsdal.no\0grondar.za\0"
-"vard\xc3\xb8.no\0"
-"kvam.no\0"
-"r.bg\0tcm.museum\0levanger.no\0cricket\0"
-"hashbang.sh\0"
-"holiday\0"
-"priv.pl\0"
-"miyazaki.miyazaki.jp\0cloudns.in\0"
-"habikino.osaka.jp\0dell\0"
-"weber\0"
-"br.it\0cb.it\0"
-"creditunion\0"
-"shitara.aichi.jp\0"
-"matsukawa.nagano.jp\0\xe0\xa4\x95\xe0\xa5\x89\xe0\xa4\xae\0"
-"madrid.museum\0redumbrella\0"
-"po.it\0ozora.hokkaido.jp\0"
-"trentinosud-tirol.it\0"
-"chernigov.ua\0k12.ca.us\0\xe4\xb8\xad\xe5\x9b\xbd\0"
-"taketomi.okinawa.jp\0mine.nu\0dray-dns.de\0"
-"kunitachi.tokyo.jp\0"
-"cloudns.cc\0"
-"nakamura.kochi.jp\0valer.hedmark.no\0drud.us\0"
-"fr\xc3\xb8ya.no\0"
-"wsa.gov.pl\0"
-"veterinaire.km\0"
-"abudhabi\0"
-"komono.mie.jp\0*.futurecms.at\0"
-"rebun.hokkaido.jp\0\xe4\xb8\xad\xe5\x9c\x8b\0"
-"fhsk.se\0"
-"priv.no\0"
-"mjondalen.no\0in.net\0"
-"computer.museum\0"
-"iraq.museum\0lund.no\0"
-"vercelli.it\0"
-"\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0mysecuritycamera.com\0"
-"monzaedellabrianza.it\0dnsdojo.org\0"
-"tarama.okinawa.jp\0"
-"toyoake.aichi.jp\0ichikawamisato.yamanashi.jp\0"
-"mb.ca\0francaise.museum\0"
-"fbx-os.fr\0"
-"topology.museum\0"
-"miyoshi.aichi.jp\0lib.de.us\0"
-"medizinhistorisches.museum\0salon\0"
-"sale\0"
-"ashibetsu.hokkaido.jp\0\xc3\xa5l.no\0brand.se\0"
-"shioya.tochigi.jp\0"
-"pilots.museum\0"
-"priv.me\0haugesund.no\0"
-"time.no\0healthcare\0"
-"gallery.museum\0"
-"tadotsu.kagawa.jp\0"
-"durban\0wed\0"
-"antiques.museum\0"
-"sandnes.no\0"
-"royken.no\0"
-"veterinaire.fr\0"
-"bnr.la\0"
-"am.br\0training\0edu.eu.org\0"
-"asuke.aichi.jp\0"
-"gr.it\0porn\0"
-"prof.pr\0mckinsey\0\xe9\xa6\x99\xe6\xa0\xbc\xe9\x87\x8c\xe6\x8b\x89\0"
-"act.edu.au\0atsugi.kanagawa.jp\0ventures\0at-band-camp.net\0"
-"kasamatsu.gifu.jp\0"
-"basilicata.it\0"
-"tatsuno.hyogo.jp\0kunohe.iwate.jp\0vt.us\0ownip.net\0"
-"siellak.no\0"
-"gr.jp\0"
-"trondheim.no\0"
-"svalbard.no\0"
-"niki.hokkaido.jp\0delaware.museum\0"
-"mosj\xc3\xb8""en.no\0"
-"yuza.yamagata.jp\0"
-"dental\0sharp\0*.magentosite.cloud\0"
-"dgca.aero\0"
-"df.gov.br\0post\0"
-"iz.hr\0"
-"abc.br\0desi\0"
-"dni.us\0"
-"aoki.nagano.jp\0"
-"bir.ru\0"
-"sakura.tochigi.jp\0"
-"gs.ah.no\0"
-"college\0"
-"her\xc3\xb8y.m\xc3\xb8re-og-romsdal.no\0"
-"abira.hokkaido.jp\0"
-"karlsoy.no\0"
-"dance\0"
-"sakuho.nagano.jp\0"
-"!city.sendai.jp\0chijiwa.nagasaki.jp\0"
-"empresa.bo\0"
-"nishigo.fukushima.jp\0anthropology.museum\0"
-"git-repos.de\0"
-"americanart.museum\0"
-"s3.us-east-2.amazonaws.com\0wmflabs.org\0"
-"for-better.biz\0"
-"final\0"
-"test-iserv.de\0"
-"colonialwilliamsburg.museum\0"
-"5.bg\0"
-"stjohn.museum\0win\0"
-"r\xc3\xa5holt.no\0insure\0"
-"spreadbetting\0"
-"yamada.toyama.jp\0on-aptible.com\0"
-"cipriani\0"
-"srv.br\0from-de.com\0gotdns.com\0"
-"selfip.com\0"
-"nationwide\0"
-"bruxelles.museum\0"
-"okuma.fukushima.jp\0silk.museum\0"
-"opole.pl\0"
-"fm.br\0s3-external-1.amazonaws.com\0"
-"tamaki.mie.jp\0sarl\0"
-"mb.it\0"
-"tarui.gifu.jp\0fujiidera.osaka.jp\0t3l3p0rt.net\0"
-"\xd8\xa7\xd8\xb1\xd8\xa7\xd9\x85\xd9\x83\xd9\x88\0"
-"karasjohka.no\0"
-"shikama.miyagi.jp\0"
-"gen.mi.us\0"
-"amagasaki.hyogo.jp\0togakushi.nagano.jp\0kirovograd.ua\0"
-"sor-fron.no\0"
-"k12.ma.us\0"
-"\xe7\xbb\x84\xe7\xb9\x94.hk\0wassamu.hokkaido.jp\0arakawa.tokyo.jp\0"
-"onojo.fukuoka.jp\0horonobe.hokkaido.jp\0"
-"g12.br\0"
-"honai.ehime.jp\0bilbao.museum\0"
-"tj.cn\0oyer.no\0"
-"reggio-emilia.it\0"
-"weir\0"
-"miasta.pl\0cloudns.us\0"
-"rj.leg.br\0"
-"zushi.kanagawa.jp\0chiropractic.museum\0forum\0"
-"rzgw.gov.pl\0cistron.nl\0"
-"wme\0"
-"shirako.chiba.jp\0spacekit.io\0"
-"\xc3\xa5krehamn.no\0averoy.no\0"
-"resistance.museum\0"
-"firebaseapp.com\0"
-"hanyu.saitama.jp\0sandiego.museum\0"
-"workshop.museum\0"
-"homesecuritypc.com\0"
-"from-or.com\0"
-"honeywell\0sells-for-u.com\0"
-"\xe0\xb4\xad\xe0\xb4\xbe\xe0\xb4\xb0\xe0\xb4\xa4\xe0\xb4\x82\0"
-"hirono.iwate.jp\0"
-"chita.aichi.jp\0"
+"melhus.no\0new\0"
+"vao.it\0"
"save\0"
-"toyooka.hyogo.jp\0"
-"lib.ne.us\0"
-"ichikawa.chiba.jp\0"
-"imari.saga.jp\0"
-"oslo.no\0"
-"hinode.tokyo.jp\0"
-"deloitte\0\xe6\x89\x8b\xe8\xa1\xa8\0"
-"n\xc3\xb8tter\xc3\xb8y.no\0is-into-cartoons.com\0"
-"kepno.pl\0"
-"rexroth\0"
-"cheltenham.museum\0"
-"au.eu.org\0be.eu.org\0"
-"lel.br\0"
-"hitachiomiya.ibaraki.jp\0"
-"alessandria.it\0tsu.mie.jp\0wow\0xenapponazure.com\0"
-"warabi.saitama.jp\0"
-"a.ssl.fastly.net\0"
-"nakanojo.gunma.jp\0"
-"mitsuke.niigata.jp\0tama.tokyo.jp\0"
-"r.se\0saxo\0"
-"google\0"
-"xz.cn\0"
-"civilization.museum\0"
-"*.sch.uk\0"
-"livorno.it\0medecin.km\0"
-"s3.dualstack.ap-southeast-2.amazonaws.com\0"
-"fm.it\0owani.aomori.jp\0kasai.hyogo.jp\0"
-"midsund.no\0"
-"kaga.ishikawa.jp\0"
-"eigersund.no\0"
-"izumo.shimane.jp\0"
-"fr\xc3\xa6na.no\0"
-"taishi.osaka.jp\0quebec\0"
-"illustration.museum\0"
-"takinoue.hokkaido.jp\0"
-"vald-aosta.it\0audi\0"
-"barlettatraniandria.it\0samsclub\0"
-"marshalls\0no-ip.org\0"
-"\xe6\x85\x88\xe5\x96\x84\0"
-"froya.no\0"
-"ube.yamaguchi.jp\0"
-"kota.aichi.jp\0hitachi.ibaraki.jp\0wildlife.museum\0s\xc3\xb8mna.no\0"
-"bg.eu.org\0"
-"wtc\0dagestan.ru\0"
-"\xe6\x84\x9b\xe7\x9f\xa5.jp\0"
-"clubmed\0wtf\0"
-"tagajo.miyagi.jp\0"
-"krasnodar.su\0"
-"basel.museum\0beer\0"
-"niepce.museum\0"
-"amber.museum\0england.museum\0"
-"rishiri.hokkaido.jp\0"
-"vr.it\0dagestan.su\0"
-"bod\xc3\xb8.no\0"
-"b\xc3\xa1hcavuotna.no\0"
-"crotone.it\0"
-"viking\0"
-"tsuru.yamanashi.jp\0"
-"ba.leg.br\0"
-"kizu.kyoto.jp\0kvanangen.no\0trysil.no\0\xe5\x80\x8b\xe4\xba\xba.\xe9\xa6\x99\xe6\xb8\xaf\0"
-"midori.gunma.jp\0jewish.museum\0"
-"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x81\xd1\x80\xd0\xb1\0"
-"k12.wa.us\0bplaced.com\0"
-"shimamaki.hokkaido.jp\0"
-"barsy.mobi\0"
-"liaison\0"
+"defense.tn\0"
+"lefrak\0"
+"kawanishi.yamagata.jp\0nfl\0"
+"katsushika.tokyo.jp\0lawyer\0"
+"\xe7\xb5\x84\xe7\xb9\x94.hk\0pramerica\0"
+"df.leg.br\0"
+"airtel\0"
+"rakkestad.no\0"
+"tsuga.tochigi.jp\0"
+"sld.pa\0"
+"med.pro\0"
+"gs.sf.no\0"
+"ecologia.bo\0"
+"ngo\0"
+"everbank\0"
+"fm.it\0nishiazai.shiga.jp\0"
+"v\xc3\xa5gan.no\0is-into-cartoons.com\0"
+"def.br\0\xd8\xb3\xd9\x88\xd8\xaf\xd8\xa7\xd9\x86\0"
+"public.museum\0software\0"
+"seaport.museum\0"
+"hino.tokyo.jp\0"
+"austin.museum\0nhk\0"
+"writesthisblog.com\0"
+"mlbfan.org\0"
+"\xe7\xb6\xb2\xe7\xb5\xa1.cn\0abr.it\0varese.it\0hirokawa.fukuoka.jp\0"
+"kvanangen.no\0"
+"maceio.br\0"
+"saxo\0"
+"furniture.museum\0"
+"tirol\0"
+"saka.hiroshima.jp\0*.magentosite.cloud\0"
+"brunel.museum\0tingvoll.no\0eaton.mi.us\0daplie.me\0"
+"s\xc3\xbc""dtirol.it\0"
+"stadt.museum\0"
+"yamada.iwate.jp\0"
+"lib.tx.us\0"
+"ravenna.it\0cistron.nl\0"
+"bestbuy\0"
+"kamisato.saitama.jp\0"
+"\xc3\xa5seral.no\0drive\0drayddns.com\0"
+"corporation.museum\0"
+"adv.br\0"
+"jorpeland.no\0info.zm\0"
+"abeno.osaka.jp\0showa.yamanashi.jp\0"
+"k12.ar.us\0"
+"idv.hk\0medizinhistorisches.museum\0"
+"locker\0"
+"sampa.br\0tsumagoi.gunma.jp\0wiw.gov.pl\0"
+"allstate\0"
+"miyota.nagano.jp\0"
+"\xe9\x9d\x99\xe5\xb2\xa1.jp\0"
+"mihama.fukui.jp\0nishiokoppe.hokkaido.jp\0"
+"tsuiki.fukuoka.jp\0"
+"even\xc3\xa1\xc5\xa1\xc5\xa1i.no\0"
+"higashisumiyoshi.osaka.jp\0"
+"acct.pro\0movie\0"
+"nichinan.miyazaki.jp\0dell\0"
+"pizza\0"
+"trentinsud-tirol.it\0\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88\0"
+"r\xc3\xb8""d\xc3\xb8y.no\0vikna.no\0s3-website-ap-southeast-1.amazonaws.com\0"
+"tone.ibaraki.jp\0cloudaccess.host\0"
+"touch.museum\0nesodden.no\0"
"fm.no\0"
-"hiroo.hokkaido.jp\0"
-"motegi.tochigi.jp\0"
-"kakuda.miyagi.jp\0\xe6\x89\x8b\xe6\x9c\xba\0"
-"ogano.saitama.jp\0"
-"fuchu.hiroshima.jp\0"
-"amusement.aero\0kaneyama.yamagata.jp\0"
-"ownprovider.com\0"
-"siljan.no\0"
-"mosvik.no\0"
-"red.sv\0"
-"tananger.no\0"
-"yamanouchi.nagano.jp\0"
+"\xe3\x82\xb3\xe3\x83\xa0\0"
+"khmelnytskyi.ua\0"
+"jgora.pl\0"
+"is-with-theband.com\0"
+"gok.pk\0pr.us\0"
+"kotoura.tottori.jp\0"
+"minamiashigara.kanagawa.jp\0"
+"kyoto.jp\0"
+"satx.museum\0brumunddal.no\0"
+"curitiba.br\0"
+"bc.ca\0\xe7\xb6\xb2\xe7\xb5\xa1.hk\0uscountryestate.museum\0hockey\0"
+"kawakami.nara.jp\0"
+"ringsaker.no\0"
+"suwa.nagano.jp\0"
+"t\xc3\xb8nsberg.no\0"
+"sf.no\0mk.ua\0"
+"komagane.nagano.jp\0murakami.niigata.jp\0"
+"fjell.no\0events\0"
+"pioneer\0"
+"dyndns-mail.com\0"
+"hizen.saga.jp\0"
+"r.se\0"
+"health.museum\0no-ip.info\0"
+"elblag.pl\0eurovision\0international\0"
+"nl.ca\0user.party.eus\0is-a-bookkeeper.com\0"
+"\xe9\xb3\xa5\xe5\x8f\x96.jp\0ogasawara.tokyo.jp\0\xe8\xaf\xba\xe5\x9f\xba\xe4\xba\x9a\0"
+"\xd8\xa7\xd8\xa8\xd9\x88\xd8\xb8\xd8\xa8\xd9\x8a\0"
+"capebreton.museum\0s\xc3\xb8ndre-land.no\0"
+"niigata.jp\0!city.kawasaki.jp\0\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86\0"
+"now\0"
+"london\0"
+"ishikawa.jp\0samukawa.kanagawa.jp\0"
+"kunstsammlung.museum\0"
+"yamato.kumamoto.jp\0"
+"australia.museum\0"
+"rome.it\0tsuru.yamanashi.jp\0"
+"wake.okayama.jp\0wloclawek.pl\0"
+"chigasaki.kanagawa.jp\0"
+"ngrok.io\0noip.us\0"
+"etc.br\0seki.gifu.jp\0"
+"lincoln.museum\0il.eu.org\0"
+"\xe5\xba\x83\xe5\xb3\xb6.jp\0"
+"eastcoast.museum\0sor-fron.no\0ipiranga\0"
+"nra\0twmail.cc\0"
+"\xc3\xa5krehamn.no\0lib.vt.us\0"
+"anan.tokushima.jp\0yamanobe.yamagata.jp\0"
+"ichiba.tokushima.jp\0"
+"f\xc3\xb8rde.no\0"
+"obi\0"
+"garden\0"
+"inami.wakayama.jp\0"
+"photos\0"
+"crafting.xyz\0"
+"parti.se\0"
+"svizzera.museum\0firewall-gateway.de\0"
+"pharmaciens.km\0chernihiv.ua\0desi\0"
+"nrw\0"
+"shiki.saitama.jp\0"
+"caa.aero\0sor-odal.no\0cc.ia.us\0"
+"norddal.no\0hu.eu.org\0ie.eu.org\0"
+"sakai.fukui.jp\0"
+"balsfjord.no\0bloxcms.com\0"
+"\xe7\x8f\xa0\xe5\xae\x9d\0shiftedit.io\0"
+"kitanakagusuku.okinawa.jp\0"
+"rc.it\0"
+"gs.nl.no\0rv.ua\0"
+"kanie.aichi.jp\0"
+"dnipropetrovsk.ua\0tube\0"
+"fuso.aichi.jp\0"
+"loppa.no\0tiffany\0"
+"reklam.hu\0"
+"numata.gunma.jp\0ntt\0"
+"sa.edu.au\0"
+"verbania.it\0"
+"shimabara.nagasaki.jp\0dnsalias.net\0"
+"nesseby.no\0plumbing\0"
+"servehttp.com\0"
+"onjuku.chiba.jp\0adv.mz\0"
+"kids.museum\0motorcycle.museum\0"
+"kamioka.akita.jp\0ine.kyoto.jp\0"
+"nationalheritage.museum\0gratis\0"
+"off\0"
+"gausdal.no\0condos\0"
+"daisen.akita.jp\0"
+"openair.museum\0gaular.no\0\xc3\xb8ystre-slidre.no\0"
+"lib.or.us\0"
+"uw.gov.pl\0"
+"ismaili\0"
+"furukawa.miyagi.jp\0kitakata.miyazaki.jp\0"
+"nagawa.nagano.jp\0"
+"s\xc3\xb8mna.no\0lpusercontent.com\0"
+"pp.az\0yomitan.okinawa.jp\0"
+"idv.tw\0"
+"estate\0"
+"caravan\0"
+"yamagata.ibaraki.jp\0"
+"b\xc3\xa5tsfjord.no\0"
+"nara.jp\0"
+"gliding.aero\0cc.as.us\0"
+"yamazoe.nara.jp\0"
+"\xe7\x9f\xb3\xe5\xb7\x9d.jp\0democrat\0"
+"iwate.jp\0"
+"skien.no\0"
+"taxi.br\0takagi.nagano.jp\0"
+"embetsu.hokkaido.jp\0kuju.oita.jp\0"
+"servehumour.com\0"
+"dr\xc3\xb8""bak.no\0"
+"minamiminowa.nagano.jp\0yamatotakada.nara.jp\0toshima.tokyo.jp\0"
+"fineart.museum\0storfjord.no\0nyc\0"
+"vall\xc3\xa9""eaoste.it\0"
+"statebank\0"
+"is-a-nascarfan.com\0""3utilities.com\0"
+"nachikatsuura.wakayama.jp\0"
+"fin.ec\0"
+"dali.museum\0songdalen.no\0"
+"obama.fukui.jp\0"
+"imabari.ehime.jp\0"
+"trysil.no\0s3.dualstack.us-east-1.amazonaws.com\0"
+"\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4\0"
+"ashoro.hokkaido.jp\0"
+"hembygdsforbund.museum\0"
+"\xe6\x89\x8b\xe8\xa1\xa8\0"
+"conf.lv\0"
+"nl.no\0feedback\0shouji\0"
+"iglesias-carbonia.it\0hashikami.aomori.jp\0"
+"sakura.tochigi.jp\0"
+"p.bg\0emerck\0"
+"sakaiminato.tottori.jp\0"
+"cleaning\0"
+"shijonawate.osaka.jp\0hino.tottori.jp\0nanyo.yamagata.jp\0"
+"\xe6\x95\x99\xe8\x82\xb2.hk\0indiana.museum\0"
+"izu.shizuoka.jp\0"
+"is-a-techie.com\0"
+"adult\0"
+"equipment\0"
+"discovery.museum\0pharmacy\0"
+"ia.us\0"
+"nishihara.okinawa.jp\0izumiotsu.osaka.jp\0"
+"nasu.tochigi.jp\0"
+"lib.vi.us\0servegame.org\0noip.me\0pantheonsite.io\0"
+"sakegawa.yamagata.jp\0"
+"ass.km\0skaun.no\0"
+"armenia.su\0"
+"half.host\0"
+"tsubata.ishikawa.jp\0"
+"servequake.com\0"
+"9.bg\0v\xc3\xa6r\xc3\xb8y.no\0gr.eu.org\0"
+"yachiyo.ibaraki.jp\0fujisawa.kanagawa.jp\0urawa.saitama.jp\0"
+"maryland.museum\0"
+"taki.mie.jp\0"
"\xe6\x96\xb0\xe9\x97\xbb\0"
-"remotewd.com\0"
-"flor\xc3\xb8.no\0cloudns.pw\0"
-"ditchyourip.com\0"
-"hida.gifu.jp\0"
-"sogne.no\0"
-"hopto.me\0"
-"now-dns.top\0"
-"vestnes.no\0"
-"yoshinogari.saga.jp\0"
-"reggio-calabria.it\0cartoonart.museum\0"
-"shinto.gunma.jp\0scholarships\0"
-"mansions.museum\0readmyblog.org\0"
-"media\0"
-"yosemite.museum\0no-ip.info\0"
-"newport.museum\0"
-"kitagata.saga.jp\0"
-"american.museum\0"
-"xin\0"
-"tatebayashi.gunma.jp\0"
-"jefferson.museum\0casino\0\xd9\x83\xd9\x88\xd9\x85\0hr.eu.org\0"
-"tsumagoi.gunma.jp\0"
-"ne.jp\0"
-"k12.nv.us\0"
-"withyoutube.com\0"
-"aguni.okinawa.jp\0ne.ke\0civilwar.museum\0"
-"p.bg\0"
-"santoandre.br\0yahiko.niigata.jp\0songdalen.no\0"
-"fiat\0homes\0"
-"schweiz.museum\0de.us\0"
-"yasuoka.nagano.jp\0nextdirect\0"
-"ne.kr\0"
-"shimofusa.chiba.jp\0project.museum\0"
-"nobeoka.miyazaki.jp\0"
-"\xe7\x8f\xa0\xe5\xae\x9d\0"
-"mutsu.aomori.jp\0"
-"voyage\0"
-"is-a-geek.com\0"
-"lillesand.no\0"
-"tottori.tottori.jp\0"
-"wada.nagano.jp\0rr.leg.br\0"
-"mat.br\0"
-"chernihiv.ua\0cloudaccess.host\0"
-"planetarium.museum\0is-a-cpa.com\0"
-"www.ro\0grozny.su\0"
-"nikolaev.ua\0"
-"am.leg.br\0"
-"fido\0softbank\0"
-"tjome.no\0"
-"kuzumaki.iwate.jp\0appspot.com\0"
-"loppa.no\0clinic\0"
-"\xe6\x8b\x9b\xe8\x81\x98\0"
-"kamaishi.iwate.jp\0"
-"\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\x89\0"
+"ilawa.pl\0"
+"fundacio.museum\0one\0travelersinsurance\0"
+"wada.nagano.jp\0\xd8\xa7\xd9\x84\xd8\xb9\xd9\x84\xd9\x8a\xd8\xa7\xd9\x86\0"
+"ong\0*.elb.amazonaws.com\0from-ks.com\0"
+"nord-aurdal.no\0\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0"
+"ninohe.iwate.jp\0"
+"otsuki.yamanashi.jp\0onl\0"
+"meguro.tokyo.jp\0"
+"trust.museum\0zhytomyr.ua\0"
+"tarui.gifu.jp\0"
+"ballooning.aero\0"
+"miyazaki.jp\0vpndns.net\0"
+"railroad.museum\0"
+"blog.bo\0capitalone\0"
+"aki.kochi.jp\0"
+"chintai\0rackmaze.com\0"
+"blog.br\0"
+"ooo\0"
+"bialystok.pl\0"
+"manno.kagawa.jp\0shichikashuku.miyagi.jp\0"
+"med.br\0scor\0"
+"scot\0"
+"fvg.it\0toyako.hokkaido.jp\0discover\0"
+"miho.ibaraki.jp\0"
+"oppegard.no\0"
+"as.us\0"
+"sd.cn\0malbork.pl\0"
+"virginia.museum\0"
+"higashitsuno.kochi.jp\0"
+"mi.it\0"
+"oksnes.no\0shangrila\0"
+"gyeongnam.kr\0limited\0rj.leg.br\0"
+"k12.ks.us\0"
+"brescia.it\0"
+"jeju.kr\0management\0podzone.net\0"
+"vads\xc3\xb8.no\0audi\0"
+"outsystemscloud.com\0"
+"funahashi.toyama.jp\0"
+"autos\0wellbeingzone.co.uk\0"
+"forlicesena.it\0olawa.pl\0ostrowwlkp.pl\0"
+"vanylven.no\0from-ms.com\0from-nc.com\0"
+"asuke.aichi.jp\0flynnhosting.net\0"
"r\xc3\xa6lingen.no\0"
-"narashino.chiba.jp\0"
-"takayama.gifu.jp\0"
-"indianmarket.museum\0"
-"rs.leg.br\0sc.leg.br\0"
-"tienda\0"
-"zagan.pl\0mein-iserv.de\0"
-"dnsdojo.net\0"
-"texas.museum\0"
-"miyagi.jp\0artdeco.museum\0global\0"
-"blockbuster\0guitars\0"
-"kasuga.hyogo.jp\0tube\0servegame.com\0"
-"gemological.museum\0fuossko.no\0"
-"taito.tokyo.jp\0"
-"kami.kochi.jp\0"
-"myfritz.net\0"
-"tula.su\0"
-"wanouchi.gifu.jp\0"
-"ibaraki.ibaraki.jp\0ar.com\0"
-"from-ny.net\0neat-url.com\0"
-"kayabe.hokkaido.jp\0grozny.ru\0"
-"ne.pw\0"
-"s\xc3\xa1lat.no\0"
-"onyourside\0from-id.com\0"
-"anani.br\0"
-"cc.tx.us\0"
-"k\xc3\xa1r\xc3\xa1\xc5\xa1johka.no\0"
-"emilia-romagna.it\0frog.museum\0"
-"phoenix.museum\0km.ua\0"
-"nx.cn\0tsuwano.shimane.jp\0"
-"art.museum\0"
-"*.0emm.com\0"
-"lexus\0"
+"med.ec\0org\0delivery\0n4t.co\0"
+"vic.edu.au\0med.ee\0pay\0golffan.us\0"
+"kinko.kagoshima.jp\0"
+"marche.it\0"
+"*.compute-1.amazonaws.com\0"
+"porsgrunn.no\0"
+"tochio.niigata.jp\0"
+"unicom\0"
+"konsulat.gov.pl\0"
+"lakas.hu\0dyndns-ip.com\0"
+"heritage.museum\0starnberg.museum\0dscloud.me\0"
+"yamatsuri.fukushima.jp\0beer\0barsy.shop\0"
+"\xe5\xb1\xb1\xe6\xa2\xa8.jp\0komaki.aichi.jp\0myoko.niigata.jp\0"
+"veneto.it\0tobetsu.hokkaido.jp\0semine.miyagi.jp\0"
+"movimiento.bo\0"
+"hammerfest.no\0"
+"zakopane.pl\0"
+"quebec\0fuettertdasnetz.de\0"
+"nishiwaki.hyogo.jp\0"
+"brandywinevalley.museum\0s3.dualstack.eu-west-2.amazonaws.com\0"
+"fiat\0"
+"granvin.no\0cc.mi.us\0"
+"grp.lk\0pvt.k12.ma.us\0"
+"name.hr\0sugito.saitama.jp\0"
+"mishima.fukushima.jp\0joetsu.niigata.jp\0"
+"suzuka.mie.jp\0"
+"\xe6\x85\x88\xe5\x96\x84\0"
+"is-an-engineer.com\0"
+"minami.tokushima.jp\0ott\0"
+"nationwide\0from-sc.com\0"
+"potenza.it\0career\0"
+"\xe6\x94\xbf\xe5\xba\x9c.hk\0panasonic\0"
+"\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82\0"
+"goshiki.hyogo.jp\0"
+"delmenhorst.museum\0zoology.museum\0lib.gu.us\0"
+"name.et\0\xe6\x89\x8b\xe6\x9c\xba\0"
+"\xd9\x83\xd9\x88\xd9\x85\0"
+"*.platform.sh\0"
+"yachts\0"
+"svelvik.no\0"
+"pet\0"
+"naturalsciences.museum\0jolster.no\0"
+"massacarrara.it\0"
+"med.ht\0ovh\0"
+"trentinsuedtirol.it\0wazuka.kyoto.jp\0"
+"county.museum\0oxford.museum\0"
+"inf.br\0"
+"ushiku.ibaraki.jp\0accountant\0"
+"fido\0"
+"kuroishi.aomori.jp\0"
+"metlife\0"
+"rsvp\0"
+"narvik.no\0mytuleap.com\0freebox-os.com\0"
+"barefoot\0"
+"bronnoy.no\0smile\0"
+"trentino-stirol.it\0"
+"inf.cu\0"
+"bt.it\0tamaki.mie.jp\0"
+"pp.se\0pp.ru\0"
+"takarazuka.hyogo.jp\0"
+"name.cy\0"
+"misasa.tottori.jp\0phd\0"
+"correios-e-telecomunica\xc3\xa7\xc3\xb5""es.museum\0"
+"kazuno.akita.jp\0"
+"pavia.it\0"
+"name.eg\0"
+"kawaminami.miyazaki.jp\0"
+"photography.museum\0"
+"pid\0"
+"california.museum\0"
+"kudamatsu.yamaguchi.jp\0"
+"sakurai.nara.jp\0"
+"fin.tn\0"
+"travel\0"
+"k12.mo.us\0pp.ua\0"
+"pin\0"
+"szczecin.pl\0zagan.pl\0"
+"\xe6\x8b\x9b\xe8\x81\x98\0"
+"is-lost.org\0"
+"name.az\0"
+"yazu.tottori.jp\0"
+"cc.sd.us\0"
+"catania.it\0"
+"aknoluokta.no\0"
+"med.ly\0fredrikstad.no\0"
+"um.gov.pl\0"
+"montreal.museum\0"
+"sosa.chiba.jp\0matsumoto.nagano.jp\0loan\0instantcloud.cn\0"
+"hokuto.hokkaido.jp\0odawara.kanagawa.jp\0"
+"is-a-hard-worker.com\0"
+"\xe5\xb2\xa1\xe5\xb1\xb1.jp\0"
+"chikuhoku.nagano.jp\0mi.th\0"
+"cartoonart.museum\0"
+"nieruchomosci.pl\0"
+"hammarfeasta.no\0"
+"seiro.niigata.jp\0"
+"ohi.fukui.jp\0"
+"lib.nh.us\0"
+"expert\0"
+"ddnsfree.com\0yombo.me\0"
+"trentin-suedtirol.it\0"
+"newjersey.museum\0\xe4\xb8\xad\xe5\x9b\xbd\0"
+"nerima.tokyo.jp\0"
+"p.se\0"
+"vda.it\0aoste.it\0ic.gov.pl\0"
+"koeln.museum\0r\xc3\xa5""de.no\0"
+"muko.kyoto.jp\0govt.nz\0"
+"tcm.museum\0austrheim.no\0"
+"vaporcloud.io\0"
+"toon.ehime.jp\0moriguchi.osaka.jp\0"
+"rightathome\0"
+"torahime.shiga.jp\0gmail\0ba.leg.br\0"
+"med.om\0institute\0systems\0"
+"moroyama.saitama.jp\0prod\0"
+"mi.us\0\xe4\xb8\xad\xe5\x9c\x8b\0"
+"hinode.tokyo.jp\0prof\0"
+"med.pa\0"
+"yasuda.kochi.jp\0hakuba.nagano.jp\0"
+"from-dc.com\0"
+"vestre-toten.no\0"
+"shinonsen.hyogo.jp\0"
+"k12.wa.us\0"
+"med.pl\0"
+"barsy.net\0"
+"usdecorativearts.museum\0osteroy.no\0pnc\0dray-dns.de\0"
+"tsushima.aichi.jp\0yukuhashi.fukuoka.jp\0kiso.nagano.jp\0fukaya.saitama.jp\0"
+"club.tw\0k12.ga.us\0"
+"taranto.it\0"
+"calabria.it\0uchinomi.kagawa.jp\0red.sv\0"
+"kr\xc3\xa5""anghke.no\0"
+"miki.hyogo.jp\0"
"oguchi.aichi.jp\0"
-"television.museum\0"
-"mil.ac\0best\0dyndns-server.com\0"
-"naturalsciences.museum\0"
-"mil.ae\0"
-"obuse.nagano.jp\0"
-"mil.al\0heritage.museum\0skj\xc3\xa5k.no\0"
-"bytom.pl\0"
-"auto\0"
-"ama.shimane.jp\0"
-"mil.ba\0steiermark.museum\0"
-"mil.ar\0ap.leg.br\0"
-"eisenbahn.museum\0"
-"murakami.niigata.jp\0"
-"vestre-slidre.no\0"
-"balsan-su\xcc\x88""dtirol.it\0"
-"nis.za\0"
+"film\0"
+"narita.chiba.jp\0us.gov.pl\0"
+"wolterskluwer\0"
+"mil.ac\0"
+"mil.ae\0association.aero\0"
+"pruszkow.pl\0"
+"\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb8\0"
+"\xe7\xb6\xb2\xe8\xb7\xaf.tw\0"
+"mil.al\0higashiizumo.shimane.jp\0run.app\0"
+"trondheim.no\0"
+"scjohnson\0solar\0"
+"cam.it\0"
+"mil.ba\0kviteseid.no\0"
+"mil.ar\0js.cn\0"
+"americanart.museum\0"
+"med.sa\0"
+"loft\0"
+"med.sd\0"
+"k12.ct.us\0"
"mil.az\0"
-"rj.gov.br\0"
-"fot.br\0landrover\0"
-"3.bg\0"
-"crew.aero\0mil.bo\0"
-"kainan.tokushima.jp\0"
-"mil.br\0sauherad.no\0ne.ug\0prudential\0dyndns-mail.com\0"
-"medecin.fr\0"
-"is-very-evil.org\0"
-"ne.tz\0blogspot.com.cy\0rn.leg.br\0"
-"sera.hiroshima.jp\0accenture\0"
-"fujimi.saitama.jp\0malopolska.pl\0"
-"gamvik.no\0"
+"sund.no\0"
+"emiliaromagna.it\0yashiro.hyogo.jp\0kaizuka.osaka.jp\0skoczow.pl\0"
+"alta.no\0"
+"\xe5\xa5\x88\xe8\x89\xaf.jp\0"
+"mil.bo\0"
+"foz.br\0tomi.nagano.jp\0"
+"guide\0"
+"mil.br\0arezzo.it\0"
+"minowa.nagano.jp\0"
+"inf.mk\0"
+"rr.leg.br\0"
+"mosvik.no\0termez.su\0"
+"best\0"
"mil.by\0"
-"kurate.fukuoka.jp\0omi.niigata.jp\0hockey\0"
-"mil.cl\0"
-"mil.cn\0ne.us\0"
-"mil.co\0\xe5\xb2\x90\xe9\x98\x9c.jp\0"
-"blogspot.com.ee\0"
-"gildeskal.no\0film\0"
-"\xd9\x85\xd8\xb5\xd8\xb1\0blogspot.com.eg\0"
-"fet.no\0"
-"nissan\0wpdevcloud.com\0"
-"east-kazakhstan.su\0hopto.org\0"
-"blogspot.com.ar\0"
-"mil.do\0nakasatsunai.hokkaido.jp\0missile.museum\0"
-"blogspot.com.au\0"
+"\xd9\x85\xd8\xb5\xd8\xb1\0"
+"mil.cl\0\xd0\xbc\xd0\xbe\xd1\x81\xd0\xba\xd0\xb2\xd0\xb0\0"
+"collection.museum\0fitjar.no\0"
+"mil.cn\0"
+"mil.co\0"
+"ra.it\0"
+"scapp.io\0"
+"auto\0lima.zone\0"
+"asso.fr\0"
+"catering\0"
+"mitsue.nara.jp\0kushimoto.wakayama.jp\0"
+"seat\0"
+"barclays\0"
+"aq.it\0ba.it\0"
+"egersund.no\0tokke.no\0"
+"\xe0\xb9\x80\xe0\xb8\x99\xe0\xb9\x87\xe0\xb8\x95.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0"
+"k12.ak.us\0"
+"mil.do\0pro\0cc.tx.us\0"
+"bss.design\0"
+"christiansburg.museum\0"
+"asso.gp\0"
"mil.ec\0"
-"ro.leg.br\0"
-"sx.cn\0trentino.it\0nissay\0noip.us\0"
-"mil.eg\0cesena-forli.it\0"
-"inawashiro.fukushima.jp\0"
-"auspost\0"
-"vevelstad.no\0nyc.mn\0"
-"is-a-geek.org\0"
-"design\0blogspot.com.br\0"
-"sellsyourhome.org\0"
-"\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\0"
-"collection.museum\0"
-"blogspot.com.by\0soundcast.me\0"
-"surgery\0"
-"shichinohe.aomori.jp\0*.alces.network\0"
-"scor\0"
-"scot\0s3-website.eu-west-2.amazonaws.com\0blogspot.com.co\0"
-"ca-central-1.elasticbeanstalk.com\0"
-"gliwice.pl\0gda.pl\0"
-"lig.it\0miyoshi.tokushima.jp\0kahoku.yamagata.jp\0"
-"mein-vigor.de\0"
-"mil.ge\0"
-"\xc3\xb8rsta.no\0mragowo.pl\0"
-"honda\0"
-"mil.gh\0vossevangen.no\0"
-"\xe5\x85\xac\xe5\x8f\xb8.cn\0xfinity\0"
-"globo\0"
-"xxx\0app.os.fedoraproject.org\0"
-"yokosuka.kanagawa.jp\0"
-"corsica\0"
-"s\xc3\xb8r-odal.no\0omega\0"
-"mil.gt\0is-a-hunter.com\0"
-"\xe5\x85\xac\xe5\x8f\xb8.hk\0honjo.akita.jp\0"
-"chimkent.su\0"
-"cs.it\0twmail.cc\0"
-"academia.bo\0"
-"select\0"
-"loan\0place\0"
-"mil.hn\0tuva.su\0"
-"j\xc3\xb8rpeland.no\0xyz\0blogspot.com.es\0"
-"oppdal.no\0rzeszow.pl\0"
-"sko.gov.pl\0press\0"
-"mil.id\0"
-"taishin.fukushima.jp\0tokuyama.yamaguchi.jp\0"
-"napoli.it\0correios-e-telecomunica\xc3\xa7\xc3\xb5""es.museum\0"
+"sd.us\0pru\0s3-ap-south-1.amazonaws.com\0"
+"rs.leg.br\0sc.leg.br\0"
+"mil.eg\0"
+"ena.gifu.jp\0"
+"passenger-association.aero\0racing\0"
+"shirako.chiba.jp\0"
+"miyoshi.tokushima.jp\0"
+"dance\0"
+"sakyo.kyoto.jp\0nome.pt\0"
+"\xd8\xa8\xd8\xa7\xd8\xb1\xd8\xaa\0"
"fire\0"
+"asso.ht\0yoshida.saitama.jp\0hotmail\0servebbs.net\0"
+"wa.gov.au\0"
+"nuremberg.museum\0fam.pk\0"
+"ingatlan.hu\0"
+"aibetsu.hokkaido.jp\0"
+"kumano.mie.jp\0am.leg.br\0"
+"pub\0"
+"cooperativa.bo\0"
+"verona.it\0"
+"mil.ge\0association.museum\0"
+"niikappu.hokkaido.jp\0kawahara.tottori.jp\0"
+"bmoattachments.org\0"
+"mil.gh\0fish\0"
+"s3-eu-west-2.amazonaws.com\0"
+"asso.bj\0nagano.jp\0shinyoshitomi.fukuoka.jp\0starhub\0"
+"kagoshima.jp\0"
+"seek\0"
+"mil.gt\0"
+"vaapste.no\0"
+"yakage.okayama.jp\0name.vn\0"
+"eastafrica.museum\0averoy.no\0"
+"asso.ci\0kv.ua\0"
+"es.gov.br\0mil.hn\0"
+"freeboxos.com\0"
+"venice.it\0"
+"pwc\0"
+"mil.id\0"
+"uda.nara.jp\0"
+"cc.nj.us\0"
+"kouzushima.tokyo.jp\0"
+"web.bo\0meland.no\0"
+"radom.pl\0"
+"planetarium.museum\0fed.us\0"
"mil.in\0"
-"eaton.mi.us\0"
+"steigen.no\0"
"mil.iq\0"
-"badajoz.museum\0p.se\0"
-"lawyer\0"
-"mibu.tochigi.jp\0\xe8\xb0\xb7\xe6\xad\x8c\0"
-"otoineppu.hokkaido.jp\0"
-"lacaixa\0"
-"fujioka.gunma.jp\0"
-"applinzi.com\0"
-"fish\0bplaced.net\0"
-"mil.jo\0"
-"xs4all.space\0"
-"onjuku.chiba.jp\0"
-"przeworsk.pl\0"
-"mo\xc3\xa5reke.no\0pomorskie.pl\0"
+"yokaichiba.chiba.jp\0name.tj\0"
+"web.co\0yolasite.com\0"
+"inf.ua\0"
+"asso.dz\0name.tr\0"
+"name.tt\0faith\0"
+"mil.jo\0nativeamerican.museum\0"
+"wroc.pl\0"
+"gildeskal.no\0"
+"shichinohe.aomori.jp\0kanoya.kagoshima.jp\0privatizehealthinsurance.net\0"
+"n.bg\0"
+"kanegasaki.iwate.jp\0ogawara.miyagi.jp\0\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\0"
+"website\0dedyn.io\0ddnss.de\0"
+"ruhr\0rn.leg.br\0"
"mil.kg\0"
-"ba.gov.br\0jogasz.hu\0nanao.ishikawa.jp\0"
-"isesaki.gunma.jp\0"
-"mochizuki.nagano.jp\0mil.km\0"
-"himi.toyama.jp\0camera\0"
-"fuel.aero\0servep2p.com\0"
-"mil.kr\0ostrowwlkp.pl\0"
-"morimachi.shizuoka.jp\0"
-"*.compute.amazonaws.com\0"
-"iron.museum\0il.eu.org\0"
-"haram.no\0"
+"web.do\0hellas.museum\0fr\xc3\xb8ya.no\0"
+"nakamichi.yamanashi.jp\0"
+"dnsalias.org\0"
+"kartuzy.pl\0"
+"mil.km\0"
+"kmpsp.gov.pl\0"
+"pixolino.com\0telebit.io\0"
+"barsy.site\0"
+"matsuura.nagasaki.jp\0mil.kr\0"
+"te.it\0"
"mil.kz\0"
-"austevoll.no\0"
-"eu-central-1.elasticbeanstalk.com\0"
-"tonaki.okinawa.jp\0karikatur.museum\0"
-"family\0"
-"nonoichi.ishikawa.jp\0"
-"mil.lv\0"
-"mil.mg\0tolga.no\0rsvp\0"
-"tamamura.gunma.jp\0osteroy.no\0"
-"no-ip.net\0"
-"net.ac\0"
-"net.ae\0miyakonojo.miyazaki.jp\0loft\0"
-"net.af\0belem.br\0"
-"net.ag\0"
-"guovdageaidnu.no\0workisboring.com\0"
-"net.ai\0mil.mv\0"
-"mil.ng\0knowsitall.info\0hu.eu.org\0ie.eu.org\0"
-"net.al\0mil.my\0mil.ni\0"
-"mil.mz\0you\0"
-"yusuhara.kochi.jp\0"
-"bearalv\xc3\xa1hki.no\0"
-"net.ba\0yalta.ua\0"
-"net.ar\0net.bb\0mil.no\0"
-"bushey.museum\0"
-"money\0"
-"net.au\0"
-"net.bh\0"
-"\xd7\xa7\xd7\x95\xd7\x9d\0"
-"net.az\0coop.ht\0"
-"hs.kr\0"
-"nov.ru\0"
-"net.bm\0mil.nz\0"
-"net.bn\0"
-"net.bo\0saves-the-whales.com\0"
-"sa.gov.au\0ladbrokes\0"
-"net.br\0sanok.pl\0"
-"net.bs\0"
-"net.bt\0"
-"ravendb.run\0"
-"yasuda.kochi.jp\0\xe4\xbf\xa1\xe6\x81\xaf\0"
-"jaguar\0myasustor.com\0"
+"oirm.gov.pl\0"
+"deporte.bo\0temasek\0barsy.pro\0"
+"target\0wien\0"
+"ap.leg.br\0"
+"yamagata.yamagata.jp\0"
+"moss.no\0"
+"ama.shimane.jp\0mil.lv\0ro.leg.br\0"
+"7.bg\0mil.mg\0jondal.no\0s3.dualstack.sa-east-1.amazonaws.com\0is-a-patsfan.org\0"
+"turin.it\0dazaifu.fukuoka.jp\0miyada.nagano.jp\0"
+"ternopil.ua\0"
+"miyoshi.hiroshima.jp\0"
+"tx.us\0marshalls\0"
+"higashikawa.hokkaido.jp\0"
+"eisenbahn.museum\0"
+"horse\0"
+"cloudfront.net\0"
+"culturalcenter.museum\0"
+"kawachinagano.osaka.jp\0"
+"mil.mv\0gda.pl\0"
+"mil.ng\0forde.no\0"
+"mil.my\0mil.ni\0lillehammer.no\0"
+"pn.it\0yamakita.kanagawa.jp\0nozawaonsen.nagano.jp\0mil.mz\0"
+"name.qa\0"
+"ntr.br\0tomigusuku.okinawa.jp\0name.pr\0"
+"web.gu\0mil.no\0"
+"barsy.pub\0"
+"undersea.museum\0"
+"fujisawa.iwate.jp\0"
+"\xd0\xb0\xd0\xba.\xd1\x81\xd1\x80\xd0\xb1\0"
+"fi.cr\0susono.shizuoka.jp\0"
+"murata.miyagi.jp\0cloud.metacentrum.cz\0"
+"voyage\0"
+"bulsan-s\xc3\xbc""dtirol.it\0mil.nz\0"
+"name.na\0nes.buskerud.no\0"
+"shinjo.okayama.jp\0"
+"whaling.museum\0podzone.org\0fr.eu.org\0"
+"web.id\0aichi.jp\0health.nz\0"
+"sunndal.no\0lancia\0s3-website-us-west-1.amazonaws.com\0"
+"name.mv\0"
+"name.ng\0"
+"name.my\0vestby.no\0cc.de.us\0"
+"azumino.nagano.jp\0nagasaki.nagasaki.jp\0"
"mil.pe\0"
-"net.ci\0yokote.akita.jp\0"
-"net.bz\0"
-"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86.ir\0mil.ph\0prod\0noip.me\0"
-"mykolaiv.ua\0nov.su\0"
-"net.cm\0prof\0"
-"net.cn\0"
-"net.co\0mil.pl\0"
-"kochi.kochi.jp\0"
-"presse.km\0discount\0"
-"blogspot.com.mt\0"
-"mil.qa\0"
-"net.cu\0"
-"takahagi.ibaraki.jp\0blogspot.com.ng\0"
-"net.cw\0tysfjord.no\0"
-"coop.br\0humanities.museum\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4\0se.leg.br\0"
-"net.cy\0geelvinck.museum\0volyn.ua\0"
-"sc.cn\0kumiyama.kyoto.jp\0"
-"mil.py\0"
-"net.dm\0ikeda.nagano.jp\0"
-"net.do\0"
-"ak.us\0"
-"ipifony.net\0"
-"net.ec\0"
-"h\xc3\xb8ylandet.no\0pulawy.pl\0"
-"seto.aichi.jp\0"
-"net.eg\0\xc3\xb8vre-eiker.no\0"
-"venice.it\0is-a-player.com\0"
-"net.dz\0"
-"sciencesnaturelles.museum\0sandvik\0"
-"oh.us\0"
-"kumano.mie.jp\0"
-"rr.gov.br\0"
-"ms.it\0nieruchomosci.pl\0"
-"xerox\0"
-"trd.br\0\xe6\x95\x99\xe8\x82\xb2.hk\0presse.ml\0"
-"ogori.fukuoka.jp\0hokksund.no\0"
-"trentino-aadige.it\0tsurugi.ishikawa.jp\0cc.mn.us\0"
-"net.et\0"
-"nanae.hokkaido.jp\0caravan\0"
-"\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xa0\xe0\xa4\xa8\0"
-"gjovik.no\0"
-"mil.ru\0endoftheinternet.org\0"
-"council.aero\0"
-"mil.rw\0"
-"am.gov.br\0mil.sh\0"
-"bolt.hu\0hotel.tz\0"
-"tsukiyono.gunma.jp\0bahcavuotna.no\0"
-"deatnu.no\0"
-"maringa.br\0usui.fukuoka.jp\0bnpparibas\0blogspot.com.tr\0"
-"dyndns-pics.com\0"
-"nogi.tochigi.jp\0"
-"tono.iwate.jp\0"
-"n.bg\0net.ge\0"
-"yun\0"
-"net.gg\0mil.st\0"
-"lur\xc3\xb8y.no\0dc.us\0"
-"taketa.oita.jp\0"
-"net.gl\0mil.sy\0s3-eu-west-3.amazonaws.com\0"
-"bn.it\0ms.kr\0malvik.no\0mil.tj\0"
-"rs.gov.br\0sc.gov.br\0net.gn\0nakagawa.fukuoka.jp\0"
-"net.gp\0oirase.aomori.jp\0oketo.hokkaido.jp\0mil.tm\0ivanovo.su\0"
-"eurovision\0"
-"net.gr\0mil.to\0"
-"rochester.museum\0"
-"net.gt\0tec.mi.us\0"
-"net.gu\0sardegna.it\0koshu.yamanashi.jp\0yorkshire.museum\0tr\xc3\xa6na.no\0mil.tr\0"
-"net.gy\0trentino-altoadige.it\0"
+"ostroleka.pl\0"
+"*.landing.myjino.ru\0"
+"munakata.fukuoka.jp\0mil.ph\0"
+"revista.bo\0mining.museum\0"
+"mil.pl\0"
+"latrobe\0"
+"katsuura.chiba.jp\0"
+"engerdal.no\0lib.ny.us\0"
+"wakayama.wakayama.jp\0"
+"sandefjord.no\0mil.qa\0k12.ky.us\0"
+"\xe5\x80\x8b\xe4\xba\xba.hk\0from-mn.com\0"
+"entertainment.aero\0love\0"
+"balsan-s\xc3\xbc""dtirol.it\0ina.ibaraki.jp\0okinoshima.shimane.jp\0"
+"westfalen.museum\0stryn.no\0mil.py\0hosting\0"
+"shisui.chiba.jp\0sowa.ibaraki.jp\0"
+"tanagura.fukushima.jp\0nanbu.tottori.jp\0"
+"gov.nc.tr\0"
+"stockholm\0"
+"kitami.hokkaido.jp\0lubartow.pl\0"
+"r\xc3\xb8ros.no\0nj.us\0industries\0hobby-site.org\0"
+"ru.com\0"
+"ono.fukushima.jp\0"
+"wiki\0georgia.su\0"
+"bauern.museum\0taipei\0"
+"lupin\0"
+"gojome.akita.jp\0boehringer\0"
+"pointto.us\0"
+"\xd8\xa8\xd9\x8a\xd8\xaa\xd9\x83\0"
+"web.lk\0name.mk\0mil.ru\0k12.il.us\0spacekit.io\0"
+"mil.rw\0dyndns-blog.com\0"
+"mil.sh\0"
+"nordreisa.no\0"
+"hichiso.gifu.jp\0shinjuku.tokyo.jp\0"
+"bahn.museum\0ybo.science\0"
+"trentinoaltoadige.it\0"
+"minamiizu.shizuoka.jp\0"
+"properties\0us.eu.org\0"
+"mil.st\0"
+"elburg.museum\0"
+"at-band-camp.net\0"
+"name.jo\0mil.sy\0"
+"mil.tj\0"
+"vi.it\0"
+"mil.tm\0"
+"on-web.fr\0"
+"mil.to\0is-a-nurse.com\0"
+"yonaguni.okinawa.jp\0web.nf\0"
+"spjelkavik.no\0"
+"mil.tr\0"
+"web.ni\0"
+"mitoyo.kagawa.jp\0yandex\0"
+"j\xc3\xb8rpeland.no\0wine\0is-a-painter.com\0"
+"fi.it\0"
"mil.tw\0"
-"net.hk\0"
-"mil.tz\0"
-"industria.bo\0net.hn\0"
-"bozen-su\xcc\x88""dtirol.it\0faith\0"
-"urn.arpa\0"
-"net.ht\0net.id\0"
-"emiliaromagna.it\0moma.museum\0"
-"matsudo.chiba.jp\0mil.vc\0"
-"nishi.fukuoka.jp\0"
+"futaba.fukushima.jp\0mil.tz\0"
+"saves-the-whales.com\0"
+"yufu.oita.jp\0"
+"mil.vc\0"
"mil.ve\0"
-"kitamoto.saitama.jp\0chizu.tottori.jp\0s\xc3\xb8rum.no\0"
-"mizumaki.fukuoka.jp\0bounceme.net\0"
-"net.il\0delmenhorst.museum\0ulvik.no\0mil.uy\0"
-"net.im\0mihama.mie.jp\0"
-"net.in\0odda.no\0s\xc3\xa1l\xc3\xa1t.no\0"
-"barclays\0"
-"net.iq\0"
-"net.ir\0naustdal.no\0"
-"net.is\0"
-"net.je\0s3-website.ap-northeast-2.amazonaws.com\0"
-"kyuragi.saga.jp\0"
-"medical.museum\0"
-"yoita.niigata.jp\0"
-"tachikawa.tokyo.jp\0kvinnherad.no\0is-an-engineer.com\0"
-"badaddja.no\0"
-"aktyubinsk.su\0"
-"net.jo\0"
-"quest\0"
-"trogstad.no\0"
-"hofu.yamaguchi.jp\0tel.tr\0"
-"net.kg\0"
-"okinawa.jp\0zip\0"
-"net.ki\0diet\0"
-"manno.kagawa.jp\0omiya.saitama.jp\0vaapste.no\0gr.eu.org\0"
-"ln.cn\0"
-"saogonca.br\0"
-"net.kn\0seat\0"
-"uki.kumamoto.jp\0net.la\0"
-"sc.ke\0net.lb\0"
-"net.lc\0"
-"recipes\0"
-"harvestcelebration.museum\0chrysler\0"
-"santabarbara.museum\0"
-"chikusei.ibaraki.jp\0itoman.okinawa.jp\0net.kw\0"
-"blogspot.com.uy\0"
-"net.ky\0googlecode.com\0"
-"net.kz\0selbu.no\0"
-"ap.gov.br\0ishikawa.okinawa.jp\0net.lk\0law.pro\0"
-"dyndns-at-work.com\0"
-"sc.kr\0"
-"net.ma\0cupcake.is\0"
-"net.lr\0boats\0"
-"kamikoani.akita.jp\0"
-"mil.za\0oracle\0"
-"net.me\0vadso.no\0game-host.org\0"
-"not.br\0net.lv\0"
-"scrapper-site.net\0"
-"capebreton.museum\0"
-"ichinoseki.iwate.jp\0net.ly\0online\0"
-"santamaria.br\0net.mk\0from-ma.com\0"
-"net.ml\0"
-"hadano.kanagawa.jp\0k12.gu.us\0"
-"rn.gov.br\0"
-"of.by\0hotel.lk\0net.mo\0"
-"mil.zm\0"
-"accident-prevention.aero\0net.ms\0rnrt.tn\0"
-"net.mt\0"
-"net.mu\0ap.gov.pl\0"
-"net.mv\0net.nf\0"
-"muika.niigata.jp\0net.mw\0net.ng\0foundation\0feste-ip.net\0"
-"net.mx\0k12.ut.us\0"
-"net.my\0net.ni\0"
-"net.mz\0mil.zw\0"
-"avocat.fr\0"
-"gyeongnam.kr\0lavangen.no\0"
-"net.nr\0tjmaxx\0"
-"radio.br\0accesscam.org\0"
-"incheon.kr\0seek\0"
-"maritimo.museum\0abarth\0kurgan.su\0"
-"molise.it\0"
-"net.nz\0"
-"b\xc3\xb8.telemark.no\0net.om\0"
-"ro.gov.br\0valle-daosta.it\0est-mon-blogueur.com\0nh-serv.co.uk\0"
-"claims\0\xe5\x98\x89\xe9\x87\x8c\xe5\xa4\xa7\xe9\x85\x92\xe5\xba\x97\0"
-"granvin.no\0net.pa\0"
-"cq.cn\0"
-"nsupdate.info\0"
-"daisen.akita.jp\0barum.no\0"
-"net.pe\0"
-"love\0"
-"oe.yamagata.jp\0"
-"drangedal.no\0net.ph\0"
-"mar.it\0"
-"\xd9\x81\xd9\x84\xd8\xb3\xd8\xb7\xd9\x8a\xd9\x86\0"
-"shinjo.yamagata.jp\0oppegard.no\0net.pk\0"
-"net.pl\0"
-"nc.tr\0"
-"1.bg\0fvg.it\0net.pn\0"
-"ogasawara.tokyo.jp\0"
-"net.qa\0"
-"ako.hyogo.jp\0net.pr\0from-me.org\0"
-"fujishiro.ibaraki.jp\0higashiyamato.tokyo.jp\0net.ps\0"
-"kitadaito.okinawa.jp\0fundacio.museum\0net.pt\0\xe3\x82\xb0\xe3\x83\xbc\xe3\x82\xb0\xe3\x83\xab\0"
-"assassination.museum\0loans\0"
-"qc.com\0"
-"kui.hiroshima.jp\0"
-"net.py\0ddns.me\0"
-"sennan.osaka.jp\0kofu.yamanashi.jp\0"
-"juedisches.museum\0"
-"andoy.no\0rogers\0"
-"ms.us\0nc.us\0"
-"akishima.tokyo.jp\0"
-"kyotamba.kyoto.jp\0"
-"arna.no\0"
-"freight.aero\0cc.ky.us\0shell\0"
-"hoylandet.no\0"
-"hotel.hu\0barclaycard\0"
-"b\xc3\xa1jddar.no\0juniper\0"
-"n\xc3\xa5\xc3\xa5mesjevuemie.no\0"
-"!www.ck\0ruhr\0"
-"fi.cr\0panama.museum\0k12.me.us\0"
-"net.sa\0\xe5\x85\xac\xe5\x8f\xb8.\xe9\xa6\x99\xe6\xb8\xaf\0"
-"hokuto.hokkaido.jp\0net.sb\0"
-"\xe5\xb2\xa1\xe5\xb1\xb1.jp\0saltdal.no\0net.sc\0"
-"net.sd\0"
-"net.ru\0"
-"exposed\0resindevice.io\0"
-"net.rw\0net.sg\0nohost.me\0"
-"net.sh\0app.lmpm.com\0"
-"horokanai.hokkaido.jp\0"
-"akrehamn.no\0meraker.no\0net.sl\0"
-"asaka.saitama.jp\0"
-"ishikawa.jp\0net.so\0"
-"ws.na\0"
-"namdalseid.no\0dscloud.me\0"
-"net.st\0"
-"szczytno.pl\0"
-"sigdal.no\0metlife\0"
-"wif.gov.pl\0pixolino.com\0"
-"net.th\0"
-"tako.chiba.jp\0net.sy\0"
-"noto.ishikawa.jp\0net.tj\0immobilien\0"
-"isa.kagoshima.jp\0is-a-geek.net\0"
-"taira.toyama.jp\0net.tm\0k12.ar.us\0"
-"net.tn\0is-a-chef.org\0"
-"net.to\0melbourne\0"
-"from-ok.com\0"
-"net.ua\0mypep.link\0"
-"net.tr\0"
-"kishiwada.osaka.jp\0bygland.no\0"
-"assedic.fr\0omuta.fukuoka.jp\0hyuga.miyazaki.jp\0net.tt\0"
-"is-a-rockstar.com\0"
-"net.tw\0"
-"columbia.museum\0"
+"ind.br\0"
+"barsyonline.co.uk\0"
+"mil.uy\0"
+"\xe5\x8d\x83\xe8\x91\x89.jp\0kitahiroshima.hokkaido.jp\0"
+"can.museum\0yorkshire.museum\0bjugn.no\0vm.bytemark.co.uk\0"
+"sande.more-og-romsdal.no\0"
+"akaiwa.okayama.jp\0"
+"sejny.pl\0health.vn\0contact\0"
+"te.ua\0"
+"tv.bb\0red\0"
+"web.pk\0\xd7\xa7\xd7\x95\xd7\x9d\0"
+"\xe0\xb8\xa8\xe0\xb8\xb6\xe0\xb8\x81\xe0\xb8\xa9\xe0\xb8\xb2.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0"
+"asso.re\0"
+"br.it\0cb.it\0shimoda.shizuoka.jp\0"
+"archi\0"
+"tanohata.iwate.jp\0"
+"kamishihoro.hokkaido.jp\0diet\0ren\0cnpy.gdn\0"
+"cc.vi.us\0"
+"omotego.fukushima.jp\0"
+"tv.bo\0sandcats.io\0"
+"blockbuster\0"
+"qvc\0from-tn.com\0"
+"fnd.br\0tv.br\0rackmaze.net\0"
+"mihara.hiroshima.jp\0azurewebsites.net\0"
+"stada\0hu.com\0"
+"mulhouse.museum\0school.museum\0"
+"shimada.shizuoka.jp\0"
+"pagespeedmobilizer.com\0"
+"bedzin.pl\0"
+"de.us\0"
+"manx.museum\0"
+"lease\0serveirc.com\0"
+"se.leg.br\0"
+"copenhagen.museum\0lanbib.se\0k12.ne.us\0"
+"studio\0"
+"friuliveneziagiulia.it\0ikeda.hokkaido.jp\0"
+"notaires.km\0leka.no\0"
+"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xd8\xa9\0*.advisor.ws\0"
+"fukagawa.hokkaido.jp\0"
+"hanggliding.aero\0s3.dualstack.ap-south-1.amazonaws.com\0"
+"resistance.museum\0mil.za\0"
+"yamagata.jp\0kamikawa.saitama.jp\0wielun.pl\0"
+"beiarn.no\0is-into-cars.com\0"
+"film.hu\0eu.com\0"
+"for-the.biz\0"
+"mil.zm\0*.vps.myjino.ru\0"
+"morimachi.shizuoka.jp\0"
+"maserati\0"
+"nagareyama.chiba.jp\0web.tj\0"
+"asso.nc\0"
+"takehara.hiroshima.jp\0yamagata.nagano.jp\0"
+"oppdal.no\0\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0mil.zw\0"
+"ind.gt\0!city.yokohama.jp\0fujimino.saitama.jp\0"
+"lib.nj.us\0\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0xs4all.space\0"
+"gs.hm.no\0netbank\0wanggou\0de.com\0"
+"web.tr\0ril\0"
+"leasing.aero\0sexy\0"
+"hirono.iwate.jp\0debian.net\0"
+"jobs\0rio\0"
+"rip\0"
+"n.se\0"
+"ggf.br\0urayasu.chiba.jp\0"
+"barsy.org\0"
+"cc.ok.us\0is-leet.com\0dsmynas.org\0"
+"ochi.kochi.jp\0satte.saitama.jp\0"
+"m\xc3\xa5lselv.no\0is-a-teacher.com\0synology.me\0"
+"zarow.pl\0"
+"firewall-gateway.com\0"
+"okawa.kochi.jp\0"
+"web.ve\0latino\0"
+"kusatsu.gunma.jp\0saikai.nagasaki.jp\0"
+"ind.in\0"
+"corsica\0"
+"oster\xc3\xb8y.no\0"
+"pub.sa\0"
+"\xe9\x95\xb7\xe9\x87\x8e.jp\0niigata.niigata.jp\0nago.okinawa.jp\0"
+"est-a-la-maison.com\0"
+"namdalseid.no\0"
+"nishikata.tochigi.jp\0"
+"kumamoto.jp\0ustka.pl\0"
+"tuva.su\0"
+"accident-prevention.aero\0"
+"roma.it\0mombetsu.hokkaido.jp\0"
+"odda.no\0barsy.co.uk\0"
+"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8b\xe0\xa4\xa4\0"
+"oita.jp\0moonscale.net\0"
+"gotdns.org\0"
+"higashimurayama.tokyo.jp\0"
+"tv.im\0publishproxy.com\0"
+"shimogo.fukushima.jp\0sanok.pl\0"
+"!www.ck\0sport.hu\0"
+"catholic\0"
+"tv.it\0"
+"eco.br\0"
+"ind.kw\0transport.museum\0homesense\0"
+"soni.nara.jp\0"
+"hinohara.tokyo.jp\0"
+"nombre.bo\0versailles.museum\0"
+"vi.us\0web.za\0"
+"now-dns.net\0"
+"is-very-bad.org\0"
+"otoineppu.hokkaido.jp\0freesite.host\0"
+"asso.km\0gallery.museum\0rahkkeravju.no\0"
+"posts-and-telecommunications.museum\0station.museum\0community\0"
+"minamiuonuma.niigata.jp\0"
+"hirosaki.aomori.jp\0"
+"dating\0"
+"horten.no\0endoftheinternet.org\0"
+"ethnology.museum\0giske.no\0charity\0"
+"sb.ua\0k12.pa.us\0"
"cyou\0"
-"gov.nc.tr\0net.uk\0alfaromeo\0"
-"de.com\0"
-"emerck\0"
-"obninsk.su\0townnews-staging.com\0"
-"soundandvision.museum\0grimstad.no\0"
-"sakuragawa.ibaraki.jp\0"
-"net.vc\0"
-"sciences.museum\0sc.ug\0"
-"izumi.osaka.jp\0troms\xc3\xb8.no\0net.ve\0"
-"sc.tz\0"
-"net.uy\0net.vi\0servegame.org\0"
-"gs.hl.no\0coop.tt\0net.uz\0"
-"yoshida.saitama.jp\0"
-"kamisunagawa.hokkaido.jp\0v\xc3\xa5g\xc3\xa5.no\0termez.su\0"
-"net.vn\0"
-"vapor.cloud\0"
-"sc.us\0store\0"
-"sakae.nagano.jp\0ibaraki.osaka.jp\0net.vu\0"
-"chocolate.museum\0"
-"coop.mv\0b.ssl.fastly.net\0"
-"coop.mw\0"
-"swatch\0"
-"works.aero\0minamata.kumamoto.jp\0"
-"jobs\0tranoy.no\0"
-"webhop.biz\0"
-"n.se\0net.ws\0"
-"lib.pa.us\0"
-"aurland.no\0"
-"dyndns-web.com\0"
-"kitami.hokkaido.jp\0"
-"tottori.jp\0"
-"forli\xcc\x80-cesena.it\0youth.museum\0"
-"dish\0"
-"touch.museum\0\xe4\xbc\x81\xe4\xb8\x9a\0"
-"fi.it\0fastlylb.net\0"
-"homesense\0"
-"of.no\0"
-"loten.no\0olayan\0"
-"mifune.kumamoto.jp\0"
-"sv.it\0joboji.iwate.jp\0"
-"wien\0"
-"wuoz.gov.pl\0"
-"hyogo.jp\0"
-"net.za\0"
-"swiebodzin.pl\0"
-"ogawara.miyagi.jp\0is-a-chef.com\0"
-"sveio.no\0"
-"vet.br\0schokoladen.museum\0dnsalias.com\0"
-"yaotsu.gifu.jp\0"
-"def.br\0net.zm\0"
-"atsuma.hokkaido.jp\0ohira.tochigi.jp\0coop.py\0"
-"shichikashuku.miyagi.jp\0"
-"sauda.no\0"
-"szczecin.pl\0"
-"press.aero\0"
-"loabat.no\0mattel\0"
-"ota.gunma.jp\0"
-"odessa.ua\0netlify.com\0"
-"asakuchi.okayama.jp\0"
-"se.gov.br\0presse.ci\0"
-"saintlouis.museum\0"
-"tome.miyagi.jp\0"
-"us-gov-west-1.elasticbeanstalk.com\0"
-"fuoisku.no\0cc.vi.us\0"
-"financial\0"
-"vipsinaapp.com\0"
-"ltd.co.im\0"
-"ed.ao\0myfirewall.org\0"
-"raholt.no\0"
-"jeonnam.kr\0"
-"coop.km\0"
-"boston.museum\0clothing\0"
-"abeno.osaka.jp\0"
-"kudoyama.wakayama.jp\0"
-"entomology.museum\0mopar\0"
-"ngrok.io\0"
-"sa.au\0samegawa.fukushima.jp\0"
-"recife.br\0poivron.org\0"
-"hizen.saga.jp\0"
-"sango.nara.jp\0minato.tokyo.jp\0lugs.org.uk\0"
-"sling\0"
-"fetsund.no\0"
-"ed.ci\0numata.gunma.jp\0seranishi.hiroshima.jp\0vagsoy.no\0"
-"s3-us-west-2.amazonaws.com\0"
-"zippo\0"
-"ogawa.ibaraki.jp\0omi.nagano.jp\0"
-"trentin-sued-tirol.it\0tomobe.ibaraki.jp\0setouchi.okayama.jp\0"
-"\xe9\xab\x98\xe7\x9f\xa5.jp\0"
-"ed.cr\0"
-"gob.ar\0shimoichi.nara.jp\0"
-"osoyro.no\0"
-"aibetsu.hokkaido.jp\0ce.leg.br\0"
-"presse.fr\0tsubame.niigata.jp\0michigan.museum\0"
-"hoteles\0"
-"wiki\0"
-"sand\xc3\xb8y.no\0"
-"sa.cr\0is-a-bruinsfan.org\0"
-"kharkov.ua\0"
-"gob.bo\0lib.wy.us\0"
-"hasura.app\0"
-"utsunomiya.tochigi.jp\0"
-"maintenance.aero\0"
-"skype\0"
-"kaluga.su\0"
-"nishitosa.kochi.jp\0obanazawa.yamagata.jp\0nv.us\0"
-"manx.museum\0\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0"
-"ome.tokyo.jp\0"
-"gob.cl\0na.it\0"
-"kiwi.nz\0"
-"buzen.fukuoka.jp\0gs.rl.no\0read-books.org\0servehalflife.com\0"
-"k12.ak.us\0"
-"uklugs.org\0"
-"skedsmokorset.no\0"
-"kerryproperties\0"
-"kinokawa.wakayama.jp\0forsale\0"
-"marnardal.no\0psp.gov.pl\0\xd0\xb0\xd0\xba.\xd1\x81\xd1\x80\xd0\xb1\0"
-"kppsp.gov.pl\0"
-"seoul.kr\0sa.gov.pl\0cieszyn.pl\0"
-"kimino.wakayama.jp\0macys\0marketing\0"
-"gmail\0"
-"\xce\xb5\xce\xbb\0"
-"gob.do\0heimatunduhren.museum\0"
-"it.ao\0alsace\0"
-"research.museum\0"
-"l.bg\0"
-"gob.ec\0kanra.gunma.jp\0vega.no\0zp.gov.pl\0"
-"agr.br\0wine\0"
-"\xd0\xba\xd0\xb0\xd1\x82\xd0\xbe\xd0\xbb\xd0\xb8\xd0\xba\0"
-"bl.it\0"
-"encyclopedic.museum\0boutique\0"
+"lubin.pl\0"
+"tachiarai.fukuoka.jp\0"
+"tj\xc3\xb8me.no\0"
+"ao.it\0"
+"asso.mc\0ontario.museum\0chernovtsy.ua\0lib.ca.us\0"
+"mus.br\0"
+"hm.no\0"
+"dellogliastra.it\0yoita.niigata.jp\0kainan.tokushima.jp\0"
+"myshopblocks.com\0"
+"from-in.com\0"
+"dscloud.biz\0"
+"mo-i-rana.no\0"
+"tv.na\0"
+"author.aero\0nesoddtangen.no\0"
+"showa.fukushima.jp\0"
+"folkebibl.no\0athleta\0"
+"nagatoro.saitama.jp\0"
+"bokn.no\0"
+"moka.tochigi.jp\0nogi.tochigi.jp\0"
+"mesaverde.museum\0technology.museum\0"
+"kamisu.ibaraki.jp\0"
+"sap\0"
+"k12.md.us\0"
+"hikari.yamaguchi.jp\0\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xa0\xe0\xa4\xa8\0"
+"casadelamoneda.museum\0sas\0shopping\0"
+"jus.br\0"
+"groundhandling.aero\0"
+"wedding\0"
+"urbinopesaro.it\0podlasie.pl\0maif\0"
+"konyvelo.hu\0sbi\0adygeya.su\0"
+"morotsuka.miyazaki.jp\0"
+"naha.okinawa.jp\0"
+"aver\xc3\xb8y.no\0sca\0"
+"rokunohe.aomori.jp\0dish\0scb\0"
+"ok.us\0sbs\0"
+"\xc3\xa5mot.no\0flora.no\0"
+"sondrio.it\0takahata.yamagata.jp\0"
+"royken.no\0"
+"salangen.no\0"
+"oirase.aomori.jp\0"
+"pescara.it\0kuchinotsu.nagasaki.jp\0"
+"shiraoi.hokkaido.jp\0vision\0"
+"tottori.jp\0onojo.fukuoka.jp\0"
+"maritimo.museum\0\xc3\xb8ksnes.no\0"
+"iida.nagano.jp\0"
+"yabuki.fukushima.jp\0"
+"gub.uy\0"
"res.in\0"
-"stjordalshalsen.no\0"
-"gob.es\0\xe6\xb2\x96\xe7\xb8\x84.jp\0sexy\0"
-"pi.it\0onga.fukuoka.jp\0"
-"maif\0"
-"barefoot\0"
-"alt.za\0"
-"pescara.it\0"
+"h\xc3\xb8nefoss.no\0"
+"cc.nh.us\0"
+"susaki.kochi.jp\0"
+"haram.no\0"
+"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xdb\x83\0"
+"adygeya.ru\0"
+"bhz.br\0iwanai.hokkaido.jp\0"
+"mx.na\0gs.jan-mayen.no\0"
+"run\0"
+"culture.museum\0"
+"ind.tn\0"
+"ses\0"
+"bandai.fukushima.jp\0etajima.hiroshima.jp\0"
+"campinagrande.br\0tv.sd\0"
+"lib.id.us\0sew\0"
+"sex\0"
+"fhsk.se\0"
+"tranoy.no\0"
+"kakuda.miyagi.jp\0"
+"l.bg\0"
+"walbrzych.pl\0"
+"\xe7\xb6\xb2\xe7\xbb\x9c.hk\0"
+"sfr\0"
+"rwe\0"
+"salzburg.museum\0"
+"press.aero\0railway.museum\0net-freaks.com\0"
+"yn.cn\0"
+"dynns.com\0"
+"ss.it\0hachirogata.akita.jp\0"
+"tv.tr\0redirectme.net\0"
+"shingu.wakayama.jp\0"
+"bungoono.oita.jp\0"
+"servebbs.org\0"
+"cs.it\0mediocampidano.it\0esashi.hokkaido.jp\0cloudapp.net\0"
"s3.eu-west-2.amazonaws.com\0"
-"yasaka.nagano.jp\0hinohara.tokyo.jp\0"
-"motorcycles\0my-wan.de\0"
-"dating\0"
-"k12.pr.us\0"
-"kopervik.no\0"
-"abr.it\0"
-"tunes\0"
-"iida.nagano.jp\0"
-"sarufutsu.hokkaido.jp\0parliament.nz\0"
-"omaha.museum\0flir\0"
-"barueri.br\0"
-"daejeon.kr\0"
-"desa.id\0"
-"s\xc3\xb8gne.no\0pila.pl\0"
-"baghdad.museum\0"
-"gob.gt\0shizukuishi.iwate.jp\0oy.lc\0"
-"health\0"
-"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0"
-"qld.gov.au\0eidfjord.no\0\xe6\x95\x99\xe8\x82\xb2.\xe9\xa6\x99\xe6\xb8\xaf\0"
-"sex.hu\0"
-"from-ar.com\0barsyonline.co.uk\0"
-"gob.hn\0sa.it\0kotoura.tottori.jp\0"
-"ed.jp\0"
-"podzone.net\0"
-"sytes.net\0"
-"bayern\0"
-"umig.gov.pl\0"
-"radio\0"
-"herad.no\0lancia\0"
-"shinyoshitomi.fukuoka.jp\0jorpeland.no\0trafficplex.cloud\0"
-"salud.bo\0atami.shizuoka.jp\0"
-"is-by.us\0"
-"mypets.ws\0mypi.co\0"
-"dubai\0"
-"suzaka.nagano.jp\0"
-"vn.ua\0"
-"yonaguni.okinawa.jp\0"
-"washingtondc.museum\0"
-"nt.au\0express\0"
-"r\xc3\xa5""de.no\0ia.us\0definima.io\0"
+"kahoku.yamagata.jp\0tv.tz\0"
+"fhapp.xyz\0"
+"kihoku.ehime.jp\0"
+"5.bg\0"
+"press.cy\0"
+"koga.ibaraki.jp\0hakusan.ishikawa.jp\0"
+"saskatchewan.museum\0"
+"trogstad.no\0"
+"hakone.kanagawa.jp\0"
+"xenapponazure.com\0"
+"bytom.pl\0"
+"analytics\0"
+"toyama.jp\0"
+"\xe4\xbf\xa1\xe6\x81\xaf\0"
+"kristiansund.no\0"
+"aquarelle\0mango\0is-a-photographer.com\0"
+"minamidaito.okinawa.jp\0"
+"\xe7\xa5\x9e\xe5\xa5\x88\xe5\xb7\x9d.jp\0chuo.yamanashi.jp\0"
+"leikanger.no\0"
+"lib.ar.us\0"
+"za.net\0"
+"ambulance.aero\0ski\0"
+"voagat.no\0"
+"namegawa.saitama.jp\0"
+"cc.dc.us\0"
+"*.quipelements.com\0"
+"flir\0"
+"nagasaki.jp\0"
+"wakkanai.hokkaido.jp\0"
+"lu.it\0me.it\0*.telebit.xyz\0"
+"lib.ok.us\0sky\0"
+"v\xc3\xa5ler.\xc3\xb8stfold.no\0"
+"himeji.hyogo.jp\0alwaysdata.net\0"
+"science.museum\0"
+"higashiura.aichi.jp\0"
+"hadano.kanagawa.jp\0"
+"me.ke\0"
+"dyndns.info\0dnsiskinky.com\0"
+"gunma.jp\0"
+"nh.us\0"
+"ikeda.fukui.jp\0"
+"googleapis.com\0"
+"farsund.no\0"
+"okoppe.hokkaido.jp\0publ.pt\0"
+"paderborn.museum\0dyndns-server.com\0"
+"*.sapporo.jp\0shibata.niigata.jp\0"
+"halloffame.museum\0"
+"farmers\0"
+"eidsberg.no\0doomdns.org\0"
+"asahi.mie.jp\0"
+"neat-url.com\0"
+"oceanographique.museum\0"
+"shinkamigoto.nagasaki.jp\0"
+"friuliv-giulia.it\0kanra.gunma.jp\0"
+"cc.me.us\0""2038.io\0"
+"lillesand.no\0es.eu.org\0"
+"url.tw\0"
+"evenassi.no\0"
+"utashinai.hokkaido.jp\0"
+"ravendb.me\0"
+"tromso.no\0lib.wy.us\0"
+"soy\0"
+"beauxarts.museum\0bounty-full.com\0"
+"uzs.gov.pl\0"
+"kvam.no\0giehtavuoatna.no\0"
+"fg.it\0familyds.net\0"
+"alaska.museum\0lib.hi.us\0s3.us-east-2.amazonaws.com\0"
+"tab\0"
+"naturhistorisches.museum\0hjartdal.no\0"
+"ora.gunma.jp\0"
+"oumu.hokkaido.jp\0"
+"paragliding.aero\0halden.no\0"
+"badajoz.museum\0"
+"cc.in.us\0"
+"modelling.aero\0mc.eu.org\0"
+"ishikawa.okinawa.jp\0"
+"www.ro\0"
+"niihama.ehime.jp\0"
+"kautokeino.no\0"
+"tax\0"
+"in.na\0"
+"shaw\0est-mon-blogueur.com\0from-ky.com\0"
+"daiwa.hiroshima.jp\0rzeszow.pl\0srl\0"
+"eidsvoll.no\0ryukyu\0"
+"taku.saga.jp\0"
+"family.museum\0bargains\0"
+"hk.cn\0notaires.fr\0bolzano-altoadige.it\0isesaki.gunma.jp\0"
+"in.ni\0"
+"kurume.fukuoka.jp\0"
+"chattanooga.museum\0lodingen.no\0"
+"przeworsk.pl\0srt\0"
+"ed.ao\0from-mi.com\0"
+"greta.fr\0amami.kagoshima.jp\0chuo.tokyo.jp\0yonago.tottori.jp\0"
+"rnu.tn\0cdn77-ssl.net\0"
+"tci\0"
+"kitaaiki.nagano.jp\0"
+"app.os.fedoraproject.org\0"
+"miyama.mie.jp\0"
+"theater.museum\0"
+"katashina.gunma.jp\0"
+"tsuno.miyazaki.jp\0fujiidera.osaka.jp\0"
+"stc\0lt.eu.org\0"
+"takasago.hyogo.jp\0"
+"ponpes.id\0ham-radio-op.net\0"
+"sells-for-u.com\0ownprovider.com\0"
+"dc.us\0duckdns.org\0"
+"mormon\0"
+"nikolaev.ua\0tdk\0"
+"usuki.oita.jp\0"
+"apartments\0"
+"ed.ci\0"
+"ce.leg.br\0"
+"oystre-slidre.no\0pl.ua\0k12.ms.us\0k12.nc.us\0softbank\0"
+"ikeda.gifu.jp\0"
+"flight.aero\0k12.ec\0\xc3\xb8rskog.no\0"
+"ed.cr\0fujimi.nagano.jp\0"
+"nagoya\0"
+"kui.hiroshima.jp\0"
+"pvt.ge\0"
+"g12.br\0tel\0"
+"khmelnitskiy.ua\0"
+"kamiizumi.saitama.jp\0"
+"s3-us-east-2.amazonaws.com\0"
+"futbol\0"
+"v\xc3\xa5gs\xc3\xb8y.no\0valer.ostfold.no\0"
+"osaka.jp\0hidaka.wakayama.jp\0mail.pl\0podhale.pl\0"
+"ddns.me\0"
+"goto.nagasaki.jp\0"
+"cincinnati.museum\0myddns.rocks\0"
"minobu.yamanashi.jp\0"
-"takanabe.miyazaki.jp\0"
-"rehab\0"
-"nt.ca\0leikanger.no\0"
-"co.ae\0shibukawa.gunma.jp\0"
-"aoste.it\0"
-"co.ag\0"
-"davvesiida.no\0bostik\0"
-"airforce\0"
-"motoyama.kochi.jp\0potager.org\0"
-"fukui.jp\0oregon.museum\0"
+"am.br\0"
+"amsterdam.museum\0"
+"trentino-s-tirol.it\0"
+"4u.com\0"
+"kr.it\0"
+"graz.museum\0"
+"yoro.gifu.jp\0"
+"cruise\0teaches-yoga.com\0"
+"minakami.gunma.jp\0"
+"orkdal.no\0"
+"imperia.it\0"
+"*.awdev.ca\0"
+"in.rs\0l.se\0dubai\0"
+"aosta.it\0"
+"alstom\0is-a-cubicle-slave.com\0"
+"me.tz\0"
+"me.uk\0"
+"cc.ny.us\0"
+,
+
+"ichikawa.hyogo.jp\0"
+"\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0"
+"thd\0"
+"nf.ca\0"
+"me.us\0"
+"pup.gov.pl\0"
+"klepp.no\0bike\0mydatto.com\0"
+"trentino-a-adige.it\0"
+"sandvik\0"
+"from-ri.com\0"
+"*.kawasaki.jp\0nakama.fukuoka.jp\0in.th\0"
+"i234.me\0"
+"toyotsu.fukuoka.jp\0"
+"broadcast.museum\0"
+"shia\0"
+"kouyama.kagoshima.jp\0"
+"coldwar.museum\0in.ua\0"
+"gov.ac\0v\xc3\xa5g\xc3\xa5.no\0"
+"aga.niigata.jp\0"
+"gov.ae\0kvinesdal.no\0"
+"gov.af\0k12.il\0"
+"jprs\0eu-west-3.elasticbeanstalk.com\0"
+"sells-it.net\0"
+"hitra.no\0s3-website-ap-southeast-2.amazonaws.com\0*.otap.co\0from-wy.com\0net.eu.org\0""4lima.de\0"
+"gov.al\0"
+"landes.museum\0"
+"chijiwa.nagasaki.jp\0"
+"gov.ba\0tt.im\0beeldengeluid.museum\0"
+"gov.ar\0gov.bb\0edogawa.tokyo.jp\0"
+"gov.as\0in.us\0"
+"s3.cn-north-1.amazonaws.com.cn\0"
+"gov.au\0"
+"gov.bf\0"
+"gov.bh\0ud.it\0"
+"gov.az\0kiyosu.aichi.jp\0"
+"gov.bm\0"
+"gov.bn\0miyashiro.saitama.jp\0"
+"jerusalem.museum\0sydney\0servehalflife.com\0"
+"tjx\0yamaxun\0"
+"gov.br\0emr.it\0"
+"gov.bs\0bing\0"
+"gov.bt\0gov.cd\0fukuchiyama.kyoto.jp\0"
+"cn.com\0fi.eu.org\0"
+"press.se\0house\0"
+"gov.by\0cpa.pro\0s3.ca-central-1.amazonaws.com\0from-wi.com\0"
+"gov.bz\0florence.it\0""4lima.at\0"
+"viking.museum\0"
+"gov.cl\0forl\xc3\xac-cesena.it\0kagami.kochi.jp\0"
+"gov.cm\0isleofman.museum\0rentals\0"
+"gov.cn\0ed.jp\0"
+"gov.co\0"
+"chtr.k12.ma.us\0"
+"\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0"
+"gov.cu\0"
+"gov.cx\0perso.ht\0"
+"gov.cy\0pilots.museum\0hughes\0"
+"dyndns-at-work.com\0"
+"gov.dm\0lib.sc.us\0flowers\0"
+"bielawa.pl\0""4lima.ch\0"
+"gov.do\0"
+"gov.ec\0"
+"gov.ee\0bern.museum\0sk\xc3\xa1nit.no\0"
+"kyonan.chiba.jp\0"
+"gov.eg\0"
+"h\xc3\xb8yanger.no\0"
+"gov.dz\0tamatsukuri.ibaraki.jp\0"
+"asnes.no\0molde.no\0"
+"dsmynas.net\0"
+"phone\0"
+"salvadordali.museum\0"
+"gov.et\0sakuragawa.ibaraki.jp\0fukudomi.saga.jp\0"
+"kr\xc3\xb8""dsherad.no\0"
+"pippu.hokkaido.jp\0"
+"mima.tokushima.jp\0ube.yamaguchi.jp\0"
+"firebaseapp.com\0barsy.menu\0"
+"basilicata.it\0"
+"government.aero\0"
+"gov.ge\0"
+"cq.cn\0naples.it\0toyo.kochi.jp\0"
+"oz.au\0"
+"gov.gh\0top\0"
+"express.aero\0gov.gi\0force.museum\0"
+"aostavalley.it\0gyeonggi.kr\0"
+"shop\0"
+"fujitsu\0recipes\0"
+"gov.gn\0kashiwazaki.niigata.jp\0"
+"buzen.fukuoka.jp\0"
+"gov.gr\0"
+"fresenius\0show\0"
+"gov.gu\0ny.us\0"
+"*.statics.cloud\0"
+"isteingeek.de\0"
+"caxias.br\0suzaka.nagano.jp\0"
+"gov.gy\0"
+"shirakawa.fukushima.jp\0"
+"gov.hk\0habmer.no\0"
+"otama.fukushima.jp\0koryo.nara.jp\0kumatori.osaka.jp\0"
+"\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4\xe0\xb1\x8d\0"
+"press.ma\0"
+"gov.ie\0lib.la.us\0"
+"kr.ua\0k12.ia.us\0"
+"eidskog.no\0"
+"\xe4\xbc\x81\xe4\xb8\x9a\0"
+"mk.eu.org\0"
+"gov.il\0kizu.kyoto.jp\0"
+"gov.in\0mito.ibaraki.jp\0kita.osaka.jp\0\xe6\x94\xbf\xe5\xba\x9c\0blogsite.xyz\0"
+"m\xc3\xa1latvuopmi.no\0beta.bounty-full.com\0"
+"kamagaya.chiba.jp\0aso.kumamoto.jp\0"
+"gov.iq\0"
+"the.br\0gov.ir\0kaneyama.fukushima.jp\0"
+"gov.is\0"
+"gov.it\0"
+"ed.pw\0"
+"kasuya.fukuoka.jp\0"
+"lugs.org.uk\0now-dns.org\0"
+"matsuyama.ehime.jp\0"
+"doshi.yamanashi.jp\0"
+"tran\xc3\xb8y.no\0ubs\0navoi.su\0"
+"trv\0"
+"gov.jo\0"
+"k12.ut.us\0"
+"feste-ip.net\0"
+"gov.kg\0"
+"vicenza.it\0uconnect\0"
+"gov.ki\0"
+"from-hi.com\0"
+"tas.edu.au\0gov.km\0aquarium.museum\0"
+"gov.kn\0"
+"j.bg\0"
+"hayashima.okayama.jp\0gov.kp\0"
+"gov.la\0"
+"gov.lb\0"
+"gov.lc\0g\xc3\xa1ls\xc3\xa1.no\0"
+"cloudns.pro\0"
+"gov.kw\0center.museum\0photo\0"
+"gov.ky\0stokke.no\0vladikavkaz.ru\0"
+"iwade.wakayama.jp\0gov.kz\0"
+"gov.lk\0"
+"ma.gov.br\0k12.tr\0"
+"volyn.ua\0rugby\0"
+"schwarz\0"
+"gov.ma\0tui\0"
+"ta.it\0yamagata.gifu.jp\0gov.lr\0"
+"gov.ls\0\xc3\xa5rdal.no\0"
+"gov.lt\0"
+"gov.me\0palace.museum\0"
+"gov.lv\0"
+"gov.mg\0orskog.no\0"
+"gov.ly\0for-our.info\0vladikavkaz.su\0"
+"gov.mk\0lu.eu.org\0me.eu.org\0servemp3.com\0"
+"hiranai.aomori.jp\0gov.ml\0"
+"plo.ps\0"
+"kisofukushima.nagano.jp\0gov.mn\0"
+"gov.mo\0us-gov-west-1.elasticbeanstalk.com\0"
+"uchihara.ibaraki.jp\0"
+"gov.mr\0"
+"3.bg\0gov.ms\0lund.no\0k12.vi\0"
+"friulivenezia-giulia.it\0"
+"gov.mu\0"
+"gov.mv\0"
+"chiropractic.museum\0gov.mw\0gov.ng\0j\xc3\xb8lster.no\0is-slick.com\0"
+"gsm.pl\0"
+"midatlantic.museum\0gov.my\0is-a-bulls-fan.com\0"
+"gov.mz\0durban\0"
+"tvs\0"
+"valled-aosta.it\0"
+"santabarbara.museum\0naustdal.no\0za.org\0"
+"mizuho.tokyo.jp\0"
+"nov.ru\0"
+"brand.se\0"
+"gov.nr\0"
+"columbia.museum\0"
+"kamoenai.hokkaido.jp\0"
+"konskowola.pl\0"
+"progressive\0"
+"hokksund.no\0lv.eu.org\0"
+"nakamura.kochi.jp\0"
+"soc.lk\0gov.om\0"
+"tondabayashi.osaka.jp\0"
+"nov.su\0*.spectrum.myjino.ru\0"
+"laz.it\0host\0"
+"b\xc3\xa1hccavuotna.no\0helsinki\0homelinux.com\0"
+"tmp.br\0siracusa.it\0vibovalentia.it\0"
+"skjervoy.no\0"
+"togura.nagano.jp\0"
+"gov.ph\0go.leg.br\0"
+"\xc3\xb8vre-eiker.no\0"
+"ullensaker.no\0gov.pk\0"
+"otake.hiroshima.jp\0gov.pl\0"
+"bolzano.it\0fukuroi.shizuoka.jp\0gov.pn\0"
+"exchange\0"
+"futtsu.chiba.jp\0"
+"gs.oslo.no\0gov.qa\0"
+"kimobetsu.hokkaido.jp\0gov.pr\0merckmsd\0"
+"gov.ps\0"
+"gov.pt\0"
+"sauda.no\0cherkasy.ua\0"
+"from-la.net\0"
+"bruxelles.museum\0gov.py\0"
+"mc.it\0iwate.iwate.jp\0ota.tokyo.jp\0"
+"og.ao\0bajddar.no\0e12.ve\0leadpages.co\0"
+"tagajo.miyagi.jp\0"
+"aoki.nagano.jp\0leczna.pl\0"
+"webhop.info\0"
+"latina.it\0virtueeldomein.nl\0"
+"tobishima.aichi.jp\0"
+"pasadena.museum\0"
+"contagem.br\0chosei.chiba.jp\0"
+"homesecuritymac.com\0diskstation.org\0"
+"naval.museum\0"
+"fujinomiya.shizuoka.jp\0tkmaxx\0"
+"holt\xc3\xa5len.no\0gov.sa\0"
+"gov.sb\0kicks-ass.net\0"
+"paris.museum\0gov.rs\0gov.sc\0"
+"trentino-suedtirol.it\0itano.tokushima.jp\0obanazawa.yamagata.jp\0gov.sd\0"
+"frankfurt.museum\0gov.ru\0"
+"\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0"
+"gov.rw\0gov.sg\0health-carereform.com\0"
+"gov.sh\0"
+"assisi.museum\0cadaques.museum\0herokuapp.com\0"
+"kamisunagawa.hokkaido.jp\0"
+"kota.aichi.jp\0gov.sl\0"
+"supplies\0"
+"noboribetsu.hokkaido.jp\0"
+"*.uberspace.de\0"
+"gov.st\0"
+"!city.sapporo.jp\0"
+"yalta.ua\0silk\0"
+"gov.sx\0"
+"gov.sy\0"
+"gov.tj\0"
+"ltda\0"
+"ichinohe.iwate.jp\0gov.tl\0"
+"oppeg\xc3\xa5rd.no\0gov.tm\0"
+"gov.tn\0"
+"gov.to\0"
+"kamo.kyoto.jp\0wodzislaw.pl\0"
+"volkenkunde.museum\0gov.ua\0"
+"honjo.akita.jp\0kamiamakusa.kumamoto.jp\0gov.tr\0"
+"gov.tt\0"
+"skanit.no\0"
+"kisarazu.chiba.jp\0ono.hyogo.jp\0"
+"gov.tw\0"
+"ve.it\0kosaka.akita.jp\0matsusaka.mie.jp\0pfizer\0"
+"swiebodzin.pl\0"
+"gov.uk\0"
+"art.museum\0vestv\xc3\xa5g\xc3\xb8y.no\0sina\0virtual-user.de\0"
+"yoga\0"
+"fe.it\0miura.kanagawa.jp\0"
+"gov.vc\0"
+"yasaka.nagano.jp\0"
+"gov.ve\0"
+"uonuma.niigata.jp\0"
+"florida.museum\0uno\0"
+"intel\0"
+"market\0"
+"gov.vn\0maison\0"
+"kristiansand.no\0blogspot.com\0"
+"misato.saitama.jp\0"
+"cc.il.us\0"
+"perso.sn\0"
+"uol\0"
+"chanel\0cn-north-1.eb.amazonaws.com.cn\0"
+"cody.museum\0"
+"czeladz.pl\0"
+"sakura\0kr.eu.org\0"
+"rn.it\0"
+"maritime.museum\0vipsinaapp.com\0"
+"harima.hyogo.jp\0"
+"staples\0"
+"boats\0"
+"hi.cn\0perso.tn\0"
+"gov.ws\0"
+"dell-ogliastra.it\0"
+"browsersafetymark.io\0"
+"bn.it\0dlugoleka.pl\0"
+"annefrank.museum\0"
+"hagi.yamaguchi.jp\0"
+"k12.az.us\0space\0loseyourip.com\0"
+"rns.tn\0"
+"mill.museum\0ups\0"
+"go.dyndns.org\0"
+"bozen-sudtirol.it\0"
+"dyndns-office.com\0"
+"hofu.yamaguchi.jp\0"
+"no-ip.ca\0"
+"togitsu.nagasaki.jp\0misato.wakayama.jp\0"
+"better-than.tv\0"
+"emp.br\0kani.gifu.jp\0"
+"oslo.no\0"
+"foggia.it\0mibu.tochigi.jp\0"
+"orsta.no\0is-gone.com\0"
+"og.it\0"
+"gov.za\0"
+"tenkawa.nara.jp\0"
+"communications.museum\0"
+"builders\0"
+"gov.zm\0"
+"juegos\0"
+"minami.kyoto.jp\0"
+"blackbaudcdn.net\0"
+"auction\0mypsx.net\0"
+"gov.zw\0"
+"monzaedellabrianza.it\0"
+"q-a.eu.org\0"
+"federation.aero\0cloudns.org\0"
+"site\0"
+"zamami.okinawa.jp\0"
+"emergency.aero\0from-md.com\0"
+"not.br\0repair\0"
+"airtraffic.aero\0"
+"satsumasendai.kagoshima.jp\0\xe0\xb4\xad\xe0\xb4\xbe\xe0\xb4\xb0\xe0\xb4\xa4\xe0\xb4\x82\0"
+"lajolla.museum\0familyds.org\0"
+"trentino-sudtirol.it\0"
+"mosj\xc3\xb8""en.no\0"
+"takatori.nara.jp\0"
+"recht.pro\0"
+"inashiki.ibaraki.jp\0"
+"durham.museum\0"
+"\xe5\xbe\xae\xe5\x8d\x9a\0"
+"vet\0"
+"co.business\0"
+"andria-barletta-trani.it\0suedtirol.it\0"
+"konin.pl\0linkyard-cloud.ch\0"
+"gs.tr.no\0"
+"labor.museum\0"
+"ayagawa.kagawa.jp\0"
+"zaporizhzhe.ua\0"
+"ovre-eiker.no\0"
+"yao.osaka.jp\0"
+"my-vigor.de\0"
+"northwesternmutual\0"
+"stalbans.museum\0"
+"hokuryu.hokkaido.jp\0football\0"
+"*.nagoya.jp\0"
+"teo.br\0"
+"presidio.museum\0b\xc3\xb8mlo.no\0kharkiv.ua\0from-mt.com\0from-nd.com\0"
+"lecco.it\0"
+"asahi.yamagata.jp\0"
+"salud.bo\0contemporaryart.museum\0aca.pro\0"
+"soja.okayama.jp\0tokigawa.saitama.jp\0prochowice.pl\0"
+"il.us\0is-a-geek.com\0"
+"tr.it\0gokase.miyazaki.jp\0"
+"dyn.ddnss.de\0"
+"ladbrokes\0"
+"uchiko.ehime.jp\0"
+"toyosato.shiga.jp\0ens.tn\0"
+"berkeley.museum\0s3.ap-south-1.amazonaws.com\0"
+"media.aero\0aaa.pro\0vig\0"
+"rimini.it\0itako.ibaraki.jp\0"
+"cc.wy.us\0"
+"gujo.gifu.jp\0"
+"fot.br\0vin\0"
+"vip\0"
+"cc.hi.us\0"
+"taishi.hyogo.jp\0"
+"neyagawa.osaka.jp\0genkai.saga.jp\0wakasa.tottori.jp\0"
+"co.ae\0"
+"development.run\0"
+"co.ag\0from-sd.com\0"
+"neustar\0"
+"birthplace.museum\0"
+"cesenaforl\xc3\xac.it\0"
+"amot.no\0skjerv\xc3\xb8y.no\0"
"co.ao\0"
-"creation.museum\0"
-"co.bb\0"
-"chirurgiens-dentistes.fr\0toyoura.hokkaido.jp\0"
-"co.at\0""1337.pictures\0"
-"noticias.bo\0"
-"co.bi\0kagawa.jp\0"
-"unnan.shimane.jp\0freebox-os.com\0"
-"handa.aichi.jp\0"
-"makurazaki.kagoshima.jp\0fuettertdasnetz.de\0"
-"co.ca\0"
-"lancashire.museum\0"
-"kasugai.aichi.jp\0"
-"rieti.it\0\xe7\xb6\xb2\xe8\xb7\xaf.tw\0"
-"co.bw\0"
-"co.ci\0komatsushima.tokushima.jp\0"
+"arakawa.saitama.jp\0"
+"co.bb\0trani-barletta-andria.it\0"
+"co.at\0"
+"suifu.ibaraki.jp\0oum.gov.pl\0"
+"co.bi\0kvafjord.no\0"
+"odate.akita.jp\0"
+"embroidery.museum\0"
+"takamatsu.kagawa.jp\0"
+"nokia\0"
+"civilaviation.aero\0co.ca\0"
+"sells-for-less.com\0"
+"creditcard\0"
+"from-ut.com\0"
+"rikubetsu.hokkaido.jp\0"
+"co.bw\0dr.na\0"
+"mt.it\0"
+"co.ci\0"
+"tr.no\0"
"co.cl\0"
-"co.cm\0"
-"kutchan.hokkaido.jp\0"
-"watches\0"
-"co.cr\0fukuchi.fukuoka.jp\0"
-"bike\0"
-"chambagri.fr\0toya.hokkaido.jp\0gob.mx\0allfinanz\0"
-"gob.ni\0"
-"fr.eu.org\0"
-"sanda.hyogo.jp\0co.cz\0"
-"matsubara.osaka.jp\0co.dk\0"
-"moriguchi.osaka.jp\0lviv.ua\0"
-"webhop.me\0"
-"algard.no\0"
-"demon.nl\0"
-"oarai.ibaraki.jp\0"
-"ed.pw\0"
-"asti.it\0"
-"ethnology.museum\0"
-"mishima.shizuoka.jp\0"
-"carbonia-iglesias.it\0"
-"maebashi.gunma.jp\0gob.pa\0golffan.us\0"
-"amakusa.kumamoto.jp\0sex.pl\0"
-"milan.it\0"
-"magazine.aero\0kaminoyama.yamagata.jp\0"
-"ntr.br\0\xe9\x95\xb7\xe5\xb4\x8e.jp\0kuwana.mie.jp\0gob.pe\0"
-"takasaki.gunma.jp\0"
-"adult.ht\0vikna.no\0poznan.pl\0"
-"kagoshima.jp\0takehara.hiroshima.jp\0voagat.no\0"
-"gob.pk\0"
-"auction\0"
-"arida.wakayama.jp\0"
-"evenassi.no\0writesthisblog.com\0"
-"kiyosato.hokkaido.jp\0"
+"co.cm\0philadelphiaarea.museum\0"
+"bounceme.net\0"
+"from-vt.com\0"
+"co.cr\0playstation\0"
+"hvaler.no\0"
+"servebbs.com\0"
+"guitars\0"
+"storj.farm\0"
+"poa.br\0co.cz\0"
+"co.dk\0"
+"dallas.museum\0"
+"leirfjord.no\0cc.ak.us\0"
+"localhistory.museum\0"
+"\xeb\x8b\xb7\xec\xbb\xb4\0"
+"attorney\0"
+"awaji.hyogo.jp\0higashiomi.shiga.jp\0"
+"homelinux.net\0"
+"business\0"
+"meet\0"
+"lib.ks.us\0"
+"krasnik.pl\0"
+"isshiki.aichi.jp\0okayama.okayama.jp\0"
+"koriyama.fukushima.jp\0"
+"horology.museum\0cc.mt.us\0cc.nd.us\0ybo.trade\0"
+"valleeaoste.it\0"
+"williamsburg.museum\0"
+"\xc3\xa5mli.no\0"
+"is-a-linux-user.org\0"
+"vv.it\0kozagawa.wakayama.jp\0"
"co.gg\0"
-"holmestrand.no\0bing\0kitchen\0"
-"urbinopesaro.it\0misato.saitama.jp\0"
-"ag.it\0kalisz.pl\0boston\0"
-"vic.gov.au\0co.gl\0"
-"utazu.kagawa.jp\0better-than.tv\0"
-"foggia.it\0"
-"nodum.co\0"
-"lierne.no\0joburg\0"
-"sado.niigata.jp\0"
-"stathelle.no\0"
-"co.gy\0"
-"monash\0"
-"komatsu\0"
-"ono.hyogo.jp\0"
-"journalism.museum\0"
-"sa.com\0"
-"hicam.net\0"
-"co.id\0\xe9\x95\xb7\xe9\x87\x8e.jp\0dominic.ua\0"
-"co.hu\0dontexist.net\0cya.gg\0"
-"uchinada.ishikawa.jp\0"
-"n\xc3\xa6r\xc3\xb8y.no\0"
-"modena.it\0afamilycompany\0"
-"is-a-chef.net\0"
-"sjc.br\0"
-"co.il\0"
-"co.im\0seiro.niigata.jp\0ap-southeast-1.elasticbeanstalk.com\0s3-sa-east-1.amazonaws.com\0"
-"co.in\0guide\0"
-"co.ir\0nodum.io\0"
-"trentinoaltoadige.it\0co.it\0yachiyo.chiba.jp\0polkowice.pl\0"
-"co.je\0gob.sv\0"
-"graz.museum\0"
-"wroclaw.pl\0"
-"iyo.ehime.jp\0"
-"osakasayama.osaka.jp\0"
-"campania.it\0"
-"co.jp\0diamonds\0"
-"stpetersburg.museum\0"
-"bronnoysund.no\0lomza.pl\0"
-"takko.aomori.jp\0co.ke\0"
-"kisarazu.chiba.jp\0"
-"ota.tokyo.jp\0rybnik.pl\0"
-"sm\xc3\xb8la.no\0vaksdal.no\0"
-"*.kawasaki.jp\0us.eu.org\0"
-"is-an-actress.com\0"
-"l.se\0"
-"loab\xc3\xa1t.no\0"
-"co.kr\0donostia.museum\0"
-"co.lc\0"
-"zoology.museum\0gob.ve\0go.leg.br\0"
-"s3.dualstack.ap-northeast-2.amazonaws.com\0"
-"eu-west-2.elasticbeanstalk.com\0"
-"omigawa.chiba.jp\0"
-"build\0"
-"fg.it\0ruovat.no\0"
-"point2this.com\0"
-"kunitomi.miyazaki.jp\0co.ma\0nt.no\0ballangen.no\0"
-"trani-barletta-andria.it\0"
-"bhz.br\0co.ls\0"
-"co.me\0"
-"co.mg\0"
-"hatsukaichi.hiroshima.jp\0"
-"kameoka.kyoto.jp\0fredrikstad.no\0"
-"isshiki.aichi.jp\0"
-"bologna.it\0"
-"theater.museum\0"
-"ekloges.cy\0"
-"padova.it\0"
-"gosen.niigata.jp\0co.na\0"
-"mo.cn\0"
-"is-a-nascarfan.com\0"
-"\xe0\xb8\xa8\xe0\xb8\xb6\xe0\xb8\x81\xe0\xb8\xa9\xe0\xb8\xb2.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0"
-"co.mu\0hitra.no\0"
-"gose.nara.jp\0"
-"co.mw\0prime\0"
-"co.ni\0"
-"co.mz\0"
-"higashikawa.hokkaido.jp\0co.nl\0"
-"co.no\0"
-"higashi.okinawa.jp\0"
-"seven\0"
-"oirm.gov.pl\0\xd9\xbe\xd8\xa7\xd9\x83\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0"
-"h\xc3\xa6gebostad.no\0"
-"mj\xc3\xb8ndalen.no\0"
-"sakai.fukui.jp\0"
-"ce.gov.br\0co.nz\0"
+"tokoname.aichi.jp\0"
+"mg.gov.br\0food\0"
+"co.gl\0"
+"wassamu.hokkaido.jp\0hakui.ishikawa.jp\0"
+"orland.no\0"
+"friuli-venezia-giulia.it\0"
+"sanfrancisco.museum\0"
+"omi.niigata.jp\0"
+"h.bg\0infiniti\0"
+"kokonoe.oita.jp\0"
+"co.gy\0meeres.museum\0merseine.nu\0"
+"ebino.miyazaki.jp\0tatar\0"
+"wy.us\0"
+"trentino-altoadige.it\0"
+"malatvuopmi.no\0"
+"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0"
+"melbourne\0"
+"co.id\0valdaosta.it\0"
+"co.hu\0hi.us\0is-a-geek.org\0"
+"xz.cn\0prudential\0"
+"yasugi.shimane.jp\0"
+"games.hu\0from-ct.com\0scrapping.cc\0"
+"so.it\0iwakura.aichi.jp\0saijo.ehime.jp\0"
+"co.il\0friulive-giulia.it\0mielec.pl\0"
+"co.im\0ikano\0msk.ru\0"
+"co.in\0"
+"co.ir\0kurotaki.nara.jp\0"
+"co.it\0ogawa.ibaraki.jp\0"
+"co.je\0"
+"foundation.museum\0clinic\0"
+"kamogawa.chiba.jp\0dr.tr\0"
+"santacruz.museum\0"
+"tsukigata.hokkaido.jp\0ford\0"
+"1.bg\0kalmykia.su\0"
+"shimofusa.chiba.jp\0"
+"bananarepublic\0msk.su\0"
+"umig.gov.pl\0"
+"co.jp\0warman\0"
+"luzern.museum\0s3-ap-northeast-1.amazonaws.com\0"
+"cuneo.it\0"
+"tananger.no\0"
+"vallee-aoste.it\0"
+"co.ke\0lindesnes.no\0cloud.goog\0"
+"milano.it\0"
+"wed\0"
+"wa.edu.au\0is-a-caterer.com\0"
+"edu.krd\0"
+"\xe5\xb2\x90\xe9\x98\x9c.jp\0co.kr\0legal\0rexroth\0"
+"co.lc\0*.stolos.io\0"
+"selfip.net\0"
+"slattum.no\0"
+"kawakami.nagano.jp\0computer\0"
+"stor-elvdal.no\0from-id.com\0"
+"meme\0"
+"co.ma\0"
+"akita.jp\0"
+"co.ls\0"
+"sakai.ibaraki.jp\0"
+"co.me\0royrvik.no\0rocks\0"
+"geek.nz\0"
+"co.mg\0school.na\0cc.co.us\0s3.amazonaws.com\0"
+"kommune.no\0"
+"kalmykia.ru\0"
+"ak.us\0"
+"aogaki.hyogo.jp\0kashima.ibaraki.jp\0"
+"shizuoka.jp\0"
+"co.na\0"
+"tako.chiba.jp\0kamikawa.hokkaido.jp\0"
+"media.museum\0lib.mo.us\0kicks-ass.org\0"
+"co.mu\0"
+"certification.aero\0co.mw\0"
+"nakanojo.gunma.jp\0"
+"suli.hu\0co.ni\0"
+"sicilia.it\0co.mz\0"
+"movistar\0co.nl\0"
+"menu\0"
+"co.no\0utwente.io\0"
+"school.nz\0"
+"vologda.su\0"
+"nu.ca\0george\0"
+"xihuan\0"
+"mt.us\0nd.us\0"
+"drangedal.no\0"
+"\xe5\xaf\x8c\xe5\xb1\xb1.jp\0co.nz\0"
+"rauma.no\0"
"co.om\0"
-"flog.br\0"
-"bj.cn\0"
-"miasa.nagano.jp\0nishikata.tochigi.jp\0bergbau.museum\0"
-"trentinostirol.it\0"
-"okazaki.aichi.jp\0"
-"nedre-eiker.no\0"
-"uryu.hokkaido.jp\0"
-"shriram\0"
-"brussels\0"
+"nakanoto.ishikawa.jp\0"
+"poivron.org\0"
+"cesenaforli.it\0discount\0"
+"loab\xc3\xa1t.no\0"
+"nakijin.okinawa.jp\0win\0"
+"skin\0"
"co.pl\0"
-"valle.no\0"
+"soundandvision.museum\0"
"co.pn\0"
-"vanylven.no\0jprs\0\xe6\x94\xbf\xe5\xba\x9c\0"
-"hakone.kanagawa.jp\0nt.ro\0"
-"portal.museum\0gmina.pl\0"
-"schwarz\0"
-"wakayama.wakayama.jp\0"
-"locus\0"
-"caa.aero\0co.pw\0volkswagen\0"
-"exchange.aero\0shimamoto.osaka.jp\0"
-"coffee\0"
-"nes.buskerud.no\0"
-"vlog.br\0"
-"*.compute.estate\0"
-"filatelia.museum\0"
-"*.otap.co\0"
-"st.no\0"
-"aosta-valley.it\0"
-"r\xc3\xb8yrvik.no\0"
-"alwaysdata.net\0"
-"sec.ps\0"
-"wroc.pl\0"
-"sukumo.kochi.jp\0"
-"bielawa.pl\0co.rs\0od.ua\0"
-"minamiise.mie.jp\0dst.mi.us\0"
-"cancerresearch\0"
-"urausu.hokkaido.jp\0co.rw\0"
-"tabayama.yamanashi.jp\0"
-"kg.kr\0mulhouse.museum\0"
-"g\xc3\xa1ivuotna.no\0"
-"hiroshima.jp\0"
-"lefrak\0"
-"co.st\0futurehosting.at\0"
-"maritime.museum\0"
-"mo.it\0co.th\0"
-"koza.wakayama.jp\0"
-"co.sz\0co.tj\0club.tw\0"
-"co.tm\0"
-"broadcast.museum\0latino\0"
-"muko.kyoto.jp\0berlevag.no\0shaw\0"
-"mutual\0co.ua\0dynvpn.de\0"
-"co.tt\0codespot.com\0"
-"anpachi.gifu.jp\0florist\0"
-"starachowice.pl\0lenug.su\0"
-"co.ug\0from-ga.com\0"
-"hitachi\0"
-"watch-and-clock.museum\0co.tz\0"
+"kasukabe.saitama.jp\0"
+"vgs.no\0notodden.no\0"
+"surgeonshall.museum\0cc.ma.us\0"
+"university.museum\0co.pw\0"
+"klodzko.pl\0"
+"static-access.net\0"
+"kddi\0"
+"volda.no\0troitsk.su\0"
+"kawai.iwate.jp\0"
+"coop.ht\0vc.it\0"
+"ikata.ehime.jp\0"
+"gs.rl.no\0"
+"catanzaro.it\0ogliastra.it\0"
+"\xc3\xa5s.no\0"
+"dreamhosters.com\0"
+"fc.it\0sagamihara.kanagawa.jp\0"
+"skedsmokorset.no\0"
+"lapy.pl\0"
+"figueres.museum\0midsund.no\0tuxfamily.org\0"
+"kushiro.hokkaido.jp\0"
+"x443.pw\0"
+"yamamoto.miyagi.jp\0"
+"blog\0"
+"co.rs\0active\0"
+"co.rw\0"
+"sorfold.no\0"
+"trentino-sued-tirol.it\0"
+"wme\0"
+"shimonita.gunma.jp\0"
+"coop.br\0kadogawa.miyazaki.jp\0"
+"shari.hokkaido.jp\0"
+"avocat.pro\0"
+"massa-carrara.it\0"
+"co.st\0"
+"shop.ht\0"
+"shop.hu\0productions\0"
+"yamaguchi.jp\0es.kr\0co.th\0"
+"co.sz\0co.tj\0"
+"francaise.museum\0co.tm\0ox.rs\0"
+"bl.it\0"
+"e164.arpa\0fhv.se\0"
+"genoa.it\0"
+"co.ua\0"
+"build\0"
+"langev\xc3\xa5g.no\0loabat.no\0"
+"co.tt\0"
+"skydiving.aero\0is-a-designer.com\0"
+"psi.br\0oseto.nagasaki.jp\0"
+"co.ug\0"
+"uji.kyoto.jp\0"
+"co.tz\0"
"co.uk\0"
-"b\xc3\xb8mlo.no\0"
-"tw.cn\0"
-"j.bg\0dell-ogliastra.it\0"
-"cherkassy.ua\0"
-"co.us\0stufftoread.com\0"
-"navigation.aero\0"
-"co.ve\0"
-"nisshin.aichi.jp\0"
-"ebino.miyazaki.jp\0co.vi\0"
-"toyotsu.fukuoka.jp\0co.uz\0"
-"is-a-cubicle-slave.com\0cloud.metacentrum.cz\0"
-"shibetsu.hokkaido.jp\0"
-"minamiizu.shizuoka.jp\0"
-"pg.it\0"
-"cooperativa.bo\0"
-"gs.tr.no\0"
-"vallee-d-aoste.it\0"
-"cc.or.us\0"
-"eun.eg\0"
-"vads\xc3\xb8.no\0travelersinsurance\0dnshome.de\0"
-"helsinki.museum\0"
-"inagi.tokyo.jp\0sola.no\0"
-"dyndns.tv\0"
-"imb.br\0"
-"weibo\0"
-"nombre.bo\0"
-"lib.nv.us\0okinawa\0"
-"soc.lk\0"
-"ninomiya.kanagawa.jp\0ing.pa\0"
-"finland.museum\0"
-"kariya.aichi.jp\0cbg.ru\0"
-"aostavalley.it\0taipei\0"
-"trieste.it\0koganei.tokyo.jp\0bloomberg\0"
-"circle\0ro.im\0"
-"ono.fukui.jp\0"
-"kaizuka.osaka.jp\0"
-"indianapolis.museum\0"
-"ufcfan.org\0"
-"finnoy.no\0"
-"ro.it\0"
-"sa-east-1.elasticbeanstalk.com\0"
-"panerai\0from-mo.com\0"
-"shirakawa.fukushima.jp\0historyofscience.museum\0kids.museum\0"
-"gotemba.shizuoka.jp\0co.za\0"
-"agro.bo\0"
-"parliament.cy\0"
-"dyndns.ws\0"
-"marker.no\0"
-"moonscale.net\0"
-"nakamichi.yamanashi.jp\0"
-"nakayama.yamagata.jp\0"
+"us.na\0"
+"transporte.bo\0"
+"co.us\0"
+"ito.shizuoka.jp\0"
+"osoyro.no\0co.ve\0knightpoint.systems\0"
+"pmn.it\0arita.saga.jp\0sosnowiec.pl\0"
+"sci.eg\0"
+"nu.it\0swinoujscie.pl\0"
+"co.vi\0"
+"co.uz\0"
+"nissedal.no\0"
+"grainger\0"
+"wow\0"
+"associates\0"
+"narusawa.yamanashi.jp\0"
+"rodeo\0"
+"kiyama.saga.jp\0"
+"lib.ak.us\0"
+"medio-campidano.it\0"
+"chikushino.fukuoka.jp\0mazowsze.pl\0"
+"ogori.fukuoka.jp\0kitaura.miyazaki.jp\0"
+"luxe\0"
+"assabu.hokkaido.jp\0"
+"geelvinck.museum\0"
+"malopolska.pl\0"
+"living.museum\0"
+"farmers.museum\0coffee\0"
+"fukushima.jp\0shingo.aomori.jp\0sasaguri.fukuoka.jp\0toyotomi.hokkaido.jp\0"
+"b\xc3\xa1hcavuotna.no\0"
+"tempio-olbia.it\0"
+"rl.no\0blue\0"
+"perugia.it\0"
+"commbank\0"
+"chichibu.saitama.jp\0"
+"hattfjelldal.no\0h.se\0"
+"inami.toyama.jp\0"
+"ftpaccess.cc\0"
+"yurihonjo.akita.jp\0"
+"nb.ca\0draydns.de\0"
+"mymediapc.net\0"
+"ma.us\0co.za\0"
+"kitaakita.akita.jp\0kosuge.yamanashi.jp\0"
+"docs\0"
+"tranibarlettaandria.it\0"
+"sydney.museum\0"
+"tamamura.gunma.jp\0onion\0"
+"taketomi.okinawa.jp\0myeffect.net\0"
+"k12.wi.us\0wtc\0"
+"noda.iwate.jp\0wtf\0"
"co.zm\0"
-"shinanomachi.nagano.jp\0xihuan\0"
-"rissa.no\0"
-"trentino-sud-tirol.it\0funabashi.chiba.jp\0podlasie.pl\0"
-"podzone.org\0"
-"safety.aero\0"
-"neyagawa.osaka.jp\0marylhurst.museum\0co.zw\0"
-"haboro.hokkaido.jp\0"
-"fukushima.jp\0"
-"channel\0shia\0"
-"kita.osaka.jp\0v\xc3\xa5ler.hedmark.no\0"
-"higashiura.aichi.jp\0chintai\0navoi.su\0"
-"\xe5\x8c\x97\xe6\xb5\xb7\xe9\x81\x93.jp\0"
-"\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4\xe0\xb1\x8d\0"
-"chikuhoku.nagano.jp\0toga.toyama.jp\0"
-"balsan-sudtirol.it\0"
-"ismaili\0\xe5\xbe\xae\xe5\x8d\x9a\0"
-"sinaapp.com\0"
-"trentin-su\xcc\x88""d-tirol.it\0lecco.it\0"
-"itabashi.tokyo.jp\0"
-"farmequipment.museum\0dr.na\0"
-"host\0gb.com\0"
-"\xe4\xba\xac\xe9\x83\xbd.jp\0"
-"akita.akita.jp\0shimogo.fukushima.jp\0"
-"furubira.hokkaido.jp\0idrett.no\0"
-"ginan.gifu.jp\0"
-"minato.osaka.jp\0pyatigorsk.ru\0"
-"\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4\0"
-"web.bo\0from-ct.com\0"
-"erimo.hokkaido.jp\0"
-"test.tj\0"
-"games.hu\0kawakami.nagano.jp\0"
-"technology.museum\0"
-"target\0"
-"web.co\0"
-"repbody.aero\0"
-"\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0"
-"sondrio.it\0circus.museum\0"
-"plo.ps\0"
-"savannahga.museum\0"
-"web.do\0"
-"ide.kyoto.jp\0civilisation.museum\0"
-"caxias.br\0"
-"valle-aosta.it\0global.ssl.fastly.net\0"
-"geology.museum\0"
-"sweden.museum\0"
-"yashio.saitama.jp\0mo.us\0vodka\0"
-"test.ru\0"
-"troitsk.su\0"
-"hirara.okinawa.jp\0mymediapc.net\0"
-"glug.org.uk\0"
-"modum.no\0"
-"eti.br\0game.tw\0from-pa.com\0"
-"kamakura.kanagawa.jp\0"
-"blogdns.com\0"
-"foodnetwork\0"
-"k12.mi.us\0"
-"toyotomi.hokkaido.jp\0"
-"r.cdn77.net\0"
-"yachimata.chiba.jp\0"
-"is-into-cars.com\0"
-"trentin-suedtirol.it\0"
-"tecnologia.bo\0az.us\0"
-"tado.mie.jp\0"
-"suedtirol.it\0shop\0"
-"from-dc.com\0"
-"matsue.shimane.jp\0"
-"horse\0"
-"web.gu\0"
-"show\0"
-"kawachinagano.osaka.jp\0reise\0"
-"neues.museum\0"
-"steam.museum\0"
-"cc.nm.us\0"
-"genting\0"
-"go.gov.br\0"
-"higashishirakawa.gifu.jp\0clinton.museum\0"
-"web.id\0dr.tr\0"
-"genova.it\0"
-"dynserv.org\0zapto.org\0"
-"lib.nm.us\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0ath.cx\0"
-"bo.telemark.no\0"
-"gamagori.aichi.jp\0"
-"dyn.ddnss.de\0"
-"muroran.hokkaido.jp\0"
+"horokanai.hokkaido.jp\0"
+"ikeda.nagano.jp\0"
+"jor.br\0"
+"y.bg\0co.zw\0"
+"news.hu\0"
"xen.prgmr.com\0"
-"svn-repos.de\0"
-"\xe7\xa6\x8f\xe5\xb2\xa1.jp\0"
-"\xd9\x83\xd8\xa7\xd8\xab\xd9\x88\xd9\x84\xd9\x8a\xd9\x83\0"
-"tochigi.jp\0"
+"otaki.saitama.jp\0"
+"ipifony.net\0"
+"minamitane.kagoshima.jp\0olecko.pl\0"
+"jpn.com\0workisboring.com\0"
+"tjome.no\0"
+"forli-cesena.it\0"
+"os.hordaland.no\0"
+"ako.hyogo.jp\0"
+"video.hu\0"
+"huissier-justice.fr\0kotohira.kagawa.jp\0"
+"tp.it\0ichikai.tochigi.jp\0"
+"gdansk.pl\0"
+"maizuru.kyoto.jp\0"
+"hsbc\0icbc\0lanxess\0singles\0elasticbeanstalk.com\0"
+"katowice.pl\0"
+"consulting.aero\0"
+"detroit.museum\0"
+"yaese.okinawa.jp\0"
+"office\0"
+"umbria.it\0"
+"toyota.aichi.jp\0gotemba.shizuoka.jp\0"
+"selfip.info\0"
+"vadso.no\0"
+"mo\xc3\xa5reke.no\0doha\0work\0"
+"ohkura.yamagata.jp\0"
+"pictures\0myphotos.cc\0"
+"eu.int\0shonai.fukuoka.jp\0sennan.osaka.jp\0"
+"philately.museum\0"
+"gallery\0"
+"misato.shimane.jp\0"
+"aerobatic.aero\0review\0"
+"yatomi.aichi.jp\0"
+"tosashimizu.kochi.jp\0"
+"gs.mr.no\0"
+"gd.cn\0"
+"polkowice.pl\0"
+"bale.museum\0"
+"zara\0"
+"mutsu.aomori.jp\0"
+"jaworzno.pl\0doctor\0xin\0"
+"chimkent.su\0sinaapp.com\0"
+"nishiarita.saga.jp\0"
+"cloudcontrolled.com\0"
+"chrome\0aktyubinsk.su\0"
+"muroto.kochi.jp\0"
+"tama.tokyo.jp\0"
+"hanyu.saitama.jp\0"
+"s3-website.us-east-2.amazonaws.com\0"
+"\xe8\x87\xba\xe7\x81\xa3\0"
+"\xe7\xbd\x91\xe5\x9d\x80\0"
+"\xe0\xb8\xad\xe0\xb8\x87\xe0\xb8\x84\xe0\xb9\x8c\xe0\xb8\x81\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0"
+"homelinux.org\0"
+"noda.chiba.jp\0"
+"ama.aichi.jp\0ami.ibaraki.jp\0"
+"misato.akita.jp\0"
+"cci.fr\0kawanishi.nara.jp\0"
+"cechire.com\0"
+"\xd8\xa8\xd8\xa7\xd8\xb2\xd8\xa7\xd8\xb1\0"
+"newholland\0vistaprint\0"
+"lucerne.museum\0"
+"vibo-valentia.it\0"
+"jp.eu.org\0"
+"haebaru.okinawa.jp\0suginami.tokyo.jp\0"
+"otofuke.hokkaido.jp\0kasuga.hyogo.jp\0"
+"mydatto.net\0"
+"marnardal.no\0"
+"blogspot.com.cy\0"
+"monster\0"
+"shimane.jp\0chikugo.fukuoka.jp\0zgora.pl\0"
+"komatsu\0"
+"trentino.it\0yakumo.shimane.jp\0"
+"tatamotors\0"
+"morioka.iwate.jp\0"
+"\xe9\xa3\x9f\xe5\x93\x81\0blogspot.com.ee\0"
+"kherson.ua\0blogspot.com.eg\0nid.io\0"
+"rendalen.no\0"
+"is-a-financialadvisor.com\0"
"kouhoku.saga.jp\0"
-"s3.ap-south-1.amazonaws.com\0"
-"pz.it\0"
-"voss.no\0"
-"tochio.niigata.jp\0"
-"akashi.hyogo.jp\0"
-"yorii.saitama.jp\0"
-"palmas.br\0"
-"lenvik.no\0sport\0"
-"v\xc3\xa5ler.\xc3\xb8stfold.no\0es.eu.org\0"
-"molde.no\0strand.no\0k12.ri.us\0homeip.net\0"
-"horology.museum\0"
-"trento.it\0toyota\0khakassia.su\0"
-"travel.pl\0"
-"ggf.br\0karmoy.no\0"
-"mimata.miyazaki.jp\0fedje.no\0ltda\0cloudns.pro\0"
-"costume.museum\0"
-"web.lk\0"
-"hornindal.no\0"
+"myasustor.com\0"
+"blogspot.com.ar\0"
+"vt.it\0"
+"alipay\0blogspot.com.au\0"
+"is-a-geek.net\0"
+"youth.museum\0"
+"kasuga.fukuoka.jp\0arao.kumamoto.jp\0is.gov.pl\0"
+"kozow.com\0"
+"daegu.kr\0*.kunden.ortsinfo.at\0"
+"weber\0"
+"game\0"
+"umaji.kochi.jp\0"
+"mr.no\0service.gov.uk\0"
+"hamamatsu.shizuoka.jp\0blogspot.com.br\0"
+"russia.museum\0spb.ru\0"
+"coop.tt\0"
+"f.bg\0is-uberleet.com\0krasnodar.su\0"
+"liaison\0"
+"karlsoy.no\0blogspot.com.by\0"
+"sandiego.museum\0"
+"republican\0"
+"v\xc3\xa5ler.hedmark.no\0"
+"obuse.nagano.jp\0"
+"blogspot.com.co\0"
+"historicalsociety.museum\0"
+"masuda.shimane.jp\0"
+"spb.su\0"
+"oizumi.gunma.jp\0"
+"wallonie.museum\0versicherung\0"
+"coop.mv\0"
+"coop.mw\0"
+"naka.ibaraki.jp\0isahaya.nagasaki.jp\0"
+"lierne.no\0utsira.no\0"
+"onna.okinawa.jp\0es.leg.br\0"
+"bydgoszcz.pl\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0jaguar\0"
+"sochi.su\0"
+"biei.hokkaido.jp\0konan.shiga.jp\0shop.th\0"
+"gliwice.pl\0"
+"trentinos-tirol.it\0"
+"uozu.toyama.jp\0"
+"dp.ua\0"
+"cc.vt.us\0"
+"bomlo.no\0"
+"grondar.za\0dyn.home-webserver.de\0"
+"gangaviika.no\0"
"okayama.jp\0"
-"!city.kobe.jp\0chikuho.fukuoka.jp\0"
-"fe.it\0is-very-sweet.org\0"
-"air-traffic-control.aero\0"
-"sr.it\0konan.aichi.jp\0"
-"natori.miyagi.jp\0"
-"ginowan.okinawa.jp\0"
-"date.hokkaido.jp\0"
-"konyvelo.hu\0newyork.museum\0"
-"pubol.museum\0"
-"web.nf\0"
-"cremona.it\0"
-"web.ni\0"
-"treviso.it\0temp-dns.com\0"
-"kumano.hiroshima.jp\0"
-"bergen.no\0hermes\0"
-"narviika.no\0"
-"kuriyama.hokkaido.jp\0"
-"kwp.gov.pl\0sucks\0"
-"hino.tottori.jp\0firewall-gateway.de\0"
-"custom.metacentrum.cz\0"
-"photography.museum\0"
-"search\0"
-"partners\0"
-"nakagusuku.okinawa.jp\0"
-"koeln.museum\0"
-"friulivgiulia.it\0"
-"pe.ca\0"
-"riik.ee\0nagiso.nagano.jp\0giske.no\0"
-"ivgu.no\0"
-"works\0"
-"world\0"
-"matera.it\0"
-"cim.br\0web.pk\0is-a-celticsfan.org\0"
-"taiji.wakayama.jp\0cruise\0"
-"travel.tt\0"
-"sokndal.no\0"
-"k12.wi.us\0mc.eu.org\0"
-"nishiwaki.hyogo.jp\0"
-"hob\xc3\xb8l.no\0"
-"repair\0"
-"miyota.nagano.jp\0mesaverde.museum\0oregontrail.museum\0"
-"hitachinaka.ibaraki.jp\0and.museum\0"
-"patria.bo\0koka.shiga.jp\0"
-"starnberg.museum\0"
-"ooguy.com\0"
-"udono.mie.jp\0"
-"\xe5\xa4\xa9\xe4\xb8\xbb\xe6\x95\x99\0"
-"\xe5\xb3\xb6\xe6\xa0\xb9.jp\0"
-"is-gone.com\0"
-"kadena.okinawa.jp\0"
-"trani-andria-barletta.it\0"
+"townnews-staging.com\0"
+"parma.it\0"
+"agents.aero\0doesntexist.com\0blogspot.com.es\0"
+"student.aero\0engineering\0"
+"college\0cloudns.asia\0"
+"tgory.pl\0embaixada.st\0"
+"mus.mi.us\0"
+"katsuragi.wakayama.jp\0kolobrzeg.pl\0"
+"shop.ro\0"
+"tas.gov.au\0"
+"pharmacien.fr\0sakura.chiba.jp\0"
+"coop.py\0zhitomir.ua\0"
+"jefferson.museum\0mangyshlak.su\0"
+"georgia.museum\0"
+"reggiocalabria.it\0muroran.hokkaido.jp\0"
+"pomorze.pl\0lancaster\0"
+"dinosaur.museum\0fyresdal.no\0"
+"kvitsoy.no\0dyndns1.de\0"
+"tsukiyono.gunma.jp\0"
+"lo.it\0"
+"zippo\0"
+"shop.pl\0"
+"genting\0mitsubishi\0"
+"bj.cn\0"
+"frei.no\0"
+"hurum.no\0y.se\0"
+"linkyard.cloud\0"
+"antiques.museum\0"
+"kimitsu.chiba.jp\0aisho.shiga.jp\0"
+"coop.km\0dattorelay.com\0"
+"lilly\0"
+"wegrow.pl\0"
+"ns.ca\0"
+"fujieda.shizuoka.jp\0"
+"\xe4\xba\xac\xe9\x83\xbd.jp\0"
+"dielddanuorri.no\0"
+"\xe9\xa6\x99\xe5\xb7\x9d.jp\0"
+"kasaoka.okayama.jp\0"
+"gs.va.no\0alpha.bounty-full.com\0"
+"free\0"
+"hyatt\0"
+"mansions.museum\0"
+"\xe6\xb2\x96\xe7\xb8\x84.jp\0"
+"hangout\0"
+"larsson.museum\0"
+"osakasayama.osaka.jp\0"
+"fortworth.museum\0googlecode.com\0securitytactics.com\0"
+"kochi.jp\0"
+"nuernberg.museum\0br\xc3\xb8nn\xc3\xb8y.no\0"
+"elk.pl\0"
+"caltanissetta.it\0owani.aomori.jp\0"
+"\xe7\xbb\x84\xe7\xbb\x87.hk\0"
+"tateyama.toyama.jp\0fbx-os.fr\0"
+"hanawa.fukushima.jp\0"
+"berlevag.no\0eid.no\0"
+"audnedaln.no\0gitlab.io\0"
+"kosei.shiga.jp\0"
+"namie.fukushima.jp\0"
+"firestone\0insure\0"
+"stat.no\0"
+"va.it\0fudai.iwate.jp\0"
+"nishikawa.yamagata.jp\0xxx\0"
+"uvic.museum\0"
+"dynalias.com\0"
+"yokkaichi.mie.jp\0"
+"mutsuzawa.chiba.jp\0uwajima.ehime.jp\0"
+"kirovograd.ua\0"
+"selfip.org\0"
+"nittedal.no\0"
+"lucania.it\0higashiizu.shizuoka.jp\0"
+"asmatart.museum\0exhibition.museum\0"
+"vt.us\0"
+"riobranco.br\0xyz\0*.ex.ortsinfo.at\0blogspot.com.mt\0"
+"aseral.no\0"
+"warmia.pl\0"
+"blogspot.com.ng\0"
+"mizumaki.fukuoka.jp\0"
+"sandoy.no\0"
+"hatsukaichi.hiroshima.jp\0"
+"pokrovsk.su\0"
+"laspezia.it\0"
+"is-certified.com\0"
+"motegi.tochigi.jp\0hayakawa.yamanashi.jp\0"
+"sm.ua\0"
+"babia-gora.pl\0"
+"bo.telemark.no\0narviika.no\0"
+"he.cn\0esan.hokkaido.jp\0unzen.nagasaki.jp\0"
+"vevelstad.no\0s3-fips-us-gov-west-1.amazonaws.com\0test-iserv.de\0"
+"valleaosta.it\0"
+"ciencia.bo\0fuossko.no\0s\xc3\xb8rreisa.no\0lib.ct.us\0"
+"dyn-ip24.de\0hasura-app.io\0"
+"cc.va.us\0"
+"k\xc3\xa1r\xc3\xa1\xc5\xa1johka.no\0"
+"nagi.okayama.jp\0gbiz\0"
+"aid.pl\0"
+"hole.no\0"
+"nakai.kanagawa.jp\0"
+"chieti.it\0"
+"flatanger.no\0krodsherad.no\0"
+"reggio-emilia.it\0"
+"us.org\0"
+"blogspot.com.tr\0"
+"is-a-llama.com\0"
+"enebakk.no\0scrysec.com\0"
+"*.sensiosite.cloud\0"
+"va.no\0k12.nm.us\0"
+"kurogi.fukuoka.jp\0shingu.hyogo.jp\0"
+"carrara-massa.it\0tamakawa.fukushima.jp\0"
+"s3-us-west-2.amazonaws.com\0"
+"kurobe.toyama.jp\0"
+"shizuoka.shizuoka.jp\0"
+"go-vip.co\0"
+"saintlouis.museum\0"
+"appspot.com\0"
+"cc.az.us\0"
+"hisayama.fukuoka.jp\0"
+"claims\0"
+"cog.mi.us\0"
+"sorocaba.br\0siteleaf.net\0"
+"historical.museum\0"
+"us-east-2.elasticbeanstalk.com\0"
+"torino.it\0"
+"iveland.no\0"
+"tokuyama.yamaguchi.jp\0"
+"clinton.museum\0you\0groks-this.info\0"
+"kiwa.mie.jp\0"
+"f.se\0"
+"mishima.shizuoka.jp\0"
+"lutsk.ua\0here-for-more.info\0"
+"s3.dualstack.ap-northeast-2.amazonaws.com\0barsyonline.com\0"
+"kirkenes.no\0"
+"mp.br\0"
+"mup.gov.pl\0"
+"flights\0"
+"\xe7\x82\xb9\xe7\x9c\x8b\0"
+"kunisaki.oita.jp\0"
+"sdn.gov.pl\0"
+"siellak.no\0"
+"otsu.shiga.jp\0"
+"is.eu.org\0"
+"netflix\0"
+"bahcavuotna.no\0\xe5\x81\xa5\xe5\xba\xb7\0potager.org\0"
+"kongsberg.no\0"
+"telefonica\0"
+"w.bg\0"
+"hasami.nagasaki.jp\0"
+"homebuilt.aero\0"
+"blogspot.com.uy\0"
+"school.za\0stage.nodeart.io\0"
+"bibai.hokkaido.jp\0"
+"city.hu\0lacaixa\0"
+"bofa\0"
+"izumi.kagoshima.jp\0"
+"monticello.museum\0cityeats\0"
+"essex.museum\0tjeldsund.no\0"
+"kakegawa.shizuoka.jp\0sncf\0"
+"gifts\0"
+"tn.it\0saitama.saitama.jp\0"
+"katagami.akita.jp\0"
+"it.eu.org\0"
+"monza-brianza.it\0"
+"js.org\0"
+"yamada.fukuoka.jp\0"
+"kagamiishi.fukushima.jp\0"
+"bjark\xc3\xb8y.no\0bplaced.com\0"
+"trd.br\0"
+"aland.fi\0"
+"ogi.saga.jp\0chungnam.kr\0"
+"deatnu.no\0likes-pie.com\0"
+"avellino.it\0"
+"va.us\0moscow\0barsy.mobi\0"
+"gildesk\xc3\xa5l.no\0mydrobo.com\0"
+"akkeshi.hokkaido.jp\0"
+"alvdal.no\0cc.gu.us\0"
+"is-an-artist.com\0"
+"shiroi.chiba.jp\0"
+"h\xc3\xa6gebostad.no\0firmdale\0uy.com\0webhosting.be\0"
+"americanexpress\0traeumtgerade.de\0"
+"nishitosa.kochi.jp\0sakawa.kochi.jp\0yun\0"
+"\xec\x82\xbc\xec\x84\xb1\0"
+"pisz.pl\0"
+"monzaebrianza.it\0yugawara.kanagawa.jp\0"
+"gotpantheon.com\0"
+"goldpoint\0"
+"koga.fukuoka.jp\0"
+"likescandy.com\0"
+"ag.it\0"
+"\xc3\xb8ygarden.no\0"
+"ogata.akita.jp\0gangwon.kr\0"
+"workshop.museum\0filegear-jp.me\0"
+"consulado.st\0"
+"l\xc3\xa6rdal.no\0cc.tn.us\0\xe7\xbd\x91\xe7\xab\x99\0"
+"\xe7\xb5\x84\xe7\xbb\x87.hk\0marketing\0"
+"fujiyoshida.yamanashi.jp\0"
+"repbody.aero\0sk.ca\0ralingen.no\0"
+"trust\0"
+"bulsan-sudtirol.it\0"
+"sasayama.hyogo.jp\0"
+"lib.ee\0az.us\0"
+"ofunato.iwate.jp\0shibata.miyagi.jp\0"
+"\xe5\xae\xb6\xe9\x9b\xbb\0in.eu.org\0"
+"andria-trani-barletta.it\0katsuragi.nara.jp\0"
+"freeddns.org\0"
+"belem.br\0"
+"lebesby.no\0"
+"consultant.aero\0amli.no\0"
+"\xe5\x9f\xbc\xe7\x8e\x89.jp\0"
+"ivgu.no\0viking\0"
+"sebastopol.ua\0"
+"author\0ddns.net\0"
+"ieee\0"
+"mat.br\0\xe5\xae\xae\xe5\x9f\x8e.jp\0"
+"services\0"
+"\xd0\xb1\xd0\xb5\xd0\xbb\0"
+"sayo.hyogo.jp\0shiiba.miyazaki.jp\0zip\0buyshouses.net\0"
+"wmflabs.org\0"
+"from-or.com\0"
+"moma.museum\0homeoffice.gov.uk\0"
+"children.museum\0"
+"balsan-sudtirol.it\0"
+"winners\0"
+"is-very-evil.org\0"
+"\xe9\xa4\x90\xe5\x8e\x85\0from-pr.com\0"
+"gj\xc3\xb8vik.no\0appchizi.com\0"
+"miyazaki.miyazaki.jp\0shiroishi.saga.jp\0anquan\0channel\0"
+"prd.fr\0koganei.tokyo.jp\0"
+"boleslawiec.pl\0exposed\0"
+"nishi.osaka.jp\0sagae.yamagata.jp\0bond\0"
+"iwama.ibaraki.jp\0"
+"surgery\0servep2p.com\0"
+"ayase.kanagawa.jp\0"
+"maintenance.aero\0"
+"yawata.kyoto.jp\0"
+"skjak.no\0vuelos\0"
+"vr.it\0kunohe.iwate.jp\0"
+"brussels.museum\0os.hedmark.no\0sk\xc3\xa5nland.no\0eu.meteorapp.com\0"
+"minamiise.mie.jp\0"
+"hagebostad.no\0"
+"rishiri.hokkaido.jp\0wzmiuw.gov.pl\0"
+"floripa.br\0namegata.ibaraki.jp\0xerox\0from-co.net\0"
+"fr.it\0higashikagura.hokkaido.jp\0saku.nagano.jp\0"
+"lib.il.us\0book\0"
+"saigawa.fukuoka.jp\0"
+"sirdal.no\0linde\0myjino.ru\0"
+"poker\0"
+"d.bg\0is-an-entertainer.com\0is-not-certified.com\0"
+"serveftp.net\0"
+"medecin.km\0"
+"yaotsu.gifu.jp\0"
+"vagsoy.no\0"
+"campidano-medio.it\0kamijima.ehime.jp\0"
+"gotsu.shimane.jp\0"
+"onthewifi.com\0"
+"\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa\0"
+"gu.us\0\xd0\xbe\xd0\xbd\xd0\xbb\xd0\xb0\xd0\xb9\xd0\xbd\0"
+"trentinosud-tirol.it\0firenze.it\0\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0"
+"yamanashi.yamanashi.jp\0realm.cz\0"
+"cruises\0"
+"dn.ua\0bharti\0"
+"tynset.no\0"
+"\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0"
+"tn.us\0"
+"prd.km\0r\xc3\xb8yken.no\0"
+"t3l3p0rt.net\0"
+"plants.museum\0"
+"vall\xc3\xa9""e-d-aoste.it\0nagaoka.niigata.jp\0rybnik.pl\0"
+"yasu.shiga.jp\0"
+"randaberg.no\0"
+"\xeb\x8b\xb7\xeb\x84\xb7\0"
+"ot.it\0pd.it\0\xe5\x92\x8c\xe6\xad\x8c\xe5\xb1\xb1.jp\0"
+"hitachinaka.ibaraki.jp\0"
+"b\xc3\xa1id\xc3\xa1r.no\0k12.oh.us\0"
+"alstahaug.no\0"
+"\xd5\xb0\xd5\xa1\xd5\xb5\0\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x81\xd1\x80\xd0\xb1\0"
+"yamatokoriyama.nara.jp\0dentist\0"
+"lib.az.us\0"
+"taiki.hokkaido.jp\0kitayama.wakayama.jp\0"
+"prd.mg\0bahccavuotna.no\0"
+"a.ssl.fastly.net\0"
+"ushistory.museum\0"
+"is-an-actress.com\0"
+"fedje.no\0gop.pk\0"
+"kikugawa.shizuoka.jp\0"
+"kvits\xc3\xb8y.no\0"
+"slz.br\0"
+"castres.museum\0training\0lebtimnetz.de\0"
+"shimonoseki.yamaguchi.jp\0"
+"architecture.museum\0"
+"lib.ms.us\0lib.nc.us\0"
+"dev-myqnapcloud.com\0"
+"\xe0\xa8\xad\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\xa4\0"
+"w.se\0"
+"broker\0"
+"database.museum\0"
+"soka.saitama.jp\0norton\0"
+"kushima.miyazaki.jp\0"
+"\xe9\x9b\x86\xe5\x9b\xa2\0"
+"sjc.br\0"
+"emilia-romagna.it\0"
+"spy.museum\0s3-ap-northeast-2.amazonaws.com\0"
+"kasamatsu.gifu.jp\0"
+"kagoshima.kagoshima.jp\0"
+"pa.gov.br\0"
+"s3-ap-southeast-2.amazonaws.com\0"
+"xbox\0*.futurecms.at\0"
+"*.sendai.jp\0"
+"abbott\0"
+"fjaler.no\0"
+"b\xc3\xa6rum.no\0"
+"minoh.osaka.jp\0"
+"agrar.hu\0"
+"markets\0"
+"computerhistory.museum\0notteroy.no\0"
+"kaita.hiroshima.jp\0"
+"indianmarket.museum\0lib.wa.us\0"
+"naklo.pl\0"
+"taa.it\0"
+"luster.no\0"
+"pb.gov.br\0"
+"ybo.party\0"
+"sand\xc3\xb8y.no\0"
+"lib.ga.us\0"
+"vall\xc3\xa9""edaoste.it\0ichikawa.chiba.jp\0"
+"mini\0"
+"yusui.kagoshima.jp\0schokokeks.net\0"
+"automotive.museum\0"
+"kunstunddesign.museum\0barum.no\0"
+"nasushiobara.tochigi.jp\0"
+"from-ar.com\0"
+"amakusa.kumamoto.jp\0kai.yamanashi.jp\0"
+"miyake.nara.jp\0mint\0"
+"aviation.museum\0fauske.no\0"
+"zlg.br\0shiriuchi.hokkaido.jp\0"
+"askvoll.no\0"
+"tmall\0"
+"ngo.lk\0poltava.ua\0"
+"s3.ap-northeast-2.amazonaws.com\0"
+"tenei.fukushima.jp\0spiegel\0"
+"kinokawa.wakayama.jp\0"
+"gs.cn\0experts-comptables.fr\0toride.ibaraki.jp\0"
+"jewishart.museum\0ivano-frankivsk.ua\0sohu\0"
+"wuoz.gov.pl\0"
+"palmsprings.museum\0dnepropetrovsk.ua\0"
+"koeln\0"
+"mallorca.museum\0"
+"nirasaki.yamanashi.jp\0bayern\0"
+"m\xc3\xa1tta-v\xc3\xa1rjjat.no\0ck.ua\0"
+"fetsund.no\0"
+"medical.museum\0blogsite.org\0"
+"komono.mie.jp\0powiat.pl\0"
+"ath.cx\0"
+"piw.gov.pl\0"
+"\xe5\xb3\xb6\xe6\xa0\xb9.jp\0glogow.pl\0nat.tn\0"
+"natural.bo\0mosjoen.no\0"
+"akiruno.tokyo.jp\0bplaced.net\0"
+"taito.tokyo.jp\0"
+"beskidy.pl\0"
+"film.museum\0"
+"sellsyourhome.org\0"
+"foodnetwork\0"
+"boavista.br\0saogonca.br\0yabu.hyogo.jp\0"
+"aomori.jp\0"
+"sakata.yamagata.jp\0"
+"\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xaa\xe0\xaf\x82\xe0\xae\xb0\xe0\xaf\x8d\0"
+"sera.hiroshima.jp\0psse.gov.pl\0"
+"safety\0*.platformsh.site\0"
+"\xe7\xa6\x8f\xe5\xb2\xa1.jp\0ngo.ph\0travelchannel\0"
+"express\0s3.dualstack.ap-southeast-1.amazonaws.com\0"
+"kv\xc3\xa6""fjord.no\0"
+"slg.br\0"
+"ventures\0"
+"sakuho.nagano.jp\0utsunomiya.tochigi.jp\0"
+"audible\0"
+"yanagawa.fukuoka.jp\0"
+"kashiwara.osaka.jp\0a.prod.fastly.net\0"
+"homedns.org\0"
+"lib.md.us\0"
+"*.ex.futurecms.at\0"
+"gaivuotna.no\0k12.in.us\0"
+"protection\0"
+"engineer.aero\0lavangen.no\0"
+"opencraft.hosting\0"
+"olayangroup\0"
+"celtic.museum\0d.se\0"
+"\xe6\x9c\xba\xe6\x9e\x84\0"
+"and.museum\0"
+"kanzaki.saga.jp\0"
+"principe.st\0"
+"politie\0song\0"
+"\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0"
+"cheltenham.museum\0marker.no\0"
+"\xc3\xa5""fjord.no\0"
+"daejeon.kr\0"
+"mizusawa.iwate.jp\0"
+"sony\0"
+"gru.br\0tosa.kochi.jp\0"
+"barlettatraniandria.it\0"
+"if.ua\0"
+"u.bg\0"
+"shimamaki.hokkaido.jp\0"
+"h\xc3\xb8ylandet.no\0"
+"bible\0ferrari\0"
+"vana\0"
+"medecin.fr\0"
+"pyatigorsk.ru\0"
+"\xe9\xa6\x99\xe6\xb8\xaf\0statefarm\0today\0"
+"kutno.pl\0"
+"education.museum\0is-a-player.com\0"
+"!city.kobe.jp\0bialowieza.pl\0frontdoor\0"
+"ap-southeast-2.elasticbeanstalk.com\0"
+"firewall-gateway.net\0"
+"presse.km\0mozilla-iot.org\0"
+"airguard.museum\0hzc.io\0"
+"arteducation.museum\0research.museum\0"
+"tsushima.nagasaki.jp\0"
+"karacol.su\0"
+"ishigaki.okinawa.jp\0"
+"freight.aero\0\xc3\xb8rland.no\0"
+"dnsdojo.com\0"
+"selfip.biz\0hasura.app\0"
+"tozsde.hu\0vlaanderen.museum\0"
+"nakasatsunai.hokkaido.jp\0"
+"\xe6\x84\x9b\xe7\x9f\xa5.jp\0mihama.aichi.jp\0matsudo.chiba.jp\0tachikawa.tokyo.jp\0"
+"toyonaka.osaka.jp\0"
+"ws.na\0"
+"tomisato.chiba.jp\0takahashi.okayama.jp\0matsuzaki.shizuoka.jp\0"
+"presse.ml\0"
+"gouv.fr\0"
+"cafe\0"
+"ascolipiceno.it\0"
+"pu.it\0"
+"osaka\0"
+"demon.nl\0"
+"lotte\0pt.eu.org\0"
+"sortland.no\0"
+"nord-odal.no\0"
+"servebeer.com\0"
+"lotto\0"
+"kazo.saitama.jp\0"
+"nalchik.ru\0"
+"pi.gov.br\0vlaanderen\0"
+"dsmynas.com\0"
+"kepno.pl\0"
+"childrens.museum\0"
+"gouv.ht\0"
+"api.stdlib.com\0"
+"\xce\xb5\xce\xbb\0"
+"mn.it\0\xe5\x8c\x97\xe6\xb5\xb7\xe9\x81\x93.jp\0"
+"pb.ao\0fylkesbibl.no\0"
+"fusa.no\0ngo.za\0nalchik.su\0"
+"dodge\0"
+"or.at\0"
+"grue.no\0"
+"kazimierz-dolny.pl\0"
+"or.bi\0"
+"se.net\0ru.net\0"
+"scientist.aero\0"
+"gouv.bj\0"
+"selje.no\0"
+"sopot.pl\0"
+"spdns.eu\0"
+"shimotsuma.ibaraki.jp\0tanabe.wakayama.jp\0intl.tn\0dev.static.land\0"
+"taka.hyogo.jp\0shimokitayama.nara.jp\0"
+"or.ci\0"
+"szex.hu\0chesapeakebay.museum\0"
+"gouv.ci\0"
+"sener\0"
+"kraanghke.no\0"
+"or.cr\0nakano.tokyo.jp\0"
+"lib.ky.us\0"
+"\xd8\xa7\xd8\xaa\xd8\xb5\xd8\xa7\xd9\x84\xd8\xa7\xd8\xaa\0"
+"microlight.aero\0ollo\0"
+"ota.gunma.jp\0himeshima.oita.jp\0"
+"tokashiki.okinawa.jp\0"
+"nsw.edu.au\0"
+"\xe7\x86\x8a\xe6\x9c\xac.jp\0"
+"botanical.museum\0"
+"house.museum\0"
+"cc.mn.us\0"
+"ogaki.gifu.jp\0"
+"gran.no\0"
+"shinichi.hiroshima.jp\0nadex\0"
+"ibigawa.gifu.jp\0"
"koto.tokyo.jp\0"
-"dontexist.org\0*.triton.zone\0"
-"sande.vestfold.no\0"
-"lt.eu.org\0"
-"cloudeity.net\0"
+"steam.museum\0"
+"arakawa.tokyo.jp\0"
+"medicina.bo\0"
+"turek.pl\0call\0"
+"apps.fbsbx.com\0"
+"*.dapps.earth\0"
+"utazu.kagawa.jp\0"
+"assassination.museum\0zero\0"
+"\xe7\xbd\x91\xe7\xb5\xa1.hk\0"
+"himi.toyama.jp\0"
+"k12.fl.us\0"
+"sar.it\0ichihara.chiba.jp\0unazuki.toyama.jp\0"
+"furniture\0"
+"id.au\0b.bg\0"
+"nissan\0"
+"bjarkoy.no\0azurecontainer.io\0"
+"camp\0"
+"mykolaiv.ua\0"
+"online.museum\0is-a-hunter.com\0"
+"b.br\0"
+"far.br\0"
+"nissay\0"
+"wpcomstaging.com\0"
+"starachowice.pl\0"
+"si.it\0"
+"erotika.hu\0garden.museum\0"
+"nikon\0"
+"cultural.museum\0issmarterthanyou.com\0"
+"egyptian.museum\0\xe5\x98\x89\xe9\x87\x8c\xe5\xa4\xa7\xe9\x85\x92\xe5\xba\x97\0"
+"misato.miyagi.jp\0weatherchannel\0"
+"br\xc3\xb8nn\xc3\xb8ysund.no\0"
+"ci.it\0karpacz.pl\0"
+"dynvpn.de\0"
+"togo.aichi.jp\0"
+"trader.aero\0k12.as.us\0"
+"sannohe.aomori.jp\0mizunami.gifu.jp\0hu.net\0"
+"cambridge.museum\0lewismiller.museum\0svn-repos.de\0"
+"pe.gov.br\0nosegawa.nara.jp\0cieszyn.pl\0hicam.net\0"
+"spdns.de\0"
+"or.id\0"
+"otsuchi.iwate.jp\0"
+"jessheim.no\0"
+"chernivtsi.ua\0kyoto\0from-nm.com\0"
+"macerata.it\0"
+"kr.com\0"
+"takanezawa.tochigi.jp\0"
+"london.museum\0bod\xc3\xb8.no\0is-a-conservative.com\0"
+"or.it\0"
+"desa.id\0mar.it\0"
+"k12.nv.us\0nis.za\0"
+"zappos\0"
+"aurskog-holand.no\0skiptvet.no\0my-gateway.de\0"
+"or.jp\0shiogama.miyagi.jp\0bungotakada.oita.jp\0"
+"clock.museum\0strand.no\0"
+"higashiyamato.tokyo.jp\0oguni.yamagata.jp\0"
+"andasuolo.no\0"
+"musica.ar\0shimamoto.osaka.jp\0"
+"or.ke\0"
"mikawa.yamagata.jp\0"
-"izumiotsu.osaka.jp\0"
-"reviews\0"
-"adv.br\0vefsn.no\0"
-"oyabe.toyama.jp\0roros.no\0"
-"nissedal.no\0"
-"izumozaki.niigata.jp\0"
-"kure.hiroshima.jp\0koge.tottori.jp\0"
-"yamamoto.miyagi.jp\0"
-"kitakata.fukushima.jp\0press.museum\0"
-"noda.iwate.jp\0skierv\xc3\xa1.no\0"
-"hm.no\0eid.no\0cloudns.asia\0"
-"\xe7\xae\x87\xe4\xba\xba.hk\0r\xc3\xb8yken.no\0from-il.com\0"
-"pisz.pl\0"
-"nishiizu.shizuoka.jp\0web.tj\0"
-"kamitonda.wakayama.jp\0silk\0"
-"inatsuki.fukuoka.jp\0futbol\0"
-"ebiz.tw\0"
-"valdaosta.it\0"
-"hashimoto.wakayama.jp\0my-firewall.org\0"
-"mizusawa.iwate.jp\0web.tr\0"
-"bradesco\0"
-"us-west-1.elasticbeanstalk.com\0"
-"hobby-site.org\0"
-"os.hedmark.no\0"
-"agro.pl\0"
-"gos.pk\0"
-"k12.mn.us\0"
-"arts.co\0freemasonry.museum\0troandin.no\0is-an-artist.com\0"
-"kasuga.fukuoka.jp\0barsy.co.uk\0"
-"minami.kyoto.jp\0"
-"sina\0"
-"h.bg\0"
-"budapest\0schokokeks.net\0"
-"tamayu.shimane.jp\0web.ve\0"
-"iwafune.tochigi.jp\0"
-"chtr.k12.ma.us\0dyn-vpn.de\0"
-"yanaizu.fukushima.jp\0barsy.support\0"
-"*.cryptonomic.net\0"
-"catania.it\0cc.as.us\0"
-"kunstunddesign.museum\0tokyo\0"
-"cleaning\0"
-"elblag.pl\0"
-"takahama.aichi.jp\0"
-"pe.it\0"
-"hanggliding.aero\0"
-"limited\0"
-"toyo.kochi.jp\0"
-"comunica\xc3\xa7\xc3\xb5""es.museum\0is-lost.org\0fi.eu.org\0"
-"webredirect.org\0"
-"food\0"
-"pharmacien.fr\0"
-"homedepot\0"
-"lib.oh.us\0"
-"wakuya.miyagi.jp\0jolster.no\0"
-"kunigami.okinawa.jp\0sanfrancisco.museum\0"
-"namie.fukushima.jp\0"
-"ama.aichi.jp\0ashiya.fukuoka.jp\0"
-"takagi.nagano.jp\0webspace.rocks\0"
-"suifu.ibaraki.jp\0pe.kr\0"
-"andria-barletta-trani.it\0"
-"fbxos.fr\0*.in.futurecms.at\0"
-"nose.osaka.jp\0grong.no\0malselv.no\0"
-"aknoluokta.no\0"
-"ac.ae\0"
-"rm.it\0"
-"ciencia.bo\0ebina.kanagawa.jp\0web.za\0is-found.org\0"
-"fla.no\0"
-"nakagawa.tokushima.jp\0"
-"textile.museum\0linkyard.cloud\0"
-"taiki.hokkaido.jp\0"
+"sumy.ua\0care\0selfip.com\0"
+"gon.pk\0dst.mi.us\0"
+"sokndal.no\0s3-website-us-east-1.amazonaws.com\0"
+"from-az.net\0"
+"ikeda.osaka.jp\0"
+"musica.bo\0"
+"takaoka.toyama.jp\0or.kr\0fund\0"
+"casa\0"
+"cars\0"
+"nishiaizu.fukushima.jp\0kusu.oita.jp\0minato.osaka.jp\0bieszczady.pl\0spot\0"
+"case\0gr.com\0"
+"nayoro.hokkaido.jp\0"
+"lib.ne.us\0"
+"cash\0"
+"owariasahi.aichi.jp\0"
+"utazas.hu\0"
+"decorativearts.museum\0sigdal.no\0"
+"mattel\0"
+"u.se\0gb.com\0"
+"shiraoka.saitama.jp\0gent\0"
+"bauhaus\0"
+"artcenter.museum\0cc.or.us\0serveftp.org\0shacknet.nu\0"
+"jdf.br\0"
+"collegefan.org\0"
+"isen.kagoshima.jp\0"
+"b\xc3\xb8.telemark.no\0"
+"tsuruta.aomori.jp\0"
+"mn.us\0"
+"higashiyoshino.nara.jp\0"
+"or.na\0"
+"tochigi.jp\0osakikamijima.hiroshima.jp\0kitagata.saga.jp\0"
+"or.mu\0"
+"enonic.io\0"
+"texas.museum\0leclerc\0"
+"id.ir\0habikino.osaka.jp\0"
+"qa2.com\0"
+"pa.gov.pl\0"
+"air-surveillance.aero\0axis.museum\0marine.ru\0"
+"ricoh\0"
+"ballangen.no\0"
+"odessa.ua\0careers\0"
+"palermo.it\0"
+"kitahata.saga.jp\0"
+"br.com\0"
+"\xe9\x95\xb7\xe5\xb4\x8e.jp\0"
+"campania.it\0hirogawa.wakayama.jp\0"
+"macapa.br\0yura.wakayama.jp\0"
+"my-wan.de\0"
+"k\xc3\xa5""fjord.no\0ar.com\0"
+"aisai.aichi.jp\0sanda.hyogo.jp\0"
+"trentin-s\xc3\xbc""dtirol.it\0"
+"estate.museum\0ringerike.no\0"
+"dyndns-at-home.com\0is-a-libertarian.com\0"
+"jx.cn\0"
+"newyork.museum\0"
+"yuzawa.niigata.jp\0"
+"hitachiomiya.ibaraki.jp\0test.tj\0"
+"k12.co.us\0linkitools.space\0"
+"or.pw\0"
+"fukui.jp\0mitaka.tokyo.jp\0"
+"\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4\0"
+"is-a-blogger.com\0"
+"kijo.miyazaki.jp\0id.lv\0"
+"cc.id.us\0"
+"id.ly\0"
+"altoadige.it\0"
+"hirara.okinawa.jp\0"
+"hapmir.no\0"
+"obira.hokkaido.jp\0kochi.kochi.jp\0higashiyodogawa.osaka.jp\0"
+"damnserver.com\0"
+"yame.fukuoka.jp\0ina.saitama.jp\0lowicz.pl\0"
+"war.museum\0"
+"omigawa.chiba.jp\0datsun\0"
+"modalen.no\0k12.pr.us\0tattoo\0karelia.su\0"
+"grajewo.pl\0"
+"sanofi\0"
+"ha.cn\0"
+"academy\0filegear-gb.me\0"
+"pr.gov.br\0tsukumi.oita.jp\0"
+"stjordalshalsen.no\0komforb.se\0"
+"av.it\0sunagawa.hokkaido.jp\0iijima.nagano.jp\0"
+"ishinomaki.miyagi.jp\0"
+"stord.no\0"
+"sakai.osaka.jp\0"
+"gouv.rw\0"
+"psc.br\0"
+"test.ru\0"
+"kakogawa.hyogo.jp\0"
+"budejju.no\0"
+"kariwa.niigata.jp\0iide.yamagata.jp\0"
+"gouv.sn\0"
+"kameoka.kyoto.jp\0"
+"uchinada.ishikawa.jp\0or.th\0observer\0"
+"tj.cn\0handa.aichi.jp\0kaga.ishikawa.jp\0"
+"snillfjord.no\0"
+"idf.il\0tuscany.it\0"
+"azure\0"
+"no.it\0"
+"ac.ae\0lib.pa.us\0"
+"presse.ci\0k12.ma.us\0\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\x9f\0"
+"kasama.ibaraki.jp\0"
+"tec.mi.us\0"
+"karuizawa.nagano.jp\0"
+"photography\0"
+"reisen\0\xe5\x95\x86\xe5\x9f\x8e\0"
+"or.ug\0"
+"hamatonbetsu.hokkaido.jp\0tomari.hokkaido.jp\0kita.tokyo.jp\0select\0"
+"or.tz\0"
+"mayfirst.info\0"
"ac.at\0"
"ac.be\0"
-"minakami.gunma.jp\0"
-"torino.it\0ikeda.gifu.jp\0"
-"uz.ua\0ford\0"
-"kl\xc3\xa6""bu.no\0"
-"withgoogle.com\0"
-"kitakata.miyazaki.jp\0nikko.tochigi.jp\0bialystok.pl\0"
-"veneto.it\0*.kobe.jp\0kawai.nara.jp\0"
-"hk.com\0"
-"h\xc3\xa5.no\0cloudns.org\0"
-"ac.ci\0"
-"ltd.cy\0plc.co.im\0hikimi.shimane.jp\0comcast\0"
-"site\0"
-"ac.cn\0\xe5\xa4\xa7\xe9\x98\xaa.jp\0"
-"aosta.it\0"
-"ambulance.aero\0!city.sapporo.jp\0"
-"ac.cr\0cuneo.it\0"
-"bolivia.bo\0meland.no\0us-4.evennode.com\0"
-"ac.cy\0tsubetsu.hokkaido.jp\0"
-"public.museum\0"
-"habmer.no\0"
-"sakyo.kyoto.jp\0eastafrica.museum\0square.museum\0"
-"shintomi.miyazaki.jp\0russia.museum\0"
-"gorlice.pl\0"
-"tamba.hyogo.jp\0norton\0"
-"tomika.gifu.jp\0"
-"blog\0"
-"12hp.de\0"
-"\xd0\xb1\xd0\xb5\xd0\xbb\0"
-"music.museum\0"
-"yoga\0"
-"nanporo.hokkaido.jp\0meet\0"
-"mazury.pl\0"
-"inashiki.ibaraki.jp\0"
-"ltd.gi\0adv.mz\0hosting-cluster.nl\0"
-"tsuga.tochigi.jp\0"
-"suita.osaka.jp\0ap-northeast-3.elasticbeanstalk.com\0"
-"qh.cn\0kiwa.mie.jp\0"
-"nome.pt\0"
-"perso.ht\0nexus\0"
-"arts.ve\0netbank\0""12hp.at\0"
-"sicilia.it\0"
-"ac.gn\0quebec.museum\0rovno.ua\0ltd.hk\0"
-"anan.tokushima.jp\0"
-"nantan.kyoto.jp\0"
-"walbrzych.pl\0"
-"us-3.evennode.com\0"
-"ina.ibaraki.jp\0labor.museum\0skjervoy.no\0wellbeingzone.eu\0"
-"rodoy.no\0"
-"cc.ks.us\0"
-"berg.no\0singles\0mk.eu.org\0"
-"akaiwa.okayama.jp\0"
+"rovigo.it\0ise.mie.jp\0"
+"qc.ca\0"
+"or.us\0"
+"laquila.it\0gamagori.aichi.jp\0foundation\0"
+"taira.toyama.jp\0"
+"valle-daosta.it\0"
+"barclaycard\0"
+"cloudcontrolapp.com\0"
+"hasvik.no\0"
+"takaharu.miyazaki.jp\0"
+"cisco\0"
+"hatoyama.saitama.jp\0credit\0"
+"ac.ci\0malselv.no\0"
+"ullensvang.no\0"
+"ac.cn\0gallup\0"
+"\xe9\x9d\x92\xe6\xa3\xae.jp\0minami-alps.yamanashi.jp\0"
+"g\xc3\xa1ivuotna.no\0b.se\0"
+"ac.cr\0"
+"baths.museum\0balat.no\0"
+"liguria.it\0kanan.osaka.jp\0"
+"ac.cy\0forum.hu\0"
+"is-a-knight.org\0"
+"pol.dz\0kitakata.fukushima.jp\0iizuna.nagano.jp\0"
+"presse.fr\0"
+"tsugaru.aomori.jp\0"
+"talk\0"
+"sandnes.no\0"
+"graphics\0"
+"carraramassa.it\0"
+"lipsy\0"
+"iiyama.nagano.jp\0nyuzen.toyama.jp\0"
+"network\0"
+"s.bg\0chocolate.museum\0labour.museum\0marburg.museum\0kongsvinger.no\0"
+"bnpparibas\0"
+"kashiba.nara.jp\0parliament.nz\0chrysler\0poznan.pl\0"
+"kiwi\0"
+"gdynia.pl\0"
+"barueri.br\0"
+"\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0"
+"kamaishi.iwate.jp\0"
+"id.us\0lasalle\0"
+"warszawa.pl\0"
+"sciencecenter.museum\0yodobashi\0myiphost.com\0"
+"is-a-republican.com\0"
+"chikujo.fukuoka.jp\0usa.oita.jp\0"
+"lib.ut.us\0"
+"gorizia.it\0ozu.kumamoto.jp\0"
+"franziskaner.museum\0mein-vigor.de\0"
+"cbre\0"
+"ac.gn\0friuli-v-giulia.it\0kuki.saitama.jp\0"
+"bentley\0"
+"cz.it\0"
+"gouv.km\0froland.no\0"
+"pol.ht\0worse-than.tv\0"
+"s3-website-eu-west-1.amazonaws.com\0"
+"salerno.it\0"
+"mino.gifu.jp\0\xe8\x81\x94\xe9\x80\x9a\0"
+"atami.shizuoka.jp\0"
+"building.museum\0flanders.museum\0""12hp.de\0"
+"ac.id\0kira.aichi.jp\0flt.cloud.muni.cz\0"
+"suldal.no\0"
+"british.museum\0reg.dk\0"
+"\xe6\x97\xb6\xe5\xb0\x9a\0"
+"journal.aero\0"
+"ac.il\0poniatowa.pl\0"
+"ac.im\0vang.no\0"
+"ac.in\0"
+"\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0"
+"ac.ir\0kagawa.jp\0\xe6\x84\x9b\xe5\xaa\x9b.jp\0"
+"coal.museum\0davvesiida.no\0knowsitall.info\0"
+"\xe7\xbe\xa4\xe9\xa6\xac.jp\0asahi.chiba.jp\0bato.tochigi.jp\0"
+"gouv.ml\0"
+"ha.no\0"
+"av.tr\0"
+"n\xc3\xa5\xc3\xa5mesjevuemie.no\0"
+"mashike.hokkaido.jp\0"
+"fuoisku.no\0"
+"ac.jp\0isa.kagoshima.jp\0"
+"portland.museum\0doesntexist.org\0"
+"12hp.at\0"
+"ac.ke\0"
+"mol.it\0saroma.hokkaido.jp\0ohda.shimane.jp\0"
+"\xe6\xa0\x83\xe6\x9c\xa8.jp\0"
+"schweiz.museum\0duck\0"
+"leg.br\0kuromatsunai.hokkaido.jp\0"
+"ryugasaki.ibaraki.jp\0"
+"ainan.ehime.jp\0wakasa.fukui.jp\0"
+"sumoto.kumamoto.jp\0"
+"murayama.yamagata.jp\0ac.kr\0"
+"portlligat.museum\0"
"12hp.ch\0"
-"analytics\0"
-"gwangju.kr\0"
-"ac.id\0"
-"arakawa.saitama.jp\0us.com\0"
-"mail.pl\0"
-"tobetsu.hokkaido.jp\0kuju.oita.jp\0"
-"furniture\0"
-"lug.org.uk\0"
-"ac.il\0"
-"ac.im\0watarai.mie.jp\0flanders.museum\0"
-"ac.in\0africa.com\0"
-"logistics.aero\0progressive\0space-to-rent.com\0"
-"*.elb.amazonaws.com.cn\0"
-"ac.ir\0is-a-landscaper.com\0"
-"lukow.pl\0"
-"kamisato.saitama.jp\0"
-"manchester.museum\0"
-"bible\0"
-"arts.museum\0author\0"
-"ac.jp\0uda.nara.jp\0"
-"langev\xc3\xa5g.no\0"
-"ichikawa.hyogo.jp\0gyokuto.kumamoto.jp\0chernovtsy.ua\0"
-"ac.ke\0blue\0"
-"uw.gov.pl\0from-hi.com\0"
-"toshima.tokyo.jp\0steinkjer.no\0dp.ua\0"
-"hk.cn\0"
-"oga.akita.jp\0"
-"\xc3\xa1k\xc5\x8boluokta.no\0"
-"imperia.it\0ltd.lk\0"
+"aircraft.aero\0navigation.aero\0"
+"ac.lk\0"
+"finance\0"
+"usr.cloud.muni.cz\0"
+"betainabox.com\0"
+"ac.ma\0"
+"trentino-alto-adige.it\0nonoichi.ishikawa.jp\0"
+"ac.ls\0"
+"ac.me\0mywire.org\0"
+"yuki.ibaraki.jp\0nantan.kyoto.jp\0"
+"stjohn.museum\0bplaced.de\0"
+"hanamaki.iwate.jp\0"
+"pittsburgh.museum\0"
+"educator.aero\0"
+"muenster.museum\0taifun-dns.de\0"
+"blanco\0"
+"ac.mu\0kh.ua\0"
+"ac.mw\0"
+"ascoli-piceno.it\0"
+"uslivinghistory.museum\0ac.ni\0"
+"trentin-sud-tirol.it\0ac.mz\0"
+"svalbard.no\0"
+"giize.com\0customer.speedpartner.de\0dyn-vpn.de\0"
+"inuyama.aichi.jp\0po.gov.pl\0"
+"mortgage\0toshiba\0"
+"cagliari.it\0sharp\0\xe7\xbd\x91\xe7\xbb\x9c\0"
+"ggee\0"
+"pug.it\0ac.nz\0"
+"ac.pa\0"
+"shibukawa.gunma.jp\0"
+"sorum.no\0"
+"fukuchi.fukuoka.jp\0"
+"sarpsborg.no\0"
+"vestnes.no\0chase\0"
+"tarumizu.kagoshima.jp\0shimane.shimane.jp\0"
+"farm.museum\0ilovecollege.info\0"
+"hitachi\0"
+"education\0"
+"taxi\0"
+"date.fukushima.jp\0ac.pr\0"
+"barrell-of-knowledge.info\0"
+"dealer\0"
+"fishing\0"
+"trentin-sued-tirol.it\0nanae.hokkaido.jp\0akashi.hyogo.jp\0sumida.tokyo.jp\0"
+"selbu.no\0"
+"rost.no\0"
+"tomika.gifu.jp\0"
+"ookuwa.nagano.jp\0hachijo.tokyo.jp\0"
+"silk.museum\0"
+"mjondalen.no\0k12.ri.us\0uk.com\0"
+"hidaka.hokkaido.jp\0"
+"austevoll.no\0"
+"iyo.ehime.jp\0"
+"plurinacional.bo\0"
+"kanagawa.jp\0"
+"is-a-cpa.com\0"
+"aerodrome.aero\0"
+"operaunite.com\0"
+"zuerich\0"
+"hol.no\0ac.rs\0"
+"nord-fron.no\0ac.ru\0ac.se\0lighting\0eu.org\0"
+"kujukuri.chiba.jp\0tara.saga.jp\0"
+"ac.rw\0"
+"yugawa.fukushima.jp\0dyndns.biz\0"
+"sauherad.no\0accountants\0"
+"eniwa.hokkaido.jp\0"
+"gol.no\0bridgestone\0dyndns-pics.com\0point2this.com\0"
+"takahama.fukui.jp\0"
+"skierv\xc3\xa1.no\0\xd2\x9b\xd0\xb0\xd0\xb7\0"
+"iitate.fukushima.jp\0otoyo.kochi.jp\0"
+"tatsuno.nagano.jp\0ibaraki.osaka.jp\0"
+"clinique\0"
+"pol.tr\0kosher\0"
+"ac.th\0"
+"mazury.pl\0slask.pl\0ac.sz\0ac.tj\0"
+"rhcloud.com\0"
+"natura\0"
+"okaya.nagano.jp\0b.ssl.fastly.net\0"
+"lunner.no\0aetna\0s3-website.eu-central-1.amazonaws.com\0"
+"fuchu.toyama.jp\0salon\0ma.leg.br\0"
+"divttasvuotna.no\0"
+"campobasso.it\0inagi.tokyo.jp\0"
+"ac.ug\0"
+"bristol.museum\0"
+"ac.tz\0"
+"ac.uk\0"
+"matsue.shimane.jp\0"
+"abiko.chiba.jp\0qpon\0"
+"aarp\0"
+"mobile\0"
+"oji.nara.jp\0"
+"ae.org\0"
+"li.it\0"
+"glass.museum\0"
+"serveminecraft.net\0"
+"amber.museum\0"
+"hirado.nagasaki.jp\0\xe5\x8f\xb0\xe6\xb9\xbe\0in.net\0"
+"ac.vn\0"
+"fussa.tokyo.jp\0\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\0"
+"ltd.cy\0money.museum\0s.se\0duns\0"
+"minamifurano.hokkaido.jp\0"
+"glas.museum\0"
+"mihama.mie.jp\0"
+"degree\0mobily\0\xe5\x9c\xa8\xe7\xba\xbf\0logoip.de\0"
+"e4.cz\0"
+"fashion\0"
+"realty\0"
+"from-nh.com\0"
+"recife.br\0nm.cn\0"
+"rio.br\0ueno.gunma.jp\0"
+"citic\0from-oh.com\0"
+"blogspot.vn\0"
+"ca-central-1.elasticbeanstalk.com\0"
+"viterbo.it\0shingu.fukuoka.jp\0"
+"chuo.chiba.jp\0urakawa.hokkaido.jp\0"
+"dvag\0"
+"fst.br\0tsunan.niigata.jp\0"
+"stockholm.museum\0"
+"kobayashi.miyazaki.jp\0\xe5\xa8\xb1\xe4\xb9\x90\0"
+"cc.ky.us\0"
+"bizen.okayama.jp\0"
+"koshimizu.hokkaido.jp\0shinjo.nara.jp\0"
+"trading\0from-tx.com\0"
+"ltd.gi\0ac.za\0al.eu.org\0"
+"gamo.shiga.jp\0"
+"rovno.ua\0hk.com\0"
"yatsushiro.kumamoto.jp\0"
-"\xd9\x87\xd9\x85\xd8\xb1\xd8\xa7\xd9\x87\0"
-"cnpy.gdn\0"
-"ac.kr\0"
-"arts.ro\0"
-"us-2.evennode.com\0"
-"shinkamigoto.nagasaki.jp\0"
-"warman\0barsyonline.com\0"
+"vn.ua\0richardli\0"
+"taishi.osaka.jp\0kaufen\0"
+"bearalv\xc3\xa1hki.no\0ac.zm\0"
+"chirurgiens-dentistes.fr\0rebun.hokkaido.jp\0"
+"state.museum\0"
+"equipment.aero\0"
+"k12.de.us\0ltd.hk\0"
+"setagaya.tokyo.jp\0"
+"ac.zw\0"
+"pvh.br\0firm.ht\0bbs.tr\0\xe5\x85\xab\xe5\x8d\xa6\0"
+"grandrapids.museum\0enterprises\0"
+"a\xc3\xa9roport.ci\0\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\0nodum.co\0"
+"bolt.hu\0technology\0"
+"firm.in\0hiroo.hokkaido.jp\0kadoma.osaka.jp\0"
+"isernia.it\0"
+"act.au\0"
+"agrigento.it\0"
+"drammen.no\0troandin.no\0pl.eu.org\0blogspot.re\0"
+"shioya.tochigi.jp\0mitou.yamaguchi.jp\0"
+"badaddja.no\0"
+"nogata.fukuoka.jp\0tonosho.kagawa.jp\0minamioguni.kumamoto.jp\0opoczno.pl\0"
+"go.ci\0"
+"shitara.aichi.jp\0"
+"beats\0meteorapp.com\0"
+"kumano.hiroshima.jp\0"
+"leksvik.no\0blogspot.ro\0"
+"maniwa.okayama.jp\0health\0"
+"londrina.br\0go.cr\0at.it\0yoichi.hokkaido.jp\0"
+"oygarden.no\0blogspot.rs\0"
+"zgorzelec.pl\0"
+"airbus\0blogspot.ru\0blogspot.se\0"
+"blogspot.sg\0"
+"andriabarlettatrani.it\0"
+"stj\xc3\xb8rdal.no\0blogspot.si\0"
+"blogspot.sk\0"
+"alto-adige.it\0"
+"filegear-sg.me\0nodum.io\0"
+"blogspot.sn\0"
+"firm.co\0"
+"kerryproperties\0dd-dns.de\0"
+"fuchu.hiroshima.jp\0blogspot.td\0"
+"temp-dns.com\0"
+"sx.cn\0tokai.aichi.jp\0"
+"ninja\0"
+"marylhurst.museum\0science-fiction.museum\0"
+"tozawa.yamagata.jp\0oshino.yamanashi.jp\0"
+"casino.hu\0firm.dk\0"
+"ac.gov.br\0mw.gov.pl\0"
+"ltd.lk\0hyundai\0"
+"kosai.shizuoka.jp\0kainan.wakayama.jp\0"
+"shintomi.miyazaki.jp\0raid\0"
+"lorenskog.no\0able\0cust.dev.thingdust.io\0"
+"hanno.saitama.jp\0"
+"rennebu.no\0blogspot.tw\0blogspot.ug\0"
+"nakayama.yamagata.jp\0"
+"nishio.aichi.jp\0"
+"origins\0dyn.cosidns.de\0abkhazia.su\0tula.su\0"
+"dattolocal.net\0"
+"baseball.museum\0vantaa.museum\0os\xc3\xb8yro.no\0"
+"\xe3\x82\xb9\xe3\x83\x88\xe3\x82\xa2\0blogspot.mr\0"
+"quicksytes.com\0"
+"sex.hu\0agriculture.museum\0"
+"muni.il\0kikuchi.kumamoto.jp\0\xe5\xa4\xa7\xe4\xbc\x97\xe6\xb1\xbd\xe8\xbd\xa6\0"
+"blogspot.mx\0"
+"blogspot.my\0"
+"bci.dnstrace.pro\0"
+"blogspot.nl\0"
+"qld.edu.au\0"
+"ikusaka.nagano.jp\0"
+"blogspot.no\0"
+"\xc3\xb8yer.no\0"
+"ms.gov.br\0otobe.hokkaido.jp\0"
+"sakaki.nagano.jp\0"
+"knx-server.net\0"
+"cc.nm.us\0"
+"moriya.ibaraki.jp\0"
+"miyawaka.fukuoka.jp\0"
+"sciencehistory.museum\0circle\0"
+"go.id\0"
+"burghof.museum\0donetsk.ua\0ky.us\0blogspot.pe\0"
+"bio.br\0"
+"izunokuni.shizuoka.jp\0"
+"frogans\0spdns.org\0"
+"york.museum\0k12.va.us\0ap-northeast-3.elasticbeanstalk.com\0"
+"takanabe.miyazaki.jp\0\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0"
+"isehara.kanagawa.jp\0auspost\0"
+"blogspot.qa\0"
+"scienceandhistory.museum\0"
+"trentinsued-tirol.it\0go.it\0blogspot.pt\0"
+"parliament.cy\0lib.ia.us\0"
+"mt.gov.br\0"
+"etne.no\0"
+"trentinos\xc3\xbc""d-tirol.it\0trentinsudtirol.it\0olbiatempio.it\0fukumitsu.toyama.jp\0juniper\0"
+"q.bg\0naturalhistory.museum\0s3-website-us-west-2.amazonaws.com\0"
+"sologne.museum\0"
+"santoandre.br\0"
+"go.jp\0kawaba.gunma.jp\0"
+"flor\xc3\xb8.no\0l-o-g-i-n.de\0"
+"ohtawara.tochigi.jp\0"
+"weibo\0blogspot.is\0"
+"lecce.it\0memorial\0blogspot.it\0"
+"go.ke\0"
+"tabayama.yamanashi.jp\0"
+"accident-investigation.aero\0"
+"kadena.okinawa.jp\0"
+"frosta.no\0"
+"toyokawa.aichi.jp\0banamex\0"
+"sibenik.museum\0"
+"blogspot.jp\0"
+"go.kr\0chirurgiens-dentistes-en-france.fr\0"
+"hamar.no\0"
+"environment.museum\0"
+"higashikagawa.kagawa.jp\0matsukawa.nagano.jp\0\xe5\x85\xac\xe5\x8f\xb8\0"
+"gs.aa.no\0"
+"honai.ehime.jp\0"
+"skole.museum\0utah.museum\0"
+"blogspot.kr\0"
+"trolley.museum\0bd.se\0from-me.org\0"
+"carrier.museum\0salat.no\0brussels\0cipriani\0"
+"grimstad.no\0krager\xc3\xb8.no\0"
+"lea\xc5\x8bgaviika.no\0blogspot.li\0"
+"is-by.us\0"
+"shiso.hyogo.jp\0"
+"arq.br\0"
+"\xed\x95\x9c\xea\xb5\xad\0"
+"blogspot.lt\0blogspot.md\0"
+"roan.no\0blogspot.lu\0"
+"dni.us\0ltd.ua\0"
+"championship.aero\0"
+"kobierzyce.pl\0"
+"schlesisches.museum\0blogspot.mk\0"
+"sex.pl\0"
+"archaeology.museum\0"
+"tonaki.okinawa.jp\0est.pr\0"
+"gotdns.com\0"
+"ltd.uk\0healthcare\0"
+"webhop.biz\0"
+"firm.ve\0"
+"itayanagi.aomori.jp\0suita.osaka.jp\0"
+"blogspot.fi\0"
+"narashino.chiba.jp\0"
+"\xe7\xbd\x91\xe5\xba\x97\0"
+"tsukui.kanagawa.jp\0shimosuwa.nagano.jp\0"
+"troms\xc3\xb8.no\0"
+"otaki.nagano.jp\0"
+"\xe5\xb9\xbf\xe4\xb8\x9c\0"
+"jfk.museum\0kl\xc3\xa6""bu.no\0ferrero\0"
+"berlin\0blogspot.fr\0"
+"oracle\0"
+"sukagawa.fukushima.jp\0\xe5\x98\x89\xe9\x87\x8c\0"
+"works\0"
+"world\0"
+"tcp4.me\0"
+"kumiyama.kyoto.jp\0open\0"
+"is-saved.org\0"
+"channelsdvr.net\0"
+"friuli-vegiulia.it\0"
+"taobao\0co.events\0"
+"\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\x89\0"
+"blogspot.gr\0"
+"praxi\0barsy.online\0resindevice.io\0"
+"tadaoka.osaka.jp\0"
+"go.pw\0is-a-anarchist.com\0"
+"trentinostirol.it\0star\0"
+"on.ca\0"
+"cloudeity.net\0"
+"nm.us\0blogspot.hk\0"
+"leirvik.no\0"
+"ong.br\0blogspot.hr\0"
+"lahppi.no\0"
+"*.compute.estate\0blogspot.hu\0blogspot.ie\0"
+"edu.ac\0\xc3\xa5lesund.no\0blackfriday\0"
+"is.it\0zentsuji.kagawa.jp\0"
+"paroch.k12.ma.us\0"
+"edu.af\0"
+"blogspot.in\0"
+"rennes\xc3\xb8y.no\0"
+"ozora.hokkaido.jp\0busan.kr\0"
+"blogspot.ba\0withyoutube.com\0"
+"edu.al\0"
+"sykkylven.no\0"
+"hirakata.osaka.jp\0"
+"eng.pro\0blogspot.be\0"
+"edu.ba\0aa.no\0blogspot.bg\0"
+"edu.ar\0edu.bb\0matera.it\0ibara.okayama.jp\0de.cool\0"
+"plc.ly\0"
+"blogspot.bj\0"
+"edu.au\0godaddy\0is-a-soxfan.org\0"
+"keisen.fukuoka.jp\0"
+"edu.bh\0moseushi.hokkaido.jp\0"
+"edu.bi\0crafts.museum\0"
+"edu.az\0kumamoto.kumamoto.jp\0"
+"firm.ro\0eu-central-1.elasticbeanstalk.com\0blogspot.ca\0"
+"exchange.aero\0edu.bm\0"
+"edu.bn\0tsurugi.ishikawa.jp\0"
+"edu.bo\0s\xc3\xb8r-odal.no\0"
+"blogspot.cf\0"
+"aremark.no\0"
+"edu.br\0go.th\0blogspot.ch\0"
+"edu.bs\0"
+"edu.bt\0go.tj\0"
+"s\xc3\xb8r-varanger.no\0"
+"blogspot.cl\0"
+"jogasz.hu\0orkanger.no\0"
+"edu.ci\0"
+"edu.bz\0"
+"gs.bu.no\0jambyl.su\0"
+"lublin.pl\0mysecuritycamera.net\0"
+"v\xc3\xa1rgg\xc3\xa1t.no\0"
+"edu.cn\0"
+"edu.co\0contemporary.museum\0blogspot.de\0"
+"blogspot.cv\0"
+"laakesvuemie.no\0go.ug\0"
+"boldlygoingnowhere.org\0"
+"go.tz\0blogspot.cz\0"
+"edu.cu\0blogspot.dk\0"
+"edu.cw\0stranda.no\0"
+"hikawa.shimane.jp\0"
+"serveftp.com\0"
+"shinanomachi.nagano.jp\0"
+"edu.dm\0finnoy.no\0"
+"yoka.hyogo.jp\0"
+"edu.do\0museet.museum\0b\xc3\xa1l\xc3\xa1t.no\0"
+"sano.tochigi.jp\0\xd8\xa7\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\0"
+"\xe9\xb9\xbf\xe5\x85\x90\xe5\xb3\xb6.jp\0"
+"edu.ec\0"
+"edu.ee\0"
+"edu.eg\0broadway\0"
+"livorno.it\0"
+"edu.dz\0carboniaiglesias.it\0"
+"lesja.no\0"
+"ce.it\0sytes.net\0"
+"linz.museum\0virtualuser.de\0"
+"seiyo.ehime.jp\0"
+"my-firewall.org\0"
+"kanmaki.nara.jp\0tendo.yamagata.jp\0wolomin.pl\0"
+"sula.no\0"
+"firm.nf\0"
+"edu.es\0savannahga.museum\0tonsberg.no\0"
+"edu.et\0"
+"myvnc.com\0"
+"engineer\0"
+"avoues.fr\0bihoro.hokkaido.jp\0caseih\0"
+"juedisches.museum\0"
+"al.gov.br\0"
+"group.aero\0cc.fl.us\0"
+"mg.leg.br\0"
+"pulawy.pl\0"
+"eng.br\0gift\0"
+"columbus.museum\0"
+"otari.nagano.jp\0"
+"edu.ge\0hermes\0"
+"honjo.saitama.jp\0"
+"edu.gh\0"
+"edu.gi\0coastaldefence.museum\0"
+"partners\0"
+"edu.gl\0minamiyamashiro.kyoto.jp\0"
+"edu.gn\0cloudns.biz\0"
+"no.eu.org\0"
+"edu.gp\0namikata.ehime.jp\0"
+"edu.gr\0"
+"cng.br\0edu.gt\0gosen.niigata.jp\0"
+"agro.bo\0edu.gu\0phoenix.museum\0lugansk.ua\0"
+"digital\0"
+"dyn-o-saur.com\0"
+"motoyama.kochi.jp\0"
+"industria.bo\0edu.gy\0"
+"edu.hk\0"
+"lombardia.it\0"
+"edu.hn\0iwaizumi.iwate.jp\0chino.nagano.jp\0futsu.nagasaki.jp\0"
+"fuel.aero\0blogspot.ae\0"
+"ishikari.hokkaido.jp\0"
+"akrehamn.no\0"
+"edu.ht\0"
+"toyota\0"
+"blogspot.al\0"
+"mobi\0tunes\0blogspot.am\0"
+"goiania.br\0co.financial\0"
+"yokoze.saitama.jp\0"
+"naoshima.kagawa.jp\0"
+"sola.no\0adac\0\xe6\xb8\xb8\xe6\x88\x8f\0"
+"edu.in\0yamanashi.jp\0"
+"edu.iq\0"
+"edu.is\0"
+"edu.it\0"
+"plc.uk\0"
+"piacenza.it\0terni.it\0lg.jp\0echizen.fukui.jp\0actor\0"
+"bu.no\0modum.no\0dy.fi\0"
+"takino.hyogo.jp\0"
+"\xe5\x8f\xb0\xe7\x81\xa3\0"
+"\xe5\x85\xac\xe7\x9b\x8a\0"
+"isa.us\0"
+"arts.co\0village.museum\0s\xc3\xb8r-fron.no\0vodka\0"
+"edu.jo\0moda\0dnshome.de\0"
+"tashkent.su\0byen.site\0"
+"akune.kagoshima.jp\0canon\0"
+"edu.kg\0"
+"edu.ki\0countryestate.museum\0"
+"green\0"
+"edu.km\0"
+"sango.nara.jp\0edu.kn\0"
+"navuotna.no\0lib.in.us\0"
+"yakumo.hokkaido.jp\0edu.kp\0"
+"edu.la\0"
+"nagahama.shiga.jp\0edu.lb\0"
+"edu.lc\0afjord.no\0"
+"rotorcraft.aero\0edu.kw\0"
+"udono.mie.jp\0global.prod.fastly.net\0"
+"edu.ky\0n\xc3\xa1vuotna.no\0"
+"\xe7\xbd\x91\xe7\xbb\x9c.cn\0edu.kz\0"
+"edu.lk\0"
+"pisa.it\0"
+"toyota.yamaguchi.jp\0comcast\0"
+"lombardy.it\0shikatsu.aichi.jp\0"
+"\xc3\xa1lt\xc3\xa1.no\0"
+"edu.lr\0"
+"edu.ls\0"
+"kawaue.gifu.jp\0"
+"edu.me\0"
+"edu.lv\0"
+"edu.mg\0"
+"edu.ly\0penza.su\0"
+"edu.mk\0"
+"edu.ml\0cricket\0telebit.app\0"
+"misaki.osaka.jp\0edu.mn\0cern\0"
+"edu.mo\0nz.eu.org\0"
+"tatebayashi.gunma.jp\0"
+"redstone\0nym.by\0"
+"nym.bz\0"
+"edu.ms\0mordovia.su\0"
};
static const quint16 tldChunkCount = 2;
-static const quint32 tldChunks[] = {65532, 101260};
+static const quint32 tldChunks[] = {65517, 101828};
QT_END_NAMESPACE
diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h
index e52aa4c33d..c757753c9c 100644
--- a/src/corelib/io/qwindowspipereader_p.h
+++ b/src/corelib/io/qwindowspipereader_p.h
@@ -97,7 +97,7 @@ private:
class Overlapped : public OVERLAPPED
{
- Q_DISABLE_COPY(Overlapped)
+ Q_DISABLE_COPY_MOVE(Overlapped)
public:
explicit Overlapped(QWindowsPipeReader *reader);
void clear();
diff --git a/src/corelib/io/qwindowspipewriter_p.h b/src/corelib/io/qwindowspipewriter_p.h
index d6671c3f27..6c269e86b7 100644
--- a/src/corelib/io/qwindowspipewriter_p.h
+++ b/src/corelib/io/qwindowspipewriter_p.h
@@ -134,7 +134,7 @@ private:
class Overlapped : public OVERLAPPED
{
- Q_DISABLE_COPY(Overlapped)
+ Q_DISABLE_COPY_MOVE(Overlapped)
public:
explicit Overlapped(QWindowsPipeWriter *pipeWriter);
void clear();
diff --git a/src/corelib/itemmodels/itemmodels.pri b/src/corelib/itemmodels/itemmodels.pri
index 068a8c4b3a..ebeac6e211 100644
--- a/src/corelib/itemmodels/itemmodels.pri
+++ b/src/corelib/itemmodels/itemmodels.pri
@@ -20,6 +20,14 @@ qtConfig(proxymodel) {
SOURCES += \
itemmodels/qabstractproxymodel.cpp
+ qtConfig(concatenatetablesproxymodel) {
+ HEADERS += \
+ itemmodels/qconcatenatetablesproxymodel.h
+
+ SOURCES += \
+ itemmodels/qconcatenatetablesproxymodel.cpp
+ }
+
qtConfig(identityproxymodel) {
HEADERS += \
itemmodels/qidentityproxymodel.h
@@ -35,6 +43,15 @@ qtConfig(proxymodel) {
SOURCES += \
itemmodels/qsortfilterproxymodel.cpp
}
+
+ qtConfig(transposeproxymodel) {
+ HEADERS += \
+ itemmodels/qtransposeproxymodel.h \
+ itemmodels/qtransposeproxymodel_p.h
+
+ SOURCES += \
+ itemmodels/qtransposeproxymodel.cpp
+ }
}
qtConfig(stringlistmodel) {
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index 83dcf68314..18f0f6f55f 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -77,7 +77,7 @@ void QPersistentModelIndexData::destroy(QPersistentModelIndexData *data)
{
Q_ASSERT(data);
Q_ASSERT(data->ref.load() == 0);
- QAbstractItemModel *model = const_cast<QAbstractItemModel *>(data->model);
+ QAbstractItemModel *model = const_cast<QAbstractItemModel *>(data->index.model());
// a valid persistent model index with a null model pointer can only happen if the model was destroyed
if (model) {
QAbstractItemModelPrivate *p = model->d_func();
@@ -512,10 +512,8 @@ QAbstractItemModel *QAbstractItemModelPrivate::staticEmptyModel()
void QAbstractItemModelPrivate::invalidatePersistentIndexes()
{
- for (QPersistentModelIndexData *data : qAsConst(persistent.indexes)) {
+ for (QPersistentModelIndexData *data : qAsConst(persistent.indexes))
data->index = QModelIndex();
- data->model = 0;
- }
persistent.indexes.clear();
}
@@ -530,7 +528,6 @@ void QAbstractItemModelPrivate::invalidatePersistentIndex(const QModelIndex &ind
QPersistentModelIndexData *data = *it;
persistent.indexes.erase(it);
data->index = QModelIndex();
- data->model = 0;
}
}
@@ -863,7 +860,6 @@ void QAbstractItemModelPrivate::rowsRemoved(const QModelIndex &parent,
QPersistentModelIndexData *data = *it;
persistent.indexes.erase(persistent.indexes.constFind(data->index));
data->index = QModelIndex();
- data->model = 0;
}
}
@@ -958,7 +954,6 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
QPersistentModelIndexData *data = *it;
persistent.indexes.erase(persistent.indexes.constFind(data->index));
data->index = QModelIndex();
- data->model = 0;
}
}
@@ -2334,7 +2329,7 @@ QModelIndex QAbstractItemModel::buddy(const QModelIndex &index) const
The way the search is performed is defined by the \a flags given. The list
that is returned may be empty. Note also that the order of results in the
list may not correspond to the order in the model, if for example a proxy
- model is used. The order of the results can not be relied upon.
+ model is used. The order of the results cannot be relied upon.
The search begins from the \a start index, and continues until the number
of matching data items equals \a hits, the search reaches the last row, or
@@ -2912,7 +2907,7 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
Note that other rows may be displaced accordingly. Note also that when moving
items within the same parent you should not attempt invalid or no-op moves. In
- the above example, item 2 is at row 2 before the move, so it can not be moved
+ the above example, item 2 is at row 2 before the move, so it cannot be moved
to row 2 (where it is already) or row 3 (no-op as row 3 means above row 3, where
it is already)
@@ -3298,8 +3293,6 @@ void QAbstractItemModel::changePersistentIndex(const QModelIndex &from, const QM
data->index = to;
if (to.isValid())
d->persistent.insertMultiAtEnd(to, data);
- else
- data->model = 0;
}
}
@@ -3332,8 +3325,6 @@ void QAbstractItemModel::changePersistentIndexList(const QModelIndexList &from,
data->index = to.at(i);
if (data->index.isValid())
toBeReinserted << data;
- else
- data->model = 0;
}
}
@@ -3963,7 +3954,7 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti
/*!
\internal
- QHash::insertMulti insert the value before the old value. and find() return the new value.
+ QMultiHash::insert inserts the value before the old value. and find() return the new value.
We need insertMultiAtEnd because we don't want to overwrite the old one, which should be removed later
There should be only one instance QPersistentModelIndexData per index, but in some intermediate state there may be
@@ -3973,9 +3964,9 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti
*/
void QAbstractItemModelPrivate::Persistent::insertMultiAtEnd(const QModelIndex& key, QPersistentModelIndexData *data)
{
- QHash<QModelIndex,QPersistentModelIndexData *>::iterator newIt =
- indexes.insertMulti(key, data);
- QHash<QModelIndex,QPersistentModelIndexData *>::iterator it = newIt + 1;
+ QHash<QModelIndex,QPersistentModelIndexData *>::iterator newIt = indexes.insert(key, data);
+ QHash<QModelIndex,QPersistentModelIndexData *>::iterator it = newIt;
+ ++it;
while (it != indexes.end() && it.key() == key) {
qSwap(*newIt,*it);
newIt = it;
diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h
index bec71b0606..c34876d1d6 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.h
+++ b/src/corelib/itemmodels/qabstractitemmodel.h
@@ -163,6 +163,7 @@ typedef QList<QModelIndex> QModelIndexList;
class QMimeData;
class QAbstractItemModelPrivate;
+class QTransposeProxyModelPrivate;
template <class Key, class T> class QMap;
@@ -173,6 +174,7 @@ class Q_CORE_EXPORT QAbstractItemModel : public QObject
friend class QPersistentModelIndexData;
friend class QAbstractItemViewPrivate;
friend class QIdentityProxyModel;
+ friend class QTransposeProxyModelPrivate;
public:
explicit QAbstractItemModel(QObject *parent = nullptr);
@@ -300,7 +302,9 @@ public Q_SLOTS:
virtual void revert();
protected Q_SLOTS:
- // Qt 6: Make virtual
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ virtual
+#endif
void resetInternalData();
protected:
diff --git a/src/corelib/itemmodels/qabstractitemmodel_p.h b/src/corelib/itemmodels/qabstractitemmodel_p.h
index 12fd93d217..e6085eca94 100644
--- a/src/corelib/itemmodels/qabstractitemmodel_p.h
+++ b/src/corelib/itemmodels/qabstractitemmodel_p.h
@@ -65,11 +65,10 @@ QT_REQUIRE_CONFIG(itemmodel);
class QPersistentModelIndexData
{
public:
- QPersistentModelIndexData() : model(0) {}
- QPersistentModelIndexData(const QModelIndex &idx) : index(idx), model(idx.model()) {}
+ QPersistentModelIndexData() {}
+ QPersistentModelIndexData(const QModelIndex &idx) : index(idx) {}
QModelIndex index;
QAtomicInt ref;
- const QAbstractItemModel *model;
static QPersistentModelIndexData *create(const QModelIndex &index);
static void destroy(QPersistentModelIndexData *data);
};
@@ -142,7 +141,7 @@ public:
struct Persistent {
Persistent() {}
- QHash<QModelIndex, QPersistentModelIndexData *> indexes;
+ QMultiHash<QModelIndex, QPersistentModelIndexData *> indexes;
QStack<QVector<QPersistentModelIndexData *> > moved;
QStack<QVector<QPersistentModelIndexData *> > invalidated;
void insertMultiAtEnd(const QModelIndex& key, QPersistentModelIndexData *data);
diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp
index 62b3ee85b9..c863406afd 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.cpp
+++ b/src/corelib/itemmodels/qabstractproxymodel.cpp
@@ -313,6 +313,18 @@ bool QAbstractProxyModel::setHeaderData(int section, Qt::Orientation orientation
return d->model->setHeaderData(sourceSection, orientation, value, role);
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \reimp
+ \since 6.0
+ */
+bool QAbstractProxyModel::clearItemData(const QModelIndex &index)
+{
+ Q_D(QAbstractProxyModel);
+ return d->model->clearItemData(mapToSource(index));
+}
+#endif
+
/*!
\reimp
*/
diff --git a/src/corelib/itemmodels/qabstractproxymodel.h b/src/corelib/itemmodels/qabstractproxymodel.h
index 08ecf9d15f..c9a73b6a31 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.h
+++ b/src/corelib/itemmodels/qabstractproxymodel.h
@@ -78,6 +78,9 @@ public:
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
bool setItemData(const QModelIndex& index, const QMap<int, QVariant> &roles) override;
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ bool clearItemData(const QModelIndex &index) override;
+#endif
QModelIndex buddy(const QModelIndex &index) const override;
bool canFetchMore(const QModelIndex &parent) const override;
diff --git a/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp b/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp
new file mode 100644
index 0000000000..a20024f468
--- /dev/null
+++ b/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp
@@ -0,0 +1,750 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qconcatenatetablesproxymodel.h"
+#include <private/qabstractitemmodel_p.h>
+#include "qsize.h"
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+class QConcatenateTablesProxyModelPrivate : public QAbstractItemModelPrivate
+{
+ Q_DECLARE_PUBLIC(QConcatenateTablesProxyModel);
+
+public:
+ QConcatenateTablesProxyModelPrivate();
+
+ int computeRowsPrior(const QAbstractItemModel *sourceModel) const;
+
+ struct SourceModelForRowResult
+ {
+ SourceModelForRowResult() : sourceModel(Q_NULLPTR), sourceRow(-1) {}
+ QAbstractItemModel *sourceModel;
+ int sourceRow;
+ };
+ SourceModelForRowResult sourceModelForRow(int row) const;
+
+ void _q_slotRowsAboutToBeInserted(const QModelIndex &, int start, int end);
+ void _q_slotRowsInserted(const QModelIndex &, int start, int end);
+ void _q_slotRowsAboutToBeRemoved(const QModelIndex &, int start, int end);
+ void _q_slotRowsRemoved(const QModelIndex &, int start, int end);
+ void _q_slotColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end);
+ void _q_slotColumnsInserted(const QModelIndex &parent, int, int);
+ void _q_slotColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+ void _q_slotColumnsRemoved(const QModelIndex &parent, int, int);
+ void _q_slotDataChanged(const QModelIndex &from, const QModelIndex &to, const QVector<int> &roles);
+ void _q_slotSourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint);
+ void _q_slotSourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint);
+ void _q_slotModelAboutToBeReset();
+ void _q_slotModelReset();
+ int columnCountAfterChange(const QAbstractItemModel *model, int newCount) const;
+ int calculatedColumnCount() const;
+ void updateColumnCount();
+ bool mapDropCoordinatesToSource(int row, int column, const QModelIndex &parent,
+ int *sourceRow, int *sourceColumn, QModelIndex *sourceParent, QAbstractItemModel **sourceModel) const;
+
+ QVector<QAbstractItemModel *> m_models;
+ int m_rowCount; // have to maintain it here since we can't compute during model destruction
+ int m_columnCount;
+
+ // for columns{AboutToBe,}{Inserted,Removed}
+ int m_newColumnCount;
+
+ // for layoutAboutToBeChanged/layoutChanged
+ QVector<QPersistentModelIndex> layoutChangePersistentIndexes;
+ QVector<QModelIndex> layoutChangeProxyIndexes;
+};
+
+QConcatenateTablesProxyModelPrivate::QConcatenateTablesProxyModelPrivate()
+ : m_rowCount(0),
+ m_columnCount(0),
+ m_newColumnCount(0)
+{
+}
+
+/*!
+ \since 5.13
+ \class QConcatenateTablesProxyModel
+ \inmodule QtCore
+ \brief The QConcatenateTablesProxyModel class proxies multiple source models, concatenating their rows.
+
+ \ingroup model-view
+
+ QConcatenateTablesProxyModel takes multiple source models and concatenates their rows.
+
+ In other words, the proxy will have all rows of the first source model,
+ followed by all rows of the second source model, and so on.
+
+ If the source models don't have the same number of columns, the proxy will only
+ have as many columns as the source model with the smallest number of columns.
+ Additional columns in other source models will simply be ignored.
+
+ Source models can be added and removed at runtime, and the column count is adjusted accordingly.
+
+ This proxy does not inherit from QAbstractProxyModel because it uses multiple source
+ models, rather than a single one.
+
+ Only flat models (lists and tables) are supported, tree models are not.
+
+ \sa QAbstractProxyModel, {Model/View Programming}, QIdentityProxyModel, QAbstractItemModel
+ */
+
+
+/*!
+ Constructs a concatenate-rows proxy model with the given \a parent.
+*/
+QConcatenateTablesProxyModel::QConcatenateTablesProxyModel(QObject *parent)
+ : QAbstractItemModel(*new QConcatenateTablesProxyModelPrivate, parent)
+{
+}
+
+/*!
+ Destroys this proxy model.
+*/
+QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel()
+{
+}
+
+/*!
+ Returns the proxy index for a given \a sourceIndex, which can be from any of the source models.
+*/
+QModelIndex QConcatenateTablesProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ if (!sourceIndex.isValid())
+ return QModelIndex();
+ const QAbstractItemModel *sourceModel = sourceIndex.model();
+ if (!d->m_models.contains(const_cast<QAbstractItemModel *>(sourceModel))) {
+ qWarning("QConcatenateTablesProxyModel: index from wrong model passed to mapFromSource");
+ Q_ASSERT(!"QConcatenateTablesProxyModel: index from wrong model passed to mapFromSource");
+ return QModelIndex();
+ }
+ if (sourceIndex.column() >= d->m_columnCount)
+ return QModelIndex();
+ int rowsPrior = d_func()->computeRowsPrior(sourceModel);
+ return createIndex(rowsPrior + sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer());
+}
+
+/*!
+ Returns the source index for a given \a proxyIndex.
+*/
+QModelIndex QConcatenateTablesProxyModel::mapToSource(const QModelIndex &proxyIndex) const
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ Q_ASSERT(checkIndex(proxyIndex));
+ if (!proxyIndex.isValid())
+ return QModelIndex();
+ if (proxyIndex.model() != this) {
+ qWarning("QConcatenateTablesProxyModel: index from wrong model passed to mapToSource");
+ Q_ASSERT(!"QConcatenateTablesProxyModel: index from wrong model passed to mapToSource");
+ return QModelIndex();
+ }
+ const int row = proxyIndex.row();
+ const auto result = d->sourceModelForRow(row);
+ if (!result.sourceModel)
+ return QModelIndex();
+ return result.sourceModel->index(result.sourceRow, proxyIndex.column());
+}
+
+/*!
+ \reimp
+*/
+QVariant QConcatenateTablesProxyModel::data(const QModelIndex &index, int role) const
+{
+ const QModelIndex sourceIndex = mapToSource(index);
+ Q_ASSERT(checkIndex(index, CheckIndexOption::IndexIsValid));
+ if (!sourceIndex.isValid())
+ return QVariant();
+ return sourceIndex.data(role);
+}
+
+/*!
+ \reimp
+*/
+bool QConcatenateTablesProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ Q_ASSERT(checkIndex(index, CheckIndexOption::IndexIsValid));
+ const QModelIndex sourceIndex = mapToSource(index);
+ Q_ASSERT(sourceIndex.isValid());
+ const auto sourceModel = const_cast<QAbstractItemModel *>(sourceIndex.model());
+ return sourceModel->setData(sourceIndex, value, role);
+}
+
+/*!
+ \reimp
+*/
+QMap<int, QVariant> QConcatenateTablesProxyModel::itemData(const QModelIndex &proxyIndex) const
+{
+ Q_ASSERT(checkIndex(proxyIndex));
+ const QModelIndex sourceIndex = mapToSource(proxyIndex);
+ Q_ASSERT(sourceIndex.isValid());
+ return sourceIndex.model()->itemData(sourceIndex);
+}
+
+/*!
+ \reimp
+*/
+bool QConcatenateTablesProxyModel::setItemData(const QModelIndex &proxyIndex, const QMap<int, QVariant> &roles)
+{
+ Q_ASSERT(checkIndex(proxyIndex));
+ const QModelIndex sourceIndex = mapToSource(proxyIndex);
+ Q_ASSERT(sourceIndex.isValid());
+ const auto sourceModel = const_cast<QAbstractItemModel *>(sourceIndex.model());
+ return sourceModel->setItemData(sourceIndex, roles);
+}
+
+/*!
+ Returns the flags for the given index.
+ If the \a index is valid, the flags come from the source model for this \a index.
+ If the \a index is invalid (as used to determine if dropping onto an empty area
+ in the view is allowed, for instance), the flags from the first model are returned.
+*/
+Qt::ItemFlags QConcatenateTablesProxyModel::flags(const QModelIndex &index) const
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ if (d->m_models.isEmpty())
+ return Qt::NoItemFlags;
+ Q_ASSERT(checkIndex(index));
+ if (!index.isValid())
+ return d->m_models.at(0)->flags(index);
+ const QModelIndex sourceIndex = mapToSource(index);
+ Q_ASSERT(sourceIndex.isValid());
+ return sourceIndex.model()->flags(sourceIndex);
+}
+
+/*!
+ This method returns the horizontal header data for the first source model,
+ and the vertical header data for the source model corresponding to each row.
+ \reimp
+*/
+QVariant QConcatenateTablesProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ if (d->m_models.isEmpty())
+ return QVariant();
+ switch (orientation) {
+ case Qt::Horizontal:
+ return d->m_models.at(0)->headerData(section, orientation, role);
+ case Qt::Vertical: {
+ const auto result = d->sourceModelForRow(section);
+ Q_ASSERT(result.sourceModel);
+ return result.sourceModel->headerData(result.sourceRow, orientation, role);
+ }
+ }
+ return QVariant();
+}
+
+/*!
+ This method returns the column count of the source model with the smallest number of columns.
+ \reimp
+*/
+int QConcatenateTablesProxyModel::columnCount(const QModelIndex &parent) const
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ if (parent.isValid())
+ return 0; // flat model
+ return d->m_columnCount;
+}
+
+/*!
+ \reimp
+*/
+QModelIndex QConcatenateTablesProxyModel::index(int row, int column, const QModelIndex &parent) const
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ Q_ASSERT(hasIndex(row, column, parent));
+ if (!hasIndex(row, column, parent))
+ return QModelIndex();
+ Q_ASSERT(checkIndex(parent, QAbstractItemModel::CheckIndexOption::ParentIsInvalid)); // flat model
+ const auto result = d->sourceModelForRow(row);
+ Q_ASSERT(result.sourceModel);
+ return mapFromSource(result.sourceModel->index(result.sourceRow, column));
+}
+
+/*!
+ \reimp
+*/
+QModelIndex QConcatenateTablesProxyModel::parent(const QModelIndex &index) const
+{
+ Q_UNUSED(index);
+ return QModelIndex(); // flat model, no hierarchy
+}
+
+/*!
+ \reimp
+*/
+int QConcatenateTablesProxyModel::rowCount(const QModelIndex &parent) const
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ Q_ASSERT(checkIndex(parent, QAbstractItemModel::CheckIndexOption::ParentIsInvalid)); // flat model
+ Q_UNUSED(parent);
+ return d->m_rowCount;
+}
+
+/*!
+ This method returns the mime types for the first source model.
+ \reimp
+*/
+QStringList QConcatenateTablesProxyModel::mimeTypes() const
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ if (d->m_models.isEmpty())
+ return QStringList();
+ return d->m_models.at(0)->mimeTypes();
+}
+
+/*!
+ The call is forwarded to the source model of the first index in the list of \a indexes.
+
+ Important: please note that this proxy only supports dragging a single row.
+ It will assert if called with indexes from multiple rows, because dragging rows that
+ might come from different source models cannot be implemented generically by this proxy model.
+ Each piece of data in the QMimeData needs to be merged, which is data-type-specific.
+ Reimplement this method in a subclass if you want to support dragging multiple rows.
+
+ \reimp
+*/
+QMimeData *QConcatenateTablesProxyModel::mimeData(const QModelIndexList &indexes) const
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ if (indexes.isEmpty())
+ return nullptr;
+ const QModelIndex firstIndex = indexes.first();
+ Q_ASSERT(checkIndex(firstIndex, CheckIndexOption::IndexIsValid));
+ const auto result = d->sourceModelForRow(firstIndex.row());
+ QModelIndexList sourceIndexes;
+ sourceIndexes.reserve(indexes.count());
+ for (const QModelIndex &index : indexes) {
+ const QModelIndex sourceIndex = mapToSource(index);
+ Q_ASSERT(sourceIndex.model() == result.sourceModel); // see documentation above
+ sourceIndexes.append(sourceIndex);
+ }
+ return result.sourceModel->mimeData(sourceIndexes);
+}
+
+
+bool QConcatenateTablesProxyModelPrivate::mapDropCoordinatesToSource(int row, int column, const QModelIndex &parent,
+ int *sourceRow, int *sourceColumn, QModelIndex *sourceParent, QAbstractItemModel **sourceModel) const
+{
+ Q_Q(const QConcatenateTablesProxyModel);
+ *sourceColumn = column;
+ if (!parent.isValid()) {
+ // Drop after the last item
+ if (row == -1 || row == m_rowCount) {
+ *sourceRow = -1;
+ *sourceModel = m_models.constLast();
+ return true;
+ }
+ // Drop between toplevel items
+ const auto result = sourceModelForRow(row);
+ Q_ASSERT(result.sourceModel);
+ *sourceRow = result.sourceRow;
+ *sourceModel = result.sourceModel;
+ return true;
+ } else {
+ if (row > -1)
+ return false; // flat model, no dropping as new children of items
+ // Drop onto item
+ const int targetRow = parent.row();
+ const auto result = sourceModelForRow(targetRow);
+ Q_ASSERT(result.sourceModel);
+ const QModelIndex sourceIndex = q->mapToSource(parent);
+ *sourceRow = -1;
+ *sourceParent = sourceIndex;
+ *sourceModel = result.sourceModel;
+ return true;
+ }
+}
+
+/*!
+ \reimp
+*/
+bool QConcatenateTablesProxyModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ if (d->m_models.isEmpty())
+ return false;
+
+ int sourceRow, sourceColumn;
+ QModelIndex sourceParent;
+ QAbstractItemModel *sourceModel;
+ if (!d->mapDropCoordinatesToSource(row, column, parent, &sourceRow, &sourceColumn, &sourceParent, &sourceModel))
+ return false;
+ return sourceModel->canDropMimeData(data, action, sourceRow, sourceColumn, sourceParent);
+}
+
+/*!
+ QConcatenateTablesProxyModel handles dropping onto an item, between items, and after the last item.
+ In all cases the call is forwarded to the underlying source model.
+ When dropping onto an item, the source model for this item is called.
+ When dropping between items, the source model immediately below the drop position is called.
+ When dropping after the last item, the last source model is called.
+
+ \reimp
+*/
+bool QConcatenateTablesProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ if (d->m_models.isEmpty())
+ return false;
+ int sourceRow, sourceColumn;
+ QModelIndex sourceParent;
+ QAbstractItemModel *sourceModel;
+ if (!d->mapDropCoordinatesToSource(row, column, parent, &sourceRow, &sourceColumn, &sourceParent, &sourceModel))
+ return false;
+
+ return sourceModel->dropMimeData(data, action, sourceRow, sourceColumn, sourceParent);
+}
+
+/*!
+ \reimp
+*/
+QSize QConcatenateTablesProxyModel::span(const QModelIndex &index) const
+{
+ Q_D(const QConcatenateTablesProxyModel);
+ Q_ASSERT(checkIndex(index));
+ if (d->m_models.isEmpty() || !index.isValid())
+ return QSize();
+ const QModelIndex sourceIndex = mapToSource(index);
+ Q_ASSERT(sourceIndex.isValid());
+ return sourceIndex.model()->span(sourceIndex);
+}
+
+/*!
+ Adds a source model \a sourceModel, below all previously added source models.
+
+ The ownership of \a sourceModel is not affected by this.
+
+ The same source model cannot be added more than once.
+ */
+void QConcatenateTablesProxyModel::addSourceModel(QAbstractItemModel *sourceModel)
+{
+ Q_D(QConcatenateTablesProxyModel);
+ Q_ASSERT(sourceModel);
+ Q_ASSERT(!d->m_models.contains(sourceModel));
+ connect(sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), this, SLOT(_q_slotDataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ connect(sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(_q_slotRowsInserted(QModelIndex,int,int)));
+ connect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_slotRowsRemoved(QModelIndex,int,int)));
+ connect(sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(_q_slotRowsAboutToBeInserted(QModelIndex,int,int)));
+ connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(_q_slotRowsAboutToBeRemoved(QModelIndex,int,int)));
+
+ connect(sourceModel, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(_q_slotColumnsInserted(QModelIndex,int,int)));
+ connect(sourceModel, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(_q_slotColumnsRemoved(QModelIndex,int,int)));
+ connect(sourceModel, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(_q_slotColumnsAboutToBeInserted(QModelIndex,int,int)));
+ connect(sourceModel, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(_q_slotColumnsAboutToBeRemoved(QModelIndex,int,int)));
+
+ connect(sourceModel, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>, QAbstractItemModel::LayoutChangeHint)),
+ this, SLOT(_q_slotSourceLayoutAboutToBeChanged(QList<QPersistentModelIndex>, QAbstractItemModel::LayoutChangeHint)));
+ connect(sourceModel, SIGNAL(layoutChanged(QList<QPersistentModelIndex>, QAbstractItemModel::LayoutChangeHint)),
+ this, SLOT(_q_slotSourceLayoutChanged(QList<QPersistentModelIndex>, QAbstractItemModel::LayoutChangeHint)));
+ connect(sourceModel, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_slotModelAboutToBeReset()));
+ connect(sourceModel, SIGNAL(modelReset()), this, SLOT(_q_slotModelReset()));
+
+ const int newRows = sourceModel->rowCount();
+ if (newRows > 0)
+ beginInsertRows(QModelIndex(), d->m_rowCount, d->m_rowCount + newRows - 1);
+ d->m_rowCount += newRows;
+ d->m_models.append(sourceModel);
+ if (newRows > 0)
+ endInsertRows();
+
+ d->updateColumnCount();
+}
+
+/*!
+ Removes the source model \a sourceModel, which was previously added to this proxy.
+
+ The ownership of \a sourceModel is not affected by this.
+*/
+void QConcatenateTablesProxyModel::removeSourceModel(QAbstractItemModel *sourceModel)
+{
+ Q_D(QConcatenateTablesProxyModel);
+ Q_ASSERT(d->m_models.contains(sourceModel));
+ disconnect(sourceModel, 0, this, 0);
+
+ const int rowsRemoved = sourceModel->rowCount();
+ const int rowsPrior = d->computeRowsPrior(sourceModel); // location of removed section
+
+ if (rowsRemoved > 0)
+ beginRemoveRows(QModelIndex(), rowsPrior, rowsPrior + rowsRemoved - 1);
+ d->m_models.removeOne(sourceModel);
+ d->m_rowCount -= rowsRemoved;
+ if (rowsRemoved > 0)
+ endRemoveRows();
+
+ d->updateColumnCount();
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotRowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ if (parent.isValid()) // not supported, the proxy is a flat model
+ return;
+ const QAbstractItemModel * const model = static_cast<QAbstractItemModel *>(q->sender());
+ const int rowsPrior = computeRowsPrior(model);
+ q->beginInsertRows(QModelIndex(), rowsPrior + start, rowsPrior + end);
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotRowsInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ if (parent.isValid()) // flat model
+ return;
+ m_rowCount += end - start + 1;
+ q->endInsertRows();
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ if (parent.isValid()) // flat model
+ return;
+ const QAbstractItemModel * const model = static_cast<QAbstractItemModel *>(q->sender());
+ const int rowsPrior = computeRowsPrior(model);
+ q->beginRemoveRows(QModelIndex(), rowsPrior + start, rowsPrior + end);
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotRowsRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ if (parent.isValid()) // flat model
+ return;
+ m_rowCount -= end - start + 1;
+ q->endRemoveRows();
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ if (parent.isValid()) // flat model
+ return;
+ const QAbstractItemModel * const model = static_cast<QAbstractItemModel *>(q->sender());
+ const int oldColCount = model->columnCount();
+ const int newColCount = columnCountAfterChange(model, oldColCount + end - start + 1);
+ Q_ASSERT(newColCount >= oldColCount);
+ if (newColCount > oldColCount)
+ // If the underlying models have a different number of columns (example: 2 and 3), inserting 2 columns in
+ // the first model leads to inserting only one column in the proxy, since qMin(2+2,3) == 3.
+ q->beginInsertColumns(QModelIndex(), start, qMin(end, start + newColCount - oldColCount - 1));
+ m_newColumnCount = newColCount;
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotColumnsInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(start);
+ Q_UNUSED(end);
+ Q_Q(QConcatenateTablesProxyModel);
+ if (parent.isValid()) // flat model
+ return;
+ if (m_newColumnCount != m_columnCount) {
+ m_columnCount = m_newColumnCount;
+ q->endInsertColumns();
+ }
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ if (parent.isValid()) // flat model
+ return;
+ const QAbstractItemModel * const model = static_cast<QAbstractItemModel *>(q->sender());
+ const int oldColCount = model->columnCount();
+ const int newColCount = columnCountAfterChange(model, oldColCount - (end - start + 1));
+ Q_ASSERT(newColCount <= oldColCount);
+ if (newColCount < oldColCount)
+ q->beginRemoveColumns(QModelIndex(), start, qMax(end, start + oldColCount - newColCount - 1));
+ m_newColumnCount = newColCount;
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotColumnsRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ Q_UNUSED(start);
+ Q_UNUSED(end);
+ if (parent.isValid()) // flat model
+ return;
+ if (m_newColumnCount != m_columnCount) {
+ m_columnCount = m_newColumnCount;
+ q->endRemoveColumns();
+ }
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotDataChanged(const QModelIndex &from, const QModelIndex &to, const QVector<int> &roles)
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ Q_ASSERT(from.isValid());
+ Q_ASSERT(to.isValid());
+ const QModelIndex myFrom = q->mapFromSource(from);
+ Q_ASSERT(q->checkIndex(myFrom, QAbstractItemModel::CheckIndexOption::IndexIsValid));
+ const QModelIndex myTo = q->mapFromSource(to);
+ Q_ASSERT(q->checkIndex(myTo, QAbstractItemModel::CheckIndexOption::IndexIsValid));
+ emit q->dataChanged(myFrom, myTo, roles);
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotSourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint)
+{
+ Q_Q(QConcatenateTablesProxyModel);
+
+ if (!sourceParents.isEmpty() && !sourceParents.contains(QModelIndex()))
+ return;
+
+ emit q->layoutAboutToBeChanged({}, hint);
+
+ const QModelIndexList persistentIndexList = q->persistentIndexList();
+ layoutChangePersistentIndexes.reserve(persistentIndexList.size());
+ layoutChangeProxyIndexes.reserve(persistentIndexList.size());
+
+ for (const QPersistentModelIndex &proxyPersistentIndex : persistentIndexList) {
+ layoutChangeProxyIndexes.append(proxyPersistentIndex);
+ Q_ASSERT(proxyPersistentIndex.isValid());
+ const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
+ Q_ASSERT(srcPersistentIndex.isValid());
+ layoutChangePersistentIndexes << srcPersistentIndex;
+ }
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotSourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint)
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ if (!sourceParents.isEmpty() && !sourceParents.contains(QModelIndex()))
+ return;
+ for (int i = 0; i < layoutChangeProxyIndexes.size(); ++i) {
+ const QModelIndex proxyIdx = layoutChangeProxyIndexes.at(i);
+ const QModelIndex newProxyIdx = q->mapFromSource(layoutChangePersistentIndexes.at(i));
+ q->changePersistentIndex(proxyIdx, newProxyIdx);
+ }
+
+ layoutChangePersistentIndexes.clear();
+ layoutChangeProxyIndexes.clear();
+
+ emit q->layoutChanged({}, hint);
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotModelAboutToBeReset()
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ Q_ASSERT(m_models.contains(const_cast<QAbstractItemModel *>(static_cast<const QAbstractItemModel *>(q->sender()))));
+ q->beginResetModel();
+ // A reset might reduce both rowCount and columnCount, and we can't notify of both at the same time,
+ // and notifying of one after the other leaves an intermediary invalid situation.
+ // So the only safe choice is to forward it as a full reset.
+}
+
+void QConcatenateTablesProxyModelPrivate::_q_slotModelReset()
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ Q_ASSERT(m_models.contains(const_cast<QAbstractItemModel *>(static_cast<const QAbstractItemModel *>(q->sender()))));
+ m_columnCount = calculatedColumnCount();
+ m_rowCount = computeRowsPrior(nullptr);
+ q->endResetModel();
+}
+
+int QConcatenateTablesProxyModelPrivate::calculatedColumnCount() const
+{
+ if (m_models.isEmpty())
+ return 0;
+
+ const auto it = std::min_element(m_models.begin(), m_models.end(), [](const QAbstractItemModel* model1, const QAbstractItemModel* model2) {
+ return model1->columnCount() < model2->columnCount();
+ });
+ return (*it)->columnCount();
+}
+
+void QConcatenateTablesProxyModelPrivate::updateColumnCount()
+{
+ Q_Q(QConcatenateTablesProxyModel);
+ const int newColumnCount = calculatedColumnCount();
+ const int columnDiff = newColumnCount - m_columnCount;
+ if (columnDiff > 0) {
+ q->beginInsertColumns(QModelIndex(), m_columnCount, m_columnCount + columnDiff - 1);
+ m_columnCount = newColumnCount;
+ q->endInsertColumns();
+ } else if (columnDiff < 0) {
+ const int lastColumn = m_columnCount - 1;
+ q->beginRemoveColumns(QModelIndex(), lastColumn + columnDiff + 1, lastColumn);
+ m_columnCount = newColumnCount;
+ q->endRemoveColumns();
+ }
+}
+
+int QConcatenateTablesProxyModelPrivate::columnCountAfterChange(const QAbstractItemModel *model, int newCount) const
+{
+ int newColumnCount = 0;
+ for (int i = 0; i < m_models.count(); ++i) {
+ const QAbstractItemModel *mod = m_models.at(i);
+ const int colCount = mod == model ? newCount : mod->columnCount();
+ if (i == 0)
+ newColumnCount = colCount;
+ else
+ newColumnCount = qMin(colCount, newColumnCount);
+ }
+ return newColumnCount;
+}
+
+int QConcatenateTablesProxyModelPrivate::computeRowsPrior(const QAbstractItemModel *sourceModel) const
+{
+ int rowsPrior = 0;
+ for (const QAbstractItemModel *model : m_models) {
+ if (model == sourceModel)
+ break;
+ rowsPrior += model->rowCount();
+ }
+ return rowsPrior;
+}
+
+QConcatenateTablesProxyModelPrivate::SourceModelForRowResult QConcatenateTablesProxyModelPrivate::sourceModelForRow(int row) const
+{
+ QConcatenateTablesProxyModelPrivate::SourceModelForRowResult result;
+ int rowCount = 0;
+ for (QAbstractItemModel *model : m_models) {
+ const int subRowCount = model->rowCount();
+ if (rowCount + subRowCount > row) {
+ result.sourceModel = model;
+ break;
+ }
+ rowCount += subRowCount;
+ }
+ result.sourceRow = row - rowCount;
+ return result;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qconcatenatetablesproxymodel.cpp"
diff --git a/src/corelib/itemmodels/qconcatenatetablesproxymodel.h b/src/corelib/itemmodels/qconcatenatetablesproxymodel.h
new file mode 100644
index 0000000000..85fc6a9c72
--- /dev/null
+++ b/src/corelib/itemmodels/qconcatenatetablesproxymodel.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCONCATENATEROWSPROXYMODEL_H
+#define QCONCATENATEROWSPROXYMODEL_H
+
+#include <QtCore/qabstractitemmodel.h>
+
+QT_BEGIN_NAMESPACE
+
+class QConcatenateTablesProxyModelPrivate;
+
+class Q_CORE_EXPORT QConcatenateTablesProxyModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ explicit QConcatenateTablesProxyModel(QObject *parent = nullptr);
+ ~QConcatenateTablesProxyModel();
+
+ Q_SCRIPTABLE void addSourceModel(QAbstractItemModel *sourceModel);
+ Q_SCRIPTABLE void removeSourceModel(QAbstractItemModel *sourceModel);
+
+ QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
+ QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
+ QMap<int, QVariant> itemData(const QModelIndex &proxyIndex) const override;
+ bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles) override;
+ Qt::ItemFlags flags(const QModelIndex &index) const override;
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
+ QModelIndex parent(const QModelIndex &index) const override;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+ QStringList mimeTypes() const override;
+ QMimeData *mimeData(const QModelIndexList &indexes) const override;
+ bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
+ QSize span(const QModelIndex &index) const override;
+
+private:
+ Q_DECLARE_PRIVATE(QConcatenateTablesProxyModel)
+ Q_DISABLE_COPY(QConcatenateTablesProxyModel)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_slotRowsAboutToBeInserted(const QModelIndex &, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotRowsInserted(const QModelIndex &, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotRowsAboutToBeRemoved(const QModelIndex &, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotRowsRemoved(const QModelIndex &, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotColumnsInserted(const QModelIndex &parent, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotColumnsRemoved(const QModelIndex &parent, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotDataChanged(const QModelIndex &from, const QModelIndex &to, const QVector<int> &roles))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotSourceLayoutAboutToBeChanged(QList<QPersistentModelIndex>, QAbstractItemModel::LayoutChangeHint))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotSourceLayoutChanged(const QList<QPersistentModelIndex> &, QAbstractItemModel::LayoutChangeHint))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotModelAboutToBeReset())
+ Q_PRIVATE_SLOT(d_func(), void _q_slotModelReset())
+};
+
+QT_END_NAMESPACE
+
+#endif // QCONCATENATEROWSPROXYMODEL_H
diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp
index f869601d3f..39992eccd3 100644
--- a/src/corelib/itemmodels/qidentityproxymodel.cpp
+++ b/src/corelib/itemmodels/qidentityproxymodel.cpp
@@ -95,7 +95,7 @@ class QIdentityProxyModelPrivate : public QAbstractProxyModelPrivate
need to implement all data handling in the same class that creates the structure of the model, and can also be used to create
re-usable components.
- This also provides a way to change the data in the case where a source model is supplied by a third party which can not be modified.
+ This also provides a way to change the data in the case where a source model is supplied by a third party which cannot be modified.
\snippet code/src_gui_itemviews_qidentityproxymodel.cpp 0
@@ -480,13 +480,13 @@ void QIdentityProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &topLeft
Q_ASSERT(topLeft.isValid() ? topLeft.model() == model : true);
Q_ASSERT(bottomRight.isValid() ? bottomRight.model() == model : true);
Q_Q(QIdentityProxyModel);
- q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight), roles);
+ emit q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight), roles);
}
void QIdentityProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last)
{
Q_Q(QIdentityProxyModel);
- q->headerDataChanged(orientation, first, last);
+ emit q->headerDataChanged(orientation, first, last);
}
void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint)
@@ -505,7 +505,7 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPe
parents << mappedParent;
}
- q->layoutAboutToBeChanged(parents, hint);
+ emit q->layoutAboutToBeChanged(parents, hint);
const auto proxyPersistentIndexes = q->persistentIndexList();
for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) {
@@ -540,7 +540,7 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersistentM
parents << mappedParent;
}
- q->layoutChanged(parents, hint);
+ emit q->layoutChanged(parents, hint);
}
void QIdentityProxyModelPrivate::_q_sourceModelAboutToBeReset()
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index 87960b0863..d13e6199db 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -424,7 +424,7 @@ public:
void updateChildrenMapping(const QModelIndex &source_parent, Mapping *parent_mapping,
Qt::Orientation orient, int start, int end, int delta_item_count, bool remove);
- virtual void _q_sourceModelDestroyed() override;
+ void _q_sourceModelDestroyed() override;
bool needsReorder(const QVector<int> &source_rows, const QModelIndex &source_parent) const;
diff --git a/src/corelib/itemmodels/qstringlistmodel.cpp b/src/corelib/itemmodels/qstringlistmodel.cpp
index f92a0d6676..a248cdcd38 100644
--- a/src/corelib/itemmodels/qstringlistmodel.cpp
+++ b/src/corelib/itemmodels/qstringlistmodel.cpp
@@ -136,6 +136,42 @@ QModelIndex QStringListModel::sibling(int row, int column, const QModelIndex &id
}
/*!
+ \reimp
+ \since 5.13
+*/
+QMap<int, QVariant> QStringListModel::itemData(const QModelIndex &index) const
+{
+ if (!checkIndex(index, CheckIndexOption::IndexIsValid | CheckIndexOption::ParentIsInvalid))
+ return QMap<int, QVariant>{};
+ const QVariant displayData = lst.at(index.row());
+ return QMap<int, QVariant>{{
+ std::make_pair<int>(Qt::DisplayRole, displayData),
+ std::make_pair<int>(Qt::EditRole, displayData)
+ }};
+}
+
+/*!
+ \reimp
+ \since 5.13
+ If \a roles contains both Qt::DisplayRole and Qt::EditRole, the latter will take precedence
+*/
+bool QStringListModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
+{
+ if (roles.isEmpty())
+ return false;
+ if (std::any_of(roles.keyBegin(), roles.keyEnd(), [](int role) -> bool {
+ return role != Qt::DisplayRole && role != Qt::EditRole;
+ })) {
+ return false;
+ }
+ auto roleIter = roles.constFind(Qt::EditRole);
+ if (roleIter == roles.constEnd())
+ roleIter = roles.constFind(Qt::DisplayRole);
+ Q_ASSERT(roleIter != roles.constEnd());
+ return setData(index, roleIter.value(), roleIter.key());
+}
+
+/*!
Returns data for the specified \a role, from the item with the
given \a index.
@@ -188,18 +224,23 @@ bool QStringListModel::setData(const QModelIndex &index, const QVariant &value,
if (lst.at(index.row()) == valueString)
return true;
lst.replace(index.row(), valueString);
- QVector<int> roles;
- roles.reserve(2);
- roles.append(Qt::DisplayRole);
- roles.append(Qt::EditRole);
- emit dataChanged(index, index, roles);
- // once Q_COMPILER_UNIFORM_INIT can be used, change to:
- // emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
+ emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
return true;
}
return false;
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \reimp
+ \since 6.0
+ */
+bool QStringListModel::clearItemData(const QModelIndex &index)
+{
+ return setData(index, QVariant(), Qt::EditRole);
+}
+#endif
+
/*!
Inserts \a count rows into the model, beginning at the given \a row.
@@ -252,6 +293,38 @@ bool QStringListModel::removeRows(int row, int count, const QModelIndex &parent)
return true;
}
+/*!
+ \since 5.13
+ \reimp
+*/
+bool QStringListModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
+{
+ if (sourceRow < 0
+ || sourceRow + count - 1 >= rowCount(sourceParent)
+ || destinationChild <= 0
+ || destinationChild > rowCount(destinationParent)
+ || sourceRow == destinationChild - 1
+ || count <= 0) {
+ return false;
+ }
+ if (!beginMoveRows(QModelIndex(), sourceRow, sourceRow + count - 1, QModelIndex(), destinationChild))
+ return false;
+ /*
+ QList::move assumes that the second argument is the index where the item will end up to
+ i.e. the valid range for that argument is from 0 to QList::size()-1
+ QAbstractItemModel::moveRows when source and destinations have the same parent assumes that
+ the item will end up being in the row BEFORE the one indicated by destinationChild
+ i.e. the valid range for that argument is from 1 to QList::size()
+ For this reason we remove 1 from destinationChild when using it inside QList
+ */
+ destinationChild--;
+ const int fromRow = destinationChild < sourceRow ? (sourceRow + count - 1) : sourceRow;
+ while (count--)
+ lst.move(fromRow, destinationChild);
+ endMoveRows();
+ return true;
+}
+
static bool ascendingLessThan(const QPair<QString, int> &s1, const QPair<QString, int> &s2)
{
return s1.first < s2.first;
diff --git a/src/corelib/itemmodels/qstringlistmodel.h b/src/corelib/itemmodels/qstringlistmodel.h
index 53376285c6..86725ea80b 100644
--- a/src/corelib/itemmodels/qstringlistmodel.h
+++ b/src/corelib/itemmodels/qstringlistmodel.h
@@ -59,11 +59,18 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ bool clearItemData(const QModelIndex &index) override;
+#endif
Qt::ItemFlags flags(const QModelIndex &index) const override;
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
+ bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
+
+ QMap<int, QVariant> itemData(const QModelIndex &index) const override;
+ bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles) override;
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override;
diff --git a/src/corelib/itemmodels/qtransposeproxymodel.cpp b/src/corelib/itemmodels/qtransposeproxymodel.cpp
new file mode 100644
index 0000000000..d4f379bc64
--- /dev/null
+++ b/src/corelib/itemmodels/qtransposeproxymodel.cpp
@@ -0,0 +1,447 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Luca Beldi <v.ronin@yahoo.it>
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtransposeproxymodel.h"
+#include <private/qtransposeproxymodel_p.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qsize.h>
+
+QT_BEGIN_NAMESPACE
+
+QModelIndex QTransposeProxyModelPrivate::uncheckedMapToSource(const QModelIndex &proxyIndex) const
+{
+ if (!model || !proxyIndex.isValid())
+ return QModelIndex();
+ if (proxyIndex.internalPointer())
+ return model->createIndex(proxyIndex.column(), proxyIndex.row(), proxyIndex.internalPointer());
+ return model->index(proxyIndex.column(), proxyIndex.row());
+}
+
+QModelIndex QTransposeProxyModelPrivate::uncheckedMapFromSource(const QModelIndex &sourceIndex) const
+{
+ if (!model || !sourceIndex.isValid())
+ return QModelIndex();
+ Q_Q(const QTransposeProxyModel);
+ return q->createIndex(sourceIndex.column(), sourceIndex.row(), sourceIndex.internalPointer());
+}
+
+void QTransposeProxyModelPrivate::onLayoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint)
+{
+ Q_Q(QTransposeProxyModel);
+ QModelIndexList toList;
+ toList.reserve(layoutChangePersistentIndexes.size());
+ for (const QPersistentModelIndex &persistIdx : qAsConst(layoutChangePersistentIndexes))
+ toList << q->mapFromSource(persistIdx);
+ q->changePersistentIndexList(layoutChangeProxyIndexes, toList);
+ layoutChangeProxyIndexes.clear();
+ layoutChangePersistentIndexes.clear();
+ QList<QPersistentModelIndex> proxyParents;
+ proxyParents.reserve(parents.size());
+ for (const QPersistentModelIndex &srcParent : parents)
+ proxyParents << q->mapFromSource(srcParent);
+ QAbstractItemModel::LayoutChangeHint proxyHint = QAbstractItemModel::NoLayoutChangeHint;
+ if (hint == QAbstractItemModel::VerticalSortHint)
+ proxyHint = QAbstractItemModel::HorizontalSortHint;
+ else if (hint == QAbstractItemModel::HorizontalSortHint)
+ proxyHint = QAbstractItemModel::VerticalSortHint;
+ emit q->layoutChanged(proxyParents, proxyHint);
+}
+
+void QTransposeProxyModelPrivate::onLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint)
+{
+ Q_Q(QTransposeProxyModel);
+ const QModelIndexList proxyPersistentIndexes = q->persistentIndexList();
+ layoutChangeProxyIndexes.clear();
+ layoutChangePersistentIndexes.clear();
+ layoutChangeProxyIndexes.reserve(proxyPersistentIndexes.size());
+ layoutChangePersistentIndexes.reserve(proxyPersistentIndexes.size());
+ for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) {
+ layoutChangeProxyIndexes << proxyPersistentIndex;
+ Q_ASSERT(proxyPersistentIndex.isValid());
+ const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
+ Q_ASSERT(srcPersistentIndex.isValid());
+ layoutChangePersistentIndexes << srcPersistentIndex;
+ }
+ QList<QPersistentModelIndex> proxyParents;
+ proxyParents.reserve(parents.size());
+ for (auto& srcParent : parents)
+ proxyParents << q->mapFromSource(srcParent);
+ QAbstractItemModel::LayoutChangeHint proxyHint = QAbstractItemModel::NoLayoutChangeHint;
+ if (hint == QAbstractItemModel::VerticalSortHint)
+ proxyHint = QAbstractItemModel::HorizontalSortHint;
+ else if (hint == QAbstractItemModel::HorizontalSortHint)
+ proxyHint = QAbstractItemModel::VerticalSortHint;
+ emit q->layoutAboutToBeChanged(proxyParents, proxyHint);
+}
+
+void QTransposeProxyModelPrivate::onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
+{
+ Q_Q(QTransposeProxyModel);
+ emit q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight), roles);
+}
+
+void QTransposeProxyModelPrivate::onHeaderDataChanged(Qt::Orientation orientation, int first, int last)
+{
+ Q_Q(QTransposeProxyModel);
+ emit q->headerDataChanged(orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal, first, last);
+}
+
+void QTransposeProxyModelPrivate::onColumnsAboutToBeInserted(const QModelIndex &parent, int first, int last)
+{
+ Q_Q(QTransposeProxyModel);
+ q->beginInsertRows(q->mapFromSource(parent), first, last);
+}
+
+void QTransposeProxyModelPrivate::onColumnsAboutToBeRemoved(const QModelIndex &parent, int first, int last)
+{
+ Q_Q(QTransposeProxyModel);
+ q->beginRemoveRows(q->mapFromSource(parent), first, last);
+}
+
+void QTransposeProxyModelPrivate::onColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn)
+{
+ Q_Q(QTransposeProxyModel);
+ q->beginMoveRows(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destinationParent), destinationColumn);
+}
+
+void QTransposeProxyModelPrivate::onRowsAboutToBeInserted(const QModelIndex &parent, int first, int last)
+{
+ Q_Q(QTransposeProxyModel);
+ q->beginInsertColumns(q->mapFromSource(parent), first, last);
+}
+
+void QTransposeProxyModelPrivate::onRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last)
+{
+ Q_Q(QTransposeProxyModel);
+ q->beginRemoveColumns(q->mapFromSource(parent), first, last);
+}
+
+void QTransposeProxyModelPrivate::onRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
+{
+ Q_Q(QTransposeProxyModel);
+ q->beginMoveColumns(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destinationParent), destinationRow);
+}
+
+/*!
+ \since 5.13
+ \class QTransposeProxyModel
+ \brief This proxy transposes the source model.
+
+ This model will make the rows of the source model become columns of the proxy model and vice-versa.
+
+ If the model is a tree, the parents will be transposed as well. For example, if an index in the source model had parent `index(2,0)`, it will have parent `index(0,2)` in the proxy.
+*/
+
+/*!
+ Constructs a new proxy model with the given \a parent.
+*/
+QTransposeProxyModel::QTransposeProxyModel(QObject* parent)
+ : QAbstractProxyModel(*new QTransposeProxyModelPrivate, parent)
+{}
+
+/*!
+ Destructs the proxy model.
+*/
+QTransposeProxyModel::~QTransposeProxyModel() = default;
+
+/*!
+ \internal
+*/
+QTransposeProxyModel::QTransposeProxyModel(QTransposeProxyModelPrivate &dd, QObject *parent)
+ : QAbstractProxyModel(dd, parent)
+{}
+
+/*!
+ \reimp
+*/
+void QTransposeProxyModel::setSourceModel(QAbstractItemModel* newSourceModel)
+{
+ Q_D(QTransposeProxyModel);
+ if (newSourceModel == d->model)
+ return;
+ beginResetModel();
+ if (d->model) {
+ for (const QMetaObject::Connection& discIter : qAsConst(d->sourceConnections))
+ disconnect(discIter);
+ }
+ d->sourceConnections.clear();
+ QAbstractProxyModel::setSourceModel(newSourceModel);
+ if (d->model) {
+ using namespace std::placeholders;
+ d->sourceConnections = QVector<QMetaObject::Connection>{
+ connect(d->model, &QAbstractItemModel::modelAboutToBeReset, this, &QTransposeProxyModel::beginResetModel),
+ connect(d->model, &QAbstractItemModel::modelReset, this, &QTransposeProxyModel::endResetModel),
+ connect(d->model, &QAbstractItemModel::dataChanged, this, std::bind(&QTransposeProxyModelPrivate::onDataChanged, d, _1, _2, _3)),
+ connect(d->model, &QAbstractItemModel::headerDataChanged, this, std::bind(&QTransposeProxyModelPrivate::onHeaderDataChanged, d, _1, _2, _3)),
+ connect(d->model, &QAbstractItemModel::columnsAboutToBeInserted, this, std::bind(&QTransposeProxyModelPrivate::onColumnsAboutToBeInserted, d, _1, _2, _3)),
+ connect(d->model, &QAbstractItemModel::columnsAboutToBeMoved, this, std::bind(&QTransposeProxyModelPrivate::onColumnsAboutToBeMoved, d, _1, _2, _3, _4, _5)),
+ connect(d->model, &QAbstractItemModel::columnsAboutToBeRemoved, this, std::bind(&QTransposeProxyModelPrivate::onColumnsAboutToBeRemoved, d, _1, _2, _3)),
+ connect(d->model, &QAbstractItemModel::columnsInserted, this, &QTransposeProxyModel::endInsertRows),
+ connect(d->model, &QAbstractItemModel::columnsRemoved, this, &QTransposeProxyModel::endRemoveRows),
+ connect(d->model, &QAbstractItemModel::columnsMoved, this, &QTransposeProxyModel::endMoveRows),
+ connect(d->model, &QAbstractItemModel::rowsAboutToBeInserted, this, std::bind(&QTransposeProxyModelPrivate::onRowsAboutToBeInserted, d, _1, _2, _3)),
+ connect(d->model, &QAbstractItemModel::rowsAboutToBeMoved, this, std::bind(&QTransposeProxyModelPrivate::onRowsAboutToBeMoved, d, _1, _2, _3, _4, _5)),
+ connect(d->model, &QAbstractItemModel::rowsAboutToBeRemoved, this, std::bind(&QTransposeProxyModelPrivate::onRowsAboutToBeRemoved, d, _1, _2, _3)),
+ connect(d->model, &QAbstractItemModel::rowsInserted, this, &QTransposeProxyModel::endInsertColumns),
+ connect(d->model, &QAbstractItemModel::rowsRemoved, this, &QTransposeProxyModel::endRemoveColumns),
+ connect(d->model, &QAbstractItemModel::rowsMoved, this, &QTransposeProxyModel::endMoveColumns),
+ connect(d->model, &QAbstractItemModel::layoutAboutToBeChanged, this, std::bind(&QTransposeProxyModelPrivate::onLayoutAboutToBeChanged, d, _1, _2)),
+ connect(d->model, &QAbstractItemModel::layoutChanged, this, std::bind(&QTransposeProxyModelPrivate::onLayoutChanged, d, _1, _2))
+ };
+ }
+ endResetModel();
+}
+
+/*!
+ \reimp
+*/
+int QTransposeProxyModel::rowCount(const QModelIndex &parent) const
+{
+ Q_D(const QTransposeProxyModel);
+ if (!d->model)
+ return 0;
+ Q_ASSERT(checkIndex(parent));
+ return d->model->columnCount(mapToSource(parent));
+}
+
+/*!
+ \reimp
+*/
+int QTransposeProxyModel::columnCount(const QModelIndex &parent) const
+{
+ Q_D(const QTransposeProxyModel);
+ if (!d->model)
+ return 0;
+ Q_ASSERT(checkIndex(parent));
+ return d->model->rowCount(mapToSource(parent));
+}
+
+/*!
+ \reimp
+*/
+QVariant QTransposeProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ Q_D(const QTransposeProxyModel);
+ if (!d->model)
+ return QVariant();
+ return d->model->headerData(section, orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal, role);
+}
+
+/*!
+ \reimp
+*/
+bool QTransposeProxyModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
+{
+ Q_D(QTransposeProxyModel);
+ if (!d->model)
+ return false;
+ return d->model->setHeaderData(section, orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal, value, role);
+}
+
+/*!
+ \reimp
+*/
+bool QTransposeProxyModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
+{
+ Q_D(QTransposeProxyModel);
+ Q_ASSERT(checkIndex(index));
+ if (!d->model || !index.isValid())
+ return false;
+ return d->model->setItemData(mapToSource(index), roles);
+}
+
+/*!
+ \reimp
+*/
+QSize QTransposeProxyModel::span(const QModelIndex &index) const
+{
+ Q_D(const QTransposeProxyModel);
+ Q_ASSERT(checkIndex(index));
+ if (!d->model || !index.isValid())
+ return QSize();
+ return d->model->span(mapToSource(index)).transposed();
+}
+
+/*!
+ \reimp
+*/
+QMap<int, QVariant> QTransposeProxyModel::itemData(const QModelIndex &index) const
+{
+ Q_D(const QTransposeProxyModel);
+ if (!d->model)
+ return QMap<int, QVariant>();
+ Q_ASSERT(checkIndex(index));
+ return d->model->itemData(mapToSource(index));
+}
+
+/*!
+ \reimp
+*/
+QModelIndex QTransposeProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
+{
+ Q_D(const QTransposeProxyModel);
+ if (!d->model || !sourceIndex.isValid())
+ return QModelIndex();
+ Q_ASSERT(d->model->checkIndex(sourceIndex));
+ return d->uncheckedMapFromSource(sourceIndex);
+}
+
+/*!
+ \reimp
+*/
+QModelIndex QTransposeProxyModel::mapToSource(const QModelIndex &proxyIndex) const
+{
+ Q_D(const QTransposeProxyModel);
+ Q_ASSERT(checkIndex(proxyIndex));
+ if (!d->model || !proxyIndex.isValid())
+ return QModelIndex();
+ return d->uncheckedMapToSource(proxyIndex);
+}
+
+/*!
+ \reimp
+*/
+QModelIndex QTransposeProxyModel::parent(const QModelIndex &index) const
+{
+ Q_D(const QTransposeProxyModel);
+ Q_ASSERT(checkIndex(index, CheckIndexOption::DoNotUseParent));
+ if (!d->model || !index.isValid())
+ return QModelIndex();
+ return d->uncheckedMapFromSource(d->uncheckedMapToSource(index).parent());
+}
+
+/*!
+ \reimp
+*/
+QModelIndex QTransposeProxyModel::index(int row, int column, const QModelIndex &parent) const
+{
+ Q_D(const QTransposeProxyModel);
+ Q_ASSERT(checkIndex(parent));
+ if (!d->model)
+ return QModelIndex();
+ return mapFromSource(d->model->index(column, row, mapToSource(parent)));
+}
+
+/*!
+ \reimp
+*/
+bool QTransposeProxyModel::insertRows(int row, int count, const QModelIndex &parent)
+{
+ Q_D(QTransposeProxyModel);
+ Q_ASSERT(checkIndex(parent));
+ if (!d->model)
+ return false;
+ return d->model->insertColumns(row, count, mapToSource(parent));
+}
+
+/*!
+ \reimp
+*/
+bool QTransposeProxyModel::removeRows(int row, int count, const QModelIndex &parent)
+{
+ Q_D(QTransposeProxyModel);
+ Q_ASSERT(checkIndex(parent));
+ if (!d->model)
+ return false;
+ return d->model->removeColumns(row, count, mapToSource(parent));
+}
+
+/*!
+ \reimp
+*/
+bool QTransposeProxyModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
+{
+ Q_D(QTransposeProxyModel);
+ Q_ASSERT(checkIndex(sourceParent));
+ Q_ASSERT(checkIndex(destinationParent));
+ if (!d->model)
+ return false;
+ return d->model->moveColumns(mapToSource(sourceParent), sourceRow, count, mapToSource(destinationParent), destinationChild);
+}
+
+/*!
+ \reimp
+*/
+bool QTransposeProxyModel::insertColumns(int column, int count, const QModelIndex &parent)
+{
+ Q_D(QTransposeProxyModel);
+ Q_ASSERT(checkIndex(parent));
+ if (!d->model)
+ return false;
+ return d->model->insertRows(column, count, mapToSource(parent));
+}
+
+/*!
+ \reimp
+*/
+bool QTransposeProxyModel::removeColumns(int column, int count, const QModelIndex &parent)
+{
+ Q_D(QTransposeProxyModel);
+ Q_ASSERT(checkIndex(parent));
+ if (!d->model)
+ return false;
+ return d->model->removeRows(column, count, mapToSource(parent));
+}
+
+/*!
+ \reimp
+*/
+bool QTransposeProxyModel::moveColumns(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
+{
+ Q_D(QTransposeProxyModel);
+ Q_ASSERT(checkIndex(sourceParent));
+ Q_ASSERT(checkIndex(destinationParent));
+ if (!d->model)
+ return false;
+ return d->model->moveRows(mapToSource(sourceParent), sourceRow, count, mapToSource(destinationParent), destinationChild);
+}
+
+/*!
+ \reimp
+ This method will perform no action. Use a QSortFilterProxyModel on top of this one if you require sorting.
+*/
+void QTransposeProxyModel::sort(int column, Qt::SortOrder order)
+{
+ Q_UNUSED(column)
+ Q_UNUSED(order)
+ return;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/itemmodels/qtransposeproxymodel.h b/src/corelib/itemmodels/qtransposeproxymodel.h
new file mode 100644
index 0000000000..879266d931
--- /dev/null
+++ b/src/corelib/itemmodels/qtransposeproxymodel.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Luca Beldi <v.ronin@yahoo.it>
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTRANSPOSEPROXYMODEL_H
+#define QTRANSPOSEPROXYMODEL_H
+
+#include <QtCore/qabstractproxymodel.h>
+#include <QtCore/qscopedpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTransposeProxyModelPrivate;
+
+class Q_CORE_EXPORT QTransposeProxyModel : public QAbstractProxyModel
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QTransposeProxyModel)
+ Q_DECLARE_PRIVATE(QTransposeProxyModel)
+public:
+ explicit QTransposeProxyModel(QObject* parent = nullptr);
+ ~QTransposeProxyModel();
+ void setSourceModel(QAbstractItemModel* newSourceModel) override;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+ bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override;
+ bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles) override;
+ QSize span(const QModelIndex &index) const override;
+ QMap<int, QVariant> itemData(const QModelIndex &index) const override;
+ QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override;
+ QModelIndex mapToSource(const QModelIndex &proxyIndex) const override;
+ QModelIndex parent(const QModelIndex &index) const override;
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
+ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
+ bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
+ bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
+ bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
+ bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
+ bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationChild) override;
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override;
+protected:
+ QTransposeProxyModel(QTransposeProxyModelPrivate &, QObject *parent);
+};
+
+QT_END_NAMESPACE
+
+#endif // QTRANSPOSEPROXYMODEL_H
diff --git a/src/corelib/itemmodels/qtransposeproxymodel_p.h b/src/corelib/itemmodels/qtransposeproxymodel_p.h
new file mode 100644
index 0000000000..fb5ce5c117
--- /dev/null
+++ b/src/corelib/itemmodels/qtransposeproxymodel_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Luca Beldi <v.ronin@yahoo.it>
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTRANSPOSEPROXYMODEL_P_H
+#define QTRANSPOSEPROXYMODEL_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 "qtransposeproxymodel.h"
+#include <private/qabstractproxymodel_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTransposeProxyModelPrivate : public QAbstractProxyModelPrivate
+{
+ Q_DECLARE_PUBLIC(QTransposeProxyModel)
+ Q_DISABLE_COPY(QTransposeProxyModelPrivate)
+private:
+ QTransposeProxyModelPrivate() = default;
+ QVector<QMetaObject::Connection> sourceConnections;
+ QVector<QPersistentModelIndex> layoutChangePersistentIndexes;
+ QModelIndexList layoutChangeProxyIndexes;
+ QModelIndex uncheckedMapToSource(const QModelIndex &proxyIndex) const;
+ QModelIndex uncheckedMapFromSource(const QModelIndex &sourceIndex) const;
+ void onLayoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint);
+ void onLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint);
+ void onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles);
+ void onHeaderDataChanged(Qt::Orientation orientation, int first, int last);
+ void onColumnsAboutToBeInserted(const QModelIndex &parent, int first, int last);
+ void onColumnsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
+ void onColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn);
+ void onRowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
+ void onRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
+ void onRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow);
+};
+
+QT_END_NAMESPACE
+
+#endif //QTRANSPOSEPROXYMODEL_P_H
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index 4550891e2a..6687eb88a5 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -501,7 +501,7 @@ void qt_apple_check_os_version()
if (!applicationName)
applicationName = NSProcessInfo.processInfo.processName;
- fprintf(stderr, "Sorry, \"%s\" can not be run on this version of %s. "
+ fprintf(stderr, "Sorry, \"%s\" cannot be run on this version of %s. "
"Qt requires %s %ld.%ld.%ld or later, you have %s %ld.%ld.%ld.\n",
applicationName.UTF8String, os,
os, long(required.majorVersion), long(required.minorVersion), long(required.patchVersion),
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 6d7985c91b..2250f91dc3 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -1265,7 +1265,11 @@ bool QCoreApplication::closingDown()
\l{QCoreApplication::sendPostedEvents()}{sendPostedEvents()} from
within that local loop.
- Calling this function processes events only for the calling thread.
+ Calling this function processes events only for the calling thread,
+ and returns after all available events have been processed. Available
+ events are events queued before the function call. This means that
+ events that are posted while the function runs will be queued until
+ a later round of event processing.
\threadsafe
@@ -1282,7 +1286,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
/*!
\overload processEvents()
- Processes pending events for the calling thread for \a maxtime
+ Processes pending events for the calling thread for \a ms
milliseconds or until there are no more events to process,
whichever is shorter.
@@ -1291,11 +1295,14 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
Calling this function processes events only for the calling thread.
+ \note Unlike the \l{QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)}{processEvents()}
+ overload, this function also processes events that are posted while the function runs.
+
\threadsafe
\sa exec(), QTimer, QEventLoop::processEvents()
*/
-void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime)
+void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int ms)
{
// ### Qt 6: consider splitting this method into a public and a private
// one, so that a user-invoked processEvents can be detected
@@ -1306,7 +1313,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m
QElapsedTimer start;
start.start();
while (data->eventDispatcher.load()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
- if (start.elapsed() > maxtime)
+ if (start.elapsed() > ms)
break;
}
}
@@ -1629,14 +1636,15 @@ bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEven
/*!
Immediately dispatches all events which have been previously queued
- with QCoreApplication::postEvent() and which are for the object \a receiver
- and have the event type \a event_type.
+ with QCoreApplication::postEvent() and which are for the object \a
+ receiver and have the event type \a event_type.
Events from the window system are \e not dispatched by this
function, but by processEvents().
- If \a receiver is null, the events of \a event_type are sent for all
- objects. If \a event_type is 0, all the events are sent for \a receiver.
+ If \a receiver is \nullptr, the events of \a event_type are sent for
+ all objects. If \a event_type is 0, all the events are sent for
+ \a receiver.
\note This method must be called from the thread in which its QObject
parameter, \a receiver, lives.
@@ -1817,10 +1825,10 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
call it, be aware that killing events may cause \a receiver to
break one or more invariants.
- If \a receiver is null, the events of \a eventType are removed for
- all objects. If \a eventType is 0, all the events are removed for
- \a receiver. You should never call this function with \a eventType
- of 0.
+ If \a receiver is \nullptr, the events of \a eventType are removed
+ for all objects. If \a eventType is 0, all the events are removed
+ for \a receiver. You should never call this function with \a
+ eventType of 0.
\threadsafe
*/
@@ -2133,7 +2141,7 @@ static void replacePercentN(QString *result, int n)
\a disambiguation is an identifying string, for when the same \a
sourceText is used in different roles within the same context. By
- default, it is null.
+ default, it is \nullptr.
See the \l QTranslator and \l QObject::tr() documentation for
more information about contexts, disambiguations and comments.
diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp
index 45c6e29e4b..34c2dde6a8 100644
--- a/src/corelib/kernel/qeventdispatcher_glib.cpp
+++ b/src/corelib/kernel/qeventdispatcher_glib.cpp
@@ -86,9 +86,10 @@ static gboolean socketNotifierSourceCheck(GSource *source)
p->pollfd.fd, t[int(p->socketNotifier->type())]);
// ### note, modifies src->pollfds!
p->socketNotifier->setEnabled(false);
+ i--;
+ } else {
+ pending = pending || ((p->pollfd.revents & p->pollfd.events) != 0);
}
-
- pending = ((p->pollfd.revents & p->pollfd.events) != 0);
}
return pending;
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index 535f86fefe..df0cac0239 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -225,7 +225,7 @@ int QThreadPipe::check(const pollfd &pfd)
QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
{
if (Q_UNLIKELY(threadPipe.init() == false))
- qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe");
+ qFatal("QEventDispatcherUNIXPrivate(): Cannot continue without a thread pipe");
}
QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate()
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index b3b6b1be20..685d765adb 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -992,8 +992,14 @@ int QEventDispatcherWin32::remainingTime(int timerId)
quint64 currentTime = qt_msectime();
for (const WinTimerInfo *t : qAsConst(d->timerVec)) {
- if (t && t->timerId == timerId) // timer found, return time to wait
- return t->timeout > currentTime ? t->timeout - currentTime : 0;
+ if (t && t->timerId == timerId) {
+ // timer found, return time to wait
+
+ if (d->internalHwnd)
+ return t->timeout > currentTime ? t->timeout - currentTime : 0;
+ else
+ return t->interval;
+ }
}
#ifndef QT_NO_DEBUG
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index 3bb618153b..dbad2a5450 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -80,31 +80,31 @@ public:
explicit QEventDispatcherWin32(QObject *parent = 0);
~QEventDispatcherWin32();
- bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags);
- bool hasPendingEvents();
+ bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags) override;
+ bool hasPendingEvents() override;
- void registerSocketNotifier(QSocketNotifier *notifier);
- void unregisterSocketNotifier(QSocketNotifier *notifier);
+ void registerSocketNotifier(QSocketNotifier *notifier) override;
+ void unregisterSocketNotifier(QSocketNotifier *notifier) override;
- void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object);
- bool unregisterTimer(int timerId);
- bool unregisterTimers(QObject *object);
- QList<TimerInfo> registeredTimers(QObject *object) const;
+ void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) override;
+ bool unregisterTimer(int timerId) override;
+ bool unregisterTimers(QObject *object) override;
+ QList<TimerInfo> registeredTimers(QObject *object) const override;
- bool registerEventNotifier(QWinEventNotifier *notifier);
- void unregisterEventNotifier(QWinEventNotifier *notifier);
+ bool registerEventNotifier(QWinEventNotifier *notifier) override;
+ void unregisterEventNotifier(QWinEventNotifier *notifier) override;
void activateEventNotifiers();
- int remainingTime(int timerId);
+ int remainingTime(int timerId) override;
- void wakeUp();
- void interrupt();
- void flush();
+ void wakeUp() override;
+ void interrupt() override;
+ void flush() override;
- void startingUp();
- void closingDown();
+ void startingUp() override;
+ void closingDown() override;
- bool event(QEvent *e);
+ bool event(QEvent *e) override;
HWND internalHwnd();
diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h
index 52abd51dc1..ec8525e6e1 100644
--- a/src/corelib/kernel/qjni_p.h
+++ b/src/corelib/kernel/qjni_p.h
@@ -76,7 +76,7 @@ public:
private:
friend class QAndroidJniEnvironment;
- Q_DISABLE_COPY(QJNIEnvironmentPrivate)
+ Q_DISABLE_COPY_MOVE(QJNIEnvironmentPrivate)
JNIEnv *jniEnv;
};
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index b8b5c0de46..2ff8b32e0a 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -216,8 +216,8 @@ private:
Constructs a new instance of this class. You can pass up to ten arguments
(\a val0, \a val1, \a val2, \a val3, \a val4, \a val5, \a val6, \a val7,
- \a val8, and \a val9) to the constructor. Returns the new object, or 0 if
- no suitable constructor is available.
+ \a val8, and \a val9) to the constructor. Returns the new object, or
+ \nullptr if no suitable constructor is available.
Note that only constructors that are declared with the Q_INVOKABLE
modifier are made available through the meta-object system.
@@ -321,8 +321,8 @@ const char *QMetaObject::className() const
/*!
\fn QMetaObject *QMetaObject::superClass() const
- Returns the meta-object of the superclass, or 0 if there is no
- such object.
+ Returns the meta-object of the superclass, or \nullptr if there is
+ no such object.
\sa className()
*/
@@ -2257,9 +2257,9 @@ bool QMetaMethod::invoke(QObject *object,
return false;
// check connection type
- QThread *currentThread = QThread::currentThread();
- QThread *objectThread = object->thread();
if (connectionType == Qt::AutoConnection) {
+ QThread *currentThread = QThread::currentThread();
+ QThread *objectThread = object->thread();
connectionType = currentThread == objectThread
? Qt::DirectConnection
: Qt::QueuedConnection;
@@ -2342,6 +2342,8 @@ bool QMetaMethod::invoke(QObject *object,
0, -1, nargs, types, args));
} else { // blocking queued connection
#if QT_CONFIG(thread)
+ QThread *currentThread = QThread::currentThread();
+ QThread *objectThread = object->thread();
if (currentThread == objectThread) {
qWarning("QMetaMethod::invoke: Dead lock detected in "
"BlockingQueuedConnection: Receiver is %s(%p)",
@@ -2613,7 +2615,7 @@ int QMetaEnum::keyCount() const
}
/*!
- Returns the key with the given \a index, or 0 if no such key exists.
+ Returns the key with the given \a index, or \nullptr if no such key exists.
\sa keyCount(), value(), valueToKey()
*/
@@ -2735,7 +2737,7 @@ int QMetaEnum::keyToValue(const char *key, bool *ok) const
/*!
Returns the string that is used as the name of the given
- enumeration \a value, or 0 if \a value is not defined.
+ enumeration \a value, or \nullptr if \a value is not defined.
For flag types, use valueToKeys().
@@ -3520,7 +3522,7 @@ bool QMetaProperty::isStored(const QObject *object) const
false. e.g., the \c text property is the \c USER editable property
of a QLineEdit.
- If \a object is null, the function returns \c false if the \c
+ If \a object is \nullptr, the function returns \c false if the \c
{Q_PROPERTY()}'s \c USER attribute is false. Otherwise it returns
true.
diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h
index 115ec835aa..6100835bad 100644
--- a/src/corelib/kernel/qmetaobjectbuilder_p.h
+++ b/src/corelib/kernel/qmetaobjectbuilder_p.h
@@ -184,7 +184,7 @@ public:
#endif
private:
- Q_DISABLE_COPY(QMetaObjectBuilder)
+ Q_DISABLE_COPY_MOVE(QMetaObjectBuilder)
QMetaObjectBuilderPrivate *d;
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 632b86959d..45d0b5df6c 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -290,6 +290,10 @@ struct DefinedTypesFilter {
\value QJsonObject QJsonObject
\value QJsonArray QJsonArray
\value QJsonDocument QJsonDocument
+ \value QCborValue QCborValue
+ \value QCborArray QCborArray
+ \value QCborMap QCborMap
+ \value QCborSimpleType QCborSimpleType
\value QModelIndex QModelIndex
\value QPersistentModelIndex QPersistentModelIndex (since 5.5)
\value QUuid QUuid
@@ -373,6 +377,13 @@ struct DefinedTypesFilter {
*/
/*!
+ \fn int QMetaType::id() const
+ \since 5.13
+
+ Returns id type hold by this QMetatype instance.
+*/
+
+/*!
\fn bool QMetaType::sizeOf() const
\since 5.0
@@ -410,8 +421,8 @@ struct DefinedTypesFilter {
pointer of this type. (given by QVariant::data for example)
If the type is an enumeration, flags() contains QMetaType::IsEnumeration, and this function
- returns the QMetaObject of the enclosing object if the enum was registered as a Q_ENUM or 0
- otherwise
+ returns the QMetaObject of the enclosing object if the enum was registered as a Q_ENUM or
+ \nullptr otherwise
\sa QMetaType::metaObjectForType(), QMetaType::flags()
*/
@@ -421,7 +432,7 @@ struct DefinedTypesFilter {
\since 5.0
Returns a copy of \a copy, assuming it is of the type that this
- QMetaType instance was created for. If \a copy is null, creates
+ QMetaType instance was created for. If \a copy is \nullptr, creates
a default constructed instance.
\sa QMetaType::destroy()
@@ -1374,236 +1385,197 @@ int QMetaType::type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName)
}
#ifndef QT_NO_DATASTREAM
-/*!
- Writes the object pointed to by \a data with the ID \a type to
- the given \a stream. Returns \c true if the object is saved
- successfully; otherwise returns \c false.
- The type must have been registered with qRegisterMetaType() and
- qRegisterMetaTypeStreamOperators() beforehand.
+namespace
+{
- Normally, you should not need to call this function directly.
- Instead, use QVariant's \c operator<<(), which relies on save()
- to stream custom types.
+template<typename T>
+class HasStreamOperator
+{
+ struct Yes { char unused[1]; };
+ struct No { char unused[2]; };
+ Q_STATIC_ASSERT(sizeof(Yes) != sizeof(No));
+
+ template<class C> static decltype(std::declval<QDataStream&>().operator>>(std::declval<C&>()), Yes()) load(int);
+ template<class C> static decltype(operator>>(std::declval<QDataStream&>(), std::declval<C&>()), Yes()) load(int);
+ template<class C> static No load(...);
+ template<class C> static decltype(operator<<(std::declval<QDataStream&>(), std::declval<const C&>()), Yes()) saveFunction(int);
+ template<class C> static decltype(std::declval<QDataStream&>().operator<<(std::declval<const C&>()), Yes()) saveMethod(int);
+ template<class C> static No saveMethod(...);
+ template<class C> static No saveFunction(...);
+ static constexpr bool LoadValue = QtMetaTypePrivate::TypeDefinition<T>::IsAvailable && (sizeof(load<T>(0)) == sizeof(Yes));
+ static constexpr bool SaveValue = QtMetaTypePrivate::TypeDefinition<T>::IsAvailable &&
+ ((sizeof(saveMethod<T>(0)) == sizeof(Yes)) || (sizeof(saveFunction<T>(0)) == sizeof(Yes)));
+public:
+ static constexpr bool Value = LoadValue && SaveValue;
+};
- \sa load(), qRegisterMetaTypeStreamOperators()
-*/
-bool QMetaType::save(QDataStream &stream, int type, const void *data)
+// Quick sanity checks
+Q_STATIC_ASSERT(HasStreamOperator<NS(QJsonDocument)>::Value);
+Q_STATIC_ASSERT(!HasStreamOperator<void*>::Value);
+Q_STATIC_ASSERT(HasStreamOperator<qint8>::Value);
+
+template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted && HasStreamOperator<T>::Value>
+struct FilteredOperatorSwitch
+{
+ static bool load(QDataStream &stream, T *data, int)
+ {
+ stream >> *data;
+ return true;
+ }
+ static bool save(QDataStream &stream, const T *data, int)
+ {
+ stream << *data;
+ return true;
+ }
+};
+template<typename T>
+struct FilteredOperatorSwitch<T, /* IsAcceptedType = */ false>
{
- if (!data || !isRegistered(type))
+ static const QMetaTypeInterface* getMetaTypeInterface(int type)
+ {
+ if (QModulesPrivate::QTypeModuleInfo<T>::IsGui && qMetaTypeGuiHelper)
+ return &qMetaTypeGuiHelper[type - QMetaType::FirstGuiType];
+ else if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget && qMetaTypeWidgetsHelper)
+ return &qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType];
+ return nullptr;
+ }
+ static bool save(QDataStream &stream, const T *data, int type)
+ {
+ if (auto interface = getMetaTypeInterface(type)) {
+ interface->saveOp(stream, data);
+ return true;
+ }
return false;
-
- switch(type) {
- case QMetaType::UnknownType:
- case QMetaType::Void:
- case QMetaType::VoidStar:
- case QMetaType::QObjectStar:
-#if QT_CONFIG(itemmodel)
- case QMetaType::QModelIndex:
- case QMetaType::QPersistentModelIndex:
-#endif
- case QMetaType::QJsonValue:
- case QMetaType::QJsonObject:
- case QMetaType::QJsonArray:
- case QMetaType::QJsonDocument:
- case QMetaType::QCborValue:
- case QMetaType::QCborArray:
- case QMetaType::QCborMap:
+ }
+ static bool load(QDataStream &stream, T *data, int type)
+ {
+ if (auto interface = getMetaTypeInterface(type)) {
+ interface->loadOp(stream, data);
+ return true;
+ }
return false;
- case QMetaType::Nullptr:
- stream << *static_cast<const std::nullptr_t *>(data);
- return true;
- case QMetaType::Long:
- stream << qlonglong(*static_cast<const long *>(data));
- break;
- case QMetaType::Int:
- stream << *static_cast<const int *>(data);
- break;
- case QMetaType::Short:
- stream << *static_cast<const short *>(data);
- break;
- case QMetaType::Char:
+ }
+};
+
+class SaveOperatorSwitch
+{
+public:
+ QDataStream &stream;
+ int m_type;
+
+ template<typename T>
+ bool delegate(const T *data)
+ {
+ return FilteredOperatorSwitch<T>::save(stream, data, m_type);
+ }
+ bool delegate(const char *data)
+ {
// force a char to be signed
- stream << *static_cast<const signed char *>(data);
- break;
- case QMetaType::ULong:
- stream << qulonglong(*static_cast<const ulong *>(data));
- break;
- case QMetaType::UInt:
- stream << *static_cast<const uint *>(data);
- break;
- case QMetaType::LongLong:
- stream << *static_cast<const qlonglong *>(data);
- break;
- case QMetaType::ULongLong:
- stream << *static_cast<const qulonglong *>(data);
- break;
- case QMetaType::UShort:
- stream << *static_cast<const ushort *>(data);
- break;
- case QMetaType::SChar:
- stream << *static_cast<const signed char *>(data);
- break;
- case QMetaType::UChar:
- stream << *static_cast<const uchar *>(data);
- break;
- case QMetaType::Bool:
- stream << qint8(*static_cast<const bool *>(data));
- break;
- case QMetaType::Float:
- stream << *static_cast<const float *>(data);
- break;
- case QMetaType::Double:
- stream << *static_cast<const double *>(data);
- break;
- case QMetaType::QChar:
- stream << *static_cast<const NS(QChar) *>(data);
- break;
-#ifndef QT_BOOTSTRAPPED
- case QMetaType::QVariantMap:
- stream << *static_cast<const NS(QVariantMap)*>(data);
- break;
- case QMetaType::QVariantHash:
- stream << *static_cast<const NS(QVariantHash)*>(data);
- break;
- case QMetaType::QVariantList:
- stream << *static_cast<const NS(QVariantList)*>(data);
- break;
- case QMetaType::QVariant:
- stream << *static_cast<const NS(QVariant)*>(data);
- break;
- case QMetaType::QByteArrayList:
- stream << *static_cast<const NS(QByteArrayList)*>(data);
- break;
-#endif
- case QMetaType::QByteArray:
- stream << *static_cast<const NS(QByteArray)*>(data);
- break;
- case QMetaType::QString:
- stream << *static_cast<const NS(QString)*>(data);
- break;
- case QMetaType::QStringList:
- stream << *static_cast<const NS(QStringList)*>(data);
- break;
-#ifndef QT_BOOTSTRAPPED
- case QMetaType::QBitArray:
- stream << *static_cast<const NS(QBitArray)*>(data);
- break;
-#endif
- case QMetaType::QDate:
- stream << *static_cast<const NS(QDate)*>(data);
- break;
- case QMetaType::QTime:
- stream << *static_cast<const NS(QTime)*>(data);
- break;
- case QMetaType::QDateTime:
- stream << *static_cast<const NS(QDateTime)*>(data);
- break;
-#ifndef QT_BOOTSTRAPPED
- case QMetaType::QUrl:
- stream << *static_cast<const NS(QUrl)*>(data);
- break;
-#endif
- case QMetaType::QLocale:
- stream << *static_cast<const NS(QLocale)*>(data);
- break;
-#ifndef QT_NO_GEOM_VARIANT
- case QMetaType::QRect:
- stream << *static_cast<const NS(QRect)*>(data);
- break;
- case QMetaType::QRectF:
- stream << *static_cast<const NS(QRectF)*>(data);
- break;
- case QMetaType::QSize:
- stream << *static_cast<const NS(QSize)*>(data);
- break;
- case QMetaType::QSizeF:
- stream << *static_cast<const NS(QSizeF)*>(data);
- break;
- case QMetaType::QLine:
- stream << *static_cast<const NS(QLine)*>(data);
- break;
- case QMetaType::QLineF:
- stream << *static_cast<const NS(QLineF)*>(data);
- break;
- case QMetaType::QPoint:
- stream << *static_cast<const NS(QPoint)*>(data);
- break;
- case QMetaType::QPointF:
- stream << *static_cast<const NS(QPointF)*>(data);
- break;
-#endif
-#ifndef QT_NO_REGEXP
- case QMetaType::QRegExp:
- stream << *static_cast<const NS(QRegExp)*>(data);
- break;
-#endif
-#if QT_CONFIG(regularexpression)
- case QMetaType::QRegularExpression:
- stream << *static_cast<const NS(QRegularExpression)*>(data);
- break;
-#endif // QT_CONFIG(regularexpression)
-#ifndef QT_BOOTSTRAPPED
- case QMetaType::QEasingCurve:
- stream << *static_cast<const NS(QEasingCurve)*>(data);
- break;
- case QMetaType::QCborSimpleType:
- stream << *static_cast<const quint8 *>(data);
- break;
-#endif // QT_BOOTSTRAPPED
- case QMetaType::QFont:
- case QMetaType::QPixmap:
- case QMetaType::QBrush:
- case QMetaType::QColor:
- case QMetaType::QPalette:
- case QMetaType::QImage:
- case QMetaType::QPolygon:
- case QMetaType::QPolygonF:
- case QMetaType::QRegion:
- case QMetaType::QBitmap:
- case QMetaType::QCursor:
- case QMetaType::QKeySequence:
- case QMetaType::QPen:
- case QMetaType::QTextLength:
- case QMetaType::QTextFormat:
- case QMetaType::QMatrix:
- case QMetaType::QTransform:
- case QMetaType::QMatrix4x4:
- case QMetaType::QVector2D:
- case QMetaType::QVector3D:
- case QMetaType::QVector4D:
- case QMetaType::QQuaternion:
- case QMetaType::QIcon:
- if (!qMetaTypeGuiHelper)
- return false;
- qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data);
- break;
- case QMetaType::QSizePolicy:
- if (!qMetaTypeWidgetsHelper)
- return false;
- qMetaTypeWidgetsHelper[type - FirstWidgetsType].saveOp(stream, data);
- break;
- case QMetaType::QUuid:
- stream << *static_cast<const NS(QUuid)*>(data);
- break;
- default: {
+ stream << qint8(*data);
+ return true;
+ }
+ bool delegate(const long *data)
+ {
+ stream << qlonglong(*data);
+ return true;
+ }
+ bool delegate(const unsigned long *data)
+ {
+ stream << qulonglong(*data);
+ return true;
+ }
+ bool delegate(const QMetaTypeSwitcher::NotBuiltinType *data)
+ {
const QVector<QCustomTypeInfo> * const ct = customTypes();
if (!ct)
return false;
-
- SaveOperator saveOp = 0;
+ QMetaType::SaveOperator saveOp = nullptr;
{
QReadLocker locker(customTypesLock());
- saveOp = ct->at(type - User).saveOp;
+ saveOp = ct->at(m_type - QMetaType::User).saveOp;
}
-
if (!saveOp)
return false;
saveOp(stream, data);
- break; }
+ return true;
}
+ bool delegate(const void*) { return false; }
+ bool delegate(const QMetaTypeSwitcher::UnknownType*) { return false; }
+};
+class LoadOperatorSwitch
+{
+public:
+ QDataStream &stream;
+ int m_type;
- return true;
+ template<typename T>
+ bool delegate(const T *data)
+ {
+ return FilteredOperatorSwitch<T>::load(stream, const_cast<T*>(data), m_type);
+ }
+ bool delegate(const char *data)
+ {
+ // force a char to be signed
+ qint8 c;
+ stream >> c;
+ *const_cast<char*>(data) = c;
+ return true;
+ }
+ bool delegate(const long *data)
+ {
+ qlonglong l;
+ stream >> l;
+ *const_cast<long*>(data) = l;
+ return true;
+ }
+ bool delegate(const unsigned long *data)
+ {
+ qlonglong l;
+ stream >> l;
+ *const_cast<unsigned long*>(data) = l;
+ return true;
+ }
+ bool delegate(const QMetaTypeSwitcher::NotBuiltinType *data)
+ {
+ const QVector<QCustomTypeInfo> * const ct = customTypes();
+ if (!ct)
+ return false;
+ QMetaType::LoadOperator loadOp = nullptr;
+ {
+ QReadLocker locker(customTypesLock());
+ loadOp = ct->at(m_type - QMetaType::User).loadOp;
+ }
+ if (!loadOp)
+ return false;
+ loadOp(stream, const_cast<QMetaTypeSwitcher::NotBuiltinType*>(data));
+ return true;
+ }
+ bool delegate(const void*) { return false; }
+ bool delegate(const QMetaTypeSwitcher::UnknownType*) { return false; }
+};
+} // namespace
+
+/*!
+ Writes the object pointed to by \a data with the ID \a type to
+ the given \a stream. Returns \c true if the object is saved
+ successfully; otherwise returns \c false.
+
+ The type must have been registered with qRegisterMetaType() and
+ qRegisterMetaTypeStreamOperators() beforehand.
+
+ Normally, you should not need to call this function directly.
+ Instead, use QVariant's \c operator<<(), which relies on save()
+ to stream custom types.
+
+ \sa load(), qRegisterMetaTypeStreamOperators()
+*/
+bool QMetaType::save(QDataStream &stream, int type, const void *data)
+{
+ if (!data)
+ return false;
+ SaveOperatorSwitch saveOp{stream, type};
+ return QMetaTypeSwitcher::switcher<bool>(saveOp, type, data);
}
/*!
@@ -1622,225 +1594,10 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
*/
bool QMetaType::load(QDataStream &stream, int type, void *data)
{
- if (!data || !isRegistered(type))
- return false;
-
- switch(type) {
- case QMetaType::UnknownType:
- case QMetaType::Void:
- case QMetaType::VoidStar:
- case QMetaType::QObjectStar:
-#if QT_CONFIG(itemmodel)
- case QMetaType::QModelIndex:
- case QMetaType::QPersistentModelIndex:
-#endif
- case QMetaType::QJsonValue:
- case QMetaType::QJsonObject:
- case QMetaType::QJsonArray:
- case QMetaType::QJsonDocument:
- case QMetaType::QCborValue:
- case QMetaType::QCborArray:
- case QMetaType::QCborMap:
+ if (!data)
return false;
- case QMetaType::Nullptr:
- stream >> *static_cast<std::nullptr_t *>(data);
- return true;
- case QMetaType::Long: {
- qlonglong l;
- stream >> l;
- *static_cast<long *>(data) = long(l);
- break; }
- case QMetaType::Int:
- stream >> *static_cast<int *>(data);
- break;
- case QMetaType::Short:
- stream >> *static_cast<short *>(data);
- break;
- case QMetaType::Char:
- // force a char to be signed
- stream >> *static_cast<signed char *>(data);
- break;
- case QMetaType::ULong: {
- qulonglong ul;
- stream >> ul;
- *static_cast<ulong *>(data) = ulong(ul);
- break; }
- case QMetaType::UInt:
- stream >> *static_cast<uint *>(data);
- break;
- case QMetaType::LongLong:
- stream >> *static_cast<qlonglong *>(data);
- break;
- case QMetaType::ULongLong:
- stream >> *static_cast<qulonglong *>(data);
- break;
- case QMetaType::UShort:
- stream >> *static_cast<ushort *>(data);
- break;
- case QMetaType::SChar:
- stream >> *static_cast<signed char *>(data);
- break;
- case QMetaType::UChar:
- stream >> *static_cast<uchar *>(data);
- break;
- case QMetaType::Bool: {
- qint8 b;
- stream >> b;
- *static_cast<bool *>(data) = b;
- break; }
- case QMetaType::Float:
- stream >> *static_cast<float *>(data);
- break;
- case QMetaType::Double:
- stream >> *static_cast<double *>(data);
- break;
- case QMetaType::QChar:
- stream >> *static_cast< NS(QChar)*>(data);
- break;
-#ifndef QT_BOOTSTRAPPED
- case QMetaType::QVariantMap:
- stream >> *static_cast< NS(QVariantMap)*>(data);
- break;
- case QMetaType::QVariantHash:
- stream >> *static_cast< NS(QVariantHash)*>(data);
- break;
- case QMetaType::QVariantList:
- stream >> *static_cast< NS(QVariantList)*>(data);
- break;
- case QMetaType::QVariant:
- stream >> *static_cast< NS(QVariant)*>(data);
- break;
- case QMetaType::QByteArrayList:
- stream >> *static_cast< NS(QByteArrayList)*>(data);
- break;
-#endif
- case QMetaType::QByteArray:
- stream >> *static_cast< NS(QByteArray)*>(data);
- break;
- case QMetaType::QString:
- stream >> *static_cast< NS(QString)*>(data);
- break;
- case QMetaType::QStringList:
- stream >> *static_cast< NS(QStringList)*>(data);
- break;
-#ifndef QT_BOOTSTRAPPED
- case QMetaType::QBitArray:
- stream >> *static_cast< NS(QBitArray)*>(data);
- break;
-#endif
- case QMetaType::QDate:
- stream >> *static_cast< NS(QDate)*>(data);
- break;
- case QMetaType::QTime:
- stream >> *static_cast< NS(QTime)*>(data);
- break;
- case QMetaType::QDateTime:
- stream >> *static_cast< NS(QDateTime)*>(data);
- break;
-#ifndef QT_BOOTSTRAPPED
- case QMetaType::QUrl:
- stream >> *static_cast< NS(QUrl)*>(data);
- break;
-#endif
- case QMetaType::QLocale:
- stream >> *static_cast< NS(QLocale)*>(data);
- break;
-#ifndef QT_NO_GEOM_VARIANT
- case QMetaType::QRect:
- stream >> *static_cast< NS(QRect)*>(data);
- break;
- case QMetaType::QRectF:
- stream >> *static_cast< NS(QRectF)*>(data);
- break;
- case QMetaType::QSize:
- stream >> *static_cast< NS(QSize)*>(data);
- break;
- case QMetaType::QSizeF:
- stream >> *static_cast< NS(QSizeF)*>(data);
- break;
- case QMetaType::QLine:
- stream >> *static_cast< NS(QLine)*>(data);
- break;
- case QMetaType::QLineF:
- stream >> *static_cast< NS(QLineF)*>(data);
- break;
- case QMetaType::QPoint:
- stream >> *static_cast< NS(QPoint)*>(data);
- break;
- case QMetaType::QPointF:
- stream >> *static_cast< NS(QPointF)*>(data);
- break;
-#endif
-#ifndef QT_NO_REGEXP
- case QMetaType::QRegExp:
- stream >> *static_cast< NS(QRegExp)*>(data);
- break;
-#endif
-#if QT_CONFIG(regularexpression)
- case QMetaType::QRegularExpression:
- stream >> *static_cast< NS(QRegularExpression)*>(data);
- break;
-#endif // QT_CONFIG(regularexpression)
-#ifndef QT_BOOTSTRAPPED
- case QMetaType::QEasingCurve:
- stream >> *static_cast< NS(QEasingCurve)*>(data);
- break;
- case QMetaType::QCborSimpleType:
- stream >> *static_cast<quint8 *>(data);
- break;
-#endif // QT_BOOTSTRAPPED
- case QMetaType::QFont:
- case QMetaType::QPixmap:
- case QMetaType::QBrush:
- case QMetaType::QColor:
- case QMetaType::QPalette:
- case QMetaType::QImage:
- case QMetaType::QPolygon:
- case QMetaType::QPolygonF:
- case QMetaType::QRegion:
- case QMetaType::QBitmap:
- case QMetaType::QCursor:
- case QMetaType::QKeySequence:
- case QMetaType::QPen:
- case QMetaType::QTextLength:
- case QMetaType::QTextFormat:
- case QMetaType::QMatrix:
- case QMetaType::QTransform:
- case QMetaType::QMatrix4x4:
- case QMetaType::QVector2D:
- case QMetaType::QVector3D:
- case QMetaType::QVector4D:
- case QMetaType::QQuaternion:
- case QMetaType::QIcon:
- if (!qMetaTypeGuiHelper)
- return false;
- qMetaTypeGuiHelper[type - FirstGuiType].loadOp(stream, data);
- break;
- case QMetaType::QSizePolicy:
- if (!qMetaTypeWidgetsHelper)
- return false;
- qMetaTypeWidgetsHelper[type - FirstWidgetsType].loadOp(stream, data);
- break;
- case QMetaType::QUuid:
- stream >> *static_cast< NS(QUuid)*>(data);
- break;
- default: {
- const QVector<QCustomTypeInfo> * const ct = customTypes();
- if (!ct)
- return false;
-
- LoadOperator loadOp = 0;
- {
- QReadLocker locker(customTypesLock());
- loadOp = ct->at(type - User).loadOp;
- }
-
- if (!loadOp)
- return false;
- loadOp(stream, data);
- break; }
- }
- return true;
+ LoadOperatorSwitch loadOp{stream, type};
+ return QMetaTypeSwitcher::switcher<bool>(loadOp, type, data);
}
#endif // QT_NO_DATASTREAM
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index ed7feee775..a47fbfe28d 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -570,6 +570,7 @@ public:
inline bool isValid() const;
inline bool isRegistered() const;
+ inline int id() const;
inline int sizeOf() const;
inline TypeFlags flags() const;
inline const QMetaObject *metaObject() const;
@@ -1976,7 +1977,9 @@ QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
typedef QList<QVariant> QVariantList;
typedef QMap<QString, QVariant> QVariantMap;
typedef QHash<QString, QVariant> QVariantHash;
-#ifndef Q_CLANG_QDOC
+#ifdef Q_CLANG_QDOC
+class QByteArrayList;
+#else
typedef QList<QByteArray> QByteArrayList;
#endif
@@ -2221,6 +2224,11 @@ inline bool QMetaType::isRegistered() const
return isValid();
}
+inline int QMetaType::id() const
+{
+ return m_typeId;
+}
+
inline void *QMetaType::create(const void *copy) const
{
// ### TODO Qt6 remove the extension
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index c8ad1bc43f..9a98db21d3 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE
static inline QString textUriListLiteral() { return QStringLiteral("text/uri-list"); }
static inline QString textHtmlLiteral() { return QStringLiteral("text/html"); }
static inline QString textPlainLiteral() { return QStringLiteral("text/plain"); }
+static inline QString textPlainUtf8Literal() { return QStringLiteral("text/plain;charset=utf-8"); }
static inline QString applicationXColorLiteral() { return QStringLiteral("application/x-color"); }
static inline QString applicationXQtImageLiteral() { return QStringLiteral("application/x-qt-image"); }
@@ -399,6 +400,10 @@ bool QMimeData::hasUrls() const
QString QMimeData::text() const
{
Q_D(const QMimeData);
+ QVariant utf8Text = d->retrieveTypedData(textPlainUtf8Literal(), QVariant::String);
+ if (!utf8Text.isNull())
+ return utf8Text.toString();
+
QVariant data = d->retrieveTypedData(textPlainLiteral(), QVariant::String);
return data.toString();
}
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index a791d2e8b3..d03b9fafb1 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -1763,7 +1763,7 @@ void QObject::killTimer(int id)
\fn template<typename T> T *QObject::findChild(const QString &name, Qt::FindChildOptions options) const
Returns the child of this object that can be cast into type T and
- that is called \a name, or 0 if there is no such object.
+ that is called \a name, or \nullptr if there is no such object.
Omitting the \a name argument causes all object names to be matched.
The search is performed recursively, unless \a options specifies the
option FindDirectChildrenOnly.
@@ -1824,12 +1824,15 @@ void QObject::killTimer(int id)
/*!
\fn template<typename T> QList<T> QObject::findChildren(const QRegExp &regExp, Qt::FindChildOptions options) const
\overload findChildren()
+ \obsolete
Returns the children of this object that can be cast to type T
and that have names matching the regular expression \a regExp,
or an empty list if there are no such objects.
The search is performed recursively, unless \a options specifies the
option FindDirectChildrenOnly.
+
+ Use the findChildren overload taking a QRegularExpression instead.
*/
/*!
@@ -2148,7 +2151,8 @@ void QObject::removeEventFilter(QObject *obj)
\fn void QObject::destroyed(QObject *obj)
This signal is emitted immediately before the object \a obj is
- destroyed, and can not be blocked.
+ destroyed, after any instances of QPointer have been notified,
+ and cannot be blocked.
All the objects's children are destroyed immediately after this
signal is emitted.
@@ -2930,8 +2934,8 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
0 may be used as a wildcard, meaning "any signal", "any receiving
object", or "any slot in the receiving object", respectively.
- The \a sender may never be 0. (You cannot disconnect signals from
- more than one object in a single call.)
+ The \a sender may never be \nullptr. (You cannot disconnect signals
+ from more than one object in a single call.)
If \a signal is 0, it disconnects \a receiver and \a method from
any signal. If not, only the specified signal is disconnected.
@@ -2942,8 +2946,8 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
If \a method is 0, it disconnects anything that is connected to \a
receiver. If not, only slots named \a method will be disconnected,
- and all other slots are left alone. The \a method must be 0 if \a
- receiver is left out, so you cannot disconnect a
+ and all other slots are left alone. The \a method must be \nullptr
+ if \a receiver is left out, so you cannot disconnect a
specifically-named slot on all objects.
\sa connect()
@@ -3282,7 +3286,7 @@ QMetaObject::Connection QMetaObject::connect(const QObject *sender, int signal_i
\internal
Same as the QMetaObject::connect, but \a signal_index must be the result of QObjectPrivate::signalIndex
- method_index is relative to the rmeta metaobject, if rmeta is null, then it is absolute index
+ method_index is relative to the rmeta metaobject, if rmeta is \nullptr, then it is absolute index
the QObjectPrivate::Connection* has a refcount of 2, so it must be passed to a QMetaObject::Connection
*/
@@ -3675,10 +3679,12 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
return;
}
- void *empty_argv[] = { 0 };
+ void *empty_argv[] = { nullptr };
+ if (!argv)
+ argv = empty_argv;
+
if (qt_signal_spy_callback_set.signal_begin_callback != 0) {
- qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index,
- argv ? argv : empty_argv);
+ qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index, argv);
}
Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index);
@@ -3741,7 +3747,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
// put into the event queue
if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread)
|| (c->connectionType == Qt::QueuedConnection)) {
- queued_activate(sender, signal_index, c, argv ? argv : empty_argv, locker);
+ queued_activate(sender, signal_index, c, argv, locker);
continue;
#if QT_CONFIG(thread)
} else if (c->connectionType == Qt::BlockingQueuedConnection) {
@@ -3753,8 +3759,8 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
}
QSemaphore semaphore;
QMetaCallEvent *ev = c->isSlotObject ?
- new QMetaCallEvent(c->slotObj, sender, signal_index, 0, 0, argv ? argv : empty_argv, &semaphore) :
- new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_index, 0, 0, argv ? argv : empty_argv, &semaphore);
+ new QMetaCallEvent(c->slotObj, sender, signal_index, 0, 0, argv, &semaphore) :
+ new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_index, 0, 0, argv, &semaphore);
QCoreApplication::postEvent(receiver, ev);
locker.unlock();
semaphore.acquire();
@@ -3773,7 +3779,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj);
locker.unlock();
Q_TRACE(QMetaObject_activate_begin_slot_functor, obj.data());
- obj->call(receiver, argv ? argv : empty_argv);
+ obj->call(receiver, argv);
Q_TRACE(QMetaObject_activate_end_slot_functor, obj.data());
// Make sure the slot object gets destroyed before the mutex is locked again, as the
@@ -3789,10 +3795,10 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
const auto callFunction = c->callFunction;
locker.unlock();
if (qt_signal_spy_callback_set.slot_begin_callback != 0)
- qt_signal_spy_callback_set.slot_begin_callback(receiver, methodIndex, argv ? argv : empty_argv);
+ qt_signal_spy_callback_set.slot_begin_callback(receiver, methodIndex, argv);
Q_TRACE(QMetaObject_activate_begin_slot, receiver, methodIndex);
- callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv);
+ callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv);
Q_TRACE(QMetaObject_activate_end_slot, receiver, methodIndex);
if (qt_signal_spy_callback_set.slot_end_callback != 0)
@@ -3803,13 +3809,11 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
locker.unlock();
if (qt_signal_spy_callback_set.slot_begin_callback != 0) {
- qt_signal_spy_callback_set.slot_begin_callback(receiver,
- method,
- argv ? argv : empty_argv);
+ qt_signal_spy_callback_set.slot_begin_callback(receiver, method, argv);
}
Q_TRACE(QMetaObject_activate_begin_slot, receiver, method);
- metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
+ metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv);
Q_TRACE(QMetaObject_activate_end_slot, receiver, method);
if (qt_signal_spy_callback_set.slot_end_callback != 0)
@@ -3854,7 +3858,7 @@ void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
It is different from QMetaObject::indexOfSignal(): indexOfSignal is the same as indexOfMethod
while QObjectPrivate::signalIndex is smaller because it doesn't give index to slots.
- If \a meta is not 0, it is set to the meta-object where the signal was found.
+ If \a meta is not \nullptr, it is set to the meta-object where the signal was found.
*/
int QObjectPrivate::signalIndex(const char *signalName,
const QMetaObject **meta) const
@@ -4987,8 +4991,8 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
0 may be used as a wildcard, meaning "any signal", "any receiving
object", or "any slot in the receiving object", respectively.
- The \a sender may never be 0. (You cannot disconnect signals from
- more than one object in a single call.)
+ The \a sender may never be \nullptr. (You cannot disconnect signals
+ from more than one object in a single call.)
If \a signal is 0, it disconnects \a receiver and \a method from
any signal. If not, only the specified signal is disconnected.
@@ -4999,8 +5003,8 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
If \a method is 0, it disconnects anything that is connected to \a
receiver. If not, only slots named \a method will be disconnected,
- and all other slots are left alone. The \a method must be 0 if \a
- receiver is left out, so you cannot disconnect a
+ and all other slots are left alone. The \a method must be \nullptr
+ if \a receiver is left out, so you cannot disconnect a
specifically-named slot on all objects.
\note It is not possible to use this overload to diconnect signals
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index aac9bcdee9..63c5a9ad73 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -176,7 +176,9 @@ public:
}
#ifndef QT_NO_REGEXP
+#if QT_DEPRECATED_SINCE(5, 13)
template<typename T>
+ QT_DEPRECATED_X("Use findChildren(const QRegularExpression &, ...) instead.")
inline QList<T> findChildren(const QRegExp &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
@@ -186,6 +188,7 @@ public:
return list;
}
#endif
+#endif
#if QT_CONFIG(regularexpression)
template<typename T>
@@ -517,7 +520,10 @@ inline T qobject_cast(const QObject *object)
template <class T> inline const char * qobject_interface_iid()
{ return nullptr; }
-#if !defined(Q_MOC_RUN) && !defined(Q_CLANG_QDOC)
+
+#if defined(Q_CLANG_QDOC)
+# define Q_DECLARE_INTERFACE(IFace, IId)
+#elif !defined(Q_MOC_RUN)
# define Q_DECLARE_INTERFACE(IFace, IId) \
template <> inline const char *qobject_interface_iid<IFace *>() \
{ return IId; } \
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 5dfef786ec..a762e6f529 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -407,7 +407,7 @@ private:
class QBoolBlocker
{
- Q_DISABLE_COPY(QBoolBlocker)
+ Q_DISABLE_COPY_MOVE(QBoolBlocker)
public:
explicit inline QBoolBlocker(bool &b, bool value=true):block(b), reset(b){block = value;}
inline ~QBoolBlocker(){block = reset; }
@@ -432,9 +432,9 @@ struct Q_CORE_EXPORT QAbstractDynamicMetaObject : public QDynamicMetaObjectData,
{
~QAbstractDynamicMetaObject();
- virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) override { return this; }
+ QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) override { return this; }
virtual int createProperty(const char *, const char *) { return -1; }
- virtual int metaCall(QObject *, QMetaObject::Call c, int _id, void **a) override
+ int metaCall(QObject *, QMetaObject::Call c, int _id, void **a) override
{ return metaCall(c, _id, a); }
virtual int metaCall(QMetaObject::Call, int _id, void **) { return _id; } // Compat overload
};
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index 8afff1fb98..aa6bd84e95 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -395,7 +395,7 @@ namespace QtPrivate {
protected:
~QSlotObjectBase() {}
private:
- Q_DISABLE_COPY(QSlotObjectBase)
+ Q_DISABLE_COPY_MOVE(QSlotObjectBase)
};
// implementation of QSlotObjectBase for which the slot is a pointer to member function of a QObject
diff --git a/src/corelib/kernel/qppsobject_p.h b/src/corelib/kernel/qppsobject_p.h
index abcf00fa05..a3bf3a5bc1 100644
--- a/src/corelib/kernel/qppsobject_p.h
+++ b/src/corelib/kernel/qppsobject_p.h
@@ -119,7 +119,7 @@ Q_SIGNALS:
private:
Q_DECLARE_PRIVATE(QPpsObject)
- Q_DISABLE_COPY(QPpsObject)
+ Q_DISABLE_COPY_MOVE(QPpsObject)
};
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp
index 53c3136857..9d0394e4a5 100644
--- a/src/corelib/kernel/qsystemerror.cpp
+++ b/src/corelib/kernel/qsystemerror.cpp
@@ -152,10 +152,7 @@ QString QSystemError::string(ErrorScope errorScope, int errorCode)
case NativeError:
#if defined (Q_OS_WIN)
return windowsErrorString(errorCode);
-#else
- //unix: fall through as native and standard library are the same
- Q_FALLTHROUGH();
-#endif
+#endif // else unix: native and standard library are the same
case StandardLibraryError:
return standardLibraryErrorString(errorCode);
default:
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index 929554f6bc..a2111a084f 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -61,14 +61,8 @@
#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
#define QT_USE_MMAP
#include "private/qcore_unix_p.h"
-#endif
-
-// most of the headers below are already included in qplatformdefs.h
-// also this lacks Large File support but that's probably irrelevant
-#if defined(QT_USE_MMAP)
// for mmap
#include <sys/mman.h>
-#include <errno.h>
#endif
#include <stdlib.h>
@@ -303,7 +297,7 @@ public:
bool used_mmap : 1;
#endif
char *unmapPointer; // used memory (mmap, new or resource file)
- quint32 unmapLength;
+ qsizetype unmapLength;
// The resource object in case we loaded the translations from a resource
QResource *resource;
@@ -323,7 +317,7 @@ public:
uint numerusRulesLength;
bool do_load(const QString &filename, const QString &directory);
- bool do_load(const uchar *data, int len, const QString &directory);
+ bool do_load(const uchar *data, qsizetype len, const QString &directory);
QString do_translate(const char *context, const char *sourceText, const char *comment,
int n) const;
void clear();
@@ -554,7 +548,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
return false;
qint64 fileSize = file.size();
- if (fileSize < MagicLength || quint32(-1) <= fileSize)
+ if (fileSize < MagicLength || fileSize > std::numeric_limits<qsizetype>::max())
return false;
{
@@ -564,7 +558,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
return false;
}
- d->unmapLength = quint32(fileSize);
+ d->unmapLength = qsizetype(fileSize);
#ifdef QT_USE_MMAP
@@ -572,21 +566,20 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
#define MAP_FILE 0
#endif
#ifndef MAP_FAILED
-#define MAP_FAILED -1
+#define MAP_FAILED reinterpret_cast<void *>(-1)
#endif
int fd = file.handle();
if (fd >= 0) {
- char *ptr;
- ptr = reinterpret_cast<char *>(
- mmap(0, d->unmapLength, // any address, whole file
- PROT_READ, // read-only memory
- MAP_FILE | MAP_PRIVATE, // swap-backed map from file
- fd, 0)); // from offset 0 of fd
- if (ptr && ptr != reinterpret_cast<char *>(MAP_FAILED)) {
+ int protection = PROT_READ; // read-only memory
+ int flags = MAP_FILE | MAP_PRIVATE; // swap-backed map from file
+ void *ptr = QT_MMAP(nullptr, d->unmapLength,// any address, whole file
+ protection, flags,
+ fd, 0); // from offset 0 of fd
+ if (ptr != MAP_FAILED) {
file.close();
d->used_mmap = true;
- d->unmapPointer = ptr;
+ d->unmapPointer = static_cast<char *>(ptr);
ok = true;
}
}
@@ -816,7 +809,7 @@ static quint32 read32(const uchar *data)
return qFromBigEndian<quint32>(data);
}
-bool QTranslatorPrivate::do_load(const uchar *data, int len, const QString &directory)
+bool QTranslatorPrivate::do_load(const uchar *data, qsizetype len, const QString &directory)
{
bool ok = true;
const uchar *end = data + len;
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 090436a3c7..18c7f7648d 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1768,7 +1768,7 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names
\fn QVariant::QVariant(int typeId, const void *copy)
Constructs variant of type \a typeId, and initializes with
- \a copy if \a copy is not 0.
+ \a copy if \a copy is not \nullptr.
Note that you have to pass the address of the variable you want stored.
@@ -1797,7 +1797,7 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names
\internal
Constructs a variant private of type \a type, and initializes with \a copy if
- \a copy is not 0.
+ \a copy is not \nullptr.
*/
void QVariant::create(int type, const void *copy)
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index ff73c27b6e..f95502e75f 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -55,6 +55,8 @@
#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
#include <variant>
+#elif defined(Q_CLANG_QDOC)
+namespace std { template<typename...> struct variant; }
#endif
QT_BEGIN_NAMESPACE
@@ -365,7 +367,7 @@ class Q_CORE_EXPORT QVariant
static inline QVariant fromValue(const T &value)
{ return qVariantFromValue(value); }
-#if defined(Q_CLANG_QDOC) || (QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L)
+#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
template<typename... Types>
static inline QVariant fromStdVariant(const std::variant<Types...> &value)
{
diff --git a/src/corelib/mimetypes/mime/packages/freedesktop.org.xml b/src/corelib/mimetypes/mime/packages/freedesktop.org.xml
index b749fe41ac..d384ffb2d5 100644
--- a/src/corelib/mimetypes/mime/packages/freedesktop.org.xml
+++ b/src/corelib/mimetypes/mime/packages/freedesktop.org.xml
@@ -64,20 +64,32 @@
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/x-atari-2600-rom">
<comment>Atari 2600</comment>
+ <comment xml:lang="ast">Atari 2600</comment>
<comment xml:lang="ca">Atari 2600</comment>
+ <comment xml:lang="cs">Atari 2600</comment>
<comment xml:lang="da">Atari 2600</comment>
<comment xml:lang="de">Atari 2600</comment>
+ <comment xml:lang="en_GB">Atari 2600</comment>
<comment xml:lang="es">Atari 2600</comment>
+ <comment xml:lang="eu">Atari 2600</comment>
<comment xml:lang="fi">Atari 2600</comment>
<comment xml:lang="fr">Atari 2600</comment>
+ <comment xml:lang="ga">Atari 2600</comment>
<comment xml:lang="he">אטארי 2600</comment>
+ <comment xml:lang="hr">Atari 2600</comment>
<comment xml:lang="hu">Atari 2600</comment>
+ <comment xml:lang="id">Atari 2600</comment>
+ <comment xml:lang="it">Atari 2600</comment>
<comment xml:lang="kk">Atari 2600</comment>
<comment xml:lang="ko">Atari 2600</comment>
+ <comment xml:lang="oc">Atari 2600</comment>
<comment xml:lang="pl">Atari 2600</comment>
<comment xml:lang="pt_BR">Atari 2600</comment>
<comment xml:lang="ru">Atari 2600</comment>
<comment xml:lang="sk">Atari 2600</comment>
+ <comment xml:lang="sr">Атари 2600</comment>
+ <comment xml:lang="sv">Atari 2600</comment>
+ <comment xml:lang="tr">Atari 2600</comment>
<comment xml:lang="uk">Atari 2600</comment>
<comment xml:lang="zh_CN">雅达利 2600</comment>
<comment xml:lang="zh_TW">Atari 2600</comment>
@@ -86,20 +98,32 @@
</mime-type>
<mime-type type="application/x-atari-7800-rom">
<comment>Atari 7800</comment>
+ <comment xml:lang="ast">Atari 7800</comment>
<comment xml:lang="ca">Atari 7800</comment>
+ <comment xml:lang="cs">Atari 7800</comment>
<comment xml:lang="da">Atari 7800</comment>
<comment xml:lang="de">Atari 7800</comment>
+ <comment xml:lang="en_GB">Atari 7800</comment>
<comment xml:lang="es">Atari 7800</comment>
+ <comment xml:lang="eu">Atari 7800</comment>
<comment xml:lang="fi">Atari 7800</comment>
<comment xml:lang="fr">Atari 7800</comment>
+ <comment xml:lang="ga">Atari 7800</comment>
<comment xml:lang="he">אטארי 7800</comment>
+ <comment xml:lang="hr">Atari 7800</comment>
<comment xml:lang="hu">Atari 7800</comment>
+ <comment xml:lang="id">Atari 7800</comment>
+ <comment xml:lang="it">Atari 7800</comment>
<comment xml:lang="kk">Atari 7800</comment>
<comment xml:lang="ko">Atari 7800</comment>
+ <comment xml:lang="oc">Atari 7800</comment>
<comment xml:lang="pl">Atari 7800</comment>
<comment xml:lang="pt_BR">Atari 7800</comment>
<comment xml:lang="ru">Atari 7800</comment>
<comment xml:lang="sk">Atari 7800</comment>
+ <comment xml:lang="sr">Атари 7800</comment>
+ <comment xml:lang="sv">Atari 7800</comment>
+ <comment xml:lang="tr">Atari 7800</comment>
<comment xml:lang="uk">Atari 7800</comment>
<comment xml:lang="zh_CN">雅达利 7800</comment>
<comment xml:lang="zh_TW">Atari 7800</comment>
@@ -109,6 +133,35 @@
<match value="ATARI7800" type="string" offset="1"/>
</magic>
</mime-type>
+ <mime-type type="application/x-atari-lynx-rom">
+ <comment>Atari Lynx</comment>
+ <comment xml:lang="ast">Atari Lynx</comment>
+ <comment xml:lang="ca">Atari Lynx</comment>
+ <comment xml:lang="cs">Atari Lynx</comment>
+ <comment xml:lang="de">Atari Lynx</comment>
+ <comment xml:lang="en_GB">Atari Lynx</comment>
+ <comment xml:lang="es">Atari Lynx</comment>
+ <comment xml:lang="fi">Atari Lynx</comment>
+ <comment xml:lang="hr">Atari Lynx</comment>
+ <comment xml:lang="hu">Atari Lynx</comment>
+ <comment xml:lang="id">Atari Lynx</comment>
+ <comment xml:lang="it">Atari Lynx</comment>
+ <comment xml:lang="kk">Atari Lynx</comment>
+ <comment xml:lang="ko">Atari Lynx</comment>
+ <comment xml:lang="pl">Atari Lynx</comment>
+ <comment xml:lang="pt_BR">Atari Lynx</comment>
+ <comment xml:lang="ru">Atari Lynx</comment>
+ <comment xml:lang="sk">Atari Lynx</comment>
+ <comment xml:lang="sv">Atari Lynx</comment>
+ <comment xml:lang="uk">Atari Lynx</comment>
+ <comment xml:lang="zh_CN">雅达利 Lynx</comment>
+ <comment xml:lang="zh_TW">Atari Lynx</comment>
+ <generic-icon name="application-x-executable"/>
+ <glob pattern="*.lnx"/>
+ <magic>
+ <match value="LYNX" type="string" offset="0"/>
+ </magic>
+ </mime-type>
<mime-type type="application/andrew-inset">
<comment>ATK inset</comment>
<comment xml:lang="ar">شكل ATK</comment>
@@ -146,7 +199,7 @@
<comment xml:lang="pt">Suplemento ATK</comment>
<comment xml:lang="pt_BR">Conjunto de entrada do ATK</comment>
<comment xml:lang="ro">Inset ATK</comment>
- <comment xml:lang="ru">вкладка ATK</comment>
+ <comment xml:lang="ru">Вкладка ATK</comment>
<comment xml:lang="sk">Vložka ATK</comment>
<comment xml:lang="sl">Vložka ATK</comment>
<comment xml:lang="sq">Inset ATK</comment>
@@ -165,6 +218,7 @@
<mime-type type="application/epub+zip">
<comment>electronic book document</comment>
<comment xml:lang="ar">مستند كتاب إلكتروني</comment>
+ <comment xml:lang="ast">documentu de llibru electrónicu</comment>
<comment xml:lang="be@latin">elektronnaja kniha</comment>
<comment xml:lang="bg">Документ — електронна книга</comment>
<comment xml:lang="ca">document de llibre electrònic</comment>
@@ -181,7 +235,7 @@
<comment xml:lang="ga">leabhar leictreonach</comment>
<comment xml:lang="gl">documento de libro electrónico</comment>
<comment xml:lang="he">מסמך מסוג ספר אלקטרוני</comment>
- <comment xml:lang="hr">dokument elektroničke knjige</comment>
+ <comment xml:lang="hr">Dokument elektroničke knjige</comment>
<comment xml:lang="hu">elektronikus könyvdokumentum</comment>
<comment xml:lang="ia">Documento de libro electronic</comment>
<comment xml:lang="id">dokumen buku elektronik</comment>
@@ -198,7 +252,7 @@
<comment xml:lang="pt">documento de livro eletrónico</comment>
<comment xml:lang="pt_BR">Documento de livro eletrônico</comment>
<comment xml:lang="ro">document carte electronică</comment>
- <comment xml:lang="ru">электронная книга</comment>
+ <comment xml:lang="ru">Электронная книга</comment>
<comment xml:lang="sk">Dokument elektronickej knihy</comment>
<comment xml:lang="sl">dokument elektronske knjige</comment>
<comment xml:lang="sq">Dokument libri elektronik</comment>
@@ -224,6 +278,7 @@
<mime-type type="application/illustrator">
<comment>Adobe Illustrator document</comment>
<comment xml:lang="ar">مستند أدوبي المصور</comment>
+ <comment xml:lang="ast">Documentu d'Adobe Illustrator</comment>
<comment xml:lang="be@latin">Dakument Adobe Illustrator</comment>
<comment xml:lang="bg">Документ — Adobe Illustrator</comment>
<comment xml:lang="ca">document d'Adobe Illustrator</comment>
@@ -244,7 +299,7 @@
<comment xml:lang="hr">Adobe Illustrator dokument</comment>
<comment xml:lang="hu">Adobe Illustrator-dokumentum</comment>
<comment xml:lang="ia">Documento Adobe Illustrator</comment>
- <comment xml:lang="id">Dokumen Adobe Illustrator</comment>
+ <comment xml:lang="id">dokumen Adobe Illustrator</comment>
<comment xml:lang="it">Documento Adobe Illustrator</comment>
<comment xml:lang="ja">Adobe Illustrator ドキュメント</comment>
<comment xml:lang="ka">Adobe Illustrator-ის დოკუმენტი</comment>
@@ -261,11 +316,11 @@
<comment xml:lang="pt">documento Adobe Illustrator</comment>
<comment xml:lang="pt_BR">Documento do Adobe Illustrator</comment>
<comment xml:lang="ro">Document Adobe Illustrator</comment>
- <comment xml:lang="ru">документ Adobe Illustrator</comment>
+ <comment xml:lang="ru">Документ Adobe Illustrator</comment>
<comment xml:lang="sk">Dokument Adobe Illustrator</comment>
<comment xml:lang="sl">Dokument Adobe Illustrator</comment>
<comment xml:lang="sq">Dokument Adobe Illustrator</comment>
- <comment xml:lang="sr">документ Адобе Илустратора</comment>
+ <comment xml:lang="sr">документ Адобе илустратора</comment>
<comment xml:lang="sv">Adobe Illustrator-dokument</comment>
<comment xml:lang="tr">Adobe Illustrator belgesi</comment>
<comment xml:lang="uk">документ Adobe Illustrator</comment>
@@ -274,10 +329,12 @@
<comment xml:lang="zh_TW">Adobe Illustrator 文件</comment>
<generic-icon name="image-x-generic"/>
<glob pattern="*.ai"/>
+ <alias type="application/vnd.adobe.illustrator"/>
</mime-type>
<mime-type type="application/mac-binhex40">
<comment>Macintosh BinHex-encoded file</comment>
<comment xml:lang="ar">ملف Macintosh BinHex مشفر</comment>
+ <comment xml:lang="ast">Ficheru codificáu en BinHex de Machintosh</comment>
<comment xml:lang="az">Macintosh BinHex-kodlanmış fayl</comment>
<comment xml:lang="be@latin">Fajł Macintosh, BinHex-zakadavany</comment>
<comment xml:lang="bg">Файл — кодиран във формат BinHex за Macintosh</comment>
@@ -297,10 +354,10 @@
<comment xml:lang="ga">comhad ionchódaithe le Macintosh BinHex</comment>
<comment xml:lang="gl">ficheiro de Macintosh codificado con BinHex</comment>
<comment xml:lang="he">קובץ בקידוד Macintosh BinHex</comment>
- <comment xml:lang="hr">Macintosh BinHex-kodirana datoteka</comment>
+ <comment xml:lang="hr">Macintosh BinHex-kôdirana datoteka</comment>
<comment xml:lang="hu">Macintosh BinHex kódolású fájl</comment>
<comment xml:lang="ia">File codificate in BinHex de Macintosh</comment>
- <comment xml:lang="id">Berkas tersandi Macintosh BinHex</comment>
+ <comment xml:lang="id">berkas tersandi Macintosh BinHex</comment>
<comment xml:lang="it">File Macintosh codificato BinHex</comment>
<comment xml:lang="ja">Macintosh BinHex エンコードファイル</comment>
<comment xml:lang="kk">Macintosh BinHex кодталған файлы</comment>
@@ -316,7 +373,7 @@
<comment xml:lang="pt">ficheiro codificado em BinHex de Macintosh</comment>
<comment xml:lang="pt_BR">Arquivo do Macintosh codificado com BinHex</comment>
<comment xml:lang="ro">Fișier codat Macintosh BinHex</comment>
- <comment xml:lang="ru">файл (закодированный Macintosh BinHex)</comment>
+ <comment xml:lang="ru">Файл (закодированный Macintosh BinHex)</comment>
<comment xml:lang="sk">Súbor kódovaný pomocou Macintosh BinHex</comment>
<comment xml:lang="sl">Kodirana datoteka Macintosh (BinHex)</comment>
<comment xml:lang="sq">File Macintosh i kodifikuar BinHex</comment>
@@ -393,6 +450,7 @@
<mime-type type="application/mathml+xml">
<comment>MathML document</comment>
<comment xml:lang="ar">مستند MathML</comment>
+ <comment xml:lang="ast">Documentu MathML</comment>
<comment xml:lang="az">MathML sənədi</comment>
<comment xml:lang="be@latin">Dakument MathML</comment>
<comment xml:lang="bg">Документ — MathML</comment>
@@ -415,7 +473,7 @@
<comment xml:lang="hr">MathML dokument</comment>
<comment xml:lang="hu">MathML-dokumentum</comment>
<comment xml:lang="ia">Documento MathML</comment>
- <comment xml:lang="id">Dokumen MathML</comment>
+ <comment xml:lang="id">dokumen MathML</comment>
<comment xml:lang="it">Documento MathML</comment>
<comment xml:lang="ja">MathML ドキュメント</comment>
<comment xml:lang="ka">MathML-ის დოკუმენტი</comment>
@@ -432,7 +490,7 @@
<comment xml:lang="pt">documento MathML</comment>
<comment xml:lang="pt_BR">Documento do MathML</comment>
<comment xml:lang="ro">Document MathML</comment>
- <comment xml:lang="ru">документ MathML</comment>
+ <comment xml:lang="ru">Документ MathML</comment>
<comment xml:lang="sk">Dokument MathML</comment>
<comment xml:lang="sl">Dokument MathML</comment>
<comment xml:lang="sq">Dokument MathML</comment>
@@ -469,7 +527,7 @@
<comment xml:lang="ga">comhad bhosca poist</comment>
<comment xml:lang="gl">ficheiro de caixa de correo</comment>
<comment xml:lang="he">קובץ תיבת-דואר</comment>
- <comment xml:lang="hr">datoteka poštanskog sandučića</comment>
+ <comment xml:lang="hr">Datoteka poštanskog sandučića</comment>
<comment xml:lang="hu">mailbox fájl</comment>
<comment xml:lang="ia">File de cassa postal</comment>
<comment xml:lang="id">berkas kotak surat</comment>
@@ -487,7 +545,7 @@
<comment xml:lang="pt">ficheiro de caixa de correio</comment>
<comment xml:lang="pt_BR">Arquivo de caixa de correio</comment>
<comment xml:lang="ro">fișier căsuță poștală</comment>
- <comment xml:lang="ru">файл почтового ящика</comment>
+ <comment xml:lang="ru">Файл почтового ящика</comment>
<comment xml:lang="sk">Súbor mailbox</comment>
<comment xml:lang="sl">datoteka poštnega predala</comment>
<comment xml:lang="sq">File mailbox</comment>
@@ -496,7 +554,7 @@
<comment xml:lang="tr">posta kutusu dosyası</comment>
<comment xml:lang="uk">файл поштової скриньки</comment>
<comment xml:lang="vi">tập tin hộp thư</comment>
- <comment xml:lang="zh_CN">mailbox 文件</comment>
+ <comment xml:lang="zh_CN">邮箱文件</comment>
<comment xml:lang="zh_TW">郵箱檔</comment>
<generic-icon name="text-x-generic"/>
<sub-class-of type="text/plain"/>
@@ -508,6 +566,7 @@
<mime-type type="application/metalink+xml">
<comment>Metalink file</comment>
<comment xml:lang="ar">ملف ميتالنك</comment>
+ <comment xml:lang="ast">Ficheru d'enllaz meta</comment>
<comment xml:lang="bg">Изтегляне — Metalink</comment>
<comment xml:lang="ca">fitxer Metalink</comment>
<comment xml:lang="cs">soubor metalink</comment>
@@ -527,7 +586,7 @@
<comment xml:lang="hr">Datoteka meta poveznice</comment>
<comment xml:lang="hu">Metalink fájl</comment>
<comment xml:lang="ia">File Metalink</comment>
- <comment xml:lang="id">Berkas Metalink</comment>
+ <comment xml:lang="id">berkas Metalink</comment>
<comment xml:lang="it">File Metalink</comment>
<comment xml:lang="ja">Metalink ファイル</comment>
<comment xml:lang="kk">Metalink файлы</comment>
@@ -540,14 +599,14 @@
<comment xml:lang="pt">ficheiro Metalink</comment>
<comment xml:lang="pt_BR">Arquivo Metalink</comment>
<comment xml:lang="ro">Fișier Metalink</comment>
- <comment xml:lang="ru">файл Metalink</comment>
+ <comment xml:lang="ru">Файл Metalink</comment>
<comment xml:lang="sk">Súbor Metalink</comment>
<comment xml:lang="sl">Datoteka povezave Metalink</comment>
<comment xml:lang="sr">датотека метавезе</comment>
<comment xml:lang="sv">Metalink-fil</comment>
<comment xml:lang="tr">Metalink dosyası</comment>
<comment xml:lang="uk">файл метапосилання</comment>
- <comment xml:lang="zh_CN">元链接文件</comment>
+ <comment xml:lang="zh_CN">Metalink 文件</comment>
<comment xml:lang="zh_TW">Metalink 檔案</comment>
<sub-class-of type="application/xml"/>
<magic priority="50">
@@ -559,6 +618,7 @@
<mime-type type="application/metalink4+xml">
<comment>Metalink file</comment>
<comment xml:lang="ar">ملف ميتالنك</comment>
+ <comment xml:lang="ast">Ficheru d'enllaz meta</comment>
<comment xml:lang="bg">Изтегляне — Metalink</comment>
<comment xml:lang="ca">fitxer Metalink</comment>
<comment xml:lang="cs">soubor metalink</comment>
@@ -578,7 +638,7 @@
<comment xml:lang="hr">Datoteka meta poveznice</comment>
<comment xml:lang="hu">Metalink fájl</comment>
<comment xml:lang="ia">File Metalink</comment>
- <comment xml:lang="id">Berkas Metalink</comment>
+ <comment xml:lang="id">berkas Metalink</comment>
<comment xml:lang="it">File Metalink</comment>
<comment xml:lang="ja">Metalink ファイル</comment>
<comment xml:lang="kk">Metalink файлы</comment>
@@ -591,14 +651,14 @@
<comment xml:lang="pt">ficheiro Metalink</comment>
<comment xml:lang="pt_BR">Arquivo Metalink</comment>
<comment xml:lang="ro">Fișier Metalink</comment>
- <comment xml:lang="ru">файл Metalink</comment>
+ <comment xml:lang="ru">Файл Metalink</comment>
<comment xml:lang="sk">Súbor Metalink</comment>
<comment xml:lang="sl">Datoteka povezave Metalink</comment>
<comment xml:lang="sr">датотека метавезе</comment>
<comment xml:lang="sv">Metalink-fil</comment>
<comment xml:lang="tr">Metalink dosyası</comment>
<comment xml:lang="uk">файл метапосилання</comment>
- <comment xml:lang="zh_CN">元链接文件</comment>
+ <comment xml:lang="zh_CN">Metalink 文件</comment>
<comment xml:lang="zh_TW">Metalink 檔案</comment>
<sub-class-of type="application/xml"/>
<magic priority="50">
@@ -610,12 +670,13 @@
<mime-type type="application/octet-stream">
<comment>unknown</comment>
<comment xml:lang="ar">مجهول</comment>
+ <comment xml:lang="ast">desconozse</comment>
<comment xml:lang="be@latin">nieviadomy</comment>
<comment xml:lang="bg">Неизвестен тип</comment>
<comment xml:lang="ca">desconegut</comment>
<comment xml:lang="cs">neznámý</comment>
<comment xml:lang="da">ukendt</comment>
- <comment xml:lang="de">Unbekannt</comment>
+ <comment xml:lang="de">unbekannt</comment>
<comment xml:lang="el">Άγνωστο</comment>
<comment xml:lang="en_GB">unknown</comment>
<comment xml:lang="eo">nekonate</comment>
@@ -627,7 +688,7 @@
<comment xml:lang="ga">anaithnid</comment>
<comment xml:lang="gl">descoñecido</comment>
<comment xml:lang="he">לא ידוע</comment>
- <comment xml:lang="hr">nepoznato</comment>
+ <comment xml:lang="hr">Nepoznato</comment>
<comment xml:lang="hu">ismeretlen</comment>
<comment xml:lang="ia">incognite</comment>
<comment xml:lang="id">tak diketahui</comment>
@@ -647,7 +708,7 @@
<comment xml:lang="pt">desconhecido</comment>
<comment xml:lang="pt_BR">Desconhecido</comment>
<comment xml:lang="ro">necunoscut</comment>
- <comment xml:lang="ru">неизвестно</comment>
+ <comment xml:lang="ru">Неизвестно</comment>
<comment xml:lang="sk">Neznámy</comment>
<comment xml:lang="sl">neznano</comment>
<comment xml:lang="sq">Nuk njihet</comment>
@@ -658,10 +719,10 @@
<comment xml:lang="vi">không rõ</comment>
<comment xml:lang="zh_CN">未知</comment>
<comment xml:lang="zh_TW">不明</comment>
- <glob pattern="*.bin"/>
</mime-type>
<mime-type type="application/x-partial-download">
<comment>Partially downloaded file</comment>
+ <comment xml:lang="ast">Ficheru baxáu parcialmente</comment>
<comment xml:lang="ca">fitxer baixat parcialment</comment>
<comment xml:lang="cs">částečně stažený soubor</comment>
<comment xml:lang="da">Delvist hentet fil</comment>
@@ -672,6 +733,7 @@
<comment xml:lang="eu">Partzialki deskargatutako fitxategia</comment>
<comment xml:lang="fi">Osittain ladattu tiedosto</comment>
<comment xml:lang="fr">fichier partiellement téléchargé</comment>
+ <comment xml:lang="ga">Comhad leath-íoslódáilte</comment>
<comment xml:lang="gl">Ficheiro descargado parcialmente</comment>
<comment xml:lang="he">קובץ שהתקבל חלקית</comment>
<comment xml:lang="hr">Djelomično preuzeta datoteka</comment>
@@ -692,7 +754,7 @@
<comment xml:lang="sv">Delvis hämtad fil</comment>
<comment xml:lang="tr">Kısmen indirilmiş dosya</comment>
<comment xml:lang="uk">частково отриманий файл</comment>
- <comment xml:lang="zh_CN">下载的部分文件</comment>
+ <comment xml:lang="zh_CN">部分下载的文件</comment>
<comment xml:lang="zh_TW">已部份下載的檔案</comment>
<generic-icon name="package-x-generic"/>
<glob pattern="*.wkdownload"/>
@@ -702,6 +764,7 @@
<mime-type type="application/oda">
<comment>ODA document</comment>
<comment xml:lang="ar">مستند ODA</comment>
+ <comment xml:lang="ast">Documentu ODA</comment>
<comment xml:lang="az">ODA sənədi</comment>
<comment xml:lang="be@latin">Dakument ODA</comment>
<comment xml:lang="bg">Документ — ODA</comment>
@@ -741,7 +804,7 @@
<comment xml:lang="pt">documento ODA</comment>
<comment xml:lang="pt_BR">Documento ODA</comment>
<comment xml:lang="ro">Document ODA</comment>
- <comment xml:lang="ru">документ ODA</comment>
+ <comment xml:lang="ru">Документ ODA</comment>
<comment xml:lang="sk">Dokument ODA</comment>
<comment xml:lang="sl">Dokument ODA</comment>
<comment xml:lang="sq">Dokument ODA</comment>
@@ -759,6 +822,7 @@
</mime-type>
<mime-type type="application/x-wwf">
<comment>WWF document</comment>
+ <comment xml:lang="ast">Documentu WWF</comment>
<comment xml:lang="bg">Документ — WWF</comment>
<comment xml:lang="ca">document WWF</comment>
<comment xml:lang="cs">dokument WWF</comment>
@@ -771,6 +835,7 @@
<comment xml:lang="eu">WWF dokumentua</comment>
<comment xml:lang="fi">WWF-asiakirja</comment>
<comment xml:lang="fr">document WWF</comment>
+ <comment xml:lang="ga">cáipéis WWF</comment>
<comment xml:lang="gl">documento de WWF</comment>
<comment xml:lang="he">מסמך WWF</comment>
<comment xml:lang="hr">WWF dokument</comment>
@@ -788,7 +853,7 @@
<comment xml:lang="pl">Dokument WWF</comment>
<comment xml:lang="pt">documento WWF</comment>
<comment xml:lang="pt_BR">Documento WWF</comment>
- <comment xml:lang="ru">документ WWF</comment>
+ <comment xml:lang="ru">Документ WWF</comment>
<comment xml:lang="sk">Dokument WWF</comment>
<comment xml:lang="sl">Dokument WWF</comment>
<comment xml:lang="sr">ВВФ документ</comment>
@@ -805,6 +870,7 @@
<mime-type type="application/pdf">
<comment>PDF document</comment>
<comment xml:lang="ar">مستند PDF</comment>
+ <comment xml:lang="ast">Documentu PDF</comment>
<comment xml:lang="be@latin">Dakument PDF</comment>
<comment xml:lang="bg">Документ — PDF</comment>
<comment xml:lang="ca">document PDF</comment>
@@ -842,7 +908,7 @@
<comment xml:lang="pt">documento PDF</comment>
<comment xml:lang="pt_BR">Documento PDF</comment>
<comment xml:lang="ro">Document PDF</comment>
- <comment xml:lang="ru">документ PDF</comment>
+ <comment xml:lang="ru">Документ PDF</comment>
<comment xml:lang="sk">Dokument PDF</comment>
<comment xml:lang="sl">Dokument PDF</comment>
<comment xml:lang="sq">Dokument PDF</comment>
@@ -868,6 +934,7 @@
<mime-type type="application/xspf+xml">
<comment>XSPF playlist</comment>
<comment xml:lang="ar">قائمة تشغيل XSPF</comment>
+ <comment xml:lang="ast">Llista de reproducción XSPF</comment>
<comment xml:lang="be@latin">Śpis piesień XSPF</comment>
<comment xml:lang="bg">Списък за изпълнение — XSPF</comment>
<comment xml:lang="ca">llista de reproducció XSPF</comment>
@@ -885,7 +952,7 @@
<comment xml:lang="ga">seinmliosta XSPF</comment>
<comment xml:lang="gl">lista de reprodución XSPF</comment>
<comment xml:lang="he">רשימת נגינה XSPF</comment>
- <comment xml:lang="hr">XSPF popis za reprodukciju</comment>
+ <comment xml:lang="hr">XSPF popis izvođenja</comment>
<comment xml:lang="hu">XSPF-lejátszólista</comment>
<comment xml:lang="ia">Lista de selection XSPF</comment>
<comment xml:lang="id">Senarai pular XSPF</comment>
@@ -903,7 +970,7 @@
<comment xml:lang="pt">lista de reprodução XSPF</comment>
<comment xml:lang="pt_BR">Lista de reprodução XSPF</comment>
<comment xml:lang="ro">Listă XSPF</comment>
- <comment xml:lang="ru">список воспроизведения XSPF</comment>
+ <comment xml:lang="ru">Список воспроизведения XSPF</comment>
<comment xml:lang="sk">Zoznam skladieb XSPF</comment>
<comment xml:lang="sl">Seznam predvajanja XSPF</comment>
<comment xml:lang="sq">Listë titujsh XSPF</comment>
@@ -929,11 +996,12 @@
<mime-type type="application/x-windows-themepack">
<comment>Microsoft Windows theme pack</comment>
<comment xml:lang="ar">حزمة سمات Microsoft Works</comment>
+ <comment xml:lang="ast">Paquete de temes de Microsoft Windows</comment>
<comment xml:lang="bg">Пакет с тема — Microsoft Windows</comment>
<comment xml:lang="ca">paquet de temes de Microsoft Windows</comment>
<comment xml:lang="cs">balík motivů Microsoft Windows</comment>
<comment xml:lang="da">Microsoft Windows-temapakke</comment>
- <comment xml:lang="de">Themenpaket für Microsoft Windows</comment>
+ <comment xml:lang="de">Microsoft-Windows-Themenpaket</comment>
<comment xml:lang="el">Πακέτο θέματος Microsoft Windows</comment>
<comment xml:lang="en_GB">Microsoft Windows theme pack</comment>
<comment xml:lang="es">paquete de tema para Microsoft Windows</comment>
@@ -961,7 +1029,7 @@
<comment xml:lang="pt">pacote de tema Microsoft Windows</comment>
<comment xml:lang="pt_BR">Pacote de temas do Microsoft Windows</comment>
<comment xml:lang="ro">Pachet de teme Microsoft Windows</comment>
- <comment xml:lang="ru">пакет темы Microsoft Windows</comment>
+ <comment xml:lang="ru">Пакет темы Microsoft Windows</comment>
<comment xml:lang="sk">Balík tém Microsoft Windows</comment>
<comment xml:lang="sl">Datoteka teme Microsoft Windows</comment>
<comment xml:lang="sr">пакет теме Мајкрософт Виндоуза</comment>
@@ -976,6 +1044,7 @@
</mime-type>
<mime-type type="audio/x-amzxml">
<comment>AmazonMP3 download file</comment>
+ <comment xml:lang="ast">Ficheru de descarga AmazonMP3</comment>
<comment xml:lang="ca">fitxer baixat d'AmazonMP3</comment>
<comment xml:lang="cs">soubor stahování AmazonMP3</comment>
<comment xml:lang="da">AmazonMP3-downloadfil</comment>
@@ -985,6 +1054,7 @@
<comment xml:lang="es">archivo de descarga de AmazonMP3</comment>
<comment xml:lang="eu">AmazonMP3 deskarga fitxategia</comment>
<comment xml:lang="fr">fichier téléchargé AmazonMP3</comment>
+ <comment xml:lang="ga">comhad íoslódáilte AmazonMP3</comment>
<comment xml:lang="gl">Ficheiro de descarga de AmazonMP3</comment>
<comment xml:lang="he">קובץ הורדת AmazonMP3</comment>
<comment xml:lang="hr">AmazonMP3 preuzeta datoteka</comment>
@@ -1000,7 +1070,7 @@
<comment xml:lang="pl">Pobrany plik AmazonMP3</comment>
<comment xml:lang="pt">ficheiro transferido AmazonMP3</comment>
<comment xml:lang="pt_BR">Arquivo de download AmazonMP3</comment>
- <comment xml:lang="ru">файл загрузки AmazonMP3</comment>
+ <comment xml:lang="ru">Файл загрузки AmazonMP3</comment>
<comment xml:lang="sk">Stiahnutý súbor AmazonMP3 </comment>
<comment xml:lang="sl">Datoteka prenosa AmazonMP3</comment>
<comment xml:lang="sr">датотека преузимања АмазонаМП3</comment>
@@ -1014,6 +1084,7 @@
<mime-type type="audio/x-gsm">
<comment>GSM 06.10 audio</comment>
<comment xml:lang="ar">GSM 06.10 سمعي</comment>
+ <comment xml:lang="ast">Audiu GSM 6.10</comment>
<comment xml:lang="bg">Аудио — GSM 06.10</comment>
<comment xml:lang="ca">àudio de GSM 06.10</comment>
<comment xml:lang="cs">zvuk GSM 06.10</comment>
@@ -1029,7 +1100,7 @@
<comment xml:lang="ga">fuaim GSM 06.10</comment>
<comment xml:lang="gl">son de GSM 06.10</comment>
<comment xml:lang="he">שמע GSM 06.10</comment>
- <comment xml:lang="hr">GSM 06.10 audio</comment>
+ <comment xml:lang="hr">GSM 06.10 zvučni zapis</comment>
<comment xml:lang="hu">GSM 06.10 hang</comment>
<comment xml:lang="ia">Audio GSM 06.10</comment>
<comment xml:lang="id">Audio GSM 06.10</comment>
@@ -1046,7 +1117,7 @@
<comment xml:lang="pt">áudio GSM 06.10</comment>
<comment xml:lang="pt_BR">Áudio GSM 06.10</comment>
<comment xml:lang="ro">GSM 06.10 audio</comment>
- <comment xml:lang="ru">аудио GSM 06.10</comment>
+ <comment xml:lang="ru">Аудио GSM 06.10</comment>
<comment xml:lang="sk">Zvuk GSM 06.10</comment>
<comment xml:lang="sl">Zvočna datoteka GSM 06.10</comment>
<comment xml:lang="sr">ГСМ 06.10 звук</comment>
@@ -1063,6 +1134,7 @@
<mime-type type="audio/x-iriver-pla">
<comment>iRiver Playlist</comment>
<comment xml:lang="ar">قائمة تشغيل iRiver</comment>
+ <comment xml:lang="ast">Llista de reproducción iRiver</comment>
<comment xml:lang="be@latin">Śpis piesień iRiver</comment>
<comment xml:lang="bg">Списък за изпълнение — iRiver</comment>
<comment xml:lang="ca">llista de reproducció iRiver</comment>
@@ -1080,7 +1152,7 @@
<comment xml:lang="ga">seinmliosta iRiver</comment>
<comment xml:lang="gl">lista de reprodución de iRiver</comment>
<comment xml:lang="he">רשימת נגינה של iRiver</comment>
- <comment xml:lang="hr">iRiver popis za reprodukciju</comment>
+ <comment xml:lang="hr">iRiver popis izvođenja</comment>
<comment xml:lang="hu">iRiver lejátszólista</comment>
<comment xml:lang="ia">Lista de selection iRiver</comment>
<comment xml:lang="id">iRiver Playlist</comment>
@@ -1098,7 +1170,7 @@
<comment xml:lang="pt">lista de reprodução iRiver</comment>
<comment xml:lang="pt_BR">Lista de reprodução do iRiver</comment>
<comment xml:lang="ro">Listă iRiver</comment>
- <comment xml:lang="ru">список воспроизведения iRiver</comment>
+ <comment xml:lang="ru">Список воспроизведения iRiver</comment>
<comment xml:lang="sk">Zoznam skladieb iRiver</comment>
<comment xml:lang="sl">Seznam predvajanja iRiver</comment>
<comment xml:lang="sq">Listë titujsh iRiver</comment>
@@ -1117,6 +1189,7 @@
<mime-type type="application/pgp-encrypted">
<comment>PGP/MIME-encrypted message header</comment>
<comment xml:lang="ar">ترويسة رسالة PGP/MIME-مشفرة</comment>
+ <comment xml:lang="ast">Testera de mensaxe cifrada en PGP/MIME</comment>
<comment xml:lang="be@latin">Zahałovak paviedamleńnia, zašyfravany ŭ PGP/MIME</comment>
<comment xml:lang="bg">Заглавна част на шифрирано съобщение — PGP/MIME</comment>
<comment xml:lang="ca">capçalera de missatge amb xifrat PGP/MIME</comment>
@@ -1153,7 +1226,7 @@
<comment xml:lang="pt">cabeçalho de mensagem encriptada com PGP/MIME</comment>
<comment xml:lang="pt_BR">Cabeçalho de mensagem criptografada PGP/MIME</comment>
<comment xml:lang="ro">Antet de mesaj encriptat PGP/MIME</comment>
- <comment xml:lang="ru">заголовок сообщения, зашифрованный PGP/MIME</comment>
+ <comment xml:lang="ru">Заголовок сообщения, зашифрованный PGP/MIME</comment>
<comment xml:lang="sk">Hlavičke správy zašifrovaná pomocou PGP/MIME</comment>
<comment xml:lang="sl">Datoteka glave šifriranega sporočila PGP/MIME</comment>
<comment xml:lang="sq">Header mesazhi të kriptuar PGP/MIME</comment>
@@ -1177,6 +1250,7 @@
<mime-type type="application/pgp-keys">
<comment>PGP keys</comment>
<comment xml:lang="ar">مفاتيح PGP</comment>
+ <comment xml:lang="ast">Claves PGP</comment>
<comment xml:lang="az">PGP açarları</comment>
<comment xml:lang="be@latin">Klučy PGP</comment>
<comment xml:lang="bg">Ключове — PGP</comment>
@@ -1215,7 +1289,7 @@
<comment xml:lang="pt">chaves PGP</comment>
<comment xml:lang="pt_BR">Chaves PGP</comment>
<comment xml:lang="ro">Chei PGP</comment>
- <comment xml:lang="ru">ключи PGP</comment>
+ <comment xml:lang="ru">Ключи PGP</comment>
<comment xml:lang="sk">Kľúče PGP</comment>
<comment xml:lang="sl">Datoteka ključa PGP</comment>
<comment xml:lang="sq">Kyçe PGP</comment>
@@ -1252,7 +1326,7 @@
<comment xml:lang="ca">signatura OpenPGP abstreta</comment>
<comment xml:lang="cs">oddělený podpis OpenPGP</comment>
<comment xml:lang="da">frigjort OpenPGP-signatur</comment>
- <comment xml:lang="de">Isolierte OpenPGP-Signatur</comment>
+ <comment xml:lang="de">isolierte OpenPGP-Signatur</comment>
<comment xml:lang="el">Αποκομμένη υπογραφή OpenPGP</comment>
<comment xml:lang="en_GB">detached OpenPGP signature</comment>
<comment xml:lang="eo">dekroĉa OpenPGP-subskribo</comment>
@@ -1264,7 +1338,7 @@
<comment xml:lang="ga">síniú OpenPGP scartha</comment>
<comment xml:lang="gl">sinatura de OpenPGP independente</comment>
<comment xml:lang="he">חתימת OpenPGP מנותקת</comment>
- <comment xml:lang="hr">odvojen OpenPGP potpis</comment>
+ <comment xml:lang="hr">Odvojen OpenPGP potpis</comment>
<comment xml:lang="hu">leválasztott OpenPGP-aláírás</comment>
<comment xml:lang="ia">Signatura OpenPGP distachate</comment>
<comment xml:lang="id">tanda tangan OpenPGP yang terlepas</comment>
@@ -1283,7 +1357,7 @@
<comment xml:lang="pt">assinatura OpenPGP solta</comment>
<comment xml:lang="pt_BR">Assinatura OpenPGP destacada</comment>
<comment xml:lang="ro">semnătură OpenPGP detașată</comment>
- <comment xml:lang="ru">отсоединённая подпись OpenPGP</comment>
+ <comment xml:lang="ru">Отсоединённая подпись OpenPGP</comment>
<comment xml:lang="sk">Oddelený podpis OpenPGP</comment>
<comment xml:lang="sl">odpet podpis OpenPGP</comment>
<comment xml:lang="sq">Firmë e shkëputur OpenPGP</comment>
@@ -1307,6 +1381,7 @@
<mime-type type="application/pkcs7-mime">
<comment>PKCS#7 Message or Certificate</comment>
+ <comment xml:lang="ast">Mensaxe o certificáu PKCS#7</comment>
<comment xml:lang="ca">missatge o certificat PKCS#7</comment>
<comment xml:lang="cs">zpráva nebo certifikát PKCS#7</comment>
<comment xml:lang="da">PKCS#7-besked eller certifikat</comment>
@@ -1317,6 +1392,7 @@
<comment xml:lang="eu">PKCS#7 mezu edo zertifikazioa</comment>
<comment xml:lang="fi">PKCS#7-viesti tai -varmenne</comment>
<comment xml:lang="fr">Message ou certificat PKCS#7</comment>
+ <comment xml:lang="ga">Teachtaireacht nó Teastas PKCS#7</comment>
<comment xml:lang="gl">Mensaxe ou certificado PKCS#7</comment>
<comment xml:lang="he">הודעה או אישור מסוג PKCS#7</comment>
<comment xml:lang="hr">PKCS#7 poruka ili vjerodajnica</comment>
@@ -1332,7 +1408,7 @@
<comment xml:lang="pl">Wiadomość lub certyfikat PKCS#7</comment>
<comment xml:lang="pt">Mensagem ou certificado PKCS#7</comment>
<comment xml:lang="pt_BR">Certificado ou Mensagem PKCS#7</comment>
- <comment xml:lang="ru">сообщение или сертификат PKCS#7</comment>
+ <comment xml:lang="ru">Сообщение или сертификат PKCS#7</comment>
<comment xml:lang="sk">Správa alebo certifikát PKCS#7</comment>
<comment xml:lang="sl">Sporočilo ali dovoljenje PKCS#7</comment>
<comment xml:lang="sr">ПКЦС#7 порука или уверење</comment>
@@ -1355,7 +1431,7 @@
<comment xml:lang="ca">signatura S/MIME abstreta</comment>
<comment xml:lang="cs">oddělený podpis S/MIME</comment>
<comment xml:lang="da">frigjort S/MIME-signatur</comment>
- <comment xml:lang="de">Isolierte S/MIME-Signatur</comment>
+ <comment xml:lang="de">isolierte S/MIME-Signatur</comment>
<comment xml:lang="el">Αποκομμένη υπογραφή S/MIME</comment>
<comment xml:lang="en_GB">detached S/MIME signature</comment>
<comment xml:lang="eo">dekroĉa S/MIME-subskribo</comment>
@@ -1367,7 +1443,7 @@
<comment xml:lang="ga">síniú S/MIME scartha</comment>
<comment xml:lang="gl">sinatura S/MIME independente</comment>
<comment xml:lang="he">חתימת S/MIME מנותקת</comment>
- <comment xml:lang="hr">odvojen S/MIME potpis</comment>
+ <comment xml:lang="hr">Odvojen S/MIME potpis</comment>
<comment xml:lang="hu">leválasztott S/MIME-aláírás</comment>
<comment xml:lang="ia">Signatura S/MIME distachate</comment>
<comment xml:lang="id">tanda tangan S/MIME yang terlepas</comment>
@@ -1386,7 +1462,7 @@
<comment xml:lang="pt">assinatura S/MIME solta</comment>
<comment xml:lang="pt_BR">Assinatura S/MIME destacada</comment>
<comment xml:lang="ro">semnătură S/MIME detașată</comment>
- <comment xml:lang="ru">отсоединённая подпись S/MIME</comment>
+ <comment xml:lang="ru">Отсоединённая подпись S/MIME</comment>
<comment xml:lang="sk">Oddelený podpis S/MIME</comment>
<comment xml:lang="sl">odpet podpis S/MIME</comment>
<comment xml:lang="sq">Firmë e shkëputur S/MIME</comment>
@@ -1437,7 +1513,7 @@
<comment xml:lang="pt">chave privada PKCS#8</comment>
<comment xml:lang="pt_BR">Chave privada PKCS#8</comment>
<comment xml:lang="ro">Cheie privată PKCS#8</comment>
- <comment xml:lang="ru">личный ключ PKCS#8</comment>
+ <comment xml:lang="ru">Личный ключ PKCS#8</comment>
<comment xml:lang="sk">Súkromný kľúč PKCS#8</comment>
<comment xml:lang="sl">Datoteka osebnega ključa PKCS#8</comment>
<comment xml:lang="sr">ПКЦС#8 лични кључ</comment>
@@ -1450,6 +1526,12 @@
<expanded-acronym>Public-Key Cryptography Standards</expanded-acronym>
<glob pattern="*.p8"/>
</mime-type>
+ <mime-type type="application/pkcs8-encrypted">
+ <comment>PKCS#8 private key (encrypted)</comment>
+ <acronym>PKCS</acronym>
+ <expanded-acronym>Public-Key Cryptography Standards</expanded-acronym>
+ <glob pattern="*.p8e"/>
+ </mime-type>
<mime-type type="application/pkcs10">
<comment>PKCS#10 certification request</comment>
<comment xml:lang="ar">طلب شهادة PKCS#10</comment>
@@ -1487,7 +1569,7 @@
<comment xml:lang="pt">pedido de certificação PKCS#10</comment>
<comment xml:lang="pt_BR">Pedido de certificação PKCS#12</comment>
<comment xml:lang="ro">Cerere de certificat PKCS#10</comment>
- <comment xml:lang="ru">запрос сертификации PKCS#10</comment>
+ <comment xml:lang="ru">Запрос сертификации PKCS#10</comment>
<comment xml:lang="sk">Požiadavka na certifikát PKCS#10</comment>
<comment xml:lang="sl">Datoteka potrdila PKCS#10</comment>
<comment xml:lang="sq">Kërkesë çertifikimi PKCS#10</comment>
@@ -1506,6 +1588,7 @@
<mime-type type="application/pkix-cert">
<comment>X.509 certificate</comment>
<comment xml:lang="ar">شهادة X.509</comment>
+ <comment xml:lang="ast">Certificáu X.509</comment>
<comment xml:lang="bg">Сертификат — X.509</comment>
<comment xml:lang="ca">certificat X.509</comment>
<comment xml:lang="cs">certifikát X.509</comment>
@@ -1521,7 +1604,7 @@
<comment xml:lang="ga">teastas X.509</comment>
<comment xml:lang="gl">Certificado X.509</comment>
<comment xml:lang="he">אישור X.509</comment>
- <comment xml:lang="hr">X.509 certifikat</comment>
+ <comment xml:lang="hr">X.509 vjerodajnica</comment>
<comment xml:lang="hu">X.509 tanúsítvány</comment>
<comment xml:lang="ia">Certificato X.509</comment>
<comment xml:lang="id">Sertifikat X.509</comment>
@@ -1537,7 +1620,7 @@
<comment xml:lang="pt">certificado X.509</comment>
<comment xml:lang="pt_BR">Certificado X.509</comment>
<comment xml:lang="ro">Certificat X.509</comment>
- <comment xml:lang="ru">сертификат X.509</comment>
+ <comment xml:lang="ru">Сертификат X.509</comment>
<comment xml:lang="sk">Certifikát X.509</comment>
<comment xml:lang="sl">Datoteka potrdila X.509</comment>
<comment xml:lang="sr">Икс.509 уверење</comment>
@@ -1551,6 +1634,7 @@
<mime-type type="application/pkix-crl">
<comment>Certificate revocation list</comment>
<comment xml:lang="ar">قائمة إبطال الشهادات</comment>
+ <comment xml:lang="ast">Llistáu de revocación de certificaos</comment>
<comment xml:lang="bg">Списък с отхвърлени сертификати</comment>
<comment xml:lang="ca">llista de revocació de certificats</comment>
<comment xml:lang="cs">seznam odvolaných certifikátů</comment>
@@ -1563,10 +1647,10 @@
<comment xml:lang="fi">Varmenteiden sulkulista</comment>
<comment xml:lang="fo">Prógv afturtøkulisti</comment>
<comment xml:lang="fr">liste de révocation de certificat</comment>
- <comment xml:lang="ga">liosta teastas cúlghairmthe</comment>
+ <comment xml:lang="ga">Liosta teastas cúlghairmthe</comment>
<comment xml:lang="gl">lista de certificados de revogación</comment>
<comment xml:lang="he">רשימת אישורים מבוטלים</comment>
- <comment xml:lang="hr">popis povučenih certifikata</comment>
+ <comment xml:lang="hr">Popis opozvanih vjerodajnica</comment>
<comment xml:lang="hu">Tanúsítvány-visszavonási lista</comment>
<comment xml:lang="ia">Lista de revocation de certificatos</comment>
<comment xml:lang="id">Daftar pencabutan sertificat (CRL)</comment>
@@ -1596,6 +1680,7 @@
<mime-type type="application/pkix-pkipath">
<comment>PkiPath certification path</comment>
<comment xml:lang="ar">مسار شهادة PkiPath</comment>
+ <comment xml:lang="ast">Camín de certificación PkiPath</comment>
<comment xml:lang="bg">Сертификационна верига — PkiPath</comment>
<comment xml:lang="ca">camí cap a la certificació PkiPath</comment>
<comment xml:lang="cs">cesta k certifikátu PkiPath</comment>
@@ -1627,7 +1712,7 @@
<comment xml:lang="pt">caminho de certificação PkiPath</comment>
<comment xml:lang="pt_BR">Pedido de certificação PkiPath</comment>
<comment xml:lang="ro">Cale certificare PkiPath</comment>
- <comment xml:lang="ru">путь сертификации PkiPath</comment>
+ <comment xml:lang="ru">Путь сертификации PkiPath</comment>
<comment xml:lang="sk">Cesta k certifikátu PkiPath</comment>
<comment xml:lang="sl">Datoteka poti potrdila PkiPath</comment>
<comment xml:lang="sr">путања уверења ПкиПат-а</comment>
@@ -1642,6 +1727,7 @@
<mime-type type="application/postscript">
<comment>PS document</comment>
<comment xml:lang="ar">مستند PS</comment>
+ <comment xml:lang="ast">Documentu PS</comment>
<comment xml:lang="be@latin">Dakument PS</comment>
<comment xml:lang="bg">Документ — PS</comment>
<comment xml:lang="ca">document PS</comment>
@@ -1677,7 +1763,7 @@
<comment xml:lang="pt">documento PS</comment>
<comment xml:lang="pt_BR">Documento PS</comment>
<comment xml:lang="ro">Document PS</comment>
- <comment xml:lang="ru">документ PS</comment>
+ <comment xml:lang="ru">Документ PS</comment>
<comment xml:lang="sk">Dokument PS</comment>
<comment xml:lang="sl">Dokument PS</comment>
<comment xml:lang="sq">Dokument PS</comment>
@@ -1701,6 +1787,7 @@
<mime-type type="application/prs.plucker">
<comment>Plucker document</comment>
<comment xml:lang="ar">مستند Plucker</comment>
+ <comment xml:lang="ast">Documentu Plucker</comment>
<comment xml:lang="be@latin">Dakument Plucker</comment>
<comment xml:lang="bg">Документ — Plucker</comment>
<comment xml:lang="ca">document Plucker</comment>
@@ -1736,7 +1823,7 @@
<comment xml:lang="pt">documento Plucker</comment>
<comment xml:lang="pt_BR">Documento do Plucker</comment>
<comment xml:lang="ro">Document Plucker</comment>
- <comment xml:lang="ru">документ Plucker</comment>
+ <comment xml:lang="ru">Документ Plucker</comment>
<comment xml:lang="sk">Dokument Plucker</comment>
<comment xml:lang="sl">Dokument Plucker</comment>
<comment xml:lang="sq">Dokument Plucker</comment>
@@ -1754,20 +1841,32 @@
</mime-type>
<mime-type type="application/raml+yaml">
<comment>RAML document</comment>
+ <comment xml:lang="ast">Documentu RAML</comment>
<comment xml:lang="ca">document RAML</comment>
+ <comment xml:lang="cs">dokument RAML</comment>
<comment xml:lang="da">RAML-dokument</comment>
<comment xml:lang="de">RAML-Dokument</comment>
+ <comment xml:lang="en_GB">RAML document</comment>
<comment xml:lang="es">documento RAML</comment>
+ <comment xml:lang="eu">RAML dokumentua</comment>
<comment xml:lang="fi">RAML-asiakirja</comment>
<comment xml:lang="fr">document RAML</comment>
+ <comment xml:lang="ga">cáipéis RAML</comment>
<comment xml:lang="he">מסמך RAML</comment>
+ <comment xml:lang="hr">RAML dokument</comment>
<comment xml:lang="hu">RAML dokumentum</comment>
+ <comment xml:lang="id">dokumen RAML</comment>
+ <comment xml:lang="it">Documento RAML</comment>
<comment xml:lang="kk">RAML құжаты</comment>
<comment xml:lang="ko">RAML 문서</comment>
+ <comment xml:lang="oc">Document RAML</comment>
<comment xml:lang="pl">Dokument RAML</comment>
<comment xml:lang="pt_BR">Documento RAML</comment>
- <comment xml:lang="ru">документ RAML</comment>
+ <comment xml:lang="ru">Документ RAML</comment>
<comment xml:lang="sk">Dokument RAML</comment>
+ <comment xml:lang="sr">РАМЛ документ</comment>
+ <comment xml:lang="sv">RAML-dokument</comment>
+ <comment xml:lang="tr">RAML belgesi</comment>
<comment xml:lang="uk">документ RAML</comment>
<comment xml:lang="zh_CN">RAML 文档</comment>
<comment xml:lang="zh_TW">RAML 文件</comment>
@@ -1831,6 +1930,7 @@
<mime-type type="application/rtf">
<comment>RTF document</comment>
<comment xml:lang="ar">مستند RTF</comment>
+ <comment xml:lang="ast">Documentu RTF</comment>
<comment xml:lang="be@latin">Dakument RTF</comment>
<comment xml:lang="bg">Документ — RTF</comment>
<comment xml:lang="ca">document RTF</comment>
@@ -1866,7 +1966,7 @@
<comment xml:lang="pt">documento RTF</comment>
<comment xml:lang="pt_BR">Documento RTF</comment>
<comment xml:lang="ro">Document RTF</comment>
- <comment xml:lang="ru">документ RTF</comment>
+ <comment xml:lang="ru">Документ RTF</comment>
<comment xml:lang="sk">Dokument RTF</comment>
<comment xml:lang="sl">Dokument RTF</comment>
<comment xml:lang="sq">Dokument RTF</comment>
@@ -1902,7 +2002,7 @@
<comment xml:lang="eu">Sieve posta-iragazki script-a</comment>
<comment xml:lang="fi">Sieve-postinsuodatuskomentotiedosto</comment>
<comment xml:lang="fr">script de filtrage de courriel Sieve</comment>
- <comment xml:lang="ga">script scagaire phost Sieve</comment>
+ <comment xml:lang="ga">script scagaire r-phost Sieve</comment>
<comment xml:lang="gl">Script de filtro de correo Sieve</comment>
<comment xml:lang="he">תסריט סינון דואר של Sieve</comment>
<comment xml:lang="hr">Sieve skripta filtriranja pošte</comment>
@@ -1923,7 +2023,7 @@
<comment xml:lang="pt">Script de filtragem de correio Sieve</comment>
<comment xml:lang="pt_BR">Script de filtro de mensagens do Sieve</comment>
<comment xml:lang="ro">Script filtrare email Sieve</comment>
- <comment xml:lang="ru">сценарий почтового фильтра Sieve</comment>
+ <comment xml:lang="ru">Сценарий почтового фильтра Sieve</comment>
<comment xml:lang="sk">Skript poštového filtra Sieve</comment>
<comment xml:lang="sl">Skriptna datoteka Sieve poštnega filtra</comment>
<comment xml:lang="sq">Script filtrim poste Sieve</comment>
@@ -1941,6 +2041,7 @@
<mime-type type="application/smil+xml">
<comment>SMIL document</comment>
<comment xml:lang="ar">مستند SMIL</comment>
+ <comment xml:lang="ast">Documentu SMIL</comment>
<comment xml:lang="be@latin">Dakument SMIL</comment>
<comment xml:lang="bg">Документ — SMIL</comment>
<comment xml:lang="ca">document SMIL</comment>
@@ -1976,7 +2077,7 @@
<comment xml:lang="pt">documento SMIL</comment>
<comment xml:lang="pt_BR">Documento SMIL</comment>
<comment xml:lang="ro">Document SMIL</comment>
- <comment xml:lang="ru">документ SMIL</comment>
+ <comment xml:lang="ru">Документ SMIL</comment>
<comment xml:lang="sk">Dokument SMIL</comment>
<comment xml:lang="sl">Dokument SMIL</comment>
<comment xml:lang="sq">Dokument SMIL</comment>
@@ -2022,7 +2123,7 @@
<comment xml:lang="ga">seinmliosta WPL</comment>
<comment xml:lang="gl">lista de reprodución WPL</comment>
<comment xml:lang="he">רשימת נגינה WPL</comment>
- <comment xml:lang="hr">WPL popis za reprodukciju</comment>
+ <comment xml:lang="hr">WPL popis izvođenja</comment>
<comment xml:lang="hu">WPL-lejátszólista</comment>
<comment xml:lang="ia">Lista de selection WPL</comment>
<comment xml:lang="id">Senarai putar WPL</comment>
@@ -2038,7 +2139,7 @@
<comment xml:lang="pt">lista de reprodução WPL</comment>
<comment xml:lang="pt_BR">Lista de reprodução do WPL</comment>
<comment xml:lang="ro">Listă redare WPL</comment>
- <comment xml:lang="ru">список воспроизведения WPL</comment>
+ <comment xml:lang="ru">Список воспроизведения WPL</comment>
<comment xml:lang="sk">Zoznam skladieb WPL</comment>
<comment xml:lang="sl">Seznam predvajanja WPL</comment>
<comment xml:lang="sr">ВПЛ списак нумера</comment>
@@ -2094,7 +2195,7 @@
<comment xml:lang="pt">base de dados SQLite2</comment>
<comment xml:lang="pt_BR">Banco de dados SQLite2</comment>
<comment xml:lang="ro">Bază de date SQLite2</comment>
- <comment xml:lang="ru">база данных SQLite2</comment>
+ <comment xml:lang="ru">База данных SQLite2</comment>
<comment xml:lang="sk">Databáza SQLite2</comment>
<comment xml:lang="sl">Podatkovna zbirka SQLite2</comment>
<comment xml:lang="sq">Bazë me të dhëna SQLite2</comment>
@@ -2105,11 +2206,12 @@
<comment xml:lang="vi">Cơ sở dữ liệu SQLite2</comment>
<comment xml:lang="zh_CN">SQLite2 数据库</comment>
<comment xml:lang="zh_TW">SQLite2 資料庫</comment>
+ <glob pattern="*.sqlite2"/>
<magic>
<match value="** This file contains an SQLite" type="string" offset="0"/>
</magic>
</mime-type>
- <mime-type type="application/x-sqlite3">
+ <mime-type type="application/vnd.sqlite3">
<comment>SQLite3 database</comment>
<comment xml:lang="ar">قاعدة بيانات SQLite3</comment>
<comment xml:lang="be@latin">Baza źviestak SQLite3</comment>
@@ -2147,7 +2249,7 @@
<comment xml:lang="pt">base de dados SQLite3</comment>
<comment xml:lang="pt_BR">Banco de dados SQLite3</comment>
<comment xml:lang="ro">Bază de date SQLite3</comment>
- <comment xml:lang="ru">база данных SQLite3</comment>
+ <comment xml:lang="ru">База данных SQLite3</comment>
<comment xml:lang="sk">Databáza SQLite3</comment>
<comment xml:lang="sl">Podatkovna zbirka SQLite3</comment>
<comment xml:lang="sq">Bazë me të dhëna SQLite3</comment>
@@ -2158,9 +2260,11 @@
<comment xml:lang="vi">Cơ sở dữ liệu SQLite3</comment>
<comment xml:lang="zh_CN">SQLite3 数据库</comment>
<comment xml:lang="zh_TW">SQLite3 資料庫</comment>
+ <glob pattern="*.sqlite3"/>
<magic>
<match value="SQLite format 3" type="string" offset="0"/>
</magic>
+ <alias type="application/x-sqlite3"/>
</mime-type>
<mime-type type="application/x-gedcom">
<comment>GEDCOM family history</comment>
@@ -2189,7 +2293,7 @@
<comment xml:lang="ja">GEDCOM 家系図データ</comment>
<comment xml:lang="ka">GEDCOM ოჯახის ისტორია</comment>
<comment xml:lang="kk">GEDCOM отбасы тарихы</comment>
- <comment xml:lang="ko">GEDCOM 가족 내력</comment>
+ <comment xml:lang="ko">GEDCOM 패밀리 기록</comment>
<comment xml:lang="lt">GEDCOM šeimos istorija</comment>
<comment xml:lang="lv">GEDCOM ģimenes vēsture</comment>
<comment xml:lang="nb">GEDCOM-familiehistorikk</comment>
@@ -2200,7 +2304,7 @@
<comment xml:lang="pt">história familiar GEDCOM</comment>
<comment xml:lang="pt_BR">Histórico familiar do GEDCOM</comment>
<comment xml:lang="ro">Tablou genealogic GEDCOM</comment>
- <comment xml:lang="ru">история семьи GEDCOM</comment>
+ <comment xml:lang="ru">История семьи GEDCOM</comment>
<comment xml:lang="sk">Rodokmeň GEDCOM</comment>
<comment xml:lang="sl">Datoteka družinske zgodovine GEDCOM</comment>
<comment xml:lang="sq">Kronollogji familje GEDCOM</comment>
@@ -2224,6 +2328,7 @@
<mime-type type="video/x-flv">
<comment>Flash video</comment>
<comment xml:lang="ar">Flash مرئي</comment>
+ <comment xml:lang="ast">Videu en Flash</comment>
<comment xml:lang="be@latin">Videa Flash</comment>
<comment xml:lang="bg">Видео — Flash</comment>
<comment xml:lang="ca">vídeo de Flash</comment>
@@ -2241,7 +2346,7 @@
<comment xml:lang="ga">físeán Flash</comment>
<comment xml:lang="gl">vídeo Flash</comment>
<comment xml:lang="he">וידאו של פלאש</comment>
- <comment xml:lang="hr">Flash video</comment>
+ <comment xml:lang="hr">Flash video snimka</comment>
<comment xml:lang="hu">Flash videó</comment>
<comment xml:lang="ia">Video Flash</comment>
<comment xml:lang="id">Video Flash</comment>
@@ -2260,7 +2365,7 @@
<comment xml:lang="pt">vídeo Flash</comment>
<comment xml:lang="pt_BR">Vídeo Flash</comment>
<comment xml:lang="ro">Video Flash</comment>
- <comment xml:lang="ru">видео Flash</comment>
+ <comment xml:lang="ru">Видео Flash</comment>
<comment xml:lang="sk">Video Flash</comment>
<comment xml:lang="sl">Video datoteka Flash</comment>
<comment xml:lang="sq">Video Flash</comment>
@@ -2269,7 +2374,7 @@
<comment xml:lang="tr">Flash video</comment>
<comment xml:lang="uk">відеокліп Flash</comment>
<comment xml:lang="vi">Ảnh động Flash</comment>
- <comment xml:lang="zh_CN">Flash 影片</comment>
+ <comment xml:lang="zh_CN">Flash 视频</comment>
<comment xml:lang="zh_TW">Flash 視訊</comment>
<generic-icon name="video-x-generic"/>
<magic priority="50">
@@ -2282,6 +2387,7 @@
</mime-type>
<mime-type type="video/x-javafx">
<comment>JavaFX video</comment>
+ <comment xml:lang="ast">Videu en JavaFX</comment>
<comment xml:lang="bg">Видео — JavaFX</comment>
<comment xml:lang="ca">vídeo de JavaFX</comment>
<comment xml:lang="cs">video JavaFX</comment>
@@ -2298,7 +2404,7 @@
<comment xml:lang="ga">físeán JavaFX</comment>
<comment xml:lang="gl">vídeo JavaFX</comment>
<comment xml:lang="he">וידאו JavaFX</comment>
- <comment xml:lang="hr">JavaFX video</comment>
+ <comment xml:lang="hr">JavaFX video snimka</comment>
<comment xml:lang="hu">JavaFX videó</comment>
<comment xml:lang="ia">Video JavaFX</comment>
<comment xml:lang="id">Video JavaFX</comment>
@@ -2313,7 +2419,7 @@
<comment xml:lang="pt">vídeo JavaFX</comment>
<comment xml:lang="pt_BR">Vídeo JavaFX</comment>
<comment xml:lang="ro">Video JavaFX</comment>
- <comment xml:lang="ru">видео JavaFX</comment>
+ <comment xml:lang="ru">Видео JavaFX</comment>
<comment xml:lang="sk">Video JavaFX</comment>
<comment xml:lang="sl">Video JavaFX</comment>
<comment xml:lang="sr">ЈаваФИкс видео</comment>
@@ -2367,7 +2473,7 @@
<comment xml:lang="pt">gravação SGF</comment>
<comment xml:lang="pt_BR">Gravação SGF</comment>
<comment xml:lang="ro">Înregistrare SGF</comment>
- <comment xml:lang="ru">запись SGF</comment>
+ <comment xml:lang="ru">Запись SGF</comment>
<comment xml:lang="sk">Záznam SGF</comment>
<comment xml:lang="sl">Datoteka shranjene igre SGF</comment>
<comment xml:lang="sq">Regjistrim SGF</comment>
@@ -2388,9 +2494,10 @@
<match value="(;FF[4]" type="string" offset="0"/>
</magic>
</mime-type>
- <mime-type type="application/x-xliff">
+ <mime-type type="application/xliff+xml">
<comment>XLIFF translation file</comment>
<comment xml:lang="ar">ملف ترجمة XLIFF</comment>
+ <comment xml:lang="ast">Ficheru de traducciones XLIFF</comment>
<comment xml:lang="be@latin">Fajł pierakładu XLIFF</comment>
<comment xml:lang="bg">Превод — XLIFF</comment>
<comment xml:lang="ca">fitxer de traducció XLIFF</comment>
@@ -2404,7 +2511,7 @@
<comment xml:lang="fi">XLIFF-käännöstiedosto</comment>
<comment xml:lang="fo">XLIFF týðingarfíla</comment>
<comment xml:lang="fr">fichier de traduction XLIFF</comment>
- <comment xml:lang="ga">comhad aistrithe XLIFF</comment>
+ <comment xml:lang="ga">comhad aistriúcháin XLIFF</comment>
<comment xml:lang="gl">ficheiro de tradución XLIFF</comment>
<comment xml:lang="he">קובץ תרגום CLIFF</comment>
<comment xml:lang="hr">XLIFF datoteka prijevoda</comment>
@@ -2425,7 +2532,7 @@
<comment xml:lang="pt">ficheiro de tradução XLIFF</comment>
<comment xml:lang="pt_BR">Arquivo de tradução XLIFF</comment>
<comment xml:lang="ro">Fișier de traducere XLIFF</comment>
- <comment xml:lang="ru">файл перевода XLIFF</comment>
+ <comment xml:lang="ru">Файл перевода XLIFF</comment>
<comment xml:lang="sk">Súbor prekladu XLIFF</comment>
<comment xml:lang="sl">Datoteka prevoda XLIFF</comment>
<comment xml:lang="sq">File përkthimesh XLIFF</comment>
@@ -2434,7 +2541,7 @@
<comment xml:lang="tr">XLIFF çeviri dosyası</comment>
<comment xml:lang="uk">файл перекладу XLIFF</comment>
<comment xml:lang="vi">Tập tin dịch XLIFF</comment>
- <comment xml:lang="zh_CN">XLIFF 消息翻译文件</comment>
+ <comment xml:lang="zh_CN">XLIFF 翻译文件</comment>
<comment xml:lang="zh_TW">XLIFF 翻譯檔</comment>
<acronym>XLIFF</acronym>
<expanded-acronym>XML Localization Interchange File Format</expanded-acronym>
@@ -2446,10 +2553,12 @@
<match value="&lt;xliff" type="string" offset="0:256"/>
</magic>
<root-XML namespaceURI='urn:oasis:names:tc:xliff:document:1.1' localName='xliff'/>
+ <alias type="application/x-xliff"/>
</mime-type>
<mime-type type="application/x-yaml">
<comment>YAML document</comment>
<comment xml:lang="ar">مستند YAML</comment>
+ <comment xml:lang="ast">Documentu YAML</comment>
<comment xml:lang="bg">Документ — YAML</comment>
<comment xml:lang="ca">document YAML</comment>
<comment xml:lang="cs">dokument YAML</comment>
@@ -2482,7 +2591,7 @@
<comment xml:lang="pt">documento YAML</comment>
<comment xml:lang="pt_BR">Documento YAML</comment>
<comment xml:lang="ro">Document YAML</comment>
- <comment xml:lang="ru">документ YAML</comment>
+ <comment xml:lang="ru">Документ YAML</comment>
<comment xml:lang="sk">Dokument YAML</comment>
<comment xml:lang="sl">Dokument YAML</comment>
<comment xml:lang="sr">ЈАМЛ документ</comment>
@@ -2506,6 +2615,7 @@
<mime-type type="application/vnd.corel-draw">
<comment>Corel Draw drawing</comment>
<comment xml:lang="ar">تصميم Corel Draw</comment>
+ <comment xml:lang="ast">Dibuxu de Corel Draw</comment>
<comment xml:lang="az">Corel Draw çəkimi</comment>
<comment xml:lang="be@latin">Rysunak Corel Draw</comment>
<comment xml:lang="bg">Чертеж — Corel Draw</comment>
@@ -2533,7 +2643,7 @@
<comment xml:lang="ja">Corel Draw ドロー</comment>
<comment xml:lang="ka">Corel Draw-ის ნახაზი</comment>
<comment xml:lang="kk">Corel Draw суреті</comment>
- <comment xml:lang="ko">Corel Draw 드로잉</comment>
+ <comment xml:lang="ko">코렐 드로우 드로잉</comment>
<comment xml:lang="lt">Corel Draw piešinys</comment>
<comment xml:lang="lv">Corel Draw zīmējums</comment>
<comment xml:lang="ms">Lukisan Corel Draw</comment>
@@ -2545,16 +2655,16 @@
<comment xml:lang="pt">desenho Corel Drawdesenho Corel Draw</comment>
<comment xml:lang="pt_BR">Desenho do Corel Draw</comment>
<comment xml:lang="ro">Desen Corel Draw</comment>
- <comment xml:lang="ru">изображение Corel Draw</comment>
+ <comment xml:lang="ru">Рисунок Corel Draw</comment>
<comment xml:lang="sk">Kresba Corel Draw</comment>
<comment xml:lang="sl">Datoteka risbe Corel Draw</comment>
<comment xml:lang="sq">Vizatim Corel Draw</comment>
- <comment xml:lang="sr">Корел Дров цртеж</comment>
+ <comment xml:lang="sr">Корелов цртеж</comment>
<comment xml:lang="sv">Corel Draw-teckning</comment>
<comment xml:lang="tr">Corel Draw çizimi</comment>
<comment xml:lang="uk">малюнок Corel Draw</comment>
<comment xml:lang="vi">Bản vẽ Corel Draw</comment>
- <comment xml:lang="zh_CN">Corel Draw 图形</comment>
+ <comment xml:lang="zh_CN">Corel Draw 绘图</comment>
<comment xml:lang="zh_TW">Corel Draw 繪圖</comment>
<generic-icon name="image-x-generic"/>
<magic priority="80">
@@ -2572,6 +2682,7 @@
<mime-type type="application/vnd.hp-hpgl">
<comment>HPGL file</comment>
<comment xml:lang="ar">ملف HPGL</comment>
+ <comment xml:lang="ast">Ficheru HPGL</comment>
<comment xml:lang="be@latin">Fajł HPGL</comment>
<comment xml:lang="bg">Файл — HPGL</comment>
<comment xml:lang="ca">fitxer HPGL</comment>
@@ -2607,7 +2718,7 @@
<comment xml:lang="pt">ficheiro HPGL</comment>
<comment xml:lang="pt_BR">Arquivo HPGL</comment>
<comment xml:lang="ro">Fișier HPGL</comment>
- <comment xml:lang="ru">файл HPGL</comment>
+ <comment xml:lang="ru">Файл HPGL</comment>
<comment xml:lang="sk">Súbor HPGL</comment>
<comment xml:lang="sl">Datoteka HPGL</comment>
<comment xml:lang="sq">File HPGL</comment>
@@ -2626,6 +2737,7 @@
<mime-type type="application/vnd.hp-pcl">
<comment>PCL file</comment>
<comment xml:lang="ar">ملف PCL</comment>
+ <comment xml:lang="ast">FIcheru PCL</comment>
<comment xml:lang="be@latin">Fajł PCL</comment>
<comment xml:lang="bg">Файл — PCL</comment>
<comment xml:lang="ca">fitxer PCL</comment>
@@ -2661,7 +2773,7 @@
<comment xml:lang="pt">ficheiro PCL</comment>
<comment xml:lang="pt_BR">Arquivo PCL</comment>
<comment xml:lang="ro">Fișier PCL</comment>
- <comment xml:lang="ru">файл PCL</comment>
+ <comment xml:lang="ru">Файл PCL</comment>
<comment xml:lang="sk">Súbor PCL</comment>
<comment xml:lang="sl">Datoteka PCL</comment>
<comment xml:lang="sq">File PCL</comment>
@@ -2680,6 +2792,7 @@
<mime-type type="application/vnd.lotus-1-2-3">
<comment>Lotus 1-2-3 spreadsheet</comment>
<comment xml:lang="ar">جدول Lotus 1-2-3</comment>
+ <comment xml:lang="ast">Fueya de cálculu de Lotus 1-2-3</comment>
<comment xml:lang="az">Lotus 1-2-3 hesab cədvəli</comment>
<comment xml:lang="be@latin">Raźlikovy arkuš Lotus 1-2-3</comment>
<comment xml:lang="bg">Таблица — Lotus 1-2-3</comment>
@@ -2718,7 +2831,7 @@
<comment xml:lang="pt">folha de cálculo Lotus 1-2-3</comment>
<comment xml:lang="pt_BR">Planilha do Lotus 1-2-3</comment>
<comment xml:lang="ro">Foaie de calcul Lotus 1-2-3</comment>
- <comment xml:lang="ru">электронная таблица Lotus 1-2-3</comment>
+ <comment xml:lang="ru">Электронная таблица Lotus 1-2-3</comment>
<comment xml:lang="sk">Zošit Lotus 1-2-3</comment>
<comment xml:lang="sl">Preglednica Lotus 1-2-3</comment>
<comment xml:lang="sq">Fletë llogaritjesh Lotus 1-2-3</comment>
@@ -2727,7 +2840,7 @@
<comment xml:lang="tr">Lotus 1-2-3 hesap tablosu</comment>
<comment xml:lang="uk">ел. таблиця Lotus 1-2-3</comment>
<comment xml:lang="vi">Bảng tính Lotus 1-2-3</comment>
- <comment xml:lang="zh_CN">Lotus 1-2-3 工作簿</comment>
+ <comment xml:lang="zh_CN">Lotus 1-2-3 电子表格</comment>
<comment xml:lang="zh_TW">Lotus 1-2-3 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<magic priority="50">
@@ -2746,6 +2859,7 @@
</mime-type>
<mime-type type="application/vnd.lotus-wordpro">
<comment>Lotus Word Pro</comment>
+ <comment xml:lang="ast">Lotus Word Pro</comment>
<comment xml:lang="ca">Lotus Word Pro</comment>
<comment xml:lang="cs">Lotus Word Pro</comment>
<comment xml:lang="da">Lotus Word Pro</comment>
@@ -2756,6 +2870,7 @@
<comment xml:lang="eu">Lotus Word Pro</comment>
<comment xml:lang="fi">Lotus Word Pro</comment>
<comment xml:lang="fr">Lotus Word Pro</comment>
+ <comment xml:lang="ga">Lotus Word Pro</comment>
<comment xml:lang="gl">Lotus Word Pro</comment>
<comment xml:lang="he">Lotus Word Pro</comment>
<comment xml:lang="hr">Lotus Word Pro</comment>
@@ -2789,6 +2904,7 @@
<mime-type type="application/vnd.ms-access">
<comment>JET database</comment>
<comment xml:lang="ar">قاعدة بيانات JET</comment>
+ <comment xml:lang="ast">Base de datos JETº</comment>
<comment xml:lang="be@latin">Baza źviestak JET</comment>
<comment xml:lang="bg">База от данни — JET</comment>
<comment xml:lang="ca">base de dades JET</comment>
@@ -2824,7 +2940,7 @@
<comment xml:lang="pt">base de dados JET</comment>
<comment xml:lang="pt_BR">Banco de dados JET</comment>
<comment xml:lang="ro">Bază de date JET</comment>
- <comment xml:lang="ru">база данных JET</comment>
+ <comment xml:lang="ru">База данных JET</comment>
<comment xml:lang="sk">Databáza JET</comment>
<comment xml:lang="sl">Podatkovna zbirka JET</comment>
<comment xml:lang="sq">Bazë me të dhëna JET</comment>
@@ -2885,7 +3001,7 @@
<comment xml:lang="pt">arquivo Microsoft Cabinet</comment>
<comment xml:lang="pt_BR">Pacote Cabinet da Microsoft</comment>
<comment xml:lang="ro">Arhivă Microsoft Cabinet</comment>
- <comment xml:lang="ru">архив Microsoft Cabinet</comment>
+ <comment xml:lang="ru">Архив Microsoft Cabinet</comment>
<comment xml:lang="sk">Archív Microsoft Cabinet</comment>
<comment xml:lang="sl">Datoteka arhiva Microsoft Cabinet</comment>
<comment xml:lang="sr">Мајкрософтова кабинет архива</comment>
@@ -2893,7 +3009,7 @@
<comment xml:lang="tr">Microsoft Cabinet arşivi</comment>
<comment xml:lang="uk">архів Cabinet Microsoft</comment>
<comment xml:lang="vi">Kho lưu Cabinet Microsoft</comment>
- <comment xml:lang="zh_CN">Microsoft CAB 归档文件</comment>
+ <comment xml:lang="zh_CN">Microsoft Cabinet 归档文件</comment>
<comment xml:lang="zh_TW">微軟 Cabinet 封存檔</comment>
<generic-icon name="package-x-generic"/>
<magic priority="60">
@@ -2941,7 +3057,7 @@
<comment xml:lang="pt">folha de cálculo Excel</comment>
<comment xml:lang="pt_BR">Planilha do Excel</comment>
<comment xml:lang="ro">Foaie de calcul Excel</comment>
- <comment xml:lang="ru">электронная таблица Excel</comment>
+ <comment xml:lang="ru">Электронная таблица Excel</comment>
<comment xml:lang="sk">Zošit Excel</comment>
<comment xml:lang="sl">Razpredelnica Microsoft Excel</comment>
<comment xml:lang="sq">Fletë llogaritje Excel</comment>
@@ -2950,7 +3066,7 @@
<comment xml:lang="tr">Excel çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця Excel</comment>
<comment xml:lang="vi">Bảng tính Excel</comment>
- <comment xml:lang="zh_CN">Microsoft Excel 工作簿</comment>
+ <comment xml:lang="zh_CN">Excel 电子表格</comment>
<comment xml:lang="zh_TW">Excel 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<magic priority="50">
@@ -2981,9 +3097,10 @@
<comment xml:lang="eu">Excel gehigarria</comment>
<comment xml:lang="fi">Excel-lisäosa</comment>
<comment xml:lang="fr">complément Excel</comment>
+ <comment xml:lang="ga">breiseán Excel</comment>
<comment xml:lang="gl">complemento de Excel</comment>
<comment xml:lang="he">תוסף של Excel</comment>
- <comment xml:lang="hr">Excel priključak</comment>
+ <comment xml:lang="hr">Excel dodatak</comment>
<comment xml:lang="hu">Excel bővítmény</comment>
<comment xml:lang="ia">Add-in Excel</comment>
<comment xml:lang="id">Add-in Excel</comment>
@@ -2998,14 +3115,14 @@
<comment xml:lang="pl">Dodatek Excel</comment>
<comment xml:lang="pt">Extensão Excel</comment>
<comment xml:lang="pt_BR">Suplemento do Excel</comment>
- <comment xml:lang="ru">дополнение Excel</comment>
+ <comment xml:lang="ru">Дополнение Excel</comment>
<comment xml:lang="sk">Doplnok aplikácie Excel</comment>
<comment xml:lang="sl">Vstavek Excel</comment>
<comment xml:lang="sr">Екселов додатак</comment>
<comment xml:lang="sv">Excel-tillägg</comment>
<comment xml:lang="tr">Excel eklentisi</comment>
<comment xml:lang="uk">додаток Excel</comment>
- <comment xml:lang="zh_CN">Excel 附加组件</comment>
+ <comment xml:lang="zh_CN">Excel 外接程序</comment>
<comment xml:lang="zh_TW">Excel 增益集</comment>
<generic-icon name="x-office-spreadsheet"/>
<glob pattern="*.xlam"/>
@@ -3024,6 +3141,7 @@
<comment xml:lang="eu">Excel 2007 kalkulu-orri binarioa</comment>
<comment xml:lang="fi">Excel 2007:n binaarinen taulukko</comment>
<comment xml:lang="fr">feuille de calcul binaire Excel 2007</comment>
+ <comment xml:lang="ga">scarbhileog dhénártha Excel 2007</comment>
<comment xml:lang="gl">ficheiro binario de folla de cálculo Excel 2007</comment>
<comment xml:lang="he">גיליון נתונים בינרי של Excel 2007</comment>
<comment xml:lang="hr">Excel 2007 binarna proračunska tablica</comment>
@@ -3041,14 +3159,14 @@
<comment xml:lang="pl">Binarny arkusz Excel 2007</comment>
<comment xml:lang="pt">folha de cálculo binária Excel 2007</comment>
<comment xml:lang="pt_BR">Planilha binária do Excel 2007</comment>
- <comment xml:lang="ru">двоичная электронная таблица Excel 2007</comment>
+ <comment xml:lang="ru">Двоичная электронная таблица Excel 2007</comment>
<comment xml:lang="sk">Binárny zošit Excel 2007</comment>
<comment xml:lang="sl">Binarna preglednica Excel 2007</comment>
<comment xml:lang="sr">Ексел 2007 бинарна табела</comment>
<comment xml:lang="sv">Binärt Excel 2007-kalkylblad</comment>
<comment xml:lang="tr">Excel 2007 ikilik çalışma sayfası</comment>
<comment xml:lang="uk">бінарна електронна таблиця Excel 2007</comment>
- <comment xml:lang="zh_CN">Excel 2007 二进制工作表</comment>
+ <comment xml:lang="zh_CN">Excel 2007 二进制电子表格</comment>
<comment xml:lang="zh_TW">Excel 2007 二進位試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<glob pattern="*.xlsb"/>
@@ -3093,7 +3211,7 @@
<comment xml:lang="pt">folha de cálculo Excel</comment>
<comment xml:lang="pt_BR">Planilha do Excel</comment>
<comment xml:lang="ro">Foaie de calcul Excel</comment>
- <comment xml:lang="ru">электронная таблица Excel</comment>
+ <comment xml:lang="ru">Электронная таблица Excel</comment>
<comment xml:lang="sk">Zošit Excel</comment>
<comment xml:lang="sl">Razpredelnica Microsoft Excel</comment>
<comment xml:lang="sq">Fletë llogaritje Excel</comment>
@@ -3102,7 +3220,7 @@
<comment xml:lang="tr">Excel çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця Excel</comment>
<comment xml:lang="vi">Bảng tính Excel</comment>
- <comment xml:lang="zh_CN">Microsoft Excel 工作簿</comment>
+ <comment xml:lang="zh_CN">Excel 电子表格</comment>
<comment xml:lang="zh_TW">Excel 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<glob pattern="*.xlsm"/>
@@ -3120,6 +3238,7 @@
<comment xml:lang="eu">Excel kalkulu-orri txantiloia</comment>
<comment xml:lang="fi">Excel-taulukkomalli</comment>
<comment xml:lang="fr">modèle de feuille de calcul Excel</comment>
+ <comment xml:lang="ga">teimpléad scarbhileoige Excel</comment>
<comment xml:lang="he">תבנית גיליון נתונים של Excel</comment>
<comment xml:lang="hr">Predložak Excel proračunske tablice</comment>
<comment xml:lang="hu">Excel munkafüzetsablon</comment>
@@ -3127,18 +3246,18 @@
<comment xml:lang="id">Templat lembar kerja Excel</comment>
<comment xml:lang="it">Modello foglio di calcolo Excel</comment>
<comment xml:lang="kk">Excel кестесінің үлгісі</comment>
- <comment xml:lang="ko">액셀 스프레드시트 양식</comment>
+ <comment xml:lang="ko">Excel 스프레드시트 서식</comment>
<comment xml:lang="oc">Modèl de fuèlh de calcul Excel</comment>
<comment xml:lang="pl">Szablon arkusza Excel</comment>
<comment xml:lang="pt">modelo de folha de cálculo Excel</comment>
<comment xml:lang="pt_BR">Modelo de planilha do Excel</comment>
- <comment xml:lang="ru">шаблон таблицы Excel</comment>
+ <comment xml:lang="ru">Шаблон таблицы Excel</comment>
<comment xml:lang="sk">Šablóna tabuľky aplikácie Excel</comment>
- <comment xml:lang="sr">Шаблон табеле Ексела</comment>
+ <comment xml:lang="sr">Екселов шаблон табеле</comment>
<comment xml:lang="sv">Excel-kalkylarksmall</comment>
<comment xml:lang="tr">Excel hesap tablosu şablonu</comment>
<comment xml:lang="uk">шаблон електронної таблиці Excel</comment>
- <comment xml:lang="zh_CN">Microsoft Excel 工作簿模板</comment>
+ <comment xml:lang="zh_CN">Excel 电子表格模板</comment>
<comment xml:lang="zh_TW">Excel 試算表範本</comment>
<generic-icon name="x-office-spreadsheet"/>
<glob pattern="*.xltm"/>
@@ -3182,16 +3301,16 @@
<comment xml:lang="pt">apresentação PowerPoint</comment>
<comment xml:lang="pt_BR">Apresentação do PowerPoint</comment>
<comment xml:lang="ro">Prezentare PowerPoint</comment>
- <comment xml:lang="ru">презентация PowerPoint</comment>
+ <comment xml:lang="ru">Презентация PowerPoint</comment>
<comment xml:lang="sk">Prezentácia PowerPoint</comment>
<comment xml:lang="sl">Predstavitev Microsoft PowerPoint</comment>
<comment xml:lang="sq">Prezantim PowerPoint</comment>
- <comment xml:lang="sr">Пауер Поинт презентација</comment>
+ <comment xml:lang="sr">Пауер поинт презентација</comment>
<comment xml:lang="sv">PowerPoint-presentation</comment>
<comment xml:lang="tr">PowerPoint sunumu</comment>
<comment xml:lang="uk">презентація PowerPoint</comment>
<comment xml:lang="vi">Trình diễn PowerPoint</comment>
- <comment xml:lang="zh_CN">Microsoft PowerPoint 演示文稿</comment>
+ <comment xml:lang="zh_CN">PowerPoint 演示文稿</comment>
<comment xml:lang="zh_TW">PowerPoint 簡報</comment>
<generic-icon name="x-office-presentation"/>
<glob pattern="*.ppz"/>
@@ -3215,9 +3334,10 @@
<comment xml:lang="eu">PowerPoint gehigarria</comment>
<comment xml:lang="fi">PowerPoint-lisäosa</comment>
<comment xml:lang="fr">complément PowerPoint</comment>
+ <comment xml:lang="ga">breiseán PowerPoint</comment>
<comment xml:lang="gl">complemento de PowerPoint</comment>
<comment xml:lang="he">תוסף של PowerPoint</comment>
- <comment xml:lang="hr">PowerPoint priključak</comment>
+ <comment xml:lang="hr">PowerPoint dodatak</comment>
<comment xml:lang="hu">PowerPoint bővítmény</comment>
<comment xml:lang="ia">Add-in PowerPoint</comment>
<comment xml:lang="id">Add-in PowerPoint</comment>
@@ -3232,14 +3352,14 @@
<comment xml:lang="pl">Dodatek PowerPoint</comment>
<comment xml:lang="pt">extensão PowerPoint</comment>
<comment xml:lang="pt_BR">Suplemento do PowerPoint</comment>
- <comment xml:lang="ru">дополнение PowerPoint</comment>
+ <comment xml:lang="ru">Дополнение PowerPoint</comment>
<comment xml:lang="sk">Doplnok aplikácie PowerPoint </comment>
<comment xml:lang="sl">Vstavek PowerPoint</comment>
- <comment xml:lang="sr">Пауер Поинт додатак</comment>
+ <comment xml:lang="sr">Пауер поинт додатак</comment>
<comment xml:lang="sv">PowerPoint-tillägg</comment>
<comment xml:lang="tr">PowerPoint eklentisi</comment>
<comment xml:lang="uk">додаток PowerPoint</comment>
- <comment xml:lang="zh_CN">PowerPoint 附加组件</comment>
+ <comment xml:lang="zh_CN">PowerPoint 外接程序</comment>
<comment xml:lang="zh_TW">PowerPoint 增益集</comment>
<generic-icon name="x-office-presentation"/>
<glob pattern="*.ppam"/>
@@ -3282,16 +3402,16 @@
<comment xml:lang="pt">apresentação PowerPoint</comment>
<comment xml:lang="pt_BR">Apresentação do PowerPoint</comment>
<comment xml:lang="ro">Prezentare PowerPoint</comment>
- <comment xml:lang="ru">презентация PowerPoint</comment>
+ <comment xml:lang="ru">Презентация PowerPoint</comment>
<comment xml:lang="sk">Prezentácia PowerPoint</comment>
<comment xml:lang="sl">Predstavitev Microsoft PowerPoint</comment>
<comment xml:lang="sq">Prezantim PowerPoint</comment>
- <comment xml:lang="sr">Пауер Поинт презентација</comment>
+ <comment xml:lang="sr">Пауер поинт презентација</comment>
<comment xml:lang="sv">PowerPoint-presentation</comment>
<comment xml:lang="tr">PowerPoint sunumu</comment>
<comment xml:lang="uk">презентація PowerPoint</comment>
<comment xml:lang="vi">Trình diễn PowerPoint</comment>
- <comment xml:lang="zh_CN">Microsoft PowerPoint 演示文稿</comment>
+ <comment xml:lang="zh_CN">PowerPoint 演示文稿</comment>
<comment xml:lang="zh_TW">PowerPoint 簡報</comment>
<generic-icon name="x-office-presentation"/>
<glob pattern="*.pptm"/>
@@ -3299,6 +3419,7 @@
</mime-type>
<mime-type type="application/vnd.ms-powerpoint.slide.macroEnabled.12">
<comment>PowerPoint slide</comment>
+ <comment xml:lang="ast">Diapositiva de PowerPoint</comment>
<comment xml:lang="ca">dispositiva de PowerPoint</comment>
<comment xml:lang="cs">promítání PowerPoint</comment>
<comment xml:lang="da">PowerPoint-dias</comment>
@@ -3309,6 +3430,7 @@
<comment xml:lang="eu">PowerPoint diapositiba</comment>
<comment xml:lang="fi">PowerPoint-dia</comment>
<comment xml:lang="fr">diapositive PowerPoint</comment>
+ <comment xml:lang="ga">sleamhnán PowerPoint</comment>
<comment xml:lang="he">שקופית של PowerPoint</comment>
<comment xml:lang="hr">PowerPoint prezentacija</comment>
<comment xml:lang="hu">PowerPoint dia</comment>
@@ -3321,13 +3443,13 @@
<comment xml:lang="pl">Slajd PowerPoint</comment>
<comment xml:lang="pt">diapositivo PowerPoint</comment>
<comment xml:lang="pt_BR">Slide do PowerPoint</comment>
- <comment xml:lang="ru">слайд PowerPoint</comment>
+ <comment xml:lang="ru">Слайд PowerPoint</comment>
<comment xml:lang="sk">Snímka aplikácie PowerPoint</comment>
- <comment xml:lang="sr">Слајд Пауер Поинта</comment>
+ <comment xml:lang="sr">Пауер поинт слајд</comment>
<comment xml:lang="sv">PowerPoint-bildspel</comment>
<comment xml:lang="tr">PowerPoint sunusu</comment>
<comment xml:lang="uk">слайд PowerPoint</comment>
- <comment xml:lang="zh_CN">PowerPoint 文稿</comment>
+ <comment xml:lang="zh_CN">PowerPoint 幻灯片</comment>
<comment xml:lang="zh_TW">PowerPoint 投影片</comment>
<generic-icon name="x-office-presentation"/>
<glob pattern="*.sldm"/>
@@ -3371,16 +3493,16 @@
<comment xml:lang="pt">apresentação PowerPoint</comment>
<comment xml:lang="pt_BR">Apresentação do PowerPoint</comment>
<comment xml:lang="ro">Prezentare PowerPoint</comment>
- <comment xml:lang="ru">презентация PowerPoint</comment>
+ <comment xml:lang="ru">Презентация PowerPoint</comment>
<comment xml:lang="sk">Prezentácia PowerPoint</comment>
<comment xml:lang="sl">Predstavitev Microsoft PowerPoint</comment>
<comment xml:lang="sq">Prezantim PowerPoint</comment>
- <comment xml:lang="sr">Пауер Поинт презентација</comment>
+ <comment xml:lang="sr">Пауер поинт презентација</comment>
<comment xml:lang="sv">PowerPoint-presentation</comment>
<comment xml:lang="tr">PowerPoint sunumu</comment>
<comment xml:lang="uk">презентація PowerPoint</comment>
<comment xml:lang="vi">Trình diễn PowerPoint</comment>
- <comment xml:lang="zh_CN">Microsoft PowerPoint 演示文稿</comment>
+ <comment xml:lang="zh_CN">PowerPoint 演示文稿</comment>
<comment xml:lang="zh_TW">PowerPoint 簡報</comment>
<generic-icon name="x-office-presentation"/>
<glob pattern="*.ppsm"/>
@@ -3388,6 +3510,7 @@
</mime-type>
<mime-type type="application/vnd.ms-powerpoint.template.macroEnabled.12">
<comment>PowerPoint presentation template</comment>
+ <comment xml:lang="ast">Plantía de presentaciones de PowerPoint</comment>
<comment xml:lang="ca">plantilla de presentació de PowerPoint</comment>
<comment xml:lang="cs">šablona prezentace PowerPoint</comment>
<comment xml:lang="da">PowerPoint-præsentationsskabelon</comment>
@@ -3398,6 +3521,7 @@
<comment xml:lang="eu">PowerPoint aurkezpen txantiloia</comment>
<comment xml:lang="fi">PowerPoint-esitysmalli</comment>
<comment xml:lang="fr">modèle de présentation PowerPoint</comment>
+ <comment xml:lang="ga">teimpléad láithreoireachta PowerPoint</comment>
<comment xml:lang="he">תבנית מצגת PowerPoint</comment>
<comment xml:lang="hr">Predložak PowerPoint prezentacije</comment>
<comment xml:lang="hu">PowerPoint bemutatósablon</comment>
@@ -3405,18 +3529,18 @@
<comment xml:lang="id">Templat presentasi PowerPoint</comment>
<comment xml:lang="it">Modello presentazione PowerPoint</comment>
<comment xml:lang="kk">PowerPoint презентация үлгісі</comment>
- <comment xml:lang="ko">파워포인드 프리젠테이션 양식</comment>
+ <comment xml:lang="ko">PowerPoint 프리젠테이션 서식</comment>
<comment xml:lang="oc">Modèl de presentacion PowerPoint</comment>
<comment xml:lang="pl">Szablon prezentacji PowerPoint</comment>
<comment xml:lang="pt">modelo de apresentação PowerPoint</comment>
<comment xml:lang="pt_BR">Modelo de apresentação do PowerPoint</comment>
- <comment xml:lang="ru">шаблон презентации PowerPoint</comment>
+ <comment xml:lang="ru">Шаблон презентации PowerPoint</comment>
<comment xml:lang="sk">Šablóna prezentácie aplikácie PowerPoint</comment>
- <comment xml:lang="sr">Шаблон презентације Пауер Поинта</comment>
+ <comment xml:lang="sr">Шаблон презентације Пауер поинта</comment>
<comment xml:lang="sv">PowerPoint-presentationsmall</comment>
<comment xml:lang="tr">PowerPoint sunum şablonu</comment>
<comment xml:lang="uk">шаблон презентації PowerPoint</comment>
- <comment xml:lang="zh_CN">Microsoft PowerPoint 演示文稿模板</comment>
+ <comment xml:lang="zh_CN">PowerPoint 演示文稿模板</comment>
<comment xml:lang="zh_TW">PowerPoint 簡報範本</comment>
<generic-icon name="x-office-presentation"/>
<glob pattern="*.potm"/>
@@ -3434,6 +3558,7 @@
<comment xml:lang="eu">Office Open XML Visio marrazkia</comment>
<comment xml:lang="fi">Office Open XML Visio -piirros</comment>
<comment xml:lang="fr">dessin Visio Office Open XML</comment>
+ <comment xml:lang="ga">Líníocht Office Open XML Visio</comment>
<comment xml:lang="he">ציור Visio ב־Open XML מבית Office</comment>
<comment xml:lang="hr">Office Open XML Visio crtež</comment>
<comment xml:lang="hu">Office Open XML Visio rajz</comment>
@@ -3445,13 +3570,13 @@
<comment xml:lang="pl">Rysunek Office Open XML Visio</comment>
<comment xml:lang="pt">desenho Office Open XML Visio</comment>
<comment xml:lang="pt_BR">Desenho do Visio em Office Open XML</comment>
- <comment xml:lang="ru">схема Visio формата Office Open XML</comment>
+ <comment xml:lang="ru">Рисунок Visio формата Office Open XML</comment>
<comment xml:lang="sk">Kresba aplikácie Visio Office Open XML</comment>
- <comment xml:lang="sr">Офис опен ИксМЛ Визио цртање</comment>
+ <comment xml:lang="sr">Офисов отворени ИксМЛ Визио цртеж</comment>
<comment xml:lang="sv">Office Open XML Visio-teckning</comment>
<comment xml:lang="tr">Office Open XML Visio Çizimi</comment>
<comment xml:lang="uk">схема VIisio у форматі Office Open XML</comment>
- <comment xml:lang="zh_CN">OOXML Visio 绘图</comment>
+ <comment xml:lang="zh_CN">Office Open XML Visio 绘图</comment>
<comment xml:lang="zh_TW">Office Open XML Visio 繪圖</comment>
<generic-icon name="image-x-generic"/>
<glob pattern="*.vsdx"/>
@@ -3469,6 +3594,7 @@
<comment xml:lang="eu">Office Open XML Visio txantiloia</comment>
<comment xml:lang="fi">Office Open XML Visio -malli</comment>
<comment xml:lang="fr">modèle Visio Office Open XML</comment>
+ <comment xml:lang="ga">Teimpléad Office Open XML Visio</comment>
<comment xml:lang="he">תבנית Visio ב־Open XML מבית Office</comment>
<comment xml:lang="hr">Predložak Office Open XML Visio</comment>
<comment xml:lang="hu">Office Open XML Visio sablon</comment>
@@ -3476,17 +3602,17 @@
<comment xml:lang="id">Templat Visio Office Open XML</comment>
<comment xml:lang="it">Modello Visio Office Open XML</comment>
<comment xml:lang="kk">Office Open XML Visio үлгісі</comment>
- <comment xml:lang="ko">오피스 오픈 XML 비지오 양식</comment>
+ <comment xml:lang="ko">오피스 오픈 XML 비지오 서식</comment>
<comment xml:lang="pl">Szablon Office Open XML Visio</comment>
<comment xml:lang="pt">modelo Office Open XML Visio</comment>
<comment xml:lang="pt_BR">Modelo do Visio em Office Open XML</comment>
- <comment xml:lang="ru">шаблон Visio формата Office Open XML</comment>
+ <comment xml:lang="ru">Шаблон Visio формата Office Open XML</comment>
<comment xml:lang="sk">Šablóna aplikácie Visio Office Open XML</comment>
- <comment xml:lang="sr">Офис опен ИксМЛ Визио шаблон</comment>
+ <comment xml:lang="sr">Офисов отворени ИксМЛ Визио шаблон</comment>
<comment xml:lang="sv">Office Open XML Visio-mall</comment>
<comment xml:lang="tr">Office Open XML Visio Şablonu</comment>
<comment xml:lang="uk">шаблон Visio у форматі Office Open XML</comment>
- <comment xml:lang="zh_CN">OOXML Visio 模板</comment>
+ <comment xml:lang="zh_CN">Office Open XML Visio 模板</comment>
<comment xml:lang="zh_TW">Office Open XML Visio 範本</comment>
<generic-icon name="image-x-generic"/>
<glob pattern="*.vstx"/>
@@ -3500,8 +3626,10 @@
<comment xml:lang="de">Office-Open-XML-Visio-Schablone</comment>
<comment xml:lang="en_GB">Office Open XML Visio Stencil</comment>
<comment xml:lang="es">esténcil en OOXML de Visio</comment>
+ <comment xml:lang="eu">Office Open XML Visio txantiloia</comment>
<comment xml:lang="fi">Office Open XML Visio -kaavio</comment>
<comment xml:lang="fr">stencil Visio Office Open XML</comment>
+ <comment xml:lang="ga">Stionsal Office Open XML Visio</comment>
<comment xml:lang="he">דגם ל־Visio ב־Open XML מבית Office</comment>
<comment xml:lang="hr">Office Open XML Visio šablona</comment>
<comment xml:lang="hu">Office Open XML Visio stencil</comment>
@@ -3513,13 +3641,13 @@
<comment xml:lang="pl">Wzór Office Open XML Visio</comment>
<comment xml:lang="pt">Stencil Office Open XML Visio</comment>
<comment xml:lang="pt_BR">Estêncil do Visio em Office Open XML</comment>
- <comment xml:lang="ru">трафарет Visio формата Office Open XML</comment>
+ <comment xml:lang="ru">Трафарет Visio формата Office Open XML</comment>
<comment xml:lang="sk">Objekt aplikácie Visio Office Open XML</comment>
- <comment xml:lang="sr">Офис опен ИксМЛ Визио шаблон</comment>
+ <comment xml:lang="sr">Офисов отворени ИксМЛ Визио шаблон</comment>
<comment xml:lang="sv">Office Open XML Visio-stencil</comment>
<comment xml:lang="tr">Office Open XML Visio Kalıbı</comment>
<comment xml:lang="uk">трафарет Visio у форматі Office Open XML</comment>
- <comment xml:lang="zh_CN">OOXML Visio 模具</comment>
+ <comment xml:lang="zh_CN">Office Open XML Visio 模具</comment>
<comment xml:lang="zh_TW">Office Open XML Visio 圖形樣本</comment>
<generic-icon name="image-x-generic"/>
<glob pattern="*.vssx"/>
@@ -3537,6 +3665,7 @@
<comment xml:lang="eu">Office Open XML Visio marrazkia</comment>
<comment xml:lang="fi">Office Open XML Visio -piirros</comment>
<comment xml:lang="fr">dessin Visio Office Open XML</comment>
+ <comment xml:lang="ga">Líníocht Office Open XML Visio</comment>
<comment xml:lang="he">ציור Visio ב־Open XML מבית Office</comment>
<comment xml:lang="hr">Office Open XML Visio crtež</comment>
<comment xml:lang="hu">Office Open XML Visio rajz</comment>
@@ -3548,13 +3677,13 @@
<comment xml:lang="pl">Rysunek Office Open XML Visio</comment>
<comment xml:lang="pt">desenho Office Open XML Visio</comment>
<comment xml:lang="pt_BR">Desenho do Visio em Office Open XML</comment>
- <comment xml:lang="ru">схема Visio формата Office Open XML</comment>
+ <comment xml:lang="ru">Рисунок Visio формата Office Open XML</comment>
<comment xml:lang="sk">Kresba aplikácie Visio Office Open XML</comment>
- <comment xml:lang="sr">Офис опен ИксМЛ Визио цртање</comment>
+ <comment xml:lang="sr">Офисов отворени ИксМЛ Визио цртеж</comment>
<comment xml:lang="sv">Office Open XML Visio-teckning</comment>
<comment xml:lang="tr">Office Open XML Visio Çizimi</comment>
<comment xml:lang="uk">схема VIisio у форматі Office Open XML</comment>
- <comment xml:lang="zh_CN">OOXML Visio 绘图</comment>
+ <comment xml:lang="zh_CN">Office Open XML Visio 绘图</comment>
<comment xml:lang="zh_TW">Office Open XML Visio 繪圖</comment>
<generic-icon name="image-x-generic"/>
<glob pattern="*.vsdm"/>
@@ -3572,6 +3701,7 @@
<comment xml:lang="eu">Office Open XML Visio txantiloia</comment>
<comment xml:lang="fi">Office Open XML Visio -malli</comment>
<comment xml:lang="fr">modèle Visio Office Open XML</comment>
+ <comment xml:lang="ga">Teimpléad Office Open XML Visio</comment>
<comment xml:lang="he">תבנית Visio ב־Open XML מבית Office</comment>
<comment xml:lang="hr">Predložak Office Open XML Visio</comment>
<comment xml:lang="hu">Office Open XML Visio sablon</comment>
@@ -3579,17 +3709,17 @@
<comment xml:lang="id">Templat Visio Office Open XML</comment>
<comment xml:lang="it">Modello Visio Office Open XML</comment>
<comment xml:lang="kk">Office Open XML Visio үлгісі</comment>
- <comment xml:lang="ko">오피스 오픈 XML 비지오 양식</comment>
+ <comment xml:lang="ko">오피스 오픈 XML 비지오 서식</comment>
<comment xml:lang="pl">Szablon Office Open XML Visio</comment>
<comment xml:lang="pt">modelo Office Open XML Visio</comment>
<comment xml:lang="pt_BR">Modelo do Visio em Office Open XML</comment>
- <comment xml:lang="ru">шаблон Visio формата Office Open XML</comment>
+ <comment xml:lang="ru">Шаблон Visio формата Office Open XML</comment>
<comment xml:lang="sk">Šablóna aplikácie Visio Office Open XML</comment>
- <comment xml:lang="sr">Офис опен ИксМЛ Визио шаблон</comment>
+ <comment xml:lang="sr">Офисов отворени ИксМЛ Визио шаблон</comment>
<comment xml:lang="sv">Office Open XML Visio-mall</comment>
<comment xml:lang="tr">Office Open XML Visio Şablonu</comment>
<comment xml:lang="uk">шаблон Visio у форматі Office Open XML</comment>
- <comment xml:lang="zh_CN">OOXML Visio 模板</comment>
+ <comment xml:lang="zh_CN">Office Open XML Visio 模板</comment>
<comment xml:lang="zh_TW">Office Open XML Visio 範本</comment>
<generic-icon name="image-x-generic"/>
<glob pattern="*.vstm"/>
@@ -3603,8 +3733,10 @@
<comment xml:lang="de">Office-Open-XML-Visio-Schablone</comment>
<comment xml:lang="en_GB">Office Open XML Visio Stencil</comment>
<comment xml:lang="es">esténcil en OOXML de Visio</comment>
+ <comment xml:lang="eu">Office Open XML Visio txantiloia</comment>
<comment xml:lang="fi">Office Open XML Visio -kaavio</comment>
<comment xml:lang="fr">stencil Visio Office Open XML</comment>
+ <comment xml:lang="ga">Stionsal Office Open XML Visio</comment>
<comment xml:lang="he">דגם ל־Visio ב־Open XML מבית Office</comment>
<comment xml:lang="hr">Office Open XML Visio šablona</comment>
<comment xml:lang="hu">Office Open XML Visio stencil</comment>
@@ -3616,13 +3748,13 @@
<comment xml:lang="pl">Wzór Office Open XML Visio</comment>
<comment xml:lang="pt">Stencil Office Open XML Visio</comment>
<comment xml:lang="pt_BR">Estêncil do Visio em Office Open XML</comment>
- <comment xml:lang="ru">трафарет Visio формата Office Open XML</comment>
+ <comment xml:lang="ru">Трафарет Visio формата Office Open XML</comment>
<comment xml:lang="sk">Objekt aplikácie Visio Office Open XML</comment>
- <comment xml:lang="sr">Офис опен ИксМЛ Визио шаблон</comment>
+ <comment xml:lang="sr">Офисов отворени ИксМЛ Визио шаблон</comment>
<comment xml:lang="sv">Office Open XML Visio-stencil</comment>
<comment xml:lang="tr">Office Open XML Visio Kalıbı</comment>
<comment xml:lang="uk">трафарет Visio у форматі Office Open XML</comment>
- <comment xml:lang="zh_CN">OOXML Visio 模具</comment>
+ <comment xml:lang="zh_CN">Office Open XML Visio 模具</comment>
<comment xml:lang="zh_TW">Office Open XML Visio 圖形樣本</comment>
<generic-icon name="image-x-generic"/>
<glob pattern="*.vssm"/>
@@ -3631,6 +3763,7 @@
<mime-type type="application/vnd.ms-word.document.macroEnabled.12">
<comment>Word document</comment>
<comment xml:lang="ar">مستند Word</comment>
+ <comment xml:lang="ast">Documentu de Word</comment>
<comment xml:lang="be@latin">Dakument Word</comment>
<comment xml:lang="bg">Документ — Word</comment>
<comment xml:lang="ca">document Word</comment>
@@ -3666,16 +3799,16 @@
<comment xml:lang="pt">documento Word</comment>
<comment xml:lang="pt_BR">Documento do Word</comment>
<comment xml:lang="ro">Document Word</comment>
- <comment xml:lang="ru">документ Word</comment>
+ <comment xml:lang="ru">Документ Word</comment>
<comment xml:lang="sk">Dokument Word</comment>
<comment xml:lang="sl">Dokument Word</comment>
<comment xml:lang="sq">Dokument Word</comment>
- <comment xml:lang="sr">Вордов документ</comment>
+ <comment xml:lang="sr">Ворд документ</comment>
<comment xml:lang="sv">Word-dokument</comment>
<comment xml:lang="tr">Word belgesi</comment>
<comment xml:lang="uk">документ Word</comment>
<comment xml:lang="vi">Tài liệu Word</comment>
- <comment xml:lang="zh_CN">Microsoft Word 文档</comment>
+ <comment xml:lang="zh_CN">Word 文档</comment>
<comment xml:lang="zh_TW">Word 文件</comment>
<generic-icon name="x-office-document"/>
<glob pattern="*.docm"/>
@@ -3683,6 +3816,7 @@
</mime-type>
<mime-type type="application/vnd.ms-word.template.macroEnabled.12">
<comment>Word document template</comment>
+ <comment xml:lang="ast">Plantía de documentu de Word</comment>
<comment xml:lang="ca">plantilla de document Word</comment>
<comment xml:lang="cs">šablona dokumentu Word</comment>
<comment xml:lang="da">Word-dokumentskabelon</comment>
@@ -3693,6 +3827,7 @@
<comment xml:lang="eu">Word dokumentuaren txantiloia</comment>
<comment xml:lang="fi">Word-asiakirjamalli</comment>
<comment xml:lang="fr">modèle de document Word</comment>
+ <comment xml:lang="ga">teimpléad Word</comment>
<comment xml:lang="he">תבנית מסמך Word</comment>
<comment xml:lang="hr">Predložak Word dokumenta</comment>
<comment xml:lang="hu">Word dokumentumsablon</comment>
@@ -3700,18 +3835,18 @@
<comment xml:lang="id">Templat dokumen Word</comment>
<comment xml:lang="it">Modello documento Word</comment>
<comment xml:lang="kk">Word құжатының үлгісі</comment>
- <comment xml:lang="ko">워드 문서 양식</comment>
+ <comment xml:lang="ko">Word 문서 서식</comment>
<comment xml:lang="oc">modèl de document Word</comment>
<comment xml:lang="pl">Szablon dokumentu Word</comment>
<comment xml:lang="pt">modelo de documento Word</comment>
<comment xml:lang="pt_BR">Modelo de documento do Word</comment>
- <comment xml:lang="ru">шаблон документа Word</comment>
+ <comment xml:lang="ru">Шаблон документа Word</comment>
<comment xml:lang="sk">Šablóna dokumentu aplikácie Word</comment>
- <comment xml:lang="sr">Шаблон документа Ворда</comment>
+ <comment xml:lang="sr">Шаблон Ворд документа</comment>
<comment xml:lang="sv">Word-dokumentmall</comment>
<comment xml:lang="tr">Word belgesi şablonu</comment>
<comment xml:lang="uk">шаблон документа Word</comment>
- <comment xml:lang="zh_CN">Microsoft Word 文档模板</comment>
+ <comment xml:lang="zh_CN">Word 文档模板</comment>
<comment xml:lang="zh_TW">Word 文件範本</comment>
<generic-icon name="x-office-document"/>
<glob pattern="*.dotm"/>
@@ -3720,6 +3855,7 @@
<mime-type type="application/oxps">
<comment>XPS document</comment>
<comment xml:lang="ar">مستند XPS</comment>
+ <comment xml:lang="ast">Documentu XPS</comment>
<comment xml:lang="be@latin">Dakument XPS</comment>
<comment xml:lang="bg">Документ — XPS</comment>
<comment xml:lang="ca">document XPS</comment>
@@ -3755,7 +3891,7 @@
<comment xml:lang="pt">documento XPS</comment>
<comment xml:lang="pt_BR">Documento XPS</comment>
<comment xml:lang="ro">Document XPS</comment>
- <comment xml:lang="ru">документ XPS</comment>
+ <comment xml:lang="ru">Документ XPS</comment>
<comment xml:lang="sk">Dokument XPS</comment>
<comment xml:lang="sl">Dokument XPS</comment>
<comment xml:lang="sq">Dokument XPS</comment>
@@ -3773,10 +3909,12 @@
<glob pattern="*.oxps"/>
<glob pattern="*.xps"/>
<alias type="application/vnd.ms-xpsdocument"/>
+ <alias type="application/xps"/>
</mime-type>
<mime-type type="application/vnd.ms-works">
<comment>Microsoft Works document</comment>
<comment xml:lang="ar">مستند Microsoft Works</comment>
+ <comment xml:lang="ast">Documentu de Microsoft Works</comment>
<comment xml:lang="be@latin">Dakument Microsoft Works</comment>
<comment xml:lang="bg">Документ — Microsoft Works</comment>
<comment xml:lang="ca">document de Microsoft Works</comment>
@@ -3812,11 +3950,11 @@
<comment xml:lang="pt">documento Microsoft Works</comment>
<comment xml:lang="pt_BR">Documento do Microsoft Works</comment>
<comment xml:lang="ro">Document Microsoft Works</comment>
- <comment xml:lang="ru">документ Microsoft Works</comment>
+ <comment xml:lang="ru">Документ Microsoft Works</comment>
<comment xml:lang="sk">Dokument Microsoft Works</comment>
<comment xml:lang="sl">Dokument Microsoft Works</comment>
<comment xml:lang="sq">Dokument Microsoft Works</comment>
- <comment xml:lang="sr">Микрософтов Воркс документ</comment>
+ <comment xml:lang="sr">документ Мајкрософт Воркса</comment>
<comment xml:lang="sv">Microsoft Works-dokument</comment>
<comment xml:lang="tr">Microsoft Works belgesi</comment>
<comment xml:lang="uk">документ Microsoft Works</comment>
@@ -3833,6 +3971,7 @@
</mime-type>
<mime-type type="application/vnd.visio">
<comment>Microsoft Visio document</comment>
+ <comment xml:lang="ast">Documentu de Microsoft Visio</comment>
<comment xml:lang="bg">Документ — Microsoft Visio</comment>
<comment xml:lang="ca">document de Microsoft Visio</comment>
<comment xml:lang="cs">dokument Microsoft Visio</comment>
@@ -3844,6 +3983,7 @@
<comment xml:lang="eu">Microsoft Visio dokumentua</comment>
<comment xml:lang="fi">Microsoft Visio -asiakirja</comment>
<comment xml:lang="fr">document Microsoft Visio</comment>
+ <comment xml:lang="ga">cáipéis Microsoft Visio</comment>
<comment xml:lang="gl">Documento de Microsoft Visio</comment>
<comment xml:lang="he">מסמך </comment>
<comment xml:lang="hr">Microsoft Visio dokument</comment>
@@ -3861,10 +4001,10 @@
<comment xml:lang="pl">Dokument Microsoft Visio</comment>
<comment xml:lang="pt">documento Microsoft Visio</comment>
<comment xml:lang="pt_BR">Documento do Microsoft Visio</comment>
- <comment xml:lang="ru">документ Microsoft Visio</comment>
+ <comment xml:lang="ru">Документ Microsoft Visio</comment>
<comment xml:lang="sk">Dokument Microsoft Visio</comment>
<comment xml:lang="sl">Dokument Microsoft Visio</comment>
- <comment xml:lang="sr">Микрософтов Визио документ</comment>
+ <comment xml:lang="sr">документ Мајкрософт Визиа</comment>
<comment xml:lang="sv">Microsoft Visio-dokument</comment>
<comment xml:lang="tr">Microsoft Visio belgesi</comment>
<comment xml:lang="uk">документ Microsoft Visio</comment>
@@ -3880,6 +4020,7 @@
<mime-type type="application/msword">
<comment>Word document</comment>
<comment xml:lang="ar">مستند Word</comment>
+ <comment xml:lang="ast">Documentu de Word</comment>
<comment xml:lang="be@latin">Dakument Word</comment>
<comment xml:lang="bg">Документ — Word</comment>
<comment xml:lang="ca">document Word</comment>
@@ -3915,16 +4056,16 @@
<comment xml:lang="pt">documento Word</comment>
<comment xml:lang="pt_BR">Documento do Word</comment>
<comment xml:lang="ro">Document Word</comment>
- <comment xml:lang="ru">документ Word</comment>
+ <comment xml:lang="ru">Документ Word</comment>
<comment xml:lang="sk">Dokument Word</comment>
<comment xml:lang="sl">Dokument Word</comment>
<comment xml:lang="sq">Dokument Word</comment>
- <comment xml:lang="sr">Вордов документ</comment>
+ <comment xml:lang="sr">Ворд документ</comment>
<comment xml:lang="sv">Word-dokument</comment>
<comment xml:lang="tr">Word belgesi</comment>
<comment xml:lang="uk">документ Word</comment>
<comment xml:lang="vi">Tài liệu Word</comment>
- <comment xml:lang="zh_CN">Microsoft Word 文档</comment>
+ <comment xml:lang="zh_CN">Word 文档</comment>
<comment xml:lang="zh_TW">Word 文件</comment>
<sub-class-of type="application/x-ole-storage"/>
<generic-icon name="x-office-document"/>
@@ -3947,6 +4088,7 @@
<mime-type type="application/msword-template">
<comment>Word template</comment>
<comment xml:lang="ar">قالب Word</comment>
+ <comment xml:lang="ast">Plantía de Word</comment>
<comment xml:lang="be@latin">Šablon Word</comment>
<comment xml:lang="bg">Шаблон за документи — Word</comment>
<comment xml:lang="ca">plantilla de Word</comment>
@@ -3982,11 +4124,11 @@
<comment xml:lang="pt">modelo Word</comment>
<comment xml:lang="pt_BR">Modelo do Word</comment>
<comment xml:lang="ro">Șablon Word</comment>
- <comment xml:lang="ru">шаблон Word</comment>
+ <comment xml:lang="ru">Шаблон Word</comment>
<comment xml:lang="sk">Šablóna Word</comment>
<comment xml:lang="sl">Predloga dokumenta Microsoft Word</comment>
<comment xml:lang="sq">Model Word</comment>
- <comment xml:lang="sr">Вордов шаблон</comment>
+ <comment xml:lang="sr">Ворд шаблон</comment>
<comment xml:lang="sv">Word-mall</comment>
<comment xml:lang="tr">Word şablonu</comment>
<comment xml:lang="uk">шаблон Word</comment>
@@ -3999,6 +4141,7 @@
</mime-type>
<mime-type type="application/gml+xml">
<comment>GML document</comment>
+ <comment xml:lang="ast">Documentu GML</comment>
<comment xml:lang="ca">document GML</comment>
<comment xml:lang="cs">dokument GML</comment>
<comment xml:lang="da">GML-dokument</comment>
@@ -4009,6 +4152,7 @@
<comment xml:lang="eu">GML dokumentua</comment>
<comment xml:lang="fi">GML-asiakirja</comment>
<comment xml:lang="fr">document GML</comment>
+ <comment xml:lang="ga">cáipéis GML</comment>
<comment xml:lang="gl">Documento GML</comment>
<comment xml:lang="he">מסמך GML</comment>
<comment xml:lang="hr">GML dokument</comment>
@@ -4024,7 +4168,7 @@
<comment xml:lang="pl">Dokument GML</comment>
<comment xml:lang="pt">documento GML</comment>
<comment xml:lang="pt_BR">Documento GML</comment>
- <comment xml:lang="ru">документ GML</comment>
+ <comment xml:lang="ru">Документ GML</comment>
<comment xml:lang="sk">Dokument GML</comment>
<comment xml:lang="sl">Dokument GML</comment>
<comment xml:lang="sr">ГМЛ документ</comment>
@@ -4077,7 +4221,7 @@
<comment xml:lang="pt">ficheiro de procura GNUnet</comment>
<comment xml:lang="pt_BR">Arquivo de pesquisa do GNUnet</comment>
<comment xml:lang="ro">Fișier căutare GNUnet</comment>
- <comment xml:lang="ru">файл поиска GNUnet</comment>
+ <comment xml:lang="ru">Файл поиска GNUnet</comment>
<comment xml:lang="sk">Vyhľadávací súbor GNUnet</comment>
<comment xml:lang="sl">Iskalna datoteka GNUnet</comment>
<comment xml:lang="sq">File kërkimi GNUnet</comment>
@@ -4096,6 +4240,7 @@
<mime-type type="application/vnd.ms-tnef">
<comment>TNEF message</comment>
<comment xml:lang="ar">رسالة TNEF</comment>
+ <comment xml:lang="ast">Mensaxe TNEF</comment>
<comment xml:lang="be@latin">List TNEF</comment>
<comment xml:lang="bg">Съобщение — TNEF</comment>
<comment xml:lang="ca">missatge TNEF</comment>
@@ -4130,7 +4275,7 @@
<comment xml:lang="pt">mensagem TNEF</comment>
<comment xml:lang="pt_BR">Mensagem TNEF</comment>
<comment xml:lang="ro">Mesaj TNEF</comment>
- <comment xml:lang="ru">сообщение TNEF</comment>
+ <comment xml:lang="ru">Сообщение TNEF</comment>
<comment xml:lang="sk">Správa TNEF</comment>
<comment xml:lang="sl">Datoteka sporočila TNEF</comment>
<comment xml:lang="sq">Mesazh TNEF</comment>
@@ -4192,16 +4337,16 @@
<comment xml:lang="pt">folha de cálculo do StarCalc</comment>
<comment xml:lang="pt_BR">Planilha do StarCalc</comment>
<comment xml:lang="ro">Foaie de calcul StarCalc</comment>
- <comment xml:lang="ru">электронная таблица StarCalc</comment>
+ <comment xml:lang="ru">Электронная таблица StarCalc</comment>
<comment xml:lang="sk">Zošit StarCalc</comment>
<comment xml:lang="sl">Preglednica StarCalc</comment>
<comment xml:lang="sq">Fletë llogaritjesh StarCalc</comment>
- <comment xml:lang="sr">Табела Стар Рачуна</comment>
+ <comment xml:lang="sr">Стар калк табела</comment>
<comment xml:lang="sv">StarCalc-kalkylblad</comment>
<comment xml:lang="tr">StarCalc çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця StarCalc</comment>
<comment xml:lang="vi">Bảng tính StarCalc</comment>
- <comment xml:lang="zh_CN">STarCalc 工作簿</comment>
+ <comment xml:lang="zh_CN">StarCalc 电子表格</comment>
<comment xml:lang="zh_TW">StarCalc 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<glob pattern="*.sdc"/>
@@ -4247,7 +4392,7 @@
<comment xml:lang="pt">gráfico do StarChart</comment>
<comment xml:lang="pt_BR">Gráfico do StarChart</comment>
<comment xml:lang="ro">Diagramă StarChart</comment>
- <comment xml:lang="ru">диаграмма StarChart</comment>
+ <comment xml:lang="ru">Диаграмма StarChart</comment>
<comment xml:lang="sk">Graf StarChart</comment>
<comment xml:lang="sl">Datoteka grafikona StarChart</comment>
<comment xml:lang="sq">Grafik StarChart</comment>
@@ -4256,7 +4401,7 @@
<comment xml:lang="tr">StarChart çizgelgesi</comment>
<comment xml:lang="uk">діаграма StarChart</comment>
<comment xml:lang="vi">Đồ thị StarChart</comment>
- <comment xml:lang="zh_CN">STarChart 图表</comment>
+ <comment xml:lang="zh_CN">StarCalc 图表</comment>
<comment xml:lang="zh_TW">StarChart 圖表</comment>
<generic-icon name="x-office-spreadsheet"/>
<glob pattern="*.sds"/>
@@ -4302,7 +4447,7 @@
<comment xml:lang="pt">desenho do StarDraw</comment>
<comment xml:lang="pt_BR">Desenho do StarDraw</comment>
<comment xml:lang="ro">Desen StarDraw</comment>
- <comment xml:lang="ru">изображение StarDraw</comment>
+ <comment xml:lang="ru">Рисунок StarDraw</comment>
<comment xml:lang="sk">Kresba StarDraw</comment>
<comment xml:lang="sl">Datoteka risbe StarDraw</comment>
<comment xml:lang="sq">Vizatim StarDraw</comment>
@@ -4311,7 +4456,7 @@
<comment xml:lang="tr">StarDraw çizimi</comment>
<comment xml:lang="uk">малюнок StarDraw</comment>
<comment xml:lang="vi">Bản vẽ StarDraw</comment>
- <comment xml:lang="zh_CN">STarDraw 绘图</comment>
+ <comment xml:lang="zh_CN">StarDraw 绘图</comment>
<comment xml:lang="zh_TW">StarDraw 繪圖</comment>
<generic-icon name="image-x-generic"/>
<glob pattern="*.sda"/>
@@ -4357,7 +4502,7 @@
<comment xml:lang="pt">apresentação do StarImpress</comment>
<comment xml:lang="pt_BR">Apresentação do StarImpress</comment>
<comment xml:lang="ro">Prezentare StarImpress</comment>
- <comment xml:lang="ru">презентация StarImpress</comment>
+ <comment xml:lang="ru">Презентация StarImpress</comment>
<comment xml:lang="sk">Prezentácia StarImpress</comment>
<comment xml:lang="sl">Predstavitev StarImpress</comment>
<comment xml:lang="sq">Prezantim StarImpress</comment>
@@ -4366,7 +4511,7 @@
<comment xml:lang="tr">StarImpress sunumu</comment>
<comment xml:lang="uk">презентація StarImpress</comment>
<comment xml:lang="vi">Trình diễn StarImpress</comment>
- <comment xml:lang="zh_CN">STarImpress 演示文稿</comment>
+ <comment xml:lang="zh_CN">StarImpress 演示文稿</comment>
<comment xml:lang="zh_TW">StarImpress 簡報檔</comment>
<generic-icon name="x-office-presentation"/>
<glob pattern="*.sdd"/>
@@ -4411,7 +4556,7 @@
<comment xml:lang="pt">email do StarMail</comment>
<comment xml:lang="pt_BR">E-mail do StarMail</comment>
<comment xml:lang="ro">Email StarEmail</comment>
- <comment xml:lang="ru">электронное письмо StarMail</comment>
+ <comment xml:lang="ru">Электронное письмо StarMail</comment>
<comment xml:lang="sk">E-mail StarMail</comment>
<comment xml:lang="sl">Datoteka pošte StarMail</comment>
<comment xml:lang="sq">Mesazh StarMail</comment>
@@ -4420,7 +4565,7 @@
<comment xml:lang="tr">StarMail epostası</comment>
<comment xml:lang="uk">поштове повідомлення StarMail</comment>
<comment xml:lang="vi">Thư điện tử StarMail</comment>
- <comment xml:lang="zh_CN">STarMail 电子邮件</comment>
+ <comment xml:lang="zh_CN">StarMail 电子邮件</comment>
<comment xml:lang="zh_TW">StarMail 郵件</comment>
<glob pattern="*.smd"/>
</mime-type>
@@ -4463,7 +4608,7 @@
<comment xml:lang="pt">fórmula do StarMath</comment>
<comment xml:lang="pt_BR">Fórmula do StarMath</comment>
<comment xml:lang="ro">Formulă StarMath</comment>
- <comment xml:lang="ru">формула StarMath</comment>
+ <comment xml:lang="ru">Формула StarMath</comment>
<comment xml:lang="sk">Vzorec StarMath</comment>
<comment xml:lang="sl">Datoteka formule StarMath</comment>
<comment xml:lang="sq">Formulë StarMath</comment>
@@ -4472,7 +4617,7 @@
<comment xml:lang="tr">StarMath formülü</comment>
<comment xml:lang="uk">формула StarMath</comment>
<comment xml:lang="vi">Công thức StarMath</comment>
- <comment xml:lang="zh_CN">STarMath 公式</comment>
+ <comment xml:lang="zh_CN">StarMath 公式</comment>
<comment xml:lang="zh_TW">StarMath 公式</comment>
<generic-icon name="x-office-document"/>
<glob pattern="*.smf"/>
@@ -4480,6 +4625,7 @@
<mime-type type="application/vnd.stardivision.writer">
<comment>StarWriter document</comment>
<comment xml:lang="ar">مستند StarWriter</comment>
+ <comment xml:lang="ast">Documentu de StarWriter</comment>
<comment xml:lang="az">StarWriter sənədi</comment>
<comment xml:lang="be@latin">Dakument StarWriter</comment>
<comment xml:lang="bg">Документ — StarWriter</comment>
@@ -4518,7 +4664,7 @@
<comment xml:lang="pt">documento do StarWriter</comment>
<comment xml:lang="pt_BR">Documento do StarWriter</comment>
<comment xml:lang="ro">Document StarWriter</comment>
- <comment xml:lang="ru">документ StarWriter</comment>
+ <comment xml:lang="ru">Документ StarWriter</comment>
<comment xml:lang="sk">Dokument StarWriter</comment>
<comment xml:lang="sl">Dokument StarWriter</comment>
<comment xml:lang="sq">Dokument StarWriter</comment>
@@ -4527,7 +4673,7 @@
<comment xml:lang="tr">StarWriter belgesi</comment>
<comment xml:lang="uk">документ StarWriter</comment>
<comment xml:lang="vi">Tài liệu StarWriter</comment>
- <comment xml:lang="zh_CN">STarWriter 文档</comment>
+ <comment xml:lang="zh_CN">StarWriter 文档</comment>
<comment xml:lang="zh_TW">StarWriter 文件</comment>
<generic-icon name="x-office-document"/>
<glob pattern="*.sdw"/>
@@ -4576,7 +4722,7 @@
<comment xml:lang="pt">folha de cálculo OpenOffice Calc</comment>
<comment xml:lang="pt_BR">Planilha do OpenOffice Calc</comment>
<comment xml:lang="ro">Foaie de calcul OpenOffice Calc</comment>
- <comment xml:lang="ru">электронная таблица OpenOffice Calc</comment>
+ <comment xml:lang="ru">Электронная таблица OpenOffice Calc</comment>
<comment xml:lang="sk">Zošit OpenOffice Calc</comment>
<comment xml:lang="sl">Razpredelnica OpenOffice.org Calc</comment>
<comment xml:lang="sq">Fletë llogaritjesh OpenOffice Calc</comment>
@@ -4585,7 +4731,7 @@
<comment xml:lang="tr">OpenOffice Calc çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця OpenOffice Calc</comment>
<comment xml:lang="vi">Bảng tính Calc của OpenOffice.org</comment>
- <comment xml:lang="zh_CN">OpenOffice.org Calc 工作簿</comment>
+ <comment xml:lang="zh_CN">OpenOffice Calc 电子表格</comment>
<comment xml:lang="zh_TW">OpenOffice Calc 試算表</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="x-office-spreadsheet"/>
@@ -4636,7 +4782,7 @@
<comment xml:lang="pt">modelo OpenOffice Calc</comment>
<comment xml:lang="pt_BR">Modelo do OpenOffice Calc</comment>
<comment xml:lang="ro">Șablon OpenOffice Calc</comment>
- <comment xml:lang="ru">шаблон OpenOffice Calc</comment>
+ <comment xml:lang="ru">Шаблон OpenOffice Calc</comment>
<comment xml:lang="sk">Šablóna OpenOffice Calc</comment>
<comment xml:lang="sl">Predloga OpenOffice.org Calc</comment>
<comment xml:lang="sq">Model OpenOffice Calc</comment>
@@ -4645,7 +4791,7 @@
<comment xml:lang="tr">OpenOffice Calc şablonu</comment>
<comment xml:lang="uk">шаблон ел.таблиці OpenOffice Calc</comment>
<comment xml:lang="vi">Mẫu bảng tính Calc của OpenOffice.org</comment>
- <comment xml:lang="zh_CN">OpenOffice.org Calc 工作簿模板</comment>
+ <comment xml:lang="zh_CN">OpenOffice Calc 模板</comment>
<comment xml:lang="zh_TW">OpenOffice Calc 範本</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="x-office-spreadsheet"/>
@@ -4696,7 +4842,7 @@
<comment xml:lang="pt">desenho OpenOffice Draw</comment>
<comment xml:lang="pt_BR">Desenho do OpenOffice Draw</comment>
<comment xml:lang="ro">Desen OpenOffice Draw</comment>
- <comment xml:lang="ru">изображение OpenOffice Draw</comment>
+ <comment xml:lang="ru">Рисунок OpenOffice Draw</comment>
<comment xml:lang="sk">Kresba OpenOffice Draw</comment>
<comment xml:lang="sl">Datoteka risbe OpenOffice.org Draw</comment>
<comment xml:lang="sq">Vizatim OpenOffice Draw</comment>
@@ -4705,7 +4851,7 @@
<comment xml:lang="tr">OpenOffice Draw çizimi</comment>
<comment xml:lang="uk">малюнок OpenOffice Draw</comment>
<comment xml:lang="vi">Bản vẽ Draw của OpenOffice.org</comment>
- <comment xml:lang="zh_CN">OpenOffice.org Draw 绘图</comment>
+ <comment xml:lang="zh_CN">OpenOffice Draw 绘图</comment>
<comment xml:lang="zh_TW">OpenOffice Draw 繪圖</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="image-x-generic"/>
@@ -4756,7 +4902,7 @@
<comment xml:lang="pt">modelo OpenOffice Draw</comment>
<comment xml:lang="pt_BR">Modelo do OpenOffice Draw</comment>
<comment xml:lang="ro">Șablon OpenOffice Draw</comment>
- <comment xml:lang="ru">шаблон OpenOffice Draw</comment>
+ <comment xml:lang="ru">Шаблон OpenOffice Draw</comment>
<comment xml:lang="sk">Šablóna OpenOffice Draw</comment>
<comment xml:lang="sl">Predloga OpenOffice.org Draw</comment>
<comment xml:lang="sq">Model OpenOffice Draw</comment>
@@ -4765,7 +4911,7 @@
<comment xml:lang="tr">OpenOffice Draw şablonu</comment>
<comment xml:lang="uk">шаблон малюнку OpenOffice Draw</comment>
<comment xml:lang="vi">Mẫu bản vẽ Draw của OpenOffice.org</comment>
- <comment xml:lang="zh_CN">OpenOffice.org Draw 绘图模板</comment>
+ <comment xml:lang="zh_CN">OpenOffice Draw 模板</comment>
<comment xml:lang="zh_TW">OpenOffice Draw 範本</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="image-x-generic"/>
@@ -4818,7 +4964,7 @@
<comment xml:lang="pt">apresentação OpenOffice Impress</comment>
<comment xml:lang="pt_BR">Apresentação do OpenOffice Impress</comment>
<comment xml:lang="ro">Prezentare OpenOffice Impress</comment>
- <comment xml:lang="ru">презентация OpenOffice Impress</comment>
+ <comment xml:lang="ru">Презентация OpenOffice Impress</comment>
<comment xml:lang="sk">Prezentácia OpenOffice Impress</comment>
<comment xml:lang="sl">Predstavitev OpenOffice.org Impress</comment>
<comment xml:lang="sq">Prezantim OpenOffice Impress</comment>
@@ -4827,7 +4973,7 @@
<comment xml:lang="tr">OpenOffice Impress sunumu</comment>
<comment xml:lang="uk">презентація OpenOffice Impress</comment>
<comment xml:lang="vi">Trình diễn Impress của OpenOffice.org</comment>
- <comment xml:lang="zh_CN">OpenOffice.org Impress 演示文稿</comment>
+ <comment xml:lang="zh_CN">OpenOffice Impress 演示文稿</comment>
<comment xml:lang="zh_TW">OpenOffice Impress 簡報</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="x-office-presentation"/>
@@ -4878,7 +5024,7 @@
<comment xml:lang="pt">modelo OpenOffice Impress</comment>
<comment xml:lang="pt_BR">Modelo do OpenOffice Impress</comment>
<comment xml:lang="ro">Șablon OpenOffice Impress</comment>
- <comment xml:lang="ru">шаблон OpenOffice Impress</comment>
+ <comment xml:lang="ru">Шаблон OpenOffice Impress</comment>
<comment xml:lang="sk">Šablóna OpenOffice Impress</comment>
<comment xml:lang="sl">Predloga OpenOffice.org Impress</comment>
<comment xml:lang="sq">Model OpenOffice Impress</comment>
@@ -4887,7 +5033,7 @@
<comment xml:lang="tr">OpenOffice Impress şablonu</comment>
<comment xml:lang="uk">шаблон презентації OpenOffice Impress</comment>
<comment xml:lang="vi">Mẫu trình diễn Impress của OpenOffice.org</comment>
- <comment xml:lang="zh_CN">OpenOffice.org Impress 演示文稿模板</comment>
+ <comment xml:lang="zh_CN">OpenOffice Impress 模板</comment>
<comment xml:lang="zh_TW">OpenOffice Impress 範本</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="x-office-presentation"/>
@@ -4938,7 +5084,7 @@
<comment xml:lang="pt">fórmula OpenOffice Math</comment>
<comment xml:lang="pt_BR">Fórmula do OpenOffice Math</comment>
<comment xml:lang="ro">Formulă OpenOffice Math</comment>
- <comment xml:lang="ru">формула OpenOffice Math</comment>
+ <comment xml:lang="ru">Формула OpenOffice Math</comment>
<comment xml:lang="sk">Vzorec OpenOffice Math</comment>
<comment xml:lang="sl">Dokument formule OpenOffice.org Math</comment>
<comment xml:lang="sq">Formulë OpenOffice Math</comment>
@@ -4947,7 +5093,7 @@
<comment xml:lang="tr">OpenOffice Math formülü</comment>
<comment xml:lang="uk">формула OpenOffice Math</comment>
<comment xml:lang="vi">Công thức Math của OpenOffice.org</comment>
- <comment xml:lang="zh_CN">OpenOffice.org Math 公式</comment>
+ <comment xml:lang="zh_CN">OpenOffice Math 公式</comment>
<comment xml:lang="zh_TW">OpenOffice Math 公式</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="x-office-document"/>
@@ -4963,6 +5109,7 @@
<mime-type type="application/vnd.sun.xml.writer">
<comment>OpenOffice Writer document</comment>
<comment xml:lang="ar">مستند Writer المكتب المفتوح</comment>
+ <comment xml:lang="ast">Documentu d'OpenOffice Writer</comment>
<comment xml:lang="az">OpenOffice Writer sənədi</comment>
<comment xml:lang="be@latin">Dakument OpenOffice Writer</comment>
<comment xml:lang="bg">Документ — OpenOffice Writer</comment>
@@ -5000,7 +5147,7 @@
<comment xml:lang="pt">documento OpenOffice Writer</comment>
<comment xml:lang="pt_BR">Documento do OpenOffice Writer</comment>
<comment xml:lang="ro">Document OpenOffice Writer</comment>
- <comment xml:lang="ru">документ OpenOffice Writer</comment>
+ <comment xml:lang="ru">Документ OpenOffice Writer</comment>
<comment xml:lang="sk">Dokument OpenOffice Writer</comment>
<comment xml:lang="sl">Dokument OpenOffice.org Writer</comment>
<comment xml:lang="sq">Dokument OpenOffice Writer</comment>
@@ -5009,7 +5156,7 @@
<comment xml:lang="tr">OpenOffice Writer belgesi</comment>
<comment xml:lang="uk">документ OpenOffice Writer</comment>
<comment xml:lang="vi">Tài liệu Writer của OpenOffice.org</comment>
- <comment xml:lang="zh_CN">OpenOffice.org Writer 文档</comment>
+ <comment xml:lang="zh_CN">OpenOffice Writer 文档</comment>
<comment xml:lang="zh_TW">OpenOffice Writer 文件</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="x-office-document"/>
@@ -5025,6 +5172,7 @@
<mime-type type="application/vnd.sun.xml.writer.global">
<comment>OpenOffice Writer global document</comment>
<comment xml:lang="ar">مستند المكتب المفتوح Writer العالمي</comment>
+ <comment xml:lang="ast">Documentu global d'OpenOffice Writer</comment>
<comment xml:lang="az">OpenOffice Writer qlobal sənədi</comment>
<comment xml:lang="be@latin">Hlabalny dakument OpenOffice Writer</comment>
<comment xml:lang="bg">Документ - глобален — OpenOffice Writer</comment>
@@ -5062,7 +5210,7 @@
<comment xml:lang="pt">documento global OpenOffice Writer</comment>
<comment xml:lang="pt_BR">Documento global do OpenOffice Writer</comment>
<comment xml:lang="ro">Document global OpenOffice Writer</comment>
- <comment xml:lang="ru">основной документ OpenOffice Writer</comment>
+ <comment xml:lang="ru">Основной документ OpenOffice Writer</comment>
<comment xml:lang="sk">Globálny dokument OpenOffice Writer</comment>
<comment xml:lang="sl">Splošni dokument OpenOffice.org Writer</comment>
<comment xml:lang="sq">Dokument i përgjithshëm OpenOffice Writer</comment>
@@ -5071,7 +5219,7 @@
<comment xml:lang="tr">OpenOffice Writer global belgesi</comment>
<comment xml:lang="uk">загальний документ OpenOffice Writer</comment>
<comment xml:lang="vi">Tài liệu toàn cục Writer của OpenOffice.org</comment>
- <comment xml:lang="zh_CN">OpenOffice.org Writer 全局文档</comment>
+ <comment xml:lang="zh_CN">OpenOffice Writer 全局文档</comment>
<comment xml:lang="zh_TW">OpenOffice Writer 主控文件</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="x-office-document"/>
@@ -5125,7 +5273,7 @@
<comment xml:lang="pt">modelo OpenOffice Writer</comment>
<comment xml:lang="pt_BR">Modelo do OpenOffice Writer</comment>
<comment xml:lang="ro">Șablon OpenOffice Writer</comment>
- <comment xml:lang="ru">шаблон OpenOffice Writer</comment>
+ <comment xml:lang="ru">Шаблон OpenOffice Writer</comment>
<comment xml:lang="sk">Šablóna OpenOffice Writer</comment>
<comment xml:lang="sl">Predloga OpenOffice.org Writer</comment>
<comment xml:lang="sq">Model OpenOffice Writer</comment>
@@ -5134,7 +5282,7 @@
<comment xml:lang="tr">OpenOffice Writer şablonu</comment>
<comment xml:lang="uk">шаблон документа OpenOffice Writer</comment>
<comment xml:lang="vi">Mẫu tài liệu Writer của OpenOffice.org</comment>
- <comment xml:lang="zh_CN">OpenOffice.org Writer 文档模板</comment>
+ <comment xml:lang="zh_CN">OpenOffice Writer 模板</comment>
<comment xml:lang="zh_TW">OpenOffice Writer 範本</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="x-office-document"/>
@@ -5150,6 +5298,7 @@
<mime-type type="application/vnd.oasis.opendocument.text">
<comment>ODT document</comment>
<comment xml:lang="ar">مستند ODT</comment>
+ <comment xml:lang="ast">Documentu ODT</comment>
<comment xml:lang="be@latin">Dakument ODT</comment>
<comment xml:lang="bg">Документ — ODT</comment>
<comment xml:lang="ca">document ODT</comment>
@@ -5186,7 +5335,7 @@
<comment xml:lang="pt">documento ODT</comment>
<comment xml:lang="pt_BR">Documento ODT</comment>
<comment xml:lang="ro">Document ODT</comment>
- <comment xml:lang="ru">документ ODT</comment>
+ <comment xml:lang="ru">Документ ODT</comment>
<comment xml:lang="sk">Dokument ODT</comment>
<comment xml:lang="sl">Dokument ODT</comment>
<comment xml:lang="sq">Dokument ODT</comment>
@@ -5213,6 +5362,7 @@
<mime-type type="application/vnd.oasis.opendocument.text-flat-xml">
<comment>ODT document (Flat XML)</comment>
<comment xml:lang="ar">مستند ODT (Flat XML)</comment>
+ <comment xml:lang="ast">Documentu ODT (XML planu)</comment>
<comment xml:lang="bg">Документ — ODT (само XML)</comment>
<comment xml:lang="ca">document ODT (XML pla)</comment>
<comment xml:lang="cs">dokument ODT (Flat XML)</comment>
@@ -5245,14 +5395,14 @@
<comment xml:lang="pt">documento ODT (XML plano)</comment>
<comment xml:lang="pt_BR">Documento ODT (Flat XML)</comment>
<comment xml:lang="ro">Document ODT (XML simplu)</comment>
- <comment xml:lang="ru">документ ODT (простой XML)</comment>
+ <comment xml:lang="ru">Документ ODT (простой XML)</comment>
<comment xml:lang="sk">Dokument ODT (čisté XML)</comment>
<comment xml:lang="sl">Datoteka dokumenta ODT (nepovezan XML)</comment>
<comment xml:lang="sr">ОДТ документ (Обични ИксМЛ)</comment>
<comment xml:lang="sv">ODT-dokument (platt XML)</comment>
<comment xml:lang="tr">ODT belgesi (Düz XML)</comment>
<comment xml:lang="uk">документ ODT (Flat XML)</comment>
- <comment xml:lang="zh_CN">ODT 文档(Flat XML)</comment>
+ <comment xml:lang="zh_CN">ODT 文档(Flat XML)</comment>
<comment xml:lang="zh_TW">ODT 文件 (Flat XML)</comment>
<acronym>FODT</acronym>
<expanded-acronym>OpenDocument Text (Flat XML)</expanded-acronym>
@@ -5299,7 +5449,7 @@
<comment xml:lang="pt">modelo ODT</comment>
<comment xml:lang="pt_BR">Modelo ODT</comment>
<comment xml:lang="ro">Șablon ODT</comment>
- <comment xml:lang="ru">шаблон ODT</comment>
+ <comment xml:lang="ru">Шаблон ODT</comment>
<comment xml:lang="sk">Šablóna ODT</comment>
<comment xml:lang="sl">Predloga dokumenta ODT</comment>
<comment xml:lang="sq">Model ODT</comment>
@@ -5362,7 +5512,7 @@
<comment xml:lang="pt">modelo OTH</comment>
<comment xml:lang="pt_BR">Modelo OTH</comment>
<comment xml:lang="ro">Șablon OTH</comment>
- <comment xml:lang="ru">шаблон OTH</comment>
+ <comment xml:lang="ru">Шаблон OTH</comment>
<comment xml:lang="sk">Šablóna OTH</comment>
<comment xml:lang="sl">Predloga OTH</comment>
<comment xml:lang="sq">Model OTH</comment>
@@ -5389,6 +5539,7 @@
<mime-type type="application/vnd.oasis.opendocument.text-master">
<comment>ODM document</comment>
<comment xml:lang="ar">مستند ODM</comment>
+ <comment xml:lang="ast">Documentu ODM</comment>
<comment xml:lang="be@latin">Dakument ODM</comment>
<comment xml:lang="bg">Документ — ODM</comment>
<comment xml:lang="ca">document ODM</comment>
@@ -5425,7 +5576,7 @@
<comment xml:lang="pt">documento ODM</comment>
<comment xml:lang="pt_BR">Documento ODM</comment>
<comment xml:lang="ro">Document ODM</comment>
- <comment xml:lang="ru">документ ODM</comment>
+ <comment xml:lang="ru">Документ ODM</comment>
<comment xml:lang="sk">Dokument ODM</comment>
<comment xml:lang="sl">Dokument ODM</comment>
<comment xml:lang="sq">Dokument ODM</comment>
@@ -5488,7 +5639,7 @@
<comment xml:lang="pt">desenho ODG</comment>
<comment xml:lang="pt_BR">Desenho ODG</comment>
<comment xml:lang="ro">Desen ODG</comment>
- <comment xml:lang="ru">изображение ODG</comment>
+ <comment xml:lang="ru">Рисунок ODG</comment>
<comment xml:lang="sk">Kresba ODG</comment>
<comment xml:lang="sl">Datoteka risbe ODG</comment>
<comment xml:lang="sq">Vizatim ODG</comment>
@@ -5547,14 +5698,14 @@
<comment xml:lang="pt">desenho ODG (XML plano)</comment>
<comment xml:lang="pt_BR">Desenho ODG (Flat XML)</comment>
<comment xml:lang="ro">Desen ODG (XML simplu)</comment>
- <comment xml:lang="ru">изображение ODG (простой XML)</comment>
+ <comment xml:lang="ru">Рисунок ODG (простой XML)</comment>
<comment xml:lang="sk">Kresba ODG (čisté XML)</comment>
<comment xml:lang="sl">Datoteka risbe ODG (nepovezan XML)</comment>
<comment xml:lang="sr">ОДГ цртеж (Обичан ИксМЛ)</comment>
<comment xml:lang="sv">ODG-teckning (platt XML)</comment>
<comment xml:lang="tr">ODG çizimi (Düz XML)</comment>
<comment xml:lang="uk">малюнок ODG (Flat XML)</comment>
- <comment xml:lang="zh_CN">ODG 绘图(Flat XML)</comment>
+ <comment xml:lang="zh_CN">ODG 绘图(Flat XML)</comment>
<comment xml:lang="zh_TW">ODG 繪圖 (Flat XML)</comment>
<acronym>FODG</acronym>
<expanded-acronym>OpenDocument Drawing (Flat XML)</expanded-acronym>
@@ -5601,7 +5752,7 @@
<comment xml:lang="pt">modelo ODG</comment>
<comment xml:lang="pt_BR">Modelo ODG</comment>
<comment xml:lang="ro">Șablon ODG</comment>
- <comment xml:lang="ru">шаблон ODG</comment>
+ <comment xml:lang="ru">Шаблон ODG</comment>
<comment xml:lang="sk">Šablóna ODG</comment>
<comment xml:lang="sl">Predloga dokumenta ODG</comment>
<comment xml:lang="sq">Model ODG</comment>
@@ -5664,7 +5815,7 @@
<comment xml:lang="pt">apresentação ODP</comment>
<comment xml:lang="pt_BR">Apresentação ODP</comment>
<comment xml:lang="ro">Prezentare ODP</comment>
- <comment xml:lang="ru">презентация ODP</comment>
+ <comment xml:lang="ru">Презентация ODP</comment>
<comment xml:lang="sk">Prezentácia ODP</comment>
<comment xml:lang="sl">Predstavitev ODP</comment>
<comment xml:lang="sq">Prezantim ODP</comment>
@@ -5723,14 +5874,14 @@
<comment xml:lang="pt">apresentação ODP (XML plano)</comment>
<comment xml:lang="pt_BR">Apresentação ODP (Flat XML)</comment>
<comment xml:lang="ro">Prezentare ODP (XML simplu)</comment>
- <comment xml:lang="ru">презентация ODP (простой XML)</comment>
+ <comment xml:lang="ru">Презентация ODP (простой XML)</comment>
<comment xml:lang="sk">Prezentácia ODP (čisté XML)</comment>
<comment xml:lang="sl">Predstavitev ODP (nepovezan XML)</comment>
<comment xml:lang="sr">ОДП презентација (Обични ИксМЛ)</comment>
<comment xml:lang="sv">ODP-presentation (platt XML)</comment>
<comment xml:lang="tr">ODP sunumu (Düz XML)</comment>
<comment xml:lang="uk">презентація ODP (Flat XML)</comment>
- <comment xml:lang="zh_CN">ODP 演示文稿(Flat XML)</comment>
+ <comment xml:lang="zh_CN">ODP 演示文稿(Flat XML)</comment>
<comment xml:lang="zh_TW">ODP 範本 (Flat XML)</comment>
<acronym>FODP</acronym>
<expanded-acronym>OpenDocument Presentation (Flat XML)</expanded-acronym>
@@ -5777,7 +5928,7 @@
<comment xml:lang="pt">modelo ODP</comment>
<comment xml:lang="pt_BR">Modelo ODP</comment>
<comment xml:lang="ro">Șablon ODP</comment>
- <comment xml:lang="ru">шаблон ODP</comment>
+ <comment xml:lang="ru">Шаблон ODP</comment>
<comment xml:lang="sk">Šablóna ODP</comment>
<comment xml:lang="sl">Predloga dokumenta ODP</comment>
<comment xml:lang="sq">Model ODP</comment>
@@ -5840,16 +5991,16 @@
<comment xml:lang="pt">folha de cálculo ODS</comment>
<comment xml:lang="pt_BR">Planilha ODS</comment>
<comment xml:lang="ro">Foaie de calcul ODS</comment>
- <comment xml:lang="ru">электронная таблица ODS</comment>
+ <comment xml:lang="ru">Электронная таблица ODS</comment>
<comment xml:lang="sk">Zošit ODS</comment>
<comment xml:lang="sl">Preglednica ODS</comment>
<comment xml:lang="sq">Fletë llogaritjesh ODS</comment>
- <comment xml:lang="sr">ОДС spreadsheet</comment>
+ <comment xml:lang="sr">ОДС табела</comment>
<comment xml:lang="sv">ODS-kalkylblad</comment>
<comment xml:lang="tr">ODS çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця ODS</comment>
<comment xml:lang="vi">Bảng tính ODS</comment>
- <comment xml:lang="zh_CN">ODS 工作簿</comment>
+ <comment xml:lang="zh_CN">ODS 电子表格</comment>
<comment xml:lang="zh_TW">ODS 試算表</comment>
<acronym>ODS</acronym>
<expanded-acronym>OpenDocument Spreadsheet</expanded-acronym>
@@ -5899,14 +6050,14 @@
<comment xml:lang="pt">folha de cálculo ODS (XML plano)</comment>
<comment xml:lang="pt_BR">Planilha ODS (Flat XML)</comment>
<comment xml:lang="ro">Foaie de calcul ODS (XML simplu)</comment>
- <comment xml:lang="ru">электронная таблица ODS (простой XML)</comment>
+ <comment xml:lang="ru">Электронная таблица ODS (простой XML)</comment>
<comment xml:lang="sk">Zošit ODS (čisté XML)</comment>
<comment xml:lang="sl">Preglednica ODS (nepovezan XML)</comment>
- <comment xml:lang="sr">ОДС spreadsheet (Обични ИксМЛ)</comment>
+ <comment xml:lang="sr">ОДС табела (обични ИксМЛ)</comment>
<comment xml:lang="sv">ODS-kalkylblad (platt XML)</comment>
<comment xml:lang="tr">ODS sunumu (Düz XML)</comment>
<comment xml:lang="uk">ел. таблиця ODS (Flat XML)</comment>
- <comment xml:lang="zh_CN">ODS 工作簿(Flat XML)</comment>
+ <comment xml:lang="zh_CN">ODS 电子表格 (Flat XML)</comment>
<comment xml:lang="zh_TW">ODS 試算表 (Flat XML)</comment>
<acronym>FODS</acronym>
<expanded-acronym>OpenDocument Spreadsheet (Flat XML)</expanded-acronym>
@@ -5953,7 +6104,7 @@
<comment xml:lang="pt">modelo ODS</comment>
<comment xml:lang="pt_BR">Modelo ODS</comment>
<comment xml:lang="ro">Șablon ODS</comment>
- <comment xml:lang="ru">шаблон ODS</comment>
+ <comment xml:lang="ru">Шаблон ODS</comment>
<comment xml:lang="sk">Šablóna ODS</comment>
<comment xml:lang="sl">Predloga dokumenta ODS</comment>
<comment xml:lang="sq">Model ODS</comment>
@@ -6015,11 +6166,11 @@
<comment xml:lang="pt">gráfico ODC</comment>
<comment xml:lang="pt_BR">Gráfico ODC</comment>
<comment xml:lang="ro">Diagramă ODC</comment>
- <comment xml:lang="ru">диаграмма ODC</comment>
+ <comment xml:lang="ru">Диаграмма ODC</comment>
<comment xml:lang="sk">Graf ODC</comment>
<comment xml:lang="sl">Datoteka grafikona ODC</comment>
<comment xml:lang="sq">Grafik ODC</comment>
- <comment xml:lang="sr">ОДЦ chart</comment>
+ <comment xml:lang="sr">ОДЦ график</comment>
<comment xml:lang="sv">ODC-diagram</comment>
<comment xml:lang="tr">ODC çizelgesi</comment>
<comment xml:lang="uk">діаграма ODC</comment>
@@ -6075,7 +6226,7 @@
<comment xml:lang="pt">modelo ODC</comment>
<comment xml:lang="pt_BR">Modelo ODC</comment>
<comment xml:lang="ro">Șablon ODC</comment>
- <comment xml:lang="ru">шаблон ODC</comment>
+ <comment xml:lang="ru">Шаблон ODC</comment>
<comment xml:lang="sk">Šablóna ODC</comment>
<comment xml:lang="sl">Predloga ODC</comment>
<comment xml:lang="sr">ОДЦ шаблон</comment>
@@ -6137,11 +6288,11 @@
<comment xml:lang="pt">fórmula ODF</comment>
<comment xml:lang="pt_BR">Fórmula ODF</comment>
<comment xml:lang="ro">Formulă ODF</comment>
- <comment xml:lang="ru">формула ODF</comment>
+ <comment xml:lang="ru">Формула ODF</comment>
<comment xml:lang="sk">Vzorec ODF</comment>
<comment xml:lang="sl">Dokument formule ODF</comment>
<comment xml:lang="sq">Formulë ODF</comment>
- <comment xml:lang="sr">ОДФ formula</comment>
+ <comment xml:lang="sr">ОДФ формула</comment>
<comment xml:lang="sv">ODF-formel</comment>
<comment xml:lang="tr">ODF formülü</comment>
<comment xml:lang="uk">формула ODF</comment>
@@ -6197,7 +6348,7 @@
<comment xml:lang="pt">modelo ODF</comment>
<comment xml:lang="pt_BR">Modelo ODF</comment>
<comment xml:lang="ro">Șablon ODF</comment>
- <comment xml:lang="ru">шаблон ODF</comment>
+ <comment xml:lang="ru">Шаблон ODF</comment>
<comment xml:lang="sk">Šablóna ODF</comment>
<comment xml:lang="sl">Predloga dokumenta ODF</comment>
<comment xml:lang="sr">ОДФ шаблон</comment>
@@ -6259,7 +6410,7 @@
<comment xml:lang="pt">base de dados ODB</comment>
<comment xml:lang="pt_BR">Banco de dados ODB</comment>
<comment xml:lang="ro">Bază de date ODB</comment>
- <comment xml:lang="ru">база данных ODB</comment>
+ <comment xml:lang="ru">База данных ODB</comment>
<comment xml:lang="sk">Databáza ODB</comment>
<comment xml:lang="sl">Podatkovna zbirka ODB</comment>
<comment xml:lang="sq">Bazë me të dhëna ODB</comment>
@@ -6287,6 +6438,7 @@
<mime-type type="application/vnd.oasis.opendocument.image">
<comment>ODI image</comment>
<comment xml:lang="ar">صورة ODI</comment>
+ <comment xml:lang="ast">Imaxe ODI</comment>
<comment xml:lang="be@latin">Vyjava ODI</comment>
<comment xml:lang="bg">Изображение — ODI</comment>
<comment xml:lang="ca">imatge ODI</comment>
@@ -6323,7 +6475,7 @@
<comment xml:lang="pt">imagem ODI</comment>
<comment xml:lang="pt_BR">Imagem ODI</comment>
<comment xml:lang="ro">Imagine ODI</comment>
- <comment xml:lang="ru">изображение ODI</comment>
+ <comment xml:lang="ru">Изображение ODI</comment>
<comment xml:lang="sk">Obrázok ODI</comment>
<comment xml:lang="sl">Slikovna datoteka ODI</comment>
<comment xml:lang="sq">Figurë ODI</comment>
@@ -6350,6 +6502,7 @@
<mime-type type="application/vnd.openofficeorg.extension">
<comment>OpenOffice.org extension</comment>
<comment xml:lang="ar">امتداد OpenOffice.org</comment>
+ <comment xml:lang="ast">Estensión d'OpenOffice.org</comment>
<comment xml:lang="be@latin">Pašyreńnie OpenOffice.org</comment>
<comment xml:lang="bg">Разширение — OpenOffice</comment>
<comment xml:lang="ca">extensió d'OpenOffice.org</comment>
@@ -6384,7 +6537,7 @@
<comment xml:lang="pt">extensão OpenOffice.org</comment>
<comment xml:lang="pt_BR">Extensão do OpenOffice</comment>
<comment xml:lang="ro">Extensie OpenOffice.org</comment>
- <comment xml:lang="ru">расширение OpenOffice.org</comment>
+ <comment xml:lang="ru">Расширение OpenOffice.org</comment>
<comment xml:lang="sk">Rozšírenie OpenOffice.org</comment>
<comment xml:lang="sl">Razširitev OpenOffice.org</comment>
<comment xml:lang="sq">Shtojcë për OpenOffice.org</comment>
@@ -6401,6 +6554,7 @@
</mime-type>
<mime-type type="application/vnd.android.package-archive">
<comment>Android package</comment>
+ <comment xml:lang="ast">Paquete d'Android</comment>
<comment xml:lang="bg">Пакет — Android</comment>
<comment xml:lang="ca">paquet d'Android</comment>
<comment xml:lang="cs">balíčky systému Android</comment>
@@ -6413,6 +6567,7 @@
<comment xml:lang="eu">Android paketea</comment>
<comment xml:lang="fi">Android-paketti</comment>
<comment xml:lang="fr">paquet Android</comment>
+ <comment xml:lang="ga">pacáiste Android</comment>
<comment xml:lang="gl">paquete de Android</comment>
<comment xml:lang="he">חבילת אנדרויד</comment>
<comment xml:lang="hr">Android paket</comment>
@@ -6430,14 +6585,14 @@
<comment xml:lang="pl">Pakiet Androida</comment>
<comment xml:lang="pt">pacote Android</comment>
<comment xml:lang="pt_BR">Pacote do Android</comment>
- <comment xml:lang="ru">пакет Android</comment>
+ <comment xml:lang="ru">Пакет Android</comment>
<comment xml:lang="sk">Balík Android</comment>
<comment xml:lang="sl">Paket Android</comment>
<comment xml:lang="sr">Андроидов пакет</comment>
<comment xml:lang="sv">Android-paket</comment>
<comment xml:lang="tr">Android paketi</comment>
<comment xml:lang="uk">пакунок Android</comment>
- <comment xml:lang="zh_CN">Android</comment>
+ <comment xml:lang="zh_CN">Android 应用包</comment>
<comment xml:lang="zh_TW">Android 軟體包</comment>
<sub-class-of type="application/x-java-archive"/>
<glob pattern="*.apk"/>
@@ -6445,6 +6600,7 @@
<mime-type type="application/vnd.symbian.install">
<comment>SIS package</comment>
<comment xml:lang="ar">حزمة SIS</comment>
+ <comment xml:lang="ast">Paquete SIS</comment>
<comment xml:lang="be@latin">Pakunak SIS</comment>
<comment xml:lang="bg">Пакет — SIS</comment>
<comment xml:lang="ca">paquet SIS</comment>
@@ -6480,7 +6636,7 @@
<comment xml:lang="pt">pacote SIS</comment>
<comment xml:lang="pt_BR">Pacote SIS</comment>
<comment xml:lang="ro">Pachet SIS</comment>
- <comment xml:lang="ru">пакет SIS</comment>
+ <comment xml:lang="ru">Пакет SIS</comment>
<comment xml:lang="sk">Balíček SIS</comment>
<comment xml:lang="sl">Datoteka paketa SIS</comment>
<comment xml:lang="sq">Paketë SIS</comment>
@@ -6502,6 +6658,7 @@
<mime-type type="x-epoc/x-sisx-app">
<comment>SISX package</comment>
<comment xml:lang="ar">حزمة SISX</comment>
+ <comment xml:lang="ast">Paquete SISX</comment>
<comment xml:lang="be@latin">Pakunak SISX</comment>
<comment xml:lang="bg">Пакет — SISX</comment>
<comment xml:lang="ca">paquet SISX</comment>
@@ -6537,7 +6694,7 @@
<comment xml:lang="pt">pacote SISX</comment>
<comment xml:lang="pt_BR">Pacote SISX</comment>
<comment xml:lang="ro">Pachet SISX</comment>
- <comment xml:lang="ru">пакет SISX</comment>
+ <comment xml:lang="ru">Пакет SISX</comment>
<comment xml:lang="sk">Balíček SISX</comment>
<comment xml:lang="sl">Datoteka paketa SISX</comment>
<comment xml:lang="sq">Paketë SISX</comment>
@@ -6569,6 +6726,7 @@
<comment xml:lang="eu">Sareko pakete kaptura</comment>
<comment xml:lang="fi">Verkkopakettien kaappaus</comment>
<comment xml:lang="fr">capture de paquet réseau</comment>
+ <comment xml:lang="ga">Gabháltas Paicéid Líonra</comment>
<comment xml:lang="gl">Captura de Network Packet</comment>
<comment xml:lang="he">לכידה של מנות נתונים ברשת</comment>
<comment xml:lang="hr">Mrežno hvatanje paketa</comment>
@@ -6586,7 +6744,7 @@
<comment xml:lang="pl">Przechwycenie pakietu sieciowego</comment>
<comment xml:lang="pt">captura Network Packet</comment>
<comment xml:lang="pt_BR">Pacote de captura de rede</comment>
- <comment xml:lang="ru">захваченные сетевые пакеты</comment>
+ <comment xml:lang="ru">Захваченные сетевые пакеты</comment>
<comment xml:lang="sk">Zachytené sieťové pakety</comment>
<comment xml:lang="sl">Zajem omrežnih paketov</comment>
<comment xml:lang="sr">Снимање мрежног пакета</comment>
@@ -6608,6 +6766,7 @@
<mime-type type="application/vnd.wordperfect">
<comment>WordPerfect document</comment>
<comment xml:lang="ar">مستند WordPerfect</comment>
+ <comment xml:lang="ast">Documentu de WordPerfect</comment>
<comment xml:lang="az">WordPerfect sənədi</comment>
<comment xml:lang="be@latin">Dakument WordPerfect</comment>
<comment xml:lang="bg">Документ — WordPerfect</comment>
@@ -6646,11 +6805,11 @@
<comment xml:lang="pt">documento WordPerfect</comment>
<comment xml:lang="pt_BR">Documento do WordPerfect</comment>
<comment xml:lang="ro">Document WordPerfect</comment>
- <comment xml:lang="ru">документ WordPerfect</comment>
+ <comment xml:lang="ru">Документ WordPerfect</comment>
<comment xml:lang="sk">Dokument WordPerfect</comment>
<comment xml:lang="sl">Dokument WordPerfect</comment>
<comment xml:lang="sq">Dokument WordPerfect</comment>
- <comment xml:lang="sr">документ Ворд Перфекта</comment>
+ <comment xml:lang="sr">документ Ворд перфекта</comment>
<comment xml:lang="sv">WordPerfect-dokument</comment>
<comment xml:lang="tr">WordPerfect belgesi</comment>
<comment xml:lang="uk">документ WordPerfect</comment>
@@ -6671,6 +6830,12 @@
<glob pattern="*.wpd"/>
<glob pattern="*.wpp"/>
</mime-type>
+ <mime-type type="application/vnd.youtube.yt">
+ <comment>YouTube Media Archive</comment>
+ <generic-icon name="video-x-generic"/>
+ <glob pattern="*.yt"/>
+ <sub-class-of type="application/zip"/>
+ </mime-type>
<mime-type type="application/x-spss-por">
<comment>SPSS Portable Data File</comment>
<comment xml:lang="ar">ملف بيانات SPSS متنقلة</comment>
@@ -6704,7 +6869,7 @@
<comment xml:lang="pt">ficheiro de dados portátil SPSS</comment>
<comment xml:lang="pt_BR">Arquivo de Dados Portáteis SPSS</comment>
<comment xml:lang="ro">Fișier portabil de date SPSS</comment>
- <comment xml:lang="ru">файл переносимых данных SPSS</comment>
+ <comment xml:lang="ru">Файл переносимых данных SPSS</comment>
<comment xml:lang="sk">Súbor prenosných dát SPSS</comment>
<comment xml:lang="sl">Prenosna podatkovna datoteka SPSS</comment>
<comment xml:lang="sr">СПСС датотека преносних података</comment>
@@ -6730,6 +6895,7 @@
<comment xml:lang="en_GB">SPSS Data File</comment>
<comment xml:lang="es">archivo de datos SPSS</comment>
<comment xml:lang="eu">SPSS datuen fitxategia</comment>
+ <comment xml:lang="fi">SPSS-datatiedosto</comment>
<comment xml:lang="fo">SPSS dátufíla</comment>
<comment xml:lang="fr">fichier de données SPSS</comment>
<comment xml:lang="ga">comhad sonraí SPSS</comment>
@@ -6751,7 +6917,7 @@
<comment xml:lang="pt">ficheiro de dados SPSS</comment>
<comment xml:lang="pt_BR">Arquivo de dados SPSS</comment>
<comment xml:lang="ro">Fișier date SPSS</comment>
- <comment xml:lang="ru">файл данных SPSS</comment>
+ <comment xml:lang="ru">Файл данных SPSS</comment>
<comment xml:lang="sk">Dátový súbor SPSS</comment>
<comment xml:lang="sl">Podatkovna datoteka SPSS</comment>
<comment xml:lang="sr">СПСС датотека података</comment>
@@ -6788,7 +6954,7 @@
<comment xml:lang="ga">leabharmharcanna XBEL</comment>
<comment xml:lang="gl">Marcadores XBEL</comment>
<comment xml:lang="he">סימניית XBEL</comment>
- <comment xml:lang="hr">XBEL knjižne oznake</comment>
+ <comment xml:lang="hr">XBEL zabilješka</comment>
<comment xml:lang="hu">XBEL-könyvjelzők</comment>
<comment xml:lang="ia">Marcapaginas XBEL</comment>
<comment xml:lang="id">Bookmark XBEL</comment>
@@ -6807,7 +6973,7 @@
<comment xml:lang="pt">marcadores XBEL</comment>
<comment xml:lang="pt_BR">Marcadores do XBEL</comment>
<comment xml:lang="ro">Semne de carte XBEL</comment>
- <comment xml:lang="ru">закладки XBEL</comment>
+ <comment xml:lang="ru">Закладки XBEL</comment>
<comment xml:lang="sk">Záložky XBEL</comment>
<comment xml:lang="sl">Datoteka zaznamkov XBEL</comment>
<comment xml:lang="sq">Libërshënues XBEL</comment>
@@ -6830,6 +6996,7 @@
<mime-type type="application/x-7z-compressed">
<comment>7-zip archive</comment>
<comment xml:lang="ar">أرشيف 7-zip</comment>
+ <comment xml:lang="ast">Archivu 7-zip</comment>
<comment xml:lang="be@latin">Archiŭ 7-zip</comment>
<comment xml:lang="bg">Архив — 7-zip</comment>
<comment xml:lang="ca">arxiu 7-zip</comment>
@@ -6866,7 +7033,7 @@
<comment xml:lang="pt">arquivo 7-zip</comment>
<comment xml:lang="pt_BR">Pacote 7-Zip</comment>
<comment xml:lang="ro">Arhivă 7-zip</comment>
- <comment xml:lang="ru">архив 7-zip</comment>
+ <comment xml:lang="ru">Архив 7-zip</comment>
<comment xml:lang="sk">Archív 7-zip</comment>
<comment xml:lang="sl">Datoteka arhiva 7-zip</comment>
<comment xml:lang="sq">Arkiv 7-zip</comment>
@@ -6886,6 +7053,7 @@
<mime-type type="application/x-abiword">
<comment>AbiWord document</comment>
<comment xml:lang="ar">مستند آبي وورد</comment>
+ <comment xml:lang="ast">Documentu d'AbiWord</comment>
<comment xml:lang="be@latin">Dakument AbiWord</comment>
<comment xml:lang="bg">Документ — AbiWord</comment>
<comment xml:lang="ca">document AbiWord</comment>
@@ -6923,7 +7091,7 @@
<comment xml:lang="pt">documento AbiWord</comment>
<comment xml:lang="pt_BR">Documento do AbiWord</comment>
<comment xml:lang="ro">Document AbiWord</comment>
- <comment xml:lang="ru">документ AbiWord</comment>
+ <comment xml:lang="ru">Документ AbiWord</comment>
<comment xml:lang="sk">Dokument AbiWord</comment>
<comment xml:lang="sl">Dokument AbiWord</comment>
<comment xml:lang="sq">Dokument AbiWord</comment>
@@ -6961,7 +7129,7 @@
<comment xml:lang="eu">CD irudiaren CUE orria</comment>
<comment xml:lang="fi">CD-vedos cuesheet</comment>
<comment xml:lang="fr">index de pistes de CD</comment>
- <comment xml:lang="ga">bileog chiúáil íomhá CD</comment>
+ <comment xml:lang="ga">bileog chiúála íomhá CD</comment>
<comment xml:lang="gl">cue sheet dunha imaxe de CD</comment>
<comment xml:lang="he">גליון נתונים לתמונת דיסק</comment>
<comment xml:lang="hr">CD slika s meta podacima</comment>
@@ -6982,11 +7150,11 @@
<comment xml:lang="pt">índice de CD de imagem</comment>
<comment xml:lang="pt_BR">Índice de Imagem de CD</comment>
<comment xml:lang="ro">Imagine CD cuesheet</comment>
- <comment xml:lang="ru">таблица содержания образа CD</comment>
+ <comment xml:lang="ru">Таблица содержания образа CD</comment>
<comment xml:lang="sk">Rozvrhnutie stôp obrazu CD</comment>
<comment xml:lang="sl">Datoteka razpredelnice odtisa CD cue</comment>
<comment xml:lang="sq">Cuesheet imazhi CD</comment>
- <comment xml:lang="sr">редослед слика ЦД-а</comment>
+ <comment xml:lang="sr">Кју лист ЦД одраза</comment>
<comment xml:lang="sv">Indexblad för cd-avbild</comment>
<comment xml:lang="tr">CD görüntüsü belgesi</comment>
<comment xml:lang="uk">таблиця CUE образу CD</comment>
@@ -7000,6 +7168,7 @@
<mime-type type="application/x-amipro">
<comment>Lotus AmiPro document</comment>
<comment xml:lang="ar">مستند Lotus AmiPro</comment>
+ <comment xml:lang="ast">Documentu de Lotus AmiPro</comment>
<comment xml:lang="az">Lotus AmiPro sənədi</comment>
<comment xml:lang="be@latin">Dakument Lotus AmiPro</comment>
<comment xml:lang="bg">Документ — Lotus AmiPro</comment>
@@ -7038,7 +7207,7 @@
<comment xml:lang="pt">documento Lotus AmiPro</comment>
<comment xml:lang="pt_BR">Documento do Lotus AmiPro</comment>
<comment xml:lang="ro">Document Lotus AmiPro</comment>
- <comment xml:lang="ru">документ Lotus AmiPro</comment>
+ <comment xml:lang="ru">Документ Lotus AmiPro</comment>
<comment xml:lang="sk">Dokument Lotus AmiPro</comment>
<comment xml:lang="sl">Dokument Lotus AmiPro</comment>
<comment xml:lang="sq">Dokument Lotus AmiPro</comment>
@@ -7055,6 +7224,7 @@
<mime-type type="application/x-aportisdoc">
<comment>AportisDoc document</comment>
<comment xml:lang="ar">مستند AportisDoc</comment>
+ <comment xml:lang="ast">Documentu d'AportisDoc</comment>
<comment xml:lang="bg">Документ — AportisDoc</comment>
<comment xml:lang="ca">document AportisDoc</comment>
<comment xml:lang="cs">dokument AportisDoc</comment>
@@ -7088,7 +7258,7 @@
<comment xml:lang="pt">documento AportisDoc</comment>
<comment xml:lang="pt_BR">Documento do AportisDoc</comment>
<comment xml:lang="ro">Document AportisDoc</comment>
- <comment xml:lang="ru">документ AportisDoc</comment>
+ <comment xml:lang="ru">Документ AportisDoc</comment>
<comment xml:lang="sk">Dokument AportisDoc</comment>
<comment xml:lang="sl">Dokument AportisDoc</comment>
<comment xml:lang="sr">Апортис Док документ</comment>
@@ -7147,7 +7317,7 @@
<comment xml:lang="pt">folha de cálculo Applix Spreadsheets</comment>
<comment xml:lang="pt_BR">Planilha do Applix Spreadsheets</comment>
<comment xml:lang="ro">Foaie de calcul Applix</comment>
- <comment xml:lang="ru">электронная таблица Applix Spreadsheets</comment>
+ <comment xml:lang="ru">Электронная таблица Applix Spreadsheets</comment>
<comment xml:lang="sk">Zošit Applix Spreadsheets</comment>
<comment xml:lang="sl">Razpredelnica Applix Spreadsheets</comment>
<comment xml:lang="sq">Fletë llogaritjesh Applix Spreadsheets</comment>
@@ -7156,7 +7326,7 @@
<comment xml:lang="tr">Applix Spreadsheets çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця Applix Spreadsheets</comment>
<comment xml:lang="vi">Bảng tính Applix Spreadsheets</comment>
- <comment xml:lang="zh_CN">Applix Spreadsheets 工作簿</comment>
+ <comment xml:lang="zh_CN">Applix Spreadsheets 电子表格</comment>
<comment xml:lang="zh_TW">Applix Spreadsheets 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<magic priority="50">
@@ -7170,6 +7340,7 @@
<mime-type type="application/x-applix-word">
<comment>Applix Words document</comment>
<comment xml:lang="ar">مستند كلمات Applix</comment>
+ <comment xml:lang="ast">Documentu d'Applix Words</comment>
<comment xml:lang="az">Applix Words sənədi</comment>
<comment xml:lang="be@latin">Dakument Applix Words</comment>
<comment xml:lang="bg">Документ — Applix Words</comment>
@@ -7209,7 +7380,7 @@
<comment xml:lang="pt">documento Applix Words</comment>
<comment xml:lang="pt_BR">Documento do Applix Words</comment>
<comment xml:lang="ro">Document Applix Words</comment>
- <comment xml:lang="ru">документ Applix Words</comment>
+ <comment xml:lang="ru">Документ Applix Words</comment>
<comment xml:lang="sk">Dokument Applix Words</comment>
<comment xml:lang="sl">Dokument Applix Words</comment>
<comment xml:lang="sq">Dokument Applix Words</comment>
@@ -7267,7 +7438,7 @@
<comment xml:lang="pt">arquivo ARC</comment>
<comment xml:lang="pt_BR">Pacote ARC</comment>
<comment xml:lang="ro">Arhivă ARC</comment>
- <comment xml:lang="ru">архив ARC</comment>
+ <comment xml:lang="ru">Архив ARC</comment>
<comment xml:lang="sk">Archív ARC</comment>
<comment xml:lang="sl">Datoteka arhiva ARC</comment>
<comment xml:lang="sq">Arkiv ARC</comment>
@@ -7328,7 +7499,7 @@
<comment xml:lang="pt">arquivo AR</comment>
<comment xml:lang="pt_BR">Pacote AR</comment>
<comment xml:lang="ro">Arhivă AR</comment>
- <comment xml:lang="ru">архив AR</comment>
+ <comment xml:lang="ru">Архив AR</comment>
<comment xml:lang="sk">Archív AR</comment>
<comment xml:lang="sl">Datoteka arhiva AR</comment>
<comment xml:lang="sq">Arkiv AR</comment>
@@ -7389,7 +7560,7 @@
<comment xml:lang="pt">arquivo ARJ</comment>
<comment xml:lang="pt_BR">Pacote ARJ</comment>
<comment xml:lang="ro">Arhivă ARJ</comment>
- <comment xml:lang="ru">архив ARJ</comment>
+ <comment xml:lang="ru">Архив ARJ</comment>
<comment xml:lang="sk">Archív ARJ</comment>
<comment xml:lang="sl">Datoteka arhiva ARJ</comment>
<comment xml:lang="sq">Arkiv ARJ</comment>
@@ -7411,6 +7582,7 @@
<mime-type type="application/x-asp">
<comment>ASP page</comment>
<comment xml:lang="ar">صفحة ASP</comment>
+ <comment xml:lang="ast">Páxina ASP</comment>
<comment xml:lang="be@latin">Staronka ASP</comment>
<comment xml:lang="bg">Страница — ASP</comment>
<comment xml:lang="ca">pàgina ASP</comment>
@@ -7447,7 +7619,7 @@
<comment xml:lang="pt">página ASP</comment>
<comment xml:lang="pt_BR">Página ASP</comment>
<comment xml:lang="ro">Pagină ASP</comment>
- <comment xml:lang="ru">страница ASP</comment>
+ <comment xml:lang="ru">Страница ASP</comment>
<comment xml:lang="sk">Stránka ASP</comment>
<comment xml:lang="sl">Datoteka spletne strani ASP</comment>
<comment xml:lang="sq">Faqe ASP</comment>
@@ -7467,6 +7639,7 @@
<mime-type type="application/x-awk">
<comment>AWK script</comment>
<comment xml:lang="ar">سكربت AWK</comment>
+ <comment xml:lang="ast">Script AWK</comment>
<comment xml:lang="az">AWK skripti</comment>
<comment xml:lang="be@latin">Skrypt AWK</comment>
<comment xml:lang="bg">Скрипт — AWK</comment>
@@ -7506,7 +7679,7 @@
<comment xml:lang="pt">script AWK</comment>
<comment xml:lang="pt_BR">Script AWK</comment>
<comment xml:lang="ro">Script AWK</comment>
- <comment xml:lang="ru">сценарий AWK</comment>
+ <comment xml:lang="ru">Сценарий AWK</comment>
<comment xml:lang="sk">Skript AWK</comment>
<comment xml:lang="sl">Skriptna datoteka AWK</comment>
<comment xml:lang="sq">Script AWK</comment>
@@ -7537,6 +7710,7 @@
<mime-type type="application/x-bcpio">
<comment>BCPIO document</comment>
<comment xml:lang="ar">مستند BCPIO</comment>
+ <comment xml:lang="ast">Documentu BCPIO</comment>
<comment xml:lang="az">BCPIO sənədi</comment>
<comment xml:lang="be@latin">Dakument BCPIO</comment>
<comment xml:lang="bg">Документ — BCPIO</comment>
@@ -7576,7 +7750,7 @@
<comment xml:lang="pt">documento BCPIO</comment>
<comment xml:lang="pt_BR">Documento BCPIO</comment>
<comment xml:lang="ro">Document BCPIO</comment>
- <comment xml:lang="ru">документ BCPIO</comment>
+ <comment xml:lang="ru">Документ BCPIO</comment>
<comment xml:lang="sk">Dokument BCPIO</comment>
<comment xml:lang="sl">Dokument BCPIO</comment>
<comment xml:lang="sq">Dokument BCPIO</comment>
@@ -7633,7 +7807,7 @@
<comment xml:lang="pt">ficheiro de semente BitTorrent</comment>
<comment xml:lang="pt_BR">Arquivo semente BitTorrent</comment>
<comment xml:lang="ro">Fișier sursă-completă BitTorrent</comment>
- <comment xml:lang="ru">файл источника BitTorrent</comment>
+ <comment xml:lang="ru">Файл источника BitTorrent</comment>
<comment xml:lang="sk">Súbor BitTorrent</comment>
<comment xml:lang="sl">Datoteka sejanja BitTorrent</comment>
<comment xml:lang="sq">File bazë BitTorrent</comment>
@@ -7652,6 +7826,7 @@
<mime-type type="application/x-blender">
<comment>Blender scene</comment>
<comment xml:lang="ar">مشهد بلندر</comment>
+ <comment xml:lang="ast">Escena de Blender</comment>
<comment xml:lang="be@latin">Scena Blender</comment>
<comment xml:lang="bg">Сцена — Blender</comment>
<comment xml:lang="ca">escena de Blender</comment>
@@ -7689,7 +7864,7 @@
<comment xml:lang="pt">cenário Blender</comment>
<comment xml:lang="pt_BR">Cena do Blender</comment>
<comment xml:lang="ro">Scenă Blender</comment>
- <comment xml:lang="ru">сцена Blender</comment>
+ <comment xml:lang="ru">Сцена Blender</comment>
<comment xml:lang="sk">Scéna Blender</comment>
<comment xml:lang="sl">Datoteka scene Blender</comment>
<comment xml:lang="sq">Skenë Blender</comment>
@@ -7711,6 +7886,7 @@
<mime-type type="application/x-bzdvi">
<comment>TeX DVI document (bzip-compressed)</comment>
<comment xml:lang="ar">مستند TeX DVI (مضغوط-bzip)</comment>
+ <comment xml:lang="ast">Documentu Tex DVI (comprimíu en bzip)</comment>
<comment xml:lang="be@latin">Dakument TeX DVI (bzip-skampresavany)</comment>
<comment xml:lang="bg">Документ — TeX DVI, компресиран с bzip</comment>
<comment xml:lang="ca">document de TeX DVI (amb compressió bzip)</comment>
@@ -7727,7 +7903,7 @@
<comment xml:lang="ga">cáipéis DVI TeX (comhbhrúite le bzip)</comment>
<comment xml:lang="gl">documento DVI de TeX (comprimido con bzip)</comment>
<comment xml:lang="he">מסמך מסוג TeX DVI (מכווץ ע״י bzip)</comment>
- <comment xml:lang="hr">TeX DVI dokument (komprimiran bzip-om)</comment>
+ <comment xml:lang="hr">TeX DVI dokument (bzip sažeto)</comment>
<comment xml:lang="hu">TeX DVI dokumentum (bzip-pel tömörítve)</comment>
<comment xml:lang="ia">Documento TeX DVI (comprimite con bzip)</comment>
<comment xml:lang="id">Dokumen TeX DVI (terkompresi bzip)</comment>
@@ -7745,7 +7921,7 @@
<comment xml:lang="pt">documento TeX DVI (compressão bzip)</comment>
<comment xml:lang="pt_BR">Documento DVI TeX (compactado com bzip)</comment>
<comment xml:lang="ro">Document TeX DVI (comprimat bzip)</comment>
- <comment xml:lang="ru">документ TeX DVI (сжатый bzip)</comment>
+ <comment xml:lang="ru">Документ TeX DVI (сжатый bzip)</comment>
<comment xml:lang="sk">Dokument TeX DVI (komprimovaný pomocou bzip)</comment>
<comment xml:lang="sl">Dokument TeX DVI (stisnjen z bzip)</comment>
<comment xml:lang="sq">Dokument Tex DVI (i kompresuar me bzip)</comment>
@@ -7754,7 +7930,7 @@
<comment xml:lang="tr">TeX DVI belgesi (bzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">документ TeX DVI (стиснений bzip)</comment>
<comment xml:lang="vi">Tài liệu DVI TeX (đã nén bzip)</comment>
- <comment xml:lang="zh_CN">TeX DVI 文档(gzip 压缩)</comment>
+ <comment xml:lang="zh_CN">TeX DVI 文档(gzip 压缩)</comment>
<comment xml:lang="zh_TW">TeX DVI 文件 (bzip 格式壓縮)</comment>
<sub-class-of type="application/x-bzip"/>
<generic-icon name="x-office-document"/>
@@ -7763,6 +7939,7 @@
<mime-type type="application/x-bzip">
<comment>Bzip archive</comment>
<comment xml:lang="ar">أرشيف Bzip</comment>
+ <comment xml:lang="ast">Archivu Bzip</comment>
<comment xml:lang="be@latin">Archiŭ bzip</comment>
<comment xml:lang="bg">Архив — bzip</comment>
<comment xml:lang="ca">arxiu bzip</comment>
@@ -7799,7 +7976,7 @@
<comment xml:lang="pt">arquivo Bzip</comment>
<comment xml:lang="pt_BR">Pacote Bzip</comment>
<comment xml:lang="ro">Arhivă Bzip</comment>
- <comment xml:lang="ru">архив BZIP</comment>
+ <comment xml:lang="ru">Архив BZIP</comment>
<comment xml:lang="sk">Archív bzip</comment>
<comment xml:lang="sl">Datoteka arhiva Bzip</comment>
<comment xml:lang="sq">Arkiv bzip</comment>
@@ -7808,7 +7985,7 @@
<comment xml:lang="tr">Bzip arşivi</comment>
<comment xml:lang="uk">архів bzip</comment>
<comment xml:lang="vi">Kho nén bzip</comment>
- <comment xml:lang="zh_CN">bzip 归档文件</comment>
+ <comment xml:lang="zh_CN">Bzip 归档文件</comment>
<comment xml:lang="zh_TW">Bzip 封存檔</comment>
<generic-icon name="package-x-generic"/>
<magic priority="50">
@@ -7821,6 +7998,7 @@
<mime-type type="application/x-bzip-compressed-tar">
<comment>Tar archive (bzip-compressed)</comment>
<comment xml:lang="ar">أرشيف Tar (مضغوط-bzip)</comment>
+ <comment xml:lang="ast">Archivu Tar (comprimíu en bzip)</comment>
<comment xml:lang="be@latin">Archiŭ tar (bzip-skampresavany)</comment>
<comment xml:lang="bg">Архив — tar, компресиран с bzip</comment>
<comment xml:lang="ca">arxiu tar (amb compressió bzip)</comment>
@@ -7837,7 +8015,7 @@
<comment xml:lang="ga">cartlann Tar (comhbhrúite le bzip)</comment>
<comment xml:lang="gl">arquivo Tar (comprimido con bzip)</comment>
<comment xml:lang="he">ארכיון Tar (מכווץ ע״י bzip)</comment>
- <comment xml:lang="hr">Tar arhiva (komprimirana bzip-om)</comment>
+ <comment xml:lang="hr">Tar arhiva (bzip sažeto)</comment>
<comment xml:lang="hu">Tar archívum (bzip-pel tömörítve)</comment>
<comment xml:lang="ia">Archivo Tar (comprimite con bzip)</comment>
<comment xml:lang="id">Arsip Tar (terkompresi bzip)</comment>
@@ -7855,7 +8033,7 @@
<comment xml:lang="pt">arquivo Tar (compressão bzip)</comment>
<comment xml:lang="pt_BR">Pacote Tar (compactado com bzip)</comment>
<comment xml:lang="ro">Arhivă Tar (comprimată bzip)</comment>
- <comment xml:lang="ru">архив TAR (сжатый BZIP)</comment>
+ <comment xml:lang="ru">Архив TAR (сжатый bzip)</comment>
<comment xml:lang="sk">Archív tar (komprimovaný pomocou bzip)</comment>
<comment xml:lang="sl">Datoteka arhiva Tar (stisnjen z bzip)</comment>
<comment xml:lang="sq">Arkiv tar (i kompresuar me bzip)</comment>
@@ -7864,7 +8042,7 @@
<comment xml:lang="tr">Tar arşivi (bzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">архів tar (стиснений bzip)</comment>
<comment xml:lang="vi">Kho nén tar (đã nén bzip)</comment>
- <comment xml:lang="zh_CN">Tar 归档文件(bzip 压缩)</comment>
+ <comment xml:lang="zh_CN">Tar 归档文件(bzip 压缩)</comment>
<comment xml:lang="zh_TW">Tar 封存檔 (bzip 格式壓縮)</comment>
<generic-icon name="package-x-generic"/>
<sub-class-of type="application/x-bzip"/>
@@ -7877,6 +8055,7 @@
<mime-type type="application/x-bzpdf">
<comment>PDF document (bzip-compressed)</comment>
<comment xml:lang="ar">مستند PDF (مضغوط-bzip)</comment>
+ <comment xml:lang="ast">Documentu PDF (comprimíu en bzip)</comment>
<comment xml:lang="be@latin">Dakument PDF (bzip-skampresavany)</comment>
<comment xml:lang="bg">Документ — PDF, компресиран с bzip</comment>
<comment xml:lang="ca">document PDF (amb compressió bzip)</comment>
@@ -7911,7 +8090,7 @@
<comment xml:lang="pt">documento PDF (compressão bzip)</comment>
<comment xml:lang="pt_BR">Documento PDF (compactado com bzip)</comment>
<comment xml:lang="ro">Document PDF (comprimat bzip)</comment>
- <comment xml:lang="ru">документ PDF (сжатый bzip)</comment>
+ <comment xml:lang="ru">Документ PDF (сжатый bzip)</comment>
<comment xml:lang="sk">Dokument PDF (komprimovaný pomocou bzip)</comment>
<comment xml:lang="sl">Dokument PDF (stisnjen z bzip)</comment>
<comment xml:lang="sq">Dokument PDF (i kompresuar me bzip)</comment>
@@ -7920,7 +8099,7 @@
<comment xml:lang="tr">PDF belgesi (bzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">документ PDF (стиснений bzip)</comment>
<comment xml:lang="vi">Tài liệu PDF (đã nén bzip)</comment>
- <comment xml:lang="zh_CN">PDF 文档(bzip 压缩)</comment>
+ <comment xml:lang="zh_CN">PDF 文档(bzip 压缩)</comment>
<comment xml:lang="zh_TW">PDF 文件 (bzip 格式壓縮)</comment>
<sub-class-of type="application/x-bzip"/>
<generic-icon name="x-office-document"/>
@@ -7929,6 +8108,7 @@
<mime-type type="application/x-bzpostscript">
<comment>PostScript document (bzip-compressed)</comment>
<comment xml:lang="ar">مستند PostScript (مضغوط-bzip)</comment>
+ <comment xml:lang="ast">Documentu PostScript (comprimíu en bzip)</comment>
<comment xml:lang="be@latin">Dakument PostScript (bzip-skampresavany)</comment>
<comment xml:lang="bg">Документ — PostScript, компресиран с bzip</comment>
<comment xml:lang="ca">document PostScript (amb compressió bzip)</comment>
@@ -7963,7 +8143,7 @@
<comment xml:lang="pt">documento PostScript (compressão bzip)</comment>
<comment xml:lang="pt_BR">Documento PostScript (compactado com bzip)</comment>
<comment xml:lang="ro">Document PostScript (comprimat bzip)</comment>
- <comment xml:lang="ru">документ PostScript (сжатый bzip)</comment>
+ <comment xml:lang="ru">Документ PostScript (сжатый bzip)</comment>
<comment xml:lang="sk">Dokument PostScript (komprimovaný pomocou bzip)</comment>
<comment xml:lang="sl">Dokument PostScript (stisnjen z bzip)</comment>
<comment xml:lang="sq">Dokument PostScript (i kompresuar me bzip)</comment>
@@ -7972,13 +8152,13 @@
<comment xml:lang="tr">PostScript belgesi (bzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">документ PostScript (стиснене bzip)</comment>
<comment xml:lang="vi">Tài liệu PostScript (đã nén bzip)</comment>
- <comment xml:lang="zh_CN">PostScript 文档(bzip 压缩)</comment>
+ <comment xml:lang="zh_CN">PostScript 文档(bzip 压缩)</comment>
<comment xml:lang="zh_TW">PostScript 文件 (bzip 格式壓縮)</comment>
<sub-class-of type="application/x-bzip"/>
<generic-icon name="x-office-document"/>
<glob pattern="*.ps.bz2"/>
</mime-type>
- <mime-type type="application/x-cbr">
+ <mime-type type="application/vnd.comicbook-rar">
<comment>comic book archive</comment>
<comment xml:lang="ar">أرشيف comic book</comment>
<comment xml:lang="be@latin">archiŭ komiksaŭ</comment>
@@ -8015,7 +8195,7 @@
<comment xml:lang="pt">arquivo de banda desenhada</comment>
<comment xml:lang="pt_BR">Pacote de histórias em quadrinhos</comment>
<comment xml:lang="ro">arhivă benzi desenate</comment>
- <comment xml:lang="ru">архив комиксов</comment>
+ <comment xml:lang="ru">Архив комиксов</comment>
<comment xml:lang="sk">Archív knihy komiksov</comment>
<comment xml:lang="sl">Datoteka arhiva stripov</comment>
<comment xml:lang="sq">Arkiv comic book</comment>
@@ -8024,11 +8204,12 @@
<comment xml:lang="tr">çizgi roman arşivi</comment>
<comment xml:lang="uk">архів коміксів</comment>
<comment xml:lang="vi">Kho nén sách tranh chuyện vui</comment>
- <comment xml:lang="zh_CN">Comic Book 归档文件</comment>
+ <comment xml:lang="zh_CN">漫画书归档文件</comment>
<comment xml:lang="zh_TW">漫畫書封存檔</comment>
<sub-class-of type="application/vnd.rar"/>
<generic-icon name="x-office-document"/>
<glob pattern="*.cbr"/>
+ <alias type="application/x-cbr"/>
</mime-type>
<mime-type type="application/x-cb7">
<comment>comic book archive</comment>
@@ -8067,7 +8248,7 @@
<comment xml:lang="pt">arquivo de banda desenhada</comment>
<comment xml:lang="pt_BR">Pacote de histórias em quadrinhos</comment>
<comment xml:lang="ro">arhivă benzi desenate</comment>
- <comment xml:lang="ru">архив комиксов</comment>
+ <comment xml:lang="ru">Архив комиксов</comment>
<comment xml:lang="sk">Archív knihy komiksov</comment>
<comment xml:lang="sl">Datoteka arhiva stripov</comment>
<comment xml:lang="sq">Arkiv comic book</comment>
@@ -8076,7 +8257,7 @@
<comment xml:lang="tr">çizgi roman arşivi</comment>
<comment xml:lang="uk">архів коміксів</comment>
<comment xml:lang="vi">Kho nén sách tranh chuyện vui</comment>
- <comment xml:lang="zh_CN">Comic Book 归档文件</comment>
+ <comment xml:lang="zh_CN">漫画书归档文件</comment>
<comment xml:lang="zh_TW">漫畫書封存檔</comment>
<sub-class-of type="application/x-7z-compressed"/>
<generic-icon name="x-office-document"/>
@@ -8119,7 +8300,7 @@
<comment xml:lang="pt">arquivo de banda desenhada</comment>
<comment xml:lang="pt_BR">Pacote de histórias em quadrinhos</comment>
<comment xml:lang="ro">arhivă benzi desenate</comment>
- <comment xml:lang="ru">архив комиксов</comment>
+ <comment xml:lang="ru">Архив комиксов</comment>
<comment xml:lang="sk">Archív knihy komiksov</comment>
<comment xml:lang="sl">Datoteka arhiva stripov</comment>
<comment xml:lang="sq">Arkiv comic book</comment>
@@ -8128,7 +8309,7 @@
<comment xml:lang="tr">çizgi roman arşivi</comment>
<comment xml:lang="uk">архів коміксів</comment>
<comment xml:lang="vi">Kho nén sách tranh chuyện vui</comment>
- <comment xml:lang="zh_CN">Comic Book 归档文件</comment>
+ <comment xml:lang="zh_CN">漫画书归档文件</comment>
<comment xml:lang="zh_TW">漫畫書封存檔</comment>
<sub-class-of type="application/x-tar"/>
<generic-icon name="x-office-document"/>
@@ -8171,7 +8352,7 @@
<comment xml:lang="pt">arquivo de banda desenhada</comment>
<comment xml:lang="pt_BR">Pacote de histórias em quadrinhos</comment>
<comment xml:lang="ro">arhivă benzi desenate</comment>
- <comment xml:lang="ru">архив комиксов</comment>
+ <comment xml:lang="ru">Архив комиксов</comment>
<comment xml:lang="sk">Archív knihy komiksov</comment>
<comment xml:lang="sl">Datoteka arhiva stripov</comment>
<comment xml:lang="sq">Arkiv comic book</comment>
@@ -8180,7 +8361,7 @@
<comment xml:lang="tr">çizgi roman arşivi</comment>
<comment xml:lang="uk">архів коміксів</comment>
<comment xml:lang="vi">Kho nén sách tranh chuyện vui</comment>
- <comment xml:lang="zh_CN">Comic Book 归档文件</comment>
+ <comment xml:lang="zh_CN">漫画书归档文件</comment>
<comment xml:lang="zh_TW">漫畫書封存檔</comment>
<sub-class-of type="application/zip"/>
<generic-icon name="x-office-document"/>
@@ -8222,7 +8403,7 @@
<comment xml:lang="pt">arquivo Lrzip</comment>
<comment xml:lang="pt_BR">Pacote Lrzip</comment>
<comment xml:lang="ro">Arhivă Lrzip</comment>
- <comment xml:lang="ru">архив LRZIP</comment>
+ <comment xml:lang="ru">Архив LRZIP</comment>
<comment xml:lang="sk">Archív Lrzip</comment>
<comment xml:lang="sl">Datoteka arhiva Lrzip</comment>
<comment xml:lang="sr">Лрзип архива</comment>
@@ -8255,7 +8436,7 @@
<comment xml:lang="ga">cartlann Tar (comhbhrúite le lrzip)</comment>
<comment xml:lang="gl">arquivo Tar (comprimido con lrzip)</comment>
<comment xml:lang="he">ארכיון Tar (מכווץ ע״י lrzip)</comment>
- <comment xml:lang="hr">Tar arhiva (komprimirana lrzip-om)</comment>
+ <comment xml:lang="hr">Tar arhiva (lrzip sažeta)</comment>
<comment xml:lang="hu">Tar archívum (lrzip-pel tömörítve)</comment>
<comment xml:lang="ia">Archivo Tar (comprimite con lrzip)</comment>
<comment xml:lang="id">Arsip Tar (terkompresi lrzip)</comment>
@@ -8271,14 +8452,14 @@
<comment xml:lang="pt">arquivo Tar (compressão Lrzip)</comment>
<comment xml:lang="pt_BR">Pacote Tar (compactado com lrzip)</comment>
<comment xml:lang="ro">Arhivă Tar (comprimată lrzip)</comment>
- <comment xml:lang="ru">архив TAR (сжатый LRZIP)</comment>
+ <comment xml:lang="ru">Архив TAR (сжатый lrzip)</comment>
<comment xml:lang="sk">Archív tar (komprimovaný pomocou lrzip)</comment>
<comment xml:lang="sl">Datoteka arhiva Tar (stisnjen z lrzip)</comment>
<comment xml:lang="sr">Тар архива (запакована лрзипом)</comment>
<comment xml:lang="sv">Tar-arkiv (lrzip-komprimerat)</comment>
<comment xml:lang="tr">Tar arşivi (lrzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">архів tar (стиснений lrzip)</comment>
- <comment xml:lang="zh_CN">Tar 归档文件 (lrzip 压缩)</comment>
+ <comment xml:lang="zh_CN">Tar 归档文件(lrzip 压缩)</comment>
<comment xml:lang="zh_TW">Tar 封存檔 (lrzip 格式壓縮)</comment>
<generic-icon name="package-x-generic"/>
<sub-class-of type="application/x-lrzip"/>
@@ -8287,6 +8468,7 @@
</mime-type>
<mime-type type="application/x-apple-diskimage">
<comment>Apple disk image</comment>
+ <comment xml:lang="ast">Imaxe de discu d'Apple</comment>
<comment xml:lang="bg">Диск — Apple</comment>
<comment xml:lang="ca">imatge de disc d'Apple</comment>
<comment xml:lang="cs">obraz disku Apple</comment>
@@ -8298,9 +8480,10 @@
<comment xml:lang="eu">Apple disko irudia</comment>
<comment xml:lang="fi">Apple-levytiedosto</comment>
<comment xml:lang="fr">image disque Apple</comment>
+ <comment xml:lang="ga">íomhá diosca Apple</comment>
<comment xml:lang="gl">imaxe de disco de Appl</comment>
<comment xml:lang="he">תמונת כונן Apple</comment>
- <comment xml:lang="hr">Apple snimka diska</comment>
+ <comment xml:lang="hr">Apple slika diska</comment>
<comment xml:lang="hu">Apple lemezkép</comment>
<comment xml:lang="ia">Imagine de disco Apple</comment>
<comment xml:lang="id">Image disk Apple</comment>
@@ -8315,95 +8498,107 @@
<comment xml:lang="pl">Obraz dysku Apple</comment>
<comment xml:lang="pt">imagem de disco Apple</comment>
<comment xml:lang="pt_BR">Imagem de disco Apple</comment>
- <comment xml:lang="ru">образ диска Apple Mac OS X</comment>
+ <comment xml:lang="ru">Образ диска Apple Mac OS X</comment>
<comment xml:lang="sk">Obraz disku Apple</comment>
<comment xml:lang="sl">Odtis diska Apple</comment>
- <comment xml:lang="sr">Еплова слика диска</comment>
+ <comment xml:lang="sr">Еплов одраз диска</comment>
<comment xml:lang="sv">Apple-diskavbild</comment>
<comment xml:lang="tr">Apple disk görüntüsü</comment>
<comment xml:lang="uk">образ диска Apple</comment>
- <comment xml:lang="zh_CN">Apple 磁盘镜像</comment>
- <comment xml:lang="zh_TW">Apple 磁碟映像</comment>
+ <comment xml:lang="zh_CN">Apple 磁盘映像</comment>
+ <comment xml:lang="zh_TW">Apple 磁碟映像檔</comment>
<glob pattern="*.dmg"/>
</mime-type>
<mime-type type="application/x-raw-disk-image">
- <comment>Raw disk image</comment>
- <comment xml:lang="ca">imatge de disc RAW</comment>
- <comment xml:lang="cs">surový obraz disku</comment>
- <comment xml:lang="da">Rå diskaftryk</comment>
- <comment xml:lang="de">Rohes Datenträgerabbild</comment>
- <comment xml:lang="el">Ανεπεξέργαστη εικόνα δίσκου</comment>
- <comment xml:lang="en_GB">Raw disk image</comment>
- <comment xml:lang="es">imagen de disco en bruto</comment>
- <comment xml:lang="eu">Disko gordinaren irudia</comment>
- <comment xml:lang="fi">Raaka levytiedosto</comment>
- <comment xml:lang="fr">image disque Raw</comment>
- <comment xml:lang="gl">Imaxe de disco en bruto</comment>
- <comment xml:lang="he">דמות גולמית של כונן</comment>
- <comment xml:lang="hr">Osnovna slika diska</comment>
- <comment xml:lang="hu">Nyers lemezkép</comment>
- <comment xml:lang="ia">Imagine de disco crude</comment>
- <comment xml:lang="id">Image disk mentah</comment>
- <comment xml:lang="it">Immagine disco raw</comment>
- <comment xml:lang="kk">Шикі диск бейнесі</comment>
- <comment xml:lang="ko">RAW 디스크 이미지</comment>
- <comment xml:lang="oc">imatge disc Raw</comment>
- <comment xml:lang="pl">Surowy obraz dysku</comment>
- <comment xml:lang="pt">imagem de disco Raw</comment>
- <comment xml:lang="pt_BR">Imagem bruta de disco</comment>
- <comment xml:lang="ru">необработанный образ диска</comment>
- <comment xml:lang="sk">Obraz disku</comment>
- <comment xml:lang="sl">Surovi odtis diska</comment>
- <comment xml:lang="sr">сирова слика диска</comment>
- <comment xml:lang="sv">Rå diskavbild</comment>
- <comment xml:lang="tr">İşlem görmemiş disk imajı</comment>
- <comment xml:lang="uk">простий образ диска</comment>
- <comment xml:lang="zh_CN">原始磁盘镜像</comment>
- <comment xml:lang="zh_TW">原生磁碟映像</comment>
- <glob pattern="*.raw-disk-image"/>
- <glob pattern="*.img"/>
- </mime-type>
- <mime-type type="application/x-raw-disk-image-xz-compressed">
- <comment>Raw disk image (XZ-compressed)</comment>
- <comment xml:lang="ca">imatge de disc RAW (amb compressió XZ)</comment>
- <comment xml:lang="cs">surový obraz disku (komprimovaný pomocí XZ)</comment>
- <comment xml:lang="da">Rå diskaftryk (XZ-komprimeret)</comment>
- <comment xml:lang="de">Rohes Datenträgerabbild (XZ-komprimiert)</comment>
- <comment xml:lang="el">Ανεπεξέργαστη εικόνα δίσκου (συμπιεσμένη XZ)</comment>
- <comment xml:lang="en_GB">Raw disk image (XZ-compressed)</comment>
- <comment xml:lang="es">imagen de disco en bruto (comprimida con XZ)</comment>
- <comment xml:lang="eu">Disko gordinaren irudia (XZ-rekin konprimitua)</comment>
- <comment xml:lang="fi">Raaka levytiedosto (XZ-pakattu)</comment>
- <comment xml:lang="fr">image disque Raw (compression XZ)</comment>
- <comment xml:lang="gl">Imaxe de disco en bruto (comprimida en XZ)</comment>
- <comment xml:lang="he">דמות גולמית של כונן (בדחיסת XZ)</comment>
- <comment xml:lang="hr">Osnovna slika diska (XZ sažeta)</comment>
- <comment xml:lang="hu">Nyers lemezkép (XZ-vel tömörítve)</comment>
- <comment xml:lang="ia">Imagine de disco crude (comprimite con XZ)</comment>
- <comment xml:lang="id">Image disk mentah (terkompresi XZ)</comment>
- <comment xml:lang="it">Immagine disco raw (compressa XZ)</comment>
- <comment xml:lang="kk">Шикі диск бейнесі (XZ-мен сығылған)</comment>
- <comment xml:lang="ko">RAW 디스크 이미지(XZ 압축)</comment>
- <comment xml:lang="oc">imatge disc Raw (compression XZ)</comment>
- <comment xml:lang="pl">Surowy obraz dysku (kompresja XZ)</comment>
- <comment xml:lang="pt">imagem de disco Raw (compressão XZ)</comment>
- <comment xml:lang="pt_BR">Imagem bruta de disco (compactada com XZ)</comment>
- <comment xml:lang="ru">необработанный образ диска (XZ-сжатый)</comment>
- <comment xml:lang="sk">Obraz disku (komprimovaný pomocou XZ)</comment>
- <comment xml:lang="sl">Surovi odtis diska (stisnjeno z XZ)</comment>
- <comment xml:lang="sr">сирова слика диска (запакована ИксЗ-ом)</comment>
- <comment xml:lang="sv">Rå diskavbild (XZ-komprimerad)</comment>
- <comment xml:lang="tr">İşlem görmemiş disk imajı (XZ ile sıkıştırılmış)</comment>
- <comment xml:lang="uk">простий образ диска (стиснений XZ)</comment>
- <comment xml:lang="zh_CN">原始磁盘镜像(XZ 压缩)</comment>
- <comment xml:lang="zh_TW">原生磁碟映像 (XZ 格式壓縮)</comment>
- <sub-class-of type="application/x-xz"/>
- <glob pattern="*.raw-disk-image.xz"/>
- <glob pattern="*.img.xz"/>
- </mime-type>
+ <comment>Raw disk image</comment>
+ <comment xml:lang="ast">Imaxe de discu en bruto</comment>
+ <comment xml:lang="ca">imatge de disc RAW</comment>
+ <comment xml:lang="cs">surový obraz disku</comment>
+ <comment xml:lang="da">Rå diskaftryk</comment>
+ <comment xml:lang="de">Rohes Datenträgerabbild</comment>
+ <comment xml:lang="el">Ανεπεξέργαστη εικόνα δίσκου</comment>
+ <comment xml:lang="en_GB">Raw disk image</comment>
+ <comment xml:lang="es">imagen de disco en bruto</comment>
+ <comment xml:lang="eu">Disko gordinaren irudia</comment>
+ <comment xml:lang="fi">Raaka levytiedosto</comment>
+ <comment xml:lang="fr">image disque Raw</comment>
+ <comment xml:lang="ga">Amhíomha diosca</comment>
+ <comment xml:lang="gl">Imaxe de disco en bruto</comment>
+ <comment xml:lang="he">דמות גולמית של כונן</comment>
+ <comment xml:lang="hr">Osnovna slika diska</comment>
+ <comment xml:lang="hu">Nyers lemezkép</comment>
+ <comment xml:lang="ia">Imagine de disco crude</comment>
+ <comment xml:lang="id">Image disk mentah</comment>
+ <comment xml:lang="it">Immagine disco raw</comment>
+ <comment xml:lang="kk">Шикі диск бейнесі</comment>
+ <comment xml:lang="ko">RAW 디스크 이미지</comment>
+ <comment xml:lang="oc">imatge disc Raw</comment>
+ <comment xml:lang="pl">Surowy obraz dysku</comment>
+ <comment xml:lang="pt">imagem de disco Raw</comment>
+ <comment xml:lang="pt_BR">Imagem bruta de disco</comment>
+ <comment xml:lang="ru">Необработанный образ диска</comment>
+ <comment xml:lang="sk">Obraz disku</comment>
+ <comment xml:lang="sl">Surovi odtis diska</comment>
+ <comment xml:lang="sr">сиров одраз диска</comment>
+ <comment xml:lang="sv">Rå diskavbild</comment>
+ <comment xml:lang="tr">İşlem görmemiş disk imajı</comment>
+ <comment xml:lang="uk">простий образ диска</comment>
+ <comment xml:lang="zh_CN">原始磁盘映像</comment>
+ <comment xml:lang="zh_TW">原生磁碟映像檔</comment>
+ <glob pattern="*.raw-disk-image"/>
+ <glob pattern="*.img"/>
+ </mime-type>
+ <mime-type type="application/x-raw-floppy-disk-image">
+ <comment>Floppy disk image</comment>
+ <sub-class-of type="application/x-raw-disk-image"/>
+ <alias type="application/x-fd-file"/>
+ <glob pattern="*.fd"/>
+ <glob pattern="*.qd"/>
+ </mime-type>
+ <mime-type type="application/x-raw-disk-image-xz-compressed">
+ <comment>Raw disk image (XZ-compressed)</comment>
+ <comment xml:lang="ast">Imaxe de discu en bruto (comprimida en XZ)</comment>
+ <comment xml:lang="ca">imatge de disc RAW (amb compressió XZ)</comment>
+ <comment xml:lang="cs">surový obraz disku (komprimovaný pomocí XZ)</comment>
+ <comment xml:lang="da">Rå diskaftryk (XZ-komprimeret)</comment>
+ <comment xml:lang="de">Rohes Datenträgerabbild (XZ-komprimiert)</comment>
+ <comment xml:lang="el">Ανεπεξέργαστη εικόνα δίσκου (συμπιεσμένη XZ)</comment>
+ <comment xml:lang="en_GB">Raw disk image (XZ-compressed)</comment>
+ <comment xml:lang="es">imagen de disco en bruto (comprimida con XZ)</comment>
+ <comment xml:lang="eu">Disko gordinaren irudia (XZ-rekin konprimitua)</comment>
+ <comment xml:lang="fi">Raaka levytiedosto (XZ-pakattu)</comment>
+ <comment xml:lang="fr">image disque Raw (compression XZ)</comment>
+ <comment xml:lang="ga">Amhíomhá (comhbhrúite le XZ)</comment>
+ <comment xml:lang="gl">Imaxe de disco en bruto (comprimida en XZ)</comment>
+ <comment xml:lang="he">דמות גולמית של כונן (בדחיסת XZ)</comment>
+ <comment xml:lang="hr">Osnovna slika diska (XZ sažeta)</comment>
+ <comment xml:lang="hu">Nyers lemezkép (XZ-vel tömörítve)</comment>
+ <comment xml:lang="ia">Imagine de disco crude (comprimite con XZ)</comment>
+ <comment xml:lang="id">Image disk mentah (terkompresi XZ)</comment>
+ <comment xml:lang="it">Immagine disco raw (compressa XZ)</comment>
+ <comment xml:lang="kk">Шикі диск бейнесі (XZ-мен сығылған)</comment>
+ <comment xml:lang="ko">RAW 디스크 이미지(XZ 압축)</comment>
+ <comment xml:lang="oc">imatge disc Raw (compression XZ)</comment>
+ <comment xml:lang="pl">Surowy obraz dysku (kompresja XZ)</comment>
+ <comment xml:lang="pt">imagem de disco Raw (compressão XZ)</comment>
+ <comment xml:lang="pt_BR">Imagem bruta de disco (compactada com XZ)</comment>
+ <comment xml:lang="ru">Необработанный образ диска (сжатый xz)</comment>
+ <comment xml:lang="sk">Obraz disku (komprimovaný pomocou XZ)</comment>
+ <comment xml:lang="sl">Surovi odtis diska (stisnjeno z XZ)</comment>
+ <comment xml:lang="sr">сиров одраз диска (запакована ИксЗ-ом)</comment>
+ <comment xml:lang="sv">Rå diskavbild (XZ-komprimerad)</comment>
+ <comment xml:lang="tr">İşlem görmemiş disk imajı (XZ ile sıkıştırılmış)</comment>
+ <comment xml:lang="uk">простий образ диска (стиснений XZ)</comment>
+ <comment xml:lang="zh_CN">原始磁盘映像(XZ 压缩)</comment>
+ <comment xml:lang="zh_TW">原生磁碟映像 (XZ 格式壓縮)</comment>
+ <sub-class-of type="application/x-xz"/>
+ <glob pattern="*.raw-disk-image.xz"/>
+ <glob pattern="*.img.xz"/>
+ </mime-type>
<mime-type type="application/x-cd-image">
<comment>raw CD image</comment>
<comment xml:lang="ar">صورة CD خامة</comment>
+ <comment xml:lang="ast">imaxe de CD en bruto</comment>
<comment xml:lang="be@latin">suvoraja vyjava CD</comment>
<comment xml:lang="bg">Изображение — raw CD</comment>
<comment xml:lang="ca">imatge de CD en cru</comment>
@@ -8440,17 +8635,17 @@
<comment xml:lang="pt">imagem em bruto de CD</comment>
<comment xml:lang="pt_BR">Imagem bruta de CD</comment>
<comment xml:lang="ro">imagine de CD brută</comment>
- <comment xml:lang="ru">необработанный образ компакт-диска</comment>
+ <comment xml:lang="ru">Необработанный образ компакт-диска</comment>
<comment xml:lang="sk">Surový obraz CD</comment>
<comment xml:lang="sl">surovi CD odtis</comment>
<comment xml:lang="sq">Imazh raw CD</comment>
- <comment xml:lang="sr">сирова слика ЦД-а</comment>
+ <comment xml:lang="sr">сиров одраз ЦД-а</comment>
<comment xml:lang="sv">rå cd-avbild</comment>
<comment xml:lang="tr">Ham CD görüntüsü</comment>
<comment xml:lang="uk">образ raw CD</comment>
<comment xml:lang="vi">ảnh đĩa CD thô</comment>
<comment xml:lang="zh_CN">原始 CD 映像</comment>
- <comment xml:lang="zh_TW">原生 CD 映像</comment>
+ <comment xml:lang="zh_TW">原生 CD 映像檔</comment>
<sub-class-of type="application/x-raw-disk-image"/>
<alias type="application/x-iso9660-image"/>
@@ -8460,20 +8655,31 @@
<mime-type type="application/x-iso9660-appimage">
<comment>AppImage application bundle</comment>
<comment xml:lang="ca">paquet d'aplicació AppImage</comment>
+ <comment xml:lang="cs">balíček AppImage s aplikací</comment>
<comment xml:lang="da">Applmage-programsamling</comment>
<comment xml:lang="de">AppImage-Anwendungspaket</comment>
+ <comment xml:lang="en_GB">AppImage application bundle</comment>
<comment xml:lang="es">paquete de aplicación AppImage</comment>
+ <comment xml:lang="eu">AppImage aplikazio bilduma</comment>
+ <comment xml:lang="fi">AppImage-sovelluspaketti</comment>
<comment xml:lang="fr">lot applicatif AppImage</comment>
+ <comment xml:lang="ga">burla feidhmchláir AppImage</comment>
<comment xml:lang="he">חבילת יישומי AppImage</comment>
+ <comment xml:lang="hr">AppImage paket aplikacije</comment>
<comment xml:lang="hu">AppImage alkalmazáscsomag</comment>
+ <comment xml:lang="id">bundel aplikasi AppImage</comment>
+ <comment xml:lang="it">Bundle applicazione AppImage</comment>
<comment xml:lang="kk">AppImage қолданбалар дестесі</comment>
<comment xml:lang="ko">AppImage 프로그램 번들</comment>
<comment xml:lang="pl">Pakiet programu AppImage</comment>
<comment xml:lang="pt_BR">Pacote de aplicativo AppImage</comment>
- <comment xml:lang="ru">пакет приложений AppImage</comment>
+ <comment xml:lang="ru">Пакет приложения AppImage</comment>
<comment xml:lang="sk">Balík aplikácií AppImage</comment>
+ <comment xml:lang="sr">скуп програма Ап-слике</comment>
+ <comment xml:lang="sv">AppImage-programbunt</comment>
+ <comment xml:lang="tr">AppImage uygulama paketi</comment>
<comment xml:lang="uk">пакунок із програмами AppImage</comment>
- <comment xml:lang="zh_CN">AppImage 应用包</comment>
+ <comment xml:lang="zh_CN">AppImage 应用组合包</comment>
<comment xml:lang="zh_TW">AppImage 應用程式套組</comment>
<sub-class-of type="application/x-executable"/>
<sub-class-of type="application/x-iso9660-image"/>
@@ -8488,7 +8694,6 @@
</match>
</magic>
<glob pattern="*.appimage"/>
- <glob pattern="*.AppImage"/>
</mime-type>
<mime-type type="application/x-cdrdao-toc">
<comment>CD Table Of Contents</comment>
@@ -8527,7 +8732,7 @@
<comment xml:lang="pt">Tabela de conteúdos de CD</comment>
<comment xml:lang="pt_BR">Sumário de CD</comment>
<comment xml:lang="ro">Tabel conținut CD</comment>
- <comment xml:lang="ru">таблица содержания CD</comment>
+ <comment xml:lang="ru">Таблица содержания CD</comment>
<comment xml:lang="sk">Obsah CD</comment>
<comment xml:lang="sl">Kazalo vsebine CD nosilca</comment>
<comment xml:lang="sq">Tregues CD</comment>
@@ -8588,7 +8793,7 @@
<comment xml:lang="pt">notação de jogo de xadrez PGN</comment>
<comment xml:lang="pt_BR">Notação de jogo de xadrez PGN</comment>
<comment xml:lang="ro">Notație joc șah PGN</comment>
- <comment xml:lang="ru">шахматная партия PGN</comment>
+ <comment xml:lang="ru">Шахматная партия PGN</comment>
<comment xml:lang="sk">Šachová notácia PGN</comment>
<comment xml:lang="sl">Datoteka opomb šahovske igre PGN</comment>
<comment xml:lang="sq">Njoftim loje shahu PGN</comment>
@@ -8612,6 +8817,7 @@
<mime-type type="application/vnd.ms-htmlhelp">
<comment>CHM document</comment>
<comment xml:lang="ar">مستند CHM</comment>
+ <comment xml:lang="ast">Documentu CHM</comment>
<comment xml:lang="be@latin">Dakument CHM</comment>
<comment xml:lang="bg">Документ — CHM</comment>
<comment xml:lang="ca">document CHM</comment>
@@ -8648,7 +8854,7 @@
<comment xml:lang="pt">documento CHM</comment>
<comment xml:lang="pt_BR">Documento CHM</comment>
<comment xml:lang="ro">Document CHM</comment>
- <comment xml:lang="ru">документ CHM</comment>
+ <comment xml:lang="ru">Документ CHM</comment>
<comment xml:lang="sk">Dokument CHM</comment>
<comment xml:lang="sl">Dokument CHM</comment>
<comment xml:lang="sq">Dokument CHM</comment>
@@ -8706,7 +8912,7 @@
<comment xml:lang="pt">byte-code Java</comment>
<comment xml:lang="pt_BR">Código compilado Java</comment>
<comment xml:lang="ro">Bytecode Java</comment>
- <comment xml:lang="ru">байт-код Java</comment>
+ <comment xml:lang="ru">Байт-код Java</comment>
<comment xml:lang="sk">Bajtový kód Java</comment>
<comment xml:lang="sl">Datoteka bitne kode Java</comment>
<comment xml:lang="sq">Byte code Java</comment>
@@ -8738,7 +8944,7 @@
<comment xml:lang="ga">comhad UNIX-comhbhrúite</comment>
<comment xml:lang="gl">ficheiro comprimido de UNIX</comment>
<comment xml:lang="he">קובץ בכיווץ UNIX</comment>
- <comment xml:lang="hr">UNIX-komprimirana datoteka</comment>
+ <comment xml:lang="hr">UNIX sažeta datoteka</comment>
<comment xml:lang="hu">Tömörített UNIX-fájl</comment>
<comment xml:lang="ia">File comprimite de UNIX</comment>
<comment xml:lang="id">Berkas terkompresi UNIX</comment>
@@ -8757,7 +8963,7 @@
<comment xml:lang="pt">ficheiro comprimido UNIX</comment>
<comment xml:lang="pt_BR">Arquivo compactado do UNIX</comment>
<comment xml:lang="ro">Fișier comprimat UNIX</comment>
- <comment xml:lang="ru">файл (UNIX-сжатый)</comment>
+ <comment xml:lang="ru">Файл (UNIX-сжатый)</comment>
<comment xml:lang="sk">Súbor komprimovaný v Unixe</comment>
<comment xml:lang="sl">Skrčena Unix datoteka</comment>
<comment xml:lang="sq">File i kompresuar UNIX</comment>
@@ -8793,7 +8999,7 @@
<comment xml:lang="ga">cartlann Tar (comhbhrúite le gzip)</comment>
<comment xml:lang="gl">arquivo Tar (comprimido con gzip)</comment>
<comment xml:lang="he">ארכיון Tar (מכווץ ע״י gzip)</comment>
- <comment xml:lang="hr">Tar arhiva (komprimirana gzip-om)</comment>
+ <comment xml:lang="hr">Tar arhiva (gzip sažeta)</comment>
<comment xml:lang="hu">Tar archívum (gzip-pel tömörítve)</comment>
<comment xml:lang="ia">Archivo Tar (comprimite con gzip)</comment>
<comment xml:lang="id">Arsip Tar (terkompresi gzip)</comment>
@@ -8811,7 +9017,7 @@
<comment xml:lang="pt">arquivo Tar (compressão gzip)</comment>
<comment xml:lang="pt_BR">Pacote Tar (compactado com gzip)</comment>
<comment xml:lang="ro">Arhivă Tar (comprimată gzip)</comment>
- <comment xml:lang="ru">архив TAR (сжатый GZIP)</comment>
+ <comment xml:lang="ru">Архив TAR (сжатый gzip)</comment>
<comment xml:lang="sk">Archív tar (komprimovaný pomocou gzip)</comment>
<comment xml:lang="sl">Datoteka arhiva Tar (stisnjen z gzip)</comment>
<comment xml:lang="sq">Arkiv tar (i kompresuar me gzip)</comment>
@@ -8820,7 +9026,7 @@
<comment xml:lang="tr">Tar arşivi (gzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">архів tar (стиснений gzip)</comment>
<comment xml:lang="vi">Kho nén tar (đã nén gzip)</comment>
- <comment xml:lang="zh_CN">Tar 归档文件(gzip 压缩)</comment>
+ <comment xml:lang="zh_CN">Tar 归档文件(gzip 压缩)</comment>
<comment xml:lang="zh_TW">Tar 封存檔 (gzip 格式壓縮)</comment>
<sub-class-of type="application/gzip"/>
<generic-icon name="package-x-generic"/>
@@ -8844,7 +9050,7 @@
<comment xml:lang="fi">ohjelman kaatumistiedot</comment>
<comment xml:lang="fo">forrits sordáta</comment>
<comment xml:lang="fr">données de plantage de programme</comment>
- <comment xml:lang="ga">sonraí thuairt ríomhchláir</comment>
+ <comment xml:lang="ga">sonraí tuairte ríomhchláir</comment>
<comment xml:lang="gl">datos de colgue do programa</comment>
<comment xml:lang="he">מידע מקריסת תכנית</comment>
<comment xml:lang="hr">podaci o rušenju programa</comment>
@@ -8866,7 +9072,7 @@
<comment xml:lang="pt">dados de rebentamento de aplicação</comment>
<comment xml:lang="pt_BR">Dados de travamento de programa</comment>
<comment xml:lang="ro">date eroare program</comment>
- <comment xml:lang="ru">данные аварийного завершения</comment>
+ <comment xml:lang="ru">Данные аварийного завершения программы</comment>
<comment xml:lang="sk">Údaje o páde programu</comment>
<comment xml:lang="sl">podatki sesutja programa</comment>
<comment xml:lang="sq">Të dhëna nga programi i bllokuar</comment>
@@ -8897,6 +9103,7 @@
<mime-type type="application/x-cpio">
<comment>CPIO archive</comment>
<comment xml:lang="ar">أرشيف CPIO</comment>
+ <comment xml:lang="ast">Archivu CPIO</comment>
<comment xml:lang="az">CPIO arxivi</comment>
<comment xml:lang="be@latin">Archiŭ CPIO</comment>
<comment xml:lang="bg">Архив — CPIO</comment>
@@ -8936,7 +9143,7 @@
<comment xml:lang="pt">arquivo CPIO</comment>
<comment xml:lang="pt_BR">Pacote CPIO</comment>
<comment xml:lang="ro">Arhivă CPIO</comment>
- <comment xml:lang="ru">архив CPIO</comment>
+ <comment xml:lang="ru">Архив CPIO</comment>
<comment xml:lang="sk">Archív CPIO</comment>
<comment xml:lang="sl">Datoteka arhiva CPIO</comment>
<comment xml:lang="sq">Arkiv CPIO</comment>
@@ -8978,7 +9185,7 @@
<comment xml:lang="ga">cartlann CPIO (comhbhrúite le gzip)</comment>
<comment xml:lang="gl">arquivo CPIO (comprimido con gzip)</comment>
<comment xml:lang="he">ארכיון CPIO (מכווץ ע״י gzip)</comment>
- <comment xml:lang="hr">CPIO arhiva (komprimirana gzip-om)</comment>
+ <comment xml:lang="hr">CPIO arhiva (gzip sažeta)</comment>
<comment xml:lang="hu">CPIO-archívum (gzip-pel tömörítve)</comment>
<comment xml:lang="ia">Archivo CPIO (comprimite con gzip)</comment>
<comment xml:lang="id">Arsip CPIO (terkompresi gzip)</comment>
@@ -8998,7 +9205,7 @@
<comment xml:lang="pt">arquivo CPIO (compressão gzip)</comment>
<comment xml:lang="pt_BR">Pacote CPIO (compactado com gzip)</comment>
<comment xml:lang="ro">Arhivă CPIO (compresie gzip)</comment>
- <comment xml:lang="ru">архив CPIO (сжатый GZIP)</comment>
+ <comment xml:lang="ru">Архив CPIO (сжатый gzip)</comment>
<comment xml:lang="sk">Archív CPIO (komprimovaný pomocou gzip)</comment>
<comment xml:lang="sl">Datoteka arhiva CPIO (skrčena z gzip)</comment>
<comment xml:lang="sq">Arkiv CPIO (kompresuar me gzip)</comment>
@@ -9007,7 +9214,7 @@
<comment xml:lang="tr">CPIO arşivi (gzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">архів CPIO (стиснений gzip)</comment>
<comment xml:lang="vi">Kho nén CPIO (đã nén gzip)</comment>
- <comment xml:lang="zh_CN">CPIO 归档文件(gzip 压缩)</comment>
+ <comment xml:lang="zh_CN">CPIO 归档文件(gzip 压缩)</comment>
<comment xml:lang="zh_TW">CPIO 封存檔 (gzip 格式壓縮)</comment>
<sub-class-of type="application/gzip"/>
<generic-icon name="package-x-generic"/>
@@ -9019,7 +9226,7 @@
<comment xml:lang="az">C qabıq skripti</comment>
<comment xml:lang="be@latin">Skrypt abałonki C</comment>
<comment xml:lang="bg">Скрипт — обвивка C</comment>
- <comment xml:lang="ca">script de C shell</comment>
+ <comment xml:lang="ca">script C shell</comment>
<comment xml:lang="cs">skript shellu C</comment>
<comment xml:lang="cy">Sgript plisgyn C</comment>
<comment xml:lang="da">C-skalprogram</comment>
@@ -9032,10 +9239,10 @@
<comment xml:lang="fi">Csh-komentotiedosto</comment>
<comment xml:lang="fo">C skel boðrøð</comment>
<comment xml:lang="fr">script C shell</comment>
- <comment xml:lang="ga">script bhlaosc C</comment>
+ <comment xml:lang="ga">script bhlaoisce C</comment>
<comment xml:lang="gl">script de C shell</comment>
<comment xml:lang="he">תסריט מעטפת C</comment>
- <comment xml:lang="hr">C skripta</comment>
+ <comment xml:lang="hr">C skripta ljuske</comment>
<comment xml:lang="hu">C héj-parancsfájl</comment>
<comment xml:lang="ia">Script C-shell</comment>
<comment xml:lang="id">Skrip shell C</comment>
@@ -9054,11 +9261,11 @@
<comment xml:lang="pt">script de terminal C</comment>
<comment xml:lang="pt_BR">Script de shell C</comment>
<comment xml:lang="ro">Script C shell</comment>
- <comment xml:lang="ru">сценарий C shell</comment>
+ <comment xml:lang="ru">Сценарий C shell</comment>
<comment xml:lang="sk">Skript shellu C</comment>
<comment xml:lang="sl">Skriptna datoteka lupine C</comment>
<comment xml:lang="sq">Script shell C</comment>
- <comment xml:lang="sr">скрипта Ц љуске</comment>
+ <comment xml:lang="sr">скрипта Ц шкољке</comment>
<comment xml:lang="sv">Skalskript (csh)</comment>
<comment xml:lang="tr">C kabuk betiği</comment>
<comment xml:lang="uk">скрипт оболонки C</comment>
@@ -9079,6 +9286,7 @@
<mime-type type="application/x-dbf">
<comment>Xbase document</comment>
<comment xml:lang="ar">مستند Xbase</comment>
+ <comment xml:lang="ast">Documentu Xbase</comment>
<comment xml:lang="be@latin">Dakument Xbase</comment>
<comment xml:lang="bg">Документ — Xbase</comment>
<comment xml:lang="ca">document Xbase</comment>
@@ -9114,7 +9322,7 @@
<comment xml:lang="pt">documento Xbase</comment>
<comment xml:lang="pt_BR">Documento do Xbase</comment>
<comment xml:lang="ro">Document Xbase</comment>
- <comment xml:lang="ru">документ Xbase</comment>
+ <comment xml:lang="ru">Документ Xbase</comment>
<comment xml:lang="sk">Dokument Xbase</comment>
<comment xml:lang="sl">Dokument Xbase</comment>
<comment xml:lang="sq">Dokument Xbase</comment>
@@ -9169,7 +9377,7 @@
<comment xml:lang="pt">programa ECMAScript</comment>
<comment xml:lang="pt_BR">Programa ECMAScript</comment>
<comment xml:lang="ro">Program ECMAScript</comment>
- <comment xml:lang="ru">программа ECMAScript</comment>
+ <comment xml:lang="ru">Программа ECMAScript</comment>
<comment xml:lang="sk">Program ECMAScript</comment>
<comment xml:lang="sl">Programska datoteka ECMAScript</comment>
<comment xml:lang="sq">Program ECMAScript</comment>
@@ -9181,6 +9389,7 @@
<comment xml:lang="zh_CN">ECMAScript 程序</comment>
<comment xml:lang="zh_TW">ECMAScript 程式</comment>
<alias type="text/ecmascript"/>
+ <sub-class-of type='application/x-executable'/>
<sub-class-of type="text/plain"/>
<generic-icon name="text-x-script"/>
<glob pattern="*.es"/>
@@ -9188,22 +9397,33 @@
<mime-type type="application/x-sega-cd-rom">
<comment>Sega CD disc image</comment>
+ <comment xml:lang="ast">Imaxe de discu de Sega CD</comment>
<comment xml:lang="ca">imatge de disc de Sega CD</comment>
+ <comment xml:lang="cs">obraz disku CD pro Sega</comment>
<comment xml:lang="da">Sega CD-diskaftryk</comment>
<comment xml:lang="de">Sega-CD-Datenträgerabbild</comment>
+ <comment xml:lang="en_GB">Sega CD disc image</comment>
<comment xml:lang="es">imagen de disco CD de Sega</comment>
+ <comment xml:lang="eu">Sega CD disko irudia</comment>
<comment xml:lang="fi">Sega CD -levykuva</comment>
<comment xml:lang="fr">image disque Sega CD</comment>
+ <comment xml:lang="ga">íomhá dlúthdhiosca Sega</comment>
<comment xml:lang="he">דמות כונן Sega CD</comment>
+ <comment xml:lang="hr">Sega CD slika diska</comment>
<comment xml:lang="hu">Sega CD-lemezkép</comment>
+ <comment xml:lang="id">image cakram CD Sega</comment>
+ <comment xml:lang="it">Immagine disco Sega Mega CD</comment>
<comment xml:lang="kk">Sega CD диск бейнесі</comment>
<comment xml:lang="ko">세가 CD 디스크 이미지</comment>
<comment xml:lang="pl">Obraz płyty konsoli Mega-CD</comment>
<comment xml:lang="pt_BR">Imagem de disco Sega CD</comment>
- <comment xml:lang="ru">образ диска CD Sega</comment>
+ <comment xml:lang="ru">Образ диска CD Sega</comment>
<comment xml:lang="sk">Obraz disku CD Sega</comment>
+ <comment xml:lang="sr">одраз диска Сега ЦД-а</comment>
+ <comment xml:lang="sv">Mega-CD-skivavbild</comment>
+ <comment xml:lang="tr">Sega CD disk kalıbı</comment>
<comment xml:lang="uk">образ диска Sega CD</comment>
- <comment xml:lang="zh_CN">Sega CD 光盘镜像</comment>
+ <comment xml:lang="zh_CN">Sega CD 光盘映像</comment>
<comment xml:lang="zh_TW">Sega CD 光碟映像檔</comment>
<generic-icon name="application-x-executable"/>
@@ -9221,6 +9441,32 @@
<mime-type type="application/x-sega-pico-rom">
<comment>Sega Pico ROM</comment>
+ <comment xml:lang="ast">ROM de Sega Pico</comment>
+ <comment xml:lang="ca">ROM de Sega Pico</comment>
+ <comment xml:lang="cs">ROM pro Sega Pico</comment>
+ <comment xml:lang="de">Sega Pico ROM</comment>
+ <comment xml:lang="en_GB">Sega Pico ROM</comment>
+ <comment xml:lang="es">ROM de Sega Pico</comment>
+ <comment xml:lang="eu">Sega Pico ROM</comment>
+ <comment xml:lang="fi">Sega Pico ROM</comment>
+ <comment xml:lang="fr">ROM Sega Pico</comment>
+ <comment xml:lang="ga">ROM Sega Pico</comment>
+ <comment xml:lang="hr">Sega Pico ROM</comment>
+ <comment xml:lang="hu">Sega Pico ROM</comment>
+ <comment xml:lang="id">ROM Sega Pico</comment>
+ <comment xml:lang="it">ROM Sega Pico</comment>
+ <comment xml:lang="kk">Sega Pico ROM</comment>
+ <comment xml:lang="ko">세카 피코 롬</comment>
+ <comment xml:lang="pl">Plik ROM konsoli Sega Pico</comment>
+ <comment xml:lang="pt_BR">ROM de Sega Pico</comment>
+ <comment xml:lang="ru">Sega Pico ROM</comment>
+ <comment xml:lang="sk">ROM pre Sega Pico</comment>
+ <comment xml:lang="sr">Сега Пико РОМ</comment>
+ <comment xml:lang="sv">Sega Pico-rom</comment>
+ <comment xml:lang="tr">Sega Pico ROM</comment>
+ <comment xml:lang="uk">ППП Sega Pico</comment>
+ <comment xml:lang="zh_CN">Sega Pico ROM</comment>
+ <comment xml:lang="zh_TW">Sega Pico ROM</comment>
<generic-icon name="application-x-executable"/>
<magic priority="50">
<match value="SEGA PICO" type="string" offset="256"/>
@@ -9228,6 +9474,7 @@
</mime-type>
<mime-type type="application/x-saturn-rom">
<comment>Sega Saturn disc image</comment>
+ <comment xml:lang="ast">Imaxe de discu de Sega Saturn</comment>
<comment xml:lang="ca">imatge de disc de Sega Saturn</comment>
<comment xml:lang="cs">obraz disku pro Sega Saturn</comment>
<comment xml:lang="da">Sega Saturn-diskaftryk</comment>
@@ -9238,6 +9485,7 @@
<comment xml:lang="eu">Sega Saturn disko irudia</comment>
<comment xml:lang="fi">Sega Saturn -levykuva</comment>
<comment xml:lang="fr">image disque Sega Saturn</comment>
+ <comment xml:lang="ga">íomhá diosca Sega Saturn</comment>
<comment xml:lang="he">דמות כונן Sega Saturn</comment>
<comment xml:lang="hr">Sega Saturn slika diska</comment>
<comment xml:lang="hu">Sega Saturn lemezkép</comment>
@@ -9250,13 +9498,13 @@
<comment xml:lang="pl">Obraz płyty konsoli Sega Saturn</comment>
<comment xml:lang="pt">imagem de disco Sega Saturn</comment>
<comment xml:lang="pt_BR">Imagem de disco do Sega Saturn</comment>
- <comment xml:lang="ru">образ диска Sega Saturn</comment>
+ <comment xml:lang="ru">Образ диска Sega Saturn</comment>
<comment xml:lang="sk">Obraz disku Sega Saturn</comment>
- <comment xml:lang="sr">слика диска Сега Сатурна</comment>
+ <comment xml:lang="sr">одраз диска Сега Сатурна</comment>
<comment xml:lang="sv">Sega Saturn-skivavbild</comment>
<comment xml:lang="tr">Sega Saturn disk kalıbı</comment>
<comment xml:lang="uk">образ диска Sega Saturn</comment>
- <comment xml:lang="zh_CN">Sega Saturn 光盘镜像</comment>
+ <comment xml:lang="zh_CN">Sega Saturn 光盘映像</comment>
<comment xml:lang="zh_TW">Sega Saturn 光碟映像檔</comment>
<generic-icon name="application-x-executable"/>
<magic priority="50">
@@ -9268,6 +9516,7 @@
</mime-type>
<mime-type type="application/x-dc-rom">
<comment>Dreamcast GD-ROM</comment>
+ <comment xml:lang="ast">GD-ROM de Dreamcast</comment>
<comment xml:lang="ca">GD-ROM de Dreamcast</comment>
<comment xml:lang="cs">GD-ROM pro Dreamcast</comment>
<comment xml:lang="da">Dreamcast GD-ROM</comment>
@@ -9277,6 +9526,7 @@
<comment xml:lang="es">GD-ROM de Dreamcast</comment>
<comment xml:lang="eu">Dreamcast GD-ROM</comment>
<comment xml:lang="fr">GD-ROM Dreamcast</comment>
+ <comment xml:lang="ga">GD-ROM Dreamcast</comment>
<comment xml:lang="he">Dreamcast GD-ROM</comment>
<comment xml:lang="hr">Dreamcast GD-ROM</comment>
<comment xml:lang="hu">Dreamcast GD-ROM</comment>
@@ -9288,8 +9538,8 @@
<comment xml:lang="oc">GD-ROM Dreamcast</comment>
<comment xml:lang="pl">Plik GD-ROM konsoli Dreamcast</comment>
<comment xml:lang="pt">GD-ROM Dreamcast</comment>
- <comment xml:lang="pt_BR">GD-ROM do Dreamcast</comment>
- <comment xml:lang="ru">GD-ROM Dreamcast</comment>
+ <comment xml:lang="pt_BR">GD-ROM de Dreamcast</comment>
+ <comment xml:lang="ru">Dreamcast GD-ROM</comment>
<comment xml:lang="sk">Dreamcast GD-ROM</comment>
<comment xml:lang="sr">Дримкаст ГД-РОМ</comment>
<comment xml:lang="sv">Dreamcast-gd-rom</comment>
@@ -9303,6 +9553,7 @@
<mime-type type="application/x-nintendo-ds-rom">
<comment>Nintendo DS ROM</comment>
<comment xml:lang="ar">Nintendo DS ROM</comment>
+ <comment xml:lang="ast">ROM de Nintendo DS</comment>
<comment xml:lang="be@latin">Nintendo DS ROM</comment>
<comment xml:lang="bg">ROM — Nintendo DS</comment>
<comment xml:lang="ca">ROM de Nintendo DS</comment>
@@ -9335,7 +9586,7 @@
<comment xml:lang="oc">ROM Nintendo DS</comment>
<comment xml:lang="pl">Plik ROM konsoli Nintendo DS</comment>
<comment xml:lang="pt">ROM Nintendo DS</comment>
- <comment xml:lang="pt_BR">ROM do Nintendo DS</comment>
+ <comment xml:lang="pt_BR">ROM de Nintendo DS</comment>
<comment xml:lang="ro">ROM Nintendo DS</comment>
<comment xml:lang="ru">Nintendo DS ROM</comment>
<comment xml:lang="sk">ROM pre Nintendo DS</comment>
@@ -9346,13 +9597,14 @@
<comment xml:lang="tr">Nintendo DS ROM</comment>
<comment xml:lang="uk">ППП Nintendo</comment>
<comment xml:lang="vi">ROM DS Nintendo</comment>
- <comment xml:lang="zh_CN">Nintendo DS ROM</comment>
+ <comment xml:lang="zh_CN">任天堂 DS ROM</comment>
<comment xml:lang="zh_TW">任天堂 DS ROM</comment>
<generic-icon name="application-x-executable"/>
<glob pattern="*.nds"/>
</mime-type>
<mime-type type="application/x-pc-engine-rom">
<comment>PC Engine ROM</comment>
+ <comment xml:lang="ast">ROM de PC Engine</comment>
<comment xml:lang="ca">ROM de PC Engine</comment>
<comment xml:lang="cs">ROM pro PC Engine</comment>
<comment xml:lang="da">PC Engine ROM</comment>
@@ -9363,6 +9615,7 @@
<comment xml:lang="eu">PC Engine ROM</comment>
<comment xml:lang="fi">PC Engine ROM</comment>
<comment xml:lang="fr">ROM PC Engine</comment>
+ <comment xml:lang="ga">ROM PC Engine</comment>
<comment xml:lang="gl">ROM de máquina de PC</comment>
<comment xml:lang="he">ROM של PC Engine</comment>
<comment xml:lang="hr">PC Engine ROM</comment>
@@ -9390,6 +9643,7 @@
</mime-type>
<mime-type type="application/x-wii-rom">
<comment>Wii disc image</comment>
+ <comment xml:lang="ast">Imaxe de discu de Wii</comment>
<comment xml:lang="ca">imatge de disc de Wii</comment>
<comment xml:lang="cs">obraz disku pro Wii</comment>
<comment xml:lang="da">Wii-diskaftryk</comment>
@@ -9400,6 +9654,7 @@
<comment xml:lang="eu">Wii disko irudia</comment>
<comment xml:lang="fi">Wii-levykuva</comment>
<comment xml:lang="fr">image disque Wii</comment>
+ <comment xml:lang="ga">íomhá diosca Wii</comment>
<comment xml:lang="gl">Imaxe de disco de Wii</comment>
<comment xml:lang="he">דמות כונן Wii</comment>
<comment xml:lang="hr">Wii slika diska</comment>
@@ -9413,14 +9668,14 @@
<comment xml:lang="pl">Obraz płyty konsoli Wii</comment>
<comment xml:lang="pt">imagem de disco Wii</comment>
<comment xml:lang="pt_BR">Imagem de disco Wii</comment>
- <comment xml:lang="ru">образ диска Wii</comment>
+ <comment xml:lang="ru">Образ диска Wii</comment>
<comment xml:lang="sk">Obraz disku Wii</comment>
<comment xml:lang="sl">Odtis diska Wii</comment>
- <comment xml:lang="sr">слика диска Вии-ја</comment>
+ <comment xml:lang="sr">одраз диска Вии-ја</comment>
<comment xml:lang="sv">Wii-skivavbild</comment>
<comment xml:lang="tr">Wii disk görüntüsü</comment>
<comment xml:lang="uk">образ диска Wii</comment>
- <comment xml:lang="zh_CN">Wii光盘镜像</comment>
+ <comment xml:lang="zh_CN">Wii 光盘映像</comment>
<comment xml:lang="zh_TW">Wii 光碟映像檔</comment>
<alias type="application/x-wii-iso-image"/>
<alias type="application/x-wbfs"/>
@@ -9441,7 +9696,9 @@
<comment xml:lang="de">WiiWare-Paket</comment>
<comment xml:lang="en_GB">WiiWare bundle</comment>
<comment xml:lang="es">conjunto de WiiWare</comment>
+ <comment xml:lang="eu">WiiWare bilduma</comment>
<comment xml:lang="fr">lot WiiWare</comment>
+ <comment xml:lang="ga">burla WiiWare</comment>
<comment xml:lang="he">מאגד WiiWare</comment>
<comment xml:lang="hr">WiiWare paket</comment>
<comment xml:lang="hu">WiiWare csomag</comment>
@@ -9454,13 +9711,13 @@
<comment xml:lang="pl">Pakiet WiiWare</comment>
<comment xml:lang="pt">pacote WiiWare</comment>
<comment xml:lang="pt_BR">Pacote WiiWare</comment>
- <comment xml:lang="ru">пакет WiiWare</comment>
+ <comment xml:lang="ru">Пакет WiiWare</comment>
<comment xml:lang="sk">Balík WiiWare</comment>
<comment xml:lang="sr">ВииВер комплет</comment>
<comment xml:lang="sv">WiiWare-paket</comment>
<comment xml:lang="tr">WiiWare paketi</comment>
<comment xml:lang="uk">пакет WiiWare</comment>
- <comment xml:lang="zh_CN">WiiWare bundle</comment>
+ <comment xml:lang="zh_CN">WiiWare 捆绑包</comment>
<comment xml:lang="zh_TW">WiiWare 綁包</comment>
<generic-icon name="application-x-executable"/>
<magic priority="50">
@@ -9482,6 +9739,7 @@
<comment xml:lang="eu">GameCube disko irudia</comment>
<comment xml:lang="fi">GameCube-levykuva</comment>
<comment xml:lang="fr">image disque GameCube</comment>
+ <comment xml:lang="ga">íomhá diosca GameCube</comment>
<comment xml:lang="gl">Imae de disco de GameCube</comment>
<comment xml:lang="he">דמות כונן GameCube</comment>
<comment xml:lang="hr">GameCube slika diska</comment>
@@ -9495,14 +9753,14 @@
<comment xml:lang="pl">Obraz płyty konsoli GameCube</comment>
<comment xml:lang="pt">imagem de disco GameCube</comment>
<comment xml:lang="pt_BR">Imagem de disco GameCube</comment>
- <comment xml:lang="ru">образ диска GameCube</comment>
+ <comment xml:lang="ru">Образ диска GameCube</comment>
<comment xml:lang="sk">Obraz disku GameCube</comment>
<comment xml:lang="sl">Odtis diska GameCube</comment>
- <comment xml:lang="sr">слика диска Гејм Коцке</comment>
+ <comment xml:lang="sr">одраз диска Гејм Коцке</comment>
<comment xml:lang="sv">GameCube-skivavbild</comment>
<comment xml:lang="tr">GameCube disk görüntüsü</comment>
<comment xml:lang="uk">образ диска GameCube</comment>
- <comment xml:lang="zh_CN">GameCube光盘镜像</comment>
+ <comment xml:lang="zh_CN">GameCube 光盘映像</comment>
<comment xml:lang="zh_TW">GameCube 光碟映像檔</comment>
<generic-icon name="application-x-executable"/>
<alias type="application/x-gamecube-iso-image"/>
@@ -9513,16 +9771,85 @@
</mime-type>
<mime-type type="application/x-thomson-cartridge-memo7">
<comment>Thomson Mémo7 cartridge</comment>
+ <comment xml:lang="ca">cartutx Thomson Mémo7</comment>
+ <comment xml:lang="cs">Kazeta Thomson Mémo7</comment>
+ <comment xml:lang="de">Thomson-Mémo7-Steckmodul</comment>
+ <comment xml:lang="en_GB">Thomson Mémo7 cartridge</comment>
+ <comment xml:lang="es">cartucho Mémo7 de Thomson</comment>
+ <comment xml:lang="fr">cartouche Thomson Mémo7</comment>
+ <comment xml:lang="ga">cartús Thomson Mémo7</comment>
+ <comment xml:lang="hr">Thomson Mémo7 uložak</comment>
+ <comment xml:lang="hu">Thomson Mémo7 kazetta</comment>
+ <comment xml:lang="id">cartridge Thomson Mémo7</comment>
+ <comment xml:lang="it">Cartuccia Thomson Mémo7</comment>
+ <comment xml:lang="kk">Thomson Mémo7 картриджі</comment>
+ <comment xml:lang="ko">톰슨 메모7 카트릿지</comment>
+ <comment xml:lang="pl">Kartridż Thomson Mémo7</comment>
+ <comment xml:lang="pt_BR">Cartucho Thomson Mémo7</comment>
+ <comment xml:lang="ru">Картридж Thomson Mémo7</comment>
+ <comment xml:lang="sk">Kazeta Thomson Mémo7</comment>
+ <comment xml:lang="sr">Томсон Мемо7 кертриџ</comment>
+ <comment xml:lang="sv">Thomson Mémo7-spelkassett</comment>
+ <comment xml:lang="tr">Thomson Mémo7 kartuşu</comment>
+ <comment xml:lang="uk">картридж Thomson Mémo7</comment>
+ <comment xml:lang="zh_CN">Thomson Mémo7 卡带</comment>
+ <comment xml:lang="zh_TW">Thomson Mémo7 卡匣</comment>
<generic-icon name="application-x-executable"/>
<glob pattern="*.m7"/>
</mime-type>
<mime-type type="application/x-thomson-cassette">
<comment>Thomson cassette</comment>
+ <comment xml:lang="ca">cinta de casset Thomson</comment>
+ <comment xml:lang="cs">Kazeta Thomson</comment>
+ <comment xml:lang="de">Thomson-Kassette</comment>
+ <comment xml:lang="en_GB">Thomson cassette</comment>
+ <comment xml:lang="es">casete de Thomson</comment>
+ <comment xml:lang="fr">cassette Thomson</comment>
+ <comment xml:lang="ga">caiséad Thomson</comment>
+ <comment xml:lang="hr">Thomson kaseta</comment>
+ <comment xml:lang="hu">Thomson kazetta</comment>
+ <comment xml:lang="id">kaset Thomson</comment>
+ <comment xml:lang="it">Cassetta Thomson</comment>
+ <comment xml:lang="kk">Thomson кассетасы</comment>
+ <comment xml:lang="ko">톰슨 카셋트</comment>
+ <comment xml:lang="pl">Kaseta Thomson</comment>
+ <comment xml:lang="pt_BR">Cassete Thomson</comment>
+ <comment xml:lang="ru">Кассета Thomson</comment>
+ <comment xml:lang="sk">Kazeta Thomson</comment>
+ <comment xml:lang="sr">Томсон касете</comment>
+ <comment xml:lang="sv">Thomson-kassett</comment>
+ <comment xml:lang="tr">Thomson kaset</comment>
+ <comment xml:lang="uk">касета Thomson</comment>
+ <comment xml:lang="zh_CN">Thomson 磁带</comment>
+ <comment xml:lang="zh_TW">Thomson 卡匣</comment>
<generic-icon name="application-x-executable"/>
<glob pattern="*.k7"/>
</mime-type>
<mime-type type="application/x-hfe-floppy-image">
<comment>HFE floppy disk image</comment>
+ <comment xml:lang="ca">imatge de disquet HFE</comment>
+ <comment xml:lang="cs">Obraz diskety HFE</comment>
+ <comment xml:lang="de">HFE-Diskettenabbild</comment>
+ <comment xml:lang="en_GB">HFE floppy disk image</comment>
+ <comment xml:lang="es">imagen de disquete HFE</comment>
+ <comment xml:lang="fr">image disquette HFE</comment>
+ <comment xml:lang="ga">íomhá diosca fhlapaigh HFE</comment>
+ <comment xml:lang="hr">HFE slika diskete</comment>
+ <comment xml:lang="hu">HFE flopi lemezkép</comment>
+ <comment xml:lang="id">image disk floppy HFE</comment>
+ <comment xml:lang="it">Immagine disco floppy HFE</comment>
+ <comment xml:lang="kk">HFE иілгіш диск бейнесі</comment>
+ <comment xml:lang="ko">HFE 플로피 디스크 이미지</comment>
+ <comment xml:lang="pl">Obraz dyskietki HFE</comment>
+ <comment xml:lang="pt_BR">Imagem de disco flexível HFE</comment>
+ <comment xml:lang="ru">Образ гибкого диска HFE</comment>
+ <comment xml:lang="sk">Obraz pružného disku HFE</comment>
+ <comment xml:lang="sr">ХФЕ слика флопи диска</comment>
+ <comment xml:lang="sv">HFE-diskavbild</comment>
+ <comment xml:lang="tr">HFE disket kalıbı</comment>
+ <comment xml:lang="uk">образ дискети HFE</comment>
+ <comment xml:lang="zh_CN">HFE 软盘映像</comment>
+ <comment xml:lang="zh_TW">HFE 軟碟映像檔</comment>
<acronym>HFE</acronym>
<expanded-acronym>HxC Floppy Emulator</expanded-acronym>
<generic-icon name="application-x-executable"/>
@@ -9530,9 +9857,33 @@
<magic>
<match value="HXCPICFE" type="string" offset="0"/>
</magic>
+ <alias type="application/x-hfe-file"/>
</mime-type>
<mime-type type="application/x-thomson-sap-image">
<comment>SAP Thomson floppy disk image</comment>
+ <comment xml:lang="ca">imatge de disquet SAP Thomson</comment>
+ <comment xml:lang="cs">Obraz diskety SAP Thomson</comment>
+ <comment xml:lang="de">SAP-Thomson-Diskettenabbild</comment>
+ <comment xml:lang="en_GB">SAP Thomson floppy disk image</comment>
+ <comment xml:lang="es">imagen de disquete SAP de Thomson</comment>
+ <comment xml:lang="fr">image disquette SAP Thomson</comment>
+ <comment xml:lang="ga">íomhá diosca fhlapaigh SAP Thomson</comment>
+ <comment xml:lang="hr">SAP Thomson slika diskete</comment>
+ <comment xml:lang="hu">SAP Thomson flopi lemezkép</comment>
+ <comment xml:lang="id">image disk floppy SAP Thomson</comment>
+ <comment xml:lang="it">Immagine disco floppy Thomson SAP</comment>
+ <comment xml:lang="kk">SAP Thomson иілгіш диск бейнесі</comment>
+ <comment xml:lang="ko">SAP 톰슨 플로피 디스크 이미지</comment>
+ <comment xml:lang="pl">Obraz dyskietki SAP Thomson</comment>
+ <comment xml:lang="pt_BR">Imagem de disco flexível SAP Thomson</comment>
+ <comment xml:lang="ru">Образ гибкого диска SAP Thomson</comment>
+ <comment xml:lang="sk">Obraz pružného disku SAP Thomson</comment>
+ <comment xml:lang="sr">САП Томсон слика флопи диска</comment>
+ <comment xml:lang="sv">SAP Thomson-diskavbild</comment>
+ <comment xml:lang="tr">SAP Thomson disket kalıbı</comment>
+ <comment xml:lang="uk">образ дискети Thomson SAP</comment>
+ <comment xml:lang="zh_CN">SAP Thomson 软盘映像</comment>
+ <comment xml:lang="zh_TW">SAP Thomson 軟碟映像檔</comment>
<acronym>SAP</acronym>
<expanded-acronym>Système d'Archivage Pukall</expanded-acronym>
<generic-icon name="application-x-executable"/>
@@ -9540,6 +9891,7 @@
<magic>
<match value="SYSTEME D'ARCHIVAGE PUKALL S.A.P. (c) Alexandre PUKALL Avril 1998" type="string" offset="1"/>
</magic>
+ <alias type="application/x-sap-file"/>
</mime-type>
<mime-type type="application/vnd.debian.binary-package">
<comment>Debian package</comment>
@@ -9583,7 +9935,7 @@
<comment xml:lang="pt">pacote Debian</comment>
<comment xml:lang="pt_BR">Pacote Debian</comment>
<comment xml:lang="ro">Pachet Debian</comment>
- <comment xml:lang="ru">пакет Debian</comment>
+ <comment xml:lang="ru">Пакет Debian</comment>
<comment xml:lang="sk">Balíček Debianu</comment>
<comment xml:lang="sl">Datoteka paketa Debian</comment>
<comment xml:lang="sq">Paketë Debian</comment>
@@ -9644,11 +9996,11 @@
<comment xml:lang="pt">ficheiro do Qt Designer</comment>
<comment xml:lang="pt_BR">Arquivo do Qt Designer</comment>
<comment xml:lang="ro">Fișier Qt Designer</comment>
- <comment xml:lang="ru">файл Qt Designer</comment>
+ <comment xml:lang="ru">Файл Qt Designer</comment>
<comment xml:lang="sk">Súbor Qt Designer</comment>
<comment xml:lang="sl">Datoteka Qt Designer</comment>
<comment xml:lang="sq">File Qt Designer</comment>
- <comment xml:lang="sr">датотека Кут Дизајнера</comment>
+ <comment xml:lang="sr">датотека Кут дизајнера</comment>
<comment xml:lang="sv">Qt Designer-fil</comment>
<comment xml:lang="tr">Qt Tasarımcı dosyası</comment>
<comment xml:lang="uk">файл програми Qt-дизайнер</comment>
@@ -9676,6 +10028,7 @@
<comment xml:lang="eu">Qt Markup lengoai fitxategia</comment>
<comment xml:lang="fi">QML-tiedosto</comment>
<comment xml:lang="fr">fichier Qt Markup Language</comment>
+ <comment xml:lang="ga">comhad teanga mharcála Qt</comment>
<comment xml:lang="gl">ficheiro de linguaxe de marcado Qt</comment>
<comment xml:lang="he">קובץ שפת סימון של Qt</comment>
<comment xml:lang="hr">Qt Markup Language datoteka</comment>
@@ -9692,17 +10045,23 @@
<comment xml:lang="pl">Plik języka znaczników Qt</comment>
<comment xml:lang="pt">ficheiro de linguagem Qt Markup</comment>
<comment xml:lang="pt_BR">Arquivo de Qt Markup Language</comment>
- <comment xml:lang="ru">файл Qt Markup Language</comment>
+ <comment xml:lang="ru">Файл Qt Markup Language</comment>
<comment xml:lang="sk">Súbor značkovacieho jazyka Qt</comment>
<comment xml:lang="sl">Datoteka označevalnega jezika Qt</comment>
- <comment xml:lang="sr">датотека Кутовог језика означавања</comment>
+ <comment xml:lang="sr">датотека КуТ-овог језика означавања</comment>
<comment xml:lang="sv">Qt-märkspråksfil</comment>
<comment xml:lang="tr">Qt İşaretleme Dili dosyası</comment>
<comment xml:lang="uk">файл мови розмітки Qt</comment>
- <comment xml:lang="zh_CN">Qt </comment>
+ <comment xml:lang="zh_CN">Qt Markup Language 文件</comment>
<comment xml:lang="zh_TW">Qt 標記語言檔</comment>
<magic priority="80">
- <match value="import Qt " type="string" offset="0:256"/>
+ <match value="/bin/env qml" type="string" offset="2:16"/>
+ <match value="import Qt" type="string" offset="0:3000">
+ <match value="{" type="string" offset="9:3009"/>
+ </match>
+ <match value="import Qml" type="string" offset="0:3000">
+ <match value="{" type="string" offset="9:3009"/>
+ </match>
</magic>
<glob pattern="*.qml"/>
<glob pattern="*.qmltypes"/>
@@ -9725,10 +10084,10 @@
<comment xml:lang="fi">työpöydän asetustiedosto</comment>
<comment xml:lang="fo">skriviborðssamansetingarfíla</comment>
<comment xml:lang="fr">fichier de configuration desktop</comment>
- <comment xml:lang="ga">comhad chumraíocht deisce</comment>
+ <comment xml:lang="ga">comhad cumraíochta deisce</comment>
<comment xml:lang="gl">ficheiro de configuración de escritorio</comment>
<comment xml:lang="he">קובץ הגדרות שולחן עבודה</comment>
- <comment xml:lang="hr">datoteka postavki radne površine</comment>
+ <comment xml:lang="hr">Datoteka prečaca radne površine</comment>
<comment xml:lang="hu">asztalbeállító fájl</comment>
<comment xml:lang="ia">File de configuration de scriptorio</comment>
<comment xml:lang="id">berkas konfigurasi destop</comment>
@@ -9747,7 +10106,7 @@
<comment xml:lang="pt">ficheiro de configuração de área de trabalho</comment>
<comment xml:lang="pt_BR">Arquivo de configuração desktop</comment>
<comment xml:lang="ro">fișier de configurare al desktopului</comment>
- <comment xml:lang="ru">файл настроек рабочего стола</comment>
+ <comment xml:lang="ru">Файл настроек рабочего стола</comment>
<comment xml:lang="sk">Súbor nastavení pracovnej plochy</comment>
<comment xml:lang="sl">nastavitvena datoteka namizja</comment>
<comment xml:lang="sq">File konfigurimi desktop</comment>
@@ -9774,6 +10133,7 @@
<mime-type type="application/x-fictionbook+xml">
<comment>FictionBook document</comment>
<comment xml:lang="ar">مستند FictionBook</comment>
+ <comment xml:lang="ast">Documentu de FictionBook</comment>
<comment xml:lang="bg">Документ — FictionBook</comment>
<comment xml:lang="ca">document FictionBook</comment>
<comment xml:lang="cs">dokument FictionBook</comment>
@@ -9807,7 +10167,7 @@
<comment xml:lang="pt">documento FictionBook</comment>
<comment xml:lang="pt_BR">Documento FictionBook</comment>
<comment xml:lang="ro">Document FictionBook</comment>
- <comment xml:lang="ru">документ FictionBook</comment>
+ <comment xml:lang="ru">Документ FictionBook</comment>
<comment xml:lang="sk">Dokument FictionBook</comment>
<comment xml:lang="sl">Dokument FictionBook</comment>
<comment xml:lang="sr">документ Фикшон Књиге</comment>
@@ -9827,6 +10187,7 @@
</mime-type>
<mime-type type="application/x-zip-compressed-fb2">
<comment>Compressed FictionBook document</comment>
+ <comment xml:lang="ast">Documentu comprimíu de FictionBook</comment>
<comment xml:lang="ca">document FictionBook amb compressió</comment>
<comment xml:lang="cs">komprimovaný dokument FictionBook</comment>
<comment xml:lang="da">Komprimeret FictionBook-dokument</comment>
@@ -9837,6 +10198,7 @@
<comment xml:lang="eu">Konprimitutako FictionBook dokumentua</comment>
<comment xml:lang="fi">Pakattu FictionBook-asiakirja</comment>
<comment xml:lang="fr">document FictionBook compressé</comment>
+ <comment xml:lang="ga">cáipéis chomhbhrúite FictionBook</comment>
<comment xml:lang="gl">Documento de FictionBook comprimida</comment>
<comment xml:lang="he">מסמך FictionBook מכווץ</comment>
<comment xml:lang="hr">Sažet FictionBook dokument</comment>
@@ -9858,7 +10220,7 @@
<comment xml:lang="tr">Sıkıştırılmış KurguKitap belgesi</comment>
<comment xml:lang="uk">стиснений документ FictionBook</comment>
<comment xml:lang="zh_CN">压缩的 FictionBook 文档</comment>
- <comment xml:lang="zh_TW">壓縮的 FictionBook 文件</comment>
+ <comment xml:lang="zh_TW">壓縮版 FictionBook 文件</comment>
<sub-class-of type="application/zip"/>
<glob pattern="*.fb2.zip"/>
<magic priority="70">
@@ -9910,7 +10272,7 @@
<comment xml:lang="pt">diagrama Dia</comment>
<comment xml:lang="pt_BR">Diagrama do Dia</comment>
<comment xml:lang="ro">Diagramă Dia</comment>
- <comment xml:lang="ru">диаграмма Dia</comment>
+ <comment xml:lang="ru">Диаграмма Dia</comment>
<comment xml:lang="sk">Diagram Dia</comment>
<comment xml:lang="sl">Datoteka diagrama Dia</comment>
<comment xml:lang="sq">Diagramë Dia</comment>
@@ -9963,7 +10325,7 @@
<comment xml:lang="pt">forma Dia</comment>
<comment xml:lang="pt_BR">Formato Dia</comment>
<comment xml:lang="ro">Figură Dia</comment>
- <comment xml:lang="ru">фигура Dia</comment>
+ <comment xml:lang="ru">Фигура Dia</comment>
<comment xml:lang="sk">Tvar Dia</comment>
<comment xml:lang="sl">Datoteka oblik Dia</comment>
<comment xml:lang="sr">облик Дие</comment>
@@ -9983,6 +10345,7 @@
<mime-type type="application/x-dvi">
<comment>TeX DVI document</comment>
<comment xml:lang="ar">مستند TeX DVI</comment>
+ <comment xml:lang="ast">Documentu Tex DVI</comment>
<comment xml:lang="be@latin">Dakument TeX DVI</comment>
<comment xml:lang="bg">Документ — TeX DVI</comment>
<comment xml:lang="ca">document DVI de TeX</comment>
@@ -10019,7 +10382,7 @@
<comment xml:lang="pt">documento TeX DVI</comment>
<comment xml:lang="pt_BR">Documento DVI TeX</comment>
<comment xml:lang="ro">Document Tex DVI</comment>
- <comment xml:lang="ru">документ TeX DVI</comment>
+ <comment xml:lang="ru">Документ TeX DVI</comment>
<comment xml:lang="sk">Dokument TeX DVI</comment>
<comment xml:lang="sl">Dokument TeX DVI</comment>
<comment xml:lang="sq">Dokument TeX DVI</comment>
@@ -10080,11 +10443,11 @@
<comment xml:lang="pt">tema Enlightenment</comment>
<comment xml:lang="pt_BR">Tema do Enlightenment</comment>
<comment xml:lang="ro">Temă Enlightenment</comment>
- <comment xml:lang="ru">тема Enlightenment</comment>
+ <comment xml:lang="ru">Тема Enlightenment</comment>
<comment xml:lang="sk">Motív Enlightenment</comment>
<comment xml:lang="sl">Datoteka teme Enlightenment</comment>
<comment xml:lang="sq">Tema Enlightenment</comment>
- <comment xml:lang="sr">тема Просвећености</comment>
+ <comment xml:lang="sr">тема за Енлајтмент</comment>
<comment xml:lang="sv">Enlightenment-tema</comment>
<comment xml:lang="tr">Enlightenment teması</comment>
<comment xml:lang="uk">тема Enlightenment</comment>
@@ -10133,7 +10496,7 @@
<comment xml:lang="pt">animação Egon Animator</comment>
<comment xml:lang="pt_BR">Animação do Egon Animator</comment>
<comment xml:lang="ro">Animație Egon Animator</comment>
- <comment xml:lang="ru">анимация Egon Animator</comment>
+ <comment xml:lang="ru">Анимация Egon Animator</comment>
<comment xml:lang="sk">Animácia Egon Animator</comment>
<comment xml:lang="sl">Datoteka animacije Egon Animator</comment>
<comment xml:lang="sq">Animim Egon Animator</comment>
@@ -10167,7 +10530,7 @@
<comment xml:lang="ga">comhad inrite</comment>
<comment xml:lang="gl">executábel</comment>
<comment xml:lang="he">קובץ הרצה</comment>
- <comment xml:lang="hr">izvršna datoteka</comment>
+ <comment xml:lang="hr">Izvršna datoteka</comment>
<comment xml:lang="hu">futtatható</comment>
<comment xml:lang="ia">Executabile</comment>
<comment xml:lang="id">dapat dieksekusi</comment>
@@ -10186,7 +10549,7 @@
<comment xml:lang="pt">executável</comment>
<comment xml:lang="pt_BR">Executável</comment>
<comment xml:lang="ro">executabil</comment>
- <comment xml:lang="ru">исполняемый</comment>
+ <comment xml:lang="ru">Исполняемый</comment>
<comment xml:lang="sk">Spustiteľný súbor</comment>
<comment xml:lang="sl">izvedljiva datoteka</comment>
<comment xml:lang="sq">I ekzekutueshëm</comment>
@@ -10254,7 +10617,7 @@
<comment xml:lang="pt">ficheiro FLTK Fluid</comment>
<comment xml:lang="pt_BR">Arquivo Fluid do FLTK</comment>
<comment xml:lang="ro">Fișier FLTK Fluid</comment>
- <comment xml:lang="ru">файл FLTK Fluid</comment>
+ <comment xml:lang="ru">Файл FLTK Fluid</comment>
<comment xml:lang="sk">Súbor FLTK Fluid</comment>
<comment xml:lang="sl">Datoteka FLTK Fluid</comment>
<comment xml:lang="sq">File FLTK Fluid</comment>
@@ -10274,10 +10637,11 @@
</magic>
<glob pattern="*.fl"/>
</mime-type>
- <mime-type type="application/font-woff">
+ <mime-type type="font/woff">
<comment>WOFF font</comment>
- <comment xml:lang="ca">tipus de lletra WOFF</comment>
- <comment xml:lang="cs">písmo WOFF</comment>
+ <comment xml:lang="ast">Fonte WOFF</comment>
+ <comment xml:lang="ca">lletra WOFF</comment>
+ <comment xml:lang="cs">font WOFF</comment>
<comment xml:lang="da">WOFF-skrifttype</comment>
<comment xml:lang="de">WOFF-Schrift</comment>
<comment xml:lang="el">Γραμματοσειρά WOFF</comment>
@@ -10286,13 +10650,14 @@
<comment xml:lang="eu">WOFF letra-tipoa</comment>
<comment xml:lang="fi">WOFF-fontti</comment>
<comment xml:lang="fr">police WOFF</comment>
+ <comment xml:lang="ga">cló WOFF</comment>
<comment xml:lang="gl">Tipo de letra WOFF</comment>
<comment xml:lang="he">גופן WOFF</comment>
<comment xml:lang="hr">WOFF slovo</comment>
<comment xml:lang="hu">WOFF-betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras WOFF</comment>
<comment xml:lang="id">Fonta WOFF</comment>
- <comment xml:lang="it">Font WOFF</comment>
+ <comment xml:lang="it">Carattere WOFF</comment>
<comment xml:lang="ja">WOFF フォント</comment>
<comment xml:lang="kk">WOFF қарібі</comment>
<comment xml:lang="ko">WOFF 글꼴</comment>
@@ -10301,7 +10666,7 @@
<comment xml:lang="pl">Czcionka WOFF</comment>
<comment xml:lang="pt">letra WOFF</comment>
<comment xml:lang="pt_BR">Fonte WOFF</comment>
- <comment xml:lang="ru">шрифт WOFF</comment>
+ <comment xml:lang="ru">Шрифт WOFF</comment>
<comment xml:lang="sk">Písmo WOFF</comment>
<comment xml:lang="sl">Pisava WOFF</comment>
<comment xml:lang="sr">ВОФФ слова</comment>
@@ -10317,55 +10682,65 @@
<match value="0x774f4646" type="big32" offset="0"/>
</magic>
<glob pattern="*.woff"/>
+ <alias type="application/font-woff"/>
+ </mime-type>
+ <mime-type type="font/woff">
+ <comment>WOFF2 font</comment>
+ <comment xml:lang="ast">Fonte WOFF2</comment>
+ <comment xml:lang="ca">lletra WOFF2</comment>
+ <comment xml:lang="cs">font WOFF2</comment>
+ <comment xml:lang="de">WOFF2-Schrift</comment>
+ <comment xml:lang="en_GB">WOFF2 font</comment>
+ <comment xml:lang="es">tipo de letra WOFF2</comment>
+ <comment xml:lang="fi">WOFF2-fontti</comment>
+ <comment xml:lang="hr">WOFF2 slovo</comment>
+ <comment xml:lang="hu">WOFF2 betűkészlet</comment>
+ <comment xml:lang="id">Fonta WOFF2</comment>
+ <comment xml:lang="it">Carattere WOFF2</comment>
+ <comment xml:lang="kk">WOFF2 қарібі</comment>
+ <comment xml:lang="ko">WOFF2 글꼴</comment>
+ <comment xml:lang="pl">Czcionka WOFF2</comment>
+ <comment xml:lang="pt_BR">Fonte WOFF2</comment>
+ <comment xml:lang="ru">Шрифт WOFF2</comment>
+ <comment xml:lang="sk">Písmo WOFF2</comment>
+ <comment xml:lang="sv">WOFF2-typsnitt</comment>
+ <comment xml:lang="uk">шрифт WOFF2</comment>
+ <comment xml:lang="zh_CN">WOFF2 字体</comment>
+ <comment xml:lang="zh_TW">WOFF2 字型</comment>
+ <acronym>WOFF2</acronym>
+ <expanded-acronym>Web Open Font Format 2.0</expanded-acronym>
+ <generic-icon name="font-x-generic"/>
+ <magic priority="50">
+ <match value="0x774f4632" type="big32" offset="0"/>
+ </magic>
+ <glob pattern="*.woff2"/>
</mime-type>
<mime-type type="application/x-font-type1">
- <comment>Postscript type-1 font</comment>
- <comment xml:lang="ar">خط Postscript type-1</comment>
- <comment xml:lang="be@latin">Šryft Postscript type-1</comment>
- <comment xml:lang="bg">Шрифт — Postscript Type 1</comment>
- <comment xml:lang="ca">tipus de lletra Postscript type-1</comment>
- <comment xml:lang="cs">písmo Postscript type-1</comment>
- <comment xml:lang="da">PostScript type-1-skrifttype</comment>
- <comment xml:lang="de">Postscript-Typ-1-Schrift</comment>
- <comment xml:lang="el">Γραμματοσειρά Postscript type-1</comment>
- <comment xml:lang="en_GB">Postscript type-1 font</comment>
+ <comment>PostScript type-1 font</comment>
+ <comment xml:lang="ca">lletra type-1 de PostScript</comment>
+ <comment xml:lang="cs">font PostScript type-1</comment>
+ <comment xml:lang="de">PostScript-Typ-1-Schrift</comment>
+ <comment xml:lang="en_GB">PostScript type-1 font</comment>
<comment xml:lang="es">tipo de letra PostScript Type-1</comment>
<comment xml:lang="eu">PostScript type-1 letra-tipoa</comment>
- <comment xml:lang="fi">PostScript tyyppi-1 -fontti</comment>
- <comment xml:lang="fo">Postscript type-1 stavasnið</comment>
- <comment xml:lang="fr">police Postscript Type 1</comment>
- <comment xml:lang="ga">cló Postscript type-1</comment>
- <comment xml:lang="gl">tipo de letra PostScript tipo-1</comment>
- <comment xml:lang="he">גופן של Postscript type-1</comment>
- <comment xml:lang="hr">Postscript crsta-1 slovo</comment>
- <comment xml:lang="hu">Postscript type-1 betűkészlet</comment>
- <comment xml:lang="ia">Typo de litteras PostScript typo 1</comment>
- <comment xml:lang="id">Fonta tipe-1 Postscript</comment>
- <comment xml:lang="it">Carattere Postscript type-1</comment>
- <comment xml:lang="ja">PostScript type-1 フォント</comment>
- <comment xml:lang="kk">Postscript type-1 қарібі</comment>
+ <comment xml:lang="fr">police PostScript Type 1</comment>
+ <comment xml:lang="ga">cló PostScript type-1</comment>
+ <comment xml:lang="hr">PostScript type-1 slovo</comment>
+ <comment xml:lang="hu">PostScript type-1 betűkészlet</comment>
+ <comment xml:lang="id">fonta PostScript type-1</comment>
+ <comment xml:lang="it">Carattere PostScript type-1</comment>
+ <comment xml:lang="kk">PostScript type-1 қарібі</comment>
<comment xml:lang="ko">PostScript Type-1 글꼴</comment>
- <comment xml:lang="lt">Postscript type-1 šriftas</comment>
- <comment xml:lang="lv">Postscript 1-tipa fonts</comment>
- <comment xml:lang="nb">Postscript type-1 skrift</comment>
- <comment xml:lang="nl">PostScript type-1-lettertype</comment>
- <comment xml:lang="nn">PostScript type 1-skrifttype</comment>
- <comment xml:lang="oc">poliça Postescript Type 1</comment>
<comment xml:lang="pl">Czcionka PostScript Type-1</comment>
- <comment xml:lang="pt">letra PostScript tipo 1</comment>
<comment xml:lang="pt_BR">Fonte PostScript tipo-1</comment>
- <comment xml:lang="ro">Font Postscript type-1</comment>
- <comment xml:lang="ru">шрифт PostScript Type-1</comment>
- <comment xml:lang="sk">Písmo Postscript type-1</comment>
- <comment xml:lang="sl">Datoteka pisave Postscript vrste-1</comment>
- <comment xml:lang="sq">Lloj gërmash Postscript type-1</comment>
+ <comment xml:lang="ru">Шрифт PostScript Type-1</comment>
+ <comment xml:lang="sk">Písmo PostScript typu 1</comment>
<comment xml:lang="sr">слова Постскрипта врсте-1</comment>
- <comment xml:lang="sv">Postscript type-1-typsnitt</comment>
- <comment xml:lang="tr">Postscript type-1 yazı tipi</comment>
- <comment xml:lang="uk">шрифт Postscript type-1</comment>
- <comment xml:lang="vi">Phông kiểu 1 PostScript</comment>
- <comment xml:lang="zh_CN">Postscript type-1 字体</comment>
- <comment xml:lang="zh_TW">Postscript type-1 字型</comment>
+ <comment xml:lang="sv">PostScript type-1-typsnitt</comment>
+ <comment xml:lang="tr">PostScript tip-1 yazı tipi</comment>
+ <comment xml:lang="uk">шрифт type-1 PostScript</comment>
+ <comment xml:lang="zh_CN">PostScript type-1 字体</comment>
+ <comment xml:lang="zh_TW">PostScript type-1 字型</comment>
<sub-class-of type="application/postscript"/>
<generic-icon name="font-x-generic"/>
<magic priority="60">
@@ -10386,8 +10761,8 @@
<comment xml:lang="az">Adobe yazı növü metrikləri</comment>
<comment xml:lang="be@latin">Metryka šryftu Adobe</comment>
<comment xml:lang="bg">Шрифтова метрика — Adobe</comment>
- <comment xml:lang="ca">mètrica de tipus de lletra Adobe</comment>
- <comment xml:lang="cs">metrika písma Adobe</comment>
+ <comment xml:lang="ca">mètrica de lletra d'Adobe</comment>
+ <comment xml:lang="cs">metrika fontu Adobe</comment>
<comment xml:lang="cy">Metrigau Ffont Adobe</comment>
<comment xml:lang="da">Adobe skrifttypefil</comment>
<comment xml:lang="de">Adobe-Schriftmetriken</comment>
@@ -10401,7 +10776,7 @@
<comment xml:lang="ga">meadarachtaí cló Adobe</comment>
<comment xml:lang="gl">métricas de fonte de Adobe</comment>
<comment xml:lang="he">מדדי גופן של Adobe</comment>
- <comment xml:lang="hr">Adobe mjere fonta</comment>
+ <comment xml:lang="hr">Adobe mjere slova</comment>
<comment xml:lang="hu">Adobe-betűmetrika</comment>
<comment xml:lang="ia">Metricas de typo de litteras Adobe</comment>
<comment xml:lang="id">Metrik fonta Adobe</comment>
@@ -10420,7 +10795,7 @@
<comment xml:lang="pt">métrica de letras Adobe</comment>
<comment xml:lang="pt_BR">Métricas de fonte Adobe</comment>
<comment xml:lang="ro">Dimensiuni font Adobe</comment>
- <comment xml:lang="ru">метрика шрифта Adobe</comment>
+ <comment xml:lang="ru">Метрика шрифта Adobe</comment>
<comment xml:lang="sk">Metrika písma Adobe</comment>
<comment xml:lang="sl">Matrika pisave Adobe</comment>
<comment xml:lang="sq">Metrik lloj gërmash Adobe</comment>
@@ -10429,7 +10804,7 @@
<comment xml:lang="tr">Adobe yazıtipi ölçüleri</comment>
<comment xml:lang="uk">метрики шрифту Adobe</comment>
<comment xml:lang="vi">Cách đo phông chữ Adobe</comment>
- <comment xml:lang="zh_CN">Adobe 字体参数</comment>
+ <comment xml:lang="zh_CN">Adobe 字体规格</comment>
<comment xml:lang="zh_TW">Adobe 字型描述檔</comment>
<generic-icon name="font-x-generic"/>
<glob pattern="*.afm"/>
@@ -10440,8 +10815,8 @@
<comment xml:lang="az">BDF yazı növü</comment>
<comment xml:lang="be@latin">Šryft BDF</comment>
<comment xml:lang="bg">Шрифт — BDF</comment>
- <comment xml:lang="ca">tipus de lletra BDF</comment>
- <comment xml:lang="cs">písmo BDF</comment>
+ <comment xml:lang="ca">lletra BDF</comment>
+ <comment xml:lang="cs">font BDF</comment>
<comment xml:lang="cy">Ffont BDF</comment>
<comment xml:lang="da">BDF-skrifttype</comment>
<comment xml:lang="de">BDF-Schrift</comment>
@@ -10456,7 +10831,7 @@
<comment xml:lang="ga">cló BDF</comment>
<comment xml:lang="gl">tipo de fonte BDF</comment>
<comment xml:lang="he">גופן BDF</comment>
- <comment xml:lang="hr">BDF font</comment>
+ <comment xml:lang="hr">BDF slovo</comment>
<comment xml:lang="hu">BDF-betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras BDF</comment>
<comment xml:lang="id">Fonta BDF</comment>
@@ -10475,7 +10850,7 @@
<comment xml:lang="pt">letra BDF</comment>
<comment xml:lang="pt_BR">Fonte BDF</comment>
<comment xml:lang="ro">Font BDF</comment>
- <comment xml:lang="ru">шрифт BDF</comment>
+ <comment xml:lang="ru">Шрифт BDF</comment>
<comment xml:lang="sk">Písmo BDF</comment>
<comment xml:lang="sl">Datoteka pisave BDF</comment>
<comment xml:lang="sq">Lloj gërme BDF</comment>
@@ -10498,8 +10873,8 @@
<comment xml:lang="az">DOS yazı növü</comment>
<comment xml:lang="be@latin">Šryft DOS</comment>
<comment xml:lang="bg">Шрифт — DOS</comment>
- <comment xml:lang="ca">tipus de lletra DOS</comment>
- <comment xml:lang="cs">písmo pro DOS</comment>
+ <comment xml:lang="ca">lletra DOS</comment>
+ <comment xml:lang="cs">font pro DOS</comment>
<comment xml:lang="cy">Ffont DOS</comment>
<comment xml:lang="da">DOS-skrifttype</comment>
<comment xml:lang="de">DOS-Schrift</comment>
@@ -10514,7 +10889,7 @@
<comment xml:lang="ga">cló DOS</comment>
<comment xml:lang="gl">tipo de fonte de DOS</comment>
<comment xml:lang="he">גופן DOS</comment>
- <comment xml:lang="hr">DOS font</comment>
+ <comment xml:lang="hr">DOS slovo</comment>
<comment xml:lang="hu">DOS-betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras DOS</comment>
<comment xml:lang="id">Fonta DOS</comment>
@@ -10533,7 +10908,7 @@
<comment xml:lang="pt">letra DOS</comment>
<comment xml:lang="pt_BR">Fonte do DOS</comment>
<comment xml:lang="ro">Font DOS</comment>
- <comment xml:lang="ru">шрифт DOS</comment>
+ <comment xml:lang="ru">Шрифт DOS</comment>
<comment xml:lang="sk">Písmo pre DOS</comment>
<comment xml:lang="sl">Datoteka pisave DOS</comment>
<comment xml:lang="sq">Gërmë DOS</comment>
@@ -10557,8 +10932,8 @@
<comment xml:lang="az">Adobe FrameMaker yazı növü</comment>
<comment xml:lang="be@latin">Šryft Adobe FrameMaker</comment>
<comment xml:lang="bg">Шрифт — Adobe FrameMaker</comment>
- <comment xml:lang="ca">tipus de lletra d'Adobe FrameMaker</comment>
- <comment xml:lang="cs">písmo Adobe FrameMaker</comment>
+ <comment xml:lang="ca">lletra d'Adobe FrameMaker</comment>
+ <comment xml:lang="cs">font Adobe FrameMaker</comment>
<comment xml:lang="cy">Ffont Adobe FrameMaker</comment>
<comment xml:lang="da">Adobe FrameMaker-skrifttype</comment>
<comment xml:lang="de">Adobe-FrameMaker-Schrift</comment>
@@ -10573,7 +10948,7 @@
<comment xml:lang="ga">cló Adobe FrameMaker</comment>
<comment xml:lang="gl">tipo de fonte de Adobe FrameMaker</comment>
<comment xml:lang="he">גופן של Adobe FrameMaker</comment>
- <comment xml:lang="hr">Adobe FrameMaker font</comment>
+ <comment xml:lang="hr">Adobe FrameMaker slovo</comment>
<comment xml:lang="hu">Adobe FrameMaker-betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras pro Adobe FrameMaker</comment>
<comment xml:lang="id">Fonta Adobe FrameMaker</comment>
@@ -10592,7 +10967,7 @@
<comment xml:lang="pt">letra Adobe FrameMaker</comment>
<comment xml:lang="pt_BR">Fonte do Adobe FrameMaker</comment>
<comment xml:lang="ro">Font Adobe FrameMaker</comment>
- <comment xml:lang="ru">шрифт Adobe FrameMaker</comment>
+ <comment xml:lang="ru">Шрифт Adobe FrameMaker</comment>
<comment xml:lang="sk">Písmo Adobe FrameMaker</comment>
<comment xml:lang="sl">Datoteka pisave Adobe FrameMaker</comment>
<comment xml:lang="sq">Gërma Adobe FrameMaker</comment>
@@ -10614,8 +10989,8 @@
<comment xml:lang="az">LIBGRX yazı növü</comment>
<comment xml:lang="be@latin">Šryft LIBGRX</comment>
<comment xml:lang="bg">Шрифт — LIBGRX</comment>
- <comment xml:lang="ca">tipus de lletra LIBGRX</comment>
- <comment xml:lang="cs">písmo LIBGRX</comment>
+ <comment xml:lang="ca">lletra LIBGRX</comment>
+ <comment xml:lang="cs">font LIBGRX</comment>
<comment xml:lang="cy">Ffont LIBGRX</comment>
<comment xml:lang="da">LIBGRX-skrifttype</comment>
<comment xml:lang="de">LIBGRX-Schrift</comment>
@@ -10630,7 +11005,7 @@
<comment xml:lang="ga">cló LIBGRX</comment>
<comment xml:lang="gl">tipo de fonte en LIBGRX</comment>
<comment xml:lang="he">גופן LIBGRX</comment>
- <comment xml:lang="hr">LIBGRX font</comment>
+ <comment xml:lang="hr">LIBGRX slovo</comment>
<comment xml:lang="hu">LIBGRX-betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras LIBGRX</comment>
<comment xml:lang="id">Fonta LIBGRX</comment>
@@ -10649,7 +11024,7 @@
<comment xml:lang="pt">letra LIBGRX</comment>
<comment xml:lang="pt_BR">Fonte LIBGRX</comment>
<comment xml:lang="ro">Font LIBGRX</comment>
- <comment xml:lang="ru">шрифт LIBGRX</comment>
+ <comment xml:lang="ru">Шрифт LIBGRX</comment>
<comment xml:lang="sk">Písmo LIBGRX</comment>
<comment xml:lang="sl">Datoteka pisave LIBGRX</comment>
<comment xml:lang="sq">Lloj gërme LIBGRX</comment>
@@ -10671,8 +11046,8 @@
<comment xml:lang="az">Linux PSF konsol yazı növü</comment>
<comment xml:lang="be@latin">Kansolny šryft PSF dla Linuksa</comment>
<comment xml:lang="bg">Шрифт — PSF, за конзолата на Линукс</comment>
- <comment xml:lang="ca">tipus de lletra de consola Linux PSF</comment>
- <comment xml:lang="cs">písmo PSF pro konzolu Linuxu</comment>
+ <comment xml:lang="ca">lletra de consola PSF de Linux</comment>
+ <comment xml:lang="cs">font PSF pro konzolu Linuxu</comment>
<comment xml:lang="cy">Ffont Linux PSF</comment>
<comment xml:lang="da">Linux PSF-konsolskrifttype</comment>
<comment xml:lang="de">Linux-PSF-Konsolenschrift</comment>
@@ -10684,10 +11059,10 @@
<comment xml:lang="fi">Linux PSF -konsolifontti</comment>
<comment xml:lang="fo">Linux PSF stýristøðs stavasnið</comment>
<comment xml:lang="fr">police console Linux PSF</comment>
- <comment xml:lang="ga">cló chonsól Linux PSF</comment>
+ <comment xml:lang="ga">cló consóil Linux PSF</comment>
<comment xml:lang="gl">tipo de fonte de consola Linux PSF</comment>
<comment xml:lang="he">גופן לקונסול מסוג Linux PSF</comment>
- <comment xml:lang="hr">Linux PSF konzolni font</comment>
+ <comment xml:lang="hr">Linux PSF konzolno slovo</comment>
<comment xml:lang="hu">Linux PSF konzolos betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras console Linux PSF</comment>
<comment xml:lang="id">Fonta konsol Linux PSF</comment>
@@ -10706,7 +11081,7 @@
<comment xml:lang="pt">letra de consola Linux PSF</comment>
<comment xml:lang="pt_BR">Fonte de console Linux PSF</comment>
<comment xml:lang="ro">Font consolă Linux PSF</comment>
- <comment xml:lang="ru">консольный шрифт Linux PSF</comment>
+ <comment xml:lang="ru">Консольный шрифт Linux PSF</comment>
<comment xml:lang="sk">Písmo PSF pre konzolu Linuxu</comment>
<comment xml:lang="sl">Datoteka pisave konzole Linux PSF</comment>
<comment xml:lang="sq">Lloj gërme për konsolë Linux PSF</comment>
@@ -10728,8 +11103,8 @@
<comment xml:lang="ar">خط كونسول PSF لينكس (مضغوط-gzip)</comment>
<comment xml:lang="be@latin">Kansolny šryft PSF dla Linuksa (gzip-skampresavany)</comment>
<comment xml:lang="bg">Шрифт — Linux PSF, компресиран с gzip</comment>
- <comment xml:lang="ca">tipus de lletra de consola Linux PSF (amb compressió gzip)</comment>
- <comment xml:lang="cs">písmo PSF pro konzolu Linuxu (komprimované pomocí gzip)</comment>
+ <comment xml:lang="ca">lletra de consola PSF de Linux (amb compressió gzip)</comment>
+ <comment xml:lang="cs">font PSF pro konzolu Linuxu (komprimace gzip)</comment>
<comment xml:lang="da">Linux PSF-konsolskrifttype (gzip-komprimeret)</comment>
<comment xml:lang="de">Linux-PSF-Konsolenschrift (gzip-komprimiert)</comment>
<comment xml:lang="el">Γραμματοσειρά κονσόλας PSF Linux (συμπιεσμένη με gzip)</comment>
@@ -10739,10 +11114,10 @@
<comment xml:lang="fi">Linux PSF -konsolifontti (gzip-pakattu)</comment>
<comment xml:lang="fo">Linux PSF stýristøðs stavasnið (gzip-stappað)</comment>
<comment xml:lang="fr">police console Linux PSF (compressée gzip)</comment>
- <comment xml:lang="ga">cló chonsól Linux PSF (comhbhrúite le gzip)</comment>
+ <comment xml:lang="ga">cló consóil Linux PSF (comhbhrúite le gzip)</comment>
<comment xml:lang="gl">tipo de fonte de consola Linux PSF (comprimida con gzip)</comment>
<comment xml:lang="he">גופן למסוף מסוג Linux PSF (מכווץ ע״י gzip)</comment>
- <comment xml:lang="hr">Linux PSF konzolni font (komprimiran gzip-om)</comment>
+ <comment xml:lang="hr">Linux PSF konzolno slovo (gzip sažeto)</comment>
<comment xml:lang="hu">Linux PSF konzolos betűkészlet (gzip-tömörítésű)</comment>
<comment xml:lang="ia">Typo de litteras console Linux PSF (comprimite con gzip)</comment>
<comment xml:lang="id">Fonta konsol Linux PSF (terkompresi gzip)</comment>
@@ -10760,7 +11135,7 @@
<comment xml:lang="pt">letra de consola Linux PSF (compressão gzip)</comment>
<comment xml:lang="pt_BR">Fonte de console Linux PSF (compactada com gzip)</comment>
<comment xml:lang="ro">Font consolă Linux PSF (compresie gzip)</comment>
- <comment xml:lang="ru">консольный шрифт Linux PSF (сжатый gzip)</comment>
+ <comment xml:lang="ru">Консольный шрифт Linux PSF (сжатый gzip)</comment>
<comment xml:lang="sk">Písmo PSF pre konzolu Linuxu (komprimované pomocou gzip)</comment>
<comment xml:lang="sl">Datoteka pisave konzole Linux PSF (skrčena z gzip)</comment>
<comment xml:lang="sq">Lloj gërme për konsolë Linux PSF (komresuar me gzip)</comment>
@@ -10769,7 +11144,7 @@
<comment xml:lang="tr">Linux PSF konsol fontu (gzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">консольний шрифт Linux PSF (стиснений gzip)</comment>
<comment xml:lang="vi">Phông chữ bàn giao tiếp PSF Linux (đã nén gzip)</comment>
- <comment xml:lang="zh_CN">Linux PSF 控制台字体(gzip 压缩)</comment>
+ <comment xml:lang="zh_CN">Linux PSF 控制台字体(gzip 压缩)</comment>
<comment xml:lang="zh_TW">Linux PSF console 字型 (gzip 格式壓縮)</comment>
<sub-class-of type="application/gzip"/>
<generic-icon name="font-x-generic"/>
@@ -10781,8 +11156,8 @@
<comment xml:lang="az">PCF yazı növü</comment>
<comment xml:lang="be@latin">Šryft PCF</comment>
<comment xml:lang="bg">Шрифт — PCF</comment>
- <comment xml:lang="ca">tipus de lletra PCF</comment>
- <comment xml:lang="cs">písmo PCF</comment>
+ <comment xml:lang="ca">lletra PCF</comment>
+ <comment xml:lang="cs">font PCF</comment>
<comment xml:lang="cy">Ffont PCF</comment>
<comment xml:lang="da">PCF-skrifttype</comment>
<comment xml:lang="de">PCF-Schrift</comment>
@@ -10816,7 +11191,7 @@
<comment xml:lang="pt">letra PCF</comment>
<comment xml:lang="pt_BR">Fonte PCF</comment>
<comment xml:lang="ro">Font PCF</comment>
- <comment xml:lang="ru">шрифт PCF</comment>
+ <comment xml:lang="ru">Шрифт PCF</comment>
<comment xml:lang="sk">Písmo PCF</comment>
<comment xml:lang="sl">Datoteka pisave PCF</comment>
<comment xml:lang="sq">Gërma PCF</comment>
@@ -10835,14 +11210,14 @@
<glob pattern="*.pcf.Z"/>
<glob pattern="*.pcf.gz"/>
</mime-type>
- <mime-type type="application/x-font-otf">
+ <mime-type type="font/otf">
<comment>OpenType font</comment>
<comment xml:lang="ar">خط OpenType</comment>
<comment xml:lang="az">OpenType yazı növü</comment>
<comment xml:lang="be@latin">Šryft OpenType</comment>
<comment xml:lang="bg">Шрифт — OpenType</comment>
- <comment xml:lang="ca">tipus de lletra OpenType</comment>
- <comment xml:lang="cs">písmo OpenType</comment>
+ <comment xml:lang="ca">lletra OpenType</comment>
+ <comment xml:lang="cs">font OpenType</comment>
<comment xml:lang="cy">Ffont OpenType</comment>
<comment xml:lang="da">OpenType-skrifttype</comment>
<comment xml:lang="de">OpenType-Schrift</comment>
@@ -10876,7 +11251,7 @@
<comment xml:lang="pt">letra OpenType</comment>
<comment xml:lang="pt_BR">Fonte OpenType</comment>
<comment xml:lang="ro">Font OpenType</comment>
- <comment xml:lang="ru">шрифт OpenType</comment>
+ <comment xml:lang="ru">Шрифт OpenType</comment>
<comment xml:lang="sk">Písmo OpenType</comment>
<comment xml:lang="sl">Datoteka pisave OpenType</comment>
<comment xml:lang="sq">Gërma OpenType</comment>
@@ -10887,12 +11262,13 @@
<comment xml:lang="vi">Phông chữ OpenType</comment>
<comment xml:lang="zh_CN">OpenType 字体</comment>
<comment xml:lang="zh_TW">OpenType 字型</comment>
- <sub-class-of type="application/x-font-ttf"/>
+ <sub-class-of type="font/ttf"/>
<generic-icon name="font-x-generic"/>
<magic priority="50">
<match value="OTTO" type="string" offset="0"/>
</magic>
<glob pattern="*.otf"/>
+ <alias type="application/x-font-otf"/>
</mime-type>
<mime-type type="application/x-font-speedo">
<comment>Speedo font</comment>
@@ -10900,8 +11276,8 @@
<comment xml:lang="az">Speedo yazı növü</comment>
<comment xml:lang="be@latin">Šryft Speedo</comment>
<comment xml:lang="bg">Шрифт — Speedo</comment>
- <comment xml:lang="ca">tipus de lletra Speedo</comment>
- <comment xml:lang="cs">písmo Speedo</comment>
+ <comment xml:lang="ca">lletra Speedo</comment>
+ <comment xml:lang="cs">font Speedo</comment>
<comment xml:lang="cy">Ffont Speedo</comment>
<comment xml:lang="da">Speedoskrifttype</comment>
<comment xml:lang="de">Speedo-Schrift</comment>
@@ -10916,7 +11292,7 @@
<comment xml:lang="ga">cló Speedo</comment>
<comment xml:lang="gl">tipo de letra Speedo</comment>
<comment xml:lang="he">גופן של Speedo</comment>
- <comment xml:lang="hr">Speedo font</comment>
+ <comment xml:lang="hr">Speedo slovo</comment>
<comment xml:lang="hu">Speedo-betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras Speedo</comment>
<comment xml:lang="id">Fonta Speedo</comment>
@@ -10935,7 +11311,7 @@
<comment xml:lang="pt">letra Speedo</comment>
<comment xml:lang="pt_BR">Fonte Speedo</comment>
<comment xml:lang="ro">Font Speedo</comment>
- <comment xml:lang="ru">шрифт Speedo</comment>
+ <comment xml:lang="ru">Шрифт Speedo</comment>
<comment xml:lang="sk">Písmo Speedo</comment>
<comment xml:lang="sl">Datoteka pisave Speedo</comment>
<comment xml:lang="sq">Gërma Speedo</comment>
@@ -10958,8 +11334,8 @@
<comment xml:lang="az">SunOS News yazı növü</comment>
<comment xml:lang="be@latin">Šryft SunOS News</comment>
<comment xml:lang="bg">Шрифт — SunOS News</comment>
- <comment xml:lang="ca">tipus de lletra SunOS News</comment>
- <comment xml:lang="cs">písmo SunOS News</comment>
+ <comment xml:lang="ca">lletra News de SunOS</comment>
+ <comment xml:lang="cs">font SunOS News</comment>
<comment xml:lang="cy">Ffont SunOS News</comment>
<comment xml:lang="da">SunOS News-skrifttype</comment>
<comment xml:lang="de">SunOS-News-Schrift</comment>
@@ -10974,7 +11350,7 @@
<comment xml:lang="ga">cló SunOS News</comment>
<comment xml:lang="gl">tipo de letra SunOS News</comment>
<comment xml:lang="he">גופן של SunOS News</comment>
- <comment xml:lang="hr">SunOS News font</comment>
+ <comment xml:lang="hr">SunOS News slovo</comment>
<comment xml:lang="hu">SunOS News-betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras SunOS News</comment>
<comment xml:lang="id">Fonta SunOS News</comment>
@@ -10993,7 +11369,7 @@
<comment xml:lang="pt">letra SunOS News</comment>
<comment xml:lang="pt_BR">Fonte SunOS News</comment>
<comment xml:lang="ro">Font SunOS News</comment>
- <comment xml:lang="ru">шрифт SunOS News</comment>
+ <comment xml:lang="ru">Шрифт SunOS News</comment>
<comment xml:lang="sk">Písmo SunOS News</comment>
<comment xml:lang="sl">Datoteka pisave SunOS News</comment>
<comment xml:lang="sq">Gërma SunOS News</comment>
@@ -11017,8 +11393,8 @@
<comment xml:lang="az">TeX yazı növü</comment>
<comment xml:lang="be@latin">Šryft TeX</comment>
<comment xml:lang="bg">Шрифт — TeX</comment>
- <comment xml:lang="ca">tipus de lletra TeX</comment>
- <comment xml:lang="cs">písmo TeX</comment>
+ <comment xml:lang="ca">lletra TeX</comment>
+ <comment xml:lang="cs">font TeX</comment>
<comment xml:lang="cy">Ffont TeX</comment>
<comment xml:lang="da">TeX-skrifttype</comment>
<comment xml:lang="de">TeX-Schrift</comment>
@@ -11033,7 +11409,7 @@
<comment xml:lang="ga">cló TeX</comment>
<comment xml:lang="gl">tipo de letra de TeX</comment>
<comment xml:lang="he">גופן TeX</comment>
- <comment xml:lang="hr">TeX font</comment>
+ <comment xml:lang="hr">TeX slovo</comment>
<comment xml:lang="hu">TeX-betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras TeX</comment>
<comment xml:lang="id">Fonta TeX</comment>
@@ -11052,7 +11428,7 @@
<comment xml:lang="pt">letra TeX</comment>
<comment xml:lang="pt_BR">Fonte TeX</comment>
<comment xml:lang="ro">Font TeX</comment>
- <comment xml:lang="ru">шрифт TeX</comment>
+ <comment xml:lang="ru">Шрифт TeX</comment>
<comment xml:lang="sk">Písmo TeX</comment>
<comment xml:lang="sl">Datoteka pisave TeX</comment>
<comment xml:lang="sq">Gërma TeX</comment>
@@ -11076,8 +11452,8 @@
<comment xml:lang="az">TeX yazı növü metrikləri</comment>
<comment xml:lang="be@latin">Metryka šryftu TeX</comment>
<comment xml:lang="bg">Шрифтова метрика — TeX</comment>
- <comment xml:lang="ca">mètrica de tipus de lletra TeX</comment>
- <comment xml:lang="cs">metrika písma TeX</comment>
+ <comment xml:lang="ca">mètrica de lletra de TeX</comment>
+ <comment xml:lang="cs">metrika fontu TeX</comment>
<comment xml:lang="cy">Metrigau Ffont TeX</comment>
<comment xml:lang="da">TeX-skrifttypeinformation</comment>
<comment xml:lang="de">TeX-Schriftmetriken</comment>
@@ -11091,7 +11467,7 @@
<comment xml:lang="ga">meadarachtaí cló TeX</comment>
<comment xml:lang="gl">Métricas de tipo de letra de TeX</comment>
<comment xml:lang="he">ממדי גופן של TeX</comment>
- <comment xml:lang="hr">TeX mjere fonta</comment>
+ <comment xml:lang="hr">TeX mjere slova</comment>
<comment xml:lang="hu">TeX-betűmetrika</comment>
<comment xml:lang="ia">Metricas de typo de litteras TeX</comment>
<comment xml:lang="id">Fonta metrik TeX</comment>
@@ -11110,7 +11486,7 @@
<comment xml:lang="pt">métricas de letra TeX</comment>
<comment xml:lang="pt_BR">Métrica de fonte TeX</comment>
<comment xml:lang="ro">Dimensiuni font TeX</comment>
- <comment xml:lang="ru">метрика шрифта TeX</comment>
+ <comment xml:lang="ru">Метрика шрифта TeX</comment>
<comment xml:lang="sk">Metrika písma TeX</comment>
<comment xml:lang="sl">Matrika pisave Tex</comment>
<comment xml:lang="sq">Gërma TeX metrics</comment>
@@ -11119,7 +11495,7 @@
<comment xml:lang="tr">TeX yazı tipi ölçüleri</comment>
<comment xml:lang="uk">метрики шрифту TeX</comment>
<comment xml:lang="vi">Cách đo phông chữ TeX</comment>
- <comment xml:lang="zh_CN">TeX 字体参数</comment>
+ <comment xml:lang="zh_CN">TeX 字体规格</comment>
<comment xml:lang="zh_TW">TeX 字型描述檔</comment>
<generic-icon name="font-x-generic"/>
<magic priority="50">
@@ -11127,13 +11503,13 @@
<match value="\000\022" type="string" offset="2"/>
</magic>
</mime-type>
- <mime-type type="application/x-font-ttf">
+ <mime-type type="font/ttf">
<comment>TrueType font</comment>
<comment xml:lang="ar">خط TrueType</comment>
<comment xml:lang="be@latin">Šryft TrueType</comment>
<comment xml:lang="bg">Шрифт — TrueType</comment>
- <comment xml:lang="ca">tipus de lletra TrueType</comment>
- <comment xml:lang="cs">písmo TrueType</comment>
+ <comment xml:lang="ca">lletra TrueType</comment>
+ <comment xml:lang="cs">font TrueType</comment>
<comment xml:lang="da">TrueType-skrifttype</comment>
<comment xml:lang="de">TrueType-Schrift</comment>
<comment xml:lang="el">Γραμματοσειρά TrueType</comment>
@@ -11147,7 +11523,7 @@
<comment xml:lang="ga">cló TrueType</comment>
<comment xml:lang="gl">tipo de letra TrueType</comment>
<comment xml:lang="he">גופן מסוג TrueType</comment>
- <comment xml:lang="hr">TrueType font</comment>
+ <comment xml:lang="hr">TrueType slovo</comment>
<comment xml:lang="hu">TrueType-betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras TrueType</comment>
<comment xml:lang="id">Fonta TrueType</comment>
@@ -11166,7 +11542,7 @@
<comment xml:lang="pt">letra TrueType</comment>
<comment xml:lang="pt_BR">Fonte TrueType</comment>
<comment xml:lang="ro">Font TrueType</comment>
- <comment xml:lang="ru">шрифт TrueType</comment>
+ <comment xml:lang="ru">Шрифт TrueType</comment>
<comment xml:lang="sk">Písmo TrueType</comment>
<comment xml:lang="sl">Datoteka pisave TrueType</comment>
<comment xml:lang="sq">Lloj gërme TrueType</comment>
@@ -11184,6 +11560,31 @@
<match value="\000\001\000\000\000" type="string" offset="0"/>
</magic>
<glob pattern="*.ttf"/>
+ <alias type="application/x-font-ttf"/>
+ </mime-type>
+ <mime-type type="font/collection">
+ <comment>Font collection</comment>
+ <comment xml:lang="ca">ccol·lecció de lletres</comment>
+ <comment xml:lang="cs">kolekce fontů</comment>
+ <comment xml:lang="de">Schriftsammlung</comment>
+ <comment xml:lang="en_GB">Font collection</comment>
+ <comment xml:lang="es">colección tipográfica</comment>
+ <comment xml:lang="fi">Fonttikokoelma</comment>
+ <comment xml:lang="hr">Kolekcija slova</comment>
+ <comment xml:lang="hu">Betűkészlet-gyűjtemény</comment>
+ <comment xml:lang="id">Koleksi fonta</comment>
+ <comment xml:lang="it">Raccolta di caratteri</comment>
+ <comment xml:lang="kk">Қаріптер жинағы</comment>
+ <comment xml:lang="ko">글꼴 모음</comment>
+ <comment xml:lang="pl">Kolekcja czcionek</comment>
+ <comment xml:lang="pt_BR">coleção de fontes</comment>
+ <comment xml:lang="ru">Коллекция шрифтов</comment>
+ <comment xml:lang="sk">Zbierka písiem</comment>
+ <comment xml:lang="sv">Typsnittssamling</comment>
+ <comment xml:lang="uk">збірка шрифтів</comment>
+ <comment xml:lang="zh_CN">字体集</comment>
+ <comment xml:lang="zh_TW">字型集</comment>
+ <generic-icon name="font-x-generic"/>
<glob pattern="*.ttc"/>
</mime-type>
<mime-type type="application/x-font-ttx">
@@ -11191,8 +11592,8 @@
<comment xml:lang="ar">خط TrueType XML</comment>
<comment xml:lang="be@latin">Šryft TrueType XML</comment>
<comment xml:lang="bg">Шрифт — TrueType XML</comment>
- <comment xml:lang="ca">tipus de lletra TrueType XML</comment>
- <comment xml:lang="cs">písmo TrueType XML</comment>
+ <comment xml:lang="ca">lletra XML de TrueType</comment>
+ <comment xml:lang="cs">font TrueType XML</comment>
<comment xml:lang="da">TrueType XML-skrifttype</comment>
<comment xml:lang="de">TrueType-XML-Schrift</comment>
<comment xml:lang="el">Γραμματοσειρά XML TrueType</comment>
@@ -11205,7 +11606,7 @@
<comment xml:lang="ga">cló XML TrueType</comment>
<comment xml:lang="gl">tipo de letra TrueType XML</comment>
<comment xml:lang="he">גופן XML מסוג TrueType</comment>
- <comment xml:lang="hr">TrueType XML font</comment>
+ <comment xml:lang="hr">TrueType XML slovo</comment>
<comment xml:lang="hu">TrueType XML betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras TrueType XML</comment>
<comment xml:lang="id">Fonta TrueType XML</comment>
@@ -11223,7 +11624,7 @@
<comment xml:lang="pt">letra TrueType XML</comment>
<comment xml:lang="pt_BR">Fonte TrueType XML</comment>
<comment xml:lang="ro">Font XML TrueType</comment>
- <comment xml:lang="ru">шрифт TrueType XML</comment>
+ <comment xml:lang="ru">Шрифт TrueType XML</comment>
<comment xml:lang="sk">Písmo TrueType XML</comment>
<comment xml:lang="sl">Datoteka pisave TrueType XML</comment>
<comment xml:lang="sq">Lloj gërme TrueType XML</comment>
@@ -11247,8 +11648,8 @@
<comment xml:lang="az">V yazı növü</comment>
<comment xml:lang="be@latin">Šryft V</comment>
<comment xml:lang="bg">Шрифт — V</comment>
- <comment xml:lang="ca">tipus de lletra V</comment>
- <comment xml:lang="cs">písmo V</comment>
+ <comment xml:lang="ca">lletra V</comment>
+ <comment xml:lang="cs">font V</comment>
<comment xml:lang="cy">Ffont V</comment>
<comment xml:lang="da">V-skrifttype</comment>
<comment xml:lang="de">V-Schrift</comment>
@@ -11263,7 +11664,7 @@
<comment xml:lang="ga">cló V</comment>
<comment xml:lang="gl">tipo de letra V</comment>
<comment xml:lang="he">גופן של V</comment>
- <comment xml:lang="hr">V font</comment>
+ <comment xml:lang="hr">V slovo</comment>
<comment xml:lang="hu">V-betűkészlet</comment>
<comment xml:lang="ia">Typo de litteras V</comment>
<comment xml:lang="id">Fonta V</comment>
@@ -11282,7 +11683,7 @@
<comment xml:lang="pt">letra V</comment>
<comment xml:lang="pt_BR">Fonte V</comment>
<comment xml:lang="ro">Font V</comment>
- <comment xml:lang="ru">шрифт V font</comment>
+ <comment xml:lang="ru">Шрифт V font</comment>
<comment xml:lang="sk">Písmo V</comment>
<comment xml:lang="sl">Datoteka pisave V</comment>
<comment xml:lang="sq">Gërmë V</comment>
@@ -11301,6 +11702,7 @@
<mime-type type="application/vnd.framemaker">
<comment>Adobe FrameMaker document</comment>
<comment xml:lang="ar">مستند أدوبي الصانع للإطارات</comment>
+ <comment xml:lang="ast">Documentu d'Adobe FrameMaker</comment>
<comment xml:lang="be@latin">Dakument Adobe FrameMaker</comment>
<comment xml:lang="bg">Документ — Adobe FrameMaker</comment>
<comment xml:lang="ca">document d'Adobe FrameMaker</comment>
@@ -11337,7 +11739,7 @@
<comment xml:lang="pt">documento Adobe FrameMaker</comment>
<comment xml:lang="pt_BR">Documento do Adobe FrameMaker</comment>
<comment xml:lang="ro">Document Adobe FrameMaker</comment>
- <comment xml:lang="ru">документ Adobe FrameMaker</comment>
+ <comment xml:lang="ru">Документ Adobe FrameMaker</comment>
<comment xml:lang="sk">Dokument Adobe FrameMaker</comment>
<comment xml:lang="sl">Dokument Adobe FrameMaker</comment>
<comment xml:lang="sq">Dokument Adobe FrameMaker</comment>
@@ -11399,7 +11801,7 @@
<comment xml:lang="oc">ROM Game Boy</comment>
<comment xml:lang="pl">Plik ROM konsoli Game Boy</comment>
<comment xml:lang="pt">ROM Game Boy</comment>
- <comment xml:lang="pt_BR">ROM do Game Boy</comment>
+ <comment xml:lang="pt_BR">ROM de Game Boy</comment>
<comment xml:lang="ro">ROM Game Boy</comment>
<comment xml:lang="ru">Game Boy ROM</comment>
<comment xml:lang="sk">ROM pre Game Boy</comment>
@@ -11424,18 +11826,29 @@
<mime-type type="application/x-gameboy-color-rom">
<comment>Game Boy Color ROM</comment>
<comment xml:lang="ca">ROM de Game Boy Color</comment>
+ <comment xml:lang="cs">ROM pro Game Boy Color</comment>
<comment xml:lang="da">Game Boy Color ROM</comment>
<comment xml:lang="de">Game Boy Color ROM</comment>
+ <comment xml:lang="en_GB">Game Boy Colour ROM</comment>
<comment xml:lang="es">ROM de Game Boy Color</comment>
+ <comment xml:lang="eu">Game Boy Color ROM</comment>
<comment xml:lang="fi">Game Boy Color -ROM</comment>
<comment xml:lang="fr">ROM Game Boy Color</comment>
+ <comment xml:lang="ga">ROM Game Boy Color</comment>
+ <comment xml:lang="he">ROM של Game Boy Color</comment>
+ <comment xml:lang="hr">Game Boy Color ROM</comment>
<comment xml:lang="hu">Game Boy Color ROM</comment>
+ <comment xml:lang="id">ROM Game Boy Color</comment>
+ <comment xml:lang="it">ROM Game Boy Color</comment>
<comment xml:lang="kk">Game Boy Color ROM</comment>
<comment xml:lang="ko">게임보이 컬러 롬</comment>
<comment xml:lang="pl">Plik ROM konsoli Game Boy Color</comment>
<comment xml:lang="pt_BR">ROM de Game Boy Color</comment>
<comment xml:lang="ru">Game Boy Color ROM</comment>
<comment xml:lang="sk">ROM pre Game Boy Color</comment>
+ <comment xml:lang="sr">Гејм Бој РОМ боје</comment>
+ <comment xml:lang="sv">Game Boy Color-rom</comment>
+ <comment xml:lang="tr">Game Boy Color ROM</comment>
<comment xml:lang="uk">ППП Game Boy Color</comment>
<comment xml:lang="zh_CN">Game Boy Color ROM</comment>
<comment xml:lang="zh_TW">Game Boy Color ROM</comment>
@@ -11484,7 +11897,7 @@
<comment xml:lang="oc">ROM Game Boy Advance</comment>
<comment xml:lang="pl">Plik ROM konsoli Game Boy Advance</comment>
<comment xml:lang="pt">ROM Game Boy Advance</comment>
- <comment xml:lang="pt_BR">ROM do Game Boy Advance</comment>
+ <comment xml:lang="pt_BR">ROM de Game Boy Advance</comment>
<comment xml:lang="ro">ROM Game Boy Advance</comment>
<comment xml:lang="ru">Game Boy Advance ROM</comment>
<comment xml:lang="sk">ROM pre Game Boy Advance</comment>
@@ -11501,6 +11914,30 @@
<glob pattern="*.gba"/>
<glob pattern="*.agb"/>
</mime-type>
+ <mime-type type="application/x-virtual-boy-rom">
+ <comment>Virtual Boy ROM</comment>
+ <comment xml:lang="ca">ROM de Virtual Boy</comment>
+ <comment xml:lang="cs">ROM pro Virtual Boy</comment>
+ <comment xml:lang="de">Virtual Boy ROM</comment>
+ <comment xml:lang="en_GB">Virtual Boy ROM</comment>
+ <comment xml:lang="es">ROM de Virtual Boy</comment>
+ <comment xml:lang="hr">Virtual Boy ROM</comment>
+ <comment xml:lang="hu">Virtual Boy ROM</comment>
+ <comment xml:lang="id">ROM Virtual Boy</comment>
+ <comment xml:lang="it">ROM Virtual Boy</comment>
+ <comment xml:lang="kk">Virtual Boy ROM</comment>
+ <comment xml:lang="ko">버추얼보이 롬</comment>
+ <comment xml:lang="pl">Plik ROM konsoli Virtual Boy</comment>
+ <comment xml:lang="pt_BR">ROM de Virtual Boy</comment>
+ <comment xml:lang="ru">Virtual Boy ROM</comment>
+ <comment xml:lang="sk">ROM pre Virtual Boy</comment>
+ <comment xml:lang="sv">Virtual Boy-rom</comment>
+ <comment xml:lang="uk">ROM Virtual Boy</comment>
+ <comment xml:lang="zh_CN">Virtual Boy ROM</comment>
+ <comment xml:lang="zh_TW">Virtual Boy ROM</comment>
+ <generic-icon name="application-x-executable"/>
+ <glob pattern="*.vb"/>
+ </mime-type>
<mime-type type="application/x-gdbm">
<comment>GDBM database</comment>
<comment xml:lang="ar">قاعدة بيانات GDBM</comment>
@@ -11540,7 +11977,7 @@
<comment xml:lang="pt">base de dados GDMB</comment>
<comment xml:lang="pt_BR">Banco de dados GDBM</comment>
<comment xml:lang="ro">Bază de date GDBM</comment>
- <comment xml:lang="ru">база данных GDBM</comment>
+ <comment xml:lang="ru">База данных GDBM</comment>
<comment xml:lang="sk">Databáza GDBM</comment>
<comment xml:lang="sl">Podatkovna zbirka GDBM</comment>
<comment xml:lang="sq">Bazë me të dhëna GDBM</comment>
@@ -11597,7 +12034,7 @@
<comment xml:lang="oc">ROM Mega Drive/Genesis</comment>
<comment xml:lang="pl">Plik ROM konsoli Mega Drive</comment>
<comment xml:lang="pt">ROM Mega Drive</comment>
- <comment xml:lang="pt_BR">ROM do Gênesis (Mega Drive)</comment>
+ <comment xml:lang="pt_BR">ROM de Genesis (Mega Drive)</comment>
<comment xml:lang="ro">ROM Genesis</comment>
<comment xml:lang="ru">Genesis ROM</comment>
<comment xml:lang="sk">ROM pre Megadrive</comment>
@@ -11624,19 +12061,29 @@
<comment>Genesis 32X ROM</comment>
<comment xml:lang="ca">ROM de Genesis 32X</comment>
+ <comment xml:lang="cs">ROM pro Genesis 32X</comment>
<comment xml:lang="da">Genesis 32X ROM</comment>
<comment xml:lang="de">Genesis 32X ROM</comment>
+ <comment xml:lang="en_GB">Genesis 32X ROM</comment>
<comment xml:lang="es">ROM de Genesis 32X</comment>
+ <comment xml:lang="eu">Genesis 32X ROM</comment>
<comment xml:lang="fi">Genesis 32X -ROM</comment>
<comment xml:lang="fr">ROM Genesis 32X</comment>
+ <comment xml:lang="ga">ROM Genesis 32X</comment>
<comment xml:lang="he">ROM מסוג Genesis 32X</comment>
+ <comment xml:lang="hr">Genesis 32X ROM</comment>
<comment xml:lang="hu">Genesis 32X ROM</comment>
+ <comment xml:lang="id">ROM Genesis 32X</comment>
+ <comment xml:lang="it">ROM Sega Mega Drive 32X</comment>
<comment xml:lang="kk">Genesis 32X ROM</comment>
<comment xml:lang="ko">제네시스 32X 롬</comment>
<comment xml:lang="pl">Plik ROM konsoli Mega Drive 32X</comment>
<comment xml:lang="pt_BR">ROM de Genesis 32X</comment>
<comment xml:lang="ru">Genesis 32X ROM</comment>
<comment xml:lang="sk">ROM pre Genesis 32X</comment>
+ <comment xml:lang="sr">Џенезис 32X РОМ</comment>
+ <comment xml:lang="sv">Mega Drive 32X-rom</comment>
+ <comment xml:lang="tr">Genesis 32X ROM</comment>
<comment xml:lang="uk">ППП Genesis 32X</comment>
<comment xml:lang="zh_CN">Genesis 32X ROM</comment>
<comment xml:lang="zh_TW">Genesis 32X ROM</comment>
@@ -11667,7 +12114,7 @@
<comment xml:lang="ga">teachtaireachtaí aistrithe (inléite ag meaisín)</comment>
<comment xml:lang="gl">mensaxes traducidos (lexíbeis por máquinas)</comment>
<comment xml:lang="he">הודעות מתורגמות (מובן ע״י מכונה)</comment>
- <comment xml:lang="hr">prevedene poruke (strojno čitljive)</comment>
+ <comment xml:lang="hr">Prevedene poruke (strojno čitljive)</comment>
<comment xml:lang="hu">lefordított üzenetek (gépi kód)</comment>
<comment xml:lang="ia">messages traducite (legibile pro machinas)</comment>
<comment xml:lang="id">pesan diterjemahkan (dapat dibaca mesin)</comment>
@@ -11687,7 +12134,7 @@
<comment xml:lang="pt">mensagens traduzidas (leitura pelo computador)</comment>
<comment xml:lang="pt_BR">Mensagens traduzidas (legível pelo computador)</comment>
<comment xml:lang="ro">mesaje traduse (citite de calculator)</comment>
- <comment xml:lang="ru">переводы сообщений (откомпилированые)</comment>
+ <comment xml:lang="ru">Переводы сообщений (откомпилированые)</comment>
<comment xml:lang="sk">Preložené správy (strojovo čitateľné)</comment>
<comment xml:lang="sl">prevedena sporočila (strojni zapis)</comment>
<comment xml:lang="sq">Mesazhe të përkthyer (të lexueshëm nga makina)</comment>
@@ -11696,7 +12143,7 @@
<comment xml:lang="tr">çevrilmiş iletiler (makine tarafından okunabilir)</comment>
<comment xml:lang="uk">перекладені повідомлення (у машинній формі)</comment>
<comment xml:lang="vi">thông điệp đã dịch (máy đọc được)</comment>
- <comment xml:lang="zh_CN">消息翻译(机读)</comment>
+ <comment xml:lang="zh_CN">已翻译消息(机读)</comment>
<comment xml:lang="zh_TW">翻譯訊息 (程式讀取格式)</comment>
<magic priority="50">
<match value="\336\22\4\225" type="string" offset="0"/>
@@ -11717,6 +12164,7 @@
<comment xml:lang="eu">GTK+ Builder</comment>
<comment xml:lang="fi">GTK+ Builder</comment>
<comment xml:lang="fr">GTK+ Builder</comment>
+ <comment xml:lang="ga">Tógálaí GTK+</comment>
<comment xml:lang="gl">Construtor de GTK+</comment>
<comment xml:lang="he">בנייה של GTK+‎</comment>
<comment xml:lang="hr">GTK+ Builder</comment>
@@ -11739,7 +12187,7 @@
<comment xml:lang="sv">GTK+ Builder</comment>
<comment xml:lang="tr">GTK+ İnşa Edici</comment>
<comment xml:lang="uk">GTK+ Builder</comment>
- <comment xml:lang="zh_CN">GTK+ 构建程序</comment>
+ <comment xml:lang="zh_CN">GTK+ Builder</comment>
<comment xml:lang="zh_TW">GTK+ Builder</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="x-office-document"/>
@@ -11789,7 +12237,7 @@
<comment xml:lang="pt">projecto Glade</comment>
<comment xml:lang="pt_BR">Projeto do Glade</comment>
<comment xml:lang="ro">Proiect Glade</comment>
- <comment xml:lang="ru">проект Glade</comment>
+ <comment xml:lang="ru">Проект Glade</comment>
<comment xml:lang="sk">Projekt Glade</comment>
<comment xml:lang="sl">Datoteka projekta Glade</comment>
<comment xml:lang="sq">Projekt Glade</comment>
@@ -11841,7 +12289,7 @@
<comment xml:lang="pt">dados financeiros GnuCash</comment>
<comment xml:lang="pt_BR">Dados financeiros do GnuCash</comment>
<comment xml:lang="ro">Date financiare GnuCash</comment>
- <comment xml:lang="ru">финансовые данные GnuCash</comment>
+ <comment xml:lang="ru">Финансовые данные GnuCash</comment>
<comment xml:lang="sk">Finančné údaje GnuCash</comment>
<comment xml:lang="sl">Datoteka finančnih podatkov GnuCash</comment>
<comment xml:lang="sr">финансијски подаци Гнуовог новца</comment>
@@ -11895,7 +12343,7 @@
<comment xml:lang="pt">folha de cálculo Gnumeric</comment>
<comment xml:lang="pt_BR">Planilha do Gnumeric</comment>
<comment xml:lang="ro">Foaie de calcul Gnumeric</comment>
- <comment xml:lang="ru">электронная таблица Gnumeric</comment>
+ <comment xml:lang="ru">Электронная таблица Gnumeric</comment>
<comment xml:lang="sk">Zošit Gnumeric</comment>
<comment xml:lang="sl">Razpredelnica Gnumeric</comment>
<comment xml:lang="sq">Fletë llogaritjesh Gnumeric</comment>
@@ -11904,7 +12352,7 @@
<comment xml:lang="tr">Gnumeric çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця Gnumeric</comment>
<comment xml:lang="vi">Bảng tính Gnumeric.</comment>
- <comment xml:lang="zh_CN">Gnumeric 工作簿</comment>
+ <comment xml:lang="zh_CN">Gnumeric 电子表格</comment>
<comment xml:lang="zh_TW">Gnumeric 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<magic priority="50">
@@ -11916,6 +12364,7 @@
<mime-type type="application/x-gnuplot">
<comment>Gnuplot document</comment>
<comment xml:lang="ar">مستند Gnuplot</comment>
+ <comment xml:lang="ast">Documentu de Gnuplot</comment>
<comment xml:lang="be@latin">Dakument Gnuplot</comment>
<comment xml:lang="bg">Документ — Gnuplot</comment>
<comment xml:lang="ca">document gnuplot</comment>
@@ -11951,7 +12400,7 @@
<comment xml:lang="pt">documento Gnuplot</comment>
<comment xml:lang="pt_BR">Documento do Gnuplot</comment>
<comment xml:lang="ro">Document Gnuplot</comment>
- <comment xml:lang="ru">документ Gnuplot</comment>
+ <comment xml:lang="ru">Документ Gnuplot</comment>
<comment xml:lang="sk">Dokument Gnuplot</comment>
<comment xml:lang="sl">Dokument Gnuplot</comment>
<comment xml:lang="sq">Dokument Gnuplot</comment>
@@ -11985,7 +12434,7 @@
<comment xml:lang="fi">Graphite- tieteellinen graafi</comment>
<comment xml:lang="fo">Grapite vísindarlig ritmynd</comment>
<comment xml:lang="fr">graphe Graphite scientific</comment>
- <comment xml:lang="ga">graf eolaíoch Graphite</comment>
+ <comment xml:lang="ga">graf eolaíochta Graphite</comment>
<comment xml:lang="gl">gráfica científica de Graphite</comment>
<comment xml:lang="he">תרשים מדעי של Graphite</comment>
<comment xml:lang="hr">Graphite znanstveni grafikon</comment>
@@ -12007,7 +12456,7 @@
<comment xml:lang="pt">gráfico científico Graphite</comment>
<comment xml:lang="pt_BR">Gráfico científico do Graphite</comment>
<comment xml:lang="ro">Grafic științific Graphite</comment>
- <comment xml:lang="ru">научная диаграмма Graphite</comment>
+ <comment xml:lang="ru">Научная диаграмма Graphite</comment>
<comment xml:lang="sk">Vedecký graf Graphite</comment>
<comment xml:lang="sl">Datoteka znanstvenega grafa Graphite</comment>
<comment xml:lang="sq">Grafik shkencor Graphite </comment>
@@ -12061,7 +12510,7 @@
<comment xml:lang="pt">catálogo GTKtalog</comment>
<comment xml:lang="pt_BR">Catálogo GTKtalog</comment>
<comment xml:lang="ro">Catalog GTKalog</comment>
- <comment xml:lang="ru">каталог GTKtalog</comment>
+ <comment xml:lang="ru">Каталог GTKtalog</comment>
<comment xml:lang="sk">Katalóg GTKtalog</comment>
<comment xml:lang="sl">Datoteka kataloga GTKtalog</comment>
<comment xml:lang="sq">Katallog GTKtalog</comment>
@@ -12080,6 +12529,7 @@
<mime-type type="application/x-gzdvi">
<comment>TeX DVI document (gzip-compressed)</comment>
<comment xml:lang="ar">مستند TeX DVI (مضغوط-gzip)</comment>
+ <comment xml:lang="ast">Documentu Tex DVI (comprimíu en gzip)</comment>
<comment xml:lang="be@latin">Dakument TeX DVI (gzip-skampresavany)</comment>
<comment xml:lang="bg">Документ — TeX DVI, компресиран с gzip</comment>
<comment xml:lang="ca">document DVI de TeX (amb compressió gzip)</comment>
@@ -12096,7 +12546,7 @@
<comment xml:lang="ga">cáipéis DVI TeX (comhbhrúite le gzip)</comment>
<comment xml:lang="gl">documento DVI de TeX (comprimido con gzip)</comment>
<comment xml:lang="he">מסמך מסוג TeX DVI (מכווץ ע״י gzip)</comment>
- <comment xml:lang="hr">TeX DVI dokument (komprimiran gzip-om)</comment>
+ <comment xml:lang="hr">TeX DVI dokument (gzip sažet)</comment>
<comment xml:lang="hu">TeX DVI dokumentum (gzip-pel tömörítve)</comment>
<comment xml:lang="ia">Documento TeX DVI (comprimite con gzip)</comment>
<comment xml:lang="id">Dokumen TeX DVI (terkompresi gzip)</comment>
@@ -12114,7 +12564,7 @@
<comment xml:lang="pt">documento TeX DVI (compressão gzip)</comment>
<comment xml:lang="pt_BR">Documento DVI TeX (compactado com gzip)</comment>
<comment xml:lang="ro">Document TeX DVI (comprimat gzip)</comment>
- <comment xml:lang="ru">документ TeX DVI (сжатый gzip)</comment>
+ <comment xml:lang="ru">Документ TeX DVI (сжатый gzip)</comment>
<comment xml:lang="sk">Dokument TeX DVI (komprimovaný pomocou gzip)</comment>
<comment xml:lang="sl">Dokument TeX DVI (stisnjen z gzip)</comment>
<comment xml:lang="sq">Dokument TeX DVI (i kompresuar me gzip)</comment>
@@ -12123,7 +12573,7 @@
<comment xml:lang="tr">TeX DVI belgesi (gzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">документ TeX DVI (стиснений gzip)</comment>
<comment xml:lang="vi">Tài liệu DVI TeX (đã nén gzip)</comment>
- <comment xml:lang="zh_CN">TeX DVI 文档(gzip 压缩)</comment>
+ <comment xml:lang="zh_CN">TeX DVI 文档(gzip 压缩)</comment>
<comment xml:lang="zh_TW">TeX DVI 文件 (gzip 格式壓縮)</comment>
<sub-class-of type="application/gzip"/>
<generic-icon name="x-office-document"/>
@@ -12167,7 +12617,7 @@
<comment xml:lang="pt">arquivo Gzip</comment>
<comment xml:lang="pt_BR">Pacote Gzip</comment>
<comment xml:lang="ro">Arhivă Gzip</comment>
- <comment xml:lang="ru">архив GZIP</comment>
+ <comment xml:lang="ru">Архив GZIP</comment>
<comment xml:lang="sk">Archív gzip</comment>
<comment xml:lang="sl">Datoteka arhiva Gzip</comment>
<comment xml:lang="sq">Arkiv gzip</comment>
@@ -12188,6 +12638,7 @@
<mime-type type="application/x-gzpdf">
<comment>PDF document (gzip-compressed)</comment>
<comment xml:lang="ar">مستند PDF (مضغوط-gzip)</comment>
+ <comment xml:lang="ast">Documentu PDF (comprimíu en gzip)</comment>
<comment xml:lang="be@latin">Dakument PDF (gzip-skampresavany)</comment>
<comment xml:lang="bg">Документ — PDF, компресиран с gzip</comment>
<comment xml:lang="ca">document PDF (amb compressió gzip)</comment>
@@ -12222,7 +12673,7 @@
<comment xml:lang="pt">documento PDF (compressão gzip)</comment>
<comment xml:lang="pt_BR">Documento PDF (compactado com gzip)</comment>
<comment xml:lang="ro">Document PDF (comprimat gzip)</comment>
- <comment xml:lang="ru">документ PDF (сжатый gzip)</comment>
+ <comment xml:lang="ru">Документ PDF (сжатый gzip)</comment>
<comment xml:lang="sk">Dokument PDF (komprimovaný pomocou gzip)</comment>
<comment xml:lang="sl">Dokument PDF (stisnjen z gzip)</comment>
<comment xml:lang="sq">Dokument PDF (i kompresuar me gzip)</comment>
@@ -12231,7 +12682,7 @@
<comment xml:lang="tr">PDF belgesi (gzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">документ PDF (стиснений gzip)</comment>
<comment xml:lang="vi">Tài liệu PDF (đã nén gzip)</comment>
- <comment xml:lang="zh_CN">PDF 文档(gzip 压缩)</comment>
+ <comment xml:lang="zh_CN">PDF 文档(gzip 压缩)</comment>
<comment xml:lang="zh_TW">PDF 文件 (gzip 格式壓縮)</comment>
<sub-class-of type="application/gzip"/>
<generic-icon name="x-office-document"/>
@@ -12240,6 +12691,7 @@
<mime-type type="application/x-gzpostscript">
<comment>PostScript document (gzip-compressed)</comment>
<comment xml:lang="ar">مستند PostScript (مضغوط-gzip)</comment>
+ <comment xml:lang="ast">Documentu PostScript (comprimíu en gzip)</comment>
<comment xml:lang="be@latin">Dakument PostScript (gzip-skampresavany)</comment>
<comment xml:lang="bg">Документ — PostScript, компресиран с gzip</comment>
<comment xml:lang="ca">document PostScript (amb compressió gzip)</comment>
@@ -12276,7 +12728,7 @@
<comment xml:lang="pt">documento PostScript (compressão gzip)</comment>
<comment xml:lang="pt_BR">Documento PostScript (compactado com gzip)</comment>
<comment xml:lang="ro">Document PostScript (comprimat gzip)</comment>
- <comment xml:lang="ru">документ PostScript (сжатый gzip)</comment>
+ <comment xml:lang="ru">Документ PostScript (сжатый gzip)</comment>
<comment xml:lang="sk">Dokument PostScript (komprimovaný pomocou gzip)</comment>
<comment xml:lang="sl">Dokument PostScript (stisnjen z gzip)</comment>
<comment xml:lang="sq">Dokument PostScript (i kompresuar me gzip)</comment>
@@ -12285,7 +12737,7 @@
<comment xml:lang="tr">PostScript belgesi (gzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">документ PostScript (стиснене gzip)</comment>
<comment xml:lang="vi">Tài liệu PostScript (đã nén gzip)</comment>
- <comment xml:lang="zh_CN">PostScript 文档(gzip 压缩)</comment>
+ <comment xml:lang="zh_CN">PostScript 文档(gzip 压缩)</comment>
<comment xml:lang="zh_TW">PostScript 文件 (gzip 格式壓縮)</comment>
<sub-class-of type="application/gzip"/>
<generic-icon name="x-office-document"/>
@@ -12294,6 +12746,7 @@
<mime-type type="application/x-hdf">
<comment>HDF document</comment>
<comment xml:lang="ar">مستند HDF</comment>
+ <comment xml:lang="ast">Documentu HDF</comment>
<comment xml:lang="az">HDF sənədi</comment>
<comment xml:lang="be@latin">Dakument HDF</comment>
<comment xml:lang="bg">Документ — HDF</comment>
@@ -12332,7 +12785,7 @@
<comment xml:lang="pt">documento HDF</comment>
<comment xml:lang="pt_BR">Documento HDF</comment>
<comment xml:lang="ro">Document HDF</comment>
- <comment xml:lang="ru">документ HDF</comment>
+ <comment xml:lang="ru">Документ HDF</comment>
<comment xml:lang="sk">Dokument HDF</comment>
<comment xml:lang="sl">Dokument HDF</comment>
<comment xml:lang="sq">Dokument HDF</comment>
@@ -12368,6 +12821,7 @@
<comment xml:lang="eu">IFF fitxtegia</comment>
<comment xml:lang="fi">IFF-tiedosto</comment>
<comment xml:lang="fr">fichier IFF</comment>
+ <comment xml:lang="ga">comhad IFF</comment>
<comment xml:lang="gl">Ficheiro IFF</comment>
<comment xml:lang="he">קובץ IFF</comment>
<comment xml:lang="hr">IFF datoteka</comment>
@@ -12383,7 +12837,7 @@
<comment xml:lang="pl">Plik IFF</comment>
<comment xml:lang="pt">ficheiro IFF</comment>
<comment xml:lang="pt_BR">Arquivo IFF</comment>
- <comment xml:lang="ru">файл IFF</comment>
+ <comment xml:lang="ru">Файл IFF</comment>
<comment xml:lang="sk">Súbor IFF</comment>
<comment xml:lang="sl">Datoteka IFF</comment>
<comment xml:lang="sr">ИФФ датотека</comment>
@@ -12437,7 +12891,7 @@
<comment xml:lang="pt">firmware iPod</comment>
<comment xml:lang="pt_BR">Firmware do iPod</comment>
<comment xml:lang="ro">Firmware iPod</comment>
- <comment xml:lang="ru">микропрограмма iPod</comment>
+ <comment xml:lang="ru">Микропрограмма iPod</comment>
<comment xml:lang="sk">Firmware iPod</comment>
<comment xml:lang="sl">Programska strojna oprema iPod</comment>
<comment xml:lang="sq">Firmware iPod</comment>
@@ -12491,7 +12945,7 @@
<comment xml:lang="pt">arquivo Java</comment>
<comment xml:lang="pt_BR">Pacote Java</comment>
<comment xml:lang="ro">Arhivă Java</comment>
- <comment xml:lang="ru">архив Java</comment>
+ <comment xml:lang="ru">Архив Java</comment>
<comment xml:lang="sk">Archív Java</comment>
<comment xml:lang="sl">Datoteka arhiva Java</comment>
<comment xml:lang="sq">Arkiv Java</comment>
@@ -12547,7 +13001,7 @@
<comment xml:lang="pt">classe Java</comment>
<comment xml:lang="pt_BR">Classe Java</comment>
<comment xml:lang="ro">Clasă Java</comment>
- <comment xml:lang="ru">класс Java</comment>
+ <comment xml:lang="ru">Класс Java</comment>
<comment xml:lang="sk">Trieda Java</comment>
<comment xml:lang="sl">Datoteka razreda Java</comment>
<comment xml:lang="sq">Klasë Java</comment>
@@ -12606,7 +13060,7 @@
<comment xml:lang="pt">ficheiro JNLP</comment>
<comment xml:lang="pt_BR">Arquivo JNLP</comment>
<comment xml:lang="ro">Fișier JNLP</comment>
- <comment xml:lang="ru">файл JNLP</comment>
+ <comment xml:lang="ru">Файл JNLP</comment>
<comment xml:lang="sk">Súbor JNLP</comment>
<comment xml:lang="sl">Datoteka JNLP</comment>
<comment xml:lang="sq">File JNLP</comment>
@@ -12660,7 +13114,7 @@
<comment xml:lang="pt">armazém de chaves Java</comment>
<comment xml:lang="pt_BR">Keystore de Java</comment>
<comment xml:lang="ro">Stocare chei Java</comment>
- <comment xml:lang="ru">хранилище ключей Java</comment>
+ <comment xml:lang="ru">Хранилище ключей Java</comment>
<comment xml:lang="sk">Úložisko kľúčov Java</comment>
<comment xml:lang="sl">Datoteka tipkovne razporeditve Java</comment>
<comment xml:lang="sr">смештај кључа Јаве</comment>
@@ -12710,7 +13164,7 @@
<comment xml:lang="pt">armazém de chaves JavaJCE</comment>
<comment xml:lang="pt_BR">Keystore JCE do Java</comment>
<comment xml:lang="ro">Stocare chei Java JCE</comment>
- <comment xml:lang="ru">хранилище ключей Java JCE</comment>
+ <comment xml:lang="ru">Хранилище ключей Java JCE</comment>
<comment xml:lang="sk">Úložisko kľúčov Java JCE</comment>
<comment xml:lang="sl">Datoteka tipkovne razporeditve Java JCE</comment>
<comment xml:lang="sr">смештај ЈЦЕ кључа Јаве</comment>
@@ -12763,7 +13217,7 @@
<comment xml:lang="pt">arquivo Java Pack200</comment>
<comment xml:lang="pt_BR">Pacote Java Pack200</comment>
<comment xml:lang="ro">Arhivă Java Pack2000</comment>
- <comment xml:lang="ru">архив Java Pack200</comment>
+ <comment xml:lang="ru">Архив Java Pack200</comment>
<comment xml:lang="sk">Archív Java Pack200</comment>
<comment xml:lang="sl">Datoteka arhiva Pack200 Java</comment>
<comment xml:lang="sq">Arkiv Java Pack200</comment>
@@ -12819,7 +13273,7 @@
<comment xml:lang="pt">programa JavaScript</comment>
<comment xml:lang="pt_BR">Programa JavaScript</comment>
<comment xml:lang="ro">Program JavaScript</comment>
- <comment xml:lang="ru">сценарий JavaScript</comment>
+ <comment xml:lang="ru">Программа JavaScript</comment>
<comment xml:lang="sk">Program jazyka JavaScript</comment>
<comment xml:lang="sl">Programska datoteka JavaScript</comment>
<comment xml:lang="sq">Program JavaScript</comment>
@@ -12828,17 +13282,31 @@
<comment xml:lang="tr">JavaScript programı</comment>
<comment xml:lang="uk">програма мовою JavaScript</comment>
<comment xml:lang="vi">Chương trình JavaScript</comment>
- <comment xml:lang="zh_CN">Javascript 程序</comment>
+ <comment xml:lang="zh_CN">JavaScript 程序</comment>
<comment xml:lang="zh_TW">JavaScript 程式</comment>
<alias type="application/x-javascript"/>
<alias type="text/javascript"/>
<sub-class-of type="application/ecmascript"/>
<generic-icon name="text-x-script"/>
+ <magic priority="50">
+ <match value="#!/bin/gjs" type="string" offset="0"/>
+ <match value="#! /bin/gjs" type="string" offset="0"/>
+ <match value='eval \"exec /bin/gjs' type="string" offset="0"/>
+ <match value="#!/usr/bin/gjs" type="string" offset="0"/>
+ <match value="#! /usr/bin/gjs" type="string" offset="0"/>
+ <match value='eval \"exec /usr/bin/gjs' type="string" offset="0"/>
+ <match value="#!/usr/local/bin/gjs" type="string" offset="0"/>
+ <match value="#! /usr/local/bin/gjs" type="string" offset="0"/>
+ <match value='eval \"exec /usr/local/bin/gjs' type="string" offset="0"/>
+ <match value='/bin/env gjs' type="string" offset="2:16"/>
+ </magic>
<glob pattern="*.js"/>
<glob pattern="*.jsm"/>
+ <glob pattern="*.mjs"/>
</mime-type>
<mime-type type="application/json">
<comment>JSON document</comment>
+ <comment xml:lang="ast">Documentu JSON</comment>
<comment xml:lang="ca">document JSON</comment>
<comment xml:lang="cs">dokument JSON</comment>
<comment xml:lang="da">JSON-dokument</comment>
@@ -12849,6 +13317,7 @@
<comment xml:lang="eu">JSON dokumentua</comment>
<comment xml:lang="fi">JSON-asiakirja</comment>
<comment xml:lang="fr">document JSON</comment>
+ <comment xml:lang="ga">cáipéis JSON</comment>
<comment xml:lang="gl">Documento JSON</comment>
<comment xml:lang="he">מסמך JSON</comment>
<comment xml:lang="hr">JSON dokument</comment>
@@ -12879,6 +13348,7 @@
</mime-type>
<mime-type type="application/jrd+json">
<comment>JRD document</comment>
+ <comment xml:lang="ast">Documentu JRD</comment>
<comment xml:lang="ca">document JRD</comment>
<comment xml:lang="cs">dokument JRD</comment>
<comment xml:lang="da">JRD-dokument</comment>
@@ -12889,6 +13359,7 @@
<comment xml:lang="eu">JRD dokumentua</comment>
<comment xml:lang="fi">JRD-asiakirja</comment>
<comment xml:lang="fr">document JRD</comment>
+ <comment xml:lang="ga">cáipéis JRD</comment>
<comment xml:lang="he">מסמך JRD</comment>
<comment xml:lang="hr">JRD dokument</comment>
<comment xml:lang="hu">JRD dokumentum</comment>
@@ -12901,7 +13372,7 @@
<comment xml:lang="pl">Dokument JRD</comment>
<comment xml:lang="pt">doxumento JRD</comment>
<comment xml:lang="pt_BR">Documento JRD</comment>
- <comment xml:lang="ru">документ JRD</comment>
+ <comment xml:lang="ru">Документ JRD</comment>
<comment xml:lang="sk">Dokument JRD</comment>
<comment xml:lang="sr">ЈРД документ</comment>
<comment xml:lang="sv">JRD-dokument</comment>
@@ -12923,7 +13394,9 @@
<comment xml:lang="de">JSON-Patch</comment>
<comment xml:lang="en_GB">JSON patch</comment>
<comment xml:lang="es">parche en JSON</comment>
+ <comment xml:lang="eu">JSON adabakia</comment>
<comment xml:lang="fr">correctif JSON</comment>
+ <comment xml:lang="ga">paiste JSON</comment>
<comment xml:lang="he">טלאי JSON</comment>
<comment xml:lang="hr">JSON zakrpa</comment>
<comment xml:lang="hu">JSON javítócsomag</comment>
@@ -12936,13 +13409,13 @@
<comment xml:lang="pl">Łata JSON</comment>
<comment xml:lang="pt">patch JSON</comment>
<comment xml:lang="pt_BR">Patch JSON</comment>
- <comment xml:lang="ru">изменение JSON</comment>
+ <comment xml:lang="ru">Патч JSON</comment>
<comment xml:lang="sk">Záplata JSON</comment>
<comment xml:lang="sr">ЈСОН закрпа</comment>
<comment xml:lang="sv">JSON patch</comment>
<comment xml:lang="tr">JSON yaması</comment>
<comment xml:lang="uk">латка JSON</comment>
- <comment xml:lang="zh_CN">JSON 补丁文件</comment>
+ <comment xml:lang="zh_CN">JSON 补丁</comment>
<comment xml:lang="zh_TW">JSON 修補檔</comment>
<acronym>JSON</acronym>
<expanded-acronym>JavaScript Object Notation</expanded-acronym>
@@ -12952,6 +13425,7 @@
</mime-type>
<mime-type type="application/ld+json">
<comment>JSON-LD document</comment>
+ <comment xml:lang="ast">Documentu JSON-LD</comment>
<comment xml:lang="ca">document JSON-LD</comment>
<comment xml:lang="cs">dokument JSON-LD</comment>
<comment xml:lang="da">JSON-LD-dokument</comment>
@@ -12962,6 +13436,7 @@
<comment xml:lang="eu">JSON-LD dokumentua</comment>
<comment xml:lang="fi">JSON-LD-asiakirja</comment>
<comment xml:lang="fr">document JSON-LD</comment>
+ <comment xml:lang="ga">cáipéis JSON-LD</comment>
<comment xml:lang="he">מסמך JSON-LD</comment>
<comment xml:lang="hr">JSON-LD dokument</comment>
<comment xml:lang="hu">JSON-LD dokumentum</comment>
@@ -12974,7 +13449,7 @@
<comment xml:lang="pl">Dokument JSON-LD</comment>
<comment xml:lang="pt">documento JSON-LD</comment>
<comment xml:lang="pt_BR">Documento JSON-LD</comment>
- <comment xml:lang="ru">документ JSON-LD</comment>
+ <comment xml:lang="ru">Документ JSON-LD</comment>
<comment xml:lang="sk">Dokument JSON-LD</comment>
<comment xml:lang="sr">ЈСОН-ЛД документ</comment>
<comment xml:lang="sv">JSON-LD-dokument</comment>
@@ -12991,18 +13466,28 @@
<mime-type type="application/x-ipynb+json">
<comment>Jupyter Notebook</comment>
<comment xml:lang="ca">llibreta de notes de Jupyter</comment>
+ <comment xml:lang="cs">sešit Jupyter</comment>
<comment xml:lang="da">Jupyter Notebook</comment>
<comment xml:lang="de">Jupyter-Dokument</comment>
+ <comment xml:lang="en_GB">Jupyter Notebook</comment>
<comment xml:lang="es">libreta de Jupyter</comment>
+ <comment xml:lang="eu">Jupyter Notebook</comment>
<comment xml:lang="fr">carnet de notes Jupyter</comment>
+ <comment xml:lang="ga">Leabhar nótaí Jupyter</comment>
<comment xml:lang="he">מחברת Jupyter</comment>
+ <comment xml:lang="hr">Jupyter bilježnica</comment>
<comment xml:lang="hu">Jupyter notesz</comment>
+ <comment xml:lang="id">Notebook Jupyter</comment>
+ <comment xml:lang="it">Notebook Jupyter</comment>
<comment xml:lang="kk">Jupyter Notebook</comment>
<comment xml:lang="ko">Jupyter 노트북</comment>
<comment xml:lang="pl">Notatnik Jupyter</comment>
<comment xml:lang="pt_BR">Bloco de Notas Jupyter</comment>
<comment xml:lang="ru">Jupyter Notebook</comment>
<comment xml:lang="sk">Zošit programu Jupyter</comment>
+ <comment xml:lang="sr">Џупитер бележница</comment>
+ <comment xml:lang="sv">Jupyter Notebook-dokument</comment>
+ <comment xml:lang="tr">Jupyter Notebook</comment>
<comment xml:lang="uk">записник Jupyter</comment>
<comment xml:lang="zh_CN">Jupyter 笔记本</comment>
<comment xml:lang="zh_TW">Jupyter 記事本</comment>
@@ -13017,6 +13502,7 @@
</mime-type>
<mime-type type="application/vnd.coffeescript">
<comment>CoffeeScript document</comment>
+ <comment xml:lang="ast">Documentu de CoffeScript</comment>
<comment xml:lang="ca">document CoffeeScript</comment>
<comment xml:lang="cs">dokument CoffeeScript</comment>
<comment xml:lang="da">CoffeeScript-dokument</comment>
@@ -13027,6 +13513,7 @@
<comment xml:lang="eu">CoffeeScript dokumentua</comment>
<comment xml:lang="fi">CoffeeScript-asiakirja</comment>
<comment xml:lang="fr">document CoffeeScript</comment>
+ <comment xml:lang="ga">cáipéis CoffeeScript</comment>
<comment xml:lang="he">מסמך CoffeeScript</comment>
<comment xml:lang="hr">CoffeeScript dokument</comment>
<comment xml:lang="hu">CoffeeScript dokumentum</comment>
@@ -13039,7 +13526,7 @@
<comment xml:lang="pl">Dokument CoffeeScript</comment>
<comment xml:lang="pt">documento CoffeeScript</comment>
<comment xml:lang="pt_BR">Documento CoffeeScript</comment>
- <comment xml:lang="ru">документ CoffeeScript</comment>
+ <comment xml:lang="ru">Документ CoffeeScript</comment>
<comment xml:lang="sk">Dokument CoffeeScript</comment>
<comment xml:lang="sr">Кофи скрипт документ</comment>
<comment xml:lang="sv">CoffeeScript-dokument</comment>
@@ -13090,7 +13577,7 @@
<comment xml:lang="pt">projecto JBuilder</comment>
<comment xml:lang="pt_BR">Projeto do JBuilder</comment>
<comment xml:lang="ro">Proiect JBuilder</comment>
- <comment xml:lang="ru">проект JBuilder</comment>
+ <comment xml:lang="ru">Проект JBuilder</comment>
<comment xml:lang="sk">Projekt JBuilder</comment>
<comment xml:lang="sl">Datoteka projekta JBuilder</comment>
<comment xml:lang="sq">Projekt JBuilder</comment>
@@ -13144,7 +13631,7 @@
<comment xml:lang="pt">desenho Karbon14</comment>
<comment xml:lang="pt_BR">Desenho do Karbon14</comment>
<comment xml:lang="ro">Desen Karbon14</comment>
- <comment xml:lang="ru">изображение Karbon14</comment>
+ <comment xml:lang="ru">Рисунок Karbon14</comment>
<comment xml:lang="sk">Kresba Karbon14</comment>
<comment xml:lang="sl">Datoteka risbe Karbon14</comment>
<comment xml:lang="sq">Vizatim Karbon14</comment>
@@ -13209,7 +13696,7 @@
<comment xml:lang="pt">gráfico KChart</comment>
<comment xml:lang="pt_BR">Gráfico do KChart</comment>
<comment xml:lang="ro">Diagramă KChart</comment>
- <comment xml:lang="ru">диаграмма KChart</comment>
+ <comment xml:lang="ru">Диаграмма KChart</comment>
<comment xml:lang="sk">Graf KChart</comment>
<comment xml:lang="sl">Datoteka grafikona KChart</comment>
<comment xml:lang="sq">Grafik KChart</comment>
@@ -13269,7 +13756,7 @@
<comment xml:lang="pt">definições Kexi para ligação de servidor de base de dados</comment>
<comment xml:lang="pt_BR">Configurações do Kexi para conexão a servidor de banco de dados</comment>
<comment xml:lang="ro">Configurări Kexi pentru conexiunea la serverul de baze de date</comment>
- <comment xml:lang="ru">параметры Kexi для подключения к серверу БД</comment>
+ <comment xml:lang="ru">Параметры Kexi для подключения к серверу БД</comment>
<comment xml:lang="sk">Nastavenia Kexi pre pripojenie k databázovému serveru</comment>
<comment xml:lang="sl">Strežniška povezava do nastavitvene datoteke Kexi.</comment>
<comment xml:lang="sr">подешавања Кексија за везу са сервером базе података</comment>
@@ -13298,7 +13785,7 @@
<comment xml:lang="ga">aicearra go tionscadal Kexi ar fhreastalaí bunachair sonraí</comment>
<comment xml:lang="gl">acceso directo a proxecto Kexi no servidor de bases de datos</comment>
<comment xml:lang="he">קיצור דרך לפרוירט Kexi בשרת נתונים</comment>
- <comment xml:lang="hr">prečac za Kexi projekt na poslužitelju baze podataka</comment>
+ <comment xml:lang="hr">Prečac do Kexi projekta na poslužitelju baze podataka</comment>
<comment xml:lang="hu">indítóikon adatbázis-kiszolgálón lévő Kexi projektre</comment>
<comment xml:lang="ia">Ligamine a projecto Kexi in servitor de base de datos</comment>
<comment xml:lang="id">pintasan ke projek Kexi pada server basis data</comment>
@@ -13314,7 +13801,7 @@
<comment xml:lang="pt">atalho para projeto Kexi em servidor de base de dados</comment>
<comment xml:lang="pt_BR">Atalho para projeto Kexi no servidor de banco de dados</comment>
<comment xml:lang="ro">scurtătură către un proiect Kexi pe un server de baze de date</comment>
- <comment xml:lang="ru">ссылка на проект Kexi на сервере БД</comment>
+ <comment xml:lang="ru">Ссылка на проект Kexi на сервере БД</comment>
<comment xml:lang="sk">Zástupca projektu Kexi na databázovom serveri</comment>
<comment xml:lang="sl">bližnjica do Kexi projekta na podatkovnem strežniku</comment>
<comment xml:lang="sr">пречица до пројекта Кексија на серверу базе података</comment>
@@ -13355,11 +13842,11 @@
<comment xml:lang="lv">Kexi datubāzes datnes balstīts projekts</comment>
<comment xml:lang="nl">Kexi database bestandgebaseerd project</comment>
<comment xml:lang="oc">projècte de banca de donadas Kexi en mòde fichièr</comment>
- <comment xml:lang="pl">Projekt bazy danych Kexi oparty na pliku</comment>
+ <comment xml:lang="pl">Projekt bazy danych Kexi na podstawie plików</comment>
<comment xml:lang="pt">projeto Kexi em base de dados baseada em ficheiros</comment>
<comment xml:lang="pt_BR">Projeto de banco de dados baseado em arquivo do Kexi</comment>
<comment xml:lang="ro">Proiect bazat pe fișiere al bazei de date Kexi</comment>
- <comment xml:lang="ru">файловый проект базы данных Kexi</comment>
+ <comment xml:lang="ru">Файловый проект базы данных Kexi</comment>
<comment xml:lang="sk">Projekt databázy Kexi s úložiskom typu súbor</comment>
<comment xml:lang="sl">Datoteka projekta podatkovne zbirke Kexi</comment>
<comment xml:lang="sr">пројекат Кексијеве базе података на основу датотеке</comment>
@@ -13401,11 +13888,11 @@
<comment xml:lang="lv">Kexi datubāzes datnes balstīts projekts</comment>
<comment xml:lang="nl">Kexi database bestandgebaseerd project</comment>
<comment xml:lang="oc">projècte de banca de donadas Kexi en mòde fichièr</comment>
- <comment xml:lang="pl">Projekt bazy danych Kexi oparty na pliku</comment>
+ <comment xml:lang="pl">Projekt bazy danych Kexi na podstawie plików</comment>
<comment xml:lang="pt">projeto Kexi em base de dados baseada em ficheiros</comment>
<comment xml:lang="pt_BR">Projeto de banco de dados baseado em arquivo do Kexi</comment>
<comment xml:lang="ro">Proiect bazat pe fișiere al bazei de date Kexi</comment>
- <comment xml:lang="ru">файловый проект базы данных Kexi</comment>
+ <comment xml:lang="ru">Файловый проект базы данных Kexi</comment>
<comment xml:lang="sk">Projekt databázy Kexi s úložiskom typu súbor</comment>
<comment xml:lang="sl">Datoteka projekta podatkovne zbirke Kexi</comment>
<comment xml:lang="sr">пројекат Кексијеве базе података на основу датотеке</comment>
@@ -13458,7 +13945,7 @@
<comment xml:lang="pt">fórmula KFormula</comment>
<comment xml:lang="pt_BR">Fórmula do KFormula</comment>
<comment xml:lang="ro">Formulă KFormula</comment>
- <comment xml:lang="ru">формула KFormula</comment>
+ <comment xml:lang="ru">Формула KFormula</comment>
<comment xml:lang="sk">Vzorec KFormula</comment>
<comment xml:lang="sl">Datoteka formule KFormula</comment>
<comment xml:lang="sq">Formulë KFormula</comment>
@@ -13523,7 +14010,7 @@
<comment xml:lang="pt">desenho KIllustrator</comment>
<comment xml:lang="pt_BR">Desenho do KIllustrator</comment>
<comment xml:lang="ro">Desen KIllustrator</comment>
- <comment xml:lang="ru">изображение KIllustrator</comment>
+ <comment xml:lang="ru">Рисунок KIllustrator</comment>
<comment xml:lang="sk">Kresba KIllustrator</comment>
<comment xml:lang="sl">Datoteka risbe KIllustrator</comment>
<comment xml:lang="sq">Vizatim KIllustrator</comment>
@@ -13583,11 +14070,11 @@
<comment xml:lang="pt">gráfico de fluxo Kivio</comment>
<comment xml:lang="pt_BR">Fluxograma do Kivio</comment>
<comment xml:lang="ro">Diagramă Kivio</comment>
- <comment xml:lang="ru">диаграмма Kivio</comment>
+ <comment xml:lang="ru">Диаграмма Kivio</comment>
<comment xml:lang="sk">Vývojový diagram Kivio</comment>
<comment xml:lang="sl">Datoteka grafikona Kivio</comment>
<comment xml:lang="sq">Diagramë fluksi Kivio</comment>
- <comment xml:lang="sr">Кливиов дијаграм протока</comment>
+ <comment xml:lang="sr">Кивиов дијаграм тока</comment>
<comment xml:lang="sv">Kivio-flödesschema</comment>
<comment xml:lang="tr">Kivio akış şeması</comment>
<comment xml:lang="uk">блок-схема Kivio</comment>
@@ -13648,7 +14135,7 @@
<comment xml:lang="pt">desenho Kontour</comment>
<comment xml:lang="pt_BR">Desenho do Kontour</comment>
<comment xml:lang="ro">Desen Kontour</comment>
- <comment xml:lang="ru">изображение Kontour</comment>
+ <comment xml:lang="ru">Рисунок Kontour</comment>
<comment xml:lang="sk">Kresba Kontour</comment>
<comment xml:lang="sl">Datoteka risbe Kontour</comment>
<comment xml:lang="sq">Vizatim Kontour</comment>
@@ -13713,7 +14200,7 @@
<comment xml:lang="pt">cenário KPovModeler</comment>
<comment xml:lang="pt_BR">Cena do KPovModeler</comment>
<comment xml:lang="ro">Scenă KPovModeler</comment>
- <comment xml:lang="ru">сцена KPovModeler</comment>
+ <comment xml:lang="ru">Сцена KPovModeler</comment>
<comment xml:lang="sk">Scéna KPovModeler</comment>
<comment xml:lang="sl">Datoteka scene KPovModeler</comment>
<comment xml:lang="sq">Skenë KPovModeler</comment>
@@ -13766,7 +14253,7 @@
<comment xml:lang="pt">apresentação KPresenter</comment>
<comment xml:lang="pt_BR">Apresentação do KPresenter</comment>
<comment xml:lang="ro">Prezentare KPresenter</comment>
- <comment xml:lang="ru">презентация KPresenter</comment>
+ <comment xml:lang="ru">Презентация KPresenter</comment>
<comment xml:lang="sk">Prezentácia KPresenter</comment>
<comment xml:lang="sl">Predstavitev KPresenter</comment>
<comment xml:lang="sq">Prezantim i KPresenter</comment>
@@ -13796,6 +14283,7 @@
<mime-type type="application/x-krita">
<comment>Krita document</comment>
<comment xml:lang="ar">مستند Krita</comment>
+ <comment xml:lang="ast">Documentu de Krita</comment>
<comment xml:lang="be@latin">Dakument Krita</comment>
<comment xml:lang="bg">Документ — Krita</comment>
<comment xml:lang="ca">document Krita</comment>
@@ -13832,7 +14320,7 @@
<comment xml:lang="pt">documento Krita</comment>
<comment xml:lang="pt_BR">Documento do Krita</comment>
<comment xml:lang="ro">Document Krita</comment>
- <comment xml:lang="ru">документ Krita</comment>
+ <comment xml:lang="ru">Документ Krita</comment>
<comment xml:lang="sk">Dokument Krita</comment>
<comment xml:lang="sl">Dokument Krita</comment>
<comment xml:lang="sq">Dokument Krita</comment>
@@ -13897,7 +14385,7 @@
<comment xml:lang="pt">folha de cálculo KSpread</comment>
<comment xml:lang="pt_BR">Planilha do KSpread</comment>
<comment xml:lang="ro">Foaie de calcul KSpread</comment>
- <comment xml:lang="ru">электронная таблица KSpread</comment>
+ <comment xml:lang="ru">Электронная таблица KSpread</comment>
<comment xml:lang="sk">Zošit KSpread</comment>
<comment xml:lang="sl">Preglednica KSpread</comment>
<comment xml:lang="sq">Fletë llogaritjesh KSpread</comment>
@@ -13906,7 +14394,7 @@
<comment xml:lang="tr">KSpread çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця KSpread</comment>
<comment xml:lang="vi">Bảng tính KSpread</comment>
- <comment xml:lang="zh_CN">KSpread 工作簿</comment>
+ <comment xml:lang="zh_CN">KSpread 电子表格</comment>
<comment xml:lang="zh_TW">KSpread 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<magic priority="60">
@@ -13962,7 +14450,7 @@
<comment xml:lang="pt">folha de cálculo KSpread (encriptada)</comment>
<comment xml:lang="pt_BR">Planilha do KSpread (criptografada)</comment>
<comment xml:lang="ro">Foaie de calcul KSpread (criptat)</comment>
- <comment xml:lang="ru">электронная таблица KSpread (зашифрованная)</comment>
+ <comment xml:lang="ru">Электронная таблица KSpread (зашифрованная)</comment>
<comment xml:lang="sk">Zošit KSpread (šifrovaný)</comment>
<comment xml:lang="sl">Preglednica KSpread (šifrirana)</comment>
<comment xml:lang="sq">Fletë llogaritjesh KSpread (e kriptuar)</comment>
@@ -13971,7 +14459,7 @@
<comment xml:lang="tr">KSpread çalışma sayfası (şifreli)</comment>
<comment xml:lang="uk">ел. таблиця KSpread (зашифрована)</comment>
<comment xml:lang="vi">Bảng tính KSpread (đã mật mã)</comment>
- <comment xml:lang="zh_CN">KSpread 加密工作簿</comment>
+ <comment xml:lang="zh_CN">KSpread 电子表格(加密)</comment>
<comment xml:lang="zh_TW">KSpread 試算表 (已加密)</comment>
<generic-icon name="x-office-spreadsheet"/>
<magic priority="50">
@@ -13994,7 +14482,7 @@
<comment xml:lang="fi">KSysV init -paketti</comment>
<comment xml:lang="fo">KSysV init pakki</comment>
<comment xml:lang="fr">paquet d'initialisation KSysV</comment>
- <comment xml:lang="ga">pacáiste thosú KSysV</comment>
+ <comment xml:lang="ga">pacáiste túsaithe KSysV</comment>
<comment xml:lang="gl">paquete de KsysV init</comment>
<comment xml:lang="he">חבילת KSysV init</comment>
<comment xml:lang="hr">KSysV init paket</comment>
@@ -14015,7 +14503,7 @@
<comment xml:lang="pt">pacote inicial KSysV</comment>
<comment xml:lang="pt_BR">Pacote init do KSysV</comment>
<comment xml:lang="ro">Pachet KSysV init</comment>
- <comment xml:lang="ru">пакет инициализации KSysV</comment>
+ <comment xml:lang="ru">Пакет инициализации KSysV</comment>
<comment xml:lang="sk">Balíček KSysV init</comment>
<comment xml:lang="sl">Datoteka paketa KSysV init</comment>
<comment xml:lang="sq">Paketë init KSysV</comment>
@@ -14036,6 +14524,7 @@
<mime-type type="application/x-kugar">
<comment>Kugar document</comment>
<comment xml:lang="ar">مستند Kugar</comment>
+ <comment xml:lang="ast">Documentu de Kugar</comment>
<comment xml:lang="be@latin">Dakument Kugar</comment>
<comment xml:lang="bg">Документ — Kugar</comment>
<comment xml:lang="ca">document Kugar</comment>
@@ -14072,7 +14561,7 @@
<comment xml:lang="pt">documento Kugar</comment>
<comment xml:lang="pt_BR">Documento do Kugar</comment>
<comment xml:lang="ro">Document Kugar</comment>
- <comment xml:lang="ru">документ Kugar</comment>
+ <comment xml:lang="ru">Документ Kugar</comment>
<comment xml:lang="sk">Dokument Kugar</comment>
<comment xml:lang="sl">Dokument Kugar</comment>
<comment xml:lang="sq">Dokument Kugar</comment>
@@ -14089,6 +14578,7 @@
<mime-type type="application/x-kword">
<comment>KWord document</comment>
<comment xml:lang="ar">مستند KWord</comment>
+ <comment xml:lang="ast">Documentu de Kword</comment>
<comment xml:lang="be@latin">Dakument KWord</comment>
<comment xml:lang="bg">Документ — KWord</comment>
<comment xml:lang="ca">document KWord</comment>
@@ -14126,7 +14616,7 @@
<comment xml:lang="pt">documento KWord</comment>
<comment xml:lang="pt_BR">Documento do KWord</comment>
<comment xml:lang="ro">Document KWord</comment>
- <comment xml:lang="ru">документ KWord</comment>
+ <comment xml:lang="ru">Документ KWord</comment>
<comment xml:lang="sk">Dokument KWord</comment>
<comment xml:lang="sl">Dokument KWord</comment>
<comment xml:lang="sq">Dokument KWord</comment>
@@ -14156,6 +14646,7 @@
<mime-type type="application/x-kword-crypt">
<comment>KWord document (encrypted)</comment>
<comment xml:lang="ar">مستند KWord (مشفر)</comment>
+ <comment xml:lang="ast">Documentu de Kword (cifráu)</comment>
<comment xml:lang="be@latin">Dakument KWord (zašyfravany)</comment>
<comment xml:lang="bg">Документ — KWord, шифриран</comment>
<comment xml:lang="ca">document KWord (xifrat)</comment>
@@ -14192,7 +14683,7 @@
<comment xml:lang="pt">documento KWord (encriptado)</comment>
<comment xml:lang="pt_BR">Documento do KWord (criptografado)</comment>
<comment xml:lang="ro">Document KWord (criptat)</comment>
- <comment xml:lang="ru">документ KWord (зашифрованный)</comment>
+ <comment xml:lang="ru">Документ KWord (зашифрованный)</comment>
<comment xml:lang="sk">Dokument KWord (šifrovaný)</comment>
<comment xml:lang="sl">Dokument KWord (šifriran)</comment>
<comment xml:lang="sq">Dokument KWord (i kriptuar)</comment>
@@ -14201,7 +14692,7 @@
<comment xml:lang="tr">KWord belgesi (şifreli)</comment>
<comment xml:lang="uk">документ KWord (зашифрований)</comment>
<comment xml:lang="vi">Tài liệu KWord (đã mật mã)</comment>
- <comment xml:lang="zh_CN">KWord 加密文档</comment>
+ <comment xml:lang="zh_CN">KWord 文档(加密)</comment>
<comment xml:lang="zh_TW">KWord 文件 (已加密)</comment>
<generic-icon name="x-office-document"/>
<magic priority="50">
@@ -14249,7 +14740,7 @@
<comment xml:lang="pt">arquivo LHA</comment>
<comment xml:lang="pt_BR">Pacote LHA</comment>
<comment xml:lang="ro">Arhivă LHA</comment>
- <comment xml:lang="ru">архив LHA</comment>
+ <comment xml:lang="ru">Архив LHA</comment>
<comment xml:lang="sk">Archív LHA</comment>
<comment xml:lang="sl">Datoteka arhiva LHA</comment>
<comment xml:lang="sq">Arkiv LHA</comment>
@@ -14318,7 +14809,7 @@
<comment xml:lang="pt">arquivo LHZ</comment>
<comment xml:lang="pt_BR">Pacote LHZ</comment>
<comment xml:lang="ro">Arhivă LHZ</comment>
- <comment xml:lang="ru">архив LHZ</comment>
+ <comment xml:lang="ru">Архив LHZ</comment>
<comment xml:lang="sk">Archív LHZ</comment>
<comment xml:lang="sl">Datoteka arhiva LHZ</comment>
<comment xml:lang="sq">Arkiv LHZ</comment>
@@ -14332,7 +14823,7 @@
<generic-icon name="package-x-generic"/>
<glob pattern="*.lhz"/>
</mime-type>
- <mime-type type="text/vnd.trolltech.linguist">
+ <mime-type type="text/vnd.qt.linguist">
<comment>message catalog</comment>
<comment xml:lang="ar">كتالوج الرسالة</comment>
<comment xml:lang="be@latin">kataloh paviedamleńniaŭ</comment>
@@ -14352,7 +14843,7 @@
<comment xml:lang="ga">catalóg theachtaireachtaí</comment>
<comment xml:lang="gl">catálogo de mensaxes</comment>
<comment xml:lang="he">קטלוג הודעות</comment>
- <comment xml:lang="hr">katalog poruka</comment>
+ <comment xml:lang="hr">Katalog poruka</comment>
<comment xml:lang="hu">üzenetkatalógus</comment>
<comment xml:lang="ia">Catalogo de messages</comment>
<comment xml:lang="id">katalog pesan</comment>
@@ -14371,7 +14862,7 @@
<comment xml:lang="pt">catálogo de mensagens</comment>
<comment xml:lang="pt_BR">Catálogo de mensagens</comment>
<comment xml:lang="ro">catalog de mesaje</comment>
- <comment xml:lang="ru">каталог сообщений</comment>
+ <comment xml:lang="ru">Каталог сообщений</comment>
<comment xml:lang="sk">Katalóg správ</comment>
<comment xml:lang="sl">katalogov sporočil</comment>
<comment xml:lang="sq">Katallog mesazhesh</comment>
@@ -14388,10 +14879,12 @@
</magic>
<glob pattern="*.ts"/>
<alias type="application/x-linguist"/>
+ <alias type="text/vnd.trolltech.linguist"/>
</mime-type>
<mime-type type="application/x-lyx">
<comment>LyX document</comment>
<comment xml:lang="ar">مستند LyX</comment>
+ <comment xml:lang="ast">Documentu de Lyx</comment>
<comment xml:lang="be@latin">Dakument LyX</comment>
<comment xml:lang="bg">Документ — LyX</comment>
<comment xml:lang="ca">document LyX</comment>
@@ -14428,7 +14921,7 @@
<comment xml:lang="pt">documento LyX</comment>
<comment xml:lang="pt_BR">Documento LyX</comment>
<comment xml:lang="ro">Document LyX</comment>
- <comment xml:lang="ru">документ LyX</comment>
+ <comment xml:lang="ru">Документ LyX</comment>
<comment xml:lang="sk">Dokument LyX</comment>
<comment xml:lang="sl">Dokument LyX</comment>
<comment xml:lang="sq">Dokument LyX</comment>
@@ -14459,6 +14952,7 @@
<comment xml:lang="eu">LZ4 artxiboa</comment>
<comment xml:lang="fi">LZ4-arkisto</comment>
<comment xml:lang="fr">archive LZ4</comment>
+ <comment xml:lang="ga">Cartlann LZ4</comment>
<comment xml:lang="gl">Arquivo LZ4</comment>
<comment xml:lang="he">ארכיון LZ4</comment>
<comment xml:lang="hr">LZ4 arhiva</comment>
@@ -14472,7 +14966,7 @@
<comment xml:lang="pl">Archiwum LZ4</comment>
<comment xml:lang="pt">arquivo LZ4</comment>
<comment xml:lang="pt_BR">Pacote LZ4</comment>
- <comment xml:lang="ru">архив LZ4</comment>
+ <comment xml:lang="ru">Архив LZ4</comment>
<comment xml:lang="sk">Archív LZ4</comment>
<comment xml:lang="sl">Datoteka arhiva LZ4</comment>
<comment xml:lang="sr">ЛЗ4 архива</comment>
@@ -14491,21 +14985,31 @@
<mime-type type="application/x-lz4-compressed-tar">
<comment>Tar archive (LZ4-compressed)</comment>
<comment xml:lang="ca">arxiu tar (amb compressió LZ4)</comment>
+ <comment xml:lang="cs">archiv Tar (komprimace LZ4)</comment>
<comment xml:lang="da">Tar-arkiv (LZ4-komprimeret)</comment>
<comment xml:lang="de">Tar-Archiv (LZ4-komprimiert)</comment>
+ <comment xml:lang="en_GB">Tar archive (LZ4-compressed)</comment>
<comment xml:lang="es">archivador Tar (comprimido con LZ4)</comment>
+ <comment xml:lang="eu">Tar artxiboa (LZ4-rekin konprimatua)</comment>
<comment xml:lang="fi">Tar-arkisto (LZ4-pakattu)</comment>
<comment xml:lang="fr">archive tar (compression LZ4)</comment>
+ <comment xml:lang="ga">cartlann Tar (comhbhrúite le LZ4)</comment>
<comment xml:lang="he">ארכיון Tar (מכווץ ע״י LZ4)</comment>
+ <comment xml:lang="hr">Tar arhiva (LZ4 sažeto)</comment>
<comment xml:lang="hu">Tar archívum (LZ4-el tömörítve)</comment>
+ <comment xml:lang="id">arsip tar (terkompresi LZ4)</comment>
+ <comment xml:lang="it">Archivio tar (compresso con LZ4)</comment>
<comment xml:lang="kk">Tar архиві (LZ4-пен сығылған)</comment>
<comment xml:lang="ko">Tar 묶음 파일(LZ4 압축)</comment>
<comment xml:lang="pl">Archiwum tar (kompresja LZ4)</comment>
<comment xml:lang="pt_BR">Arquvio Tar (compactado com LZ4)</comment>
- <comment xml:lang="ru">архив TAR (сжатый LZ4)</comment>
+ <comment xml:lang="ru">Архив TAR (сжатый lz4)</comment>
<comment xml:lang="sk">Archív tar (komprimovaný pomocou LZ4)</comment>
+ <comment xml:lang="sr">Тар архива (запакована ЛЗ4-ом)</comment>
+ <comment xml:lang="sv">Tar-arkiv (LZ4-komprimerat)</comment>
+ <comment xml:lang="tr">Tar arşivi (LZ4 ile sıkıştırılmış)</comment>
<comment xml:lang="uk">архів tar (стиснений LZ4)</comment>
- <comment xml:lang="zh_CN">Tar 归档文件 (LZ4 压缩)</comment>
+ <comment xml:lang="zh_CN">Tar 归档文件(LZ4 压缩)</comment>
<comment xml:lang="zh_TW">Tar 封存檔 (LZ4 格式壓縮)</comment>
<generic-icon name="package-x-generic"/>
<sub-class-of type="application/x-lz4"/>
@@ -14546,7 +15050,7 @@
<comment xml:lang="pt">arquivo LZip</comment>
<comment xml:lang="pt_BR">Pacote Lzip</comment>
<comment xml:lang="ro">Arhivă Lzip</comment>
- <comment xml:lang="ru">архив LZIP</comment>
+ <comment xml:lang="ru">Архив LZIP</comment>
<comment xml:lang="sk">Archív Lzip</comment>
<comment xml:lang="sl">Datoteka arhiva Lzip</comment>
<comment xml:lang="sr">Лзип архива</comment>
@@ -14564,21 +15068,31 @@
<mime-type type="application/x-lzip-compressed-tar">
<comment>Tar archive (lzip-compressed)</comment>
<comment xml:lang="ca">arxiu tar (amb compressió lzip)</comment>
+ <comment xml:lang="cs">archiv Tar (komprimace lzip)</comment>
<comment xml:lang="da">Tar-arkiv (lzip-komprimeret)</comment>
<comment xml:lang="de">Tar-Archiv (lzip-komprimiert)</comment>
+ <comment xml:lang="en_GB">Tar archive (lzip-compressed)</comment>
<comment xml:lang="es">archivador Tar (comprimido con lzip)</comment>
+ <comment xml:lang="eu">Tar artxiboa (lzip-rekin konprimatua)</comment>
<comment xml:lang="fi">Tar-arkisto (lzip-pakattu)</comment>
<comment xml:lang="fr">archive tar (compressée lzip)</comment>
+ <comment xml:lang="ga">cartlann Tar (comhbhrúite le lzip)</comment>
<comment xml:lang="he">ארכיון Tar (מכווץ ע״י lzip)</comment>
+ <comment xml:lang="hr">Tar arhiva (lzip sažeto)</comment>
<comment xml:lang="hu">Tar archívum (lzippel tömörítve)</comment>
+ <comment xml:lang="id">arsip tar (terkompresi lzip)</comment>
+ <comment xml:lang="it">Archivio tar (compresso con lzip)</comment>
<comment xml:lang="kk">Tar архиві (lzip-пен сығылған)</comment>
<comment xml:lang="ko">TAR 묶음 파일(LZIP 압축)</comment>
<comment xml:lang="pl">Archiwum tar (kompresja lzip)</comment>
<comment xml:lang="pt_BR">Arquivo Tar (compactado com lzip)</comment>
- <comment xml:lang="ru">архив TAR (сжатый lzip)</comment>
+ <comment xml:lang="ru">Архив TAR (сжатый lzip)</comment>
<comment xml:lang="sk">Archív tar (komprimovaný pomocou lzip)</comment>
+ <comment xml:lang="sr">Тар архива (запакована лзипом)</comment>
+ <comment xml:lang="sv">Tar-arkiv (lzip-komprimerat)</comment>
+ <comment xml:lang="tr">Tar arşivi (lzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">архів tar (стиснений lzip)</comment>
- <comment xml:lang="zh_CN">Tar 归档文件 (lzip 压缩)</comment>
+ <comment xml:lang="zh_CN">Tar 归档文件(lzip 压缩)</comment>
<comment xml:lang="zh_TW">Tar 封存檔 (lzip 格式壓縮)</comment>
<generic-icon name="package-x-generic"/>
<sub-class-of type="application/x-lzip"/>
@@ -14586,6 +15100,32 @@
</mime-type>
<mime-type type="application/x-lzpdf">
<comment>PDF document (lzip-compressed)</comment>
+ <comment xml:lang="ast">Documentu PDF (comprimíu en lzip)</comment>
+ <comment xml:lang="ca">document PDF (amb compressió lzip)</comment>
+ <comment xml:lang="cs">dokument PDF (komprimace lzip)</comment>
+ <comment xml:lang="de">PDF-Dokument (lzip-komprimiert)</comment>
+ <comment xml:lang="en_GB">PDF document (lzip-compressed)</comment>
+ <comment xml:lang="es">documento PDF (comprimido con lzip)</comment>
+ <comment xml:lang="eu">PDF dokumentua (lzip-rekin konprimitua)</comment>
+ <comment xml:lang="fi">PDF-asiakirja (lzip-pakattu)</comment>
+ <comment xml:lang="fr">document PDF (compressé lzip)</comment>
+ <comment xml:lang="ga">cáipéis PDF (comhbhrúite le lzip)</comment>
+ <comment xml:lang="hr">PDF dokument (lzip sažeto)</comment>
+ <comment xml:lang="hu">PDF dokumentum (lzip-tömörítésű)</comment>
+ <comment xml:lang="id">dokumen PDF (termkompresi lzip)</comment>
+ <comment xml:lang="it">Documento PDF (compresso con lzip)</comment>
+ <comment xml:lang="kk">PDF құжаты (lzip-пен сығылған)</comment>
+ <comment xml:lang="ko">PDF 문서(LZIP 압축)</comment>
+ <comment xml:lang="pl">Dokument PDF (kompresja lzip)</comment>
+ <comment xml:lang="pt_BR">Documento PDF (compactado com lzip)</comment>
+ <comment xml:lang="ru">Документ PDF (сжатый lzip)</comment>
+ <comment xml:lang="sk">Dokument PDF (komprimovaný pomocou lzip)</comment>
+ <comment xml:lang="sr">ПДФ документ (запакован лзип-ом)</comment>
+ <comment xml:lang="sv">PDF-dokument (lzip-komprimerat)</comment>
+ <comment xml:lang="tr">PDF belgesi (lzip ile sıkıştırılmış)</comment>
+ <comment xml:lang="uk">документ PDF (стиснений lzip)</comment>
+ <comment xml:lang="zh_CN">PDF 文档(lzip 压缩)</comment>
+ <comment xml:lang="zh_TW">PDF 文件 (lzip 格式壓縮)</comment>
<sub-class-of type="application/x-lzip"/>
<generic-icon name="x-office-document"/>
<glob pattern="*.pdf.lz"/>
@@ -14628,7 +15168,7 @@
<comment xml:lang="pt">arquivo LZMA</comment>
<comment xml:lang="pt_BR">Pacote LZMA</comment>
<comment xml:lang="ro">Arhivă LZMA</comment>
- <comment xml:lang="ru">архив LZMA</comment>
+ <comment xml:lang="ru">Архив LZMA</comment>
<comment xml:lang="sk">Archív LZMA</comment>
<comment xml:lang="sl">Datoteka arhiva LZMA</comment>
<comment xml:lang="sq">Arkiv LZMA</comment>
@@ -14650,7 +15190,7 @@
<comment xml:lang="be@latin">Archiŭ tar (LZMA-skampresavany)</comment>
<comment xml:lang="bg">Архив — tar, компресиран с LZMA</comment>
<comment xml:lang="ca">arxiu tar (amb compressió LZMA)</comment>
- <comment xml:lang="cs">archiv tar (komprimovaný pomocí LZMA)</comment>
+ <comment xml:lang="cs">archiv Tar (komprimace LZMA)</comment>
<comment xml:lang="da">Tar-arkiv (LZMA-komprimeret)</comment>
<comment xml:lang="de">Tar-Archiv (LZMA-komprimiert)</comment>
<comment xml:lang="el">Αρχείο Tar (συμπιεσμένο με LZMA)</comment>
@@ -14663,7 +15203,7 @@
<comment xml:lang="ga">cartlann Tar (comhbhrúite le LZMA)</comment>
<comment xml:lang="gl">arquivo Tar (comprimido con LZMA)</comment>
<comment xml:lang="he">ארכיון Tar (מכווץ ע״י LZMA)</comment>
- <comment xml:lang="hr">Tar arhiva (komprimirana LZMA-om)</comment>
+ <comment xml:lang="hr">Tar arhiva (LZMA sažeta)</comment>
<comment xml:lang="hu">Tar archívum (LZMA-val tömörítve)</comment>
<comment xml:lang="ia">Archivo Tar (comprimite con LZMA)</comment>
<comment xml:lang="id">Arsip Tar (terkompresi LZMA)</comment>
@@ -14681,7 +15221,7 @@
<comment xml:lang="pt">arquivo Tar (compressão LZMA)</comment>
<comment xml:lang="pt_BR">Pacote Tar (compactado com LZMA)</comment>
<comment xml:lang="ro">Arhivă Tar (comprimată LZMA)</comment>
- <comment xml:lang="ru">архив TAR (сжатый LZMA)</comment>
+ <comment xml:lang="ru">Архив TAR (сжатый lzma)</comment>
<comment xml:lang="sk">Archív tar (komprimovaný pomocou LZMA)</comment>
<comment xml:lang="sl">Datoteka arhiva Tar (stisnjen z LZMA)</comment>
<comment xml:lang="sq">Arkiv tar (i kompresuar me LZMA)</comment>
@@ -14690,7 +15230,7 @@
<comment xml:lang="tr">Tar arşivi (LZMA ile sıkıştırılmış)</comment>
<comment xml:lang="uk">архів tar (стиснений LZMA)</comment>
<comment xml:lang="vi">Kho nén tar (đã nén LZMA)</comment>
- <comment xml:lang="zh_CN">Tar 归档文件 (LZMA 压缩)</comment>
+ <comment xml:lang="zh_CN">Tar 归档文件(LZMA 压缩)</comment>
<comment xml:lang="zh_TW">Tar 封存檔 (LZMA 格式壓縮)</comment>
<sub-class-of type="application/x-lzma"/>
<generic-icon name="package-x-generic"/>
@@ -14736,7 +15276,7 @@
<comment xml:lang="pt">arquivo LZO</comment>
<comment xml:lang="pt_BR">Pacote LZO</comment>
<comment xml:lang="ro">Arhivă LZO</comment>
- <comment xml:lang="ru">архив LZO</comment>
+ <comment xml:lang="ru">Архив LZO</comment>
<comment xml:lang="sk">Archív LZO</comment>
<comment xml:lang="sl">Datoteka arhiva LZO</comment>
<comment xml:lang="sq">Arkiv LZO</comment>
@@ -14764,9 +15304,9 @@
<comment xml:lang="el">Συμπιεσμένο αρχείο Qpress</comment>
<comment xml:lang="en_GB">Qpress archive</comment>
<comment xml:lang="es">archivador de Qpress</comment>
- <comment xml:lang="eu">Qpress artxiboa</comment>
<comment xml:lang="fi">Qpress-arkisto</comment>
<comment xml:lang="fr">Archive Qpress</comment>
+ <comment xml:lang="ga">cartlann Qpress</comment>
<comment xml:lang="gl">Arquivo Qpress</comment>
<comment xml:lang="he">ארכיון Qpress</comment>
<comment xml:lang="hr">Qpress arhiva</comment>
@@ -14780,7 +15320,7 @@
<comment xml:lang="pl">Archiwum Qpress</comment>
<comment xml:lang="pt">arquivo Qpress</comment>
<comment xml:lang="pt_BR">Pacote Qpress</comment>
- <comment xml:lang="ru">архив Qpress</comment>
+ <comment xml:lang="ru">Архив Qpress</comment>
<comment xml:lang="sk">Archív Qpress</comment>
<comment xml:lang="sl">Datoteka arhiva Qpress</comment>
<comment xml:lang="sr">Купрес архива</comment>
@@ -14806,6 +15346,7 @@
<comment xml:lang="eu">XAR artxiboa</comment>
<comment xml:lang="fi">XAR-arkisto</comment>
<comment xml:lang="fr">archive XAR</comment>
+ <comment xml:lang="ga">cartlann XAR</comment>
<comment xml:lang="he">ארכיון XAR</comment>
<comment xml:lang="hr">XAR arhiva</comment>
<comment xml:lang="hu">XAR archívum</comment>
@@ -14816,7 +15357,7 @@
<comment xml:lang="oc">Archiu XAR</comment>
<comment xml:lang="pl">Archiwum XAR</comment>
<comment xml:lang="pt_BR">Arquivo XAR</comment>
- <comment xml:lang="ru">архив XAR</comment>
+ <comment xml:lang="ru">Архив XAR</comment>
<comment xml:lang="sk">Archív XAR</comment>
<comment xml:lang="sr">ИксАР архива</comment>
<comment xml:lang="sv">XAR-arkiv</comment>
@@ -14843,9 +15384,9 @@
<comment xml:lang="el">Συμπιεσμένο αρχείο Zlib</comment>
<comment xml:lang="en_GB">Zlib archive</comment>
<comment xml:lang="es">archivador Zlib</comment>
- <comment xml:lang="eu">Zlib artxiboa</comment>
<comment xml:lang="fi">Zlib-arkisto</comment>
<comment xml:lang="fr">Archive Zlib</comment>
+ <comment xml:lang="ga">cartlann Zlib</comment>
<comment xml:lang="gl">Arquivo Zlib</comment>
<comment xml:lang="he">ארכיון Zlib</comment>
<comment xml:lang="hr">Zlib arhiva</comment>
@@ -14859,7 +15400,7 @@
<comment xml:lang="pl">Archiwum Zlib</comment>
<comment xml:lang="pt">arquivo Zlib</comment>
<comment xml:lang="pt_BR">Pacote Zlib</comment>
- <comment xml:lang="ru">архив Zlib</comment>
+ <comment xml:lang="ru">Архив Zlib</comment>
<comment xml:lang="sk">Archív Zlib</comment>
<comment xml:lang="sl">Datoteka arhiva Zlib</comment>
<comment xml:lang="sr">Злиб архива</comment>
@@ -14912,7 +15453,7 @@
<comment xml:lang="pt">apresentação MagicPoint</comment>
<comment xml:lang="pt_BR">Apresentação do MagicPoint</comment>
<comment xml:lang="ro">Prezentare MagicPoint</comment>
- <comment xml:lang="ru">презентация MagicPoint</comment>
+ <comment xml:lang="ru">Презентация MagicPoint</comment>
<comment xml:lang="sk">Prezentácia MagicPoint</comment>
<comment xml:lang="sl">Predstavitev MagicPoint</comment>
<comment xml:lang="sq">Prezantim MagicPoint</comment>
@@ -14966,7 +15507,7 @@
<comment xml:lang="pt">ficheiro MacBinary de Macintosh</comment>
<comment xml:lang="pt_BR">Arquivo do Macintosh MacBinary</comment>
<comment xml:lang="ro">Fișier Macintosh MacBinary</comment>
- <comment xml:lang="ru">файл Macintosh MacBinary</comment>
+ <comment xml:lang="ru">Файл Macintosh MacBinary</comment>
<comment xml:lang="sk">Súbor pre Macintosh MacBinary</comment>
<comment xml:lang="sl">Izvedljiva dvojiška datoteka Macintosh MacBinary</comment>
<comment xml:lang="sq">File MacBinary Macintosh</comment>
@@ -15019,7 +15560,7 @@
<comment xml:lang="pt">fluxo Matroska</comment>
<comment xml:lang="pt_BR">Transmissão do Matroska</comment>
<comment xml:lang="ro">Flux Matroska</comment>
- <comment xml:lang="ru">поток Matroska</comment>
+ <comment xml:lang="ru">Поток Matroska</comment>
<comment xml:lang="sk">Stream Matroska</comment>
<comment xml:lang="sl">Pretočni vir Matroska</comment>
<comment xml:lang="sq">Stream Matroska</comment>
@@ -15045,6 +15586,7 @@
<mime-type type="video/x-matroska">
<comment>Matroska video</comment>
<comment xml:lang="ar">Matroska مرئي</comment>
+ <comment xml:lang="ast">Videu en Matroska</comment>
<comment xml:lang="be@latin">Videa Matroska</comment>
<comment xml:lang="bg">Видео — Matroska</comment>
<comment xml:lang="ca">vídeo Matroska</comment>
@@ -15062,7 +15604,7 @@
<comment xml:lang="ga">físeán Matroska</comment>
<comment xml:lang="gl">vídeo de Matroska</comment>
<comment xml:lang="he">וידאו Matroska</comment>
- <comment xml:lang="hr">Matroska video</comment>
+ <comment xml:lang="hr">Matroška video snimka</comment>
<comment xml:lang="hu">Matroska-videó</comment>
<comment xml:lang="ia">Video Matroska</comment>
<comment xml:lang="id">Video Matroska</comment>
@@ -15082,7 +15624,7 @@
<comment xml:lang="pt">vídeo Matroska</comment>
<comment xml:lang="pt_BR">Vídeo Matroska</comment>
<comment xml:lang="ro">Video Matroska</comment>
- <comment xml:lang="ru">видео Matroska</comment>
+ <comment xml:lang="ru">Видео Matroska</comment>
<comment xml:lang="sk">Video Matroska</comment>
<comment xml:lang="sl">Video datoteka Matroska</comment>
<comment xml:lang="sq">Video Matroska</comment>
@@ -15098,6 +15640,7 @@
</mime-type>
<mime-type type="video/x-matroska-3d">
<comment>Matroska 3D video</comment>
+ <comment xml:lang="ast">Videu en Matroska 3D</comment>
<comment xml:lang="ca">vídeo Matroska 3D</comment>
<comment xml:lang="cs">3D video Matroska</comment>
<comment xml:lang="da">Matroska 3D-video</comment>
@@ -15108,6 +15651,7 @@
<comment xml:lang="eu">Matroska 3D bideoa</comment>
<comment xml:lang="fi">Matroska 3D-video</comment>
<comment xml:lang="fr">vidéo Matroska 3D</comment>
+ <comment xml:lang="ga">físeán Matroska 3D</comment>
<comment xml:lang="gl">Video Matroska 3D</comment>
<comment xml:lang="he">סרטון תלת ממדי מסוג Matroska</comment>
<comment xml:lang="hr">Matroška 3D video snimka</comment>
@@ -15153,7 +15697,7 @@
<comment xml:lang="ga">fuaim Matroska</comment>
<comment xml:lang="gl">son de Matroska</comment>
<comment xml:lang="he">שמע Matroska</comment>
- <comment xml:lang="hr">Matroska audio</comment>
+ <comment xml:lang="hr">Matroška zvučni zapis</comment>
<comment xml:lang="hu">Matroska hang</comment>
<comment xml:lang="ia">Audio Matroska</comment>
<comment xml:lang="id">Audio Matroska</comment>
@@ -15172,7 +15716,7 @@
<comment xml:lang="pt">áudio Matroska</comment>
<comment xml:lang="pt_BR">Áudio Matroska</comment>
<comment xml:lang="ro">Audio Matroska</comment>
- <comment xml:lang="ru">аудио Matroska</comment>
+ <comment xml:lang="ru">Аудио Matroska</comment>
<comment xml:lang="sk">Zvuk Matroska</comment>
<comment xml:lang="sl">Zvočna datoteka Matroska</comment>
<comment xml:lang="sq">Audio Matroska</comment>
@@ -15189,6 +15733,7 @@
<mime-type type="video/webm">
<comment>WebM video</comment>
<comment xml:lang="ar">WebM مرئي</comment>
+ <comment xml:lang="ast">Videu en WebM</comment>
<comment xml:lang="bg">Видео — WebM</comment>
<comment xml:lang="ca">vídeo WebM</comment>
<comment xml:lang="cs">video WebM</comment>
@@ -15205,7 +15750,7 @@
<comment xml:lang="ga">físeán WebM</comment>
<comment xml:lang="gl">vídeo WebM</comment>
<comment xml:lang="he">וידאו WebM</comment>
- <comment xml:lang="hr">WebM video</comment>
+ <comment xml:lang="hr">WebM video snimka</comment>
<comment xml:lang="hu">WebM videó</comment>
<comment xml:lang="ia">Video WebM</comment>
<comment xml:lang="id">Video WebM</comment>
@@ -15221,7 +15766,7 @@
<comment xml:lang="pt">vídeo WebM</comment>
<comment xml:lang="pt_BR">Vídeo WebM</comment>
<comment xml:lang="ro">Video WebM</comment>
- <comment xml:lang="ru">видео WebM</comment>
+ <comment xml:lang="ru">Видео WebM</comment>
<comment xml:lang="sk">Video WebM</comment>
<comment xml:lang="sl">Video datoteka WebM</comment>
<comment xml:lang="sr">ВебМ видео</comment>
@@ -15261,7 +15806,7 @@
<comment xml:lang="ga">fuaim WebM</comment>
<comment xml:lang="gl">son WebM</comment>
<comment xml:lang="he">שמע WebM</comment>
- <comment xml:lang="hr">WebM audio</comment>
+ <comment xml:lang="hr">WebM zvučni zapis</comment>
<comment xml:lang="hu">WebM hang</comment>
<comment xml:lang="ia">Audio WebM</comment>
<comment xml:lang="id">Audio WebM</comment>
@@ -15277,7 +15822,7 @@
<comment xml:lang="pt">áudio WebM</comment>
<comment xml:lang="pt_BR">Áudio WebM</comment>
<comment xml:lang="ro">Audio WebM</comment>
- <comment xml:lang="ru">аудио WebM</comment>
+ <comment xml:lang="ru">Аудио WebM</comment>
<comment xml:lang="sk">Zvuk WebM</comment>
<comment xml:lang="sl">Zvočna datoteka WebM</comment>
<comment xml:lang="sr">ВебМ звук</comment>
@@ -15300,6 +15845,7 @@
<comment xml:lang="eu">MHTML web artxiboa</comment>
<comment xml:lang="fi">MHTML-kooste</comment>
<comment xml:lang="fr">archive web MHTML</comment>
+ <comment xml:lang="ga">cartlann ghréasáin MHTML</comment>
<comment xml:lang="gl">Arquivo web MHTML</comment>
<comment xml:lang="he">ארכיון רשת MHTML</comment>
<comment xml:lang="hr">MHTML web arhiva</comment>
@@ -15315,7 +15861,7 @@
<comment xml:lang="pl">Archiwum witryny MHTML</comment>
<comment xml:lang="pt">arquivo web MHTML</comment>
<comment xml:lang="pt_BR">Pacote web MHTML</comment>
- <comment xml:lang="ru">веб-архив MHTML</comment>
+ <comment xml:lang="ru">Веб-архив MHTML</comment>
<comment xml:lang="sk">Webový archív MHTML</comment>
<comment xml:lang="sl">Spletni arhiv MHTML</comment>
<comment xml:lang="sr">МХТМЛ веб архива</comment>
@@ -15333,6 +15879,7 @@
<mime-type type="application/mxf">
<comment>MXF video</comment>
<comment xml:lang="ar">MXF مرئي</comment>
+ <comment xml:lang="ast">Videu en MXF</comment>
<comment xml:lang="bg">Видео — MXF</comment>
<comment xml:lang="ca">vídeo MXF</comment>
<comment xml:lang="cs">video MXF</comment>
@@ -15349,7 +15896,7 @@
<comment xml:lang="ga">físeán MXF</comment>
<comment xml:lang="gl">vídeo MXF</comment>
<comment xml:lang="he">וידאו MXF</comment>
- <comment xml:lang="hr">MXF video</comment>
+ <comment xml:lang="hr">MXF video snimka</comment>
<comment xml:lang="hu">MXF videó</comment>
<comment xml:lang="ia">Video MXF</comment>
<comment xml:lang="id">Video MXF</comment>
@@ -15366,7 +15913,7 @@
<comment xml:lang="pt">vídeo MXF</comment>
<comment xml:lang="pt_BR">Vídeo MXF</comment>
<comment xml:lang="ro">Video MXF</comment>
- <comment xml:lang="ru">видео MXF</comment>
+ <comment xml:lang="ru">Видео MXF</comment>
<comment xml:lang="sk">Video MXF</comment>
<comment xml:lang="sl">Video datoteka MXF</comment>
<comment xml:lang="sr">МИксФ видео</comment>
@@ -15421,7 +15968,7 @@
<comment xml:lang="pt">ficheiro OCL</comment>
<comment xml:lang="pt_BR">Arquivo OCL</comment>
<comment xml:lang="ro">Fișier OCL</comment>
- <comment xml:lang="ru">файл OCL</comment>
+ <comment xml:lang="ru">Файл OCL</comment>
<comment xml:lang="sk">Súbor OCL</comment>
<comment xml:lang="sl">Datoteka OCL</comment>
<comment xml:lang="sq">File OCL</comment>
@@ -15451,6 +15998,7 @@
<comment xml:lang="eu">COBOL iturburu-kodea</comment>
<comment xml:lang="fi">COBOL-lähdekoodi</comment>
<comment xml:lang="fr">fichier source COBOL</comment>
+ <comment xml:lang="ga">cód foinseach COBOL</comment>
<comment xml:lang="gl">ficheiro fonte de COBOL</comment>
<comment xml:lang="he">קובץ מקור של COBOL</comment>
<comment xml:lang="hr">COBOL izvorna datoteka</comment>
@@ -15468,14 +16016,14 @@
<comment xml:lang="pl">Plik źródłowy COBOL</comment>
<comment xml:lang="pt">ficheiro origem COBOL</comment>
<comment xml:lang="pt_BR">Arquivo de código-fonte em COBOL</comment>
- <comment xml:lang="ru">файл исходного кода на COBOL</comment>
+ <comment xml:lang="ru">Файл исходного кода на COBOL</comment>
<comment xml:lang="sk">Zdrojový súbor COBOLu</comment>
<comment xml:lang="sl">Izvorna koda COBOL</comment>
<comment xml:lang="sr">изворна датотека КОБОЛ-а</comment>
<comment xml:lang="sv">COBOL-källkodsfil</comment>
<comment xml:lang="tr">COBOL kaynak dosyası</comment>
<comment xml:lang="uk">вихідний код мовою COBOL</comment>
- <comment xml:lang="zh_CN">COBOL 源</comment>
+ <comment xml:lang="zh_CN">COBOL 源文件</comment>
<comment xml:lang="zh_TW">COBOL 源檔</comment>
<acronym>COBOL</acronym>
<expanded-acronym>COmmon Business Oriented Language</expanded-acronym>
@@ -15496,6 +16044,7 @@
<comment xml:lang="eu">Mobipocket liburua</comment>
<comment xml:lang="fi">Mobipocket e-kirja</comment>
<comment xml:lang="fr">livre numérique Mobipocket</comment>
+ <comment xml:lang="ga">r-leabhar Mobipocket</comment>
<comment xml:lang="gl">E-book Mobipocket</comment>
<comment xml:lang="he">ספר אלקטרוני של Mobipocket</comment>
<comment xml:lang="hr">Mobipocket e-knjiga</comment>
@@ -15513,7 +16062,7 @@
<comment xml:lang="pl">E-book Mobipocket</comment>
<comment xml:lang="pt">ebook Mobipocket</comment>
<comment xml:lang="pt_BR">E-book Mobipocket</comment>
- <comment xml:lang="ru">электронная книга Mobipocket</comment>
+ <comment xml:lang="ru">Электронная книга Mobipocket</comment>
<comment xml:lang="sk">E-kniha Mobipocket</comment>
<comment xml:lang="sl">e-knjiga Mobipocket</comment>
<comment xml:lang="sr">Мобипокет ел. књига</comment>
@@ -15537,6 +16086,7 @@
<mime-type type="application/x-mif">
<comment>Adobe FrameMaker MIF document</comment>
<comment xml:lang="ar">مستند أدوبي الصانع للإطارات MIF</comment>
+ <comment xml:lang="ast">Documentu MIF d'Adobe FrameMaker</comment>
<comment xml:lang="be@latin">Dakument Adobe FrameMaker MIF</comment>
<comment xml:lang="bg">Документ — Adobe FrameMaker MIF</comment>
<comment xml:lang="ca">document MIF d'Adobe FrameMaker</comment>
@@ -15573,7 +16123,7 @@
<comment xml:lang="pt">documento Adobe FrameMaker MIF</comment>
<comment xml:lang="pt_BR">Documento MIF do Adobe FrameMaker</comment>
<comment xml:lang="ro">Document Adobe FrameMaker MIF</comment>
- <comment xml:lang="ru">документ Adobe FrameMaker MIF</comment>
+ <comment xml:lang="ru">Документ Adobe FrameMaker MIF</comment>
<comment xml:lang="sk">Dokument Adobe FrameMaker MIF</comment>
<comment xml:lang="sl">Dokument Adobe FrameMaker MIF</comment>
<comment xml:lang="sq">Dokument MIF Adobe FrameMaker</comment>
@@ -15606,7 +16156,7 @@
<comment xml:lang="ga">leabharmharcanna Mozilla</comment>
<comment xml:lang="gl">Marcadores de Mozilla</comment>
<comment xml:lang="he">סימניה של Mozilla</comment>
- <comment xml:lang="hr">Mozilla knjižne oznake</comment>
+ <comment xml:lang="hr">Mozilla zabilješke</comment>
<comment xml:lang="hu">Mozilla-könyvjelzők</comment>
<comment xml:lang="ia">Marcapaginas Mozilla</comment>
<comment xml:lang="id">Bookmark Mozilla</comment>
@@ -15625,7 +16175,7 @@
<comment xml:lang="pt">marcadores do Mozilla</comment>
<comment xml:lang="pt_BR">Favoritos do Mozilla</comment>
<comment xml:lang="ro">Semne de carte Mozilla</comment>
- <comment xml:lang="ru">закладки Mozilla</comment>
+ <comment xml:lang="ru">Закладки Mozilla</comment>
<comment xml:lang="sk">Záložky Mozilla</comment>
<comment xml:lang="sl">Datoteka zaznamkov Mozilla</comment>
<comment xml:lang="sq">Libërshënues Mozilla</comment>
@@ -15683,7 +16233,7 @@
<comment xml:lang="pt">executável DOS/Windows</comment>
<comment xml:lang="pt_BR">Executável do DOS/Windows</comment>
<comment xml:lang="ro">Executabil DOS/Windows</comment>
- <comment xml:lang="ru">исполняемый файл DOS/Windows</comment>
+ <comment xml:lang="ru">Исполняемый файл DOS/Windows</comment>
<comment xml:lang="sk">Spustiteľný súbor pre DOS/Windows</comment>
<comment xml:lang="sl">Izvedljiva datoteka DOS/Windows</comment>
<comment xml:lang="sq">I ekzekutueshëm DOS/Windows</comment>
@@ -15741,7 +16291,7 @@
<comment xml:lang="sk">Internetový odkaz</comment>
<comment xml:lang="sl">Internetna bližnjica</comment>
<comment xml:lang="sq">Shkurtim internet</comment>
- <comment xml:lang="sr">Интернет пречица</comment>
+ <comment xml:lang="sr">интернет пречица</comment>
<comment xml:lang="sv">Internetgenväg</comment>
<comment xml:lang="tr">İnternet kısayolu</comment>
<comment xml:lang="uk">інтернет-посилання</comment>
@@ -15759,6 +16309,7 @@
<mime-type type="application/x-mswrite">
<comment>WRI document</comment>
<comment xml:lang="ar">مستند WRI</comment>
+ <comment xml:lang="ast">Documentu WRI</comment>
<comment xml:lang="be@latin">Dakument WRI</comment>
<comment xml:lang="bg">Документ — WRI</comment>
<comment xml:lang="ca">document WRI</comment>
@@ -15794,7 +16345,7 @@
<comment xml:lang="pt">documento WRI</comment>
<comment xml:lang="pt_BR">Documento WRI</comment>
<comment xml:lang="ro">Document WRI</comment>
- <comment xml:lang="ru">документ WRI</comment>
+ <comment xml:lang="ru">Документ WRI</comment>
<comment xml:lang="sk">Dokument WRI</comment>
<comment xml:lang="sl">Dokument WRI</comment>
<comment xml:lang="sq">Dokument WRI</comment>
@@ -15847,7 +16398,7 @@
<comment xml:lang="oc">ROM MSX</comment>
<comment xml:lang="pl">Plik ROM konsoli MSX</comment>
<comment xml:lang="pt">ROM MSX</comment>
- <comment xml:lang="pt_BR">ROM do MSX</comment>
+ <comment xml:lang="pt_BR">ROM de MSX</comment>
<comment xml:lang="ro">ROM MSX</comment>
<comment xml:lang="ru">MSX ROM</comment>
<comment xml:lang="sk">ROM pre MSX</comment>
@@ -15900,7 +16451,7 @@
<comment xml:lang="pt">macro M4</comment>
<comment xml:lang="pt_BR">Macro M4</comment>
<comment xml:lang="ro">Macro M4</comment>
- <comment xml:lang="ru">макрос M4</comment>
+ <comment xml:lang="ru">Макрос M4</comment>
<comment xml:lang="sk">Makro M4</comment>
<comment xml:lang="sl">Makro datoteka M4</comment>
<comment xml:lang="sq">Macro M4</comment>
@@ -15952,7 +16503,7 @@
<comment xml:lang="oc">ROM Nintendo64</comment>
<comment xml:lang="pl">Plik ROM konsoli Nintendo64</comment>
<comment xml:lang="pt">ROM Nintendo64</comment>
- <comment xml:lang="pt_BR">ROM do Nintendo64</comment>
+ <comment xml:lang="pt_BR">ROM de Nintendo64</comment>
<comment xml:lang="ro">ROM Nintendo64</comment>
<comment xml:lang="ru">Nintendo64 ROM</comment>
<comment xml:lang="sk">ROM pre Nintendo64</comment>
@@ -15963,7 +16514,7 @@
<comment xml:lang="tr">Nintendo64 ROM</comment>
<comment xml:lang="uk">ППП Nintendo64</comment>
<comment xml:lang="vi">ROM Nintendo64</comment>
- <comment xml:lang="zh_CN">Nintendo64 ROM</comment>
+ <comment xml:lang="zh_CN">任天堂 64 ROM</comment>
<comment xml:lang="zh_TW">Nintendo64 ROM</comment>
<generic-icon name="application-x-executable"/>
<glob pattern="*.n64"/>
@@ -16000,7 +16551,7 @@
<comment xml:lang="ga">nasc Nautilus</comment>
<comment xml:lang="gl">ligazón de nautilus</comment>
<comment xml:lang="he">קישור של Nautilus</comment>
- <comment xml:lang="hr">Nautilus veza</comment>
+ <comment xml:lang="hr">Nautilusova poveznica</comment>
<comment xml:lang="hu">Nautilus-link</comment>
<comment xml:lang="ia">Ligamine Nautilus</comment>
<comment xml:lang="id">Taut Nautilus</comment>
@@ -16019,7 +16570,7 @@
<comment xml:lang="pt">atalho Nautilus</comment>
<comment xml:lang="pt_BR">Link do Nautilus</comment>
<comment xml:lang="ro">Legătură Nautilus</comment>
- <comment xml:lang="ru">ссылка Nautilus</comment>
+ <comment xml:lang="ru">Ссылка Nautilus</comment>
<comment xml:lang="sk">Odkaz Nautilus</comment>
<comment xml:lang="sl">Datoteka povezave Nautilus</comment>
<comment xml:lang="sq">Lidhje Nautilus</comment>
@@ -16039,25 +16590,49 @@
<mime-type type="application/x-neo-geo-pocket-rom">
<comment>Neo-Geo Pocket ROM</comment>
<comment xml:lang="ca">ROM de Neo-Geo Pocket</comment>
+ <comment xml:lang="cs">ROM pro Neo-Geo Pocket</comment>
<comment xml:lang="da">Neo-Geo Pocket ROM</comment>
<comment xml:lang="de">Neo-Geo Pocket ROM</comment>
+ <comment xml:lang="en_GB">Neo-Geo Pocket ROM</comment>
<comment xml:lang="es">ROM de Neo-Geo Pocket</comment>
+ <comment xml:lang="eu">Neo-Geo Pocket ROM</comment>
<comment xml:lang="fi">Neo-Geo Pocket -ROM</comment>
<comment xml:lang="fr">ROM Neo-Geo Pocket</comment>
+ <comment xml:lang="ga">ROM Neo-Geo Pocket</comment>
+ <comment xml:lang="hr">Neo-Geo Pocket ROM</comment>
<comment xml:lang="hu">Neo-Geo Pocket ROM</comment>
+ <comment xml:lang="id">ROM Neo-Geo Pocket</comment>
+ <comment xml:lang="it">ROM Neo-Geo Pocket</comment>
<comment xml:lang="kk">Neo-Geo Pocket ROM</comment>
<comment xml:lang="ko">네오지오 포켓 롬</comment>
<comment xml:lang="pl">Plik ROM konsoli Neo-Geo Pocket</comment>
<comment xml:lang="pt_BR">ROM de Neo-Geo Pocket</comment>
<comment xml:lang="ru">Neo-Geo Pocket ROM</comment>
<comment xml:lang="sk">ROM pre Neo-Geo Pocket</comment>
+ <comment xml:lang="sr">Нео-Гео Покет РОМ</comment>
+ <comment xml:lang="sv">Neo-Geo Pocket-rom</comment>
+ <comment xml:lang="tr">Neo-Geo Pocket ROM</comment>
<comment xml:lang="uk">ППП Neo-Geo Pocket</comment>
<comment xml:lang="zh_CN">Neo-Geo Pocket ROM</comment>
<comment xml:lang="zh_TW">Neo-Geo Pocket ROM</comment>
<generic-icon name="application-x-executable"/>
<glob pattern="*.ngp"/>
<magic>
- <match value="COPYRIGHT BY SNK CORPORATION" type="string" offset="0"/>
+ <match value="0x0" type="byte" offset="35">
+ <match value="COPYRIGHT BY SNK CORPORATION" type="string" offset="0"/>
+ <match value=" LICENSED BY SNK CORPORATION" type="string" offset="0"/>
+ </match>
+ </magic>
+ </mime-type>
+ <mime-type type="application/x-neo-geo-pocket-color-rom">
+ <comment>Neo-Geo Pocket Color ROM</comment>
+ <generic-icon name="application-x-executable"/>
+ <glob pattern="*.ngc"/>
+ <magic>
+ <match value="0x10" type="byte" offset="35">
+ <match value="COPYRIGHT BY SNK CORPORATION" type="string" offset="0"/>
+ <match value=" LICENSED BY SNK CORPORATION" type="string" offset="0"/>
+ </match>
</magic>
</mime-type>
<mime-type type="application/x-nes-rom">
@@ -16099,7 +16674,7 @@
<comment xml:lang="oc">ROM NES</comment>
<comment xml:lang="pl">Plik ROM konsoli NES</comment>
<comment xml:lang="pt">ROM NES</comment>
- <comment xml:lang="pt_BR">ROM do NES</comment>
+ <comment xml:lang="pt_BR">ROM de NES</comment>
<comment xml:lang="ro">ROM NES</comment>
<comment xml:lang="ru">NES ROM</comment>
<comment xml:lang="sk">ROM pre NES</comment>
@@ -16121,6 +16696,7 @@
<mime-type type="application/x-netcdf">
<comment>Unidata NetCDF document</comment>
<comment xml:lang="ar">مستند Unidata NetCDF</comment>
+ <comment xml:lang="ast">Documentu NetCDF d'Unidata</comment>
<comment xml:lang="be@latin">Dakument Unidata NetCDF</comment>
<comment xml:lang="bg">Документ — Unidata NetCDF</comment>
<comment xml:lang="ca">document d'Unidata NetCDF</comment>
@@ -16157,7 +16733,7 @@
<comment xml:lang="pt">documento Unidata NetCDF</comment>
<comment xml:lang="pt_BR">Documento do Unidata NetCDF</comment>
<comment xml:lang="ro">Document Unidata NetCDF</comment>
- <comment xml:lang="ru">документ Unidata NetCDF</comment>
+ <comment xml:lang="ru">Документ Unidata NetCDF</comment>
<comment xml:lang="sk">Dokument Unidata NetCDF</comment>
<comment xml:lang="sl">Dokument Unidata NetCDF</comment>
<comment xml:lang="sq">Dokument Unidata NetCDF</comment>
@@ -16186,6 +16762,7 @@
<comment xml:lang="es">índice NewzBin de usenet</comment>
<comment xml:lang="eu">NewzBin usenet indizea</comment>
<comment xml:lang="fr">index usenet </comment>
+ <comment xml:lang="ga">innéacs usenet NewzBin</comment>
<comment xml:lang="gl">Índice de usenet NEwzBin</comment>
<comment xml:lang="he">אינדקס שרתי חדשות NewzBin</comment>
<comment xml:lang="hr">NewzBin usenet indeks</comment>
@@ -16202,14 +16779,14 @@
<comment xml:lang="pl">Indeks grup dyskusyjnych NewzBin</comment>
<comment xml:lang="pt">índice usenet NewzBin</comment>
<comment xml:lang="pt_BR">Índice de usenet NewzBin</comment>
- <comment xml:lang="ru">индекс usenet NewzBin</comment>
+ <comment xml:lang="ru">Индекс usenet NewzBin</comment>
<comment xml:lang="sk">Index Usenetu NewzBin</comment>
<comment xml:lang="sl">Kazalo usenet NewzBin</comment>
<comment xml:lang="sr">Њузбин попис јузнета</comment>
<comment xml:lang="sv">NewzBin-usenetindex</comment>
<comment xml:lang="tr">NewzBin usenet dizini</comment>
<comment xml:lang="uk">покажчик usenet NewzBin</comment>
- <comment xml:lang="zh_CN">NewzBin usenet 索引</comment>
+ <comment xml:lang="zh_CN">NewzBin Usenet 索引</comment>
<comment xml:lang="zh_TW">NewzBin usenet 索引</comment>
<sub-class-of type="application/xml"/>
<magic priority="80">
@@ -16236,10 +16813,10 @@
<comment xml:lang="ga">cód réada</comment>
<comment xml:lang="gl">código obxecto</comment>
<comment xml:lang="he">קוד אובייקט</comment>
- <comment xml:lang="hr">kod objekta</comment>
+ <comment xml:lang="hr">Object kôd</comment>
<comment xml:lang="hu">tárgykód</comment>
<comment xml:lang="ia">Codice objecto</comment>
- <comment xml:lang="id">kode object</comment>
+ <comment xml:lang="id">kode objek</comment>
<comment xml:lang="it">Codice oggetto</comment>
<comment xml:lang="ja">オブジェクトコード</comment>
<comment xml:lang="kk">объектті коды</comment>
@@ -16255,7 +16832,7 @@
<comment xml:lang="pt">código de objeto</comment>
<comment xml:lang="pt_BR">Código-objeto</comment>
<comment xml:lang="ro">cod sursă obiect</comment>
- <comment xml:lang="ru">объектный код</comment>
+ <comment xml:lang="ru">Объектный код</comment>
<comment xml:lang="sk">Objektový kód</comment>
<comment xml:lang="sl">predmetna koda</comment>
<comment xml:lang="sq">Kod objekti</comment>
@@ -16299,7 +16876,7 @@
<comment xml:lang="ga">formáid mhalairte Annodex</comment>
<comment xml:lang="gl">formato intercambiábel de Annodex</comment>
<comment xml:lang="he">תבנית החלפת Annodex</comment>
- <comment xml:lang="hr">Annodex oblik za razmjenu</comment>
+ <comment xml:lang="hr">Annodex format razmjene</comment>
<comment xml:lang="hu">Annodex csereformátum</comment>
<comment xml:lang="ia">Formato de excambio Annodex</comment>
<comment xml:lang="id">Format pertukaran Annodex</comment>
@@ -16316,7 +16893,7 @@
<comment xml:lang="pt">formato de troca Annodex</comment>
<comment xml:lang="pt_BR">Formato de troca Annodex</comment>
<comment xml:lang="ro">Format schimb Annodex</comment>
- <comment xml:lang="ru">формат обмена Annodex</comment>
+ <comment xml:lang="ru">Формат обмена Annodex</comment>
<comment xml:lang="sk">Formát pre výmenu Annodex</comment>
<comment xml:lang="sl">Izmenjalna datoteka Annodex</comment>
<comment xml:lang="sr">Анодексов запис размене</comment>
@@ -16340,6 +16917,7 @@
<mime-type type="video/annodex">
<comment>Annodex Video</comment>
<comment xml:lang="ar">Annodex مرئي</comment>
+ <comment xml:lang="ast">Videu n'Annodex</comment>
<comment xml:lang="bg">Видео — Annodex</comment>
<comment xml:lang="ca">Annodex Video</comment>
<comment xml:lang="cs">video Annodex</comment>
@@ -16353,10 +16931,10 @@
<comment xml:lang="fi">Annodex-video</comment>
<comment xml:lang="fo">Annodex video</comment>
<comment xml:lang="fr">vidéo Annodex</comment>
- <comment xml:lang="ga">físeán Annodex</comment>
+ <comment xml:lang="ga">Físeán Annodex</comment>
<comment xml:lang="gl">vídeo de Annodex</comment>
<comment xml:lang="he">וידאו Annodex</comment>
- <comment xml:lang="hr">Annodex Video</comment>
+ <comment xml:lang="hr">Annodex video snimka</comment>
<comment xml:lang="hu">Annodex videó</comment>
<comment xml:lang="ia">Video Annodex</comment>
<comment xml:lang="id">Video Annodex</comment>
@@ -16373,7 +16951,7 @@
<comment xml:lang="pt">vídeo Annodex</comment>
<comment xml:lang="pt_BR">Vídeo Annodex</comment>
<comment xml:lang="ro">Video Annodex</comment>
- <comment xml:lang="ru">видео Annodex</comment>
+ <comment xml:lang="ru">Видео Annodex</comment>
<comment xml:lang="sk">Video Annodex</comment>
<comment xml:lang="sl">Video datoteka Annodex</comment>
<comment xml:lang="sr">Анодекс видео</comment>
@@ -16410,10 +16988,10 @@
<comment xml:lang="fi">Annodex-ääni</comment>
<comment xml:lang="fo">Annodex ljóður</comment>
<comment xml:lang="fr">audio Annodex</comment>
- <comment xml:lang="ga">fuaim Annodex</comment>
+ <comment xml:lang="ga">Fuaim Annodex</comment>
<comment xml:lang="gl">son de Annodex</comment>
<comment xml:lang="he">שמע Annodex</comment>
- <comment xml:lang="hr">Annodex Audio</comment>
+ <comment xml:lang="hr">Annodex zvučni zapis</comment>
<comment xml:lang="hu">Annodex hang</comment>
<comment xml:lang="ia">Audio Annodex</comment>
<comment xml:lang="id">Audio Annodex</comment>
@@ -16430,7 +17008,7 @@
<comment xml:lang="pt">áudio Annodex</comment>
<comment xml:lang="pt_BR">Áudio Annodex</comment>
<comment xml:lang="ro">Audio Annodex</comment>
- <comment xml:lang="ru">аудио Annodex</comment>
+ <comment xml:lang="ru">Аудио Annodex</comment>
<comment xml:lang="sk">Zvuk Annodex</comment>
<comment xml:lang="sl">Zvočna datoteka Annodex</comment>
<comment xml:lang="sr">Анодекс аудио</comment>
@@ -16489,7 +17067,7 @@
<comment xml:lang="pt">ficheiro multimédia Ogg</comment>
<comment xml:lang="pt_BR">Arquivo multimídia Ogg</comment>
<comment xml:lang="ro">Fișier multimedia Ogg</comment>
- <comment xml:lang="ru">мультимедийный файл Ogg</comment>
+ <comment xml:lang="ru">Мультимедийный файл Ogg</comment>
<comment xml:lang="sk">Súbor multimédií Ogg</comment>
<comment xml:lang="sl">Večpredstavnostna datoteka Ogg</comment>
<comment xml:lang="sq">File multimedial Ogg</comment>
@@ -16523,7 +17101,7 @@
<comment xml:lang="fi">Ogg-ääni</comment>
<comment xml:lang="fo">Ogg ljóður</comment>
<comment xml:lang="fr">audio Ogg</comment>
- <comment xml:lang="ga">fuaim Ogg</comment>
+ <comment xml:lang="ga">Fuaim Ogg</comment>
<comment xml:lang="gl">son Ogg</comment>
<comment xml:lang="he">שמע Ogg</comment>
<comment xml:lang="hr">Ogg zvučni zapis</comment>
@@ -16545,7 +17123,7 @@
<comment xml:lang="pt">áudio Ogg</comment>
<comment xml:lang="pt_BR">Áudio Ogg</comment>
<comment xml:lang="ro">Audio Ogg</comment>
- <comment xml:lang="ru">аудио Ogg</comment>
+ <comment xml:lang="ru">Аудио Ogg</comment>
<comment xml:lang="sk">Zvuk Ogg</comment>
<comment xml:lang="sl">Zvočna datoteka Ogg</comment>
<comment xml:lang="sq">Audio Ogg</comment>
@@ -16568,6 +17146,7 @@
<mime-type type="video/ogg">
<comment>Ogg Video</comment>
<comment xml:lang="ar">Ogg مرئي</comment>
+ <comment xml:lang="ast">Videu n'Ogg</comment>
<comment xml:lang="be@latin">Videa Ogg</comment>
<comment xml:lang="bg">Видео — Ogg</comment>
<comment xml:lang="ca">vídeo Ogg</comment>
@@ -16581,7 +17160,7 @@
<comment xml:lang="fi">Ogg-video</comment>
<comment xml:lang="fo">Ogg Video</comment>
<comment xml:lang="fr">vidéo Ogg</comment>
- <comment xml:lang="ga">físeán Ogg</comment>
+ <comment xml:lang="ga">Físeán Ogg</comment>
<comment xml:lang="gl">vídeo Ogg</comment>
<comment xml:lang="he">וידאו Ogg</comment>
<comment xml:lang="hr">Ogg video snimka</comment>
@@ -16603,7 +17182,7 @@
<comment xml:lang="pt">vídeo Ogg</comment>
<comment xml:lang="pt_BR">Vídeo Ogg</comment>
<comment xml:lang="ro">Video Ogg</comment>
- <comment xml:lang="ru">видео Ogg</comment>
+ <comment xml:lang="ru">Видео Ogg</comment>
<comment xml:lang="sk">Video Ogg</comment>
<comment xml:lang="sl">Video datoteka Ogg</comment>
<comment xml:lang="sq">Video Ogg</comment>
@@ -16664,7 +17243,7 @@
<comment xml:lang="pt">áudio Ogg Vorbis</comment>
<comment xml:lang="pt_BR">Áudio Ogg Vorbis</comment>
<comment xml:lang="ro">Audio Ogg Vorbis</comment>
- <comment xml:lang="ru">аудио Ogg Vorbis</comment>
+ <comment xml:lang="ru">Аудио Ogg Vorbis</comment>
<comment xml:lang="sk">Zvuk Ogg Vorbis</comment>
<comment xml:lang="sl">Zvočna datoteka Ogg Vorbis</comment>
<comment xml:lang="sq">Audio Ogg Vorbis</comment>
@@ -16724,7 +17303,7 @@
<comment xml:lang="pt">áudio Ogg FLAC</comment>
<comment xml:lang="pt_BR">Áudio Ogg FLAC</comment>
<comment xml:lang="ro">Audio Ogg FLAC</comment>
- <comment xml:lang="ru">аудио Ogg FLAC</comment>
+ <comment xml:lang="ru">Аудио Ogg FLAC</comment>
<comment xml:lang="sk">Zvuk Ogg FLAC</comment>
<comment xml:lang="sl">Zvočna datoteka Ogg FLAC</comment>
<comment xml:lang="sq">Audio Ogg FLAC</comment>
@@ -16760,6 +17339,7 @@
<comment xml:lang="eu">Opus audioa</comment>
<comment xml:lang="fi">Opus-ääni</comment>
<comment xml:lang="fr">audio Opus</comment>
+ <comment xml:lang="ga">fuaim Opus</comment>
<comment xml:lang="gl">Son Opus</comment>
<comment xml:lang="he">שמע Opus</comment>
<comment xml:lang="hr">Opus zvučni zapis</comment>
@@ -16828,7 +17408,7 @@
<comment xml:lang="pt">áudio Ogg Speex</comment>
<comment xml:lang="pt_BR">Áudio Ogg Speex</comment>
<comment xml:lang="ro">Audio Ogg Speex</comment>
- <comment xml:lang="ru">аудио Ogg Speex</comment>
+ <comment xml:lang="ru">Аудио Ogg Speex</comment>
<comment xml:lang="sk">Zvuk Ogg Speex</comment>
<comment xml:lang="sl">Zvočna datoteka Ogg Speex</comment>
<comment xml:lang="sq">Audio Ogg Speex</comment>
@@ -16867,7 +17447,7 @@
<comment xml:lang="ga">fuaim Speex</comment>
<comment xml:lang="gl">son Speex</comment>
<comment xml:lang="he">שמע של Speex</comment>
- <comment xml:lang="hr">Speex audio</comment>
+ <comment xml:lang="hr">Speex zvučni zapis</comment>
<comment xml:lang="hu">Speex hang</comment>
<comment xml:lang="ia">Audio Speex</comment>
<comment xml:lang="id">Audio Speex</comment>
@@ -16885,7 +17465,7 @@
<comment xml:lang="pt">áudio Speex</comment>
<comment xml:lang="pt_BR">Áudio Speex</comment>
<comment xml:lang="ro">Audio Speex</comment>
- <comment xml:lang="ru">аудио Speex</comment>
+ <comment xml:lang="ru">Аудио Speex</comment>
<comment xml:lang="sk">Zvuk Speex</comment>
<comment xml:lang="sl">Zvočna datoteka Speex</comment>
<comment xml:lang="sq">Audio Speex</comment>
@@ -16904,6 +17484,7 @@
<mime-type type="video/x-theora+ogg">
<comment>Ogg Theora video</comment>
<comment xml:lang="ar">Ogg Theora مرئي</comment>
+ <comment xml:lang="ast">Videu n'Ogg Theora</comment>
<comment xml:lang="be@latin">Videa Ogg Theora</comment>
<comment xml:lang="bg">Видео — Ogg Theora</comment>
<comment xml:lang="ca">vídeo Ogg Theora</comment>
@@ -16939,7 +17520,7 @@
<comment xml:lang="pt">vídeo Ogg Theora</comment>
<comment xml:lang="pt_BR">Vídeo Ogg Theora</comment>
<comment xml:lang="ro">Video Ogg Theora</comment>
- <comment xml:lang="ru">видео Ogg Theora</comment>
+ <comment xml:lang="ru">Видео Ogg Theora</comment>
<comment xml:lang="sk">Video Ogg Theora</comment>
<comment xml:lang="sl">Video datoteka Ogg Theora</comment>
<comment xml:lang="sq">Video Ogg Theora</comment>
@@ -16962,6 +17543,7 @@
<mime-type type="video/x-ogm+ogg">
<comment>OGM video</comment>
<comment xml:lang="ar">OGM مرئي</comment>
+ <comment xml:lang="ast">Videu n'OGM</comment>
<comment xml:lang="be@latin">Videa OGM</comment>
<comment xml:lang="bg">Видео — OGM</comment>
<comment xml:lang="ca">vídeo OGM</comment>
@@ -16979,7 +17561,7 @@
<comment xml:lang="ga">físeán OGM</comment>
<comment xml:lang="gl">vídeo OGM</comment>
<comment xml:lang="he">וידאו OGM</comment>
- <comment xml:lang="hr">OGM video</comment>
+ <comment xml:lang="hr">OGM video snimka</comment>
<comment xml:lang="hu">OGM-videó</comment>
<comment xml:lang="ia">Video OGM</comment>
<comment xml:lang="id">Video OGM</comment>
@@ -16998,7 +17580,7 @@
<comment xml:lang="pt">vídeo OGM</comment>
<comment xml:lang="pt_BR">Vídeo OGM</comment>
<comment xml:lang="ro">Video OGM</comment>
- <comment xml:lang="ru">видео OGM</comment>
+ <comment xml:lang="ru">Видео OGM</comment>
<comment xml:lang="sk">Video OGM</comment>
<comment xml:lang="sl">Video datoteka OGM</comment>
<comment xml:lang="sq">Video OGM</comment>
@@ -17022,6 +17604,7 @@
<mime-type type="application/x-ole-storage">
<comment>OLE2 compound document storage</comment>
<comment xml:lang="ar">تخزين مجمع مستند OLE2</comment>
+ <comment xml:lang="ast">Almacenamientu de documentos compuestu por OLE2</comment>
<comment xml:lang="be@latin">Schovišča dla kampanentaŭ dakumentu OLE2</comment>
<comment xml:lang="bg">Съставен документ-хранилище — OLE2</comment>
<comment xml:lang="ca">emmagatzematge de documents compostos OLE2</comment>
@@ -17036,7 +17619,7 @@
<comment xml:lang="fi">OLE2-yhdisteasiakirjatallenne</comment>
<comment xml:lang="fo">OLE2 samansett skjalagoymsla</comment>
<comment xml:lang="fr">document de stockage composé OLE2</comment>
- <comment xml:lang="ga">stóras cháipéisí comhshuite OLE2</comment>
+ <comment xml:lang="ga">stóras cáipéisí comhshuite OLE2</comment>
<comment xml:lang="gl">almacenamento de documento composto OLE2</comment>
<comment xml:lang="he">אחסון מסמך משותף OLE2</comment>
<comment xml:lang="hr">OLE2 pohrana složenog dokumenta</comment>
@@ -17058,7 +17641,7 @@
<comment xml:lang="pt">armazenamento de documento composto OLE2</comment>
<comment xml:lang="pt_BR">Armazenamento de documento composto OLE2</comment>
<comment xml:lang="ro">Document de stocare compus OLE2</comment>
- <comment xml:lang="ru">хранилище составных документов OLE2</comment>
+ <comment xml:lang="ru">Хранилище составных документов OLE2</comment>
<comment xml:lang="sk">Úložisko zloženého dokumentu OLE2</comment>
<comment xml:lang="sl">Združeni dokument OLE2</comment>
<comment xml:lang="sq">Arkiv dokumenti i përbërë OLE2</comment>
@@ -17077,6 +17660,7 @@
</mime-type>
<mime-type type="application/vnd.ms-publisher">
<comment>Microsoft Publisher document</comment>
+ <comment xml:lang="ast">Documentu de Microsoft Publisher</comment>
<comment xml:lang="ca">document de Microsoft Publisher</comment>
<comment xml:lang="cs">dokument Microsoft Publisher</comment>
<comment xml:lang="da">Microsoft Publisher-dokument</comment>
@@ -17087,6 +17671,7 @@
<comment xml:lang="eu">Microsoft Publisher dokumentua</comment>
<comment xml:lang="fi">Microsoft Publisher -asiakirja</comment>
<comment xml:lang="fr">document Microsoft Publisher</comment>
+ <comment xml:lang="ga">cáipéis Microsoft Publisher</comment>
<comment xml:lang="gl">Documento de Microsoft Publisher</comment>
<comment xml:lang="he">מסמך Microsoft Publisher</comment>
<comment xml:lang="hr">Microsoft Publisher dokument</comment>
@@ -17131,7 +17716,7 @@
<comment xml:lang="ga">pacáiste Windows Installer</comment>
<comment xml:lang="gl">paquete de instalación de Windows</comment>
<comment xml:lang="he">חבילה של Windows Installer</comment>
- <comment xml:lang="hr">Windows Installer paket</comment>
+ <comment xml:lang="hr">Windows Instalacijski paket</comment>
<comment xml:lang="hu">Windows Installer csomag</comment>
<comment xml:lang="ia">Pacchetto Windows Installer</comment>
<comment xml:lang="id">Paket Windows Installer</comment>
@@ -17148,7 +17733,7 @@
<comment xml:lang="pt">pacote de instalação Windows</comment>
<comment xml:lang="pt_BR">Pacote do Windows Installer</comment>
<comment xml:lang="ro">Pachet instalator Windows</comment>
- <comment xml:lang="ru">пакет Windows Installer</comment>
+ <comment xml:lang="ru">Пакет Windows Installer</comment>
<comment xml:lang="sk">Balík Windows Installer</comment>
<comment xml:lang="sl">Datoteka paketa Windows namestilnika</comment>
<comment xml:lang="sq">Paketë Windows Installer</comment>
@@ -17202,7 +17787,7 @@
<comment xml:lang="pt">folha de cálculo GNU Oleo</comment>
<comment xml:lang="pt_BR">Planilha do GNU Oleo</comment>
<comment xml:lang="ro">Foaie de calcul GNU Oleo</comment>
- <comment xml:lang="ru">электронная таблица GNU Oleo</comment>
+ <comment xml:lang="ru">Электронная таблица GNU Oleo</comment>
<comment xml:lang="sk">Zošit GNU Oleo</comment>
<comment xml:lang="sl">Preglednica GNU Oleo</comment>
<comment xml:lang="sq">Fletë llogaritje GNU Oleo</comment>
@@ -17211,7 +17796,7 @@
<comment xml:lang="tr">GNU Oleo çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця GNU Oleo</comment>
<comment xml:lang="vi">Bảng tính Oleo của GNU</comment>
- <comment xml:lang="zh_CN">GNU Oleo 工作簿</comment>
+ <comment xml:lang="zh_CN">GNU Oleo 电子表格</comment>
<comment xml:lang="zh_TW">GNU Oleo 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<magic priority="50">
@@ -17258,7 +17843,7 @@
<comment xml:lang="pt">arquivo PAK</comment>
<comment xml:lang="pt_BR">Pacote PAK</comment>
<comment xml:lang="ro">Arhivă PAK</comment>
- <comment xml:lang="ru">архив PAK</comment>
+ <comment xml:lang="ru">Архив PAK</comment>
<comment xml:lang="sk">Archív PAK</comment>
<comment xml:lang="sl">Datoteka arhiva PAK</comment>
<comment xml:lang="sq">Arkiv PAK</comment>
@@ -17267,7 +17852,7 @@
<comment xml:lang="tr">PAK arşivi</comment>
<comment xml:lang="uk">архів PAK</comment>
<comment xml:lang="vi">Kho nén PAK</comment>
- <comment xml:lang="zh_CN">AR 归档文件</comment>
+ <comment xml:lang="zh_CN">PAK 归档文件</comment>
<comment xml:lang="zh_TW">PAK 封存檔</comment>
<generic-icon name="package-x-generic"/>
<magic priority="80">
@@ -17316,7 +17901,7 @@
<comment xml:lang="pt">base de dados Palm OS</comment>
<comment xml:lang="pt_BR">Banco de dados do Palm OS</comment>
<comment xml:lang="ro">Bază de date Palm OS</comment>
- <comment xml:lang="ru">база данных Palm OS</comment>
+ <comment xml:lang="ru">База данных Palm OS</comment>
<comment xml:lang="sk">Databáza Palm OS</comment>
<comment xml:lang="sl">Podatkovna zbirka Palm OS</comment>
<comment xml:lang="sq">Bankë me të dhëna Palm OS</comment>
@@ -17370,7 +17955,7 @@
<comment xml:lang="pt">arquivo Parchive</comment>
<comment xml:lang="pt_BR">Pacote Parchive</comment>
<comment xml:lang="ro">Arhivă Parchive</comment>
- <comment xml:lang="ru">архив Parchive</comment>
+ <comment xml:lang="ru">Архив Parchive</comment>
<comment xml:lang="sk">Archív Parchive</comment>
<comment xml:lang="sl">Datoteka arhiva Parchive</comment>
<comment xml:lang="sq">Arkiv Parchive</comment>
@@ -17429,7 +18014,7 @@
<comment xml:lang="pt">executável PEF</comment>
<comment xml:lang="pt_BR">Executável PEF</comment>
<comment xml:lang="ro">Executabil PEF</comment>
- <comment xml:lang="ru">исполняемый файл PEF</comment>
+ <comment xml:lang="ru">Исполняемый файл PEF</comment>
<comment xml:lang="sk">Spustiteľný súbor PEF</comment>
<comment xml:lang="sl">Izvedljiva datoteka PEF</comment>
<comment xml:lang="sq">E ekzekutueshme PEF</comment>
@@ -17485,7 +18070,7 @@
<comment xml:lang="pt">script Perl</comment>
<comment xml:lang="pt_BR">Script Perl</comment>
<comment xml:lang="ro">Script Perl</comment>
- <comment xml:lang="ru">сценарий Perl</comment>
+ <comment xml:lang="ru">Сценарий Perl</comment>
<comment xml:lang="sk">Skript jazyka Perl</comment>
<comment xml:lang="sl">Skriptna datoteka Perl</comment>
<comment xml:lang="sq">Script Perl</comment>
@@ -17499,6 +18084,7 @@
<sub-class-of type="application/x-executable"/>
<sub-class-of type="text/plain"/>
<generic-icon name="text-x-script"/>
+ <alias type="text/x-perl"/>
<magic priority="50">
<match value='eval \"exec /usr/local/bin/perl' type="string" offset="0"/>
<match value="/bin/perl" type="string" offset="2:16"/>
@@ -17563,7 +18149,7 @@
<comment xml:lang="pt">script PHP</comment>
<comment xml:lang="pt_BR">Script PHP</comment>
<comment xml:lang="ro">Script PHP</comment>
- <comment xml:lang="ru">сценарий PHP</comment>
+ <comment xml:lang="ru">Сценарий PHP</comment>
<comment xml:lang="sk">Skript PHP</comment>
<comment xml:lang="sl">Skriptna datoteka PHP</comment>
<comment xml:lang="sq">Script PHP</comment>
@@ -17600,7 +18186,7 @@
<comment xml:lang="fi">PKCS#7-varmennenippu</comment>
<comment xml:lang="fo">PKCS#7 váttanar bundi</comment>
<comment xml:lang="fr">lot de certificats PKCS#7</comment>
- <comment xml:lang="ga">cuach theastas PKCS#7</comment>
+ <comment xml:lang="ga">burla teastas PKCS#7</comment>
<comment xml:lang="gl">paquete de certificado PKCS#7</comment>
<comment xml:lang="he">בקשה מוסמכת PKCS#7</comment>
<comment xml:lang="hr">PKCS#7 paket vjerodajnica</comment>
@@ -17619,7 +18205,7 @@
<comment xml:lang="pt">pacote de certificação PKCS#7</comment>
<comment xml:lang="pt_BR">Pacote de certificados PKCS#7</comment>
<comment xml:lang="ro">Pachet certificat PKCS#7</comment>
- <comment xml:lang="ru">пакет сертификатов PKCS#7</comment>
+ <comment xml:lang="ru">Пакет сертификата PKCS#7</comment>
<comment xml:lang="sk">Zväzok certifikátov PKCS#7</comment>
<comment xml:lang="sl">Datoteka potrdila PKCS#7</comment>
<comment xml:lang="sr">ПКЦС#7 пакет уверења</comment>
@@ -17651,7 +18237,7 @@
<comment xml:lang="fi">PKCS#12-varmennenippu</comment>
<comment xml:lang="fo">PKCS#12 váttanar bundi</comment>
<comment xml:lang="fr">lot de certificats PKCS#12</comment>
- <comment xml:lang="ga">cuach theastas PKCS#12</comment>
+ <comment xml:lang="ga">burla teastas PKCS#12</comment>
<comment xml:lang="gl">paquete de certificado PKCS#12</comment>
<comment xml:lang="he">בקשה מוסמכת PKCS#12</comment>
<comment xml:lang="hr">PKCS#12 paket vjerodajnica</comment>
@@ -17673,7 +18259,7 @@
<comment xml:lang="pt">pacote de certificação PKCS#12</comment>
<comment xml:lang="pt_BR">Pacote de certificados PKCS#12</comment>
<comment xml:lang="ro">Certificat împachetat PKCS#12</comment>
- <comment xml:lang="ru">пакет сертификатов PKCS#12</comment>
+ <comment xml:lang="ru">Пакет сертификата PKCS#12</comment>
<comment xml:lang="sk">Zväzok certifikátov PKCS#12</comment>
<comment xml:lang="sl">Datoteka potrdila PKCS#12</comment>
<comment xml:lang="sq">Bundle çertifikate PKCS#12</comment>
@@ -17727,7 +18313,7 @@
<comment xml:lang="pt">folha de cálculo PlanPerfect</comment>
<comment xml:lang="pt_BR">Planilha do PlanPerfect</comment>
<comment xml:lang="ro">Foaie de calcul PlanPerfect</comment>
- <comment xml:lang="ru">электронная таблица PlanPerfect</comment>
+ <comment xml:lang="ru">Электронная таблица PlanPerfect</comment>
<comment xml:lang="sk">Zošit PlanPerfect</comment>
<comment xml:lang="sl">Preglednica PlanPerfect</comment>
<comment xml:lang="sq">Fletë llogaritjesh PlanPerfect</comment>
@@ -17736,7 +18322,7 @@
<comment xml:lang="tr">PlanPerfect çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця PlanPerfect</comment>
<comment xml:lang="vi">Bảng tính PlanPerfect</comment>
- <comment xml:lang="zh_CN">PlanPerfect 工作簿</comment>
+ <comment xml:lang="zh_CN">PlanPerfect 电子表格</comment>
<comment xml:lang="zh_TW">PlanPerfect 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<glob pattern="*.pln"/>
@@ -17744,6 +18330,7 @@
<mime-type type="application/x-pocket-word">
<comment>Pocket Word document</comment>
<comment xml:lang="ar">مستند Pocket Word</comment>
+ <comment xml:lang="ast">Documentu de PocketWord</comment>
<comment xml:lang="bg">Документ — Pocket Word</comment>
<comment xml:lang="ca">document de Pocket Word</comment>
<comment xml:lang="cs">dokument Pocket Word</comment>
@@ -17775,7 +18362,7 @@
<comment xml:lang="pt">documento Pocket Word</comment>
<comment xml:lang="pt_BR">Documento do Pocket Word</comment>
<comment xml:lang="ro">Document Pocket Word</comment>
- <comment xml:lang="ru">документ Pocket Word</comment>
+ <comment xml:lang="ru">Документ Pocket Word</comment>
<comment xml:lang="sk">Dokument Pocket Word</comment>
<comment xml:lang="sl">Dokument Pocket Word</comment>
<comment xml:lang="sr">документ Покет Ворда</comment>
@@ -17831,7 +18418,7 @@
<comment xml:lang="pt">resultados de análise de perfil</comment>
<comment xml:lang="pt_BR">Resultados do profiler</comment>
<comment xml:lang="ro">rezultate profiler</comment>
- <comment xml:lang="ru">результаты профилирования</comment>
+ <comment xml:lang="ru">Результаты профилирования</comment>
<comment xml:lang="sk">Výsledky profilera</comment>
<comment xml:lang="sl">rezultati profilirnika</comment>
<comment xml:lang="sq">Rezultate të profiluesit</comment>
@@ -17840,7 +18427,7 @@
<comment xml:lang="tr">profil sonuçları</comment>
<comment xml:lang="uk">результати профілювання</comment>
<comment xml:lang="vi">kết quả nét hiện trạng</comment>
- <comment xml:lang="zh_CN">profiler 结果</comment>
+ <comment xml:lang="zh_CN">探查器结果</comment>
<comment xml:lang="zh_TW">硬體資訊產生器成果</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text-x-generic"/>
@@ -17849,6 +18436,7 @@
<mime-type type="application/x-pw">
<comment>Pathetic Writer document</comment>
<comment xml:lang="ar">مستند Pathetic Writer</comment>
+ <comment xml:lang="ast">Documentu de Pathetic Writer</comment>
<comment xml:lang="be@latin">Dakument Pathetic Writer</comment>
<comment xml:lang="bg">Документ — Pathetic Writer</comment>
<comment xml:lang="ca">document de Pathetic Writer</comment>
@@ -17885,7 +18473,7 @@
<comment xml:lang="pt">documento do Pathetic Writer</comment>
<comment xml:lang="pt_BR">Documento do Pathetic Writer</comment>
<comment xml:lang="ro">Document Pathetic Writer</comment>
- <comment xml:lang="ru">документ Pathetic Writer</comment>
+ <comment xml:lang="ru">Документ Pathetic Writer</comment>
<comment xml:lang="sk">Dokument Pathetic Writer</comment>
<comment xml:lang="sl">Dokument Pathetic Writer</comment>
<comment xml:lang="sq">Dokument Pathetic Writer</comment>
@@ -17940,7 +18528,7 @@
<comment xml:lang="pt">código binário Python</comment>
<comment xml:lang="pt_BR">Código compilado Python</comment>
<comment xml:lang="ro">Bytecode Python</comment>
- <comment xml:lang="ru">байт-код Python</comment>
+ <comment xml:lang="ru">Байт-код Python</comment>
<comment xml:lang="sk">Bajtový kód Python</comment>
<comment xml:lang="sl">Datoteka bitne kode Python</comment>
<comment xml:lang="sq">Bytecode Python</comment>
@@ -17959,6 +18547,7 @@
</mime-type>
<mime-type type="application/x-qtiplot">
<comment>QtiPlot document</comment>
+ <comment xml:lang="ast">Documentu de QtiPlot</comment>
<comment xml:lang="ca">document QtiPlot</comment>
<comment xml:lang="cs">dokument GtiPlot</comment>
<comment xml:lang="da">QtiPlot-dokument</comment>
@@ -17969,6 +18558,7 @@
<comment xml:lang="eu">QtiPlot dokumentua</comment>
<comment xml:lang="fi">QtiPlot-asiakirja</comment>
<comment xml:lang="fr">document QtiPlot</comment>
+ <comment xml:lang="ga">cáipéis QtiPlot</comment>
<comment xml:lang="gl">Documento de QtiPilot</comment>
<comment xml:lang="he">מסמך QtiPlot</comment>
<comment xml:lang="hr">QtiPlot dokument</comment>
@@ -17984,7 +18574,7 @@
<comment xml:lang="pl">Dokument QtiPlot</comment>
<comment xml:lang="pt">documento QtiPlot</comment>
<comment xml:lang="pt_BR">Documento do QtiPlot</comment>
- <comment xml:lang="ru">документ QtiPlot</comment>
+ <comment xml:lang="ru">Документ QtiPlot</comment>
<comment xml:lang="sk">Dokument QtiPlot</comment>
<comment xml:lang="sl">Dokument QtiPlot</comment>
<comment xml:lang="sr">КутиПлот документ</comment>
@@ -18040,7 +18630,7 @@
<comment xml:lang="pt">folha de cálculo Quattro Pro</comment>
<comment xml:lang="pt_BR">Planilha do Quattro Pro</comment>
<comment xml:lang="ro">Foaie de calcul Quattro Pro</comment>
- <comment xml:lang="ru">электронная таблица Quattro Pro</comment>
+ <comment xml:lang="ru">Электронная таблица Quattro Pro</comment>
<comment xml:lang="sk">Zošit Quattro Pro</comment>
<comment xml:lang="sl">Preglednica Quattro Pro</comment>
<comment xml:lang="sq">Fletë llogaritjesh Quattro Pro</comment>
@@ -18049,7 +18639,7 @@
<comment xml:lang="tr">Quattro Pro çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця Quattro Pro</comment>
<comment xml:lang="vi">Bảng tính Quattro Pro</comment>
- <comment xml:lang="zh_CN">Quattro Pro 工作簿</comment>
+ <comment xml:lang="zh_CN">Quattro Pro 电子表格</comment>
<comment xml:lang="zh_TW">Quattro Pro 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<glob pattern="*.wb1"/>
@@ -18093,7 +18683,7 @@
<comment xml:lang="pt">lista de reprodução QuickTime metalink</comment>
<comment xml:lang="pt_BR">Lista de reprodução metalink do QuickTime</comment>
<comment xml:lang="ro">Listă cu metalegături QuickTime</comment>
- <comment xml:lang="ru">список воспроизведения мета-ссылок QuickTime</comment>
+ <comment xml:lang="ru">Список воспроизведения мета-ссылок QuickTime</comment>
<comment xml:lang="sk">Zoznam skladieb metalink QuickTime</comment>
<comment xml:lang="sl">Seznam predvajanja QuickTime</comment>
<comment xml:lang="sq">Listë titujsh metalink QuickTime</comment>
@@ -18102,7 +18692,7 @@
<comment xml:lang="tr">QuickTime metalink çalma listesi</comment>
<comment xml:lang="uk">список відтворення QuickTime metalink</comment>
<comment xml:lang="vi">Danh mục nhạc siêu liên kết Quicktime</comment>
- <comment xml:lang="zh_CN">QuickTime 元链接播放列表</comment>
+ <comment xml:lang="zh_CN">QuickTime Metalink 播放列表</comment>
<comment xml:lang="zh_TW">QuickTime metalink 播放清單</comment>
<generic-icon name="video-x-generic"/>
<sub-class-of type="video/quicktime"/>
@@ -18120,6 +18710,7 @@
<mime-type type="application/x-qw">
<comment>Quicken document</comment>
<comment xml:lang="ar">مستند Quicken</comment>
+ <comment xml:lang="ast">Documentu de Quicken</comment>
<comment xml:lang="az">Quicken sənədi</comment>
<comment xml:lang="be@latin">Dakument Quicken</comment>
<comment xml:lang="bg">Документ — Quicken</comment>
@@ -18158,7 +18749,7 @@
<comment xml:lang="pt">documento Quicken</comment>
<comment xml:lang="pt_BR">Documento do Quicken</comment>
<comment xml:lang="ro">Document Quicken</comment>
- <comment xml:lang="ru">документ Quicken</comment>
+ <comment xml:lang="ru">Документ Quicken</comment>
<comment xml:lang="sk">Dokument Quicken</comment>
<comment xml:lang="sl">Dokument Quicken</comment>
<comment xml:lang="sq">Dokument Quicken</comment>
@@ -18212,7 +18803,7 @@
<comment xml:lang="pt">arquivo RAR</comment>
<comment xml:lang="pt_BR">Pacote RAR</comment>
<comment xml:lang="ro">Arhivă RAR</comment>
- <comment xml:lang="ru">архив RAR</comment>
+ <comment xml:lang="ru">Архив RAR</comment>
<comment xml:lang="sk">Archív RAR</comment>
<comment xml:lang="sl">Datoteka arhiva RAR</comment>
<comment xml:lang="sq">Arkiv RAR</comment>
@@ -18272,7 +18863,7 @@
<comment xml:lang="pt">arquivo DAR</comment>
<comment xml:lang="pt_BR">Pacote DAR</comment>
<comment xml:lang="ro">Arhivă DAR</comment>
- <comment xml:lang="ru">архив DAR</comment>
+ <comment xml:lang="ru">Архив DAR</comment>
<comment xml:lang="sk">Archív DAR</comment>
<comment xml:lang="sl">Datoteka arhiva DAR</comment>
<comment xml:lang="sq">Arkiv DAR</comment>
@@ -18328,7 +18919,7 @@
<comment xml:lang="pt">arquivo Alzip</comment>
<comment xml:lang="pt_BR">Pacote Alzip</comment>
<comment xml:lang="ro">Arhivă Alzip</comment>
- <comment xml:lang="ru">архив ALZIP</comment>
+ <comment xml:lang="ru">Архив ALZIP</comment>
<comment xml:lang="sk">Archív Alzip</comment>
<comment xml:lang="sl">Datoteka arhiva Alzip</comment>
<comment xml:lang="sq">Arkiv Alzip</comment>
@@ -18358,14 +18949,14 @@
<comment xml:lang="en_GB">rejected patch</comment>
<comment xml:lang="eo">reĵeta flikaĵo</comment>
<comment xml:lang="es">parche rechazado</comment>
- <comment xml:lang="eu">baztertutako bide-izena</comment>
+ <comment xml:lang="eu">baztertutako adabakia</comment>
<comment xml:lang="fi">hylättyjen muutosten tiedosto</comment>
<comment xml:lang="fo">vrakað rætting</comment>
<comment xml:lang="fr">correctif rejeté</comment>
<comment xml:lang="ga">paiste diúltaithe</comment>
<comment xml:lang="gl">parche rexeitado</comment>
<comment xml:lang="he">טלאי שנדחה</comment>
- <comment xml:lang="hr">odbijena zakrpa</comment>
+ <comment xml:lang="hr">Odbijena zakrpa</comment>
<comment xml:lang="hu">visszautasított folt</comment>
<comment xml:lang="ia">Patch rejectate</comment>
<comment xml:lang="id">patch ditolak</comment>
@@ -18384,7 +18975,7 @@
<comment xml:lang="pt">patch rejeitado</comment>
<comment xml:lang="pt_BR">Arquivo de patch rejeitado</comment>
<comment xml:lang="ro">petec respsins</comment>
- <comment xml:lang="ru">отвергнутый патч</comment>
+ <comment xml:lang="ru">Отклонённый патч</comment>
<comment xml:lang="sk">Odmietnutá záplata</comment>
<comment xml:lang="sl">zavrnjen popravek</comment>
<comment xml:lang="sq">Patch i kthyer mbrapsht</comment>
@@ -18439,7 +19030,7 @@
<comment xml:lang="pt">pacote RPM</comment>
<comment xml:lang="pt_BR">Pacote RPM</comment>
<comment xml:lang="ro">Pachet RPM</comment>
- <comment xml:lang="ru">пакет RPM</comment>
+ <comment xml:lang="ru">Пакет RPM</comment>
<comment xml:lang="sk">Balík RPM</comment>
<comment xml:lang="sl">Datoteka paketa RPM</comment>
<comment xml:lang="sq">Paketë RPM</comment>
@@ -18469,6 +19060,7 @@
<comment xml:lang="eu">Iturburu RPM paketea</comment>
<comment xml:lang="fi">RPM-lähdepaketti</comment>
<comment xml:lang="fr">paquet source RPM</comment>
+ <comment xml:lang="ga">pacáiste foinse RPM</comment>
<comment xml:lang="gl">Paquete RPM de fontes</comment>
<comment xml:lang="he">חבילת מקור RPM</comment>
<comment xml:lang="hr">RPM paket izvora</comment>
@@ -18484,7 +19076,7 @@
<comment xml:lang="pl">Źródłowy pakiet RPM</comment>
<comment xml:lang="pt">pacote origem RPM</comment>
<comment xml:lang="pt_BR">Pacote fonte RPM</comment>
- <comment xml:lang="ru">пакет RPM с исходным кодом</comment>
+ <comment xml:lang="ru">Пакет RPM с исходным кодом</comment>
<comment xml:lang="sk">Zdrojový balík RPM</comment>
<comment xml:lang="sl">Paket izvorne kode RPM</comment>
<comment xml:lang="sr">изворни РПМ пакет</comment>
@@ -18537,7 +19129,7 @@
<comment xml:lang="pt">script Ruby</comment>
<comment xml:lang="pt_BR">Script Ruby</comment>
<comment xml:lang="ro">Script Ruby</comment>
- <comment xml:lang="ru">сценарий Ruby</comment>
+ <comment xml:lang="ru">Сценарий Ruby</comment>
<comment xml:lang="sk">Skript Ruby</comment>
<comment xml:lang="sl">Skriptna datoteka Ruby</comment>
<comment xml:lang="sq">Script Ruby</comment>
@@ -18596,7 +19188,7 @@
<comment xml:lang="pt">script Markaby</comment>
<comment xml:lang="pt_BR">Script Markaby</comment>
<comment xml:lang="ro">Script Markaby</comment>
- <comment xml:lang="ru">сценарий Markaby</comment>
+ <comment xml:lang="ru">Сценарий Markaby</comment>
<comment xml:lang="sk">Skript Markaby</comment>
<comment xml:lang="sl">Skriptna datoteka Markaby</comment>
<comment xml:lang="sq">Script Markaby</comment>
@@ -18623,6 +19215,7 @@
<comment xml:lang="eu">Rust iturburu-kodea</comment>
<comment xml:lang="fi">Rust-lähdekoodi</comment>
<comment xml:lang="fr">code source Rust</comment>
+ <comment xml:lang="ga">cód foinseach Rust</comment>
<comment xml:lang="he">קוד מקור של Rust</comment>
<comment xml:lang="hr">Rust izvorni kôd</comment>
<comment xml:lang="hu">Rust forrásfájl</comment>
@@ -18635,7 +19228,7 @@
<comment xml:lang="pl">Kod źródłowy Rust</comment>
<comment xml:lang="pt">código origem Rust</comment>
<comment xml:lang="pt_BR">Código-fonte Rust</comment>
- <comment xml:lang="ru">исходный код Rust</comment>
+ <comment xml:lang="ru">Исходный код Rust</comment>
<comment xml:lang="sk">Zdrojový kód Rust</comment>
<comment xml:lang="sr">Раст изворни ко̂д</comment>
<comment xml:lang="sv">Rust-källkod</comment>
@@ -18684,7 +19277,7 @@
<comment xml:lang="pt">folha de cálculo SC/Xspread</comment>
<comment xml:lang="pt_BR">Planilha do SC/Xspread</comment>
<comment xml:lang="ro">Foaie de calcul SC/Xspread</comment>
- <comment xml:lang="ru">электронная таблица SC/Xspread</comment>
+ <comment xml:lang="ru">Электронная таблица SC/Xspread</comment>
<comment xml:lang="sk">Zošit SC/Xspread</comment>
<comment xml:lang="sl">Preglednica SC/Xspread</comment>
<comment xml:lang="sq">Fletë llogaritjesh SC/Xspread</comment>
@@ -18693,7 +19286,7 @@
<comment xml:lang="tr">SC/Xspread çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця SC/Xspread</comment>
<comment xml:lang="vi">Bảng tính SC/Xspread</comment>
- <comment xml:lang="zh_CN">SC/Xspread 工作簿</comment>
+ <comment xml:lang="zh_CN">SC/Xspread 电子表格</comment>
<comment xml:lang="zh_TW">SC/Xspread 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<magic priority="50">
@@ -18722,7 +19315,7 @@
<comment xml:lang="ga">cartlann bhlaoisce</comment>
<comment xml:lang="gl">ficheiro shell</comment>
<comment xml:lang="he">ארכיון מעטפת</comment>
- <comment xml:lang="hr">arhiva ljuske</comment>
+ <comment xml:lang="hr">Arhiva ljuske</comment>
<comment xml:lang="hu">héjarchívum</comment>
<comment xml:lang="ia">Archivo de shell</comment>
<comment xml:lang="id">arsip shell</comment>
@@ -18741,7 +19334,7 @@
<comment xml:lang="pt">arquivo de terminal</comment>
<comment xml:lang="pt_BR">Pacote shell</comment>
<comment xml:lang="ro">arhivă shell</comment>
- <comment xml:lang="ru">архив оболочки UNIX</comment>
+ <comment xml:lang="ru">Архив shell</comment>
<comment xml:lang="sk">Archív shellu</comment>
<comment xml:lang="sl">lupinski arhiv</comment>
<comment xml:lang="sq">Arkiv shell</comment>
@@ -18792,7 +19385,7 @@
<comment xml:lang="pt">biblioteca partilhada libtool</comment>
<comment xml:lang="pt_BR">Biblioteca compartilhada libtool</comment>
<comment xml:lang="ro">bibliotecă partajată libtool</comment>
- <comment xml:lang="ru">разделяемая библиотека libtool</comment>
+ <comment xml:lang="ru">Разделяемая библиотека libtool</comment>
<comment xml:lang="sk">Zdieľaná knižnica libtool</comment>
<comment xml:lang="sl">Souporabna knjižnica libtool</comment>
<comment xml:lang="sq">Librari e përbashkët libtool</comment>
@@ -18848,7 +19441,7 @@
<comment xml:lang="pt">biblioteca partilhada</comment>
<comment xml:lang="pt_BR">Biblioteca compartilhada</comment>
<comment xml:lang="ro">bibliotecă partajată</comment>
- <comment xml:lang="ru">разделяемая библиотека</comment>
+ <comment xml:lang="ru">Разделяемая библиотека</comment>
<comment xml:lang="sk">Zdieľaná knižnica</comment>
<comment xml:lang="sl">souporabljena knjižnica</comment>
<comment xml:lang="sq">Librari e përbashkët</comment>
@@ -18883,7 +19476,7 @@
<comment xml:lang="az">qabıq skripti</comment>
<comment xml:lang="be@latin">skrypt abałonki</comment>
<comment xml:lang="bg">Скрипт на обвивката</comment>
- <comment xml:lang="ca">script de shell</comment>
+ <comment xml:lang="ca">script shell</comment>
<comment xml:lang="cs">skript shellu</comment>
<comment xml:lang="cy">sgript plisgyn</comment>
<comment xml:lang="da">skalprogram</comment>
@@ -18899,7 +19492,7 @@
<comment xml:lang="ga">script bhlaoisce</comment>
<comment xml:lang="gl">script de shell</comment>
<comment xml:lang="he">תסריט מעטפת</comment>
- <comment xml:lang="hr">skripta ljuske</comment>
+ <comment xml:lang="hr">Skripta ljuske</comment>
<comment xml:lang="hu">héj-parancsfájl</comment>
<comment xml:lang="ia">Script de shell</comment>
<comment xml:lang="id">skrip shell</comment>
@@ -18918,7 +19511,7 @@
<comment xml:lang="pt">script de terminal</comment>
<comment xml:lang="pt_BR">Script shell</comment>
<comment xml:lang="ro">script shell</comment>
- <comment xml:lang="ru">сценарий оболочки UNIX</comment>
+ <comment xml:lang="ru">Сценарий shell</comment>
<comment xml:lang="sk">Skript shellu</comment>
<comment xml:lang="sl">lupinski skript</comment>
<comment xml:lang="sq">Script shell</comment>
@@ -18987,7 +19580,7 @@
<comment xml:lang="pt">ficheiro Shockwave Flash</comment>
<comment xml:lang="pt_BR">Arquivo Shockwave Flash</comment>
<comment xml:lang="ro">Fișier Shockwave Flash</comment>
- <comment xml:lang="ru">файл Shockwave Flash</comment>
+ <comment xml:lang="ru">Файл Shockwave Flash</comment>
<comment xml:lang="sk">Súbor Shockwave Flash</comment>
<comment xml:lang="sl">Datoteka Shockwave Flash</comment>
<comment xml:lang="sq">File Flash Shockwave</comment>
@@ -19029,7 +19622,7 @@
<comment xml:lang="ga">fuaim Shorten</comment>
<comment xml:lang="gl">son Shorten</comment>
<comment xml:lang="he">שמע של Shorten</comment>
- <comment xml:lang="hr">Shorten audio</comment>
+ <comment xml:lang="hr">Shorten zvučni zapis</comment>
<comment xml:lang="hu">Shorten hang</comment>
<comment xml:lang="ia">Audio Shorten</comment>
<comment xml:lang="id">Audio Shorten</comment>
@@ -19047,7 +19640,7 @@
<comment xml:lang="pt">áudio Shorten</comment>
<comment xml:lang="pt_BR">Áudio Shorten</comment>
<comment xml:lang="ro">Audio Shorten</comment>
- <comment xml:lang="ru">аудио Shorten</comment>
+ <comment xml:lang="ru">Аудио Shorten</comment>
<comment xml:lang="sk">Zvuk Shorten</comment>
<comment xml:lang="sl">Zvočna datoteka Shorten</comment>
<comment xml:lang="sq">Audio Shorten</comment>
@@ -19104,7 +19697,7 @@
<comment xml:lang="pt">folha de cálculo Siag</comment>
<comment xml:lang="pt_BR">Planilha do Siag</comment>
<comment xml:lang="ro">Foaie de calcul Siag</comment>
- <comment xml:lang="ru">электронная таблица Siag</comment>
+ <comment xml:lang="ru">Электронная таблица Siag</comment>
<comment xml:lang="sk">Zošit Siag</comment>
<comment xml:lang="sl">Preglednica Siag</comment>
<comment xml:lang="sq">Fletë llogaritjesh Siag</comment>
@@ -19113,7 +19706,7 @@
<comment xml:lang="tr">Siag çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця Siag</comment>
<comment xml:lang="vi">Bảng tính Slag</comment>
- <comment xml:lang="zh_CN">Siag 工作簿</comment>
+ <comment xml:lang="zh_CN">Siag 电子表格</comment>
<comment xml:lang="zh_TW">Siag 試算表</comment>
<generic-icon name="x-office-spreadsheet"/>
<glob pattern="*.siag"/>
@@ -19121,6 +19714,7 @@
<mime-type type="image/x-skencil">
<comment>Skencil document</comment>
<comment xml:lang="ar">مستند Skencil</comment>
+ <comment xml:lang="ast">Documentu de Skencil</comment>
<comment xml:lang="be@latin">Dakument Skencil</comment>
<comment xml:lang="bg">Документ — Skencil</comment>
<comment xml:lang="ca">document Skencil</comment>
@@ -19155,7 +19749,7 @@
<comment xml:lang="pt">documento Skencil</comment>
<comment xml:lang="pt_BR">Documento do Skencil</comment>
<comment xml:lang="ro">Document Skencil</comment>
- <comment xml:lang="ru">документ Skencil</comment>
+ <comment xml:lang="ru">Документ Skencil</comment>
<comment xml:lang="sk">Dokument Skencil</comment>
<comment xml:lang="sl">Dokument Skencil</comment>
<comment xml:lang="sq">Dokument Skencil</comment>
@@ -19213,7 +19807,7 @@
<comment xml:lang="pt">pacote Stampede</comment>
<comment xml:lang="pt_BR">Pacote Stampede</comment>
<comment xml:lang="ro">Pachet Stampede</comment>
- <comment xml:lang="ru">пакет Stampede</comment>
+ <comment xml:lang="ru">Пакет Stampede</comment>
<comment xml:lang="sk">Balíček Stampede</comment>
<comment xml:lang="sl">Datoteka paketa Stampede</comment>
<comment xml:lang="sq">Paketë Stampede</comment>
@@ -19229,18 +19823,28 @@
<mime-type type="application/x-sg1000-rom">
<comment>SG-1000 ROM</comment>
<comment xml:lang="ca">ROM de SG-1000</comment>
+ <comment xml:lang="cs">ROM pro SG-1000</comment>
<comment xml:lang="da">SG-1000 ROM</comment>
<comment xml:lang="de">SG-1000 ROM</comment>
+ <comment xml:lang="en_GB">SG-1000 ROM</comment>
<comment xml:lang="es">ROM de SG-1000</comment>
+ <comment xml:lang="eu">SG-1000 ROM</comment>
<comment xml:lang="fi">SG-1000 -ROM</comment>
<comment xml:lang="fr">ROM SG-1000</comment>
+ <comment xml:lang="ga">ROM SG-1000</comment>
+ <comment xml:lang="hr">SG-1000 ROM</comment>
<comment xml:lang="hu">SG-1000 ROM</comment>
+ <comment xml:lang="id">ROM SG-1000</comment>
+ <comment xml:lang="it">ROM SG-1000</comment>
<comment xml:lang="kk">SG-1000 ROM</comment>
<comment xml:lang="ko">SG-1000 롬</comment>
<comment xml:lang="pl">Plik ROM konsoli SG-1000</comment>
<comment xml:lang="pt_BR">ROM de SG-1000</comment>
<comment xml:lang="ru">SG-1000 ROM</comment>
<comment xml:lang="sk">ROM pre SG-1000</comment>
+ <comment xml:lang="sr">СГ-1000 РОМ</comment>
+ <comment xml:lang="sv">SG-1000-rom</comment>
+ <comment xml:lang="tr">SG-1000 ROM</comment>
<comment xml:lang="uk">ППП SG-1000</comment>
<comment xml:lang="zh_CN">SG-1000 ROM</comment>
<comment xml:lang="zh_TW">SG-1000 ROM</comment>
@@ -19251,18 +19855,28 @@
<comment>Master System ROM</comment>
<comment xml:lang="ca">ROM de Master System</comment>
+ <comment xml:lang="cs">ROM pro Master System</comment>
<comment xml:lang="da">Master System ROM</comment>
<comment xml:lang="de">Master System ROM</comment>
+ <comment xml:lang="en_GB">Master System ROM</comment>
<comment xml:lang="es">ROM de Master System</comment>
+ <comment xml:lang="eu">Master System ROM</comment>
<comment xml:lang="fi">Master System -ROM</comment>
<comment xml:lang="fr">ROM Master System</comment>
+ <comment xml:lang="ga">ROM Master System</comment>
+ <comment xml:lang="hr">Master System ROM</comment>
<comment xml:lang="hu">Master System ROM</comment>
+ <comment xml:lang="id">ROM Master System</comment>
+ <comment xml:lang="it">ROM Master System</comment>
<comment xml:lang="kk">Master System ROM</comment>
<comment xml:lang="ko">마스터 시스템 롬</comment>
<comment xml:lang="pl">Plik ROM konsoli SMS</comment>
<comment xml:lang="pt_BR">ROM de Master System</comment>
<comment xml:lang="ru">Master System ROM</comment>
<comment xml:lang="sk">ROM pre Master System</comment>
+ <comment xml:lang="sr">Мастер Систем РОМ</comment>
+ <comment xml:lang="sv">Master System-rom</comment>
+ <comment xml:lang="tr">Master System ROM</comment>
<comment xml:lang="uk">ППП Master System</comment>
<comment xml:lang="zh_CN">Master System ROM</comment>
<comment xml:lang="zh_TW">Master System ROM</comment>
@@ -19273,18 +19887,28 @@
<mime-type type="application/x-gamegear-rom">
<comment>Game Gear ROM</comment>
<comment xml:lang="ca">ROM de Game Gear</comment>
+ <comment xml:lang="cs">ROM pro Game Gear</comment>
<comment xml:lang="da">Game Gear ROM</comment>
<comment xml:lang="de">Game Gear ROM</comment>
+ <comment xml:lang="en_GB">Game Gear ROM</comment>
<comment xml:lang="es">ROM de Game Gear</comment>
+ <comment xml:lang="eu">Game Gear ROM</comment>
<comment xml:lang="fi">Game Gear -ROM</comment>
<comment xml:lang="fr">ROM Game Gear</comment>
+ <comment xml:lang="ga">ROM Game Gear</comment>
+ <comment xml:lang="hr">Game Gear ROM</comment>
<comment xml:lang="hu">Game Gear ROM</comment>
+ <comment xml:lang="id">ROM Game Gear</comment>
+ <comment xml:lang="it">ROM Game Gear</comment>
<comment xml:lang="kk">Game Gear ROM</comment>
<comment xml:lang="ko">게임 기어 롬</comment>
<comment xml:lang="pl">Plik ROM konsoli Game Gear</comment>
<comment xml:lang="pt_BR">ROM de Game Gear</comment>
<comment xml:lang="ru">Game Gear ROM</comment>
<comment xml:lang="sk">ROM pre Game Gear</comment>
+ <comment xml:lang="sr">Гејм Гир РОМ</comment>
+ <comment xml:lang="sv">Game Gear-rom</comment>
+ <comment xml:lang="tr">Game Gear ROM</comment>
<comment xml:lang="uk">ППП Game Gear</comment>
<comment xml:lang="zh_CN">Game Gear ROM</comment>
<comment xml:lang="zh_TW">Game Gear ROM</comment>
@@ -19328,7 +19952,7 @@
<comment xml:lang="oc">ROM Super Nintendo</comment>
<comment xml:lang="pl">Plik ROM konsoli SNES</comment>
<comment xml:lang="pt">ROM Super Nintendo</comment>
- <comment xml:lang="pt_BR">ROM do Super Nintendo</comment>
+ <comment xml:lang="pt_BR">ROM de Super Nintendo</comment>
<comment xml:lang="ro">ROM Super Nintendo</comment>
<comment xml:lang="ru">Super NES ROM</comment>
<comment xml:lang="sk">ROM pre Super Nintendo</comment>
@@ -19384,7 +20008,7 @@
<comment xml:lang="pt">arquivo StuffIt</comment>
<comment xml:lang="pt_BR">Pacote StuffIt</comment>
<comment xml:lang="ro">Arhivă StuffIt</comment>
- <comment xml:lang="ru">архив StuffIt</comment>
+ <comment xml:lang="ru">Архив StuffIt</comment>
<comment xml:lang="sk">Archív StuffIt</comment>
<comment xml:lang="sl">Datoteka arhiva StuffIt</comment>
<comment xml:lang="sq">Arkiv StuffIt</comment>
@@ -19424,7 +20048,7 @@
<comment xml:lang="ga">fotheidil SubRip</comment>
<comment xml:lang="gl">subtítulos SubRip</comment>
<comment xml:lang="he">כתוביות של SubRip</comment>
- <comment xml:lang="hr">SubRip titlovi</comment>
+ <comment xml:lang="hr">SubRip podnaslovi</comment>
<comment xml:lang="hu">SubRip feliratok</comment>
<comment xml:lang="ia">Subtitulos SubRip</comment>
<comment xml:lang="id">Subjudul SubRip</comment>
@@ -19442,7 +20066,7 @@
<comment xml:lang="pt">legendas SubRip</comment>
<comment xml:lang="pt_BR">Legendas SubRip</comment>
<comment xml:lang="ro">Subtitrare SubRip</comment>
- <comment xml:lang="ru">субтитры SubRip</comment>
+ <comment xml:lang="ru">Субтитры SubRip</comment>
<comment xml:lang="sk">Titulky SubRip</comment>
<comment xml:lang="sl">Datoteka podnapisov SubRip</comment>
<comment xml:lang="sq">Nëntituj SubRip</comment>
@@ -19476,12 +20100,13 @@
<comment xml:lang="eu">WebVTT azpitituluak</comment>
<comment xml:lang="fi">WebVTT-tekstitykset</comment>
<comment xml:lang="fr">sous-titres WebVTT</comment>
+ <comment xml:lang="ga">fotheidil WebVTT</comment>
<comment xml:lang="gl">subtítulos WebVTT</comment>
<comment xml:lang="he">כתוביות WebVTT</comment>
- <comment xml:lang="hr">WebVTT titlovi</comment>
+ <comment xml:lang="hr">WebVTT podnaslovi</comment>
<comment xml:lang="hu">WebVTT feliratok</comment>
<comment xml:lang="ia">Subtitulos WebVTT</comment>
- <comment xml:lang="id">Subtitel WebVTT</comment>
+ <comment xml:lang="id">Subjudul WebVTT</comment>
<comment xml:lang="it">Sottotitoli WebVTT</comment>
<comment xml:lang="ja">WebVTT サブタイトル</comment>
<comment xml:lang="ka">WebVTT ქვეტიტრები</comment>
@@ -19493,7 +20118,7 @@
<comment xml:lang="pl">Napisy WebVTT</comment>
<comment xml:lang="pt">legendas WebVTT</comment>
<comment xml:lang="pt_BR">Legendas WebVTT</comment>
- <comment xml:lang="ru">субтитры WebVTT</comment>
+ <comment xml:lang="ru">Субтитры WebVTT</comment>
<comment xml:lang="sk">Titulky WebVTT</comment>
<comment xml:lang="sl">Podnapisi WebVTT</comment>
<comment xml:lang="sr">Веб ВТТ преводи</comment>
@@ -19531,7 +20156,7 @@
<comment xml:lang="ga">fotheidil SAMI</comment>
<comment xml:lang="gl">subtítulos SAMI</comment>
<comment xml:lang="he">כתוביות SAMI</comment>
- <comment xml:lang="hr">SAMI titlovi</comment>
+ <comment xml:lang="hr">SAMI podnaslovi</comment>
<comment xml:lang="hu">SAMI feliratok</comment>
<comment xml:lang="ia">Subtitulos SAMI</comment>
<comment xml:lang="id">Subjudul SAMI</comment>
@@ -19549,7 +20174,7 @@
<comment xml:lang="pt">legendas SAMI</comment>
<comment xml:lang="pt_BR">Legendas SAMI</comment>
<comment xml:lang="ro">Subtitrări SAMI</comment>
- <comment xml:lang="ru">субтитры SAMI</comment>
+ <comment xml:lang="ru">Субтитры SAMI</comment>
<comment xml:lang="sk">Titulky SAMI</comment>
<comment xml:lang="sl">Datoteka podnapisov SAMI</comment>
<comment xml:lang="sq">Nëntituj SAMI</comment>
@@ -19590,7 +20215,7 @@
<comment xml:lang="ga">fotheidil MicroDVD</comment>
<comment xml:lang="gl">subtítulos de MicroDVD</comment>
<comment xml:lang="he">כתוביות של MicroDVD</comment>
- <comment xml:lang="hr">MicroDVD titlovi</comment>
+ <comment xml:lang="hr">MicroDVD podnaslovi</comment>
<comment xml:lang="hu">MicroDVD feliratok</comment>
<comment xml:lang="ia">Subtitulos MicroDVD</comment>
<comment xml:lang="id">Subjudul MicroDVD</comment>
@@ -19609,7 +20234,7 @@
<comment xml:lang="pt">legendas MicroDVD</comment>
<comment xml:lang="pt_BR">Legendas MicroDVD</comment>
<comment xml:lang="ro">Subtitrări MicroDVD</comment>
- <comment xml:lang="ru">субтитры MicroDVD</comment>
+ <comment xml:lang="ru">Субтитры MicroDVD</comment>
<comment xml:lang="sk">Titulky MicroDVD</comment>
<comment xml:lang="sl">Datoteka podnapisov MicroDVD</comment>
<comment xml:lang="sq">Nëntituj MicroDVD</comment>
@@ -19648,7 +20273,7 @@
<comment xml:lang="ga">fotheidil MPSub</comment>
<comment xml:lang="gl">subtítulos MPSub</comment>
<comment xml:lang="he">כתוביות MPSub</comment>
- <comment xml:lang="hr">MPSub titlovi</comment>
+ <comment xml:lang="hr">MPSub podnaslovi</comment>
<comment xml:lang="hu">MPSub feliratok</comment>
<comment xml:lang="ia">Subtitulos MPSub</comment>
<comment xml:lang="id">Subjudul MPSub</comment>
@@ -19667,7 +20292,7 @@
<comment xml:lang="pt">legendas MPSub</comment>
<comment xml:lang="pt_BR">Legendas MPSub</comment>
<comment xml:lang="ro">Subtitrări MPSub</comment>
- <comment xml:lang="ru">субтитры MPSub</comment>
+ <comment xml:lang="ru">Субтитры MPSub</comment>
<comment xml:lang="sk">Titulky MPSub</comment>
<comment xml:lang="sl">Datoteka podnapisov MPSub</comment>
<comment xml:lang="sq">Nëntituj MPSub</comment>
@@ -19706,7 +20331,7 @@
<comment xml:lang="ga">fotheidil SSA</comment>
<comment xml:lang="gl">Subtitulos SSA</comment>
<comment xml:lang="he">כתובית SSA</comment>
- <comment xml:lang="hr">SSA titlovi</comment>
+ <comment xml:lang="hr">SSA podnaslovi</comment>
<comment xml:lang="hu">SSA feliratok</comment>
<comment xml:lang="ia">Subtitulos SSA</comment>
<comment xml:lang="id">Subjudul SSA</comment>
@@ -19724,7 +20349,7 @@
<comment xml:lang="pt">legendas SSA</comment>
<comment xml:lang="pt_BR">Legendas SSA</comment>
<comment xml:lang="ro">Subtitrări SSA</comment>
- <comment xml:lang="ru">субтитры SSA</comment>
+ <comment xml:lang="ru">Субтитры SSA</comment>
<comment xml:lang="sk">Titulky SSA</comment>
<comment xml:lang="sl">Datoteka podnapisov SSA</comment>
<comment xml:lang="sq">Nëntituj SSA</comment>
@@ -19765,7 +20390,7 @@
<comment xml:lang="ga">fotheidil SubViewer</comment>
<comment xml:lang="gl">subtítulos SubViewer</comment>
<comment xml:lang="he">כתוביות של SubViewer</comment>
- <comment xml:lang="hr">SubViewer titlovi</comment>
+ <comment xml:lang="hr">SubViewer podnaslovi</comment>
<comment xml:lang="hu">SubViewer feliratok</comment>
<comment xml:lang="ia">Subtitulos SubViewer</comment>
<comment xml:lang="id">Subjudul SubViewer</comment>
@@ -19783,7 +20408,7 @@
<comment xml:lang="pt">legendas SubViewer</comment>
<comment xml:lang="pt_BR">Legendas SubViewer</comment>
<comment xml:lang="ro">Subtitrare SubViewer</comment>
- <comment xml:lang="ru">субтитры SubViewer</comment>
+ <comment xml:lang="ru">Субтитры SubViewer</comment>
<comment xml:lang="sk">Titulky SubViewer</comment>
<comment xml:lang="sl">Datoteka podnapisov SubViewer</comment>
<comment xml:lang="sq">Nëntituj SubViewer</comment>
@@ -19819,7 +20444,7 @@
<comment xml:lang="ga">ton buailte iMelody</comment>
<comment xml:lang="gl">Melodía de iMelody</comment>
<comment xml:lang="he">צלצול של iMelody</comment>
- <comment xml:lang="hr">iMelody ton zvonjenja</comment>
+ <comment xml:lang="hr">iMelody melodija zvona</comment>
<comment xml:lang="hu">iMelody csengőhang</comment>
<comment xml:lang="ia">Tono de appello iMelody</comment>
<comment xml:lang="id">nada dering iMelody</comment>
@@ -19837,7 +20462,7 @@
<comment xml:lang="pt">toque iMelody</comment>
<comment xml:lang="pt_BR">Toque de celular do iMelody</comment>
<comment xml:lang="ro">Sonerie iMelody</comment>
- <comment xml:lang="ru">мелодия iMelody</comment>
+ <comment xml:lang="ru">Мелодия iMelody</comment>
<comment xml:lang="sk">Vyzváňacie melódie iMelody</comment>
<comment xml:lang="sl">Zvonjenje iMelody</comment>
<comment xml:lang="sq">Zile iMelody</comment>
@@ -19876,7 +20501,7 @@
<comment xml:lang="ga">fuaim SMAF</comment>
<comment xml:lang="gl">son SMAF</comment>
<comment xml:lang="he">שמע SMAF</comment>
- <comment xml:lang="hr">SMAF audio</comment>
+ <comment xml:lang="hr">SMAF zvučni zapis</comment>
<comment xml:lang="hu">SMAF hang</comment>
<comment xml:lang="ia">Audio SMAF</comment>
<comment xml:lang="id">Audio SMAF</comment>
@@ -19894,7 +20519,7 @@
<comment xml:lang="pt">áudio SMAF</comment>
<comment xml:lang="pt_BR">Áudio SMAF</comment>
<comment xml:lang="ro">Audio SMAF</comment>
- <comment xml:lang="ru">аудио SMAF</comment>
+ <comment xml:lang="ru">Аудио SMAF</comment>
<comment xml:lang="sk">Zvuk SMAF</comment>
<comment xml:lang="sl">Zvočna datoteka SMAF</comment>
<comment xml:lang="sq">Audio SMAF</comment>
@@ -19935,7 +20560,7 @@
<comment xml:lang="ga">seinmliosta MRML</comment>
<comment xml:lang="gl">lista de reprodución MRML</comment>
<comment xml:lang="he">רשימת השמעה MRML</comment>
- <comment xml:lang="hr">MRML popis za reprodukciju</comment>
+ <comment xml:lang="hr">MRML popis izvođenja</comment>
<comment xml:lang="hu">MRML-lejátszólista</comment>
<comment xml:lang="ia">Lista de selection MRML</comment>
<comment xml:lang="id">Senarai putar MRML</comment>
@@ -19954,7 +20579,7 @@
<comment xml:lang="pt">lista de reprodução MRML</comment>
<comment xml:lang="pt_BR">Lista de reprodução do MRML</comment>
<comment xml:lang="ro">Listă redare MRML</comment>
- <comment xml:lang="ru">список воспроизведения MRML</comment>
+ <comment xml:lang="ru">Список воспроизведения MRML</comment>
<comment xml:lang="sk">Zoznam skladieb MRML</comment>
<comment xml:lang="sl">Seznam predvajanja MRML</comment>
<comment xml:lang="sq">Listë titujsh MRML</comment>
@@ -19993,7 +20618,7 @@
<comment xml:lang="ga">fuaim XMF</comment>
<comment xml:lang="gl">son XMF</comment>
<comment xml:lang="he">שמע XMF</comment>
- <comment xml:lang="hr">XMF audio</comment>
+ <comment xml:lang="hr">XMF zvučni zapis</comment>
<comment xml:lang="hu">XMF hang</comment>
<comment xml:lang="ia">Audio XMF</comment>
<comment xml:lang="id">Audio XMF</comment>
@@ -20011,7 +20636,7 @@
<comment xml:lang="pt">aúdio XMF</comment>
<comment xml:lang="pt_BR">Áudio XMF</comment>
<comment xml:lang="ro">Audio XMF</comment>
- <comment xml:lang="ru">аудио XMF</comment>
+ <comment xml:lang="ru">Аудио XMF</comment>
<comment xml:lang="sk">Zvuk XMF</comment>
<comment xml:lang="sl">Zvočna datoteka XMF</comment>
<comment xml:lang="sq">Audio XMF</comment>
@@ -20073,7 +20698,7 @@
<comment xml:lang="pt">arquivo SV4 CPIO</comment>
<comment xml:lang="pt_BR">Pacote SV4 CPIO</comment>
<comment xml:lang="ro">Arhivă SV4 CPIO</comment>
- <comment xml:lang="ru">архив SV4 CPIO</comment>
+ <comment xml:lang="ru">Архив SV4 CPIO</comment>
<comment xml:lang="sk">Archív SV4 CPIO</comment>
<comment xml:lang="sl">Datoteka arhiva SV4 CPIO</comment>
<comment xml:lang="sq">Arkiv SV4 CPIO</comment>
@@ -20126,7 +20751,7 @@
<comment xml:lang="pt">arquivo SV4 CPIO (com CRC)</comment>
<comment xml:lang="pt_BR">Pacote SV4 CPIO (com CRC)</comment>
<comment xml:lang="ro">Arhivă SV4 CPIO (cu CRC)</comment>
- <comment xml:lang="ru">архив SV4 CPIP (с CRC)</comment>
+ <comment xml:lang="ru">Архив SV4 CPIO (с CRC)</comment>
<comment xml:lang="sk">Archív SV4 CPIO (s CRC)</comment>
<comment xml:lang="sl">Datoteka arhiva SV4 CPIO (z razpršilom CRC)</comment>
<comment xml:lang="sq">Arkiv SV4 CPIO (me CRC)</comment>
@@ -20135,7 +20760,7 @@
<comment xml:lang="tr">SV4 CPIO arşivi (CRC ile)</comment>
<comment xml:lang="uk">архів SV4 CPIO (з CRC)</comment>
<comment xml:lang="vi">Kho nén CPIO SV4 (với CRC)</comment>
- <comment xml:lang="zh_CN">SV4 CPIP 归档文件(带有 CRC)</comment>
+ <comment xml:lang="zh_CN">SV4 CPIP 归档文件(带 CRC)</comment>
<comment xml:lang="zh_TW">SV4 CPIO 封存檔 (具有 CRC)</comment>
<generic-icon name="package-x-generic"/>
<glob pattern="*.sv4crc"/>
@@ -20180,7 +20805,7 @@
<comment xml:lang="pt">arquivo Tar</comment>
<comment xml:lang="pt_BR">Pacote Tar</comment>
<comment xml:lang="ro">Arhivă Tar</comment>
- <comment xml:lang="ru">архив TAR</comment>
+ <comment xml:lang="ru">Архив TAR</comment>
<comment xml:lang="sk">Archív tar</comment>
<comment xml:lang="sl">Datoteka arhiva Tar</comment>
<comment xml:lang="sq">Arkiv tar</comment>
@@ -20220,7 +20845,7 @@
<comment xml:lang="ga">cartlann Tar (comhbhrúite)</comment>
<comment xml:lang="gl">arquivo Tar (comprimido)</comment>
<comment xml:lang="he">ארכיון Tar (מכווץ)</comment>
- <comment xml:lang="hr">Tar arhiva (komprimirana)</comment>
+ <comment xml:lang="hr">Tar arhiva (sažeta)</comment>
<comment xml:lang="hu">Tar archívum (tömörített)</comment>
<comment xml:lang="ia">Archivo Tar (comprimite)</comment>
<comment xml:lang="id">Arsip Tar (terkompresi)</comment>
@@ -20238,7 +20863,7 @@
<comment xml:lang="pt">arquivo Tar (comprimido)</comment>
<comment xml:lang="pt_BR">Pacote Tar (compactado)</comment>
<comment xml:lang="ro">Arhivă Tar (comprimată)</comment>
- <comment xml:lang="ru">архив TAR (сжатый)</comment>
+ <comment xml:lang="ru">Архив TAR (сжатый)</comment>
<comment xml:lang="sk">Archív tar (komprimovaný)</comment>
<comment xml:lang="sl">Datoteka arhiva Tar (stisnjen)</comment>
<comment xml:lang="sq">Arkiv tar (i kompresuar)</comment>
@@ -20247,7 +20872,7 @@
<comment xml:lang="tr">Tar arşivi (sıkıştırılmış)</comment>
<comment xml:lang="uk">архів tar (стиснений)</comment>
<comment xml:lang="vi">Kho nén tar (đã nén)</comment>
- <comment xml:lang="zh_CN">Tar 归档文件(压缩)</comment>
+ <comment xml:lang="zh_CN">Tar 归档文件(压缩)</comment>
<comment xml:lang="zh_TW">Tar 封存檔 (UNIX 格式壓縮)</comment>
<sub-class-of type="application/x-compress"/>
<generic-icon name="package-x-generic"/>
@@ -20259,8 +20884,8 @@
<comment xml:lang="ar">ملف الخط العام</comment>
<comment xml:lang="be@latin">zvyčajny fajł šryftu</comment>
<comment xml:lang="bg">Шрифт</comment>
- <comment xml:lang="ca">fitxer genèric de tipus de lletra</comment>
- <comment xml:lang="cs">obecný soubor písma</comment>
+ <comment xml:lang="ca">fitxer de lletra genèrica</comment>
+ <comment xml:lang="cs">obecný soubor s fontem</comment>
<comment xml:lang="da">general skrifttypefil</comment>
<comment xml:lang="de">Allgemeine Schriftdatei</comment>
<comment xml:lang="el">Γενικό αρχείο γραμματοσειράς</comment>
@@ -20274,7 +20899,7 @@
<comment xml:lang="ga">comhad cló ginearálta</comment>
<comment xml:lang="gl">ficheiro de tipo de fonte xenérica</comment>
<comment xml:lang="he">קובץ גופן גנרי</comment>
- <comment xml:lang="hr">općenita datoteka fonta</comment>
+ <comment xml:lang="hr">Izvorna datoteka slova</comment>
<comment xml:lang="hu">általános betűkészletfájl</comment>
<comment xml:lang="ia">File de typo de litteras generic</comment>
<comment xml:lang="id">berkas fonta generik</comment>
@@ -20293,7 +20918,7 @@
<comment xml:lang="pt">ficheiro genérico de letra</comment>
<comment xml:lang="pt_BR">Arquivo de fonte genérico</comment>
<comment xml:lang="ro">fișier de font generic</comment>
- <comment xml:lang="ru">обычный файл шрифта</comment>
+ <comment xml:lang="ru">Обычный файл шрифта</comment>
<comment xml:lang="sk">Obyčajný súbor písma</comment>
<comment xml:lang="sl">izvorna datoteka pisave</comment>
<comment xml:lang="sq">File lloj gërme i përgjithshëm</comment>
@@ -20312,8 +20937,8 @@
<comment xml:lang="ar">ملف الخط المرزم</comment>
<comment xml:lang="be@latin">zapakavany fajł šryftu</comment>
<comment xml:lang="bg">Шрифт — компресиран</comment>
- <comment xml:lang="ca">fitxer empaquetat de tipus de lletra</comment>
- <comment xml:lang="cs">komprimovaný soubor písma</comment>
+ <comment xml:lang="ca">fitxer de lletra empaquetada</comment>
+ <comment xml:lang="cs">komprimovaný soubor s fontem</comment>
<comment xml:lang="da">pakket skrifttypefil</comment>
<comment xml:lang="de">Gepackte Schriftdatei</comment>
<comment xml:lang="el">Αρχείο συμπιεσμένης γραμματοσειράς</comment>
@@ -20327,7 +20952,7 @@
<comment xml:lang="ga">comhad cló pacáilte</comment>
<comment xml:lang="gl">ficheiro de fonte empaquetada</comment>
<comment xml:lang="he">קובץ גופן ארוז</comment>
- <comment xml:lang="hr">pakirana datoteka fonta</comment>
+ <comment xml:lang="hr">Zapakirana datoteka slova</comment>
<comment xml:lang="hu">packed font-fájl</comment>
<comment xml:lang="ia">File de typos de litteras impacchettate</comment>
<comment xml:lang="id">berkas fonta terkemas</comment>
@@ -20346,7 +20971,7 @@
<comment xml:lang="pt">ficheiro de letras empacotadas</comment>
<comment xml:lang="pt_BR">Arquivo de fonte empacotado</comment>
<comment xml:lang="ro">fișier font împachetat</comment>
- <comment xml:lang="ru">сжатый файл шрифта</comment>
+ <comment xml:lang="ru">Сжатый файл шрифта</comment>
<comment xml:lang="sk">Komprimovaný súbor písma</comment>
<comment xml:lang="sl">pakirana datoteka pisave</comment>
<comment xml:lang="sq">File lloj gërmash i kondensuar</comment>
@@ -20363,6 +20988,7 @@
<mime-type type="application/x-tgif">
<comment>TGIF document</comment>
<comment xml:lang="ar">مستند TGIF</comment>
+ <comment xml:lang="ast">Documentu de TGIF</comment>
<comment xml:lang="be@latin">Dakument TGIF</comment>
<comment xml:lang="bg">Документ — TGIF</comment>
<comment xml:lang="ca">document TGIF</comment>
@@ -20399,7 +21025,7 @@
<comment xml:lang="pt">documento TGIF</comment>
<comment xml:lang="pt_BR">Documento TGIF</comment>
<comment xml:lang="ro">Document TGIF</comment>
- <comment xml:lang="ru">документ TGIF</comment>
+ <comment xml:lang="ru">Документ TGIF</comment>
<comment xml:lang="sk">Dokument TGIF</comment>
<comment xml:lang="sl">Dokument TGIF</comment>
<comment xml:lang="sq">Dokument TGIF</comment>
@@ -20438,7 +21064,7 @@
<comment xml:lang="ga">téama</comment>
<comment xml:lang="gl">tema</comment>
<comment xml:lang="he">ערכת נושא</comment>
- <comment xml:lang="hr">tema</comment>
+ <comment xml:lang="hr">Tema</comment>
<comment xml:lang="hu">téma</comment>
<comment xml:lang="ia">Thema</comment>
<comment xml:lang="id">tema</comment>
@@ -20458,7 +21084,7 @@
<comment xml:lang="pt">tema</comment>
<comment xml:lang="pt_BR">Tema</comment>
<comment xml:lang="ro">temă</comment>
- <comment xml:lang="ru">тема</comment>
+ <comment xml:lang="ru">Тема</comment>
<comment xml:lang="sk">Motív</comment>
<comment xml:lang="sl">tema</comment>
<comment xml:lang="sq">Temë</comment>
@@ -20476,6 +21102,7 @@
<mime-type type="application/x-toutdoux">
<comment>ToutDoux document</comment>
<comment xml:lang="ar">مستند ToutDoux</comment>
+ <comment xml:lang="ast">Documentu de ToutDoux</comment>
<comment xml:lang="az">ToutDoux sənədi</comment>
<comment xml:lang="be@latin">Dakument ToutDoux</comment>
<comment xml:lang="bg">Документ — ToutDoux</comment>
@@ -20514,7 +21141,7 @@
<comment xml:lang="pt">documento ToutDoux</comment>
<comment xml:lang="pt_BR">Documento do ToutDoux</comment>
<comment xml:lang="ro">Document ToutDoux</comment>
- <comment xml:lang="ru">документ ToutDoux</comment>
+ <comment xml:lang="ru">Документ ToutDoux</comment>
<comment xml:lang="sk">Dokument ToutDoux</comment>
<comment xml:lang="sl">Dokument ToutDoux</comment>
<comment xml:lang="sq">Dokument ToutDoux</comment>
@@ -20566,7 +21193,7 @@
<comment xml:lang="pt">cópia de segurança</comment>
<comment xml:lang="pt_BR">Arquivo de backup</comment>
<comment xml:lang="ro">fișier de backup</comment>
- <comment xml:lang="ru">резервная копия</comment>
+ <comment xml:lang="ru">Резервная копия</comment>
<comment xml:lang="sk">Záložný súbor</comment>
<comment xml:lang="sl">varnostna kopija datoteke</comment>
<comment xml:lang="sq">File backup</comment>
@@ -20586,6 +21213,7 @@
<mime-type type="text/troff">
<comment>Troff document</comment>
<comment xml:lang="ar">مستند Troff</comment>
+ <comment xml:lang="ast">Documentu de Troff</comment>
<comment xml:lang="az">Troff sənədi</comment>
<comment xml:lang="be@latin">Dakument Troff</comment>
<comment xml:lang="bg">Документ — Troff</comment>
@@ -20624,7 +21252,7 @@
<comment xml:lang="pt">documento Troff</comment>
<comment xml:lang="pt_BR">Documento Troff</comment>
<comment xml:lang="ro">Document Troff</comment>
- <comment xml:lang="ru">документ Troff</comment>
+ <comment xml:lang="ru">Документ Troff</comment>
<comment xml:lang="sk">Dokument troff</comment>
<comment xml:lang="sl">Dokument Troff</comment>
<comment xml:lang="sq">Dokument Troff</comment>
@@ -20657,7 +21285,9 @@
<comment xml:lang="el">Έγγραφο βοήθειας manpage</comment>
<comment xml:lang="en_GB">Manpage manual document</comment>
<comment xml:lang="es">documento de manual de Manpage</comment>
+ <comment xml:lang="eu">Manpage eskuliburu dokumentua</comment>
<comment xml:lang="fr">document manuel Manpage</comment>
+ <comment xml:lang="ga">cáipéis lámhleabhair Man</comment>
<comment xml:lang="he">מסמך תיעוד man</comment>
<comment xml:lang="hr">Manpage dokument priručnika</comment>
<comment xml:lang="hu">Manpage kézikönyv-dokumentum</comment>
@@ -20670,7 +21300,7 @@
<comment xml:lang="pl">Dokument podręcznika stron pomocy</comment>
<comment xml:lang="pt">documento de ajuda Manpage</comment>
<comment xml:lang="pt_BR">Documento Manpage</comment>
- <comment xml:lang="ru">документ справочной системы Manpage</comment>
+ <comment xml:lang="ru">Документ справочной системы Manpage</comment>
<comment xml:lang="sk">Dokument manuálu Manpage</comment>
<comment xml:lang="sr">документ упутства странице упутства</comment>
<comment xml:lang="sv">Manpage-manualdokument</comment>
@@ -20704,7 +21334,7 @@
<comment xml:lang="ga">leathanach lámhleabhair (comhbhrúite)</comment>
<comment xml:lang="gl">páxina de manual (comprimida)</comment>
<comment xml:lang="he">דף עזר (מכווץ)</comment>
- <comment xml:lang="hr">stranica priručnika (komprimirana)</comment>
+ <comment xml:lang="hr">Stranica priručnika (sažeta)</comment>
<comment xml:lang="hu">kézikönyvoldal (tömörített)</comment>
<comment xml:lang="ia">Pagina de manual (comprimite)</comment>
<comment xml:lang="id">halaman manual (terkompresi)</comment>
@@ -20723,7 +21353,7 @@
<comment xml:lang="pt">página de manual (comprimida)</comment>
<comment xml:lang="pt_BR">Página de manual (compactada)</comment>
<comment xml:lang="ro">pagină de manual (comprimată)</comment>
- <comment xml:lang="ru">страница руководства (сжатая)</comment>
+ <comment xml:lang="ru">Страница руководства (сжатая)</comment>
<comment xml:lang="sk">Manuálová stránka (komprimovaná)</comment>
<comment xml:lang="sl">stran priročnika (stisnjena)</comment>
<comment xml:lang="sq">Faqe manuali (e kompresuar)</comment>
@@ -20732,7 +21362,7 @@
<comment xml:lang="tr">kılavuz dosyası (sıkıştırılmış)</comment>
<comment xml:lang="uk">сторінка посібника (стиснена)</comment>
<comment xml:lang="vi">trang hướng dẫn (đã nén)</comment>
- <comment xml:lang="zh_CN">手册页 (压缩)</comment>
+ <comment xml:lang="zh_CN">手册页(压缩)</comment>
<comment xml:lang="zh_TW">手冊頁面 (壓縮版)</comment>
<generic-icon name="text-x-generic"/>
</mime-type>
@@ -20755,7 +21385,7 @@
<comment xml:lang="ga">cartlann Tar (comhbhrúite le LZO)</comment>
<comment xml:lang="gl">arquivo Tar (comprimido con LZO)</comment>
<comment xml:lang="he">ארכיון Tar (מכווץ ע״י LZO)</comment>
- <comment xml:lang="hr">Tar arhiva (komprimirana LZO-om)</comment>
+ <comment xml:lang="hr">Tar arhiva (LZO sažeta)</comment>
<comment xml:lang="hu">Tar archívum (LZO-val tömörítve)</comment>
<comment xml:lang="ia">Archivo Tar (comprimite con LZO)</comment>
<comment xml:lang="id">Arsip Tar (terkompresi LZO)</comment>
@@ -20773,7 +21403,7 @@
<comment xml:lang="pt">arquivo Tar (compressão LZO)</comment>
<comment xml:lang="pt_BR">Pacote Tar (compactado com LZO)</comment>
<comment xml:lang="ro">Arhivă Tar (comprimată LZO)</comment>
- <comment xml:lang="ru">архив TAR (сжатый LZO)</comment>
+ <comment xml:lang="ru">Архив TAR (сжатый lzo)</comment>
<comment xml:lang="sk">Archív tar (komprimovaný pomocou LZO)</comment>
<comment xml:lang="sl">Datoteka arhiva Tar (stisnjen z LZO)</comment>
<comment xml:lang="sq">Arkiv tar (i kompresuar me LZO)</comment>
@@ -20782,7 +21412,7 @@
<comment xml:lang="tr">Tar arşivi (LZO ile sıkıştırılmış)</comment>
<comment xml:lang="uk">архів tar (стиснений LZO)</comment>
<comment xml:lang="vi">Kho nén tar (đã nén LZO)</comment>
- <comment xml:lang="zh_CN">Tar 归档文件(LZO 压缩)</comment>
+ <comment xml:lang="zh_CN">Tar 归档文件(LZO 压缩)</comment>
<comment xml:lang="zh_TW">Tar 封存檔 (LZO 格式壓縮)</comment>
<sub-class-of type="application/x-lzop"/>
<generic-icon name="package-x-generic"/>
@@ -20824,7 +21454,7 @@
<comment xml:lang="pt">arquivo XZ</comment>
<comment xml:lang="pt_BR">Pacote XZ</comment>
<comment xml:lang="ro">Arhivă XZ</comment>
- <comment xml:lang="ru">архив XZ</comment>
+ <comment xml:lang="ru">Архив XZ</comment>
<comment xml:lang="sk">Archív XZ</comment>
<comment xml:lang="sl">Datoteka arhiva XZ</comment>
<comment xml:lang="sr">ИксЗ архива</comment>
@@ -20857,7 +21487,7 @@
<comment xml:lang="ga">cartlann Tar (comhbhrúite le XZ)</comment>
<comment xml:lang="gl">arquivo Tar (comprimido con XZ)</comment>
<comment xml:lang="he">ארכיון Tar (מכווץ ע״י XZ)</comment>
- <comment xml:lang="hr">Tar arhiva (komprimirana XZ-om)</comment>
+ <comment xml:lang="hr">Tar arhiva ( XZ sažeta)</comment>
<comment xml:lang="hu">Tar archívum (XZ-vel tömörítve)</comment>
<comment xml:lang="ia">Archivo Tar (comprimite con XZ)</comment>
<comment xml:lang="id">Arsip Tar (terkompresi XZ)</comment>
@@ -20873,14 +21503,14 @@
<comment xml:lang="pt">arquivo Tar (compressão XZ)</comment>
<comment xml:lang="pt_BR">Pacote Tar (compactado com XZ)</comment>
<comment xml:lang="ro">Arhivă Tar (comprimată XZ)</comment>
- <comment xml:lang="ru">архив TAR (сжатый XZ)</comment>
+ <comment xml:lang="ru">Архив TAR (сжатый xz)</comment>
<comment xml:lang="sk">Archív tar (komprimovaný pomocou XZ)</comment>
<comment xml:lang="sl">Datoteka arhiva Tar (stisnjen z XZ)</comment>
<comment xml:lang="sr">Тар архива (запакована ИксЗ-ом)</comment>
<comment xml:lang="sv">Tar-arkiv (XZ-komprimerat)</comment>
<comment xml:lang="tr">Tar arşivi (XZ ile sıkıştırılmış)</comment>
<comment xml:lang="uk">архів tar (стиснений XZ)</comment>
- <comment xml:lang="zh_CN">Tar 归档文件(XZ 压缩)</comment>
+ <comment xml:lang="zh_CN">Tar 归档文件(XZ 压缩)</comment>
<comment xml:lang="zh_TW">Tar 封存檔 (XZ 格式壓縮)</comment>
<sub-class-of type="application/x-xz"/>
<generic-icon name="package-x-generic"/>
@@ -20889,6 +21519,7 @@
</mime-type>
<mime-type type="application/x-xzpdf">
<comment>PDF document (XZ-compressed)</comment>
+ <comment xml:lang="ast">Documentu PDF (comprimíu en XZ)</comment>
<comment xml:lang="bg">Документ — PDF, компресиран с XZ</comment>
<comment xml:lang="ca">document PDF (amb compressió XZ)</comment>
<comment xml:lang="cs">dokument PDF (komprimovaný pomocí XZ)</comment>
@@ -20900,9 +21531,10 @@
<comment xml:lang="eu">PDF dokumentua (XZ-rekin konprimitua)</comment>
<comment xml:lang="fi">PDF-asiakirja (XZ-pakattu)</comment>
<comment xml:lang="fr">document PDF (compressé XZ)</comment>
+ <comment xml:lang="ga">cáipéis PDF (comhbhrúite le XZ)</comment>
<comment xml:lang="gl">documento PDF (comprimido en XZ)</comment>
<comment xml:lang="he">מסמך PDF (מכווץ ע״י XZ)</comment>
- <comment xml:lang="hr">PDF dokument (komprimiran XZ-om)</comment>
+ <comment xml:lang="hr">PDF dokument ( XZ sažet)</comment>
<comment xml:lang="hu">PDF dokumentum (XZ-vel tömörített)</comment>
<comment xml:lang="ia">Documento PDF (comprimite con XZ)</comment>
<comment xml:lang="id">Dokumen PDF (terkompresi XZ)</comment>
@@ -20917,14 +21549,14 @@
<comment xml:lang="pl">Dokument PDF (kompresja XZ)</comment>
<comment xml:lang="pt">documento PDF (compressão XZ)</comment>
<comment xml:lang="pt_BR">Documento PDF (compactado com XZ)</comment>
- <comment xml:lang="ru">документ PDF (сжатый XZ)</comment>
+ <comment xml:lang="ru">Документ PDF (сжатый xz)</comment>
<comment xml:lang="sk">Dokument PDF (komprimovaný pomocou XZ)</comment>
<comment xml:lang="sl">Dokument PDF (XZ-stisnjen)</comment>
<comment xml:lang="sr">ПДФ документ (запакован ИксЗ-ом)</comment>
<comment xml:lang="sv">PDF-dokument (XZ-komprimerat)</comment>
<comment xml:lang="tr">PDF belgesi (XZ ile sıkıştırılmış)</comment>
<comment xml:lang="uk">документ PDF (стиснений xz)</comment>
- <comment xml:lang="zh_CN">PDF 文档(XZ)</comment>
+ <comment xml:lang="zh_CN">PDF 文档(XZ)</comment>
<comment xml:lang="zh_TW">PDF 文件 (XZ 格式壓縮)</comment>
<sub-class-of type="application/x-xz"/>
<generic-icon name="x-office-document"/>
@@ -20968,7 +21600,7 @@
<comment xml:lang="pt">arquivo Ustar</comment>
<comment xml:lang="pt_BR">Pacote Ustar</comment>
<comment xml:lang="ro">Arhivă Ustar</comment>
- <comment xml:lang="ru">архив Ustar</comment>
+ <comment xml:lang="ru">Архив Ustar</comment>
<comment xml:lang="sk">Archív ustar</comment>
<comment xml:lang="sl">Datoteka arhiva Ustar</comment>
<comment xml:lang="sq">Arkiv Ustar</comment>
@@ -21004,7 +21636,7 @@
<comment xml:lang="ga">cód foinseach WAIS</comment>
<comment xml:lang="gl">código fonte WAIS</comment>
<comment xml:lang="he">קוד מקור של WAIS</comment>
- <comment xml:lang="hr">WAIS izvorni kod</comment>
+ <comment xml:lang="hr">WAIS izvorni kôd</comment>
<comment xml:lang="hu">WAIS-forráskód</comment>
<comment xml:lang="ia">Codice-fonte WAIS</comment>
<comment xml:lang="id">Kode program WAIS</comment>
@@ -21023,7 +21655,7 @@
<comment xml:lang="pt">código origem WAIS</comment>
<comment xml:lang="pt_BR">Código-fonte WAIS</comment>
<comment xml:lang="ro">Cod sursă WAIS</comment>
- <comment xml:lang="ru">исходный код WAIS</comment>
+ <comment xml:lang="ru">Исходный код WAIS</comment>
<comment xml:lang="sk">Zdrojový kód WAIS</comment>
<comment xml:lang="sl">Datoteka izvorne kode WAIS</comment>
<comment xml:lang="sq">Kod burues WAIS</comment>
@@ -21077,7 +21709,7 @@
<comment xml:lang="pt">imagem do WordPerfect/Drawperfect</comment>
<comment xml:lang="pt_BR">Imagem do WordPerfect/Drawperfect</comment>
<comment xml:lang="ro">Imagine WordPerfect/Drawperfect</comment>
- <comment xml:lang="ru">изображение WordPerfect/Drawperfect</comment>
+ <comment xml:lang="ru">Изображение WordPerfect/Drawperfect</comment>
<comment xml:lang="sk">Obrázok WordPerfect/Drawperfect</comment>
<comment xml:lang="sl">Slikovna datoteka Drawperfect</comment>
<comment xml:lang="sq">Figurë WordPerfect/Drawperfect</comment>
@@ -21091,6 +21723,54 @@
<generic-icon name="image-x-generic"/>
<glob pattern="*.wpg"/>
</mime-type>
+ <mime-type type="application/x-wonderswan-rom">
+ <comment>Bandai WonderSwan ROM</comment>
+ <comment xml:lang="ca">ROM de Bandai WonderSwan</comment>
+ <comment xml:lang="cs">ROM pro Bandai WonderSwan</comment>
+ <comment xml:lang="de">Bandai WonderSwan ROM</comment>
+ <comment xml:lang="en_GB">Bandai WonderSwan ROM</comment>
+ <comment xml:lang="es">ROM de Bandai WonderSwan</comment>
+ <comment xml:lang="hr">Bandai WonderSwan ROM</comment>
+ <comment xml:lang="hu">Bandai WonderSwan ROM</comment>
+ <comment xml:lang="id">ROM Bandai WonderSwan</comment>
+ <comment xml:lang="it">ROM Bandai WonderSwan</comment>
+ <comment xml:lang="kk">Bandai WonderSwan ROM</comment>
+ <comment xml:lang="ko">반다이 원더스완 롬</comment>
+ <comment xml:lang="pl">Plik ROM konsoli Bandai WonderSwan</comment>
+ <comment xml:lang="pt_BR">ROM de WonderSwan da Bandai</comment>
+ <comment xml:lang="ru">Bandai WonderSwan ROM</comment>
+ <comment xml:lang="sk">ROM pre Bandai WonderSwan</comment>
+ <comment xml:lang="sv">Bandai WonderSwan-rom</comment>
+ <comment xml:lang="uk">ROM Bandai WonderSwan</comment>
+ <comment xml:lang="zh_CN">万代 WonderSwan ROM</comment>
+ <comment xml:lang="zh_TW">Bandai WonderSwan ROM</comment>
+ <generic-icon name="application-x-executable"/>
+ <glob pattern="*.ws"/>
+ </mime-type>
+ <mime-type type="application/x-wonderswan-color-rom">
+ <comment>Bandai WonderSwan Color ROM</comment>
+ <comment xml:lang="ca">ROM de Bandai WonderSwan Color</comment>
+ <comment xml:lang="cs">ROM pro Bandai WonderSwan Color</comment>
+ <comment xml:lang="de">Bandai WonderSwan Color ROM</comment>
+ <comment xml:lang="en_GB">Bandai WonderSwan Color ROM</comment>
+ <comment xml:lang="es">ROM de Bandai WonderSwan Color</comment>
+ <comment xml:lang="hr">Bandai WonderSwan Color ROM</comment>
+ <comment xml:lang="hu">Bandai WonderSwan Color ROM</comment>
+ <comment xml:lang="id">ROM Bandai WonderSwan Color</comment>
+ <comment xml:lang="it">ROM Bandai WonderSwan Color</comment>
+ <comment xml:lang="kk">Bandai WonderSwan Color ROM</comment>
+ <comment xml:lang="ko">반다이 원더스완 컬러 롬</comment>
+ <comment xml:lang="pl">Plik ROM konsoli Bandai WonderSwan Color</comment>
+ <comment xml:lang="pt_BR">ROM de WonderSwan Color da Bandai</comment>
+ <comment xml:lang="ru">Bandai WonderSwan Color ROM</comment>
+ <comment xml:lang="sk">ROM pre Bandai WonderSwan Color</comment>
+ <comment xml:lang="sv">Bandai WonderSwan Color-rom</comment>
+ <comment xml:lang="uk">ROM Bandai WonderSwan Color</comment>
+ <comment xml:lang="zh_CN">万代 WonderSwan Color ROM</comment>
+ <comment xml:lang="zh_TW">Bandai WonderSwan Color ROM</comment>
+ <generic-icon name="application-x-executable"/>
+ <glob pattern="*.wsc"/>
+ </mime-type>
<mime-type type="application/x-x509-ca-cert">
<comment>DER/PEM/Netscape-encoded X.509 certificate</comment>
<comment xml:lang="ar">شهادة DER/PEM/Netscape-encoded X.509</comment>
@@ -21111,7 +21791,7 @@
<comment xml:lang="ga">teastas X.509 ionchódaithe le DER/PEM/Netscape</comment>
<comment xml:lang="gl">certificado X.509 codificado con DER/PEM/Netscape</comment>
<comment xml:lang="he">אישור מסוג X.509 של DER/PEM/Netscape-encoded</comment>
- <comment xml:lang="hr">DER/PEM/Netscape-kodiran X.509 certifikat</comment>
+ <comment xml:lang="hr">DER/PEM/Netscape-kodiran X.509 vjerodajnica</comment>
<comment xml:lang="hu">DER/PEM/Netscape formátumú X.509-tanúsítvány</comment>
<comment xml:lang="ia">Certificato X.509 codificate in DER/PEM/Netscape</comment>
<comment xml:lang="id">Sertifikat DER/PEM/Netscape-tersandi X.509</comment>
@@ -21131,7 +21811,7 @@
<comment xml:lang="pt">certificado X.509 codificado com DER/PEM/Netscape</comment>
<comment xml:lang="pt_BR">Certificado X.509 codificado com DER/PEM/Netscape</comment>
<comment xml:lang="ro">Certificat DER/PEM/Netscape-codat X.509</comment>
- <comment xml:lang="ru">сертификат X.509 (DER/PEM/Netscape-закодированный)</comment>
+ <comment xml:lang="ru">Сертификат X.509 (DER/PEM/Netscape-закодированный)</comment>
<comment xml:lang="sk">Certifikát X.509 kódovaný ako DER/PEM/Netscape</comment>
<comment xml:lang="sl">Datoteka potrdila DER/PEM/Netscape X.509</comment>
<comment xml:lang="sq">Çertifikatë DER/PEM/Netscape-encoded X.509</comment>
@@ -21151,6 +21831,7 @@
<mime-type type="application/x-zerosize">
<comment>empty document</comment>
<comment xml:lang="ar">مستند فارغ</comment>
+ <comment xml:lang="ast">documentu baleru</comment>
<comment xml:lang="be@latin">pusty dakument</comment>
<comment xml:lang="bg">Празен документ</comment>
<comment xml:lang="ca">document buit</comment>
@@ -21168,7 +21849,7 @@
<comment xml:lang="ga">cáipéis fholamh</comment>
<comment xml:lang="gl">documeto baleiro</comment>
<comment xml:lang="he">מסמך ריק</comment>
- <comment xml:lang="hr">prazan dokument</comment>
+ <comment xml:lang="hr">Prazan dokument</comment>
<comment xml:lang="hu">üres dokumentum</comment>
<comment xml:lang="ia">Documento vacue</comment>
<comment xml:lang="id">dokumen kosong</comment>
@@ -21187,7 +21868,7 @@
<comment xml:lang="pt">documento vazio</comment>
<comment xml:lang="pt_BR">Documento vazio</comment>
<comment xml:lang="ro">document gol</comment>
- <comment xml:lang="ru">пустой документ</comment>
+ <comment xml:lang="ru">Пустой документ</comment>
<comment xml:lang="sk">Prázdny dokument</comment>
<comment xml:lang="sl">prazen dokument</comment>
<comment xml:lang="sq">Dokument bosh</comment>
@@ -21239,7 +21920,7 @@
<comment xml:lang="pt">arquivo Zoo</comment>
<comment xml:lang="pt_BR">Pacote Zoo</comment>
<comment xml:lang="ro">Arhivă Zoo</comment>
- <comment xml:lang="ru">архив ZOO</comment>
+ <comment xml:lang="ru">Архив ZOO</comment>
<comment xml:lang="sk">Archív zoo</comment>
<comment xml:lang="sl">Datoteka arhiva ZOO</comment>
<comment xml:lang="sq">Arkiv zoo</comment>
@@ -21295,7 +21976,7 @@
<comment xml:lang="pt">página XHTML</comment>
<comment xml:lang="pt_BR">Página XHTML</comment>
<comment xml:lang="ro">Pagină XHTML</comment>
- <comment xml:lang="ru">страница XHTML</comment>
+ <comment xml:lang="ru">Страница XHTML</comment>
<comment xml:lang="sk">Stránka XHTML</comment>
<comment xml:lang="sl">Datoteka spletne strani XHTML</comment>
<comment xml:lang="sq">Faqe XHTML</comment>
@@ -21360,7 +22041,7 @@
<comment xml:lang="pt">arquivo Zip</comment>
<comment xml:lang="pt_BR">Pacote Zip</comment>
<comment xml:lang="ro">Arhivă zip</comment>
- <comment xml:lang="ru">архив ZIP</comment>
+ <comment xml:lang="ru">Архив ZIP</comment>
<comment xml:lang="sk">Archív ZIP</comment>
<comment xml:lang="sl">Datoteka arhiva ZIP</comment>
<comment xml:lang="sq">Arkiv zip</comment>
@@ -21391,6 +22072,7 @@
<comment xml:lang="eu">WIM disko irudia</comment>
<comment xml:lang="fi">WIM-levytiedosto</comment>
<comment xml:lang="fr">image disque WIM</comment>
+ <comment xml:lang="ga">íomhá diosca WIM</comment>
<comment xml:lang="he">דמות דיסק WIM</comment>
<comment xml:lang="hr">WIM slika diska</comment>
<comment xml:lang="hu">WIM lemezkép</comment>
@@ -21403,13 +22085,13 @@
<comment xml:lang="pl">Obraz dysku WIM</comment>
<comment xml:lang="pt">imagem de disco WIM</comment>
<comment xml:lang="pt_BR">Imagem de disco WIM</comment>
- <comment xml:lang="ru">образ диска WIM</comment>
+ <comment xml:lang="ru">Образ диска WIM</comment>
<comment xml:lang="sk">Obraz disku WIM</comment>
<comment xml:lang="sr">слика диска ВИМ-а</comment>
<comment xml:lang="sv">WIM-diskavbild</comment>
<comment xml:lang="tr">WIM disk kalıbı</comment>
<comment xml:lang="uk">образ диска WIM</comment>
- <comment xml:lang="zh_CN">WIM 磁盘镜像</comment>
+ <comment xml:lang="zh_CN">WIM 磁盘映像</comment>
<comment xml:lang="zh_TW">WIM 磁碟映像檔</comment>
<acronym>WIM</acronym>
<expanded-acronym>Windows Imaging Format</expanded-acronym>
@@ -21441,7 +22123,7 @@
<comment xml:lang="ga">fuaim Dolby Digital</comment>
<comment xml:lang="gl">son Dolby Digital</comment>
<comment xml:lang="he">שמע Dolby Digital</comment>
- <comment xml:lang="hr">Dolby Digital audio</comment>
+ <comment xml:lang="hr">Dolby Digital zvučni zapis</comment>
<comment xml:lang="hu">Dolby Digital hang</comment>
<comment xml:lang="ia">Audio Dolby Digital</comment>
<comment xml:lang="id">Audio Dolby Digital</comment>
@@ -21461,7 +22143,7 @@
<comment xml:lang="pt">áudio Dolby Digital</comment>
<comment xml:lang="pt_BR">Áudio Dolby Digital</comment>
<comment xml:lang="ro">Audio Dolby Digital</comment>
- <comment xml:lang="ru">аудио Dolby Digital</comment>
+ <comment xml:lang="ru">Аудио Dolby Digital</comment>
<comment xml:lang="sk">Zvuk Dolby Digital</comment>
<comment xml:lang="sl">Zvočna datoteka Dolby Digital</comment>
<comment xml:lang="sq">Audio Dolby Digital</comment>
@@ -21489,6 +22171,7 @@
<comment xml:lang="eu">DTS audioa</comment>
<comment xml:lang="fi">DTS-ääni</comment>
<comment xml:lang="fr">audio DTS</comment>
+ <comment xml:lang="ga">fuaim DTS</comment>
<comment xml:lang="gl">Son DTS</comment>
<comment xml:lang="he">שמע DTS</comment>
<comment xml:lang="hr">DTS zvučni zapis</comment>
@@ -21501,10 +22184,10 @@
<comment xml:lang="ko">DTS 오디오</comment>
<comment xml:lang="lv">DTS audio</comment>
<comment xml:lang="oc">àudio DTS</comment>
- <comment xml:lang="pl">Dźwięk DTS</comment>
+ <comment xml:lang="pl">Plik dźwiękowy DTS</comment>
<comment xml:lang="pt">aúdio DTS</comment>
<comment xml:lang="pt_BR">Áudio DTS</comment>
- <comment xml:lang="ru">аудио DTS</comment>
+ <comment xml:lang="ru">Аудио DTS</comment>
<comment xml:lang="sk">Zvuk DTS</comment>
<comment xml:lang="sl">Zvok DTS</comment>
<comment xml:lang="sr">ДТС звук</comment>
@@ -21534,6 +22217,7 @@
<comment xml:lang="eu">DTSHD audioa</comment>
<comment xml:lang="fi">DTS-HD-ääni</comment>
<comment xml:lang="fr">audio DTSHD</comment>
+ <comment xml:lang="ga">fuaim DTSHD</comment>
<comment xml:lang="gl">Son DTSHD</comment>
<comment xml:lang="he">שמע DTSHD</comment>
<comment xml:lang="hr">DTSHD zvučni zapis</comment>
@@ -21546,10 +22230,10 @@
<comment xml:lang="ko">DTSHD 오디오</comment>
<comment xml:lang="lv">DTSHD audio</comment>
<comment xml:lang="oc">àudio DTSHD</comment>
- <comment xml:lang="pl">Dźwięk DTSHD</comment>
+ <comment xml:lang="pl">Plik dźwiękowy DTSHD</comment>
<comment xml:lang="pt">áudio DTSHD</comment>
<comment xml:lang="pt_BR">Áudio DTSHD</comment>
- <comment xml:lang="ru">аудио DTSHD</comment>
+ <comment xml:lang="ru">Аудио DTSHD</comment>
<comment xml:lang="sk">Zvuk DTSHD</comment>
<comment xml:lang="sl">Zvok DTSHD</comment>
<comment xml:lang="sr">ДТСХД звук</comment>
@@ -21585,7 +22269,7 @@
<comment xml:lang="ga">fuaim AMR</comment>
<comment xml:lang="gl">son AMR</comment>
<comment xml:lang="he">שמע AMR</comment>
- <comment xml:lang="hr">AMR audio</comment>
+ <comment xml:lang="hr">AMR zvučni zapis</comment>
<comment xml:lang="hu">AMR hang</comment>
<comment xml:lang="ia">Audio AMR</comment>
<comment xml:lang="id">Audio AMR</comment>
@@ -21604,7 +22288,7 @@
<comment xml:lang="pt">áudio AMR</comment>
<comment xml:lang="pt_BR">Áudio AMR</comment>
<comment xml:lang="ro">Audio AMR</comment>
- <comment xml:lang="ru">аудио AMR</comment>
+ <comment xml:lang="ru">Аудио AMR</comment>
<comment xml:lang="sk">Zvuk AMR</comment>
<comment xml:lang="sl">Zvočna datoteka AMR</comment>
<comment xml:lang="sq">Audio AMR</comment>
@@ -21644,7 +22328,7 @@
<comment xml:lang="ga">fuaim AMR-WB</comment>
<comment xml:lang="gl">son AMR-WB</comment>
<comment xml:lang="he">שמע AMR-WN</comment>
- <comment xml:lang="hr">AMR-WB audio</comment>
+ <comment xml:lang="hr">AMR-WB zvučni zapis</comment>
<comment xml:lang="hu">AMR-WB hang</comment>
<comment xml:lang="ia">Audio AMR-WB</comment>
<comment xml:lang="id">Audio AMR-WB</comment>
@@ -21663,7 +22347,7 @@
<comment xml:lang="pt">áudio AMR-WB</comment>
<comment xml:lang="pt_BR">Áudio AMR-WB</comment>
<comment xml:lang="ro">Audio AMR-WB</comment>
- <comment xml:lang="ru">аудио AMR-WB</comment>
+ <comment xml:lang="ru">Аудио AMR-WB</comment>
<comment xml:lang="sk">Zvuk AMR-WB</comment>
<comment xml:lang="sl">Zvočna datoteka AMR-WB</comment>
<comment xml:lang="sq">Audio AMR-WB</comment>
@@ -21724,7 +22408,7 @@
<comment xml:lang="pt">áudio ULAW (Sun)</comment>
<comment xml:lang="pt_BR">Áudio ULAW (Sun)</comment>
<comment xml:lang="ro">Fișier audio ULAW (Sun)</comment>
- <comment xml:lang="ru">аудио ULAW (Sun)</comment>
+ <comment xml:lang="ru">Аудио ULAW (Sun)</comment>
<comment xml:lang="sk">Zvuk ULAW (Sun)</comment>
<comment xml:lang="sl">Zvočna datoteka ULAW (Sun)</comment>
<comment xml:lang="sq">Audio ULAW (Sun)</comment>
@@ -21761,7 +22445,7 @@
<comment xml:lang="ga">fuaim Commodore 64</comment>
<comment xml:lang="gl">son de Commodore 64</comment>
<comment xml:lang="he">שמע של Commodore 64</comment>
- <comment xml:lang="hr">Commodore 64 audio</comment>
+ <comment xml:lang="hr">Commodore 64 zvučni zapis</comment>
<comment xml:lang="hu">Commodore 64 hang</comment>
<comment xml:lang="ia">Audio Commodore 64</comment>
<comment xml:lang="id">Audio Commodore 64</comment>
@@ -21781,7 +22465,7 @@
<comment xml:lang="pt">áudio Commodore 64</comment>
<comment xml:lang="pt_BR">Áudio Commodore 64</comment>
<comment xml:lang="ro">Audio Commodore 64</comment>
- <comment xml:lang="ru">аудио Commodore 64</comment>
+ <comment xml:lang="ru">Аудио Commodore 64</comment>
<comment xml:lang="sk">Zvuk Commodore 64</comment>
<comment xml:lang="sl">Zvočna datoteka Commodore 64</comment>
<comment xml:lang="sq">Audio Commodore 64</comment>
@@ -21839,7 +22523,7 @@
<comment xml:lang="pt">áudio PCM</comment>
<comment xml:lang="pt_BR">Áudio PCM</comment>
<comment xml:lang="ro">Audio PCM</comment>
- <comment xml:lang="ru">аудио PCM</comment>
+ <comment xml:lang="ru">Аудио PCM</comment>
<comment xml:lang="sk">Zvuk PCM</comment>
<comment xml:lang="sl">Zvočna datoteka PCM</comment>
<comment xml:lang="sq">Audio PCM</comment>
@@ -21888,7 +22572,7 @@
<comment xml:lang="ga">fuaim AIFC</comment>
<comment xml:lang="gl">son AIFC</comment>
<comment xml:lang="he">שמע AIFC</comment>
- <comment xml:lang="hr">AIFC audio</comment>
+ <comment xml:lang="hr">AIFC zvučni zapis</comment>
<comment xml:lang="hu">AIFC hang</comment>
<comment xml:lang="ia">Audio AIFC</comment>
<comment xml:lang="id">Audio AIFC</comment>
@@ -21908,7 +22592,7 @@
<comment xml:lang="pt">áudio AIFC</comment>
<comment xml:lang="pt_BR">Áudio AIFC</comment>
<comment xml:lang="ro">Fișier audio AIFC</comment>
- <comment xml:lang="ru">аудио AIFC</comment>
+ <comment xml:lang="ru">Аудио AIFC</comment>
<comment xml:lang="sk">Zvuk AIFC</comment>
<comment xml:lang="sl">Zvočna datoteka AIFC</comment>
<comment xml:lang="sq">Audio AIFC</comment>
@@ -21951,7 +22635,7 @@
<comment xml:lang="ga">fuaim AIFF/Amiga/Mac</comment>
<comment xml:lang="gl">son AIFF/Amiga/Mac</comment>
<comment xml:lang="he">שמע AIFF/Amiga/Mac</comment>
- <comment xml:lang="hr">AIFF/Amiga/Mac audio</comment>
+ <comment xml:lang="hr">AIFF/Amiga/Mac zvučni zapis</comment>
<comment xml:lang="hu">AIFF/Amiga/Mac hang</comment>
<comment xml:lang="ia">Audio AIFF/Amiga/Mac</comment>
<comment xml:lang="id">Audio AIFF/Amiga/Mac</comment>
@@ -21971,7 +22655,7 @@
<comment xml:lang="pt">áudio AIFF/Amiga/Mac</comment>
<comment xml:lang="pt_BR">Áudio AIFF/Amiga/Mac</comment>
<comment xml:lang="ro">Audio AIFF/Amiga/Mac</comment>
- <comment xml:lang="ru">аудио AIFF/Amiga/Mac</comment>
+ <comment xml:lang="ru">Аудио AIFF/Amiga/Mac</comment>
<comment xml:lang="sk">Zvuk AIFF/Amiga/Mac</comment>
<comment xml:lang="sl">Zvočna datoteka AIFF/Amiga/Mac</comment>
<comment xml:lang="sq">Audio AIFF/Amiga/Mac</comment>
@@ -22029,7 +22713,7 @@
<comment xml:lang="pt">áudio Monkey</comment>
<comment xml:lang="pt_BR">Áudio Monkey's</comment>
<comment xml:lang="ro">Audio Monkey's</comment>
- <comment xml:lang="ru">аудио Monkey's</comment>
+ <comment xml:lang="ru">Аудио Monkey's</comment>
<comment xml:lang="sk">Zvuk Monkey's</comment>
<comment xml:lang="sl">Zvočna datoteka Monkey</comment>
<comment xml:lang="sq">Audio Monkey's</comment>
@@ -22038,13 +22722,44 @@
<comment xml:lang="tr">Monkey's sesi</comment>
<comment xml:lang="uk">звук Monkey's</comment>
<comment xml:lang="vi">Âm thanh cua Monkey</comment>
- <comment xml:lang="zh_CN">Monkey's audio 音频</comment>
+ <comment xml:lang="zh_CN">Monkey's Audio 音频</comment>
<comment xml:lang="zh_TW">Monkey's 音訊</comment>
<magic priority="50">
<match value="MAC " type="string" offset="0"/>
</magic>
<glob pattern="*.ape"/>
</mime-type>
+ <mime-type type="audio/x-pn-audibleaudio">
+ <comment>Audible.Com audio</comment>
+ <comment xml:lang="ca">àudio Audible.Com</comment>
+ <comment xml:lang="cs">zvuk Audible.Com</comment>
+ <comment xml:lang="de">Audible.Com-Audio</comment>
+ <comment xml:lang="en_GB">Audible.Com audio</comment>
+ <comment xml:lang="es">sonido de Audible.com</comment>
+ <comment xml:lang="hr">Audible.Com zvučni zapis</comment>
+ <comment xml:lang="hu">Audible.Com hang</comment>
+ <comment xml:lang="id">Audio Audible.Com</comment>
+ <comment xml:lang="it">Audio Audible.Com</comment>
+ <comment xml:lang="kk">Audible.Com аудиосы</comment>
+ <comment xml:lang="ko">Audible.Com 오디오</comment>
+ <comment xml:lang="pl">Plik dźwiękowy Audible.com</comment>
+ <comment xml:lang="pt_BR">Áudio de audible.com</comment>
+ <comment xml:lang="ru">Аудио Audible.Com</comment>
+ <comment xml:lang="sk">Audio Audible.Com</comment>
+ <comment xml:lang="sv">Audible.Com-ljud</comment>
+ <comment xml:lang="uk">звук Audible.Com</comment>
+ <comment xml:lang="zh_CN">Audible.Com 音频</comment>
+ <comment xml:lang="zh_TW">Audible.Com 音訊</comment>
+ <magic priority="50">
+
+ <match value="1469084982" type="big32" offset="4"/>
+ <match value="aax " type="string" offset="8"/>
+ </magic>
+ <glob pattern="*.aa"/>
+ <glob pattern="*.aax"/>
+ <alias type="audio/vnd.audible"/>
+ <alias type="audio/vnd.audible.aax"/>
+ </mime-type>
<mime-type type="audio/x-it">
<comment>Impulse Tracker audio</comment>
<comment xml:lang="ar">Impulse Tracker سمعي</comment>
@@ -22067,7 +22782,7 @@
<comment xml:lang="ga">fuaim Impulse Tracker</comment>
<comment xml:lang="gl">son de Impulse Tracker</comment>
<comment xml:lang="he">שמע של Impulse Tracker</comment>
- <comment xml:lang="hr">Impulse Tracker audio</comment>
+ <comment xml:lang="hr">Impulse Tracker zvučni zapis</comment>
<comment xml:lang="hu">Impulse Tracker hang</comment>
<comment xml:lang="ia">Audio Impulse Tracker</comment>
<comment xml:lang="id">Audio Impulse Tracker</comment>
@@ -22086,7 +22801,7 @@
<comment xml:lang="pt">áudio Impulse Tracker</comment>
<comment xml:lang="pt_BR">Áudio Impulse Tracker</comment>
<comment xml:lang="ro">Audio Impulse Tracker</comment>
- <comment xml:lang="ru">аудио Impulse Tracker</comment>
+ <comment xml:lang="ru">Аудио Impulse Tracker</comment>
<comment xml:lang="sk">Zvuk Impulse Tracker</comment>
<comment xml:lang="sl">Zvočna datoteka Impulse Tracker</comment>
<comment xml:lang="sq">Audio Impulse Tracker</comment>
@@ -22122,7 +22837,7 @@
<comment xml:lang="ga">fuaim FLAC</comment>
<comment xml:lang="gl">son FLAC</comment>
<comment xml:lang="he">קובץ שמע מסוג FLAC</comment>
- <comment xml:lang="hr">FLAC audio</comment>
+ <comment xml:lang="hr">FLAC zvučni zapis</comment>
<comment xml:lang="hu">FLAC hang</comment>
<comment xml:lang="ia">Audio FLAC</comment>
<comment xml:lang="id">Audio FLAC</comment>
@@ -22142,7 +22857,7 @@
<comment xml:lang="pt">áudio FLAC</comment>
<comment xml:lang="pt_BR">Áudio FLAC</comment>
<comment xml:lang="ro">Audio FLAC</comment>
- <comment xml:lang="ru">аудио FLAC</comment>
+ <comment xml:lang="ru">Аудио FLAC</comment>
<comment xml:lang="sk">Zvuk FLAC</comment>
<comment xml:lang="sl">Zvočna datoteka Flac</comment>
<comment xml:lang="sq">Audio FLAC</comment>
@@ -22179,7 +22894,7 @@
<comment xml:lang="ga">fuaim WavPack</comment>
<comment xml:lang="gl">son WavPack</comment>
<comment xml:lang="he">שמע WavPack</comment>
- <comment xml:lang="hr">WavPack audio</comment>
+ <comment xml:lang="hr">WavPack zvučni zapis</comment>
<comment xml:lang="hu">WavPack hang</comment>
<comment xml:lang="ia">Audio WavPack</comment>
<comment xml:lang="id">Audio WavPack</comment>
@@ -22197,7 +22912,7 @@
<comment xml:lang="pt">áudio WavPack</comment>
<comment xml:lang="pt_BR">Áudio WavPack</comment>
<comment xml:lang="ro">Audio WavPack</comment>
- <comment xml:lang="ru">аудио WavPack</comment>
+ <comment xml:lang="ru">Аудио WavPack</comment>
<comment xml:lang="sk">Zvuk WavPack</comment>
<comment xml:lang="sl">Zvočna datoteka WavPack</comment>
<comment xml:lang="sq">Audio WavPack</comment>
@@ -22230,7 +22945,7 @@
<comment xml:lang="fi">WavPack-äänikorjaustiedosto</comment>
<comment xml:lang="fo">WavPack ljóðrættingarfíla</comment>
<comment xml:lang="fr">fichier de correction audio WavPack</comment>
- <comment xml:lang="ga">comhad cheartú fhuaim WavPack</comment>
+ <comment xml:lang="ga">comhad ceartúchán fuaime WavPack</comment>
<comment xml:lang="gl">ficheiro de corrección de son WavPack</comment>
<comment xml:lang="he">קובץ תיקון שמע של WavPack</comment>
<comment xml:lang="hr">WavPack datoteka ispravke zvuka</comment>
@@ -22251,7 +22966,7 @@
<comment xml:lang="pt">ficheiro de correção áudio WavPack</comment>
<comment xml:lang="pt_BR">Arquivo de correção de áudio WavPack</comment>
<comment xml:lang="ro">Fișier audio de corecție WavPack</comment>
- <comment xml:lang="ru">файл коррекции аудио WavPack</comment>
+ <comment xml:lang="ru">Файл коррекции аудио WavPack</comment>
<comment xml:lang="sk">Opravný zvukový súbor WavPack</comment>
<comment xml:lang="sl">popravljalna zvočna datoteka WavPack</comment>
<comment xml:lang="sq">File korrigjgimi audio WavPack</comment>
@@ -22260,7 +22975,7 @@
<comment xml:lang="tr">WavPack ses düzeltme dosyası</comment>
<comment xml:lang="uk">файл корекції звуку WavPack</comment>
<comment xml:lang="vi">Tập tin sửa chữa âm thanh WavPack</comment>
- <comment xml:lang="zh_CN">WavPack 音频校正文档</comment>
+ <comment xml:lang="zh_CN">WavPack 音频校正文件</comment>
<comment xml:lang="zh_TW">WavPack 音訊校正檔</comment>
<magic priority="50">
<match value="wvpk" type="string" offset="0"/>
@@ -22289,7 +23004,7 @@
<comment xml:lang="ga">fuaim MIDI</comment>
<comment xml:lang="gl">son MIDI</comment>
<comment xml:lang="he">שמע MIDI</comment>
- <comment xml:lang="hr">MIDI audio</comment>
+ <comment xml:lang="hr">MIDI zvučni zapis</comment>
<comment xml:lang="hu">MIDI hang</comment>
<comment xml:lang="ia">Audio MIDI</comment>
<comment xml:lang="id">Audio MIDI</comment>
@@ -22308,7 +23023,7 @@
<comment xml:lang="pt">áudio MIDI</comment>
<comment xml:lang="pt_BR">Áudio MIDI</comment>
<comment xml:lang="ro">Audio MIDI</comment>
- <comment xml:lang="ru">аудио MIDI</comment>
+ <comment xml:lang="ru">Аудио MIDI</comment>
<comment xml:lang="sk">Zvuk MIDI</comment>
<comment xml:lang="sl">Zvočna datoteka MIDI</comment>
<comment xml:lang="sq">Audio MIDI</comment>
@@ -22346,7 +23061,7 @@
<comment xml:lang="ga">fuaim chomhbhrúite Tracker</comment>
<comment xml:lang="gl">son comprimido de Tracker</comment>
<comment xml:lang="he">שמע גשש מכווץ</comment>
- <comment xml:lang="hr">komprimirani Tracker audio</comment>
+ <comment xml:lang="hr">Sažeti Tracker zvučni zapis</comment>
<comment xml:lang="hu">tömörített Tracker hang</comment>
<comment xml:lang="ia">Audio Tracker comprimite</comment>
<comment xml:lang="id">audio Tracker terkompresi</comment>
@@ -22363,7 +23078,7 @@
<comment xml:lang="pt">áudio comprimido Tracker</comment>
<comment xml:lang="pt_BR">Áudio Tracker compactado</comment>
<comment xml:lang="ro">Tracker audio comprimat</comment>
- <comment xml:lang="ru">аудио Tracker (сжатое)</comment>
+ <comment xml:lang="ru">Сжатое аудио Tracker</comment>
<comment xml:lang="sk">Komprimovaný zvuk Tracker</comment>
<comment xml:lang="sl">Skrčena zvočna datoteka Tracker</comment>
<comment xml:lang="sq">Audio Tracker e kompresuar</comment>
@@ -22391,6 +23106,7 @@
<comment xml:lang="eu">AAC audioa</comment>
<comment xml:lang="fi">AAC-ääni</comment>
<comment xml:lang="fr">audio AAC</comment>
+ <comment xml:lang="ga">fuaim AAC</comment>
<comment xml:lang="gl">Son AAC</comment>
<comment xml:lang="he">שמע AAC</comment>
<comment xml:lang="hr">AAC zvučni zapis</comment>
@@ -22403,10 +23119,10 @@
<comment xml:lang="ko">AAC 오디오</comment>
<comment xml:lang="lv">AAC audio</comment>
<comment xml:lang="oc">àudio AAC</comment>
- <comment xml:lang="pl">Dźwięk AAC</comment>
+ <comment xml:lang="pl">Plik dźwiękowy AAC</comment>
<comment xml:lang="pt">áudio AAC</comment>
<comment xml:lang="pt_BR">Áudio AAC</comment>
- <comment xml:lang="ru">аудио AAC</comment>
+ <comment xml:lang="ru">Аудио AAC</comment>
<comment xml:lang="sk">Zvuk AAC</comment>
<comment xml:lang="sl">Zvok AAC</comment>
<comment xml:lang="sr">ААЦ звук</comment>
@@ -22422,8 +23138,17 @@
<match value="0xFFF0" type="big16" offset="0" mask="0xFFF6"/>
</magic>
<glob pattern="*.aac"/>
+ <glob pattern="*.adts"/>
+ <glob weight="10" pattern="*.ass"/>
<alias type="audio/x-aac"/>
</mime-type>
+ <mime-type type="audio/usac">
+ <comment>USAC audio</comment>
+ <acronym>USAC</acronym>
+ <expanded-acronym>Unified Speech and Audio Coding</expanded-acronym>
+ <glob pattern="*.loas"/>
+ <glob pattern="*.xhe"/>
+ </mime-type>
<mime-type type="audio/mp4">
<comment>MPEG-4 audio</comment>
<comment xml:lang="ar">MPEG-4 سمعي</comment>
@@ -22444,7 +23169,7 @@
<comment xml:lang="ga">fuaim MPEG-4</comment>
<comment xml:lang="gl">son MPEG-4</comment>
<comment xml:lang="he">שמע MPEG-4</comment>
- <comment xml:lang="hr">MPEG-4 audio</comment>
+ <comment xml:lang="hr">MPEG-4 zvučni zapis</comment>
<comment xml:lang="hu">MPEG-4 hang</comment>
<comment xml:lang="ia">Audio MPEG-4</comment>
<comment xml:lang="id">Audio MPEG-4</comment>
@@ -22463,7 +23188,7 @@
<comment xml:lang="pt">áudio MPEG-4</comment>
<comment xml:lang="pt_BR">Áudio MPEG-4</comment>
<comment xml:lang="ro">Audio MPEG-4</comment>
- <comment xml:lang="ru">аудио MPEG-4</comment>
+ <comment xml:lang="ru">Аудио MPEG-4</comment>
<comment xml:lang="sk">Zvuk MPEG-4</comment>
<comment xml:lang="sl">Zvočna datoteka MPEG-4</comment>
<comment xml:lang="sq">Audio MPEG-4</comment>
@@ -22482,9 +23207,15 @@
<glob pattern="*.m4a"/>
<glob pattern="*.f4a"/>
</mime-type>
+ <mime-type type="audio/x-m4r">
+ <comment>MPEG-4 Ringtone</comment>
+ <glob pattern="*.m4r"/>
+ <sub-class-of type="video/mp4"/>
+ </mime-type>
<mime-type type="video/mp4">
<comment>MPEG-4 video</comment>
<comment xml:lang="ar">MPEG-4 مرئي</comment>
+ <comment xml:lang="ast">Videu en MPEG-4</comment>
<comment xml:lang="be@latin">Videa MPEG-4</comment>
<comment xml:lang="bg">Видео — MPEG-4</comment>
<comment xml:lang="ca">vídeo MPEG-4</comment>
@@ -22502,7 +23233,7 @@
<comment xml:lang="ga">físeán MPEG-4</comment>
<comment xml:lang="gl">vídeo MPEG-4</comment>
<comment xml:lang="he">וידאו MPEG-4</comment>
- <comment xml:lang="hr">MPEG-4 video</comment>
+ <comment xml:lang="hr">MPEG-4 video snimka</comment>
<comment xml:lang="hu">MPEG-4 videó</comment>
<comment xml:lang="ia">Video MPEG-4</comment>
<comment xml:lang="id">Video MPEG-4</comment>
@@ -22521,7 +23252,7 @@
<comment xml:lang="pt">vídeo MPEG-4</comment>
<comment xml:lang="pt_BR">Vídeo MPEG-4</comment>
<comment xml:lang="ro">Video MPEG-4</comment>
- <comment xml:lang="ru">видео MPEG-4</comment>
+ <comment xml:lang="ru">Видео MPEG-4</comment>
<comment xml:lang="sk">Video MPEG-4</comment>
<comment xml:lang="sl">Video datoteka MPEG-4</comment>
<comment xml:lang="sq">Video MPEG-4</comment>
@@ -22563,10 +23294,10 @@
<comment xml:lang="fi">MPEG-4-äänikirja</comment>
<comment xml:lang="fo">MPEG-4 ljóðbók</comment>
<comment xml:lang="fr">livre audio MPEG-4</comment>
- <comment xml:lang="ga">leabhar fhuaim MPEG-4</comment>
+ <comment xml:lang="ga">closleabhar MPEG-4</comment>
<comment xml:lang="gl">sonlibro de MPEG-4</comment>
<comment xml:lang="he">ספר דיגיטלי MPEG-4</comment>
- <comment xml:lang="hr">MPEG-4 audio knjiga</comment>
+ <comment xml:lang="hr">MPEG-4 zvučna knjiga</comment>
<comment xml:lang="hu">MPEG-4 hangoskönyv</comment>
<comment xml:lang="ia">Libro audio MPEG-4</comment>
<comment xml:lang="id">Buku audio MPEG-4</comment>
@@ -22585,7 +23316,7 @@
<comment xml:lang="pt">livro áudio MPEG-4</comment>
<comment xml:lang="pt_BR">Áudio livro MPEG-4</comment>
<comment xml:lang="ro">Carte audio MPEG-4</comment>
- <comment xml:lang="ru">аудиокнига MPEG-4</comment>
+ <comment xml:lang="ru">Аудиокнига MPEG-4</comment>
<comment xml:lang="sk">Zvuková kniha MPEG-4</comment>
<comment xml:lang="sl">Zvočna knjiga MPEG-4</comment>
<comment xml:lang="sq">Audiolibër MPEG-4</comment>
@@ -22641,7 +23372,7 @@
<comment xml:lang="pt">ficheiro multimédia 3GPP</comment>
<comment xml:lang="pt_BR">Arquivo multimídia 3GPP</comment>
<comment xml:lang="ro">Fișier multimedia 3GPP</comment>
- <comment xml:lang="ru">мультимедийный файл 3GPP</comment>
+ <comment xml:lang="ru">Мультимедийный файл 3GPP</comment>
<comment xml:lang="sk">Súbor multimédií 3GPP</comment>
<comment xml:lang="sl">Večpredstavnostna datoteka 3GPP</comment>
<comment xml:lang="sq">File multimedial 3GPP</comment>
@@ -22707,7 +23438,7 @@
<comment xml:lang="pt">ficheiro multimédia 3GPP2</comment>
<comment xml:lang="pt_BR">Arquivo multimídia 3GPP2</comment>
<comment xml:lang="ro">Fișier multimedia 3GPP2</comment>
- <comment xml:lang="ru">мультимедийный файл 3GPP2</comment>
+ <comment xml:lang="ru">Мультимедийный файл 3GPP2</comment>
<comment xml:lang="sk">Súbor multimédií 3GPP2</comment>
<comment xml:lang="sl">Večpredstavnostna datoteka 3GPP2</comment>
<comment xml:lang="sr">3ГПП2 мултимедијална датотека</comment>
@@ -22747,7 +23478,7 @@
<comment xml:lang="ga">fuaim Amiga SoundTracker</comment>
<comment xml:lang="gl">son de Amiga SoundTracker</comment>
<comment xml:lang="he">קובץ שמע של Amiga SoundTracker</comment>
- <comment xml:lang="hr">Amiga SoundTracker audio</comment>
+ <comment xml:lang="hr">Amiga SoundTracker zvučni zapis</comment>
<comment xml:lang="hu">Amiga SoundTracker hang</comment>
<comment xml:lang="ia">Audio Amiga SoundTracker</comment>
<comment xml:lang="id">Audio Amida SoundTracker</comment>
@@ -22767,7 +23498,7 @@
<comment xml:lang="pt">áudio SoundTracker do Amiga</comment>
<comment xml:lang="pt_BR">Áudio Amiga SoundTracker</comment>
<comment xml:lang="ro">Audio Amiga SoundTracker</comment>
- <comment xml:lang="ru">аудио Amiga SoundTracker</comment>
+ <comment xml:lang="ru">Аудио Amiga SoundTracker</comment>
<comment xml:lang="sk">Zvuk Amiga SoundTracker</comment>
<comment xml:lang="sl">Zvočna datoteka Amiga SoundTracker</comment>
<comment xml:lang="sq">Audio Amiga SoundTracker</comment>
@@ -22840,7 +23571,7 @@
<comment xml:lang="ga">fuaim MP2</comment>
<comment xml:lang="gl">son MP2</comment>
<comment xml:lang="he">שמע MP2</comment>
- <comment xml:lang="hr">MP2 audio</comment>
+ <comment xml:lang="hr">MP2 zvučni zapis</comment>
<comment xml:lang="hu">MP2 hang</comment>
<comment xml:lang="ia">Audio MP2</comment>
<comment xml:lang="id">Audio MP2</comment>
@@ -22858,7 +23589,7 @@
<comment xml:lang="pt">áudio MP2</comment>
<comment xml:lang="pt_BR">Áudio MP2</comment>
<comment xml:lang="ro">Audio MP2</comment>
- <comment xml:lang="ru">аудио MP2</comment>
+ <comment xml:lang="ru">Аудио MP2</comment>
<comment xml:lang="sk">Zvuk MP2</comment>
<comment xml:lang="sl">Zvočna datoteka MP2</comment>
<comment xml:lang="sq">Audio MP2</comment>
@@ -22894,7 +23625,7 @@
<comment xml:lang="ga">fuaim MP3</comment>
<comment xml:lang="gl">son MP3</comment>
<comment xml:lang="he">שמע MP3</comment>
- <comment xml:lang="hr">MP3 audio</comment>
+ <comment xml:lang="hr">MP3 zvučni zapis</comment>
<comment xml:lang="hu">MP3 hang</comment>
<comment xml:lang="ia">Audio MP3</comment>
<comment xml:lang="id">Audio MP3</comment>
@@ -22914,7 +23645,7 @@
<comment xml:lang="pt">áudio MP3</comment>
<comment xml:lang="pt_BR">Áudio MP3</comment>
<comment xml:lang="ro">Audio MP3</comment>
- <comment xml:lang="ru">аудио MP3</comment>
+ <comment xml:lang="ru">Аудио MP3</comment>
<comment xml:lang="sk">Zvuk MP3</comment>
<comment xml:lang="sl">Zvočna datoteka MP3</comment>
<comment xml:lang="sq">Audio MP3</comment>
@@ -22972,11 +23703,11 @@
<comment xml:lang="nl">MP3-audio (gestreamd)</comment>
<comment xml:lang="nn">Strauma MP3-lyd</comment>
<comment xml:lang="oc">àudio MP3 (flux)</comment>
- <comment xml:lang="pl">Dźwięk MP3 (strumień)</comment>
+ <comment xml:lang="pl">Plik dźwiękowy MP3 (strumień)</comment>
<comment xml:lang="pt">áudio MP3 (em fluxo)</comment>
<comment xml:lang="pt_BR">Áudio MP3 (em fluxo)</comment>
<comment xml:lang="ro">Audio MP3 (flux)</comment>
- <comment xml:lang="ru">аудио MP3 (потоковое)</comment>
+ <comment xml:lang="ru">Аудио MP3 (потоковое)</comment>
<comment xml:lang="sk">Zvuk MP3 (streamovaný)</comment>
<comment xml:lang="sl">Zvočna datoteka MP3 (pretočna)</comment>
<comment xml:lang="sq">Audio MP3 (streamed)</comment>
@@ -22985,7 +23716,7 @@
<comment xml:lang="tr">MP3 sesi (akış)</comment>
<comment xml:lang="uk">звук MP3 (потоковий)</comment>
<comment xml:lang="vi">Âm thanh MP3 (chạy luồng)</comment>
- <comment xml:lang="zh_CN">MP3 流音频</comment>
+ <comment xml:lang="zh_CN">MP3 音频流媒体</comment>
<comment xml:lang="zh_TW">MP3 音訊 (串流)</comment>
<sub-class-of type="text/plain"/>
<alias type="audio/mpegurl"/>
@@ -23033,14 +23764,14 @@
<comment xml:lang="pt">lista de reprodução HTTP Live Streaming</comment>
<comment xml:lang="pt_BR">Lista de Reprodução Streaming ao Vivo de HTTP</comment>
<comment xml:lang="ro">Listă de redare difuzată ca flux HTTP</comment>
- <comment xml:lang="ru">список воспроизведения HTTP-потока</comment>
+ <comment xml:lang="ru">Список воспроизведения HTTP-потока</comment>
<comment xml:lang="sk">Zoznam stôp HTTP Live Streaming</comment>
<comment xml:lang="sl">Seznam predvajanja živega pretoka HTTP</comment>
<comment xml:lang="sr">ХТТП списак нумера Живог Протока</comment>
<comment xml:lang="sv">HTTP Live Streaming-spellista</comment>
<comment xml:lang="tr">HTTP Canlı Akış çalma listesi</comment>
<comment xml:lang="uk">список відтворення HTTP Live Streaming</comment>
- <comment xml:lang="zh_CN">HTTP 直播流播放列表</comment>
+ <comment xml:lang="zh_CN">HTTP 实时流播放列表</comment>
<comment xml:lang="zh_TW">HTTP 即時串流播放清單</comment>
<sub-class-of type="text/plain"/>
<glob pattern="*.m3u"/>
@@ -23071,7 +23802,7 @@
<comment xml:lang="ga">seinmliosta Microsoft ASX</comment>
<comment xml:lang="gl">lista de reprodución Microsoft ASX</comment>
<comment xml:lang="he">רשימת השמעה ASX (מיקרוסופט)</comment>
- <comment xml:lang="hr">Microsoft ASX popis za reprodukciju</comment>
+ <comment xml:lang="hr">Microsoft ASX popis izvođenja</comment>
<comment xml:lang="hu">Microsoft ASX lejátszólista</comment>
<comment xml:lang="ia">Lista de selection Microsoft ASX</comment>
<comment xml:lang="id">Senarai putar Microsoft ASX</comment>
@@ -23090,7 +23821,7 @@
<comment xml:lang="pt">lista de reprodução Microsoft ASX</comment>
<comment xml:lang="pt_BR">Lista de reprodução do Microsoft ASX</comment>
<comment xml:lang="ro">Listă redare Microsoft ASX</comment>
- <comment xml:lang="ru">список воспроизведения Microsoft ASX</comment>
+ <comment xml:lang="ru">Список воспроизведения Microsoft ASX</comment>
<comment xml:lang="sk">Zoznam skladieb Microsoft ASX</comment>
<comment xml:lang="sl">Seznam predvajanja Microsoft ASX</comment>
<comment xml:lang="sq">Listë titujsh Microsoft ASF</comment>
@@ -23154,7 +23885,7 @@
<comment xml:lang="pt">áudio PSF</comment>
<comment xml:lang="pt_BR">Áudio PSF</comment>
<comment xml:lang="ro">Audio PSF</comment>
- <comment xml:lang="ru">аудио PSF</comment>
+ <comment xml:lang="ru">Аудио PSF</comment>
<comment xml:lang="sk">Zvuk PSF</comment>
<comment xml:lang="sl">Zvočna datoteka PSF</comment>
<comment xml:lang="sq">Audio PSF</comment>
@@ -23192,7 +23923,7 @@
<comment xml:lang="ga">fuaim MiniPSF</comment>
<comment xml:lang="gl">son MiniPSF</comment>
<comment xml:lang="he">שמע של MiniPSP</comment>
- <comment xml:lang="hr">MiniPSF audio</comment>
+ <comment xml:lang="hr">MiniPSF zvučni zapis</comment>
<comment xml:lang="hu">MiniPSF hang</comment>
<comment xml:lang="ia">Audio MiniPSF</comment>
<comment xml:lang="id">Audio MiniPSF</comment>
@@ -23211,7 +23942,7 @@
<comment xml:lang="pt">áudio MiniPSF</comment>
<comment xml:lang="pt_BR">Áudio MiniPSF</comment>
<comment xml:lang="ro">Audio MiniPSF</comment>
- <comment xml:lang="ru">аудио MiniPSF</comment>
+ <comment xml:lang="ru">Аудио MiniPSF</comment>
<comment xml:lang="sk">Zvuk MiniPSF</comment>
<comment xml:lang="sl">Zvočna datoteka MiniPSF</comment>
<comment xml:lang="sq">Audio MiniPSF</comment>
@@ -23243,7 +23974,7 @@
<comment xml:lang="fi">PSFlib-äänikirjasto</comment>
<comment xml:lang="fo">PSFlib ljóðsavn</comment>
<comment xml:lang="fr">bibliothèque audio PSFlib</comment>
- <comment xml:lang="ga">leabharlann fhuaim PSFlib</comment>
+ <comment xml:lang="ga">leabharlann fhuaime PSFlib</comment>
<comment xml:lang="gl">Biblioteca de son PSFlib</comment>
<comment xml:lang="he">ספריית שמע PSFlib</comment>
<comment xml:lang="hr">PSFlib zvučna biblioteka</comment>
@@ -23264,7 +23995,7 @@
<comment xml:lang="pt">biblioteca áudio PSFlib</comment>
<comment xml:lang="pt_BR">Biblioteca de áudio PSFlib</comment>
<comment xml:lang="ro">Bibliotecă audio PSFlib</comment>
- <comment xml:lang="ru">фонотека PSFlib</comment>
+ <comment xml:lang="ru">Фонотека PSFlib</comment>
<comment xml:lang="sk">Zvuková knižnica PSFlib</comment>
<comment xml:lang="sl">Zvočna knjižnica PSFlib</comment>
<comment xml:lang="sq">Librari audio PSFlib</comment>
@@ -23273,7 +24004,7 @@
<comment xml:lang="tr">PSFlib ses kitaplığı</comment>
<comment xml:lang="uk">аудіобібліотека PSFlib</comment>
<comment xml:lang="vi">Thư viện âm thanh PSFlib</comment>
- <comment xml:lang="zh_CN">PSFlib 音频库文件</comment>
+ <comment xml:lang="zh_CN">PSFlib 音频库</comment>
<comment xml:lang="zh_TW">PSFlib 音訊庫</comment>
<acronym>PSFlib</acronym>
<expanded-acronym>Portable Sound Format Library</expanded-acronym>
@@ -23299,7 +24030,7 @@
<comment xml:lang="ga">fuaim Windows Media</comment>
<comment xml:lang="gl">son de Windows Media</comment>
<comment xml:lang="he">שמע של Windows Media</comment>
- <comment xml:lang="hr">Windows Media audio</comment>
+ <comment xml:lang="hr">Windows Media zvučni zapis</comment>
<comment xml:lang="hu">Windows Media hang</comment>
<comment xml:lang="ia">Audio Windows Media</comment>
<comment xml:lang="id">Audio Windows Media</comment>
@@ -23317,7 +24048,7 @@
<comment xml:lang="pt">áudio Windows Media</comment>
<comment xml:lang="pt_BR">Áudio do Windows Media</comment>
<comment xml:lang="ro">Audio Windows Media</comment>
- <comment xml:lang="ru">аудио Windows Media</comment>
+ <comment xml:lang="ru">Аудио Windows Media</comment>
<comment xml:lang="sk">Zvuk Windows Media</comment>
<comment xml:lang="sl">Zvočna datoteka Windows Media</comment>
<comment xml:lang="sq">Audio Windows Media</comment>
@@ -23351,7 +24082,7 @@
<comment xml:lang="ga">fuaim Musepack</comment>
<comment xml:lang="gl">son de Musepack</comment>
<comment xml:lang="he">שמע של Musepack</comment>
- <comment xml:lang="hr">Musepack audio</comment>
+ <comment xml:lang="hr">Musepack zvučni zapis</comment>
<comment xml:lang="hu">Musepack hang</comment>
<comment xml:lang="ia">Audio Musepack</comment>
<comment xml:lang="id">Audio Musepack</comment>
@@ -23369,7 +24100,7 @@
<comment xml:lang="pt">áudio Musepack</comment>
<comment xml:lang="pt_BR">Áudio Musepack</comment>
<comment xml:lang="ro">Audio Musepack</comment>
- <comment xml:lang="ru">аудио Musepack</comment>
+ <comment xml:lang="ru">Аудио Musepack</comment>
<comment xml:lang="sk">Zvuk Musepack</comment>
<comment xml:lang="sl">Zvočna datoteka Musepack</comment>
<comment xml:lang="sq">Audio Musepack</comment>
@@ -23390,6 +24121,7 @@
<mime-type type="audio/vnd.rn-realaudio">
<comment>RealAudio document</comment>
<comment xml:lang="ar">مستند RealAudio</comment>
+ <comment xml:lang="ast">Documentu RealAudio</comment>
<comment xml:lang="be@latin">Dakument RealAudio</comment>
<comment xml:lang="bg">Документ — RealAudio</comment>
<comment xml:lang="ca">document RealAudio</comment>
@@ -23425,7 +24157,7 @@
<comment xml:lang="pt">documento RealAudio</comment>
<comment xml:lang="pt_BR">Documento RealAudio</comment>
<comment xml:lang="ro">Document RealAudio</comment>
- <comment xml:lang="ru">документ RealAudio</comment>
+ <comment xml:lang="ru">Документ RealAudio</comment>
<comment xml:lang="sk">Dokument RealAudio</comment>
<comment xml:lang="sl">Dokument RealAudio</comment>
<comment xml:lang="sq">Dokument RealAudio</comment>
@@ -23457,7 +24189,7 @@
<comment xml:lang="fi">RealMedia-metatiedosto</comment>
<comment xml:lang="fo">RealMedia metafíla</comment>
<comment xml:lang="fr">métafichier RealMedia</comment>
- <comment xml:lang="ga">meiteachomhad RealMedia</comment>
+ <comment xml:lang="ga">Meiteachomhad RealMedia</comment>
<comment xml:lang="gl">Metaficheiro RealMedia</comment>
<comment xml:lang="he">קובץ מטא של RealMedia</comment>
<comment xml:lang="hr">RealMedia meta datoteka</comment>
@@ -23478,7 +24210,7 @@
<comment xml:lang="pt">metaficheiro RealMedia</comment>
<comment xml:lang="pt_BR">Meta arquivo do RealMedia</comment>
<comment xml:lang="ro">Metafișier RealMedia</comment>
- <comment xml:lang="ru">мета-файл RealMedia</comment>
+ <comment xml:lang="ru">Мета-файл RealMedia</comment>
<comment xml:lang="sk">RealMedia Metafile</comment>
<comment xml:lang="sl">Metadatoteka RealMedia</comment>
<comment xml:lang="sq">Metafile RealMedia</comment>
@@ -23494,6 +24226,7 @@
<mime-type type="video/vnd.rn-realvideo">
<comment>RealVideo document</comment>
<comment xml:lang="ar">مستند RealVideo</comment>
+ <comment xml:lang="ast">Documentu RealVideo</comment>
<comment xml:lang="be@latin">Dakument RealVideo</comment>
<comment xml:lang="bg">Документ — RealVideo</comment>
<comment xml:lang="ca">document RealVideo</comment>
@@ -23529,7 +24262,7 @@
<comment xml:lang="pt">documento RealVideo</comment>
<comment xml:lang="pt_BR">Documento RealVideo</comment>
<comment xml:lang="ro">Document RealVideo</comment>
- <comment xml:lang="ru">документ RealVideo</comment>
+ <comment xml:lang="ru">Документ RealVideo</comment>
<comment xml:lang="sk">Dokument RealVideo</comment>
<comment xml:lang="sl">Video datoteka RealVideo</comment>
<comment xml:lang="sq">Dokument RealVideo</comment>
@@ -23547,6 +24280,7 @@
<mime-type type="application/vnd.rn-realmedia">
<comment>RealMedia document</comment>
<comment xml:lang="ar">مستند RealMedia</comment>
+ <comment xml:lang="ast">Documentu RealMedia</comment>
<comment xml:lang="be@latin">Dakument RealMedia</comment>
<comment xml:lang="bg">Документ — RealMedia</comment>
<comment xml:lang="ca">document RealMedia</comment>
@@ -23582,7 +24316,7 @@
<comment xml:lang="pt">documento RealMedia</comment>
<comment xml:lang="pt_BR">Documento RealMedia</comment>
<comment xml:lang="ro">Document RealMedia</comment>
- <comment xml:lang="ru">документ RealMedia</comment>
+ <comment xml:lang="ru">Документ RealMedia</comment>
<comment xml:lang="sk">Dokument RealMedia</comment>
<comment xml:lang="sl">Dokument RealMedia</comment>
<comment xml:lang="sq">Dokument RealMedia</comment>
@@ -23608,6 +24342,7 @@
<mime-type type="image/vnd.rn-realpix">
<comment>RealPix document</comment>
<comment xml:lang="ar">مستند RealPix</comment>
+ <comment xml:lang="ast">Documentu RealPix</comment>
<comment xml:lang="be@latin">Dakument RealPix</comment>
<comment xml:lang="bg">Документ — RealPix</comment>
<comment xml:lang="ca">document RealPix</comment>
@@ -23643,7 +24378,7 @@
<comment xml:lang="pt">documento RealPix</comment>
<comment xml:lang="pt_BR">Documento RealPix</comment>
<comment xml:lang="ro">Document RealPix</comment>
- <comment xml:lang="ru">документ RealPix</comment>
+ <comment xml:lang="ru">Документ RealPix</comment>
<comment xml:lang="sk">Dokument RealPix</comment>
<comment xml:lang="sl">Dokument RealPix</comment>
<comment xml:lang="sq">Dokument RealPix</comment>
@@ -23659,6 +24394,7 @@
<mime-type type="text/vnd.rn-realtext">
<comment>RealText document</comment>
<comment xml:lang="ar">مستند RealText</comment>
+ <comment xml:lang="ast">Documentu RealText</comment>
<comment xml:lang="be@latin">Dakument RealText</comment>
<comment xml:lang="bg">Документ — RealText</comment>
<comment xml:lang="ca">document RealText</comment>
@@ -23694,7 +24430,7 @@
<comment xml:lang="pt">documento RealText</comment>
<comment xml:lang="pt_BR">Documento RealText</comment>
<comment xml:lang="ro">Document RealText</comment>
- <comment xml:lang="ru">документ RealText</comment>
+ <comment xml:lang="ru">Документ RealText</comment>
<comment xml:lang="sk">Dokument RealText</comment>
<comment xml:lang="sl">Dokument RealText</comment>
<comment xml:lang="sq">Dokument RealText</comment>
@@ -23729,7 +24465,7 @@
<comment xml:lang="ga">fuaim RIFF</comment>
<comment xml:lang="gl">son RIFF</comment>
<comment xml:lang="he">שמע RIFF</comment>
- <comment xml:lang="hr">RIFF audio</comment>
+ <comment xml:lang="hr">RIFF zvučni zapis</comment>
<comment xml:lang="hu">RIFF-kép</comment>
<comment xml:lang="ia">Audio RIFF</comment>
<comment xml:lang="id">Audio RIFF</comment>
@@ -23748,7 +24484,7 @@
<comment xml:lang="pt">áudio RIFF</comment>
<comment xml:lang="pt_BR">Áudio RIFF</comment>
<comment xml:lang="ro">Audio RIFF</comment>
- <comment xml:lang="ru">аудио RIFF</comment>
+ <comment xml:lang="ru">Аудио RIFF</comment>
<comment xml:lang="sk">Zvuk RIFF</comment>
<comment xml:lang="sl">Zvočna datoteka RIFF</comment>
<comment xml:lang="sq">Audio RIFF</comment>
@@ -23771,6 +24507,7 @@
<comment xml:lang="es">contenedor RIFF</comment>
<comment xml:lang="eu">RIFF edukitzailea</comment>
<comment xml:lang="fr">conteneur RIFF</comment>
+ <comment xml:lang="ga">coimeádán RIFF</comment>
<comment xml:lang="gl">Contenedor RIFF</comment>
<comment xml:lang="he">מכולת RIFF</comment>
<comment xml:lang="hr">RIFF spremnik</comment>
@@ -23820,7 +24557,7 @@
<comment xml:lang="ga">fuaim Scream Tracker 3</comment>
<comment xml:lang="gl">son Scream Tracker 3</comment>
<comment xml:lang="he">שמע של Scream Tracker 3</comment>
- <comment xml:lang="hr">Scream Tracker 3 audio</comment>
+ <comment xml:lang="hr">Scream Tracker 3 zvučni zapis</comment>
<comment xml:lang="hu">Scream Tracker 3 hang</comment>
<comment xml:lang="ia">Audio Scream Tracker 3</comment>
<comment xml:lang="id">Audio Scream Tracker 3</comment>
@@ -23839,7 +24576,7 @@
<comment xml:lang="pt">áudio Scream Tracker 3</comment>
<comment xml:lang="pt_BR">Áudio Scream Tracker 3</comment>
<comment xml:lang="ro">Audio Scream Tracker 3</comment>
- <comment xml:lang="ru">аудио Scream Tracker 3</comment>
+ <comment xml:lang="ru">Аудио Scream Tracker 3</comment>
<comment xml:lang="sk">Skladba Scream Tracker 3</comment>
<comment xml:lang="sl">Zvočna datoteka Scream Tracker 3</comment>
<comment xml:lang="sq">Audio Scream Tracker 3</comment>
@@ -23875,7 +24612,7 @@
<comment xml:lang="ga">seinmliosta MP3 ShoutCast</comment>
<comment xml:lang="gl">lista de reprodución MP3 de ShoutCast</comment>
<comment xml:lang="he">רשימת השמעה MP3 של ShoutCast</comment>
- <comment xml:lang="hr">MP3 ShoutCast popis za reprodukciju</comment>
+ <comment xml:lang="hr">MP3 ShoutCast popis izvođenja</comment>
<comment xml:lang="hu">MP3 ShoutCast-lejátszólista</comment>
<comment xml:lang="ia">Lista de selection MP3 ShoutCast</comment>
<comment xml:lang="id">Senarai putar MP3 ShoutCast</comment>
@@ -23894,7 +24631,7 @@
<comment xml:lang="pt">lista de reprodução MP3 ShoutCast</comment>
<comment xml:lang="pt_BR">Lista de reprodução MP3 ShoutCast</comment>
<comment xml:lang="ro">Listă MP3 ShoutCast</comment>
- <comment xml:lang="ru">список воспроизведения MP3 ShoutCast</comment>
+ <comment xml:lang="ru">Список воспроизведения MP3 ShoutCast</comment>
<comment xml:lang="sk">Zoznam skladieb MP3 ShoutCast</comment>
<comment xml:lang="sl">Seznam predvajanja MP3 ShoutCast</comment>
<comment xml:lang="sq">Listë titujsh MP3 ShoutCast</comment>
@@ -23936,7 +24673,7 @@
<comment xml:lang="ga">fuaim Scream Tracker</comment>
<comment xml:lang="gl">son Scream Tracker</comment>
<comment xml:lang="he">שמע של Scream Tracker</comment>
- <comment xml:lang="hr">Scream Tracker audio</comment>
+ <comment xml:lang="hr">Scream Tracker zvučni zapis</comment>
<comment xml:lang="hu">Scream Tracker hang</comment>
<comment xml:lang="ia">Audio Scream Tracker</comment>
<comment xml:lang="id">Audio Scream Tracker</comment>
@@ -23955,7 +24692,7 @@
<comment xml:lang="pt">áudio Scream Tracker</comment>
<comment xml:lang="pt_BR">Áudio Scream Tracker</comment>
<comment xml:lang="ro">Audio Scream Tracker</comment>
- <comment xml:lang="ru">аудио Scream Tracker</comment>
+ <comment xml:lang="ru">Аудио Scream Tracker</comment>
<comment xml:lang="sk">Skladba Scream Tracker</comment>
<comment xml:lang="sl">Zvočna datoteka Scream Tracker</comment>
<comment xml:lang="sq">Audio Scream Tracker</comment>
@@ -23995,7 +24732,7 @@
<comment xml:lang="ga">fuaim VOC</comment>
<comment xml:lang="gl">son VOC</comment>
<comment xml:lang="he">שמע VOC</comment>
- <comment xml:lang="hr">VOC audio</comment>
+ <comment xml:lang="hr">VOC zvučni zapis</comment>
<comment xml:lang="hu">VOC hang</comment>
<comment xml:lang="ia">Audio VOC</comment>
<comment xml:lang="id">Audio VOC</comment>
@@ -24014,7 +24751,7 @@
<comment xml:lang="pt">áudio VOC</comment>
<comment xml:lang="pt_BR">Áudio VOC</comment>
<comment xml:lang="ro">Audio VOC</comment>
- <comment xml:lang="ru">аудио VOC</comment>
+ <comment xml:lang="ru">Аудио VOC</comment>
<comment xml:lang="sk">Zvuk VOC</comment>
<comment xml:lang="sl">Zvočna datoteka VOC</comment>
<comment xml:lang="sq">Audio VOC</comment>
@@ -24049,7 +24786,7 @@
<comment xml:lang="ga">fuaim WAV</comment>
<comment xml:lang="gl">son WAV</comment>
<comment xml:lang="he">שמע WAV</comment>
- <comment xml:lang="hr">WAV audio</comment>
+ <comment xml:lang="hr">WAV zvučni zapis</comment>
<comment xml:lang="hu">WAV hang</comment>
<comment xml:lang="ia">Audio WAV</comment>
<comment xml:lang="id">Audio WAV</comment>
@@ -24068,7 +24805,7 @@
<comment xml:lang="pt">áudio WAV</comment>
<comment xml:lang="pt_BR">Áudio WAV</comment>
<comment xml:lang="ro">Audio WAV</comment>
- <comment xml:lang="ru">аудио WAV</comment>
+ <comment xml:lang="ru">Аудио WAV</comment>
<comment xml:lang="sk">Zvuk WAV</comment>
<comment xml:lang="sl">Zvočna datoteka WAV</comment>
<comment xml:lang="sq">Audio WAV</comment>
@@ -24128,7 +24865,7 @@
<comment xml:lang="pt">instrumento Scream Tracker</comment>
<comment xml:lang="pt_BR">Instrumento Scream Tracker</comment>
<comment xml:lang="ro">Instrument Scream Tracker</comment>
- <comment xml:lang="ru">инструмент Scream Tracker</comment>
+ <comment xml:lang="ru">Инструмент Scream Tracker</comment>
<comment xml:lang="sk">Nástroj pre Scream Tracker</comment>
<comment xml:lang="sl">Datoteka zvoka glasbila Scream Tracker</comment>
<comment xml:lang="sq">Instrument Scream Tracker</comment>
@@ -24166,7 +24903,7 @@
<comment xml:lang="ga">fuaim FastTracker II</comment>
<comment xml:lang="gl">son de FastTracker II</comment>
<comment xml:lang="he">שמע FastTracker II</comment>
- <comment xml:lang="hr">FastTracker II audio</comment>
+ <comment xml:lang="hr">FastTracker II zvučni zapis</comment>
<comment xml:lang="hu">FastTracker II hang</comment>
<comment xml:lang="ia">Audio FastTracker II</comment>
<comment xml:lang="id">Audio FastTracker II</comment>
@@ -24186,7 +24923,7 @@
<comment xml:lang="pt">áudio FastTracker II</comment>
<comment xml:lang="pt_BR">Áudio FastTracker II</comment>
<comment xml:lang="ro">Audio FastTracker II</comment>
- <comment xml:lang="ru">аудио FastTracker II</comment>
+ <comment xml:lang="ru">Аудио FastTracker II</comment>
<comment xml:lang="sk">Zvuk FastTracker II</comment>
<comment xml:lang="sl">Zvočna datoteka FastTracker II</comment>
<comment xml:lang="sq">Audio FastTracker II</comment>
@@ -24222,7 +24959,7 @@
<comment xml:lang="ga">fuaim TrueAudio</comment>
<comment xml:lang="gl">son Trueson</comment>
<comment xml:lang="he">שמע TrueAudio</comment>
- <comment xml:lang="hr">TrueAudio audio</comment>
+ <comment xml:lang="hr">TrueAudio zvučni zapis</comment>
<comment xml:lang="hu">TrueAudio hang</comment>
<comment xml:lang="ia">Audio TrueAudio</comment>
<comment xml:lang="id">Audio TrueAudio</comment>
@@ -24240,7 +24977,7 @@
<comment xml:lang="pt">áudio TrueAudio</comment>
<comment xml:lang="pt_BR">Áudio TrueAudio</comment>
<comment xml:lang="ro">Audio TrueAudio</comment>
- <comment xml:lang="ru">аудио TrueAudio</comment>
+ <comment xml:lang="ru">Аудио TrueAudio</comment>
<comment xml:lang="sk">Zvuk TrueAudio</comment>
<comment xml:lang="sl">Zvočna datoteka TrueAudio</comment>
<comment xml:lang="sq">Audio TrueAudio</comment>
@@ -24298,7 +25035,7 @@
<comment xml:lang="pt">imagem BMP Windows</comment>
<comment xml:lang="pt_BR">Imagem BMP do Windows</comment>
<comment xml:lang="ro">Imagine Windows BMP</comment>
- <comment xml:lang="ru">изображение Windows BMP</comment>
+ <comment xml:lang="ru">Изображение Windows BMP</comment>
<comment xml:lang="sk">Obrázok Windows BMP</comment>
<comment xml:lang="sl">Slikovna datoteka Windows BMP</comment>
<comment xml:lang="sq">Figurë Windows BMP</comment>
@@ -24360,7 +25097,7 @@
<comment xml:lang="pt">imagem WBMP</comment>
<comment xml:lang="pt_BR">Imagem WBMP</comment>
<comment xml:lang="ro">Imagine WBMP</comment>
- <comment xml:lang="ru">изображение WBMP</comment>
+ <comment xml:lang="ru">Изображение WBMP</comment>
<comment xml:lang="sk">Obrázok WBMP</comment>
<comment xml:lang="sl">Slikovna datoteka WBMP</comment>
<comment xml:lang="sq">Figurë WBMP</comment>
@@ -24393,7 +25130,7 @@
<comment xml:lang="fi">Computer Graphics -metatiedosto</comment>
<comment xml:lang="fo">Teldugrafikk metafíla</comment>
<comment xml:lang="fr">métafichier Computer Graphics</comment>
- <comment xml:lang="ga">meiteachomhad Grafaicí Ríomhaire</comment>
+ <comment xml:lang="ga">Meiteachomhad Grafaicí Ríomhaire</comment>
<comment xml:lang="gl">metaficheiro de Computer Graphics</comment>
<comment xml:lang="he">קובץ-מטה מסוג Computer Graphics</comment>
<comment xml:lang="hr">Computer Graphics meta datoteka</comment>
@@ -24415,7 +25152,7 @@
<comment xml:lang="pt">metaficheiro Computer Graphics</comment>
<comment xml:lang="pt_BR">Meta-arquivo do Computer Graphics</comment>
<comment xml:lang="ro">Metafișier Computer Graphics</comment>
- <comment xml:lang="ru">метафайл компьютерной графики</comment>
+ <comment xml:lang="ru">Метафайл компьютерной графики</comment>
<comment xml:lang="sk">Computer Graphics Metafile</comment>
<comment xml:lang="sl">Metadatoteka računalniške grafike (CGM)</comment>
<comment xml:lang="sq">Metafile Computer Graphics</comment>
@@ -24424,7 +25161,7 @@
<comment xml:lang="tr">Computer Graphics Meta dosyası</comment>
<comment xml:lang="uk">метафайл комп'ютерної графіки</comment>
<comment xml:lang="vi">Siêu tập tin đồ họa máy tính (CMF)</comment>
- <comment xml:lang="zh_CN">CGM 计算机图像元文件</comment>
+ <comment xml:lang="zh_CN">计算机图形图元文件 (CGM)</comment>
<comment xml:lang="zh_TW">CGM 影像</comment>
<glob pattern="*.cgm"/>
</mime-type>
@@ -24468,7 +25205,7 @@
<comment xml:lang="pt">fax CCITT G3</comment>
<comment xml:lang="pt_BR">Fax do CCITT G3</comment>
<comment xml:lang="ro">Fax CCITT G3</comment>
- <comment xml:lang="ru">факс CCITT G3</comment>
+ <comment xml:lang="ru">Факс CCITT G3</comment>
<comment xml:lang="sk">Fax CCITT G3</comment>
<comment xml:lang="sl">Datoteka faksimila CCITT G3</comment>
<comment xml:lang="sq">Fax CCITT G3</comment>
@@ -24523,7 +25260,7 @@
<comment xml:lang="pt">imagem de fax G3</comment>
<comment xml:lang="pt_BR">Imagem de fax G3</comment>
<comment xml:lang="ro">Imagine fax G3</comment>
- <comment xml:lang="ru">факсовое изображение G3</comment>
+ <comment xml:lang="ru">Факсовое изображение G3</comment>
<comment xml:lang="sk">Obrázok fax G3</comment>
<comment xml:lang="sl">Slikovna datoteka G3 fax</comment>
<comment xml:lang="sq">Figurë Fax G3</comment>
@@ -24532,7 +25269,7 @@
<comment xml:lang="tr">G3 fax görüntüsü</comment>
<comment xml:lang="uk">факс G3</comment>
<comment xml:lang="vi">Ảnh điện thư G3</comment>
- <comment xml:lang="zh_CN">G3 传真文档</comment>
+ <comment xml:lang="zh_CN">G3 传真图像</comment>
<comment xml:lang="zh_TW">G3 傳真圖</comment>
</mime-type>
<mime-type type="image/gif">
@@ -24577,7 +25314,7 @@
<comment xml:lang="pt">imagem GIF</comment>
<comment xml:lang="pt_BR">Imagem GIF</comment>
<comment xml:lang="ro">Imagine GIF</comment>
- <comment xml:lang="ru">изображение GIF</comment>
+ <comment xml:lang="ru">Изображение GIF</comment>
<comment xml:lang="sk">Obrázok GIF</comment>
<comment xml:lang="sl">Slikovna datoteka GIF</comment>
<comment xml:lang="sq">Figurë GIF</comment>
@@ -24593,6 +25330,16 @@
</magic>
<glob pattern="*.gif"/>
</mime-type>
+ <mime-type type="image/heif">
+ <comment>HEIF image</comment>
+ <acronym>HEIF</acronym>
+ <expanded-acronym>High Efficiency Image File</expanded-acronym>
+ <glob pattern="*.heic"/>
+ <glob pattern="*.heif"/>
+ <alias type="image/heic"/>
+ <alias type="image/heic-sequence"/>
+ <alias type="image/heif-sequence"/>
+ </mime-type>
<mime-type type="image/ief">
<comment>IEF image</comment>
<comment xml:lang="ar">صورة IEF</comment>
@@ -24634,7 +25381,7 @@
<comment xml:lang="pt">imagem IEF</comment>
<comment xml:lang="pt_BR">Imagem IEF</comment>
<comment xml:lang="ro">Imagine IEF</comment>
- <comment xml:lang="ru">изображение IEF</comment>
+ <comment xml:lang="ru">Изображение IEF</comment>
<comment xml:lang="sk">Obrázok IEF</comment>
<comment xml:lang="sl">Slikovna datoteka IEF</comment>
<comment xml:lang="sq">Figurë IEF</comment>
@@ -24688,7 +25435,7 @@
<comment xml:lang="pt">imagem JPEG</comment>
<comment xml:lang="pt_BR">Imagem JPEG</comment>
<comment xml:lang="ro">Imagine JPEG</comment>
- <comment xml:lang="ru">изображение JPEG</comment>
+ <comment xml:lang="ru">Изображение JPEG</comment>
<comment xml:lang="sk">Obrázok JPEG</comment>
<comment xml:lang="sl">Slikovna datoteka JPEG</comment>
<comment xml:lang="sq">Figurë JPEG</comment>
@@ -24708,69 +25455,164 @@
<glob pattern="*.jpe"/>
<alias type="image/pjpeg"/>
</mime-type>
- <mime-type type="image/jp2">
- <comment>JPEG-2000 image</comment>
- <comment xml:lang="ar">صورة JPEG-2000</comment>
- <comment xml:lang="be@latin">Vyjava JPEG-2000</comment>
- <comment xml:lang="bg">Изображение — JPEG-2000</comment>
- <comment xml:lang="ca">imatge JPEG-2000</comment>
- <comment xml:lang="cs">obrázek JPEG-2000</comment>
- <comment xml:lang="da">JPEG2000-billede</comment>
- <comment xml:lang="de">JPEG-2000-Bild</comment>
- <comment xml:lang="el">Εικόνα JPEG-2000</comment>
- <comment xml:lang="en_GB">JPEG-2000 image</comment>
- <comment xml:lang="eo">JPEG-2000-bildo</comment>
- <comment xml:lang="es">imagen JPEG-2000</comment>
- <comment xml:lang="eu">JPEG-2000 irudia</comment>
- <comment xml:lang="fi">JPEG-2000-kuva</comment>
- <comment xml:lang="fo">JPEG-2000 mynd</comment>
- <comment xml:lang="fr">image JPEG-2000</comment>
- <comment xml:lang="ga">íomhá JPEG-2000</comment>
- <comment xml:lang="gl">imaxe JPEG-2000</comment>
- <comment xml:lang="he">תמונת JPEG-2000</comment>
- <comment xml:lang="hr">JPEG-2000 slika</comment>
- <comment xml:lang="hu">JPEG-2000 kép</comment>
- <comment xml:lang="ia">Imagine JPEG-2000</comment>
- <comment xml:lang="id">Citra JPEG-2000</comment>
- <comment xml:lang="it">Immagine JPEG-2000</comment>
- <comment xml:lang="ja">JPEG-2000 画像</comment>
- <comment xml:lang="kk">JPEG-2000 суреті</comment>
- <comment xml:lang="ko">JPEG-2000 그림</comment>
- <comment xml:lang="lt">JPEG-2000 paveikslėlis</comment>
- <comment xml:lang="lv">JPEG-2000 attēls</comment>
- <comment xml:lang="ms">Imej JPEG-2000</comment>
- <comment xml:lang="nb">JPEG-2000-bilde</comment>
- <comment xml:lang="nl">JPEG-2000-afbeelding</comment>
- <comment xml:lang="nn">JPEG-2000-bilete</comment>
- <comment xml:lang="oc">imatge JPEG-2000</comment>
- <comment xml:lang="pl">Obraz JPEG-2000</comment>
- <comment xml:lang="pt">imagem JPEG-2000</comment>
+ <mime-type type="video/x-mjpeg">
+ <comment>MJPEG video stream</comment>
+ <acronym>MJPEG</acronym>
+ <expanded-acronym>Motion JPEG</expanded-acronym>
+ <sub-class-of type="image/jpeg"/>
+ <glob pattern="*.mjpeg"/>
+ <glob pattern="*.mjpg"/>
+ </mime-type>
+ <mime-type type="image/x-jp2-codestream">
+ <comment>JPEG-2000 codestream</comment>
+ <comment xml:lang="ca">flux de codis JPEG-2000</comment>
+ <comment xml:lang="cs">datový tok JPEG-2000</comment>
+ <comment xml:lang="de">JPEG-2000 Codestream</comment>
+ <comment xml:lang="en_GB">JPEG-2000 codestream</comment>
+ <comment xml:lang="es">secuencia de código JPEG-2000</comment>
+ <comment xml:lang="hr">JPEG-2000 kôd strujanja</comment>
+ <comment xml:lang="hu">JPEG-2000 kódfolyam</comment>
+ <comment xml:lang="id">codestream JPEG-2000</comment>
+ <comment xml:lang="it">Codestream JPEG-2000</comment>
+ <comment xml:lang="kk">JPEG-2000 код ағыны</comment>
+ <comment xml:lang="ko">JPEG-2000 코드스트림</comment>
+ <comment xml:lang="pl">Strumień kodu JPEG-2000</comment>
<comment xml:lang="pt_BR">Imagem JPEG-2000</comment>
- <comment xml:lang="ro">Imagine JPEG-2000</comment>
- <comment xml:lang="ru">изображение JPEG-2000</comment>
- <comment xml:lang="sk">Obrázok JPEG-2000</comment>
- <comment xml:lang="sl">Slikovna datoteka JPEG-2000</comment>
- <comment xml:lang="sq">Figurë JPEG-2000</comment>
- <comment xml:lang="sr">ЈПЕГ-2000 слика</comment>
- <comment xml:lang="sv">JPEG-2000-bild</comment>
- <comment xml:lang="tr">JPEG-2000 görüntüsü</comment>
- <comment xml:lang="uk">зображення JPEG-2000</comment>
- <comment xml:lang="vi">Ảnh JPEG-2000</comment>
- <comment xml:lang="zh_CN">JPEG-2000 图像</comment>
- <comment xml:lang="zh_TW">JPEG-2000 影像</comment>
+ <comment xml:lang="ru">Кодовый поток JPEG-2000</comment>
+ <comment xml:lang="sk">JPEG-2000 codestream</comment>
+ <comment xml:lang="sv">JPEG-2000-kodström</comment>
+ <comment xml:lang="uk">потік коду JPEG-2000</comment>
+ <comment xml:lang="zh_CN">JPEG-2000 码流</comment>
+ <comment xml:lang="zh_TW">JPEG-2000 代碼串流</comment>
+ <magic priority="50">
+ <match value="0xff4fff51" type="big32" offset="0"/>
+ </magic>
+ <glob pattern="*.j2c"/>
+ <glob pattern="*.j2k"/>
+ <glob pattern="*.jpc"/>
+ </mime-type>
+ <mime-type type="image/jp2">
+ <comment>JPEG-2000 JP2 image</comment>
+ <comment xml:lang="ca">imatge JPEG-2000 JP2</comment>
+ <comment xml:lang="cs">obrázek JPEG-2000 JP2</comment>
+ <comment xml:lang="de">JPEG-2000 JP2-Bild</comment>
+ <comment xml:lang="en_GB">JPEG-2000 JP2 image</comment>
+ <comment xml:lang="es">imagen JPEG-2000 JP2</comment>
+ <comment xml:lang="fi">JPEG-2000 JP2 -kuva</comment>
+ <comment xml:lang="hr">JPEG-2000 JP2 slika</comment>
+ <comment xml:lang="hu">JPEG-2000 JP2 kép</comment>
+ <comment xml:lang="id">Citra JPEG-2000 JP2</comment>
+ <comment xml:lang="it">Immagine JPEG-2000 JP2</comment>
+ <comment xml:lang="kk">JPEG-2000 JP2 суреті</comment>
+ <comment xml:lang="ko">JPEG-2000 JP2 그림</comment>
+ <comment xml:lang="pl">Obraz JP2 JPEG-2000</comment>
+ <comment xml:lang="pt_BR">Imagem JP2 de JPEG-2000</comment>
+ <comment xml:lang="ru">Изоражение JPEG-2000 JP2</comment>
+ <comment xml:lang="sk">Obrázok JPEG-2000 JP2</comment>
+ <comment xml:lang="sv">JPEG-2000 JP2-bild</comment>
+ <comment xml:lang="uk">зображення JP2 JPEG-2000</comment>
+ <comment xml:lang="zh_CN">JPEG-2000 JP2 图像</comment>
+ <comment xml:lang="zh_TW">JPEG-2000 JP2 影像</comment>
+ <acronym>JP2</acronym>
+ <expanded-acronym>JPEG-2000</expanded-acronym>
<alias type="image/jpeg2000"/>
- <alias type="image/jpx"/>
<alias type="image/jpeg2000-image"/>
<alias type="image/x-jpeg2000-image"/>
<magic priority="50">
- <match value="\xFF\x4F\xFF\x51\x00" type="string" offset="0"/>
- <match value="0x0c6a5020" type="big32" offset="3"/>
- <match value="jp2" type="string" offset="20"/>
+ <match value="\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a jp2\x20" type="string" offset="0" mask="0xffffffffffffffffffffffff0000000000000000ffffffff"/>
</magic>
<glob pattern="*.jp2"/>
- <glob pattern="*.jpx"/>
+ <glob pattern="*.jpg2"/>
+ </mime-type>
+ <mime-type type="image/jpx">
+ <comment>JPEG-2000 JPX image</comment>
+ <comment xml:lang="ca">imatge JPEG-2000 JPX</comment>
+ <comment xml:lang="cs">obrázek JPEG-2000 JPX</comment>
+ <comment xml:lang="de">JPEG-2000 JPX-Bild</comment>
+ <comment xml:lang="en_GB">JPEG-2000 JPX image</comment>
+ <comment xml:lang="es">imagen JPEG-2000 JPX</comment>
+ <comment xml:lang="fi">JPEG-2000 JPX -kuva</comment>
+ <comment xml:lang="hr">JPEG-2000 JPX slika</comment>
+ <comment xml:lang="hu">JPEG-2000 JPX kép</comment>
+ <comment xml:lang="id">Citra JPEG-2000 JPX</comment>
+ <comment xml:lang="it">Immagine JPEG-2000 JPX</comment>
+ <comment xml:lang="kk">JPEG-2000 JPX суреті</comment>
+ <comment xml:lang="ko">JPEG-2000 JPX 그림</comment>
+ <comment xml:lang="pl">Obraz JPX JPEG-2000</comment>
+ <comment xml:lang="pt_BR">Imagem JPX de JPEG-2000</comment>
+ <comment xml:lang="ru">Изображение JPEG-2000 JPX</comment>
+ <comment xml:lang="sk">Obrázok JPEG-2000 JPX</comment>
+ <comment xml:lang="sv">JPEG-2000 JPX-bild</comment>
+ <comment xml:lang="uk">зображення JPX JPEG-2000</comment>
+ <comment xml:lang="zh_CN">JPEG-2000 JPX 图像</comment>
+ <comment xml:lang="zh_TW">JPEG-2000 JPX 影像</comment>
+ <acronym>JPX</acronym>
+ <expanded-acronym>JPEG-2000 eXtended</expanded-acronym>
+ <magic priority="50">
+ <match value="\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a jpx\x20" type="string" offset="0" mask="0xffffffffffffffffffffffff0000000000000000ffffffff"/>
+ </magic>
<glob pattern="*.jpf"/>
-
+ <glob pattern="*.jpx"/>
+ </mime-type>
+ <mime-type type="image/jpm">
+ <comment>JPEG-2000 JPM image</comment>
+ <comment xml:lang="ca">imatge JPEG-2000 JPM</comment>
+ <comment xml:lang="cs">obrázek JPEG-2000 JPM</comment>
+ <comment xml:lang="de">JPEG-2000 JPM-Bild</comment>
+ <comment xml:lang="en_GB">JPEG-2000 JPM image</comment>
+ <comment xml:lang="es">imagen JPEG-2000 JPM</comment>
+ <comment xml:lang="fi">JPEG-2000 JPM -kuva</comment>
+ <comment xml:lang="hr">JPEG-2000 JPM slika</comment>
+ <comment xml:lang="hu">JPEG-2000 JPM kép</comment>
+ <comment xml:lang="id">Citra JPEG-2000 JPM</comment>
+ <comment xml:lang="it">Immagine JPEG-2000 JPM</comment>
+ <comment xml:lang="kk">JPEG-2000 JPM суреті</comment>
+ <comment xml:lang="ko">JPEG-2000 JPM 그림</comment>
+ <comment xml:lang="pl">Obraz JPM JPEG-2000</comment>
+ <comment xml:lang="pt_BR">Imagem JPM de JPEG-2000</comment>
+ <comment xml:lang="ru">Изображение JPEG-2000 JPM</comment>
+ <comment xml:lang="sk">Obrázok JPEG-2000 JPM</comment>
+ <comment xml:lang="sv">JPEG-2000 JPM-bild</comment>
+ <comment xml:lang="uk">зображення JPM JPEG-2000</comment>
+ <comment xml:lang="zh_CN">JPEG-2000 JPM 图像</comment>
+ <comment xml:lang="zh_TW">JPEG-2000 JPM 影像</comment>
+ <acronym>JPM</acronym>
+ <expanded-acronym>JPEG-2000 Mixed</expanded-acronym>
+ <magic priority="50">
+ <match value="\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a jpm\x20" type="string" offset="0" mask="0xffffffffffffffffffffffff0000000000000000ffffffff"/>
+ </magic>
+ <glob pattern="*.jpm"/>
+ <glob pattern="*.jpgm"/>
+ </mime-type>
+ <mime-type type="video/mj2">
+ <comment>JPEG-2000 MJ2 video</comment>
+ <comment xml:lang="ca">vídeo JPEG-2000 MJ2</comment>
+ <comment xml:lang="cs">video JPEG-2000 MJ2</comment>
+ <comment xml:lang="de">JPEG-2000 MJ2-Video</comment>
+ <comment xml:lang="en_GB">JPEG-2000 MJ2 video</comment>
+ <comment xml:lang="es">vídeo JPEG-2000 MJ2</comment>
+ <comment xml:lang="fi">JPEG-2000 MJ2 -video</comment>
+ <comment xml:lang="hr">JPEG-2000 MJ2 video snimka</comment>
+ <comment xml:lang="hu">JPEG-2000 MJ2 videó</comment>
+ <comment xml:lang="id">Video JPEG-2000 MJ2</comment>
+ <comment xml:lang="it">Video JPEG-2000 MJ2</comment>
+ <comment xml:lang="kk">JPEG-2000 MJ2 видеосы</comment>
+ <comment xml:lang="ko">JPEG-2000 MJ2 동영상</comment>
+ <comment xml:lang="pl">Plik wideo MJ2 JPEG-2000</comment>
+ <comment xml:lang="pt_BR">Imagem MJ2 de JPEG-2000</comment>
+ <comment xml:lang="ru">Видео JPEG-2000 MJ2</comment>
+ <comment xml:lang="sk">Video JPEG-2000 MJ2</comment>
+ <comment xml:lang="sv">JPEG-2000 MJ2-bild</comment>
+ <comment xml:lang="uk">зображення MJ2 JPEG-2000</comment>
+ <comment xml:lang="zh_CN">JPEG-2000 MJ2 视频</comment>
+ <comment xml:lang="zh_TW">JPEG-2000 MJ2 視訊</comment>
+ <acronym>MJ2</acronym>
+ <expanded-acronym>Motion JPEG-2000</expanded-acronym>
+ <magic priority="50">
+ <match value="\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a mjp2" type="string" offset="0" mask="0xffffffffffffffffffffffff0000000000000000ffffffff"/>
+ </magic>
+ <glob pattern="*.mj2"/>
+ <glob pattern="*.mjp2"/>
</mime-type>
<mime-type type="image/openraster">
<comment>OpenRaster archiving image</comment>
@@ -24807,14 +25649,14 @@
<comment xml:lang="pt">imagem arquivo OpenRaster</comment>
<comment xml:lang="pt_BR">Imagem de arquivamento OpenRaster</comment>
<comment xml:lang="ro">Arhivă imagine OpenRaster</comment>
- <comment xml:lang="ru">архивное изображение OpenRaster</comment>
+ <comment xml:lang="ru">Архивное изображение OpenRaster</comment>
<comment xml:lang="sk">Archivačný obrázok OpenRaster</comment>
<comment xml:lang="sl">Odtis arhiva OpenRaster</comment>
<comment xml:lang="sr">слика Опен Растер архивирања</comment>
<comment xml:lang="sv">OpenRaster-arkivbild</comment>
<comment xml:lang="tr">OpenRaster arşivleme görüntüsü</comment>
<comment xml:lang="uk">архівоване зображення OpenRaster</comment>
- <comment xml:lang="zh_CN">OpenRaster 归档映像</comment>
+ <comment xml:lang="zh_CN">OpenRaster 归档图像</comment>
<comment xml:lang="zh_TW">OpenRaster 封存影像</comment>
<sub-class-of type="application/zip"/>
<magic priority="70">
@@ -24864,7 +25706,7 @@
<comment xml:lang="pt">superfície DirectDraw</comment>
<comment xml:lang="pt_BR">Superfície do DirectDraw</comment>
<comment xml:lang="ro">Suprafață DirectDraw</comment>
- <comment xml:lang="ru">плоскость DirectDraw</comment>
+ <comment xml:lang="ru">Плоскость DirectDraw</comment>
<comment xml:lang="sk">Plocha DirectDraw</comment>
<comment xml:lang="sl">Datoteka predmeta DirectDraw</comment>
<comment xml:lang="sq">Superfaqe DirectDraw</comment>
@@ -24899,7 +25741,7 @@
<comment xml:lang="ga">cúrsóir X11</comment>
<comment xml:lang="gl">Cursor X11</comment>
<comment xml:lang="he">סמן של X11</comment>
- <comment xml:lang="hr">X11 kursor</comment>
+ <comment xml:lang="hr">X11 pokazivač</comment>
<comment xml:lang="hu">X11 kurzor</comment>
<comment xml:lang="ia">Cursor X11</comment>
<comment xml:lang="id">Kursor X11</comment>
@@ -24917,7 +25759,7 @@
<comment xml:lang="pt">cursor X11</comment>
<comment xml:lang="pt_BR">Cursor do X11</comment>
<comment xml:lang="ro">Cursor X11</comment>
- <comment xml:lang="ru">курсор X11</comment>
+ <comment xml:lang="ru">Курсор X11</comment>
<comment xml:lang="sk">Kurzor X11</comment>
<comment xml:lang="sl">Datoteka kazalke X11</comment>
<comment xml:lang="sq">Kursor X11</comment>
@@ -24971,7 +25813,7 @@
<comment xml:lang="pt">imagem EXR</comment>
<comment xml:lang="pt_BR">Imagem EXR</comment>
<comment xml:lang="ro">Imagine EXR</comment>
- <comment xml:lang="ru">изображение EXR</comment>
+ <comment xml:lang="ru">Изображение EXR</comment>
<comment xml:lang="sk">Obrázok EXR</comment>
<comment xml:lang="sl">Slikovna datoteka EXR</comment>
<comment xml:lang="sq">Figurë EXR</comment>
@@ -25026,7 +25868,7 @@
<comment xml:lang="pt">desenho Quickdraw/PICT de Macintosh</comment>
<comment xml:lang="pt_BR">Desenho do Macintosh Quickdraw/PICT</comment>
<comment xml:lang="ro">Desen Macintosh Quickdraw/PICT</comment>
- <comment xml:lang="ru">рисунок Macintosh Quickdraw/PICT</comment>
+ <comment xml:lang="ru">Рисунок Macintosh Quickdraw/PICT</comment>
<comment xml:lang="sk">Kresba Macintosh QuickDraw/PICT</comment>
<comment xml:lang="sl">Datoteka risbe Macintosh Quickdraw/PICT</comment>
<comment xml:lang="sq">Vizatim Macintosh Quickdraw/PICT</comment>
@@ -25097,7 +25939,7 @@
<comment xml:lang="pt">imagem UFRaw ID</comment>
<comment xml:lang="pt_BR">Imagem ID do UFRaw</comment>
<comment xml:lang="ro">ID imagine UFRaw</comment>
- <comment xml:lang="ru">изображение UFRaw ID</comment>
+ <comment xml:lang="ru">Изображение UFRaw ID</comment>
<comment xml:lang="sk">Obrázok ID UFRaw</comment>
<comment xml:lang="sl">Slikovna datoteka UFRaw ID</comment>
<comment xml:lang="sq">Figurë UFRaw ID</comment>
@@ -25130,7 +25972,7 @@
<comment xml:lang="fi">digitaalinen raakakuva</comment>
<comment xml:lang="fo">talgild rámynd</comment>
<comment xml:lang="fr">image brute numérique</comment>
- <comment xml:lang="ga">amhíomhá digiteach</comment>
+ <comment xml:lang="ga">amhíomhá dhigiteach</comment>
<comment xml:lang="gl">imaxe en bruto dixital</comment>
<comment xml:lang="he">תמונה דיגטלית גולמית</comment>
<comment xml:lang="hr">Digitalna osnovna slika</comment>
@@ -25151,7 +25993,7 @@
<comment xml:lang="pt">imagem digital em bruto</comment>
<comment xml:lang="pt_BR">Imagem digital bruta</comment>
<comment xml:lang="ro">imagine digitală brută</comment>
- <comment xml:lang="ru">необработанные цифровые изображения</comment>
+ <comment xml:lang="ru">Необработанное цифровое изображение</comment>
<comment xml:lang="sk">Digitálny surový obrázok</comment>
<comment xml:lang="sl">surova digitalna slika</comment>
<comment xml:lang="sq">Figurë raw dixhitale</comment>
@@ -25201,7 +26043,7 @@
<comment xml:lang="pt">negativo Adobe DNG</comment>
<comment xml:lang="pt_BR">Negativo DNG da Adobe</comment>
<comment xml:lang="ro">Negativ Adobe DNG</comment>
- <comment xml:lang="ru">негатив Adobe DNG</comment>
+ <comment xml:lang="ru">Негатив Adobe DNG</comment>
<comment xml:lang="sk">Adobe Digital Negative (DNG)</comment>
<comment xml:lang="sl">Datoteka negativa Adobe DNG</comment>
<comment xml:lang="sq">Negativ Adobe DNG</comment>
@@ -25258,7 +26100,7 @@
<comment xml:lang="pt">imagem em bruto Canon CRW</comment>
<comment xml:lang="pt_BR">Imagem bruta CRW da Canon</comment>
<comment xml:lang="ro">Imagine brută Canon CRW</comment>
- <comment xml:lang="ru">необработанное изображение Canon CRW</comment>
+ <comment xml:lang="ru">Необработанное изображение Canon CRW</comment>
<comment xml:lang="sk">Surový obrázok Canon CRW</comment>
<comment xml:lang="sl">Surova slikovna datoteka Canon CRW</comment>
<comment xml:lang="sq">Figurë raw Canon CRW</comment>
@@ -25267,7 +26109,7 @@
<comment xml:lang="tr">Canon CRW ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив CRW Canon</comment>
<comment xml:lang="vi">Ảnh thô Canon CRW</comment>
- <comment xml:lang="zh_CN">Canon CRW 原始图像</comment>
+ <comment xml:lang="zh_CN">佳能 CRW 原始图像</comment>
<comment xml:lang="zh_TW">Canon CRW 原生影像</comment>
<acronym>CRW</acronym>
<expanded-acronym>Canon RaW</expanded-acronym>
@@ -25316,7 +26158,7 @@
<comment xml:lang="pt">imagem em bruto Canon CR2</comment>
<comment xml:lang="pt_BR">Imagem bruta CR2 da Canon</comment>
<comment xml:lang="ro">Imagine brută Canon CR2</comment>
- <comment xml:lang="ru">необработанное изображение Canon CR2</comment>
+ <comment xml:lang="ru">Необработанное изображение Canon CR2</comment>
<comment xml:lang="sk">Surový obrázok Canon CR2</comment>
<comment xml:lang="sl">Surova slikovna datoteka Canon CR2</comment>
<comment xml:lang="sq">Figurë raw Canon CR2</comment>
@@ -25325,7 +26167,7 @@
<comment xml:lang="tr">Canon CR2 ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив CR2 Canon</comment>
<comment xml:lang="vi">Ảnh thô Canon CR2</comment>
- <comment xml:lang="zh_CN">Canon CR2 原始图像</comment>
+ <comment xml:lang="zh_CN">佳能 CR2 原始图像</comment>
<comment xml:lang="zh_TW">Canon CR2 原生影像</comment>
<acronym>CR2</acronym>
<expanded-acronym>Canon Raw 2</expanded-acronym>
@@ -25371,7 +26213,7 @@
<comment xml:lang="pt">imagem em bruto Fuji RAF</comment>
<comment xml:lang="pt_BR">Imagem bruta RAF da Fuji</comment>
<comment xml:lang="ro">Imagine brută Fuji RAF</comment>
- <comment xml:lang="ru">необработанное изображение Fuji RAF</comment>
+ <comment xml:lang="ru">Необработанное изображение Fuji RAF</comment>
<comment xml:lang="sk">Surový obrázok Fuji RAF</comment>
<comment xml:lang="sl">Surova slikovna datoteka Fuji RAF</comment>
<comment xml:lang="sq">Figurë raw Fuji RAF</comment>
@@ -25380,7 +26222,7 @@
<comment xml:lang="tr">Fuji RAF ham görüntüsü</comment>
<comment xml:lang="uk">Цифровий негатив RAF Fuji</comment>
<comment xml:lang="vi">Ảnh thô Fuji RAF</comment>
- <comment xml:lang="zh_CN">富士RAF 原始图像</comment>
+ <comment xml:lang="zh_CN">富士 RAF 原始图像</comment>
<comment xml:lang="zh_TW">Fuji RAF 原生影像</comment>
<acronym>RAF</acronym>
<expanded-acronym>RAw Format</expanded-acronym>
@@ -25427,7 +26269,7 @@
<comment xml:lang="pt">imagem em bruto Kodak DCR</comment>
<comment xml:lang="pt_BR">Imagem bruta DCR da Kodak</comment>
<comment xml:lang="ro">Imagine brută Kodak DCR</comment>
- <comment xml:lang="ru">необработанное изображение Kodak DCR</comment>
+ <comment xml:lang="ru">Необработанное изображение Kodak DCR</comment>
<comment xml:lang="sk">Surový obrázok Kodak DCR</comment>
<comment xml:lang="sl">Surova slikovna datoteka Kodak DCR</comment>
<comment xml:lang="sq">Figurë raw Kodak DCR</comment>
@@ -25436,7 +26278,7 @@
<comment xml:lang="tr">Kodak DCR ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив DCR Kodak</comment>
<comment xml:lang="vi">Ảnh thô Kodak DCR</comment>
- <comment xml:lang="zh_CN">Kodak DCR 原始图像</comment>
+ <comment xml:lang="zh_CN">柯达 DCR 原始图像</comment>
<comment xml:lang="zh_TW">Kodak DCR 原生影像</comment>
<acronym>DCR</acronym>
<expanded-acronym>Digital Camera Raw</expanded-acronym>
@@ -25481,7 +26323,7 @@
<comment xml:lang="pt">imagem em bruto Kodak K25</comment>
<comment xml:lang="pt_BR">Imagem bruta K25 da Kodak</comment>
<comment xml:lang="ro">Imagine brută Kodak K25</comment>
- <comment xml:lang="ru">необработанное изображение Kodak K25</comment>
+ <comment xml:lang="ru">Необработанное изображение Kodak K25</comment>
<comment xml:lang="sk">Surový obrázok Kodak K25</comment>
<comment xml:lang="sl">Surova slikovna datoteka Kodak K25</comment>
<comment xml:lang="sq">Figurë raw Kodak K25</comment>
@@ -25490,7 +26332,7 @@
<comment xml:lang="tr">Kodak K25 ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив K25 Kodak</comment>
<comment xml:lang="vi">Ảnh thô Kodak K25</comment>
- <comment xml:lang="zh_CN">Kodak K25 原始图像</comment>
+ <comment xml:lang="zh_CN">柯达 K25 原始图像</comment>
<comment xml:lang="zh_TW">Kodak K25 原生影像</comment>
<acronym>K25</acronym>
<expanded-acronym>Kodak DC25</expanded-acronym>
@@ -25535,7 +26377,7 @@
<comment xml:lang="pt">imagem em bruto Kodak KDC</comment>
<comment xml:lang="pt_BR">Imagem bruta KDC da Kodak</comment>
<comment xml:lang="ro">Imagine brută Kodak KDC</comment>
- <comment xml:lang="ru">необработанное изображение Kodak KDC</comment>
+ <comment xml:lang="ru">Необработанное изображение Kodak KDC</comment>
<comment xml:lang="sk">Surový obrázok Kodak KDC</comment>
<comment xml:lang="sl">Surova slikovna datoteka Kodak KDC</comment>
<comment xml:lang="sq">Figurë raw Kodak KDC</comment>
@@ -25544,7 +26386,7 @@
<comment xml:lang="tr">Kodak KDC ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив KDC Kodak</comment>
<comment xml:lang="vi">Ảnh thô Kodak KDC</comment>
- <comment xml:lang="zh_CN">Kodak KDC 原始图像</comment>
+ <comment xml:lang="zh_CN">柯达 KDC 原始图像</comment>
<comment xml:lang="zh_TW">Kodak KDC 原生影像</comment>
<acronym>KDC</acronym>
<expanded-acronym>Kodak Digital Camera</expanded-acronym>
@@ -25592,7 +26434,7 @@
<comment xml:lang="pt">imagem em bruto Minolta MRW</comment>
<comment xml:lang="pt_BR">Imagem bruta MRW do Minolta</comment>
<comment xml:lang="ro">Imagine brută Minolta MRW</comment>
- <comment xml:lang="ru">необработанное изображение Minolta MRW</comment>
+ <comment xml:lang="ru">Необработанное изображение Minolta MRW</comment>
<comment xml:lang="sk">Surový obrázok Minolta MRW</comment>
<comment xml:lang="sl">Surova slikovna datoteka Minolta MRW</comment>
<comment xml:lang="sq">Figurë raw Minolta MRW</comment>
@@ -25601,7 +26443,7 @@
<comment xml:lang="tr">Minolta MRW ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив MRW Minolta</comment>
<comment xml:lang="vi">Ảnh thô Minolta MRW</comment>
- <comment xml:lang="zh_CN">Minolta MRW 原始图像</comment>
+ <comment xml:lang="zh_CN">美能达 MRW 原始图像</comment>
<comment xml:lang="zh_TW">Minolta MRW 原生影像</comment>
<acronym>MRW</acronym>
<expanded-acronym>Minolta RaW</expanded-acronym>
@@ -25648,7 +26490,7 @@
<comment xml:lang="pt">imagem em bruto Nikon NEF</comment>
<comment xml:lang="pt_BR">Imagem bruta NEF da Nikon</comment>
<comment xml:lang="ro">Imagine brută Nikon NEF</comment>
- <comment xml:lang="ru">необработанное изображение Nikon NEF</comment>
+ <comment xml:lang="ru">Необработанное изображение Nikon NEF</comment>
<comment xml:lang="sk">Surový obrázok Nikon NEF</comment>
<comment xml:lang="sl">Surova slikovna datoteka Nikon NEF</comment>
<comment xml:lang="sq">Figurë raw Nikon NEF</comment>
@@ -25657,7 +26499,7 @@
<comment xml:lang="tr">Nikon NEF ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив NEF Nikon</comment>
<comment xml:lang="vi">Ảnh thô Nikon NEF</comment>
- <comment xml:lang="zh_CN">Nikon NEF 原始图像</comment>
+ <comment xml:lang="zh_CN">尼康 NEF 原始图像</comment>
<comment xml:lang="zh_TW">Nikon NEF 原生影像</comment>
<acronym>NEF</acronym>
<expanded-acronym>Nikon Electronic Format</expanded-acronym>
@@ -25703,7 +26545,7 @@
<comment xml:lang="pt">imagem em bruto Olympus ORF</comment>
<comment xml:lang="pt_BR">Imagem bruta ORF da Olympus</comment>
<comment xml:lang="ro">Imagine brută Olympus ORF</comment>
- <comment xml:lang="ru">необработанное изображение Olympus ORF</comment>
+ <comment xml:lang="ru">Необработанное изображение Olympus ORF</comment>
<comment xml:lang="sk">Surový obrázok Olympus ORF</comment>
<comment xml:lang="sl">Surova slikovna datoteka Olympus ORF</comment>
<comment xml:lang="sq">Figurë raw Olympus ORF</comment>
@@ -25712,7 +26554,7 @@
<comment xml:lang="tr">Olympus ORF ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив ORF Olympus</comment>
<comment xml:lang="vi">Ảnh thô Olympus ORF</comment>
- <comment xml:lang="zh_CN">Olympus ORF 原始图像</comment>
+ <comment xml:lang="zh_CN">奥林巴斯 ORF 原始图像</comment>
<comment xml:lang="zh_TW">Olympus ORF 原生影像</comment>
<acronym>ORF</acronym>
<expanded-acronym>Olympus Raw Format</expanded-acronym>
@@ -25727,7 +26569,7 @@
</magic>
<glob pattern="*.orf"/>
</mime-type>
- <mime-type type="image/x-panasonic-raw">
+ <mime-type type="image/x-panasonic-rw">
<comment>Panasonic raw image</comment>
<comment xml:lang="ar">صورة Panasonic خامة</comment>
<comment xml:lang="be@latin">Suvoraja vyjava Panasonic</comment>
@@ -25764,7 +26606,7 @@
<comment xml:lang="pt">imagem em bruto Panasonic</comment>
<comment xml:lang="pt_BR">Imagem bruta da Panasonic</comment>
<comment xml:lang="ro">Imagine brută Panasonic</comment>
- <comment xml:lang="ru">необработанное изображение Panasonic</comment>
+ <comment xml:lang="ru">Необработанное изображение Panasonic</comment>
<comment xml:lang="sk">Surový obrázok Panasonic</comment>
<comment xml:lang="sl">Surova slikovna datoteka Panasonic</comment>
<comment xml:lang="sq">Figurë raw Panasonic</comment>
@@ -25773,7 +26615,7 @@
<comment xml:lang="tr">Panasonic ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив Panasonic</comment>
<comment xml:lang="vi">Ảnh thô Panasonic</comment>
- <comment xml:lang="zh_CN">Panasonic 原始图像</comment>
+ <comment xml:lang="zh_CN">松下原始图像</comment>
<comment xml:lang="zh_TW">Panasonic 原生影像</comment>
<sub-class-of type="image/x-dcraw"/>
<magic priority="50">
@@ -25781,8 +26623,9 @@
<match value="IIU\x00\x08\x00\x00\x00" type="string" offset="0"/>
</magic>
<glob pattern="*.raw"/>
+ <alias type="image/x-panasonic-raw"/>
</mime-type>
- <mime-type type="image/x-panasonic-raw2">
+ <mime-type type="image/x-panasonic-rw2">
<comment>Panasonic raw2 image</comment>
<comment xml:lang="bg">Изображение — Panasonic raw2</comment>
<comment xml:lang="ca">imatge «RAW2» de Panasonic</comment>
@@ -25795,6 +26638,7 @@
<comment xml:lang="eu">Panasonic raw2 irudia</comment>
<comment xml:lang="fi">Panasonic raw2 -kuva</comment>
<comment xml:lang="fr">image raw2 Panasonic</comment>
+ <comment xml:lang="ga">íomhá raw2 Panasonic</comment>
<comment xml:lang="gl">imaxe en bruto raw2 de Panasonic</comment>
<comment xml:lang="he">תמונת raw2 של Panasonic</comment>
<comment xml:lang="hr">Panasonic raw2 image</comment>
@@ -25811,14 +26655,14 @@
<comment xml:lang="pl">Obraz raw2 Panasonic</comment>
<comment xml:lang="pt">imagem em bruto Panasonic</comment>
<comment xml:lang="pt_BR">Imagem raw2 da Panasonic</comment>
- <comment xml:lang="ru">необработанное изображение Panasonic RAW 2</comment>
+ <comment xml:lang="ru">Необработанное изображение Panasonic raw2</comment>
<comment xml:lang="sk">Surový obrázok Panasonic raw2</comment>
<comment xml:lang="sl">Slikovna datoteka Panasonic raw2</comment>
<comment xml:lang="sr">Панасоник сирова2 слика</comment>
<comment xml:lang="sv">Panasonic raw2-bild</comment>
<comment xml:lang="tr">Panasonic raw2 görüntüsü</comment>
<comment xml:lang="uk">зображення формату raw2 Panasonic</comment>
- <comment xml:lang="zh_CN">Panasonic raw2 图像</comment>
+ <comment xml:lang="zh_CN">松下 raw2 图像</comment>
<comment xml:lang="zh_TW">Panasonic raw2 影像</comment>
<sub-class-of type="image/x-dcraw"/>
<magic priority="50">
@@ -25826,6 +26670,7 @@
<match value="IIU\x00\x18\x00\x00\x00" type="string" offset="0"/>
</magic>
<glob pattern="*.rw2"/>
+ <alias type="image/x-panasonic-raw2"/>
</mime-type>
<mime-type type="image/x-pentax-pef">
<comment>Pentax PEF raw image</comment>
@@ -25864,7 +26709,7 @@
<comment xml:lang="pt">imagem em bruto Pentax PEF</comment>
<comment xml:lang="pt_BR">Imagem bruta PEF da Pentax</comment>
<comment xml:lang="ro">Imagine brută Pentax PEF</comment>
- <comment xml:lang="ru">необработанное изображение Pentax PEF</comment>
+ <comment xml:lang="ru">Необработанное изображение Pentax PEF</comment>
<comment xml:lang="sk">Surový obrázok Pentax PEF</comment>
<comment xml:lang="sl">Surova slikovna datoteka Pentax PEF</comment>
<comment xml:lang="sq">Figurë raw Pentax PEF</comment>
@@ -25873,7 +26718,7 @@
<comment xml:lang="tr">Pentax PEF ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив PEF Pentax</comment>
<comment xml:lang="vi">Ảnh thô Pentax PEF</comment>
- <comment xml:lang="zh_CN">Pentax PEF 原始图像</comment>
+ <comment xml:lang="zh_CN">宾得 PEF 原始图像</comment>
<comment xml:lang="zh_TW">Pentax PEF 原生影像</comment>
<acronym>PEF</acronym>
<expanded-acronym>Pentax Electronic Format</expanded-acronym>
@@ -25918,7 +26763,7 @@
<comment xml:lang="pt">imagem em bruto Sigma X3F</comment>
<comment xml:lang="pt_BR">Imagem bruta X3F da Sigma</comment>
<comment xml:lang="ro">Imagine brută Sigma X3F</comment>
- <comment xml:lang="ru">необработанное изображение Sigma X3F</comment>
+ <comment xml:lang="ru">Необработанное изображение Sigma X3F</comment>
<comment xml:lang="sk">Surový obrázok Sigma X3F</comment>
<comment xml:lang="sl">Surova slikovna datoteka Sigma X3F</comment>
<comment xml:lang="sq">Fifurë raw Sigma X3F</comment>
@@ -25927,7 +26772,7 @@
<comment xml:lang="tr">Sigma X3F ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив X3F Sigma</comment>
<comment xml:lang="vi">Ảnh thô Sigma X3F</comment>
- <comment xml:lang="zh_CN">Sigma X3F 原始图像</comment>
+ <comment xml:lang="zh_CN">适马 X3F 原始图像</comment>
<comment xml:lang="zh_TW">Sigma X3F 原生影像</comment>
<acronym>X3F</acronym>
<expanded-acronym>X3 Foveon</expanded-acronym>
@@ -25978,7 +26823,7 @@
<comment xml:lang="pt">imagem em bruto Sony SRF</comment>
<comment xml:lang="pt_BR">Imagem bruta SRF da Sony</comment>
<comment xml:lang="ro">Imagine brută Sony SRF</comment>
- <comment xml:lang="ru">необработанное изображение Sony SRF</comment>
+ <comment xml:lang="ru">Необработанное изображение Sony SRF</comment>
<comment xml:lang="sk">Surový obrázok Sony SRF</comment>
<comment xml:lang="sl">Surova slikovna datoteka Sony SRF</comment>
<comment xml:lang="sq">Figurë raw Sony SRF</comment>
@@ -25987,7 +26832,7 @@
<comment xml:lang="tr">Sony SRF ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив SRF Sony</comment>
<comment xml:lang="vi">Ảnh thô Sony SRF</comment>
- <comment xml:lang="zh_CN">Sony SRF 原始映像</comment>
+ <comment xml:lang="zh_CN">索尼 SRF 原始映像</comment>
<comment xml:lang="zh_TW">Sony SRF 原生影像</comment>
<acronym>SRF</acronym>
<expanded-acronym>Sony Raw Format</expanded-acronym>
@@ -26032,7 +26877,7 @@
<comment xml:lang="pt">imagem em bruto Sony SR2</comment>
<comment xml:lang="pt_BR">Imagem bruta SR2 da Sony</comment>
<comment xml:lang="ro">Imagine brută Sony SR2</comment>
- <comment xml:lang="ru">необработанное изображение Sony SR2</comment>
+ <comment xml:lang="ru">Необработанное изображение Sony SR2</comment>
<comment xml:lang="sk">Surový obrázok Sony SR2</comment>
<comment xml:lang="sl">Surova slikovna datoteka Sony SR2</comment>
<comment xml:lang="sq">Figurë raw Sony SR2</comment>
@@ -26041,7 +26886,7 @@
<comment xml:lang="tr">Sony SR2 ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив SR2 Sony</comment>
<comment xml:lang="vi">Ảnh thô Sony SR2</comment>
- <comment xml:lang="zh_CN">Sony SR2 原始映像</comment>
+ <comment xml:lang="zh_CN">索尼 SR2 原始映像</comment>
<comment xml:lang="zh_TW">Sony SR2 原生影像</comment>
<acronym>SR2</acronym>
<expanded-acronym>Sony Raw format 2</expanded-acronym>
@@ -26086,7 +26931,7 @@
<comment xml:lang="pt">imagem em bruto Sony ARW</comment>
<comment xml:lang="pt_BR">Imagem bruta ARW da Sony</comment>
<comment xml:lang="ro">Imagine brută Sony ARW</comment>
- <comment xml:lang="ru">необработанное изображение Sony ARW</comment>
+ <comment xml:lang="ru">Необработанное изображение Sony ARW</comment>
<comment xml:lang="sk">Surový obrázok Sony ARW</comment>
<comment xml:lang="sl">Surova slikovna datoteka Sony ARW</comment>
<comment xml:lang="sq">Figurë raw Sony ARW</comment>
@@ -26095,7 +26940,7 @@
<comment xml:lang="tr">Sony ARW ham görüntüsü</comment>
<comment xml:lang="uk">цифровий негатив ARW Sony</comment>
<comment xml:lang="vi">Ảnh thô Sony ARW</comment>
- <comment xml:lang="zh_CN">Sony ARW 原始映像</comment>
+ <comment xml:lang="zh_CN">索尼 ARW 原始映像</comment>
<comment xml:lang="zh_TW">Sony ARW 原生影像</comment>
<acronym>ARW</acronym>
<expanded-acronym>Alpha Raw format</expanded-acronym>
@@ -26144,7 +26989,7 @@
<comment xml:lang="pt">imagem PNG</comment>
<comment xml:lang="pt_BR">Imagem PNG</comment>
<comment xml:lang="ro">Imagine PNG</comment>
- <comment xml:lang="ru">изображение PNG</comment>
+ <comment xml:lang="ru">Изображение PNG</comment>
<comment xml:lang="sk">Obrázok PNG</comment>
<comment xml:lang="sl">Slikovna datoteka PNG</comment>
<comment xml:lang="sq">Figurë PNG</comment>
@@ -26175,7 +27020,7 @@
<comment xml:lang="eu">'Run Lenght Encoded' bitmap irudia</comment>
<comment xml:lang="fi">RLE-koodattu bittikartta</comment>
<comment xml:lang="fr">image matricielle Run Length Encoded</comment>
- <comment xml:lang="ga">íomhá mhapa giotáin Run Length Encoded</comment>
+ <comment xml:lang="ga">íomhá ghiotánmhapach ionchódaithe fad reatha</comment>
<comment xml:lang="gl">mapa de bits con codificación do tamaño durante a execución</comment>
<comment xml:lang="he">מקודד מפת סיביות של Run Length</comment>
<comment xml:lang="hr">Run Length Encoded bitmap slika</comment>
@@ -26196,7 +27041,7 @@
<comment xml:lang="pt">mapa de bitas Run Length Encoded</comment>
<comment xml:lang="pt_BR">Classe de comprimento imagem bitmap codificada</comment>
<comment xml:lang="ro">Imagine bitmap codată RLE</comment>
- <comment xml:lang="ru">растровое изображение (сжатое RLE)</comment>
+ <comment xml:lang="ru">Растровое изображение, сжатое RLE</comment>
<comment xml:lang="sk">Bitmapový obrázok Run Length Encoded</comment>
<comment xml:lang="sl">Zaporedno kodirana bitna slika (RLE)</comment>
<comment xml:lang="sq">Figurë bitmap RLE (Run Length Encoded)</comment>
@@ -26247,7 +27092,7 @@
<comment xml:lang="pt">imagem SVG</comment>
<comment xml:lang="pt_BR">Imagem SVG</comment>
<comment xml:lang="ro">Imagine SVG</comment>
- <comment xml:lang="ru">изображение SVG</comment>
+ <comment xml:lang="ru">Изображение SVG</comment>
<comment xml:lang="sk">Obrázok SVG</comment>
<comment xml:lang="sl">Slikovna vektorska datoteka SVG</comment>
<comment xml:lang="sq">Figurë SVG</comment>
@@ -26287,7 +27132,7 @@
<comment xml:lang="ga">íomhá SVG comhbhrúite</comment>
<comment xml:lang="gl">imaxe SVG comprimida</comment>
<comment xml:lang="he">תמונת SVG מכווצת</comment>
- <comment xml:lang="hr">komprimirana SVG slika</comment>
+ <comment xml:lang="hr">Sažeta SVG slika</comment>
<comment xml:lang="hu">tömörített SVG kép</comment>
<comment xml:lang="ia">Imagine SVG comprimite</comment>
<comment xml:lang="id">Citra SVG terkompresi</comment>
@@ -26305,7 +27150,7 @@
<comment xml:lang="pt">imagem SVG comprimida</comment>
<comment xml:lang="pt_BR">Imagem SVG compactada</comment>
<comment xml:lang="ro">imagine comprimată SVG</comment>
- <comment xml:lang="ru">сжатое изображение SVG</comment>
+ <comment xml:lang="ru">Сжатое изображение SVG</comment>
<comment xml:lang="sk">Komprimovaný obrázok SVG</comment>
<comment xml:lang="sl">Slikovna datoteka SVG (stisnjena)</comment>
<comment xml:lang="sq">Figurë SVG e kompresuar</comment>
@@ -26360,7 +27205,7 @@
<comment xml:lang="pt">imagem TIFF</comment>
<comment xml:lang="pt_BR">Imagem TIFF</comment>
<comment xml:lang="ro">Imagine TIFF</comment>
- <comment xml:lang="ru">изображение TIFF</comment>
+ <comment xml:lang="ru">Изображение TIFF</comment>
<comment xml:lang="sk">Obrázok TIFF</comment>
<comment xml:lang="sl">Slikovna datoteka TIFF</comment>
<comment xml:lang="sq">Figurë TIFF</comment>
@@ -26389,9 +27234,9 @@
<comment xml:lang="el">Πολυσέλιδη εικόνα TIFF</comment>
<comment xml:lang="en_GB">Multi-page TIFF image</comment>
<comment xml:lang="es">imagen TIFF de varias páginas</comment>
- <comment xml:lang="eu">Orri anitzeko TIFF irudia</comment>
<comment xml:lang="fi">Monisivuinen TIFF-kuva</comment>
<comment xml:lang="fr">Image TIFF multi-page</comment>
+ <comment xml:lang="ga">íomhá il-leathanach TIFF</comment>
<comment xml:lang="gl">Imaxe TIFF multipáxina</comment>
<comment xml:lang="he">תמונת TIFF עם ריבוי עמודים</comment>
<comment xml:lang="hr">Višestrana TIFF slika</comment>
@@ -26425,7 +27270,7 @@
<comment xml:lang="be@latin">Vyjava AutoCAD</comment>
<comment xml:lang="bg">Изображение — AutoCAD</comment>
<comment xml:lang="ca">imatge d'AutoCAD</comment>
- <comment xml:lang="cs">obrázek AutoCAD</comment>
+ <comment xml:lang="cs">výkres AutoCAD</comment>
<comment xml:lang="cy">Delwedd AutoCAD</comment>
<comment xml:lang="da">AutoCAD-billede</comment>
<comment xml:lang="de">AutoCAD-Bild</comment>
@@ -26460,7 +27305,7 @@
<comment xml:lang="pt">imagem AutoCAD</comment>
<comment xml:lang="pt_BR">Imagem do AutoCAD</comment>
<comment xml:lang="ro">Imagine AutoCAD</comment>
- <comment xml:lang="ru">изображение AutoCAD</comment>
+ <comment xml:lang="ru">Изображение AutoCAD</comment>
<comment xml:lang="sk">Obrázok AutoCAD</comment>
<comment xml:lang="sl">Slikovna datoteka AutoCAD</comment>
<comment xml:lang="sq">Figurë AutoCAD</comment>
@@ -26490,7 +27335,7 @@
<comment xml:lang="fi">DXF-vektorikuva</comment>
<comment xml:lang="fo">DXF vektormynd</comment>
<comment xml:lang="fr">image vectorielle DXF</comment>
- <comment xml:lang="ga">íomhá veicteoir DXF</comment>
+ <comment xml:lang="ga">íomhá veicteoireach DXF</comment>
<comment xml:lang="gl">imaxe de vector DXF</comment>
<comment xml:lang="he">תמונת DXF וקטורית</comment>
<comment xml:lang="hr">DXF vektorska slika</comment>
@@ -26513,7 +27358,7 @@
<comment xml:lang="pt">imagem de vectores DXF</comment>
<comment xml:lang="pt_BR">Imagem vetorial DXF</comment>
<comment xml:lang="ro">Imagine vectorială DXF</comment>
- <comment xml:lang="ru">векторное изображение DXF</comment>
+ <comment xml:lang="ru">Векторное изображение DXF</comment>
<comment xml:lang="sk">Vektorový obrázok DXF</comment>
<comment xml:lang="sl">Slikovna vektorska datoteka DXF</comment>
<comment xml:lang="sq">Figurë vektoriale DFX</comment>
@@ -26533,6 +27378,7 @@
<mime-type type="image/vnd.ms-modi">
<comment>Microsoft Document Imaging format</comment>
<comment xml:lang="ar">صيغة مستند تصوير مايكروسوفت</comment>
+ <comment xml:lang="ast">Formatu d'imáxenes de Microsoft Document</comment>
<comment xml:lang="bg">Изображение — Microsoft Document Imaging</comment>
<comment xml:lang="ca">format Microsoft Document Imaging</comment>
<comment xml:lang="cs">formát Microsoft Document Imaging</comment>
@@ -26564,7 +27410,7 @@
<comment xml:lang="pt">formato Microsoft Document Imaging</comment>
<comment xml:lang="pt_BR">Formato do Microsoft Document Imaging</comment>
<comment xml:lang="ro">Format Microsoft Document Imaging</comment>
- <comment xml:lang="ru">формат Microsoft Document Imaging</comment>
+ <comment xml:lang="ru">Формат Microsoft Document Imaging</comment>
<comment xml:lang="sk">Formát Microsoft Document Imaging</comment>
<comment xml:lang="sl">Zapis Microsoft Document Imaging</comment>
<comment xml:lang="sr">запис слика Мајкрософтовог документа</comment>
@@ -26572,7 +27418,7 @@
<comment xml:lang="tr">Microsoft Belge Görüntüleme biçimi</comment>
<comment xml:lang="uk">формат Microsoft Document Imaging</comment>
<comment xml:lang="vi">Định dạng tạo ảnh tài liệu Microsoft</comment>
- <comment xml:lang="zh_CN">Microsoft Document Imaging 扫描图像</comment>
+ <comment xml:lang="zh_CN">Microsoft Document Imaging 格式</comment>
<comment xml:lang="zh_TW">微軟文件影像格式</comment>
<acronym>MDI</acronym>
<expanded-acronym>Microsoft Document Imaging</expanded-acronym>
@@ -26593,6 +27439,7 @@
<comment xml:lang="eu">WebP irudia</comment>
<comment xml:lang="fi">WebP-kuva</comment>
<comment xml:lang="fr">image WebP</comment>
+ <comment xml:lang="ga">íomhá WebP</comment>
<comment xml:lang="gl">Imaxe WebP</comment>
<comment xml:lang="he">תמונת WebP</comment>
<comment xml:lang="hr">WebP slika</comment>
@@ -26664,7 +27511,7 @@
<comment xml:lang="pt">imagem 3D Studio</comment>
<comment xml:lang="pt_BR">Imagem do 3D Studio</comment>
<comment xml:lang="ro">Imagine 3D Studio</comment>
- <comment xml:lang="ru">сцена 3D Studio</comment>
+ <comment xml:lang="ru">Сцена 3D Studio</comment>
<comment xml:lang="sk">Obrázok 3D Studio</comment>
<comment xml:lang="sl">Slikovna datoteka 3D Studio</comment>
<comment xml:lang="sq">Figurë 3D Studio</comment>
@@ -26717,7 +27564,7 @@
<comment xml:lang="pt">imagem Applix Graphics</comment>
<comment xml:lang="pt_BR">Imagem do Applix Graphics</comment>
<comment xml:lang="ro">Imagine Applix Graphics</comment>
- <comment xml:lang="ru">изображение Applix Graphics</comment>
+ <comment xml:lang="ru">Изображение Applix Graphics</comment>
<comment xml:lang="sk">Obrázok Applix Graphics</comment>
<comment xml:lang="sl">Slikovna datoteka Applix Graphics</comment>
<comment xml:lang="sq">Figurë Applix Graphics</comment>
@@ -26754,7 +27601,7 @@
<comment xml:lang="ga">íomhá EPS (comhbhrúite le bzip)</comment>
<comment xml:lang="gl">imaxe EPS (comprimida con bzip)</comment>
<comment xml:lang="he">תמונת EPS (מכווץ בbzip)</comment>
- <comment xml:lang="hr">EPS slika (komprimirana bzip-om)</comment>
+ <comment xml:lang="hr">EPS slika (bzip sažeta)</comment>
<comment xml:lang="hu">EPS kép (bzip-tömörítésű)</comment>
<comment xml:lang="ia">Imagine EPS (comprimite con bzip)</comment>
<comment xml:lang="id">Citra EPS (terkompresi bzip)</comment>
@@ -26773,7 +27620,7 @@
<comment xml:lang="pt">imagem EPS (compressão bzip)</comment>
<comment xml:lang="pt_BR">Imagem EPS (compactada com bzip)</comment>
<comment xml:lang="ro">Imagine EPS (compresie bzip)</comment>
- <comment xml:lang="ru">изображение EPS (сжатое bzip)</comment>
+ <comment xml:lang="ru">Изображение EPS (сжатое bzip)</comment>
<comment xml:lang="sk">Obrázok EPS (komprimovaný pomocou bzip)</comment>
<comment xml:lang="sl">Slikovna datoteka EPS (stisnjena z bzip)</comment>
<comment xml:lang="sq">Figurë EPS (e kompresuar me bzip)</comment>
@@ -26782,7 +27629,7 @@
<comment xml:lang="tr">EPS görüntüsü (bzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">зображення EPS (стиснене bzip)</comment>
<comment xml:lang="vi">Ảnh EPS (đã nén bzip)</comment>
- <comment xml:lang="zh_CN">EPS 图像(bzip 压缩)</comment>
+ <comment xml:lang="zh_CN">EPS 图像(bzip 压缩)</comment>
<comment xml:lang="zh_TW">EPS 影像 (bzip 格式壓縮)</comment>
<sub-class-of type="application/x-bzip"/>
<glob pattern="*.eps.bz2"/>
@@ -26831,7 +27678,7 @@
<comment xml:lang="pt">imagem raster CMU</comment>
<comment xml:lang="pt_BR">Imagem raster CMU</comment>
<comment xml:lang="ro">Imagine raster CMU</comment>
- <comment xml:lang="ru">растровое изображение CMU</comment>
+ <comment xml:lang="ru">Растровое изображение CMU</comment>
<comment xml:lang="sk">Rastrový obrázok CMU</comment>
<comment xml:lang="sl">Slikovna rastrska datoteka CMU</comment>
<comment xml:lang="sq">Figurë raster CMU</comment>
@@ -26840,7 +27687,7 @@
<comment xml:lang="tr">CMU tarama görüntüsü</comment>
<comment xml:lang="uk">растрове зображення CMU</comment>
<comment xml:lang="vi">Ảnh mành CMU</comment>
- <comment xml:lang="zh_CN">CMU 矢量图像</comment>
+ <comment xml:lang="zh_CN">CMU 光栅图像</comment>
<comment xml:lang="zh_TW">CMU raster 影像</comment>
<glob pattern="*.ras"/>
</mime-type>
@@ -26881,7 +27728,7 @@
<comment xml:lang="pt">imagem GIMP comprimida</comment>
<comment xml:lang="pt_BR">Imagem do GIMP compactada</comment>
<comment xml:lang="ro">imagine comprimată GIMP</comment>
- <comment xml:lang="ru">сжатое изображение GIMP</comment>
+ <comment xml:lang="ru">Сжатое изображение GIMP</comment>
<comment xml:lang="sk">Komprimovaný obrázok GIMP</comment>
<comment xml:lang="sl">Slikovna datoteka GIMP (stisnjena)</comment>
<comment xml:lang="sq">Figurë GIMP e kompresuar</comment>
@@ -26934,7 +27781,7 @@
<comment xml:lang="pt">imagem DICOM</comment>
<comment xml:lang="pt_BR">Imagem DICOM</comment>
<comment xml:lang="ro">Imagine DICOM</comment>
- <comment xml:lang="ru">изображение DICOM</comment>
+ <comment xml:lang="ru">Изображение DICOM</comment>
<comment xml:lang="sk">Obrázok DICOM</comment>
<comment xml:lang="sl">Slikovna datoteka DICOM</comment>
<comment xml:lang="sq">Figurë DICOM</comment>
@@ -26957,6 +27804,7 @@
<mime-type type="application/x-docbook+xml">
<comment>DocBook document</comment>
<comment xml:lang="ar">مستند DocBook</comment>
+ <comment xml:lang="ast">Documentu DocBook</comment>
<comment xml:lang="be@latin">Dakument DocBook</comment>
<comment xml:lang="bg">Документ — DocBook</comment>
<comment xml:lang="ca">document DocBook</comment>
@@ -26993,7 +27841,7 @@
<comment xml:lang="pt">documento DocBook</comment>
<comment xml:lang="pt_BR">Documento DocBook</comment>
<comment xml:lang="ro">Document DocBook</comment>
- <comment xml:lang="ru">документ DocBook</comment>
+ <comment xml:lang="ru">Документ DocBook</comment>
<comment xml:lang="sk">Dokument DocBook</comment>
<comment xml:lang="sl">Dokument DocBook</comment>
<comment xml:lang="sq">Dokument DocBook</comment>
@@ -27056,7 +27904,7 @@
<comment xml:lang="pt">imagem DIB</comment>
<comment xml:lang="pt_BR">Imagem DIB</comment>
<comment xml:lang="ro">Imagine DIB</comment>
- <comment xml:lang="ru">изображение DIB</comment>
+ <comment xml:lang="ru">Изображение DIB</comment>
<comment xml:lang="sk">Obrázok DIB</comment>
<comment xml:lang="sl">Slikovna datoteka DIB</comment>
<comment xml:lang="sq">Figurë DIB</comment>
@@ -27113,7 +27961,7 @@
<comment xml:lang="pt">imagem DjVu</comment>
<comment xml:lang="pt_BR">Imagem DjVu</comment>
<comment xml:lang="ro">Imagine DjVu</comment>
- <comment xml:lang="ru">изображение DjVu</comment>
+ <comment xml:lang="ru">Изображение DjVu</comment>
<comment xml:lang="sk">Obrázok DjVu</comment>
<comment xml:lang="sl">Slikovna datoteka DjVu</comment>
<comment xml:lang="sq">Figurë DjVu</comment>
@@ -27126,7 +27974,7 @@
<comment xml:lang="zh_TW">DjVu 影像</comment>
<alias type="image/x-djvu"/>
<alias type="image/x.djvu"/>
- <magic priority="50">
+ <magic priority="80">
<match value="AT&amp;TFORM" type="string" offset="0">
<match value="DJVU" type="string" offset="12"/>
</match>
@@ -27139,6 +27987,7 @@
</mime-type>
<mime-type type="image/vnd.djvu+multipage">
<comment>DjVu document</comment>
+ <comment xml:lang="ast">Documentu DjVu</comment>
<comment xml:lang="ca">document DjVu</comment>
<comment xml:lang="cs">dokument DjVu</comment>
<comment xml:lang="da">DjVu-dokument</comment>
@@ -27149,6 +27998,7 @@
<comment xml:lang="eu">DjVu dokumentua</comment>
<comment xml:lang="fi">DjVu-asiakirja</comment>
<comment xml:lang="fr">document DjVu</comment>
+ <comment xml:lang="ga">cáipéis DjVu</comment>
<comment xml:lang="he">מסמך DjVu</comment>
<comment xml:lang="hr">DjVu dokument</comment>
<comment xml:lang="hu">DjVu dokumentum</comment>
@@ -27161,7 +28011,7 @@
<comment xml:lang="pl">Dokument DjVu</comment>
<comment xml:lang="pt">documento DjVu</comment>
<comment xml:lang="pt_BR">Documento DjVu</comment>
- <comment xml:lang="ru">документ DjVu</comment>
+ <comment xml:lang="ru">Документ DjVu</comment>
<comment xml:lang="sk">Dokument DjVu</comment>
<comment xml:lang="sr">ДјВу документ</comment>
<comment xml:lang="sv">DjVu-dokument</comment>
@@ -27170,7 +28020,7 @@
<comment xml:lang="zh_CN">DjVu 文档</comment>
<comment xml:lang="zh_TW">DjVu 文件</comment>
<generic-icon name="x-office-document"/>
- <magic priority="50">
+ <magic priority="80">
<match value="AT&amp;TFORM" type="string" offset="0">
<match value="DJVM" type="string" offset="12"/>
</match>
@@ -27221,7 +28071,7 @@
<comment xml:lang="pt">imagem DPX</comment>
<comment xml:lang="pt_BR">Imagem DPX</comment>
<comment xml:lang="ro">Imagine DPX</comment>
- <comment xml:lang="ru">изображение DPX</comment>
+ <comment xml:lang="ru">Изображение DPX</comment>
<comment xml:lang="sk">Obrázok DPX</comment>
<comment xml:lang="sl">Slikovna datoteka DPX</comment>
<comment xml:lang="sq">Figurë DPX</comment>
@@ -27277,7 +28127,7 @@
<comment xml:lang="pt">imagem EPS</comment>
<comment xml:lang="pt_BR">Imagem EPS</comment>
<comment xml:lang="ro">Imagine EPS</comment>
- <comment xml:lang="ru">изображение EPS</comment>
+ <comment xml:lang="ru">Изображение EPS</comment>
<comment xml:lang="sk">Obrázok EPS</comment>
<comment xml:lang="sl">Slikovna datoteka EPS</comment>
<comment xml:lang="sq">Figurë EPS</comment>
@@ -27307,6 +28157,7 @@
<mime-type type="image/fits">
<comment>FITS document</comment>
<comment xml:lang="ar">مستند FITS</comment>
+ <comment xml:lang="ast">Documentu FITS</comment>
<comment xml:lang="be@latin">Dakument FITS</comment>
<comment xml:lang="bg">Документ — FITS</comment>
<comment xml:lang="ca">document FITS</comment>
@@ -27343,7 +28194,7 @@
<comment xml:lang="pt">documento FITS</comment>
<comment xml:lang="pt_BR">Documento FITS</comment>
<comment xml:lang="ro">Document FITS</comment>
- <comment xml:lang="ru">документ FITS</comment>
+ <comment xml:lang="ru">Документ FITS</comment>
<comment xml:lang="sk">Dokument FITS</comment>
<comment xml:lang="sl">Dokument FITS</comment>
<comment xml:lang="sq">Dokument FITS</comment>
@@ -27401,7 +28252,7 @@
<comment xml:lang="pt">imagem FPX</comment>
<comment xml:lang="pt_BR">Imagem FPX</comment>
<comment xml:lang="ro">Imagine FPX</comment>
- <comment xml:lang="ru">изображение FPX</comment>
+ <comment xml:lang="ru">Изображение FPX</comment>
<comment xml:lang="sk">Obrázok FPX</comment>
<comment xml:lang="sl">Slikovna datoteka FPX</comment>
<comment xml:lang="sq">Figurë FPX</comment>
@@ -27437,7 +28288,7 @@
<comment xml:lang="ga">íomhá EPS (comhbhrúite le gzip)</comment>
<comment xml:lang="gl">imaxe EPS (comprimida con gzip)</comment>
<comment xml:lang="he">תמונת EPS (מכווץ ע״י gzip)</comment>
- <comment xml:lang="hr">EPS slika (komprimirana gzip-om)</comment>
+ <comment xml:lang="hr">EPS slika (gzip sažeta)</comment>
<comment xml:lang="hu">EPS kép (gzip-tömörítésű)</comment>
<comment xml:lang="ia">Imagine EPS (comprimite con gzip)</comment>
<comment xml:lang="id">Citra EPS (terkompresi gzip)</comment>
@@ -27456,7 +28307,7 @@
<comment xml:lang="pt">imagem EPS (compressão gzip)</comment>
<comment xml:lang="pt_BR">Imagem EPS (compactada com gzip)</comment>
<comment xml:lang="ro">Imagine EPS (compresie gzip)</comment>
- <comment xml:lang="ru">изображение EPS (сжатое gzip)</comment>
+ <comment xml:lang="ru">Изображение EPS (сжатое gzip)</comment>
<comment xml:lang="sk">Obrázok EPS (komprimovaný pomocou gzip)</comment>
<comment xml:lang="sl">Slikovna datoteka EPS (stisnjena z gzip)</comment>
<comment xml:lang="sq">Figurë EPS (e kompresuar me gzip)</comment>
@@ -27465,7 +28316,7 @@
<comment xml:lang="tr">EPS görüntüsü (gzip ile sıkıştırılmış)</comment>
<comment xml:lang="uk">зображення EPS (стиснене gzip)</comment>
<comment xml:lang="vi">Ảnh EPS (đã nén gzip)</comment>
- <comment xml:lang="zh_CN">EPS 图像(gzip 压缩)</comment>
+ <comment xml:lang="zh_CN">EPS 图像(gzip 压缩)</comment>
<comment xml:lang="zh_TW">EPS 影像 (gzip 格式壓縮)</comment>
<sub-class-of type="application/gzip"/>
<glob pattern="*.eps.gz"/>
@@ -27484,6 +28335,7 @@
<comment xml:lang="eu">Windows ikonoa</comment>
<comment xml:lang="fi">Windows-kuvake</comment>
<comment xml:lang="fr">icône Windows</comment>
+ <comment xml:lang="ga">deilbhín Windows</comment>
<comment xml:lang="he">סמל של Windows</comment>
<comment xml:lang="hr">Windows ikona</comment>
<comment xml:lang="hu">Windows ikon</comment>
@@ -27496,7 +28348,7 @@
<comment xml:lang="pl">Ikona Windows</comment>
<comment xml:lang="pt">ícone Windows</comment>
<comment xml:lang="pt_BR">Ícone do Windows</comment>
- <comment xml:lang="ru">значок Windows</comment>
+ <comment xml:lang="ru">Значок Windows</comment>
<comment xml:lang="sk">Ikona Windows</comment>
<comment xml:lang="sl">Ikona Windows</comment>
<comment xml:lang="sr">Иконица Виндоуза</comment>
@@ -27557,7 +28409,7 @@
<comment xml:lang="pt">ćone MacOS X</comment>
<comment xml:lang="pt_BR">Ícone do MacOS X</comment>
<comment xml:lang="ro">Iconiță MacOS X</comment>
- <comment xml:lang="ru">значок MacOS X</comment>
+ <comment xml:lang="ru">Значок MacOS X</comment>
<comment xml:lang="sk">Ikona MacOS X</comment>
<comment xml:lang="sl">Datoteka ikone MacOS X</comment>
<comment xml:lang="sq">Ikonë MacOS X</comment>
@@ -27614,7 +28466,7 @@
<comment xml:lang="pt">imagem ILBM</comment>
<comment xml:lang="pt_BR">Imagem ILBM</comment>
<comment xml:lang="ro">Imagine ILBM</comment>
- <comment xml:lang="ru">изображение ILBM</comment>
+ <comment xml:lang="ru">Изображение ILBM</comment>
<comment xml:lang="sk">Obrázok ILMB</comment>
<comment xml:lang="sl">Slikovna datoteka ILBM</comment>
<comment xml:lang="sq">Figurë ILBM</comment>
@@ -27678,7 +28530,7 @@
<comment xml:lang="pt">imagem JNG</comment>
<comment xml:lang="pt_BR">Imagem JNG</comment>
<comment xml:lang="ro">Imagine JNG</comment>
- <comment xml:lang="ru">изображение JNG</comment>
+ <comment xml:lang="ru">Изображение JNG</comment>
<comment xml:lang="sk">Obrázok JNG</comment>
<comment xml:lang="sl">Slikovna datoteka JNG</comment>
<comment xml:lang="sq">Figurë JNG</comment>
@@ -27734,7 +28586,7 @@
<comment xml:lang="pt">Objecto LightWave</comment>
<comment xml:lang="pt_BR">Objeto LightWave</comment>
<comment xml:lang="ro">Obiect LightWave</comment>
- <comment xml:lang="ru">объект LightWave</comment>
+ <comment xml:lang="ru">Объект LightWave</comment>
<comment xml:lang="sk">Objekt LightWave</comment>
<comment xml:lang="sl">Datoteka predmeta LightWave</comment>
<comment xml:lang="sq">Objekt LightWave</comment>
@@ -27789,7 +28641,7 @@
<comment xml:lang="pt">cenário LightWave</comment>
<comment xml:lang="pt_BR">Cena LightWave</comment>
<comment xml:lang="ro">Scenă LightWave</comment>
- <comment xml:lang="ru">сцена LightWave</comment>
+ <comment xml:lang="ru">Сцена LightWave</comment>
<comment xml:lang="sk">Scéna LightWave</comment>
<comment xml:lang="sl">Datoteka scene LightWave</comment>
<comment xml:lang="sq">Skenë LightWave</comment>
@@ -27818,7 +28670,7 @@
<comment xml:lang="fi">MacPaint-bittikartta</comment>
<comment xml:lang="fo">MacPaint Bitmap mynd</comment>
<comment xml:lang="fr">image matricielle MacPaint</comment>
- <comment xml:lang="ga">íomhá MacPaint Bitmap</comment>
+ <comment xml:lang="ga">íomhá ghiotánmhapach MacPaint</comment>
<comment xml:lang="gl">imaxe de mapa de bits MacPaint</comment>
<comment xml:lang="he">תמונת מפת-סיביות של MacPaint</comment>
<comment xml:lang="hr">MacPaint Bitmap slika</comment>
@@ -27839,7 +28691,7 @@
<comment xml:lang="pt">imagem MacPaint Bitmap</comment>
<comment xml:lang="pt_BR">Imagem de bitmap do MacPaint</comment>
<comment xml:lang="ro">Imagine MacPaint Bitmap</comment>
- <comment xml:lang="ru">растровое изображение MacPaint</comment>
+ <comment xml:lang="ru">Растровое изображение MacPaint</comment>
<comment xml:lang="sk">Obrázok MacPaint Bitmap</comment>
<comment xml:lang="sl">Slikovna bitna datoteka MacPaint</comment>
<comment xml:lang="sq">Figurë BitMap MacPaint</comment>
@@ -27889,7 +28741,7 @@
<comment xml:lang="pt">desenho Office</comment>
<comment xml:lang="pt_BR">Desenho do Office</comment>
<comment xml:lang="ro">Desen Office</comment>
- <comment xml:lang="ru">изображение Office</comment>
+ <comment xml:lang="ru">Рисунок Office</comment>
<comment xml:lang="sk">Kresba Office</comment>
<comment xml:lang="sl">Datoteka risbe Office</comment>
<comment xml:lang="sq">Vizatim Office</comment>
@@ -27898,7 +28750,7 @@
<comment xml:lang="tr">Ofis çizimi</comment>
<comment xml:lang="uk">малюнок Office</comment>
<comment xml:lang="vi">Bản vẽ Office</comment>
- <comment xml:lang="zh_CN">Microsoft Office 绘图</comment>
+ <comment xml:lang="zh_CN">Office 绘图</comment>
<comment xml:lang="zh_TW">Office 繪圖</comment>
<glob pattern="*.msod"/>
</mime-type>
@@ -27940,7 +28792,7 @@
<comment xml:lang="pt">imagem NIFF</comment>
<comment xml:lang="pt_BR">Imagem NIFF</comment>
<comment xml:lang="ro">Imagine NIF</comment>
- <comment xml:lang="ru">изображение NIFF</comment>
+ <comment xml:lang="ru">Изображение NIFF</comment>
<comment xml:lang="sk">Obrázok NIFF</comment>
<comment xml:lang="sl">Slikovna datoteka NIFF</comment>
<comment xml:lang="sq">Figurë NIFF</comment>
@@ -27993,7 +28845,7 @@
<comment xml:lang="pt">imagem PCX</comment>
<comment xml:lang="pt_BR">Imagem PCX</comment>
<comment xml:lang="ro">Imagine PCX</comment>
- <comment xml:lang="ru">изображение PCX</comment>
+ <comment xml:lang="ru">Изображение PCX</comment>
<comment xml:lang="sk">Obrázok PCX</comment>
<comment xml:lang="sl">Slikovna datoteka PCX</comment>
<comment xml:lang="sq">Figurë PCX</comment>
@@ -28056,7 +28908,7 @@
<comment xml:lang="pt">imagem PCD</comment>
<comment xml:lang="pt_BR">Imagem PCD</comment>
<comment xml:lang="ro">Imagine PCD</comment>
- <comment xml:lang="ru">изображение PCD</comment>
+ <comment xml:lang="ru">Изображение PCD</comment>
<comment xml:lang="sk">Obrázok PCD</comment>
<comment xml:lang="sl">Slikovna datoteka PCD</comment>
<comment xml:lang="sq">Figurë PCD</comment>
@@ -28112,7 +28964,7 @@
<comment xml:lang="pt">imagem PNM</comment>
<comment xml:lang="pt_BR">Imagem PNM</comment>
<comment xml:lang="ro">Imagine PNM</comment>
- <comment xml:lang="ru">изображение PNM</comment>
+ <comment xml:lang="ru">Изображение PNM</comment>
<comment xml:lang="sk">Obrázok PNM</comment>
<comment xml:lang="sl">Slikovna datoteka PNM</comment>
<comment xml:lang="sq">Figurë PNM</comment>
@@ -28165,7 +29017,7 @@
<comment xml:lang="pt">imagem PBM</comment>
<comment xml:lang="pt_BR">Imagem PBM</comment>
<comment xml:lang="ro">Imagine PBM</comment>
- <comment xml:lang="ru">изображение PBM</comment>
+ <comment xml:lang="ru">Изображение PBM</comment>
<comment xml:lang="sk">Obrázok PBM</comment>
<comment xml:lang="sl">Slikovna datoteka PBM</comment>
<comment xml:lang="sq">Figurë PBM</comment>
@@ -28234,7 +29086,7 @@
<comment xml:lang="pt">imagem PGM</comment>
<comment xml:lang="pt_BR">Imagem PGM</comment>
<comment xml:lang="ro">Imagine PGM</comment>
- <comment xml:lang="ru">изображение PGM</comment>
+ <comment xml:lang="ru">Изображение PGM</comment>
<comment xml:lang="sk">Obrázok PGM</comment>
<comment xml:lang="sl">Slikovna datoteka PGM</comment>
<comment xml:lang="sq">Figurë PGM</comment>
@@ -28303,7 +29155,7 @@
<comment xml:lang="pt">imagem PPM</comment>
<comment xml:lang="pt_BR">Imagem PPM</comment>
<comment xml:lang="ro">Imagine PPM</comment>
- <comment xml:lang="ru">изображение PPM</comment>
+ <comment xml:lang="ru">Изображение PPM</comment>
<comment xml:lang="sk">Obrázok PPM</comment>
<comment xml:lang="sl">Slikovna datoteka PPM</comment>
<comment xml:lang="sq">Figurë PPM</comment>
@@ -28369,7 +29221,7 @@
<comment xml:lang="pt">imagem Photoshop</comment>
<comment xml:lang="pt_BR">Imagem do Photoshop</comment>
<comment xml:lang="ro">Imagine Photoshop</comment>
- <comment xml:lang="ru">изображение Photoshop</comment>
+ <comment xml:lang="ru">Изображение Photoshop</comment>
<comment xml:lang="sk">Obrázok Photoshop</comment>
<comment xml:lang="sl">Slikovna datoteka Photoshop</comment>
<comment xml:lang="sr">Фотошоп слика</comment>
@@ -28431,7 +29283,7 @@
<comment xml:lang="pt">imagem RGB</comment>
<comment xml:lang="pt_BR">Imagem RGB</comment>
<comment xml:lang="ro">Imagine RGB</comment>
- <comment xml:lang="ru">изображение RGB</comment>
+ <comment xml:lang="ru">Изображение RGB</comment>
<comment xml:lang="sk">Obrázok RGB</comment>
<comment xml:lang="sl">Slikovna datoteka RGB</comment>
<comment xml:lang="sq">Figurë RGB</comment>
@@ -28482,7 +29334,7 @@
<comment xml:lang="pt">imagem SGI</comment>
<comment xml:lang="pt_BR">Imagem SGI</comment>
<comment xml:lang="ro">Imagine SGI</comment>
- <comment xml:lang="ru">изображение SGI</comment>
+ <comment xml:lang="ru">Изображение SGI</comment>
<comment xml:lang="sk">Obrázok SGI</comment>
<comment xml:lang="sl">Slikovna datoteka SGI</comment>
<comment xml:lang="sq">Figurë SGI</comment>
@@ -28532,7 +29384,7 @@
<comment xml:lang="pt">imagem raster Sun</comment>
<comment xml:lang="pt_BR">Imagem raster da Sun</comment>
<comment xml:lang="ro">Imagine rasterizată Sun</comment>
- <comment xml:lang="ru">растровое изображение Sun</comment>
+ <comment xml:lang="ru">Растровое изображение Sun</comment>
<comment xml:lang="sk">Rastrový obrázok Sun</comment>
<comment xml:lang="sl">Slikovna rastrska datoteka Sun</comment>
<comment xml:lang="sq">Figurë raster Sun</comment>
@@ -28586,7 +29438,7 @@
<comment xml:lang="pt">imagem TGA</comment>
<comment xml:lang="pt_BR">Imagem TGA</comment>
<comment xml:lang="ro">Imagine TGA</comment>
- <comment xml:lang="ru">изображение TGA</comment>
+ <comment xml:lang="ru">Изображение TGA</comment>
<comment xml:lang="sk">Obrázok TGA</comment>
<comment xml:lang="sl">Slikovna datoteka TGA</comment>
<comment xml:lang="sq">Figurë TGA</comment>
@@ -28614,8 +29466,8 @@
<match value="0x20" type="byte" offset="16"/>
</match>
</magic>
- <glob pattern="*.icb"/>
<glob pattern="*.tga"/>
+ <glob pattern="*.icb"/>
<glob pattern="*.tpic"/>
<glob pattern="*.vda"/>
<glob pattern="*.vst"/>
@@ -28641,7 +29493,7 @@
<comment xml:lang="ga">cúrsóir Windows</comment>
<comment xml:lang="gl">Cursor de Windows</comment>
<comment xml:lang="he">סמן של Windows</comment>
- <comment xml:lang="hr">Windows kursor</comment>
+ <comment xml:lang="hr">Windows pokazivač</comment>
<comment xml:lang="hu">Windows-kurzor</comment>
<comment xml:lang="ia">Cursor pro Windows</comment>
<comment xml:lang="id">Kursor Windows</comment>
@@ -28660,7 +29512,7 @@
<comment xml:lang="pt">cursor Windows</comment>
<comment xml:lang="pt_BR">Cursor do Windows</comment>
<comment xml:lang="ro">Cursor Windows</comment>
- <comment xml:lang="ru">курсор Windows</comment>
+ <comment xml:lang="ru">Курсор Windows</comment>
<comment xml:lang="sk">Kurzor Windows</comment>
<comment xml:lang="sl">Datoteka kazalke Windows</comment>
<comment xml:lang="sq">Kursor Windows</comment>
@@ -28694,10 +29546,10 @@
<comment xml:lang="fi">animoitu Windows-osoitin</comment>
<comment xml:lang="fo">Windows livindaigjørdur vísi</comment>
<comment xml:lang="fr">curseur animé Windows</comment>
- <comment xml:lang="ga">cúrsóir beo Windows</comment>
+ <comment xml:lang="ga">cúrsóir beoite Windows</comment>
<comment xml:lang="gl">Cursor animado de Windows</comment>
<comment xml:lang="he">סמן מונפש של Windows</comment>
- <comment xml:lang="hr">Windows animirani kursor</comment>
+ <comment xml:lang="hr">Windows animirani pokazivač</comment>
<comment xml:lang="hu">Windows animált kurzor</comment>
<comment xml:lang="ia">Cursor animate pro Windows</comment>
<comment xml:lang="id">Kursor animasi Windows</comment>
@@ -28714,7 +29566,7 @@
<comment xml:lang="pt">cursor animado Windows</comment>
<comment xml:lang="pt_BR">Cursor animado do Windows</comment>
<comment xml:lang="ro">Cursor animat Windows</comment>
- <comment xml:lang="ru">анимированный курсор Windows</comment>
+ <comment xml:lang="ru">Анимированный курсор Windows</comment>
<comment xml:lang="sk">Animovaný kurzor Windows</comment>
<comment xml:lang="sl">Datoteka animirane kazalke Windows</comment>
<comment xml:lang="sq">Kursor i animuar Windows</comment>
@@ -28723,7 +29575,7 @@
<comment xml:lang="tr">Windows canlandırmalı imleci</comment>
<comment xml:lang="uk">анімований курсор Windows</comment>
<comment xml:lang="vi">Con chạy hoạt họa Windows</comment>
- <comment xml:lang="zh_CN">Windows 动画光标</comment>
+ <comment xml:lang="zh_CN">Windows 动态光标</comment>
<comment xml:lang="zh_TW">Windows 滑鼠動畫游標</comment>
<magic priority="50">
<match value="RIFF" type="string" offset="0">
@@ -28771,7 +29623,7 @@
<comment xml:lang="pt">imagem EMF</comment>
<comment xml:lang="pt_BR">Imagem EMF</comment>
<comment xml:lang="ro">Imagine EMF</comment>
- <comment xml:lang="ru">изображение EMF</comment>
+ <comment xml:lang="ru">Изображение EMF</comment>
<comment xml:lang="sk">Obrázok EMF</comment>
<comment xml:lang="sl">Slikovna datoteka EMF</comment>
<comment xml:lang="sq">Figurë EMF</comment>
@@ -28836,7 +29688,7 @@
<comment xml:lang="pt">imagem WMF</comment>
<comment xml:lang="pt_BR">Imagem WMF</comment>
<comment xml:lang="ro">Imagine WMF</comment>
- <comment xml:lang="ru">изображение WMF</comment>
+ <comment xml:lang="ru">Изображение WMF</comment>
<comment xml:lang="sk">Obrázok WMF</comment>
<comment xml:lang="sl">Slikovna datoteka WMF</comment>
<comment xml:lang="sq">Figurë WMF</comment>
@@ -28907,7 +29759,7 @@
<comment xml:lang="pt">imagem XBM</comment>
<comment xml:lang="pt_BR">Imagem XBM</comment>
<comment xml:lang="ro">Imagine XBM</comment>
- <comment xml:lang="ru">изображение XBM</comment>
+ <comment xml:lang="ru">Изображение XBM</comment>
<comment xml:lang="sk">Obrázok XBM</comment>
<comment xml:lang="sl">Slikovna datoteka XBM</comment>
<comment xml:lang="sq">Figurë XBM</comment>
@@ -28962,7 +29814,7 @@
<comment xml:lang="pt">imagem GIMP</comment>
<comment xml:lang="pt_BR">Imagem do GIMP</comment>
<comment xml:lang="ro">Imagine GIMP</comment>
- <comment xml:lang="ru">изображение GIMP</comment>
+ <comment xml:lang="ru">Изображение GIMP</comment>
<comment xml:lang="sk">Obrázok GIMP</comment>
<comment xml:lang="sl">Slikovna datoteka GIMP</comment>
<comment xml:lang="sq">Figurë GIMP</comment>
@@ -28979,6 +29831,80 @@
<match value="gimp xcf v" type="string" offset="0"/>
</magic>
</mime-type>
+ <mime-type type="image/x-gimp-gbr">
+ <comment>GIMP brush</comment>
+ <comment xml:lang="ca">pinzell de GIMP</comment>
+ <comment xml:lang="cs">štětec GIMP</comment>
+ <comment xml:lang="de">GIMP-Pinsel</comment>
+ <comment xml:lang="en_GB">GIMP brush</comment>
+ <comment xml:lang="es">pincel del GIMP</comment>
+ <comment xml:lang="hr">GIMP kist</comment>
+ <comment xml:lang="hu">GIMP ecset</comment>
+ <comment xml:lang="id">Kuas GIMP</comment>
+ <comment xml:lang="it">Pennello GIMP</comment>
+ <comment xml:lang="kk">GIMP бояу жаққышы</comment>
+ <comment xml:lang="ko">GIMP 붓</comment>
+ <comment xml:lang="pl">Pędzel programu GIMP</comment>
+ <comment xml:lang="pt_BR">Pincel do GIMP</comment>
+ <comment xml:lang="ru">Кисть GIMP</comment>
+ <comment xml:lang="sk">Štetec aplikácie GIMP</comment>
+ <comment xml:lang="sv">GIMP-pensel</comment>
+ <comment xml:lang="uk">пензель GIMP</comment>
+ <comment xml:lang="zh_CN">GIMP 笔刷</comment>
+ <comment xml:lang="zh_TW">GIMP 筆刷</comment>
+ <glob pattern="*.gbr"/>
+ <magic priority="50">
+ <match value="GIMP" type="string" offset="20"/>
+ </magic>
+ </mime-type>
+ <mime-type type="image/x-gimp-gih">
+ <comment>GIMP brush pipe</comment>
+ <comment xml:lang="ca">conducte del pinzell de GIMP</comment>
+ <comment xml:lang="cs">zřetězení štětců GIMP</comment>
+ <comment xml:lang="de">GIMP-Pinselanimation</comment>
+ <comment xml:lang="en_GB">GIMP brush pipe</comment>
+ <comment xml:lang="es">pincel animado del GIMP</comment>
+ <comment xml:lang="hr">GIMP valjkasti kist</comment>
+ <comment xml:lang="hu">GIMP ecsetcsatorna</comment>
+ <comment xml:lang="id">Pipa kuas GIMP</comment>
+ <comment xml:lang="it">Pipe pennello GIMP</comment>
+ <comment xml:lang="kk">GIMP бояу жаққыш түтігі</comment>
+ <comment xml:lang="ko">GIMP 붓 파이프</comment>
+ <comment xml:lang="pl">Potok pędzla programu GIMP</comment>
+ <comment xml:lang="pt_BR">Tubo de pincel do GIMP</comment>
+ <comment xml:lang="ru">Анимированная кисть GIMP</comment>
+ <comment xml:lang="sv">GIMP-penselrör</comment>
+ <comment xml:lang="uk">канал пензлів GIMP</comment>
+ <comment xml:lang="zh_CN">GIMP 管刷</comment>
+ <comment xml:lang="zh_TW">GIMP 筆刷導管</comment>
+ <glob pattern="*.gih"/>
+ </mime-type>
+ <mime-type type="image/x-gimp-pat">
+ <comment>GIMP pattern</comment>
+ <comment xml:lang="ca">patró de GIMP</comment>
+ <comment xml:lang="cs">vzorek GIMP</comment>
+ <comment xml:lang="de">GIMP-Muster</comment>
+ <comment xml:lang="en_GB">GIMP pattern</comment>
+ <comment xml:lang="es">patrón del GIMP</comment>
+ <comment xml:lang="hr">GIMP uzorak</comment>
+ <comment xml:lang="hu">GIMP minta</comment>
+ <comment xml:lang="id">Pola GIMP</comment>
+ <comment xml:lang="it">Motivo GIMP</comment>
+ <comment xml:lang="kk">GIMP оюы</comment>
+ <comment xml:lang="ko">GIMP 패턴</comment>
+ <comment xml:lang="pl">Deseń programu GIMP</comment>
+ <comment xml:lang="pt_BR">Textura do GIMP</comment>
+ <comment xml:lang="ru">Шаблон GIMP</comment>
+ <comment xml:lang="sk">Vzor aplikácie GIMP</comment>
+ <comment xml:lang="sv">GIMP-mönster</comment>
+ <comment xml:lang="uk">візерунок GIMP</comment>
+ <comment xml:lang="zh_CN">GIMP 图案</comment>
+ <comment xml:lang="zh_TW">GIMP 樣式</comment>
+ <glob pattern="*.pat"/>
+ <magic priority="50">
+ <match value="GPAT" type="string" offset="20"/>
+ </magic>
+ </mime-type>
<mime-type type="image/x-xfig">
<comment>XFig image</comment>
<comment xml:lang="ar">صورة XFig</comment>
@@ -29018,7 +29944,7 @@
<comment xml:lang="pt">imagem XFig</comment>
<comment xml:lang="pt_BR">Imagem do XFig</comment>
<comment xml:lang="ro">Imagine XFig</comment>
- <comment xml:lang="ru">изображение XFig</comment>
+ <comment xml:lang="ru">Изображение XFig</comment>
<comment xml:lang="sk">Obrázok XFig</comment>
<comment xml:lang="sl">Slikovna datoteka XFig</comment>
<comment xml:lang="sq">Figurë XFig</comment>
@@ -29073,7 +29999,7 @@
<comment xml:lang="pt">imagem XPM</comment>
<comment xml:lang="pt_BR">Imagem XPM</comment>
<comment xml:lang="ro">Imagine XPM</comment>
- <comment xml:lang="ru">изображение XPM</comment>
+ <comment xml:lang="ru">Изображение XPM</comment>
<comment xml:lang="sk">Obrázok XPM</comment>
<comment xml:lang="sl">Slikovna datoteka XPM</comment>
<comment xml:lang="sq">Figurë XPM</comment>
@@ -29111,7 +30037,7 @@
<comment xml:lang="fi">X-ikkunakuva</comment>
<comment xml:lang="fo">X vindeyga mynd</comment>
<comment xml:lang="fr">image X window</comment>
- <comment xml:lang="ga">íomhá fhuinneog X</comment>
+ <comment xml:lang="ga">íomhá X-windows</comment>
<comment xml:lang="gl">imaxe de X Window</comment>
<comment xml:lang="he">תמונת חלון של X</comment>
<comment xml:lang="hr">X window slika</comment>
@@ -29133,7 +30059,7 @@
<comment xml:lang="pt">imagem de janela X</comment>
<comment xml:lang="pt_BR">Imagem de janela do X</comment>
<comment xml:lang="ro">Imagine X window</comment>
- <comment xml:lang="ru">изображение X window</comment>
+ <comment xml:lang="ru">Изображение X window</comment>
<comment xml:lang="sk">Obrázok X window</comment>
<comment xml:lang="sl">slika X oken</comment>
<comment xml:lang="sq">Figurë X window</comment>
@@ -29142,13 +30068,14 @@
<comment xml:lang="tr">X pencere görüntüsü</comment>
<comment xml:lang="uk">зображення X window</comment>
<comment xml:lang="vi">Ảnh cửa sổ X</comment>
- <comment xml:lang="zh_CN">X window 图像</comment>
+ <comment xml:lang="zh_CN">X Window 图像</comment>
<comment xml:lang="zh_TW">X window 影像</comment>
<glob pattern="*.xwd"/>
</mime-type>
<mime-type type="inode/blockdevice">
<comment>block device</comment>
<comment xml:lang="ar">جهاز كتلي</comment>
+ <comment xml:lang="ast">preséu de bloques</comment>
<comment xml:lang="be@latin">blokavaja pryłada</comment>
<comment xml:lang="bg">Блоково устройство</comment>
<comment xml:lang="ca">dispositiu de blocs</comment>
@@ -29169,7 +30096,7 @@
<comment xml:lang="hr">Blokovski uređaj</comment>
<comment xml:lang="hu">blokkos eszköz</comment>
<comment xml:lang="ia">Dispositivo de blocos</comment>
- <comment xml:lang="id">blok divais</comment>
+ <comment xml:lang="id">peranti blok</comment>
<comment xml:lang="it">Device a blocchi</comment>
<comment xml:lang="ja">ブロックデバイス</comment>
<comment xml:lang="kk">блоктық құрылғысы</comment>
@@ -29185,7 +30112,7 @@
<comment xml:lang="pt">dispositivo de bloco</comment>
<comment xml:lang="pt_BR">Dispositivo de bloco</comment>
<comment xml:lang="ro">dispozitiv bloc</comment>
- <comment xml:lang="ru">блочное устройство</comment>
+ <comment xml:lang="ru">Блочное устройство</comment>
<comment xml:lang="sk">Blokové zariadenie</comment>
<comment xml:lang="sl">bločna naprava</comment>
<comment xml:lang="sq">device me blloqe</comment>
@@ -29200,6 +30127,7 @@
<mime-type type="inode/chardevice">
<comment>character device</comment>
<comment xml:lang="ar">جهاز حرفي</comment>
+ <comment xml:lang="ast">preséu de caráuteres</comment>
<comment xml:lang="be@latin">znakavaja pryłada</comment>
<comment xml:lang="bg">Символно устройство</comment>
<comment xml:lang="ca">dispositiu de caràcters</comment>
@@ -29220,7 +30148,7 @@
<comment xml:lang="hr">Znakovni uređaj</comment>
<comment xml:lang="hu">karakteres eszköz</comment>
<comment xml:lang="ia">Dispositivo de characteres</comment>
- <comment xml:lang="id">karakter divais</comment>
+ <comment xml:lang="id">peranti karakter</comment>
<comment xml:lang="it">Device a caratteri</comment>
<comment xml:lang="ja">キャラクタデバイス</comment>
<comment xml:lang="kk">символдық құрылғысы</comment>
@@ -29236,7 +30164,7 @@
<comment xml:lang="pt">dispositivo de caracteres</comment>
<comment xml:lang="pt_BR">Dispositivo de caractere</comment>
<comment xml:lang="ro">dispozitiv caracter</comment>
- <comment xml:lang="ru">символьное устройство</comment>
+ <comment xml:lang="ru">Символьное устройство</comment>
<comment xml:lang="sk">Znakové zariadenie</comment>
<comment xml:lang="sl">znakovna naprava</comment>
<comment xml:lang="sq">device me karaktere</comment>
@@ -29251,6 +30179,7 @@
<mime-type type="inode/directory">
<comment>folder</comment>
<comment xml:lang="ar">مجلّد</comment>
+ <comment xml:lang="ast">carpeta</comment>
<comment xml:lang="be@latin">kataloh</comment>
<comment xml:lang="bg">Папка</comment>
<comment xml:lang="ca">carpeta</comment>
@@ -29268,7 +30197,7 @@
<comment xml:lang="ga">fillteán</comment>
<comment xml:lang="gl">cartafol</comment>
<comment xml:lang="he">תיקייה</comment>
- <comment xml:lang="hr">direktorij</comment>
+ <comment xml:lang="hr">Mapa</comment>
<comment xml:lang="hu">mappa</comment>
<comment xml:lang="ia">Dossier</comment>
<comment xml:lang="id">folder</comment>
@@ -29287,7 +30216,7 @@
<comment xml:lang="pt">pasta</comment>
<comment xml:lang="pt_BR">Pasta</comment>
<comment xml:lang="ro">dosar</comment>
- <comment xml:lang="ru">папка</comment>
+ <comment xml:lang="ru">Папка</comment>
<comment xml:lang="sk">Priečinok</comment>
<comment xml:lang="sl">mapa</comment>
<comment xml:lang="sq">Kartelë</comment>
@@ -29340,7 +30269,7 @@
<comment xml:lang="pt">canal</comment>
<comment xml:lang="pt_BR">Pipe</comment>
<comment xml:lang="ro">canal pipe</comment>
- <comment xml:lang="ru">канал</comment>
+ <comment xml:lang="ru">Канал</comment>
<comment xml:lang="sk">Rúra</comment>
<comment xml:lang="sl">cev</comment>
<comment xml:lang="sq">Pipe</comment>
@@ -29355,6 +30284,7 @@
<mime-type type="inode/mount-point">
<comment>mount point</comment>
<comment xml:lang="ar">نقطة الوصْل</comment>
+ <comment xml:lang="ast">puntu de montaxe</comment>
<comment xml:lang="be@latin">punkt mantavańnia</comment>
<comment xml:lang="bg">Точка на монтиране</comment>
<comment xml:lang="ca">punt de muntatge</comment>
@@ -29372,7 +30302,7 @@
<comment xml:lang="ga">pointe feistithe</comment>
<comment xml:lang="gl">punto de montaxe</comment>
<comment xml:lang="he">נקודת עיגון</comment>
- <comment xml:lang="hr">točka montiranja</comment>
+ <comment xml:lang="hr">Točka montiranja</comment>
<comment xml:lang="hu">csatolási pont</comment>
<comment xml:lang="ia">Puncto de montage</comment>
<comment xml:lang="id">titik mount</comment>
@@ -29391,7 +30321,7 @@
<comment xml:lang="pt">ponto de montagem</comment>
<comment xml:lang="pt_BR">Ponto de montagem</comment>
<comment xml:lang="ro">loc montare</comment>
- <comment xml:lang="ru">точка монтирования</comment>
+ <comment xml:lang="ru">Точка монтирования</comment>
<comment xml:lang="sk">Miesto pripojenia</comment>
<comment xml:lang="sl">priklopna točka</comment>
<comment xml:lang="sq">Pikë montimi</comment>
@@ -29424,7 +30354,7 @@
<comment xml:lang="ga">soicéad</comment>
<comment xml:lang="gl">socket</comment>
<comment xml:lang="he">נקודת חיבור</comment>
- <comment xml:lang="hr">utičnica</comment>
+ <comment xml:lang="hr">Priključnica</comment>
<comment xml:lang="hu">illesztőpont</comment>
<comment xml:lang="ia">Socket</comment>
<comment xml:lang="id">soket</comment>
@@ -29443,7 +30373,7 @@
<comment xml:lang="pt">tomada</comment>
<comment xml:lang="pt_BR">Socket</comment>
<comment xml:lang="ro">socket</comment>
- <comment xml:lang="ru">сокет</comment>
+ <comment xml:lang="ru">Сокет</comment>
<comment xml:lang="sk">Soket</comment>
<comment xml:lang="sl">vtič</comment>
<comment xml:lang="sq">Socket</comment>
@@ -29458,6 +30388,7 @@
<mime-type type="inode/symlink">
<comment>symbolic link</comment>
<comment xml:lang="ar">وصلة رمزية</comment>
+ <comment xml:lang="ast">enllaz simbólicu</comment>
<comment xml:lang="az">simvolik körpü</comment>
<comment xml:lang="be@latin">symbalnaja spasyłka</comment>
<comment xml:lang="bg">Символна връзка</comment>
@@ -29477,7 +30408,7 @@
<comment xml:lang="ga">nasc siombalach</comment>
<comment xml:lang="gl">ligazón simbólica</comment>
<comment xml:lang="he">קישור סימבולי</comment>
- <comment xml:lang="hr">simbolička veza</comment>
+ <comment xml:lang="hr">Simbolička poveznica</comment>
<comment xml:lang="hu">szimbolikus link</comment>
<comment xml:lang="ia">Ligamine symbolic</comment>
<comment xml:lang="id">taut simbolik</comment>
@@ -29497,7 +30428,7 @@
<comment xml:lang="pt">ligação simbólica</comment>
<comment xml:lang="pt_BR">Ligação simbólica</comment>
<comment xml:lang="ro">legătură simbolică</comment>
- <comment xml:lang="ru">символьная ссылка</comment>
+ <comment xml:lang="ru">Символьная ссылка</comment>
<comment xml:lang="sk">Symbolický odkaz</comment>
<comment xml:lang="sl">simbolna povezava</comment>
<comment xml:lang="sq">Lidhje simbolike</comment>
@@ -29528,10 +30459,10 @@
<comment xml:lang="fi">viestin jakeluilmoitus</comment>
<comment xml:lang="fo">post útberingarfrásøgn</comment>
<comment xml:lang="fr">rapport de livraison de courriels</comment>
- <comment xml:lang="ga">tuairisc sheachadadh poist</comment>
+ <comment xml:lang="ga">tuairisc sheachadta r-phoist</comment>
<comment xml:lang="gl">informe de entrega de correo</comment>
<comment xml:lang="he">דוח העברת דואר</comment>
- <comment xml:lang="hr">izvještaj dostave pošte</comment>
+ <comment xml:lang="hr">Izvještaj dostave pošte</comment>
<comment xml:lang="hu">jelentés levélkézbesítésről</comment>
<comment xml:lang="ia">Reporto de livration de e-mail</comment>
<comment xml:lang="id">laporan pengantaran surat</comment>
@@ -29550,7 +30481,7 @@
<comment xml:lang="pt">relatório de entrega de email</comment>
<comment xml:lang="pt_BR">Relatório de entrega de correspondência</comment>
<comment xml:lang="ro">raport de trimitere email</comment>
- <comment xml:lang="ru">отчёт о доставке сообщения</comment>
+ <comment xml:lang="ru">Отчёт о доставке сообщения</comment>
<comment xml:lang="sk">Správa o doručení pošty</comment>
<comment xml:lang="sl">poročilo dostave pošte</comment>
<comment xml:lang="sq">Raport mbi dorëzimin e mesazhit</comment>
@@ -29583,7 +30514,7 @@
<comment xml:lang="fi">viestin kuittausilmoitus</comment>
<comment xml:lang="fo">post avhendingarfrásøgn</comment>
<comment xml:lang="fr">rapport de disposition de courriels</comment>
- <comment xml:lang="ga">tuairisc chóiriú poist</comment>
+ <comment xml:lang="ga">tuairisc chóirithe r-phoist</comment>
<comment xml:lang="gl">informe de disposición de correo</comment>
<comment xml:lang="he">דוח אספקת דואר</comment>
<comment xml:lang="hr">Izvještaj smještaja e-pošte</comment>
@@ -29605,7 +30536,7 @@
<comment xml:lang="pt">relatório de disposição de email</comment>
<comment xml:lang="pt_BR">Relatório de disposição de correspondência</comment>
<comment xml:lang="ro">confirmare primire email</comment>
- <comment xml:lang="ru">отчёт о перемещении почты</comment>
+ <comment xml:lang="ru">Отчёт о перемещении почты</comment>
<comment xml:lang="sk">Správa o odovzdaní pošty</comment>
<comment xml:lang="sl">poročilo razporeditve pošte</comment>
<comment xml:lang="sq">Raport mbi njoftimin e mesazhit</comment>
@@ -29641,7 +30572,7 @@
<comment xml:lang="ga">tagairt do chomhad cianda</comment>
<comment xml:lang="gl">referencia a un ficheiro remoto</comment>
<comment xml:lang="he">התיחסות לקובץ מרוחק</comment>
- <comment xml:lang="hr">referenca na udaljenu datoteku</comment>
+ <comment xml:lang="hr">Preporuka na udaljenu datoteku</comment>
<comment xml:lang="hu">hivatkozás távoli fájlra</comment>
<comment xml:lang="ia">Referentia a un file remote</comment>
<comment xml:lang="id">referensi ke berkas jarak jauh</comment>
@@ -29660,7 +30591,7 @@
<comment xml:lang="pt">referência a um ficheiro remoto</comment>
<comment xml:lang="pt_BR">Referência para arquivo remoto</comment>
<comment xml:lang="ro">referință fișier la distanță</comment>
- <comment xml:lang="ru">ссылка на удалённый файл</comment>
+ <comment xml:lang="ru">Ссылка на удалённый файл</comment>
<comment xml:lang="sk">Odkaz na vzdialený súbor</comment>
<comment xml:lang="sl">sklic do oddaljene datoteke</comment>
<comment xml:lang="sq">Referim për tek file në distancë</comment>
@@ -29692,7 +30623,7 @@
<comment xml:lang="fi">nyyssiviesti</comment>
<comment xml:lang="fo">Usenet news boð</comment>
<comment xml:lang="fr">message de groupe d'échange Usenet</comment>
- <comment xml:lang="ga">teachtaireacht nuacht Usenet</comment>
+ <comment xml:lang="ga">teachtaireacht nuachta Usenet</comment>
<comment xml:lang="gl">mensaxes de noticias de Usenet</comment>
<comment xml:lang="he">הודעת חדשות של Usenet</comment>
<comment xml:lang="hr">Usenet poruka novosti</comment>
@@ -29714,7 +30645,7 @@
<comment xml:lang="pt">mensagem de notícias Usenet</comment>
<comment xml:lang="pt_BR">Mensagem de notícias da Usenet</comment>
<comment xml:lang="ro">Mesaj Usenet de știri </comment>
- <comment xml:lang="ru">новостное сообщение Usenet</comment>
+ <comment xml:lang="ru">Новостное сообщение Usenet</comment>
<comment xml:lang="sk">Príspevok do diskusných skupín Usenet</comment>
<comment xml:lang="sl">novičarsko sporočilo Usenet</comment>
<comment xml:lang="sq">Mesazh lajmesh Usenet</comment>
@@ -29754,14 +30685,14 @@
<comment xml:lang="ga">teachtaireacht ríomhphoist neamhiomlán</comment>
<comment xml:lang="gl">mensaxe de correo electrónico parcial</comment>
<comment xml:lang="he">מסר דוא״ל חלקי</comment>
- <comment xml:lang="hr">djelomična poruka e-pošte</comment>
+ <comment xml:lang="hr">Nepotpuna poruka e-pošte</comment>
<comment xml:lang="hu">részleges elektronikus levél</comment>
<comment xml:lang="ia">Message de e-mail partial</comment>
<comment xml:lang="id">pesan email sebagian</comment>
<comment xml:lang="it">Messaggio email parziale</comment>
<comment xml:lang="ja">部分メールメッセージ</comment>
<comment xml:lang="kk">электронды поштаның үзінді мәлімдемесі</comment>
- <comment xml:lang="ko">부분적 전자 우편 메시지</comment>
+ <comment xml:lang="ko">전자 우편 메시지 일부</comment>
<comment xml:lang="lt">nepilnas el. laiškas</comment>
<comment xml:lang="lv">daļēja e-pasta vēstule</comment>
<comment xml:lang="ms">Bahagian mesej emel</comment>
@@ -29773,7 +30704,7 @@
<comment xml:lang="pt">mensagem parcial de email</comment>
<comment xml:lang="pt_BR">Mensagem de e-mail parcial</comment>
<comment xml:lang="ro">mesaj de email parțial</comment>
- <comment xml:lang="ru">фрагмент сообщения электронной почты</comment>
+ <comment xml:lang="ru">Фрагмент сообщения электронной почты</comment>
<comment xml:lang="sk">Čiastočná e-mailová správa</comment>
<comment xml:lang="sl">delno elektronsko sporočilo</comment>
<comment xml:lang="sq">Mesazh poste i pjesëshëm</comment>
@@ -29807,7 +30738,7 @@
<comment xml:lang="ga">teachtaireacht ríomhphoist</comment>
<comment xml:lang="gl">mensaxe de correo electrónico</comment>
<comment xml:lang="he">הודעת דואר אלקטרוני</comment>
- <comment xml:lang="hr">poruka e-pošte</comment>
+ <comment xml:lang="hr">Poruka e-pošte</comment>
<comment xml:lang="hu">elektronikus levél</comment>
<comment xml:lang="ia">Message de e-mail</comment>
<comment xml:lang="id">pesan email</comment>
@@ -29826,7 +30757,7 @@
<comment xml:lang="pt">mensagem de email</comment>
<comment xml:lang="pt_BR">Mensagem de e-mail</comment>
<comment xml:lang="ro">mesaj email</comment>
- <comment xml:lang="ru">почтовое сообщение</comment>
+ <comment xml:lang="ru">Почтовое сообщение</comment>
<comment xml:lang="sk">E-mailová správa</comment>
<comment xml:lang="sl">sporočilo elektronske pošte</comment>
<comment xml:lang="sq">Mesazh poste</comment>
@@ -29872,7 +30803,7 @@
<comment xml:lang="fi">GNU-postiviesti</comment>
<comment xml:lang="fo">GNU mail boð</comment>
<comment xml:lang="fr">message de courriel GNU</comment>
- <comment xml:lang="ga">teachtaireacht phost GNU</comment>
+ <comment xml:lang="ga">teachtaireacht r-phoist GNU</comment>
<comment xml:lang="gl">mensaxe de correo electrónico de GNU</comment>
<comment xml:lang="he">הודעת דואר של GNU</comment>
<comment xml:lang="hr">GNU poruka pošte</comment>
@@ -29895,7 +30826,7 @@
<comment xml:lang="pt">mensagem de email GNU</comment>
<comment xml:lang="pt_BR">Mensagem de e-mail GNU</comment>
<comment xml:lang="ro">Mesaj GNU mail</comment>
- <comment xml:lang="ru">почтовое сообщение GNU</comment>
+ <comment xml:lang="ru">Почтовое сообщение GNU</comment>
<comment xml:lang="sk">Správa GNU mail</comment>
<comment xml:lang="sl">Sporočilo pošte GNU</comment>
<comment xml:lang="sq">Mesazh GNU mail</comment>
@@ -29911,20 +30842,31 @@
</mime-type>
<mime-type type="model/iges">
<comment>IGES document</comment>
+ <comment xml:lang="ast">Documentu IGES</comment>
<comment xml:lang="ca">document IGES</comment>
+ <comment xml:lang="cs">dokument IGES</comment>
<comment xml:lang="da">IGES-dokument</comment>
<comment xml:lang="de">IGES-Dokument</comment>
+ <comment xml:lang="en_GB">IGES document</comment>
<comment xml:lang="es">documento IGES</comment>
+ <comment xml:lang="eu">IGES dokumentua</comment>
<comment xml:lang="fi">IGES-asiakirja</comment>
<comment xml:lang="fr">document IGES</comment>
+ <comment xml:lang="ga">cáipéis IGES</comment>
<comment xml:lang="he">מסמך IGES</comment>
+ <comment xml:lang="hr">IGES dokument</comment>
<comment xml:lang="hu">IGES dokumentum</comment>
+ <comment xml:lang="id">dokumen IGES</comment>
+ <comment xml:lang="it">Documento IGES</comment>
<comment xml:lang="kk">IGES құжаты</comment>
<comment xml:lang="ko">IGES 문서</comment>
<comment xml:lang="pl">Dokument IGES</comment>
<comment xml:lang="pt_BR">Documento IGES</comment>
- <comment xml:lang="ru">документ IGES</comment>
+ <comment xml:lang="ru">Документ IGES</comment>
<comment xml:lang="sk">Dokument IGES</comment>
+ <comment xml:lang="sr">ИГЕС документ</comment>
+ <comment xml:lang="sv">IGES-dokument</comment>
+ <comment xml:lang="tr">IGES belgesi</comment>
<comment xml:lang="uk">документ IGES</comment>
<comment xml:lang="zh_CN">IGES 文档</comment>
<comment xml:lang="zh_TW">IGES 文件</comment>
@@ -29942,6 +30884,7 @@
<mime-type type="model/vrml">
<comment>VRML document</comment>
<comment xml:lang="ar">مستند VRML</comment>
+ <comment xml:lang="ast">Documentu VRML</comment>
<comment xml:lang="az">VRML sənədi</comment>
<comment xml:lang="be@latin">Dakument VRML</comment>
<comment xml:lang="bg">Документ — VRML</comment>
@@ -29980,7 +30923,7 @@
<comment xml:lang="pt">documento VRML</comment>
<comment xml:lang="pt_BR">Documento VRML</comment>
<comment xml:lang="ro">Document VRML</comment>
- <comment xml:lang="ru">документ VRML</comment>
+ <comment xml:lang="ru">Документ VRML</comment>
<comment xml:lang="sk">Dokument VRML</comment>
<comment xml:lang="sl">Dokument VRML</comment>
<comment xml:lang="sq">Dokument VRML</comment>
@@ -30021,10 +30964,10 @@
<comment xml:lang="fi">viesti useissa muodoissa</comment>
<comment xml:lang="fo">boð í fleiri sniðum</comment>
<comment xml:lang="fr">message en formats divers</comment>
- <comment xml:lang="ga">teachtaireacht i roinnt fhormáidí</comment>
+ <comment xml:lang="ga">teachtaireacht i bhformáidí éagsúla</comment>
<comment xml:lang="gl">mensaxe en varios formatos</comment>
<comment xml:lang="he">הודעה במספר תבניות</comment>
- <comment xml:lang="hr">poruka u nekoliko oblika</comment>
+ <comment xml:lang="hr">Poruka u nekoliko oblika</comment>
<comment xml:lang="hu">többféle formátumú üzenet</comment>
<comment xml:lang="ia">Message in plure formatos</comment>
<comment xml:lang="id">pesan dalam beberapa format</comment>
@@ -30043,7 +30986,7 @@
<comment xml:lang="pt">mensagem em vários formatos</comment>
<comment xml:lang="pt_BR">Mensagem em vários formatos</comment>
<comment xml:lang="ro">mesaj în diferite formate</comment>
- <comment xml:lang="ru">сообщение в нескольких форматах</comment>
+ <comment xml:lang="ru">Сообщение в нескольких форматах</comment>
<comment xml:lang="sk">Správa v niekoľkých formátoch</comment>
<comment xml:lang="sl">sporočilo v več zapisih</comment>
<comment xml:lang="sq">Mesazh në formate të ndryshëm</comment>
@@ -30052,7 +30995,7 @@
<comment xml:lang="tr">farklı biçimlerde ileti</comment>
<comment xml:lang="uk">повідомлення у кількох форматах</comment>
<comment xml:lang="vi">thông điệp có vài định dạng</comment>
- <comment xml:lang="zh_CN">各种格式的消息</comment>
+ <comment xml:lang="zh_CN">各种格式的信件</comment>
<comment xml:lang="zh_TW">多種格式的訊息</comment>
</mime-type>
<mime-type type="multipart/appledouble">
@@ -30096,7 +31039,7 @@
<comment xml:lang="pt">ficheiro codificado em AppleDouble de Macintosh</comment>
<comment xml:lang="pt_BR">Arquivo do Macintosh codificado com AppleDouble</comment>
<comment xml:lang="ro">Fișier codat Macintosh AppleDouble</comment>
- <comment xml:lang="ru">файл (закодированный Macintosh AppleDouble)</comment>
+ <comment xml:lang="ru">Файл, закодированный Macintosh AppleDouble</comment>
<comment xml:lang="sk">Súbor kódovaný pomocou Macintosh AppleDouble</comment>
<comment xml:lang="sl">Kodirana datoteka Macintosh (AppleDouble)</comment>
<comment xml:lang="sq">File Macintosh i kodifikuar AppleDouble</comment>
@@ -30133,7 +31076,7 @@
<comment xml:lang="hr">Poruka kratkg sadržaja</comment>
<comment xml:lang="hu">ömlesztett üzenet</comment>
<comment xml:lang="ia">Digesto de messages</comment>
- <comment xml:lang="id">pesan digest</comment>
+ <comment xml:lang="id">digest pesan</comment>
<comment xml:lang="it">Digest di messaggi</comment>
<comment xml:lang="ja">メッセージダイジェスト</comment>
<comment xml:lang="kk">мәлімдеме профилі</comment>
@@ -30149,7 +31092,7 @@
<comment xml:lang="pt">grupo de mensagens</comment>
<comment xml:lang="pt_BR">Resumo de mensagem</comment>
<comment xml:lang="ro">colecție mesaje email</comment>
- <comment xml:lang="ru">профиль сообщения</comment>
+ <comment xml:lang="ru">Дайджест сообщения</comment>
<comment xml:lang="sk">Prehľad správ</comment>
<comment xml:lang="sl">povzetek sporočila</comment>
<comment xml:lang="sq">Shpërndarje mesazhesh</comment>
@@ -30158,7 +31101,7 @@
<comment xml:lang="tr">mesaj özeti</comment>
<comment xml:lang="uk">збірка повідомлень</comment>
<comment xml:lang="vi">bản tóm tắt thông điệp</comment>
- <comment xml:lang="zh_CN">消息摘要</comment>
+ <comment xml:lang="zh_CN">信件摘要</comment>
<comment xml:lang="zh_TW">訊息摘要</comment>
</mime-type>
<mime-type type="multipart/encrypted">
@@ -30183,7 +31126,7 @@
<comment xml:lang="ga">teachtaireacht chriptithe</comment>
<comment xml:lang="gl">mensaxe cifrado</comment>
<comment xml:lang="he">הודעה מוצפנת</comment>
- <comment xml:lang="hr">šifrirana poruka</comment>
+ <comment xml:lang="hr">Šifrirana poruka</comment>
<comment xml:lang="hu">titkosított üzenet</comment>
<comment xml:lang="ia">Message cryptate</comment>
<comment xml:lang="id">pesan terenkripsi</comment>
@@ -30202,7 +31145,7 @@
<comment xml:lang="pt">mensagem encriptada</comment>
<comment xml:lang="pt_BR">Mensagem criptografada</comment>
<comment xml:lang="ro">mesaj criptat</comment>
- <comment xml:lang="ru">зашифрованное сообщение</comment>
+ <comment xml:lang="ru">Зашифрованное сообщение</comment>
<comment xml:lang="sk">Zašifrovaná správa</comment>
<comment xml:lang="sl">šifrirano sporočilo</comment>
<comment xml:lang="sq">Mesazh i kriptuar</comment>
@@ -30217,6 +31160,7 @@
<mime-type type="multipart/mixed">
<comment>compound documents</comment>
<comment xml:lang="ar">مستندات مركبة</comment>
+ <comment xml:lang="ast">documentos compuestos</comment>
<comment xml:lang="be@latin">składanyja dakumenty</comment>
<comment xml:lang="bg">Съставни документи</comment>
<comment xml:lang="ca">documents compostos</comment>
@@ -30253,7 +31197,7 @@
<comment xml:lang="pt">documentos compostos</comment>
<comment xml:lang="pt_BR">Documentos compostos</comment>
<comment xml:lang="ro">documente compuse</comment>
- <comment xml:lang="ru">составные документы</comment>
+ <comment xml:lang="ru">Составные документы</comment>
<comment xml:lang="sk">Zložené dokumenty</comment>
<comment xml:lang="sl">združeni dokumenti</comment>
<comment xml:lang="sq">dokumente të përbërë</comment>
@@ -30268,6 +31212,7 @@
<mime-type type="multipart/related">
<comment>compound document</comment>
<comment xml:lang="ar">مستند مركب</comment>
+ <comment xml:lang="ast">documentu compuestu</comment>
<comment xml:lang="az">birləşik sənəd</comment>
<comment xml:lang="be@latin">składany dakument</comment>
<comment xml:lang="bg">Съставен документ</comment>
@@ -30306,7 +31251,7 @@
<comment xml:lang="pt">documento composto</comment>
<comment xml:lang="pt_BR">Documento composto</comment>
<comment xml:lang="ro">document compus</comment>
- <comment xml:lang="ru">составной документ</comment>
+ <comment xml:lang="ru">Составной документ</comment>
<comment xml:lang="sk">Zložený dokument</comment>
<comment xml:lang="sl">združeni dokument</comment>
<comment xml:lang="sq">dokumet i përbërë</comment>
@@ -30337,7 +31282,7 @@
<comment xml:lang="fi">viestijärjestelmän ilmoitus</comment>
<comment xml:lang="fo">postkervisfrásøgn</comment>
<comment xml:lang="fr">rapport système de courriels</comment>
- <comment xml:lang="ga">tuairisc chóras poist</comment>
+ <comment xml:lang="ga">tuairisc chórais r-phoist</comment>
<comment xml:lang="gl">informe do sistema de correo</comment>
<comment xml:lang="he">דו״ח של מערכת הדואר</comment>
<comment xml:lang="hr">Izvještaj sustava pošte</comment>
@@ -30359,7 +31304,7 @@
<comment xml:lang="pt">relatório de sistema de email</comment>
<comment xml:lang="pt_BR">Relatório do sistema de correspondência</comment>
<comment xml:lang="ro">raport sistem email</comment>
- <comment xml:lang="ru">отчёт почтовой системы</comment>
+ <comment xml:lang="ru">Отчёт почтовой системы</comment>
<comment xml:lang="sk">Správa poštového systému</comment>
<comment xml:lang="sl">poročilo poštnega sistema</comment>
<comment xml:lang="sq">Raport i sistemit të postës</comment>
@@ -30393,7 +31338,7 @@
<comment xml:lang="ga">teachtaireacht sínithe</comment>
<comment xml:lang="gl">mensaxe firmado</comment>
<comment xml:lang="he">הודעה חתומה</comment>
- <comment xml:lang="hr">potpisana poruka</comment>
+ <comment xml:lang="hr">Potpisana poruka</comment>
<comment xml:lang="hu">aláírt üzenet</comment>
<comment xml:lang="ia">Message signate</comment>
<comment xml:lang="id">pesan ditandatangani</comment>
@@ -30412,7 +31357,7 @@
<comment xml:lang="pt">mensagem assinada</comment>
<comment xml:lang="pt_BR">Mensagem assinada</comment>
<comment xml:lang="ro">mesaj semnat</comment>
- <comment xml:lang="ru">подписанное сообщение</comment>
+ <comment xml:lang="ru">Подписанное сообщение</comment>
<comment xml:lang="sk">Podpísaná správa</comment>
<comment xml:lang="sl">podpisano sporočilo</comment>
<comment xml:lang="sq">Mesazh i firmosur</comment>
@@ -30444,7 +31389,7 @@
<comment xml:lang="ga">sruth sonraí (brú freastalaí)</comment>
<comment xml:lang="gl">fluxo de datos (por iniciativa do servidor)</comment>
<comment xml:lang="he">מידע בזרימה (דחיפה ע״י השרת)</comment>
- <comment xml:lang="hr">Tok podataka (poslužiteljem pogurano)</comment>
+ <comment xml:lang="hr">Strujanje podataka (poslužiteljem pogurano)</comment>
<comment xml:lang="hu">sugárzott adatfolyam (kiszolgálóról)</comment>
<comment xml:lang="ia">Fluxo de datos (pulsate per servitor)</comment>
<comment xml:lang="id">arus data (dorongan server)</comment>
@@ -30463,7 +31408,7 @@
<comment xml:lang="pt">fluxo de dados (empurrados pelo servidor)</comment>
<comment xml:lang="pt_BR">Fluxo de dados (por iniciativa do servidor)</comment>
<comment xml:lang="ro">flux de date (de la server)</comment>
- <comment xml:lang="ru">поток данных (server push)</comment>
+ <comment xml:lang="ru">Поток данных (server push)</comment>
<comment xml:lang="sk">Prúd dát (posielaný serverom)</comment>
<comment xml:lang="sl">pretok podatkov (strežniški)</comment>
<comment xml:lang="sq">Fluks me të dhëna (server push)</comment>
@@ -30472,7 +31417,7 @@
<comment xml:lang="tr">veri akışı (sunucudan gönderilen)</comment>
<comment xml:lang="uk">потік даних (від сервера)</comment>
<comment xml:lang="vi">luồng dữ liệu (trình phục vụ đẩy)</comment>
- <comment xml:lang="zh_CN">数据流(服务器推送)</comment>
+ <comment xml:lang="zh_CN">数据流(服务器推送)</comment>
<comment xml:lang="zh_TW">資料串流 (server push)</comment>
</mime-type>
<mime-type type="text/calendar">
@@ -30513,7 +31458,7 @@
<comment xml:lang="pt">calendário VCS/ICS</comment>
<comment xml:lang="pt_BR">Calendário VCS/ICS</comment>
<comment xml:lang="ro">Calendar VCS/ICS</comment>
- <comment xml:lang="ru">календарь VCS/ICS</comment>
+ <comment xml:lang="ru">Календарь VCS/ICS</comment>
<comment xml:lang="sk">Kalendár VCS/ICS</comment>
<comment xml:lang="sl">Datoteka koledarja VCS/ICS</comment>
<comment xml:lang="sq">Kalendar VCS/ICS</comment>
@@ -30575,7 +31520,7 @@
<comment xml:lang="pt">folha de estilos CSS</comment>
<comment xml:lang="pt_BR">Folha de estilo CSS</comment>
<comment xml:lang="ro">Pagină de stil CSS</comment>
- <comment xml:lang="ru">таблица стилей CSS</comment>
+ <comment xml:lang="ru">Таблица стилей CSS</comment>
<comment xml:lang="sk">Štýly CSS</comment>
<comment xml:lang="sl">Slogovna predloga CSS</comment>
<comment xml:lang="sq">Fletë stili CSS</comment>
@@ -30611,7 +31556,7 @@
<comment xml:lang="ga">cárta gnó leictreonach</comment>
<comment xml:lang="gl">tarxeta de negocio electrónica</comment>
<comment xml:lang="he">כרטיס ביקור אלקטרוני</comment>
- <comment xml:lang="hr">elektronička posjetnica</comment>
+ <comment xml:lang="hr">Elektronička posjetnica</comment>
<comment xml:lang="hu">elektronikus névjegykártya</comment>
<comment xml:lang="ia">Carta de visita electronic</comment>
<comment xml:lang="id">kartu bisnis elektronik</comment>
@@ -30628,7 +31573,7 @@
<comment xml:lang="pt">cartão de visita eletrónico</comment>
<comment xml:lang="pt_BR">Cartão de visitas eletrônico</comment>
<comment xml:lang="ro">carte de vizită electronică</comment>
- <comment xml:lang="ru">электронная визитная карточка</comment>
+ <comment xml:lang="ru">Электронная визитная карточка</comment>
<comment xml:lang="sk">Elektronická vizitka</comment>
<comment xml:lang="sl">elektronska poslovna vizitka</comment>
<comment xml:lang="sq">Skedë elektronike biznesi</comment>
@@ -30653,6 +31598,7 @@
</mime-type>
<mime-type type="text/turtle">
<comment>Turtle document</comment>
+ <comment xml:lang="ast">Documentu Turtle</comment>
<comment xml:lang="ca">document Turtle</comment>
<comment xml:lang="cs">dokument Turtle</comment>
<comment xml:lang="da">Turtle-dokument</comment>
@@ -30663,6 +31609,7 @@
<comment xml:lang="eu">Turtle dokumentua</comment>
<comment xml:lang="fi">Turtle-asiakirja</comment>
<comment xml:lang="fr">document Turtle</comment>
+ <comment xml:lang="ga">cáipéis Turtle</comment>
<comment xml:lang="he">מסמך Turtle</comment>
<comment xml:lang="hr">Turtle dokument</comment>
<comment xml:lang="hu">Turtle dokumentum</comment>
@@ -30675,7 +31622,7 @@
<comment xml:lang="pl">Dokument Turtle</comment>
<comment xml:lang="pt">documento Turtle</comment>
<comment xml:lang="pt_BR">Documento Turtle</comment>
- <comment xml:lang="ru">документ Turtle</comment>
+ <comment xml:lang="ru">Документ Turtle</comment>
<comment xml:lang="sk">Dokument Turtle</comment>
<comment xml:lang="sr">Тартл документ</comment>
<comment xml:lang="sv">Turtle-dokument</comment>
@@ -30689,6 +31636,7 @@
<mime-type type="text/x-txt2tags">
<comment>txt2tags document</comment>
<comment xml:lang="ar">مستند txt2tags</comment>
+ <comment xml:lang="ast">Documentu txt2tags</comment>
<comment xml:lang="be@latin">dakument txt2tags</comment>
<comment xml:lang="bg">Документ — txt2tags</comment>
<comment xml:lang="ca">document txt2tags</comment>
@@ -30709,7 +31657,7 @@
<comment xml:lang="hr">txt2tags dokument</comment>
<comment xml:lang="hu">txt2tags dokumentum</comment>
<comment xml:lang="ia">Documento txt2tags</comment>
- <comment xml:lang="id">dokumen txt2tags</comment>
+ <comment xml:lang="id">Dokumen txt2tags</comment>
<comment xml:lang="it">Documento txt2tags</comment>
<comment xml:lang="ja">txt2tags ドキュメント</comment>
<comment xml:lang="ka">txt2tags დოკუმენტი</comment>
@@ -30725,7 +31673,7 @@
<comment xml:lang="pt">documento txt2tags</comment>
<comment xml:lang="pt_BR">Documento do txt2tags</comment>
<comment xml:lang="ro">document txt2tags</comment>
- <comment xml:lang="ru">документ txt2tags</comment>
+ <comment xml:lang="ru">Документ txt2tags</comment>
<comment xml:lang="sk">Dokument txt2tags</comment>
<comment xml:lang="sl">Dokument txt2tags</comment>
<comment xml:lang="sq">Dokument txt2tags</comment>
@@ -30747,7 +31695,7 @@
<comment>Verilog source code</comment>
<comment xml:lang="bg">Изходен код — Verilog</comment>
<comment xml:lang="ca">codi font en Verilog</comment>
- <comment xml:lang="cs">zdrojový kód Verilog</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce Verilog</comment>
<comment xml:lang="da">Verilog-kildekode</comment>
<comment xml:lang="de">Verilog-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας Verilog</comment>
@@ -30757,9 +31705,10 @@
<comment xml:lang="eu">Verilog iturburu-kodea</comment>
<comment xml:lang="fi">Verilog-lähdekoodi</comment>
<comment xml:lang="fr">code source Verilog</comment>
+ <comment xml:lang="ga">cód foinseach Verilog</comment>
<comment xml:lang="gl">código fonte en Verilog</comment>
<comment xml:lang="he">קוד מקור של </comment>
- <comment xml:lang="hr">Verilog izvorni kod</comment>
+ <comment xml:lang="hr">Verilog izvorni kôd</comment>
<comment xml:lang="hu">Verilog-forráskód</comment>
<comment xml:lang="ia">Codice-fonte Verilog</comment>
<comment xml:lang="id">Kode sumber Verilog</comment>
@@ -30773,7 +31722,7 @@
<comment xml:lang="pl">Kod źródłowy Verilog</comment>
<comment xml:lang="pt">código origem Verilog</comment>
<comment xml:lang="pt_BR">Código-fonte Verilog</comment>
- <comment xml:lang="ru">исходный код Verilog</comment>
+ <comment xml:lang="ru">Исходный код Verilog</comment>
<comment xml:lang="sk">Zdrojový kód Verilog</comment>
<comment xml:lang="sl">Datoteka izvorne kode Verilog</comment>
<comment xml:lang="sr">изворни код Верилога</comment>
@@ -30798,6 +31747,7 @@
<comment xml:lang="eu">SystemVerilog goiburua</comment>
<comment xml:lang="fi">SystemVerilog-otsake</comment>
<comment xml:lang="fr">en-tête </comment>
+ <comment xml:lang="ga">ceanntásc SystemVerilog</comment>
<comment xml:lang="gl">Cabeceiras de SystemVerilog</comment>
<comment xml:lang="he">כותרת SystemVerilog</comment>
<comment xml:lang="hr">SystemVerilog zaglavlje</comment>
@@ -30814,14 +31764,14 @@
<comment xml:lang="pl">Nagłówek SystemVerilog</comment>
<comment xml:lang="pt">cabeçalho SystemVerilog</comment>
<comment xml:lang="pt_BR">Cabeçalho de SystemVerilog</comment>
- <comment xml:lang="ru">заголовочный файл SystemVerilog</comment>
+ <comment xml:lang="ru">Заголовочный файл SystemVerilog</comment>
<comment xml:lang="sk">Hlavičky SystemVerilog</comment>
<comment xml:lang="sl">Datoteka glave SystemVerilog</comment>
<comment xml:lang="sr">заглавље Система Верилога</comment>
<comment xml:lang="sv">SystemVerilog-headerfil</comment>
<comment xml:lang="tr">SystemVerilog başlığı</comment>
<comment xml:lang="uk">заголовки SystemVerilog</comment>
- <comment xml:lang="zh_CN">SystemVerilog 头</comment>
+ <comment xml:lang="zh_CN">SystemVerilog 头文件</comment>
<comment xml:lang="zh_TW">SystemVerilog 標頭</comment>
<sub-class-of type="text/x-verilog"/>
<glob pattern="*.svh"/>
@@ -30839,9 +31789,10 @@
<comment xml:lang="eu">SystemVerilog iturburu-kodea</comment>
<comment xml:lang="fi">SystemVerilog-lähdekoodi</comment>
<comment xml:lang="fr">code source </comment>
+ <comment xml:lang="ga">cód foinseach SystemVerilog</comment>
<comment xml:lang="gl">código fonte en SystemVerilog</comment>
<comment xml:lang="he">קוד מקור של SystemVerilog</comment>
- <comment xml:lang="hr">SystemVerilog izvorni kod</comment>
+ <comment xml:lang="hr">SystemVerilog izvorni kôd</comment>
<comment xml:lang="hu">SystemVerilog-forráskód</comment>
<comment xml:lang="ia">Codice-fonte SystemVerilog</comment>
<comment xml:lang="id">Kode sumber SystemVerilog</comment>
@@ -30855,7 +31806,7 @@
<comment xml:lang="pl">Kod źródłowy SystemVerilog</comment>
<comment xml:lang="pt">código origem SystemVerilog</comment>
<comment xml:lang="pt_BR">Código-fonte de SystemVerilog</comment>
- <comment xml:lang="ru">исходный код SystemVerilog</comment>
+ <comment xml:lang="ru">Исходный код SystemVerilog</comment>
<comment xml:lang="sk">Zdrojový kód SystemVerilog</comment>
<comment xml:lang="sl">Datoteka izvorne kode SystemVerilog</comment>
<comment xml:lang="sr">изворни код Система Верилога</comment>
@@ -30871,7 +31822,7 @@
<comment>VHDL source code</comment>
<comment xml:lang="bg">Изходен код — VHDL</comment>
<comment xml:lang="ca">codi font en VHDL</comment>
- <comment xml:lang="cs">zdrojový kód VHDL</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce VHDL</comment>
<comment xml:lang="da">VHDL-kildekode</comment>
<comment xml:lang="de">VHDL-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας VHDL</comment>
@@ -30881,9 +31832,10 @@
<comment xml:lang="eu">VHDL iturburu-kodea</comment>
<comment xml:lang="fi">VHDL-lähdekoodi</comment>
<comment xml:lang="fr">code source VHDL</comment>
+ <comment xml:lang="ga">cód foinseach VHDL</comment>
<comment xml:lang="gl">código fonte en VHDL</comment>
<comment xml:lang="he">קוד מקור של VHDL</comment>
- <comment xml:lang="hr">VHDL izvorni kod</comment>
+ <comment xml:lang="hr">VHDL izvorni kôd</comment>
<comment xml:lang="hu">VHDL-forráskód</comment>
<comment xml:lang="ia">Codice-fonte VHDL</comment>
<comment xml:lang="id">Kode sumber VHDL</comment>
@@ -30897,7 +31849,7 @@
<comment xml:lang="pl">Kod źródłowy VHDL</comment>
<comment xml:lang="pt">código origem VHDL</comment>
<comment xml:lang="pt_BR">Código-fonte VHDL</comment>
- <comment xml:lang="ru">исходный код VHDL</comment>
+ <comment xml:lang="ru">Исходный код VHDL</comment>
<comment xml:lang="sk">Zdrojový kód VHDL</comment>
<comment xml:lang="sl">Datoteka izvorne kode VHDL</comment>
<comment xml:lang="sr">ВХДЛ изворни код</comment>
@@ -30915,6 +31867,7 @@
<mime-type type="text/enriched">
<comment>enriched text document</comment>
<comment xml:lang="ar">مستند نصي مغنى</comment>
+ <comment xml:lang="ast">documentu de testu arriquecíu</comment>
<comment xml:lang="az">zəngin mətn sənədi</comment>
<comment xml:lang="be@latin">azdobleny tekstavy dakument</comment>
<comment xml:lang="bg">Документ с обогатен текст</comment>
@@ -30934,7 +31887,7 @@
<comment xml:lang="ga">cáipéis téacs saibhrithe</comment>
<comment xml:lang="gl">documento de texto enriquecido</comment>
<comment xml:lang="he">מסמך טקסט מועשר</comment>
- <comment xml:lang="hr">obogaćeni tekstualni dokument</comment>
+ <comment xml:lang="hr">Obogaćeni tekstovni dokument</comment>
<comment xml:lang="hu">enriched text dokumentum</comment>
<comment xml:lang="ia">Documento de texto inricchite</comment>
<comment xml:lang="id">dokumen teks diperkaya</comment>
@@ -30953,7 +31906,7 @@
<comment xml:lang="pt">documento de texto rico</comment>
<comment xml:lang="pt_BR">Documento de texto enriquecido</comment>
<comment xml:lang="ro">document text îmbogățit</comment>
- <comment xml:lang="ru">форматированный текстовый документ</comment>
+ <comment xml:lang="ru">Форматированный текстовый документ</comment>
<comment xml:lang="sk">Rozšírený textový dokument</comment>
<comment xml:lang="sl">dokument z obogatenim besedilom</comment>
<comment xml:lang="sq">Dokument teksti i pasuruar</comment>
@@ -30962,7 +31915,7 @@
<comment xml:lang="tr">zenginleştirilmiş metin belgesi</comment>
<comment xml:lang="uk">форматований текстовий документ</comment>
<comment xml:lang="vi">tài liệu văn bản có kiểu dáng</comment>
- <comment xml:lang="zh_CN">富文本文档</comment>
+ <comment xml:lang="zh_CN">浓缩文本文档 (ETF)</comment>
<comment xml:lang="zh_TW">豐富化文字文件</comment>
<sub-class-of type="text/plain"/>
</mime-type>
@@ -30988,7 +31941,7 @@
<comment xml:lang="ga">leathanach cabhrach</comment>
<comment xml:lang="gl">páxina de axuda</comment>
<comment xml:lang="he">דף עזרה</comment>
- <comment xml:lang="hr">stranica pomoći</comment>
+ <comment xml:lang="hr">Stranica pomoći</comment>
<comment xml:lang="hu">súgóoldal</comment>
<comment xml:lang="ia">Pagina de adjuta</comment>
<comment xml:lang="id">halaman bantuan</comment>
@@ -31007,7 +31960,7 @@
<comment xml:lang="pt">página de ajuda</comment>
<comment xml:lang="pt_BR">Página de ajuda</comment>
<comment xml:lang="ro">pagină de ajutor</comment>
- <comment xml:lang="ru">страница справки</comment>
+ <comment xml:lang="ru">Страница справки</comment>
<comment xml:lang="sk">Stránka Pomocníka</comment>
<comment xml:lang="sl">stran pomoči</comment>
<comment xml:lang="sq">Faqe ndihme</comment>
@@ -31023,6 +31976,7 @@
<mime-type type="text/plain">
<comment>plain text document</comment>
<comment xml:lang="ar">مستند نصي مجرد</comment>
+ <comment xml:lang="ast">documentu de testu planu</comment>
<comment xml:lang="be@latin">prosty tekstavy dakument</comment>
<comment xml:lang="bg">Документ с неформатиран текст</comment>
<comment xml:lang="ca">document de text pla</comment>
@@ -31039,10 +31993,10 @@
<comment xml:lang="ga">cáipéis ghnáth-théacs</comment>
<comment xml:lang="gl">documento de texto sinxelo</comment>
<comment xml:lang="he">מסמך טקסט פשוט</comment>
- <comment xml:lang="hr">običan tekstualni dokument</comment>
+ <comment xml:lang="hr">Običan tekstovni dokument</comment>
<comment xml:lang="hu">egyszerű szöveg</comment>
<comment xml:lang="ia">Documento de texto simple</comment>
- <comment xml:lang="id">dokumen teks biasa</comment>
+ <comment xml:lang="id">dokumen teks polos</comment>
<comment xml:lang="it">Documento in testo semplice</comment>
<comment xml:lang="ja">平文テキストドキュメント</comment>
<comment xml:lang="kk">мәтіндік құжаты</comment>
@@ -31058,7 +32012,7 @@
<comment xml:lang="pt">documento em texto simples</comment>
<comment xml:lang="pt_BR">Documento de Texto</comment>
<comment xml:lang="ro">document text simplu</comment>
- <comment xml:lang="ru">текстовый документ</comment>
+ <comment xml:lang="ru">Текстовый документ</comment>
<comment xml:lang="sk">Obyčajný textový dokument</comment>
<comment xml:lang="sl">običajna besedilna datoteka</comment>
<comment xml:lang="sq">Dokument në tekst të thjeshtë</comment>
@@ -31115,7 +32069,7 @@
<comment xml:lang="pt">ficheiro RDF</comment>
<comment xml:lang="pt_BR">Arquivo RDF</comment>
<comment xml:lang="ro">Fișier RDF</comment>
- <comment xml:lang="ru">файл RDF</comment>
+ <comment xml:lang="ru">Файл RDF</comment>
<comment xml:lang="sk">Súbor RDF</comment>
<comment xml:lang="sl">Datoteka RDF</comment>
<comment xml:lang="sq">File RDF</comment>
@@ -31146,6 +32100,7 @@
<comment xml:lang="es">archivo en XML OWL</comment>
<comment xml:lang="eu">OWL XML fitxategia</comment>
<comment xml:lang="fr">fichier XML OWL</comment>
+ <comment xml:lang="ga">comhad XML OWL</comment>
<comment xml:lang="hr">OWL XML datoteka</comment>
<comment xml:lang="hu">OWL XML-fájl</comment>
<comment xml:lang="ia">File XML OWL</comment>
@@ -31157,7 +32112,7 @@
<comment xml:lang="pl">Plik XML OWL</comment>
<comment xml:lang="pt">ficheiro OWL XML</comment>
<comment xml:lang="pt_BR">Arquivo OWL XML</comment>
- <comment xml:lang="ru">файл XML OWL</comment>
+ <comment xml:lang="ru">Файл XML OWL</comment>
<comment xml:lang="sk">Súbor XML OWL</comment>
<comment xml:lang="sr">ОВЛ ИксМЛ датотека</comment>
<comment xml:lang="sv">OWL XML-fil</comment>
@@ -31196,14 +32151,14 @@
<comment xml:lang="ga">ceanntásca ríomhphoist</comment>
<comment xml:lang="gl">cabeceiras de correo electrónico</comment>
<comment xml:lang="he">כותרת דוא״ל</comment>
- <comment xml:lang="hr">zaglavlja e-pošte</comment>
+ <comment xml:lang="hr">Zaglavlja e-pošte</comment>
<comment xml:lang="hu">levélfejléc</comment>
<comment xml:lang="ia">Capites de e-mail</comment>
- <comment xml:lang="id">tajuk email</comment>
+ <comment xml:lang="id">header email</comment>
<comment xml:lang="it">Intestazioni email</comment>
<comment xml:lang="ja">メールヘッダー</comment>
<comment xml:lang="kk">пошталық тақырыптамалары</comment>
- <comment xml:lang="ko">전자 우편 헤더</comment>
+ <comment xml:lang="ko">전자메일 헤더</comment>
<comment xml:lang="lt">el. laiško antraštės</comment>
<comment xml:lang="lv">e-pasta galvene</comment>
<comment xml:lang="ms">Pengepala emel</comment>
@@ -31215,7 +32170,7 @@
<comment xml:lang="pt">cabeçalhos de email</comment>
<comment xml:lang="pt_BR">Cabeçalhos de e-mail</comment>
<comment xml:lang="ro">antete email</comment>
- <comment xml:lang="ru">почтовые заголовки</comment>
+ <comment xml:lang="ru">Почтовые заголовки</comment>
<comment xml:lang="sk">Hlavičky e-mailu</comment>
<comment xml:lang="sl">glava elektronske pošte</comment>
<comment xml:lang="sq">Header email</comment>
@@ -31231,6 +32186,7 @@
<mime-type type="text/richtext">
<comment>rich text document</comment>
<comment xml:lang="ar">مستند نصي غني</comment>
+ <comment xml:lang="ast">documentu de testu ricu</comment>
<comment xml:lang="az">zəngin mətn sənədi</comment>
<comment xml:lang="be@latin">azdobleny tekstavy dakument</comment>
<comment xml:lang="bg">Документ — rich text</comment>
@@ -31249,7 +32205,7 @@
<comment xml:lang="ga">cáipéis mhéith-théacs</comment>
<comment xml:lang="gl">documento do texto enriquecido</comment>
<comment xml:lang="he">מסמך טקסט עשיר</comment>
- <comment xml:lang="hr">obogaćeni tekstualni dokument</comment>
+ <comment xml:lang="hr">Obogaćeni tekstovni dokument</comment>
<comment xml:lang="hu">rich text-dokumentum</comment>
<comment xml:lang="ia">Documento de texto inricchite</comment>
<comment xml:lang="id">dokumen teks kaya</comment>
@@ -31268,7 +32224,7 @@
<comment xml:lang="pt">documento em texto rico</comment>
<comment xml:lang="pt_BR">Documento rich text</comment>
<comment xml:lang="ro">document text îmbogățit</comment>
- <comment xml:lang="ru">документ с форматированным текстом</comment>
+ <comment xml:lang="ru">Документ с форматированным текстом</comment>
<comment xml:lang="sk">Textový dokument RTF</comment>
<comment xml:lang="sl">dokument z oblikovanim besedilom</comment>
<comment xml:lang="sq">Dokument rich text</comment>
@@ -31277,7 +32233,7 @@
<comment xml:lang="tr">zengin metin belgesi</comment>
<comment xml:lang="uk">форматований текстовий документ</comment>
<comment xml:lang="vi">tài liệu văn bản có kiểu dáng (RTF)</comment>
- <comment xml:lang="zh_CN">RTF 丰富文本文档</comment>
+ <comment xml:lang="zh_CN">富文本文档 (RTF)</comment>
<comment xml:lang="zh_TW">豐富文字文件</comment>
<sub-class-of type="text/plain"/>
<glob pattern="*.rtx"/>
@@ -31319,7 +32275,7 @@
<comment xml:lang="pt">resumo RSS</comment>
<comment xml:lang="pt_BR">Resumo RSS</comment>
<comment xml:lang="ro">Rezumat RSS</comment>
- <comment xml:lang="ru">сводка RSS</comment>
+ <comment xml:lang="ru">Сводка RSS</comment>
<comment xml:lang="sk">Súhrn RSS</comment>
<comment xml:lang="sl">Datoteka povzetek RSS</comment>
<comment xml:lang="sq">Përmbledhje RSS</comment>
@@ -31366,7 +32322,7 @@
<comment xml:lang="it">Feed di distribuzione Atom</comment>
<comment xml:lang="ja">Atom 配信フィード</comment>
<comment xml:lang="kk">Atom жаңалықтар таспасы</comment>
- <comment xml:lang="ko">Atom 동기화 피드</comment>
+ <comment xml:lang="ko">Atom 묶음 피드</comment>
<comment xml:lang="lt">Atom sindikacijos kanalas</comment>
<comment xml:lang="lv">Atom sindikāta barotne</comment>
<comment xml:lang="nb">Atom syndikeringsstrøm</comment>
@@ -31377,7 +32333,7 @@
<comment xml:lang="pt">feed Atom</comment>
<comment xml:lang="pt_BR">Fonte de notícias Atom</comment>
<comment xml:lang="ro">Flux agregare Atom</comment>
- <comment xml:lang="ru">лента новостей Atom</comment>
+ <comment xml:lang="ru">Лента новостей Atom</comment>
<comment xml:lang="sk">Kanál Atom</comment>
<comment xml:lang="sl">Sindikalni vir Atom</comment>
<comment xml:lang="sq">Feed për përhapje Atom</comment>
@@ -31386,7 +32342,7 @@
<comment xml:lang="tr">Atom besleme kaynağı</comment>
<comment xml:lang="uk">трансляція подач Atom</comment>
<comment xml:lang="vi">Nguồn tin tức Atom</comment>
- <comment xml:lang="zh_CN">Atom 更新种子</comment>
+ <comment xml:lang="zh_CN">Atom 聚合种子</comment>
<comment xml:lang="zh_TW">Atom 聯合供稿饋流</comment>
<sub-class-of type="application/xml"/>
<generic-icon name="text-html"/>
@@ -31432,7 +32388,7 @@
<comment xml:lang="pt">feed OPML</comment>
<comment xml:lang="pt_BR">Fonte de notícias OPML</comment>
<comment xml:lang="ro">Flux OPML syndication</comment>
- <comment xml:lang="ru">лента новостей OPML</comment>
+ <comment xml:lang="ru">Лента новостей OPML</comment>
<comment xml:lang="sk">Kanál OPML</comment>
<comment xml:lang="sl">Sindikalni vir OPML</comment>
<comment xml:lang="sq">Feed për përhapje OPML</comment>
@@ -31454,6 +32410,7 @@
<mime-type type="text/sgml">
<comment>SGML document</comment>
<comment xml:lang="ar">مستند SGML</comment>
+ <comment xml:lang="ast">Documentu SGML</comment>
<comment xml:lang="be@latin">Dakument SGML</comment>
<comment xml:lang="bg">Документ — SGML</comment>
<comment xml:lang="ca">document SGML</comment>
@@ -31491,7 +32448,7 @@
<comment xml:lang="pt">documento SGML</comment>
<comment xml:lang="pt_BR">Documento SGML</comment>
<comment xml:lang="ro">Document SGML</comment>
- <comment xml:lang="ru">документ SGML</comment>
+ <comment xml:lang="ru">Документ SGML</comment>
<comment xml:lang="sk">Dokument SGML</comment>
<comment xml:lang="sl">Dokument SGML</comment>
<comment xml:lang="sq">Dokument SGML</comment>
@@ -31511,6 +32468,7 @@
<mime-type type="text/spreadsheet">
<comment>spreadsheet interchange document</comment>
<comment xml:lang="ar">مستند تبادل الجدول</comment>
+ <comment xml:lang="ast">documentu d'intercambéu de fueyes de cálculu</comment>
<comment xml:lang="be@latin">dakument dla abmienu raźlikovymi arkušami</comment>
<comment xml:lang="bg">Документ за обмяна между програми за електронни таблици</comment>
<comment xml:lang="ca">document d'intercanvi de full de càlcul</comment>
@@ -31545,7 +32503,7 @@
<comment xml:lang="pt">documento de troca interna de folhas de cálculo</comment>
<comment xml:lang="pt_BR">Documento de intercâmbio de planilhas</comment>
<comment xml:lang="ro">document schimb filă de calcul</comment>
- <comment xml:lang="ru">документ Spreadsheet Interchange</comment>
+ <comment xml:lang="ru">Документ Spreadsheet Interchange</comment>
<comment xml:lang="sk">Zošitový prenosový dokument</comment>
<comment xml:lang="sl">dokument izmenjeve preglednic</comment>
<comment xml:lang="sq">Dokument shkëmbimi për fletë llogaritje</comment>
@@ -31566,6 +32524,7 @@
<mime-type type="text/tab-separated-values">
<comment>TSV document</comment>
<comment xml:lang="ar">مستند TSV</comment>
+ <comment xml:lang="ast">Documentu TSV</comment>
<comment xml:lang="be@latin">Dakument TSV</comment>
<comment xml:lang="bg">Документ — TSV</comment>
<comment xml:lang="ca">document TSV</comment>
@@ -31600,7 +32559,7 @@
<comment xml:lang="pt">documento TSV</comment>
<comment xml:lang="pt_BR">Documento TSV</comment>
<comment xml:lang="ro">Document TSV</comment>
- <comment xml:lang="ru">документ TSV</comment>
+ <comment xml:lang="ru">Документ TSV</comment>
<comment xml:lang="sk">Dokument TSV</comment>
<comment xml:lang="sl">Dokument TSV</comment>
<comment xml:lang="sq">Dokument TSV</comment>
@@ -31658,7 +32617,7 @@
<comment xml:lang="tr">Graphviz DOT grafiği</comment>
<comment xml:lang="uk">граф DOT Graphviz</comment>
<comment xml:lang="vi">Biểu đồ DOT Graphviz</comment>
- <comment xml:lang="zh_CN">Graphviz DOT 科学图形</comment>
+ <comment xml:lang="zh_CN">Graphviz DOT 图形</comment>
<comment xml:lang="zh_TW">Graphviz DOT 圖</comment>
<generic-icon name="x-office-document"/>
<magic priority="50">
@@ -31673,6 +32632,7 @@
<mime-type type="text/vnd.sun.j2me.app-descriptor">
<comment>JAD document</comment>
<comment xml:lang="ar">مستند JAD</comment>
+ <comment xml:lang="ast">Documentu JAD</comment>
<comment xml:lang="be@latin">Dakument JAD</comment>
<comment xml:lang="bg">Документ — JAD</comment>
<comment xml:lang="ca">document JAD</comment>
@@ -31708,7 +32668,7 @@
<comment xml:lang="pt">documento JAD</comment>
<comment xml:lang="pt_BR">Documento JAD</comment>
<comment xml:lang="ro">Document JAD</comment>
- <comment xml:lang="ru">документ JAD</comment>
+ <comment xml:lang="ru">Документ JAD</comment>
<comment xml:lang="sk">Dokument JAD</comment>
<comment xml:lang="sl">Dokument JAD</comment>
<comment xml:lang="sq">Dokument JAD</comment>
@@ -31729,6 +32689,7 @@
<mime-type type="text/vnd.wap.wml">
<comment>WML document</comment>
<comment xml:lang="ar">مستند WML</comment>
+ <comment xml:lang="ast">Documentu WML</comment>
<comment xml:lang="az">WML sənədi</comment>
<comment xml:lang="be@latin">Dakument WML</comment>
<comment xml:lang="bg">Документ — WML</comment>
@@ -31767,7 +32728,7 @@
<comment xml:lang="pt">documento WML</comment>
<comment xml:lang="pt_BR">Documento WML</comment>
<comment xml:lang="ro">Document WML</comment>
- <comment xml:lang="ru">документ WML</comment>
+ <comment xml:lang="ru">Документ WML</comment>
<comment xml:lang="sk">Dokument WML</comment>
<comment xml:lang="sl">Dokument WML</comment>
<comment xml:lang="sq">Dokument WML</comment>
@@ -31820,7 +32781,7 @@
<comment xml:lang="pt">programa WMLScript</comment>
<comment xml:lang="pt_BR">Programa WMLScript</comment>
<comment xml:lang="ro">Program WMLScript</comment>
- <comment xml:lang="ru">сценарий WMLScript</comment>
+ <comment xml:lang="ru">Программа WMLScript</comment>
<comment xml:lang="sk">Program WMLScript</comment>
<comment xml:lang="sl">Programska datoteka WMLScript</comment>
<comment xml:lang="sq">Program WMLScript</comment>
@@ -31872,7 +32833,7 @@
<comment xml:lang="pt">arquivo ACE</comment>
<comment xml:lang="pt_BR">Pacote ACE</comment>
<comment xml:lang="ro">Arhivă ACE</comment>
- <comment xml:lang="ru">архив ACE</comment>
+ <comment xml:lang="ru">Архив ACE</comment>
<comment xml:lang="sk">Archív ACE</comment>
<comment xml:lang="sl">Datoteka arhiva ACE</comment>
<comment xml:lang="sq">Arkiv ACE</comment>
@@ -31909,10 +32870,10 @@
<comment xml:lang="ga">cód foinseach Ada</comment>
<comment xml:lang="gl">código fonte en Ada</comment>
<comment xml:lang="he">קוד מקור Ada</comment>
- <comment xml:lang="hr">Ada izvorni kod</comment>
+ <comment xml:lang="hr">Ada izvorni kôd</comment>
<comment xml:lang="hu">Ada-forráskód</comment>
<comment xml:lang="ia">Codice-fonte Ada</comment>
- <comment xml:lang="id">Kode program Ada</comment>
+ <comment xml:lang="id">Kode sumber Ada</comment>
<comment xml:lang="it">Codice sorgente Ada</comment>
<comment xml:lang="ja">Ada ソースコード</comment>
<comment xml:lang="ka">Ada-ის საწყისი კოდი</comment>
@@ -31929,7 +32890,7 @@
<comment xml:lang="pt">código origem Ada</comment>
<comment xml:lang="pt_BR">Código-fonte Ada</comment>
<comment xml:lang="ro">Cod sursă Ada</comment>
- <comment xml:lang="ru">исходный код Ada</comment>
+ <comment xml:lang="ru">Исходный код Ada</comment>
<comment xml:lang="sk">Zdrojový kód jazyka Ada</comment>
<comment xml:lang="sl">Datoteka izvorne kode Ada</comment>
<comment xml:lang="sq">Kod burues Ada</comment>
@@ -31983,7 +32944,7 @@
<comment xml:lang="pt">lista de autores</comment>
<comment xml:lang="pt_BR">Lista de autores</comment>
<comment xml:lang="ro">listă autori</comment>
- <comment xml:lang="ru">список авторов</comment>
+ <comment xml:lang="ru">Список авторов</comment>
<comment xml:lang="sk">Zoznam autorov</comment>
<comment xml:lang="sl">seznam avtorjev</comment>
<comment xml:lang="sq">Lista e autorëve</comment>
@@ -32000,6 +32961,7 @@
<mime-type type="text/x-bibtex">
<comment>BibTeX document</comment>
<comment xml:lang="ar">مستند BibTeX</comment>
+ <comment xml:lang="ast">Documentu de BibTeX</comment>
<comment xml:lang="be@latin">Dakument BibTeX</comment>
<comment xml:lang="bg">Документ — BibTeX</comment>
<comment xml:lang="ca">document BibTeX</comment>
@@ -32036,7 +32998,7 @@
<comment xml:lang="pt">documento BibTeX</comment>
<comment xml:lang="pt_BR">Documento BibTeX</comment>
<comment xml:lang="ro">Document BibTeX</comment>
- <comment xml:lang="ru">документ BibTeX</comment>
+ <comment xml:lang="ru">Документ BibTeX</comment>
<comment xml:lang="sk">Dokument BibTeX</comment>
<comment xml:lang="sl">Dokument BibTeX</comment>
<comment xml:lang="sq">Dokument BibTeX</comment>
@@ -32075,7 +33037,7 @@
<comment xml:lang="hr">C++ zaglavlje</comment>
<comment xml:lang="hu">C++ fejléc</comment>
<comment xml:lang="ia">Capite C++</comment>
- <comment xml:lang="id">Tajuk C++</comment>
+ <comment xml:lang="id">Header C++</comment>
<comment xml:lang="it">Header C++</comment>
<comment xml:lang="ja">C++ ヘッダー</comment>
<comment xml:lang="ka">C++-ის თავსართი</comment>
@@ -32091,7 +33053,7 @@
<comment xml:lang="pt">cabeçalho C++</comment>
<comment xml:lang="pt_BR">Cabeçalho C++</comment>
<comment xml:lang="ro">Antet C++</comment>
- <comment xml:lang="ru">заголовочный файл C++</comment>
+ <comment xml:lang="ru">Заголовочный файл C++</comment>
<comment xml:lang="sk">Hlavičky jazyka C++</comment>
<comment xml:lang="sl">Datoteka glave C++</comment>
<comment xml:lang="sq">Header C++</comment>
@@ -32100,7 +33062,7 @@
<comment xml:lang="tr">C++ başlığı</comment>
<comment xml:lang="uk">файл заголовків мовою C++</comment>
<comment xml:lang="vi">Phần đầu mã nguồn C++</comment>
- <comment xml:lang="zh_CN">C++ 源代码头文件</comment>
+ <comment xml:lang="zh_CN">C++ 头文件</comment>
<comment xml:lang="zh_TW">C++ 標頭檔</comment>
<sub-class-of type="text/x-chdr"/>
<glob pattern="*.hh"/>
@@ -32115,7 +33077,7 @@
<comment xml:lang="be@latin">Kryničny kod C++</comment>
<comment xml:lang="bg">Изходен код — C++</comment>
<comment xml:lang="ca">codi font en C++</comment>
- <comment xml:lang="cs">zdrojový kód C++</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce C++</comment>
<comment xml:lang="da">C++-kildekode</comment>
<comment xml:lang="de">C++-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας C++</comment>
@@ -32129,10 +33091,10 @@
<comment xml:lang="ga">cód foinseach C++</comment>
<comment xml:lang="gl">código fonte de C++</comment>
<comment xml:lang="he">קוד מקור של C++‎</comment>
- <comment xml:lang="hr">C++ izvorni kod</comment>
+ <comment xml:lang="hr">C++ izvorni kôd</comment>
<comment xml:lang="hu">C++-forráskód</comment>
<comment xml:lang="ia">Codice-fonte C++</comment>
- <comment xml:lang="id">Kode program C++</comment>
+ <comment xml:lang="id">Kode sumber C++</comment>
<comment xml:lang="it">Codice sorgente C++</comment>
<comment xml:lang="ja">C++ ソースコード</comment>
<comment xml:lang="ka">C++-ის საწყისი კოდი</comment>
@@ -32149,7 +33111,7 @@
<comment xml:lang="pt">código origem C++</comment>
<comment xml:lang="pt_BR">Código-fonte C++</comment>
<comment xml:lang="ro">Cod sursă C++</comment>
- <comment xml:lang="ru">исходный код C++</comment>
+ <comment xml:lang="ru">Исходный код C++</comment>
<comment xml:lang="sk">Zdrojový kód jazyka C++</comment>
<comment xml:lang="sl">Datoteka izvorne kode C++</comment>
<comment xml:lang="sq">Kod burues C++</comment>
@@ -32170,6 +33132,7 @@
<mime-type type="text/x-changelog">
<comment>ChangeLog document</comment>
<comment xml:lang="ar">مستند ChangeLog</comment>
+ <comment xml:lang="ast">Documentu de rexistru de cambeos</comment>
<comment xml:lang="be@latin">Dakument zafiksavanych źmienaŭ ChangeLog</comment>
<comment xml:lang="bg">Дневник за промени — ChangeLog</comment>
<comment xml:lang="ca">document de registre de canvis</comment>
@@ -32186,7 +33149,7 @@
<comment xml:lang="ga">cáipéis ChangeLog</comment>
<comment xml:lang="gl">documento Changelog</comment>
<comment xml:lang="he">מסמך של ChangeLog</comment>
- <comment xml:lang="hr">Dokument zaspisa promjena</comment>
+ <comment xml:lang="hr">Dokument zapisa promjena</comment>
<comment xml:lang="hu">ChangeLog dokumentum</comment>
<comment xml:lang="ia">Lista de cambiamentos</comment>
<comment xml:lang="id">Dokumen ChangeLog</comment>
@@ -32205,11 +33168,11 @@
<comment xml:lang="pt">documento ChangeLog</comment>
<comment xml:lang="pt_BR">Documento ChangeLog</comment>
<comment xml:lang="ro">Document ChangeLog</comment>
- <comment xml:lang="ru">протокол изменений</comment>
+ <comment xml:lang="ru">Протокол изменений</comment>
<comment xml:lang="sk">Dokument ChangeLog</comment>
<comment xml:lang="sl">Dokument ChangeLog</comment>
<comment xml:lang="sq">Dokument ChangeLog</comment>
- <comment xml:lang="sr">Ченџ Лог документ</comment>
+ <comment xml:lang="sr">документ дневника измена</comment>
<comment xml:lang="sv">Ändringsloggsdokument</comment>
<comment xml:lang="tr">Değişim Günlüğü belgesi</comment>
<comment xml:lang="uk">документ ChangeLog</comment>
@@ -32241,7 +33204,7 @@
<comment xml:lang="hr">C zaglavlje</comment>
<comment xml:lang="hu">C fejléc</comment>
<comment xml:lang="ia">Capite C</comment>
- <comment xml:lang="id">Tajuk C</comment>
+ <comment xml:lang="id">Header C</comment>
<comment xml:lang="it">Header C</comment>
<comment xml:lang="ja">C ヘッダー</comment>
<comment xml:lang="ka">C-ის თავსართი</comment>
@@ -32257,7 +33220,7 @@
<comment xml:lang="pt">cabeçalho C</comment>
<comment xml:lang="pt_BR">Cabeçalho C</comment>
<comment xml:lang="ro">Antet C</comment>
- <comment xml:lang="ru">заголовочный файл C</comment>
+ <comment xml:lang="ru">Заголовочный файл C</comment>
<comment xml:lang="sk">Hlavičky jazyka C</comment>
<comment xml:lang="sl">Datoteka glave C</comment>
<comment xml:lang="sq">Header C</comment>
@@ -32291,10 +33254,10 @@
<comment xml:lang="ga">cód foinseach CMake</comment>
<comment xml:lang="gl">código fonte de CMake</comment>
<comment xml:lang="he">קוד מקור של CMake</comment>
- <comment xml:lang="hr">CMake izvorni kod</comment>
+ <comment xml:lang="hr">CMake izvorni kôd</comment>
<comment xml:lang="hu">CMake-forráskód</comment>
<comment xml:lang="ia">Codice-fonte CMake</comment>
- <comment xml:lang="id">Kode program CMake</comment>
+ <comment xml:lang="id">Kode sumber CMake</comment>
<comment xml:lang="it">Codice sorgente CMake</comment>
<comment xml:lang="ja">CMake ソースコード</comment>
<comment xml:lang="ka">CMake-ის საწყისი კოდი</comment>
@@ -32310,7 +33273,7 @@
<comment xml:lang="pt">código origem CMake</comment>
<comment xml:lang="pt_BR">Código-fonte CMake</comment>
<comment xml:lang="ro">Cod sursă CMake</comment>
- <comment xml:lang="ru">исходный код CMake</comment>
+ <comment xml:lang="ru">Исходный код CMake</comment>
<comment xml:lang="sk">Zdrojový kód CMake</comment>
<comment xml:lang="sl">Datoteka izvorne kode CMake</comment>
<comment xml:lang="sq">Kod burues CMake</comment>
@@ -32328,6 +33291,7 @@
<mime-type type="text/csv">
<comment>CSV document</comment>
<comment xml:lang="ar">مستند CSV</comment>
+ <comment xml:lang="ast">Documentu CVS</comment>
<comment xml:lang="be@latin">Dakument CSV</comment>
<comment xml:lang="bg">Документ — CSV</comment>
<comment xml:lang="ca">document CSV</comment>
@@ -32364,7 +33328,7 @@
<comment xml:lang="pt">documento CSV</comment>
<comment xml:lang="pt_BR">Documento CSV</comment>
<comment xml:lang="ro">Document CSV</comment>
- <comment xml:lang="ru">документ CSV</comment>
+ <comment xml:lang="ru">Документ CSV</comment>
<comment xml:lang="sk">Dokument CSV</comment>
<comment xml:lang="sl">Dokument CSV</comment>
<comment xml:lang="sq">Dokument CSV</comment>
@@ -32384,6 +33348,7 @@
</mime-type>
<mime-type type="text/csv-schema">
<comment>CSV Schema document</comment>
+ <comment xml:lang="ast">Documentu d'esquema CSV</comment>
<comment xml:lang="ca">document Schema de CSV</comment>
<comment xml:lang="cs">dokument schématu CSV</comment>
<comment xml:lang="da">CSV Schema-dokument</comment>
@@ -32392,6 +33357,8 @@
<comment xml:lang="es">documento esquemático CSV</comment>
<comment xml:lang="eu">CSV Schema dokumentua</comment>
<comment xml:lang="fr">document schéma CSV</comment>
+ <comment xml:lang="ga">cáipéis scéimre CSV</comment>
+ <comment xml:lang="he">מסמך פריסת CSV</comment>
<comment xml:lang="hr">CSV Shema dokument</comment>
<comment xml:lang="hu">CSV sémadokumentum</comment>
<comment xml:lang="ia">Documento CSV Schema</comment>
@@ -32402,7 +33369,7 @@
<comment xml:lang="pl">Dokument schematu CSV</comment>
<comment xml:lang="pt">documento CSV Schema</comment>
<comment xml:lang="pt_BR">Documento CSV Schema</comment>
- <comment xml:lang="ru">документ CSV Schema</comment>
+ <comment xml:lang="ru">Документ CSV Schema</comment>
<comment xml:lang="sk">Dokument schémy CSV</comment>
<comment xml:lang="sr">документ ЦСВ шеме</comment>
<comment xml:lang="sv">CSV Schema-dokument</comment>
@@ -32418,6 +33385,7 @@
<mime-type type="text/x-copying">
<comment>license terms</comment>
<comment xml:lang="ar">شروط الترخيص</comment>
+ <comment xml:lang="ast">términos de llicencia</comment>
<comment xml:lang="be@latin">licenzijnyja ŭmovy</comment>
<comment xml:lang="bg">Лицензни условия</comment>
<comment xml:lang="ca">condicions de llicència</comment>
@@ -32434,7 +33402,7 @@
<comment xml:lang="ga">téarmaí ceadúnais</comment>
<comment xml:lang="gl">termos de licenza</comment>
<comment xml:lang="he">תנאי רישיון</comment>
- <comment xml:lang="hr">uvjeti licence</comment>
+ <comment xml:lang="hr">Uvjeti licence</comment>
<comment xml:lang="hu">licencfeltételek</comment>
<comment xml:lang="ia">Conditiones de licentia</comment>
<comment xml:lang="id">persyaratan lisensi</comment>
@@ -32452,7 +33420,7 @@
<comment xml:lang="pt">termos de licença</comment>
<comment xml:lang="pt_BR">Termos de licença</comment>
<comment xml:lang="ro">termeni de licență</comment>
- <comment xml:lang="ru">лицензионное соглашение</comment>
+ <comment xml:lang="ru">Лицензионное соглашение</comment>
<comment xml:lang="sk">Licenčné podmienky</comment>
<comment xml:lang="sl">pogoji in dovoljenja uporabe</comment>
<comment xml:lang="sq">Kushte liçence</comment>
@@ -32469,6 +33437,7 @@
<mime-type type="text/x-credits">
<comment>author credits</comment>
<comment xml:lang="ar">شكر وتقدير المؤلف</comment>
+ <comment xml:lang="ast">creitos del autor</comment>
<comment xml:lang="be@latin">zasłuhi aŭtara</comment>
<comment xml:lang="bg">Благодарности към авторите</comment>
<comment xml:lang="ca">atribucions d'autor</comment>
@@ -32502,7 +33471,7 @@
<comment xml:lang="pt">créditos de autor</comment>
<comment xml:lang="pt_BR">Créditos do autor</comment>
<comment xml:lang="ro">mulțumiri autori</comment>
- <comment xml:lang="ru">авторы программы</comment>
+ <comment xml:lang="ru">Авторы программы</comment>
<comment xml:lang="sk">Autorské zásluhy</comment>
<comment xml:lang="sl">avtorske zasluge</comment>
<comment xml:lang="sq">Kreditë e autorëve</comment>
@@ -32522,7 +33491,7 @@
<comment xml:lang="be@latin">Kryničny kod C</comment>
<comment xml:lang="bg">Изходен код — C</comment>
<comment xml:lang="ca">codi font en C</comment>
- <comment xml:lang="cs">zdrojový kód C</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce C</comment>
<comment xml:lang="da">C-kildekode</comment>
<comment xml:lang="de">C-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας C</comment>
@@ -32536,10 +33505,10 @@
<comment xml:lang="ga">cód foinseach C</comment>
<comment xml:lang="gl">código fonte en C</comment>
<comment xml:lang="he">קוד מקור של C</comment>
- <comment xml:lang="hr">C izvorni kod</comment>
+ <comment xml:lang="hr">C izvorni kôd</comment>
<comment xml:lang="hu">C-forráskód</comment>
<comment xml:lang="ia">Codice-fonte C</comment>
- <comment xml:lang="id">Kode program C</comment>
+ <comment xml:lang="id">Kode sumber C</comment>
<comment xml:lang="it">Codice sorgente C</comment>
<comment xml:lang="ja">C ソースコード</comment>
<comment xml:lang="ka">C-ის საწყისი კოდი</comment>
@@ -32556,7 +33525,7 @@
<comment xml:lang="pt">código origem C</comment>
<comment xml:lang="pt_BR">Código-fonte C</comment>
<comment xml:lang="ro">Cod sursă C</comment>
- <comment xml:lang="ru">исходный код C</comment>
+ <comment xml:lang="ru">Исходный код C</comment>
<comment xml:lang="sk">Zdrojový kód jazyka C</comment>
<comment xml:lang="sl">Datoteka izvorne kode C</comment>
<comment xml:lang="sq">Kod burues C</comment>
@@ -32582,7 +33551,7 @@
<comment xml:lang="be@latin">Kryničny kod C#</comment>
<comment xml:lang="bg">Изходен код — C#</comment>
<comment xml:lang="ca">codi font en C#</comment>
- <comment xml:lang="cs">zdrojový kód C#</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce C#</comment>
<comment xml:lang="da">C#-kildekode</comment>
<comment xml:lang="de">C#-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας C#</comment>
@@ -32596,10 +33565,10 @@
<comment xml:lang="ga">cód foinseach C#</comment>
<comment xml:lang="gl">código fonte en C#</comment>
<comment xml:lang="he">קוד מקור של C#‎</comment>
- <comment xml:lang="hr">C# izvorni kod</comment>
+ <comment xml:lang="hr">C# izvorni kôd</comment>
<comment xml:lang="hu">C#-forráskód</comment>
<comment xml:lang="ia">Codice-fonte C#</comment>
- <comment xml:lang="id">Kode program C#</comment>
+ <comment xml:lang="id">Kode sumber C#</comment>
<comment xml:lang="it">Codice sorgente C#</comment>
<comment xml:lang="ja">C# ソースコード</comment>
<comment xml:lang="ka">C#-ის საწყისი კოდი</comment>
@@ -32616,7 +33585,7 @@
<comment xml:lang="pt">código origem C#</comment>
<comment xml:lang="pt_BR">Código-fonte C#</comment>
<comment xml:lang="ro">Cod sursă C#</comment>
- <comment xml:lang="ru">исходный код C#</comment>
+ <comment xml:lang="ru">Исходный код C#</comment>
<comment xml:lang="sk">Zdrojový kód jazyka C#</comment>
<comment xml:lang="sl">Datoteka izvorne kode C#</comment>
<comment xml:lang="sq">Kod burues C#</comment>
@@ -32636,7 +33605,7 @@
<comment xml:lang="be@latin">Kryničny kod Vala</comment>
<comment xml:lang="bg">Изходен код — Vala</comment>
<comment xml:lang="ca">codi font en Vala</comment>
- <comment xml:lang="cs">zdrojový kód Vala</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce Vala</comment>
<comment xml:lang="da">Valakildekode</comment>
<comment xml:lang="de">Vala-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας Vala</comment>
@@ -32650,10 +33619,10 @@
<comment xml:lang="ga">cód foinseach Vala</comment>
<comment xml:lang="gl">código fonte en Vala</comment>
<comment xml:lang="he">קוד מקור של Vala</comment>
- <comment xml:lang="hr">Vala izvorni kod</comment>
+ <comment xml:lang="hr">Vala izvorni kôd</comment>
<comment xml:lang="hu">Vala forráskód</comment>
<comment xml:lang="ia">Codice-fonte Vala</comment>
- <comment xml:lang="id">Kode program Vala</comment>
+ <comment xml:lang="id">Kode sumber Vala</comment>
<comment xml:lang="it">Codice sorgente Vala</comment>
<comment xml:lang="ja">Vala ソースコード</comment>
<comment xml:lang="kk">Vala бастапқы коды</comment>
@@ -32668,7 +33637,7 @@
<comment xml:lang="pt">código origem Vala</comment>
<comment xml:lang="pt_BR">Código-fonte Vala</comment>
<comment xml:lang="ro">Cod sursă Vala</comment>
- <comment xml:lang="ru">исходный код Vala</comment>
+ <comment xml:lang="ru">Исходный код Vala</comment>
<comment xml:lang="sk">Zdrojový kód Vala</comment>
<comment xml:lang="sl">Datoteka izvorne kode Vala</comment>
<comment xml:lang="sq">Kod burues Vala</comment>
@@ -32697,9 +33666,10 @@
<comment xml:lang="eu">OOC iturburu-kodea</comment>
<comment xml:lang="fi">OOC-lähdekoodi</comment>
<comment xml:lang="fr">source code OOC</comment>
+ <comment xml:lang="ga">cód foinseach OOC</comment>
<comment xml:lang="gl">código fonte de OOC</comment>
<comment xml:lang="he">קוד מקור של OOC</comment>
- <comment xml:lang="hr">OOC izvorni kod</comment>
+ <comment xml:lang="hr">OOC izvorni kôd</comment>
<comment xml:lang="hu">OOC forráskód</comment>
<comment xml:lang="ia">Codice-fonte OCC</comment>
<comment xml:lang="id">Kode sumber OOC</comment>
@@ -32714,14 +33684,14 @@
<comment xml:lang="pl">Kod źródłowy OOC</comment>
<comment xml:lang="pt">código origem OOC</comment>
<comment xml:lang="pt_BR">Código-fonte OOC</comment>
- <comment xml:lang="ru">исходный код OOC</comment>
+ <comment xml:lang="ru">Исходный код OOC</comment>
<comment xml:lang="sk">Zdrojový kód OOC</comment>
<comment xml:lang="sl">Izvorna koda OOC</comment>
<comment xml:lang="sr">ООЦ изворни ко̂д</comment>
<comment xml:lang="sv">OOC-källkod</comment>
<comment xml:lang="tr">OOC kaynak kodu</comment>
<comment xml:lang="uk">вихідний код мовою OOC</comment>
- <comment xml:lang="zh_CN">OOC</comment>
+ <comment xml:lang="zh_CN">OOC 源代码</comment>
<comment xml:lang="zh_TW">OOC 源碼</comment>
<acronym>OOC</acronym>
<expanded-acronym>Out Of Class</expanded-acronym>
@@ -32770,7 +33740,7 @@
<comment xml:lang="pt">script DCL</comment>
<comment xml:lang="pt_BR">Script DCL</comment>
<comment xml:lang="ro">Script DCL</comment>
- <comment xml:lang="ru">сценарий DCL</comment>
+ <comment xml:lang="ru">Сценарий DCL</comment>
<comment xml:lang="sk">Skript DCL</comment>
<comment xml:lang="sl">Skriptna datoteka DCL</comment>
<comment xml:lang="sq">Script DCL</comment>
@@ -32789,6 +33759,7 @@
<mime-type type="text/x-dsl">
<comment>DSSSL document</comment>
<comment xml:lang="ar">مستند DSSSL</comment>
+ <comment xml:lang="ast">Documentu DSSSL</comment>
<comment xml:lang="az">DSSSL sənədi</comment>
<comment xml:lang="be@latin">Dakument DSSSL</comment>
<comment xml:lang="bg">Документ — DSSSL</comment>
@@ -32828,7 +33799,7 @@
<comment xml:lang="pt">documento DSSSL</comment>
<comment xml:lang="pt_BR">Documento DSSSL</comment>
<comment xml:lang="ro">Document DSSSL</comment>
- <comment xml:lang="ru">документ DSSSL</comment>
+ <comment xml:lang="ru">Документ DSSSL</comment>
<comment xml:lang="sk">Dokument DSSSL</comment>
<comment xml:lang="sl">Dokument DSSSL</comment>
<comment xml:lang="sq">Dokument DSSSL</comment>
@@ -32850,7 +33821,7 @@
<comment xml:lang="be@latin">Kryničny kod D</comment>
<comment xml:lang="bg">Изходен код — D</comment>
<comment xml:lang="ca">codi font en D</comment>
- <comment xml:lang="cs">zdrojový kód D</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce D</comment>
<comment xml:lang="da">D-kildekode</comment>
<comment xml:lang="de">D-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας D</comment>
@@ -32864,10 +33835,10 @@
<comment xml:lang="ga">cód foinseach D</comment>
<comment xml:lang="gl">código fonte de D</comment>
<comment xml:lang="he">קוד מקור לשפת D</comment>
- <comment xml:lang="hr">D izvorni kod</comment>
+ <comment xml:lang="hr">D izvorni kôd</comment>
<comment xml:lang="hu">D-forráskód</comment>
<comment xml:lang="ia">Codice-fonte D</comment>
- <comment xml:lang="id">Kode program D</comment>
+ <comment xml:lang="id">Kode sumber D</comment>
<comment xml:lang="it">Codice sorgente D</comment>
<comment xml:lang="ja">D ソースコード</comment>
<comment xml:lang="ka">D-ის საწყისი კოდი</comment>
@@ -32883,7 +33854,7 @@
<comment xml:lang="pt">código origem D</comment>
<comment xml:lang="pt_BR">Código-fonte D</comment>
<comment xml:lang="ro">Cod sursă D</comment>
- <comment xml:lang="ru">исходный код D</comment>
+ <comment xml:lang="ru">Исходный код D</comment>
<comment xml:lang="sk">Zdrojový kód jazyka D</comment>
<comment xml:lang="sl">Datoteka izvorne kode D</comment>
<comment xml:lang="sq">Kod burues D</comment>
@@ -32937,7 +33908,7 @@
<comment xml:lang="pt">ficheiro DTD</comment>
<comment xml:lang="pt_BR">Arquivo DTD</comment>
<comment xml:lang="ro">Fișier DTD</comment>
- <comment xml:lang="ru">файл DTD</comment>
+ <comment xml:lang="ru">Файл DTD</comment>
<comment xml:lang="sk">Súbor DTD</comment>
<comment xml:lang="sl">Datoteka DTD</comment>
<comment xml:lang="sq">File DTD</comment>
@@ -32961,7 +33932,7 @@
<comment xml:lang="be@latin">Kryničny kod Eiffel</comment>
<comment xml:lang="bg">Изходен код — Eiffel</comment>
<comment xml:lang="ca">codi font en Eiffel</comment>
- <comment xml:lang="cs">zdrojový kód Eiffel</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce Eiffel</comment>
<comment xml:lang="da">Eiffelkildekode</comment>
<comment xml:lang="de">Eiffel-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας Eiffel</comment>
@@ -32975,10 +33946,10 @@
<comment xml:lang="ga">cód foinseach Eiffel</comment>
<comment xml:lang="gl">código fone de Eiffel</comment>
<comment xml:lang="he">קוד מקור של Eiffel</comment>
- <comment xml:lang="hr">Eiffel izvorni kod</comment>
+ <comment xml:lang="hr">Eiffel izvorni kôd</comment>
<comment xml:lang="hu">Eiffel forráskód</comment>
<comment xml:lang="ia">Codice-fonte Eiffel</comment>
- <comment xml:lang="id">Kode program Eiffel</comment>
+ <comment xml:lang="id">Kode sumber Eiffel</comment>
<comment xml:lang="it">Codice sorgente Eiffel</comment>
<comment xml:lang="ja">Eiffel ソースコード</comment>
<comment xml:lang="ka">Eiffel-ის საწყისი კოდი</comment>
@@ -32994,7 +33965,7 @@
<comment xml:lang="pt">código origem Eiffel</comment>
<comment xml:lang="pt_BR">Código-fonte Eiffel</comment>
<comment xml:lang="ro">Cod sursă Eiffel</comment>
- <comment xml:lang="ru">исходный код Eiffel</comment>
+ <comment xml:lang="ru">Исходный код Eiffel</comment>
<comment xml:lang="sk">Zdrojový kód Eiffel</comment>
<comment xml:lang="sl">Datoteka izvorne kode Eiffel</comment>
<comment xml:lang="sq">Kod burues Eiffel</comment>
@@ -33031,7 +34002,7 @@
<comment xml:lang="ga">cód foinseach Emacs Lisp</comment>
<comment xml:lang="gl">código fonte de Emacs Lisp</comment>
<comment xml:lang="he">קוד מקור של Emcas Lisp</comment>
- <comment xml:lang="hr">Emacs Lisp izvorni kod</comment>
+ <comment xml:lang="hr">Emacs Lisp izvorni kôd</comment>
<comment xml:lang="hu">Emacs Lisp-forráskód</comment>
<comment xml:lang="ia">Codice-fonte Lisp de Emacs</comment>
<comment xml:lang="id">Kode sumber Emacs Lisp</comment>
@@ -33051,7 +34022,7 @@
<comment xml:lang="pt">código origem Emacs Lisp</comment>
<comment xml:lang="pt_BR">Código-fonte Lisp do Emacs</comment>
<comment xml:lang="ro">Cod sursă Emacs Lisp</comment>
- <comment xml:lang="ru">исходный код Emacs Lisp</comment>
+ <comment xml:lang="ru">Исходный код Emacs Lisp</comment>
<comment xml:lang="sk">Zdrojový kód Emacs Lisp</comment>
<comment xml:lang="sl">Datoteka izvorne kode Emacs Lisp</comment>
<comment xml:lang="sq">Kod burues Emacs Lisp</comment>
@@ -33075,7 +34046,7 @@
<comment xml:lang="be@latin">Kryničny kod Erlang</comment>
<comment xml:lang="bg">Изходен код — Erlang</comment>
<comment xml:lang="ca">codi font en Erlang</comment>
- <comment xml:lang="cs">zdrojový kód Erlang</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce Erlang</comment>
<comment xml:lang="da">Erlangkildekode</comment>
<comment xml:lang="de">Erlang-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας Erlang</comment>
@@ -33089,10 +34060,10 @@
<comment xml:lang="ga">cód foinseach Erlang</comment>
<comment xml:lang="gl">código fonte de Erlang</comment>
<comment xml:lang="he">קוד מקור של Erlang</comment>
- <comment xml:lang="hr">Erlang izvorni kod</comment>
+ <comment xml:lang="hr">Erlang izvorni kôd</comment>
<comment xml:lang="hu">Erlang forráskód</comment>
<comment xml:lang="ia">Codice-fonte Erlang</comment>
- <comment xml:lang="id">Kode program Erlang</comment>
+ <comment xml:lang="id">Kode sumber Erlang</comment>
<comment xml:lang="it">Codice sorgente Erlang</comment>
<comment xml:lang="ja">Erlang ソースコード</comment>
<comment xml:lang="ka">Erlang-ის საწყისი კოდი</comment>
@@ -33108,7 +34079,7 @@
<comment xml:lang="pt">código origem Erlang</comment>
<comment xml:lang="pt_BR">Código-fonte Erlang</comment>
<comment xml:lang="ro">Cod sursă Erlang</comment>
- <comment xml:lang="ru">исходный код Erlang</comment>
+ <comment xml:lang="ru">Исходный код Erlang</comment>
<comment xml:lang="sk">Zdrojový kód Erlang</comment>
<comment xml:lang="sl">Datoteka izvorne kode Erlang</comment>
<comment xml:lang="sq">Kod burues Erlang</comment>
@@ -33129,7 +34100,7 @@
<comment xml:lang="be@latin">Kryničny kod Fortran</comment>
<comment xml:lang="bg">Изходен код — Fortran</comment>
<comment xml:lang="ca">codi font en Fortran</comment>
- <comment xml:lang="cs">zdrojový kód Fortran</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce Fortran</comment>
<comment xml:lang="cy">Ffynhonnell rhaglen FORTRAN</comment>
<comment xml:lang="da">Fortrankildekode</comment>
<comment xml:lang="de">Fortran-Quelltext</comment>
@@ -33144,10 +34115,10 @@
<comment xml:lang="ga">cód foinseach Fortran</comment>
<comment xml:lang="gl">código fonte de Fortran</comment>
<comment xml:lang="he">קוד מקור של Fortran</comment>
- <comment xml:lang="hr">Fortran izvorni kod</comment>
+ <comment xml:lang="hr">Fortran izvorni kôd</comment>
<comment xml:lang="hu">Fortran-forráskód</comment>
<comment xml:lang="ia">Codice-fonte Fortran</comment>
- <comment xml:lang="id">Kode program Fortran</comment>
+ <comment xml:lang="id">Kode sumber Fortran</comment>
<comment xml:lang="it">Codice sorgente Fortran</comment>
<comment xml:lang="ja">Fortran ソースコード</comment>
<comment xml:lang="ka">Fortran-ის საწყისი კოდი</comment>
@@ -33164,7 +34135,7 @@
<comment xml:lang="pt">código origem Fortran</comment>
<comment xml:lang="pt_BR">Código-fonte Fortran</comment>
<comment xml:lang="ro">Cod sursă Fortran</comment>
- <comment xml:lang="ru">исходный код Fortran</comment>
+ <comment xml:lang="ru">Исходный код Fortran</comment>
<comment xml:lang="sk">Zdrojový kód Fortran</comment>
<comment xml:lang="sl">Datoteka izvorne kode Fortran</comment>
<comment xml:lang="sq">Kod burues Fortran</comment>
@@ -33193,10 +34164,12 @@
<comment xml:lang="eu">Genie iturburu-kodea</comment>
<comment xml:lang="fi">Genie-lähdekoodi</comment>
<comment xml:lang="fr">code source Genie</comment>
+ <comment xml:lang="ga">cód foinseach Genie</comment>
+ <comment xml:lang="he">קוד מקור של Genie</comment>
<comment xml:lang="hr">Genie izvorni kôd</comment>
<comment xml:lang="hu">Genie forráskód</comment>
<comment xml:lang="ia">Codice-fonte Genie</comment>
- <comment xml:lang="id">Kode program Genie</comment>
+ <comment xml:lang="id">Kode sumber Genie</comment>
<comment xml:lang="it">Codice sorgente Genie</comment>
<comment xml:lang="kk">Genie бастапқы коды</comment>
<comment xml:lang="ko">Genie 소스 코드</comment>
@@ -33204,7 +34177,7 @@
<comment xml:lang="pl">Kod źródłowy Genie</comment>
<comment xml:lang="pt">código origem Genie</comment>
<comment xml:lang="pt_BR">Código-fonte Genie</comment>
- <comment xml:lang="ru">исходный код Genie</comment>
+ <comment xml:lang="ru">Исходный код Genie</comment>
<comment xml:lang="sk">Zdrojový kód Genie</comment>
<comment xml:lang="sl">Izvorna koda Genie</comment>
<comment xml:lang="sr">Гение изворни ко̂д</comment>
@@ -33220,6 +34193,7 @@
<mime-type type="text/x-gettext-translation">
<comment>translation file</comment>
<comment xml:lang="ar">ملف الترجمة</comment>
+ <comment xml:lang="ast">ficheru de traducción</comment>
<comment xml:lang="be@latin">fajł pierakładu</comment>
<comment xml:lang="bg">Превод</comment>
<comment xml:lang="ca">fitxer de traducció</comment>
@@ -33234,10 +34208,10 @@
<comment xml:lang="fi">käännöstiedosto</comment>
<comment xml:lang="fo">týðingarfíla</comment>
<comment xml:lang="fr">fichier de traduction</comment>
- <comment xml:lang="ga">comhad aistrithe</comment>
+ <comment xml:lang="ga">comhad aistriúcháin</comment>
<comment xml:lang="gl">ficheiro de tradución</comment>
<comment xml:lang="he">קובץ תרגום</comment>
- <comment xml:lang="hr">datoteka prijevoda</comment>
+ <comment xml:lang="hr">Datoteka prijevoda</comment>
<comment xml:lang="hu">fordítási fájl</comment>
<comment xml:lang="ia">File de traduction</comment>
<comment xml:lang="id">berkas terjemahan</comment>
@@ -33256,7 +34230,7 @@
<comment xml:lang="pt">ficheiro de tradução</comment>
<comment xml:lang="pt_BR">Arquivo de tradução</comment>
<comment xml:lang="ro">fișier traducere</comment>
- <comment xml:lang="ru">файл переводов</comment>
+ <comment xml:lang="ru">Файл переводов</comment>
<comment xml:lang="sk">Súbor prekladu</comment>
<comment xml:lang="sl">datoteka prevoda programa</comment>
<comment xml:lang="sq">File përkthimesh</comment>
@@ -33265,7 +34239,7 @@
<comment xml:lang="tr">çeviri dosyası</comment>
<comment xml:lang="uk">файл перекладу</comment>
<comment xml:lang="vi">tập tin dịch</comment>
- <comment xml:lang="zh_CN">消息翻译文件</comment>
+ <comment xml:lang="zh_CN">翻译文件</comment>
<comment xml:lang="zh_TW">翻譯檔</comment>
<sub-class-of type="text/plain"/>
<glob pattern="*.po"/>
@@ -33275,6 +34249,7 @@
<mime-type type="text/x-gettext-translation-template">
<comment>translation template</comment>
<comment xml:lang="ar">قالب الترجمة</comment>
+ <comment xml:lang="ast">plantía de traducción</comment>
<comment xml:lang="be@latin">šablon dla pierakładu</comment>
<comment xml:lang="bg">Шаблон за преводи</comment>
<comment xml:lang="ca">plantilla de traducció</comment>
@@ -33289,10 +34264,10 @@
<comment xml:lang="fi">käännösmalli</comment>
<comment xml:lang="fo">týðingarformur</comment>
<comment xml:lang="fr">modèle de traduction</comment>
- <comment xml:lang="ga">teimpléad aistrithe</comment>
+ <comment xml:lang="ga">teimpléad aistriúcháin</comment>
<comment xml:lang="gl">plantilla de tradución</comment>
<comment xml:lang="he">תבנית תרגום</comment>
- <comment xml:lang="hr">predložak prijevoda</comment>
+ <comment xml:lang="hr">Predložak prijevoda</comment>
<comment xml:lang="hu">fordítási sablon</comment>
<comment xml:lang="ia">Patrono de traduction</comment>
<comment xml:lang="id">templat terjemahan</comment>
@@ -33311,7 +34286,7 @@
<comment xml:lang="pt">modelo de tradução</comment>
<comment xml:lang="pt_BR">Modelo de tradução</comment>
<comment xml:lang="ro">șablon de traducere</comment>
- <comment xml:lang="ru">шаблон переводов</comment>
+ <comment xml:lang="ru">Шаблон переводов</comment>
<comment xml:lang="sk">Šablóna prekladu</comment>
<comment xml:lang="sl">predloga datoteke prevoda programa</comment>
<comment xml:lang="sq">Model përkthimesh</comment>
@@ -33320,7 +34295,7 @@
<comment xml:lang="tr">çeviri şablonu</comment>
<comment xml:lang="uk">шаблон перекладу</comment>
<comment xml:lang="vi">mẫu dịch</comment>
- <comment xml:lang="zh_CN">消息翻译模板</comment>
+ <comment xml:lang="zh_CN">翻译模板</comment>
<comment xml:lang="zh_TW">翻譯模版</comment>
<sub-class-of type="text/plain"/>
<glob pattern="*.pot"/>
@@ -33332,18 +34307,27 @@
<mime-type type="text/x-gherkin">
<comment>feature specification in Gherkin format</comment>
<comment xml:lang="ca">especificació de funcionalitat en format Gherkin</comment>
+ <comment xml:lang="cs">specifikace vlastností ve formátu Gherkin</comment>
<comment xml:lang="da">funktionspecifikation i Gherkin-format</comment>
<comment xml:lang="de">Funktionsspezifikation im Gherkin-Format</comment>
+ <comment xml:lang="en_GB">feature specification in Gherkin format</comment>
<comment xml:lang="es">especificación de funcionalidad en formato Gherkin</comment>
<comment xml:lang="fr">spécification fonctionnelle au format Gherkin</comment>
+ <comment xml:lang="ga">sonraíocht gnéithe i bhformáid Gherkin</comment>
<comment xml:lang="he">פירוט תכונות בתבנית Gherkin</comment>
+ <comment xml:lang="hr">opis značajke u Gherkin formatu</comment>
<comment xml:lang="hu">funkcióleírás Gherkin formátumban</comment>
+ <comment xml:lang="id">spesifikasi fitur dalam format Gherkin</comment>
+ <comment xml:lang="it">Specifica di funzionalità in formato Gherkin</comment>
<comment xml:lang="kk">Gherkin пішіміндегі функционалды анықтамалар</comment>
<comment xml:lang="ko">Gherkin 형식의 기능 명세</comment>
<comment xml:lang="pl">Specyfikacja funkcji w formacie Gherkin</comment>
<comment xml:lang="pt_BR">Especificação de recurso no formato Gherkin</comment>
- <comment xml:lang="ru">функциональные определения в формате Gherkin</comment>
+ <comment xml:lang="ru">Функциональные определения в формате Gherkin</comment>
<comment xml:lang="sk">Špecifikácia funkcie vo formáte Gherkin</comment>
+ <comment xml:lang="sr">одредба функције у запису Геркина</comment>
+ <comment xml:lang="sv">egenskapsspecifikation i Gherkin-format</comment>
+ <comment xml:lang="tr">Gherkin biçiminde özellik belirtimi</comment>
<comment xml:lang="uk">специфікація можливості у форматі Gherkin</comment>
<comment xml:lang="zh_CN">Gherkin 格式中的功能规范</comment>
<comment xml:lang="zh_TW">Gherkin 格式的特徵規格</comment>
@@ -33353,6 +34337,7 @@
<mime-type type="text/html">
<comment>HTML document</comment>
<comment xml:lang="ar">مستند HTML</comment>
+ <comment xml:lang="ast">Documentu HTML</comment>
<comment xml:lang="be@latin">Dakument HTML</comment>
<comment xml:lang="bg">Документ — HTML</comment>
<comment xml:lang="ca">document HTML</comment>
@@ -33388,7 +34373,7 @@
<comment xml:lang="pt">documento HTML</comment>
<comment xml:lang="pt_BR">Documento HTML</comment>
<comment xml:lang="ro">Document HTML</comment>
- <comment xml:lang="ru">документ HTML</comment>
+ <comment xml:lang="ru">Документ HTML</comment>
<comment xml:lang="sk">Dokument HTML</comment>
<comment xml:lang="sl">Dokument HTML</comment>
<comment xml:lang="sq">Dokument HTML</comment>
@@ -33434,7 +34419,7 @@
<comment xml:lang="de">Webanwendungscache-Manifest</comment>
<comment xml:lang="el">Δηλωτικό λανθάνουσας μνήμης εφαρμογής Ιστού</comment>
<comment xml:lang="en_GB">Web application cache manifest</comment>
- <comment xml:lang="es">manifiesto de caché de aplicación web</comment>
+ <comment xml:lang="es">manifiesto de antememoria de aplicación web</comment>
<comment xml:lang="eu">Web aplikazioaren cache-aren agiria</comment>
<comment xml:lang="fo">Net nýtsluskipanarkova manifest</comment>
<comment xml:lang="fr">manifeste de cache d'application Web</comment>
@@ -33457,7 +34442,7 @@
<comment xml:lang="pt">manifesto de cache de aplicação web</comment>
<comment xml:lang="pt_BR">Manifest de cache de aplicação web</comment>
<comment xml:lang="ro">Manifest de cache pentru aplicații web</comment>
- <comment xml:lang="ru">манифест кэша веб-приложения</comment>
+ <comment xml:lang="ru">Манифест кэша веб-приложения</comment>
<comment xml:lang="sk">Manifest vyrovnávacej pamäte webovej aplikácie</comment>
<comment xml:lang="sl">Predpomnilnik spletnega programa</comment>
<comment xml:lang="sr">проглас оставе Веб програма</comment>
@@ -33480,6 +34465,7 @@
<mime-type type="text/x-google-video-pointer">
<comment>Google Video Pointer</comment>
<comment xml:lang="ar">مؤشر فيديو جوجل</comment>
+ <comment xml:lang="ast">Google Video Pointer</comment>
<comment xml:lang="be@latin">Pakazalnik Google Video</comment>
<comment xml:lang="bg">Документ-указател към видео на Google</comment>
<comment xml:lang="ca">apuntador a vídeo de Google</comment>
@@ -33539,7 +34525,7 @@
<comment xml:lang="be@latin">Kryničny kod Haskell</comment>
<comment xml:lang="bg">Изходен код на Haskell</comment>
<comment xml:lang="ca">codi font en Haskell</comment>
- <comment xml:lang="cs">zdrojový kód Haskell</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce Haskell</comment>
<comment xml:lang="cy">Ffynhonnell rhaglen Haskell</comment>
<comment xml:lang="da">Haskellkildekode</comment>
<comment xml:lang="de">Haskell-Quelltext</comment>
@@ -33554,10 +34540,10 @@
<comment xml:lang="ga">cód foinseach Haskell</comment>
<comment xml:lang="gl">código fonte de Haskell</comment>
<comment xml:lang="he">קוד מקור של Haskell</comment>
- <comment xml:lang="hr">Haskell izvorni kod</comment>
+ <comment xml:lang="hr">Haskell izvorni kôd</comment>
<comment xml:lang="hu">Haskell-forráskód</comment>
<comment xml:lang="ia">Codice-fonte Haskell</comment>
- <comment xml:lang="id">Kode program Haskell</comment>
+ <comment xml:lang="id">Kode sumber Haskell</comment>
<comment xml:lang="it">Codice sorgente Haskell</comment>
<comment xml:lang="ja">Haskell ソースコード</comment>
<comment xml:lang="kk">Haskell бастапқы коды</comment>
@@ -33573,7 +34559,7 @@
<comment xml:lang="pt">código origem Haskell</comment>
<comment xml:lang="pt_BR">Código-fonte Haskell</comment>
<comment xml:lang="ro">Cod sursă Haskell</comment>
- <comment xml:lang="ru">исходный код Haskell</comment>
+ <comment xml:lang="ru">Исходный код Haskell</comment>
<comment xml:lang="sk">Zdrojový kód Haskell</comment>
<comment xml:lang="sl">Datoteka izvorne kode Haskell</comment>
<comment xml:lang="sq">Kod burues Haskell</comment>
@@ -33590,6 +34576,7 @@
<mime-type type="text/x-idl">
<comment>IDL document</comment>
<comment xml:lang="ar">مستند IDL</comment>
+ <comment xml:lang="ast">Documentu IDL</comment>
<comment xml:lang="az">IDL sənədi</comment>
<comment xml:lang="be@latin">Dakument IDL</comment>
<comment xml:lang="bg">Документ — IDL</comment>
@@ -33628,7 +34615,7 @@
<comment xml:lang="pt">documento IDL</comment>
<comment xml:lang="pt_BR">Documento IDL</comment>
<comment xml:lang="ro">Document IDL</comment>
- <comment xml:lang="ru">документ IDL</comment>
+ <comment xml:lang="ru">Документ IDL</comment>
<comment xml:lang="sk">Dokument IDL</comment>
<comment xml:lang="sl">Dokument IDL</comment>
<comment xml:lang="sq">Dokument IDL</comment>
@@ -33647,6 +34634,7 @@
<mime-type type="text/x-install">
<comment>installation instructions</comment>
<comment xml:lang="ar">تعليمات التثبيت</comment>
+ <comment xml:lang="ast">instrucciones d'instalación</comment>
<comment xml:lang="be@latin">instrukcyja dla instalavańnia</comment>
<comment xml:lang="bg">Инструкции за инсталация</comment>
<comment xml:lang="ca">instruccions d'instal·lació</comment>
@@ -33663,7 +34651,7 @@
<comment xml:lang="ga">treoracha suiteála</comment>
<comment xml:lang="gl">instrucións de instalación</comment>
<comment xml:lang="he">הוראות התקנה</comment>
- <comment xml:lang="hr">upute za instalaciju</comment>
+ <comment xml:lang="hr">Upute za instalaciju</comment>
<comment xml:lang="hu">telepítési utasítások</comment>
<comment xml:lang="ia">Instructiones de installation</comment>
<comment xml:lang="id">instruksi instalasi</comment>
@@ -33681,7 +34669,7 @@
<comment xml:lang="pt">instruções de instalação</comment>
<comment xml:lang="pt_BR">Instruções de instalação</comment>
<comment xml:lang="ro">instrucțiuni de instalare</comment>
- <comment xml:lang="ru">инструкции по установке программы</comment>
+ <comment xml:lang="ru">Инструкции по установке</comment>
<comment xml:lang="sk">Návod na inštaláciu</comment>
<comment xml:lang="sl">navodila namestitve</comment>
<comment xml:lang="sq">Udhëzime instalimi</comment>
@@ -33701,7 +34689,7 @@
<comment xml:lang="be@latin">Kryničny kod Java</comment>
<comment xml:lang="bg">Изходен код на Java</comment>
<comment xml:lang="ca">codi font en Java</comment>
- <comment xml:lang="cs">zdrojový kód Java</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce Java</comment>
<comment xml:lang="da">Javakildekode</comment>
<comment xml:lang="de">Java-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας Java</comment>
@@ -33715,10 +34703,10 @@
<comment xml:lang="ga">cód foinseach Java</comment>
<comment xml:lang="gl">código fonte de Java</comment>
<comment xml:lang="he">קוד מקור ב־Java</comment>
- <comment xml:lang="hr">Java izvorni kod</comment>
+ <comment xml:lang="hr">Java izvorni kôd</comment>
<comment xml:lang="hu">Java-forráskód</comment>
<comment xml:lang="ia">Codice-fonte Java</comment>
- <comment xml:lang="id">Kode program Java</comment>
+ <comment xml:lang="id">Kode sumber Java</comment>
<comment xml:lang="it">Codice sorgente Java</comment>
<comment xml:lang="ja">Java ソースコード</comment>
<comment xml:lang="kk">Java бастапқы коды</comment>
@@ -33734,7 +34722,7 @@
<comment xml:lang="pt">código origem Java</comment>
<comment xml:lang="pt_BR">Código-fonte Java</comment>
<comment xml:lang="ro">Cod sursă Java</comment>
- <comment xml:lang="ru">исходный код Java</comment>
+ <comment xml:lang="ru">Исходный код Java</comment>
<comment xml:lang="sk">Zdrojový kód Java</comment>
<comment xml:lang="sl">Datoteka izvorne kode Java</comment>
<comment xml:lang="sq">Kod burues Java</comment>
@@ -33765,7 +34753,7 @@
<comment xml:lang="fi">LDIF-osoitekirja</comment>
<comment xml:lang="fo">LDIF adressubók</comment>
<comment xml:lang="fr">carnet d'adresses LDIF</comment>
- <comment xml:lang="ga">leabhar sheoltaí LDIF</comment>
+ <comment xml:lang="ga">leabhar seoltaí LDIF</comment>
<comment xml:lang="gl">lista de enderezos LDIF</comment>
<comment xml:lang="he">ספר כתובות של LDIF</comment>
<comment xml:lang="hr">LDIF adresar</comment>
@@ -33786,7 +34774,7 @@
<comment xml:lang="pt">livro de endereços LDIF</comment>
<comment xml:lang="pt_BR">Livro de endereços LDIF</comment>
<comment xml:lang="ro">Agendă LDIF</comment>
- <comment xml:lang="ru">адресная книга LDIF</comment>
+ <comment xml:lang="ru">Адресная книга LDIF</comment>
<comment xml:lang="sk">Adresár LDIF</comment>
<comment xml:lang="sl">Datoteka imenika naslovov LDIF</comment>
<comment xml:lang="sq">Rubrikë LDIF</comment>
@@ -33842,7 +34830,7 @@
<comment xml:lang="pt">folha de música Lilypond</comment>
<comment xml:lang="pt_BR">Partitura do Lilypond</comment>
<comment xml:lang="ro">Fișă muzică Lilypond</comment>
- <comment xml:lang="ru">список музыки Lilypond</comment>
+ <comment xml:lang="ru">Список музыки Lilypond</comment>
<comment xml:lang="sk">Notový papier Lilypond</comment>
<comment xml:lang="sl">Glasbena predloga Lilypond</comment>
<comment xml:lang="sq">Partiturë Lilypond</comment>
@@ -33876,10 +34864,10 @@
<comment xml:lang="ga">cód foinseach LHS</comment>
<comment xml:lang="gl">código fonte en LHS</comment>
<comment xml:lang="he">קוד מקור של LHS</comment>
- <comment xml:lang="hr">LHS izvorni kod</comment>
+ <comment xml:lang="hr">LHS izvorni kôd</comment>
<comment xml:lang="hu">LHS forráskód</comment>
<comment xml:lang="ia">Codice-fonte LHS</comment>
- <comment xml:lang="id">Kode program LHS</comment>
+ <comment xml:lang="id">Kode sumber LHS</comment>
<comment xml:lang="it">Codice sorgente LHS</comment>
<comment xml:lang="ja">LHS ソースコード</comment>
<comment xml:lang="kk">LHS бастапқы коды</comment>
@@ -33894,7 +34882,7 @@
<comment xml:lang="pt">código origem LHS</comment>
<comment xml:lang="pt_BR">Código-fonte LHS</comment>
<comment xml:lang="ro">Cod sursă LHS</comment>
- <comment xml:lang="ru">исходный код LHS</comment>
+ <comment xml:lang="ru">Исходный код LHS</comment>
<comment xml:lang="sk">Zdrojový kód LHS</comment>
<comment xml:lang="sl">Datoteka izvorne kode LHS</comment>
<comment xml:lang="sq">Kod burues LHS</comment>
@@ -33913,6 +34901,7 @@
<mime-type type="text/x-log">
<comment>application log</comment>
<comment xml:lang="ar">سجل التطبيق</comment>
+ <comment xml:lang="ast">rexistru d'aplicación</comment>
<comment xml:lang="be@latin">časopis aplikacyi</comment>
<comment xml:lang="bg">Файл-дневник на приложение</comment>
<comment xml:lang="ca">registre d'aplicació</comment>
@@ -33949,7 +34938,7 @@
<comment xml:lang="pt">diário de aplicação</comment>
<comment xml:lang="pt_BR">Registro de aplicativo</comment>
<comment xml:lang="ro">înregistrare aplicație</comment>
- <comment xml:lang="ru">журнал сообщений</comment>
+ <comment xml:lang="ru">Журнал сообщений</comment>
<comment xml:lang="sk">Záznam aplikácie</comment>
<comment xml:lang="sl">dnevnik programa</comment>
<comment xml:lang="sq">log i mesazheve të programit</comment>
@@ -34005,7 +34994,7 @@
<comment xml:lang="pt">Makefile</comment>
<comment xml:lang="pt_BR">Makefile (arquivo do make)</comment>
<comment xml:lang="ro">Makefile</comment>
- <comment xml:lang="ru">Makefile (файл сборки)</comment>
+ <comment xml:lang="ru">Файл Makefile</comment>
<comment xml:lang="sk">Makefile</comment>
<comment xml:lang="sl">Datoteka Makefile</comment>
<comment xml:lang="sq">Makefile</comment>
@@ -34029,6 +35018,7 @@
</mime-type>
<mime-type type="text/markdown">
<comment>Markdown document</comment>
+ <comment xml:lang="ast">Documentu Markdown</comment>
<comment xml:lang="bg">Документ — Markdown</comment>
<comment xml:lang="ca">document Markdown</comment>
<comment xml:lang="cs">dokument Markdown</comment>
@@ -34040,6 +35030,7 @@
<comment xml:lang="eu">Markdown dokumentua</comment>
<comment xml:lang="fi">Markdown-asiakirja</comment>
<comment xml:lang="fr">document Markdown</comment>
+ <comment xml:lang="ga">cáipéis Markdown</comment>
<comment xml:lang="gl">documento de Markdown</comment>
<comment xml:lang="he">מסמך Markdown</comment>
<comment xml:lang="hr">Markdown dokument</comment>
@@ -34056,7 +35047,7 @@
<comment xml:lang="pl">Dokument Markdown</comment>
<comment xml:lang="pt">documento Markdown</comment>
<comment xml:lang="pt_BR">Documento Markdown</comment>
- <comment xml:lang="ru">документ Markdown</comment>
+ <comment xml:lang="ru">Документ Markdown</comment>
<comment xml:lang="sk">Dokument Markdown</comment>
<comment xml:lang="sl">Dokument Markdown</comment>
<comment xml:lang="sr">Маркдаун документ</comment>
@@ -34108,7 +35099,7 @@
<comment xml:lang="pt">ficheiro Qt MOC</comment>
<comment xml:lang="pt_BR">Arquivo Qt MOC</comment>
<comment xml:lang="ro">Fișier Qt MOC</comment>
- <comment xml:lang="ru">файл Qt MOC</comment>
+ <comment xml:lang="ru">Файл Qt MOC</comment>
<comment xml:lang="sk">Súbor Qt MOC</comment>
<comment xml:lang="sl">Datoteka Qt MOC</comment>
<comment xml:lang="sq">File Qt MOC</comment>
@@ -34117,7 +35108,7 @@
<comment xml:lang="tr">Qt MOC dosyası</comment>
<comment xml:lang="uk">файл-метаоб'єкт Qt</comment>
<comment xml:lang="vi">Tập tin MOC của Qt</comment>
- <comment xml:lang="zh_CN">Qt 元对象编译文件</comment>
+ <comment xml:lang="zh_CN">Qt 元对象编译器文件</comment>
<comment xml:lang="zh_TW">Qt MOC 檔</comment>
<acronym>Qt MOC</acronym>
<expanded-acronym>Qt Meta Object Compiler</expanded-acronym>
@@ -34161,7 +35152,7 @@
<comment xml:lang="pt">extrato do registo do Windows</comment>
<comment xml:lang="pt_BR">Extrator de registro do Windows</comment>
<comment xml:lang="ro">Extras al registrului Windows</comment>
- <comment xml:lang="ru">фрагмент Windows Registry</comment>
+ <comment xml:lang="ru">Фрагмент Windows Registry</comment>
<comment xml:lang="sk">Časť registrov Windows</comment>
<comment xml:lang="sl">izvleček vpisnika Windows</comment>
<comment xml:lang="sq">Pjesë Windows Registry</comment>
@@ -34170,7 +35161,7 @@
<comment xml:lang="tr">Windows Kayıt Defteri özü</comment>
<comment xml:lang="uk">частина реєстру Windows</comment>
<comment xml:lang="vi">Bản trích Registry Windows</comment>
- <comment xml:lang="zh_CN">Windows 注册表文件</comment>
+ <comment xml:lang="zh_CN">Windows 注册表提取</comment>
<comment xml:lang="zh_TW">Windows Registry 抽出</comment>
<sub-class-of type="text/plain"/>
<magic priority="50">
@@ -34216,7 +35207,7 @@
<comment xml:lang="pt">formato Managed Object</comment>
<comment xml:lang="pt_BR">Formato de objeto gerenciado</comment>
<comment xml:lang="ro">Managed Object Format</comment>
- <comment xml:lang="ru">формат управляемого объекта</comment>
+ <comment xml:lang="ru">Формат управляемого объекта</comment>
<comment xml:lang="sk">Formát Managed Object</comment>
<comment xml:lang="sl">Datoteka Managed Object</comment>
<comment xml:lang="sq">Managed Object Format</comment>
@@ -34267,7 +35258,7 @@
<comment xml:lang="pt">publicação Mup</comment>
<comment xml:lang="pt_BR">Publicação do Mup</comment>
<comment xml:lang="ro">Publicație Mup</comment>
- <comment xml:lang="ru">публикация Mup</comment>
+ <comment xml:lang="ru">Публикация Mup</comment>
<comment xml:lang="sk">Publikácie Mup</comment>
<comment xml:lang="sl">Datoteka objave Mup</comment>
<comment xml:lang="sq">Publikim Mup</comment>
@@ -34291,7 +35282,7 @@
<comment xml:lang="be@latin">Kryničny kod Objective-C</comment>
<comment xml:lang="bg">Изходен код — Objective C</comment>
<comment xml:lang="ca">codi font en Objective-C</comment>
- <comment xml:lang="cs">zdrojový kód Objective-C</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce Objective-C</comment>
<comment xml:lang="da">Objektiv C-kildekode</comment>
<comment xml:lang="de">Objective-C-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας Objective-C</comment>
@@ -34308,7 +35299,7 @@
<comment xml:lang="hr">Objective-C izvorni kôd</comment>
<comment xml:lang="hu">Objective-C forráskód</comment>
<comment xml:lang="ia">Codice-fonte Objective-C</comment>
- <comment xml:lang="id">Kode program Objective-C</comment>
+ <comment xml:lang="id">Kode sumber Objective-C</comment>
<comment xml:lang="it">Codice sorgente Objective-C</comment>
<comment xml:lang="ja">Objective-C ソースコード</comment>
<comment xml:lang="ka">Objective-C-ის საწყისი კოდი</comment>
@@ -34325,7 +35316,7 @@
<comment xml:lang="pt">código origem Objective-C</comment>
<comment xml:lang="pt_BR">Código-fonte Objective-C</comment>
<comment xml:lang="ro">Cod sursă Objective-C</comment>
- <comment xml:lang="ru">исходный код Objective-C</comment>
+ <comment xml:lang="ru">Исходный код Objective-C</comment>
<comment xml:lang="sk">Zdrojový kód Objective-C</comment>
<comment xml:lang="sl">Datoteka izvorne kode Objective-C</comment>
<comment xml:lang="sq">Kod burues C objekt</comment>
@@ -34348,7 +35339,7 @@
<comment xml:lang="be@latin">Kryničny kod OCaml</comment>
<comment xml:lang="bg">Изходен код — OCaml</comment>
<comment xml:lang="ca">codi font en OCaml</comment>
- <comment xml:lang="cs">zdrojový kód OCaml</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce OCaml</comment>
<comment xml:lang="da">OCaml-kildekode</comment>
<comment xml:lang="de">OCaml-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας OCaml</comment>
@@ -34362,10 +35353,10 @@
<comment xml:lang="ga">cód foinseach OCaml</comment>
<comment xml:lang="gl">código fonte de OCaml</comment>
<comment xml:lang="he">קוד מקור של OCaml</comment>
- <comment xml:lang="hr">OCaml izvorni kod</comment>
+ <comment xml:lang="hr">OCaml izvorni kôd</comment>
<comment xml:lang="hu">OCaml forráskód</comment>
<comment xml:lang="ia">Codice-fonte OCaml</comment>
- <comment xml:lang="id">Kode program OCaml</comment>
+ <comment xml:lang="id">Kode sumber OCaml</comment>
<comment xml:lang="it">Codice sorgente OCaml</comment>
<comment xml:lang="ja">OCaml ソースコード</comment>
<comment xml:lang="kk">OCaml бастапқы коды</comment>
@@ -34380,7 +35371,7 @@
<comment xml:lang="pt">código origem OCaml</comment>
<comment xml:lang="pt_BR">Código-fonte OCaml</comment>
<comment xml:lang="ro">Cod sursă OCaml</comment>
- <comment xml:lang="ru">исходный код OCaml</comment>
+ <comment xml:lang="ru">Исходный код OCaml</comment>
<comment xml:lang="sk">Zdrojový kód OCaml</comment>
<comment xml:lang="sl">Datoteka izvorne kode OCaml</comment>
<comment xml:lang="sq">Kod burues OCaml</comment>
@@ -34394,6 +35385,33 @@
<glob pattern="*.ml"/>
<glob pattern="*.mli"/>
</mime-type>
+ <mime-type type="text/x-opencl-src">
+ <comment>OpenCL source code</comment>
+ <comment xml:lang="ca">codi font en OpenCL</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce OpenCL</comment>
+ <comment xml:lang="de">OpenCL-Quelltext</comment>
+ <comment xml:lang="en_GB">OpenCL source code</comment>
+ <comment xml:lang="es">código fuente en OpenCL</comment>
+ <comment xml:lang="fi">OpenCL-lähdekoodi</comment>
+ <comment xml:lang="hr">OpenCL izvorni kôd</comment>
+ <comment xml:lang="hu">OpenCL forráskód</comment>
+ <comment xml:lang="id">Kode sumber OpenCL</comment>
+ <comment xml:lang="it">Codice sorgente OpenCL</comment>
+ <comment xml:lang="kk">OpenCL бастапқы коды</comment>
+ <comment xml:lang="ko">OpenCL 소스 코드</comment>
+ <comment xml:lang="pl">Kod źródłowy OpenCL</comment>
+ <comment xml:lang="pt_BR">Código-fonte do OpenCL</comment>
+ <comment xml:lang="ru">Исходный код OpenGL</comment>
+ <comment xml:lang="sk">Zdrojový kód OpenCL</comment>
+ <comment xml:lang="sv">OpenCL-källkod</comment>
+ <comment xml:lang="uk">вихідний код мовою OpenCL</comment>
+ <comment xml:lang="zh_CN">OpenCL 源代码</comment>
+ <comment xml:lang="zh_TW">OpenCL 源碼</comment>
+ <acronym>OpenCL</acronym>
+ <expanded-acronym>Open Computing Language</expanded-acronym>
+ <sub-class-of type="text/x-csrc"/>
+ <glob pattern="*.cl"/>
+ </mime-type>
<mime-type type="text/x-matlab">
<comment>MATLAB script/function</comment>
<comment xml:lang="ar">سكربت/وظيفة MATLAB</comment>
@@ -34431,7 +35449,7 @@
<comment xml:lang="pt">script/função MATLAB</comment>
<comment xml:lang="pt_BR">Script/função do MATLAB</comment>
<comment xml:lang="ro">Funcție/script MATLAB</comment>
- <comment xml:lang="ru">сценарий/функция MATLAB</comment>
+ <comment xml:lang="ru">Сценарий/функция MATLAB</comment>
<comment xml:lang="sk">Skript/funkcia MATLAB</comment>
<comment xml:lang="sl">Skriptna datoteka MATLAB</comment>
<comment xml:lang="sq">Script/Funksion MATLAB</comment>
@@ -34467,11 +35485,12 @@
<comment xml:lang="eu">Meson iturburu-kodea</comment>
<comment xml:lang="fi">Meson-lähdekoodi</comment>
<comment xml:lang="fr">code source Meson</comment>
+ <comment xml:lang="ga">cód foinseach Meson</comment>
<comment xml:lang="he">קוד מקור Meson</comment>
<comment xml:lang="hr">Meson izvorni kôd</comment>
<comment xml:lang="hu">Meson forráskód</comment>
<comment xml:lang="ia">Codice-fonte Meson</comment>
- <comment xml:lang="id">Kode program Meson</comment>
+ <comment xml:lang="id">Kode sumber Meson</comment>
<comment xml:lang="it">Codice sorgente Meson</comment>
<comment xml:lang="kk">Meson бастапқы коды</comment>
<comment xml:lang="ko">Meson 소스 코드</comment>
@@ -34479,7 +35498,7 @@
<comment xml:lang="pl">Kod źródłowy Meson</comment>
<comment xml:lang="pt">código origem Meson</comment>
<comment xml:lang="pt_BR">Código-fonte Meson</comment>
- <comment xml:lang="ru">исходный код Meson</comment>
+ <comment xml:lang="ru">Исходный код Meson</comment>
<comment xml:lang="sk">Zdrojový kód Meson</comment>
<comment xml:lang="sr">Месон изворни ко̂д</comment>
<comment xml:lang="sv">Meson-källkod</comment>
@@ -34503,6 +35522,7 @@
<comment xml:lang="eu">Modelica modeloa</comment>
<comment xml:lang="fi">Modelica-malli</comment>
<comment xml:lang="fr">modèle Modelica</comment>
+ <comment xml:lang="ga">samhail Modelica</comment>
<comment xml:lang="gl">Modelo de Modelica</comment>
<comment xml:lang="he">דגם של Modelica</comment>
<comment xml:lang="hr">Modelica model</comment>
@@ -34518,7 +35538,7 @@
<comment xml:lang="pl">Model Modelica</comment>
<comment xml:lang="pt">modelo Modelica</comment>
<comment xml:lang="pt_BR">Modelo da Modelica</comment>
- <comment xml:lang="ru">модель Modelica</comment>
+ <comment xml:lang="ru">Модель Modelica</comment>
<comment xml:lang="sk">Model Modelica</comment>
<comment xml:lang="sl">Model Modelica</comment>
<comment xml:lang="sr">модел Моделике</comment>
@@ -34551,7 +35571,7 @@
<comment xml:lang="be@latin">Kryničny kod Pascal</comment>
<comment xml:lang="bg">Изходен код — Pascal</comment>
<comment xml:lang="ca">codi font en Pascal</comment>
- <comment xml:lang="cs">zdrojový kód Pascal</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce Pascal</comment>
<comment xml:lang="da">Pascalkildekode</comment>
<comment xml:lang="de">Pascal-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας Pascal</comment>
@@ -34568,7 +35588,7 @@
<comment xml:lang="hr">Pascal izvorni kôd</comment>
<comment xml:lang="hu">Pascal-forráskód</comment>
<comment xml:lang="ia">Codice-fonte Pascal</comment>
- <comment xml:lang="id">Kode program Pascal</comment>
+ <comment xml:lang="id">Kode sumber Pascal</comment>
<comment xml:lang="it">Codice sorgente Pascal</comment>
<comment xml:lang="ja">Pascal ソースコード</comment>
<comment xml:lang="kk">Pascal бастапқы коды</comment>
@@ -34584,7 +35604,7 @@
<comment xml:lang="pt">código origem Pascal</comment>
<comment xml:lang="pt_BR">Código-fonte Pascal</comment>
<comment xml:lang="ro">Cod sursă Pascal</comment>
- <comment xml:lang="ru">исходный код Pascal</comment>
+ <comment xml:lang="ru">Исходный код Pascal</comment>
<comment xml:lang="sk">Zdrojový kód Pascal</comment>
<comment xml:lang="sl">Datoteka izvorne kode Pascal</comment>
<comment xml:lang="sq">Kod burues Pascal</comment>
@@ -34619,7 +35639,7 @@
<comment xml:lang="ga">difríochtaí idir chomhaid</comment>
<comment xml:lang="gl">diferenzas entre ficheiros</comment>
<comment xml:lang="he">הבדל בין קבצים</comment>
- <comment xml:lang="hr">razlike između datoteka</comment>
+ <comment xml:lang="hr">Razlike između datoteka</comment>
<comment xml:lang="hu">diff-különbségfájl</comment>
<comment xml:lang="ia">Differentias inter files</comment>
<comment xml:lang="id">perbedaan diantara berkas</comment>
@@ -34638,7 +35658,7 @@
<comment xml:lang="pt">diferenças entre ficheiros</comment>
<comment xml:lang="pt_BR">Diferenças entre arquivos</comment>
<comment xml:lang="ro">diferențe între fișiere</comment>
- <comment xml:lang="ru">различия между файлами</comment>
+ <comment xml:lang="ru">Различия между файлами</comment>
<comment xml:lang="sk">Rozdiely medzi súbormi</comment>
<comment xml:lang="sl">razlike med datotekami</comment>
<comment xml:lang="sq">Diferencë midis file</comment>
@@ -34670,7 +35690,7 @@
<comment>Go source code</comment>
<comment xml:lang="bg">Изходен код — Go</comment>
<comment xml:lang="ca">codi font en Go</comment>
- <comment xml:lang="cs">zdrojový kód Go</comment>
+ <comment xml:lang="cs">zdrojový kód v jazyce Go</comment>
<comment xml:lang="da">Go-kildekode</comment>
<comment xml:lang="de">Go-Quelltext</comment>
<comment xml:lang="el">Πηγαίος κώδικας Go</comment>
@@ -34680,9 +35700,10 @@
<comment xml:lang="eu">Go iturburu-kodea</comment>
<comment xml:lang="fi">Go-lähdekoodi</comment>
<comment xml:lang="fr">code source Go</comment>
+ <comment xml:lang="ga">cód foinseach Go</comment>
<comment xml:lang="gl">código fonte de Go</comment>
<comment xml:lang="he">קוד מקור של Go</comment>
- <comment xml:lang="hr">Go izvorni kod</comment>
+ <comment xml:lang="hr">Go izvorni kôd</comment>
<comment xml:lang="hu">Go forráskód</comment>
<comment xml:lang="ia">Codice-fonte Go</comment>
<comment xml:lang="id">Kode sumber Go</comment>
@@ -34697,14 +35718,14 @@
<comment xml:lang="pl">Kod źródłowy Go</comment>
<comment xml:lang="pt">cigo origem Go</comment>
<comment xml:lang="pt_BR">Código-fonte Go</comment>
- <comment xml:lang="ru">исходный код Go</comment>
+ <comment xml:lang="ru">Исходный код Go</comment>
<comment xml:lang="sk">Zdrojový kód Go</comment>
<comment xml:lang="sl">Izvorna koda Go</comment>
<comment xml:lang="sr">Гоу изворни ко̂д</comment>
<comment xml:lang="sv">Go-källkod</comment>
<comment xml:lang="tr">Go kaynak kodu</comment>
<comment xml:lang="uk">вихідний код мовою Go</comment>
- <comment xml:lang="zh_CN">Go </comment>
+ <comment xml:lang="zh_CN">Go 源代码</comment>
<comment xml:lang="zh_TW">Go 源碼</comment>
<sub-class-of type="text/plain"/>
<glob pattern="*.go"/>
@@ -34721,6 +35742,7 @@
<comment xml:lang="eu">SCons konfigurazio-fitxategia</comment>
<comment xml:lang="fi">SCons-asetustiedosto</comment>
<comment xml:lang="fr">fichier de configuration SCons</comment>
+ <comment xml:lang="ga">comhad cumraíochta SCons</comment>
<comment xml:lang="he">קובץ תצורה של SCons</comment>
<comment xml:lang="hr">SCons datoteka podešavanja</comment>
<comment xml:lang="hu">SCons beállítófájl</comment>
@@ -34733,7 +35755,7 @@
<comment xml:lang="pl">Plik konfiguracji SCons</comment>
<comment xml:lang="pt">ficheiro de configuração SCons</comment>
<comment xml:lang="pt_BR">Arquivo de configuração do SCons</comment>
- <comment xml:lang="ru">файл настроек SCons</comment>
+ <comment xml:lang="ru">Файл настроек SCons</comment>
<comment xml:lang="sk">Konfiguračný súbor SCons</comment>
<comment xml:lang="sl">Prilagoditvena datoteka SCons</comment>
<comment xml:lang="sr">СКонс датотека подешавања</comment>
@@ -34747,13 +35769,52 @@
<glob pattern="SConscript"/>
<glob pattern="SConscript.*"/>
</mime-type>
+ <mime-type type="text/x-python3">
+ <comment>Python 3 script</comment>
+ <comment xml:lang="ca">script Python 3</comment>
+ <comment xml:lang="cs">skript v jazyce Python 3</comment>
+ <comment xml:lang="de">Python-3-Skript</comment>
+ <comment xml:lang="en_GB">Python 3 script</comment>
+ <comment xml:lang="es">secuencia de órdenes en Python 3</comment>
+ <comment xml:lang="fi">Python 3 -skripti</comment>
+ <comment xml:lang="hr">Python3 skripta</comment>
+ <comment xml:lang="hu">Python 3 parancsfájl</comment>
+ <comment xml:lang="id">Skrip Python 3</comment>
+ <comment xml:lang="it">Script Python 3</comment>
+ <comment xml:lang="kk">Python 3 скрипті</comment>
+ <comment xml:lang="ko">파이썬 3 스크립트</comment>
+ <comment xml:lang="pl">Skrypt Python 3</comment>
+ <comment xml:lang="pt_BR">Script Python 3</comment>
+ <comment xml:lang="ru">Сценарий Python 3</comment>
+ <comment xml:lang="sk">Skript Python 3</comment>
+ <comment xml:lang="sv">Python 3-skript</comment>
+ <comment xml:lang="uk">скрипт мовою Python 3</comment>
+ <comment xml:lang="zh_CN">Python 3 脚本</comment>
+ <comment xml:lang="zh_TW">Python 3 指令稿</comment>
+ <sub-class-of type='text/x-python'/>
+ <magic priority="60">
+ <match value="#!/bin/python3" type="string" offset="0"/>
+ <match value="#! /bin/python3" type="string" offset="0"/>
+ <match value='eval \"exec /bin/python3' type="string" offset="0"/>
+ <match value="#!/usr/bin/python3" type="string" offset="0"/>
+ <match value="#! /usr/bin/python3" type="string" offset="0"/>
+ <match value='eval \"exec /usr/bin/python3' type="string" offset="0"/>
+ <match value="#!/usr/local/bin/python3" type="string" offset="0"/>
+ <match value="#! /usr/local/bin/python3" type="string" offset="0"/>
+ <match value='eval \"exec /usr/local/bin/python3' type="string" offset="0"/>
+ <match value='/bin/env python3' type="string" offset="2:16"/>
+ </magic>
+ <glob weight="50" pattern="*.py"/>
+ <glob weight="60" pattern="*.py3"/>
+ <glob weight="60" pattern="*.py3x"/>
+ </mime-type>
<mime-type type="text/x-python">
<comment>Python script</comment>
<comment xml:lang="ar">سكربت بايثون</comment>
<comment xml:lang="be@latin">Skrypt Python</comment>
<comment xml:lang="bg">Скрипт — Python</comment>
<comment xml:lang="ca">script Python</comment>
- <comment xml:lang="cs">skript Python</comment>
+ <comment xml:lang="cs">skript v jazyce Python</comment>
<comment xml:lang="da">Pythonprogram</comment>
<comment xml:lang="de">Python-Skript</comment>
<comment xml:lang="el">Δέσμη ενεργειών Python</comment>
@@ -34786,7 +35847,7 @@
<comment xml:lang="pt">script Python</comment>
<comment xml:lang="pt_BR">Script Python</comment>
<comment xml:lang="ro">Script Python</comment>
- <comment xml:lang="ru">сценарий Python</comment>
+ <comment xml:lang="ru">Сценарий Python</comment>
<comment xml:lang="sk">Skript Python</comment>
<comment xml:lang="sl">Skriptna datoteka Python</comment>
<comment xml:lang="sq">Script Python</comment>
@@ -34811,9 +35872,9 @@
<match value='eval \"exec /usr/local/bin/python' type="string" offset="0"/>
<match value='/bin/env python' type="string" offset="2:16"/>
</magic>
- <glob pattern="*.py"/>
- <glob pattern="*.pyx"/>
- <glob pattern="*.wsgi"/>
+ <glob weight="60" pattern="*.py"/>
+ <glob weight="60" pattern="*.pyx"/>
+ <glob weight="60" pattern="*.wsgi"/>
</mime-type>
<mime-type type="text/x-lua">
<comment>Lua script</comment>
@@ -34821,7 +35882,7 @@
<comment xml:lang="be@latin">Skrypt Lua</comment>
<comment xml:lang="bg">Скрипт на Lua</comment>
<comment xml:lang="ca">script Lua</comment>
- <comment xml:lang="cs">skript Lua</comment>
+ <comment xml:lang="cs">skript v jazyce Lua</comment>
<comment xml:lang="da">Luaprogram</comment>
<comment xml:lang="de">Lua-Skript</comment>
<comment xml:lang="el">Δέσμη ενεργειών Lua</comment>
@@ -34853,7 +35914,7 @@
<comment xml:lang="pt">script Lua</comment>
<comment xml:lang="pt_BR">Script Lua</comment>
<comment xml:lang="ro">Script Lua</comment>
- <comment xml:lang="ru">сценарий Lua</comment>
+ <comment xml:lang="ru">Сценарий Lua</comment>
<comment xml:lang="sk">Skript Lua</comment>
<comment xml:lang="sl">Skriptna datoteka Lua</comment>
<comment xml:lang="sq">Script Lua</comment>
@@ -34877,6 +35938,7 @@
<mime-type type="text/x-readme">
<comment>README document</comment>
<comment xml:lang="ar">مستند README</comment>
+ <comment xml:lang="ast">Documentu LLEIME</comment>
<comment xml:lang="az">README sənədi</comment>
<comment xml:lang="be@latin">Dakument README</comment>
<comment xml:lang="bg">Документ — „Да се прочете“</comment>
@@ -34915,7 +35977,7 @@
<comment xml:lang="pt">documento LEIA-ME</comment>
<comment xml:lang="pt_BR">Documento README</comment>
<comment xml:lang="ro">Document README</comment>
- <comment xml:lang="ru">документ README</comment>
+ <comment xml:lang="ru">Документ README</comment>
<comment xml:lang="sk">Dokument README</comment>
<comment xml:lang="sl">Dokument README</comment>
<comment xml:lang="sq">Dokument README</comment>
@@ -34932,6 +35994,7 @@
<mime-type type="text/x-nfo">
<comment>NFO document</comment>
<comment xml:lang="ar">مستند NFO</comment>
+ <comment xml:lang="ast">Documentu NFO</comment>
<comment xml:lang="be@latin">Dakument NFO</comment>
<comment xml:lang="bg">Документ — NFO</comment>
<comment xml:lang="ca">document NFO</comment>
@@ -34967,7 +36030,7 @@
<comment xml:lang="pt">documento NFO</comment>
<comment xml:lang="pt_BR">Documento NFO</comment>
<comment xml:lang="ro">Document NFO</comment>
- <comment xml:lang="ru">документ NFO</comment>
+ <comment xml:lang="ru">Документ NFO</comment>
<comment xml:lang="sk">Dokument NFO</comment>
<comment xml:lang="sl">Dokument NFO</comment>
<comment xml:lang="sq">Dokument NFO</comment>
@@ -35018,7 +36081,7 @@
<comment xml:lang="pt">ficheiro de especificações RPM</comment>
<comment xml:lang="pt_BR">Arquivo de especificação RPM</comment>
<comment xml:lang="ro">Fișier RPM spec</comment>
- <comment xml:lang="ru">файл описания RPM</comment>
+ <comment xml:lang="ru">Файл описания RPM</comment>
<comment xml:lang="sk">Súbor RPM spec</comment>
<comment xml:lang="sl">Določilna datoteka RPM</comment>
<comment xml:lang="sq">File specifikimi RPM</comment>
@@ -35041,18 +36104,27 @@
<mime-type type="text/x-sass">
<comment>Sass CSS pre-processor file</comment>
<comment xml:lang="ca">fitxer preprocessador CSS Sass</comment>
+ <comment xml:lang="cs">soubor preprocesoru Sass CSS</comment>
<comment xml:lang="da">Sass CSS-forbrænderfil</comment>
<comment xml:lang="de">Sass-CSS-Präprozessordatei</comment>
+ <comment xml:lang="en_GB">Sass CSS pre-processor file</comment>
<comment xml:lang="es">archivo de preprocesador de CSS Sass</comment>
<comment xml:lang="fr">fichier de prétraitement CSS Sass</comment>
+ <comment xml:lang="ga">comhad réamhphróiseálaí CSS Sass</comment>
<comment xml:lang="he">קובץ קדם עיבוד Sass CSS</comment>
+ <comment xml:lang="hr">Sass CSS datoteka predobrade</comment>
<comment xml:lang="hu">Sass CSS előfeldolgozó fájl</comment>
+ <comment xml:lang="id">berkas pre-processor Sass CSS</comment>
+ <comment xml:lang="it">File CSS Sass</comment>
<comment xml:lang="kk">Sass CSS препроцессор файлы</comment>
<comment xml:lang="ko">Sass CSS 전처리기 파일</comment>
<comment xml:lang="pl">Plik preprocesora CSS Sass</comment>
<comment xml:lang="pt_BR">Arquivo de pré-processamento Sass CSS</comment>
- <comment xml:lang="ru">файл препроцессора Sass CSS</comment>
+ <comment xml:lang="ru">Файл препроцессора Sass CSS</comment>
<comment xml:lang="sk">Súbor Sass CSS pre-procesora</comment>
+ <comment xml:lang="sr">датотека Сас ЦСС пре-процесора</comment>
+ <comment xml:lang="sv">Sass CSS-preprocessorfil</comment>
+ <comment xml:lang="tr">Sass CSS önişlemci dosyası</comment>
<comment xml:lang="uk">файл препроцесора CSS Sass</comment>
<comment xml:lang="zh_CN">Sass CSS 预处理器文件</comment>
<comment xml:lang="zh_TW">Sass CSS 處理器前檔案</comment>
@@ -35073,9 +36145,10 @@
<comment xml:lang="eu">Scala iturburu-kodea</comment>
<comment xml:lang="fi">Scala-lähdekoodi</comment>
<comment xml:lang="fr">code source Scala</comment>
+ <comment xml:lang="ga">cód foinseach Scala</comment>
<comment xml:lang="gl">código fnote en Scala</comment>
<comment xml:lang="he">קוד מקור של Scala</comment>
- <comment xml:lang="hr">Scala izvorni kod</comment>
+ <comment xml:lang="hr">Scala izvorni kôd</comment>
<comment xml:lang="hu">Scala forráskód</comment>
<comment xml:lang="ia">Codice-fonte Scala</comment>
<comment xml:lang="id">Kode sumber Scala</comment>
@@ -35090,7 +36163,7 @@
<comment xml:lang="pl">Kod źródłowy Scala</comment>
<comment xml:lang="pt">código origem Scala</comment>
<comment xml:lang="pt_BR">Código-fonte Scala</comment>
- <comment xml:lang="ru">исходный код Scala</comment>
+ <comment xml:lang="ru">Исходный код Scala</comment>
<comment xml:lang="sk">Zdrojový kód Scala</comment>
<comment xml:lang="sl">Izvorna koda Scala</comment>
<comment xml:lang="sr">Скала изворни ко̂д</comment>
@@ -35124,7 +36197,7 @@
<comment xml:lang="ga">cód foinseach Scheme</comment>
<comment xml:lang="gl">código fonte en Scheme</comment>
<comment xml:lang="he">קוד מקור של Scheme</comment>
- <comment xml:lang="hr">Scheme izvorni kod</comment>
+ <comment xml:lang="hr">Scheme izvorni kôd</comment>
<comment xml:lang="hu">Scheme-forráskód</comment>
<comment xml:lang="ia">Codice-fonte Scheme</comment>
<comment xml:lang="id">Kode program Scheme</comment>
@@ -35143,7 +36216,7 @@
<comment xml:lang="pt">código origem Scheme</comment>
<comment xml:lang="pt_BR">Código-fonte Scheme</comment>
<comment xml:lang="ro">Cod sursă Scheme</comment>
- <comment xml:lang="ru">исходный код Scheme</comment>
+ <comment xml:lang="ru">Исходный код Scheme</comment>
<comment xml:lang="sk">Zdrojový kód Scheme</comment>
<comment xml:lang="sl">Datoteka izvorne kode Scheme</comment>
<comment xml:lang="sq">Kod burues Scheme</comment>
@@ -35161,18 +36234,27 @@
<mime-type type="text/x-scss">
<comment>Sass CSS pre-processor file</comment>
<comment xml:lang="ca">fitxer preprocessador CSS Sass</comment>
+ <comment xml:lang="cs">soubor preprocesoru Sass CSS</comment>
<comment xml:lang="da">Sass CSS-forbrænderfil</comment>
<comment xml:lang="de">Sass-CSS-Präprozessordatei</comment>
+ <comment xml:lang="en_GB">Sass CSS pre-processor file</comment>
<comment xml:lang="es">archivo de preprocesador de CSS Sass</comment>
<comment xml:lang="fr">fichier de prétraitement CSS Sass</comment>
+ <comment xml:lang="ga">comhad réamhphróiseálaí CSS Sass</comment>
<comment xml:lang="he">קובץ קדם עיבוד Sass CSS</comment>
+ <comment xml:lang="hr">Sass CSS datoteka predobrade</comment>
<comment xml:lang="hu">Sass CSS előfeldolgozó fájl</comment>
+ <comment xml:lang="id">berkas pre-processor Sass CSS</comment>
+ <comment xml:lang="it">File CSS Sass</comment>
<comment xml:lang="kk">Sass CSS препроцессор файлы</comment>
<comment xml:lang="ko">Sass CSS 전처리기 파일</comment>
<comment xml:lang="pl">Plik preprocesora CSS Sass</comment>
<comment xml:lang="pt_BR">Arquivo de pré-processamento Sass CSS</comment>
- <comment xml:lang="ru">файл препроцессора Sass CSS</comment>
+ <comment xml:lang="ru">Файл препроцессора Sass CSS</comment>
<comment xml:lang="sk">Súbor Sass CSS pre-procesora</comment>
+ <comment xml:lang="sr">датотека Сас ЦСС пре-процесора</comment>
+ <comment xml:lang="sv">Sass CSS-preprocessorfil</comment>
+ <comment xml:lang="tr">Sass CSS önişlemci dosyası</comment>
<comment xml:lang="uk">файл препроцесора CSS Sass</comment>
<comment xml:lang="zh_CN">Sass CSS 预处理器文件</comment>
<comment xml:lang="zh_TW">Sass CSS 處理器前檔案</comment>
@@ -35183,6 +36265,7 @@
<mime-type type="text/x-setext">
<comment>Setext document</comment>
<comment xml:lang="ar">مستند Setext</comment>
+ <comment xml:lang="ast">Documentu Setext</comment>
<comment xml:lang="az">Setext sənədi</comment>
<comment xml:lang="be@latin">Dakument Setext</comment>
<comment xml:lang="bg">Документ — Setext</comment>
@@ -35221,7 +36304,7 @@
<comment xml:lang="pt">documento Setext</comment>
<comment xml:lang="pt_BR">Documento Setext</comment>
<comment xml:lang="ro">Document Setext</comment>
- <comment xml:lang="ru">документ Setext</comment>
+ <comment xml:lang="ru">Документ Setext</comment>
<comment xml:lang="sk">Dokument Setext</comment>
<comment xml:lang="sl">Dokument Setext</comment>
<comment xml:lang="sq">Dokument Setext</comment>
@@ -35257,7 +36340,7 @@
<comment xml:lang="ga">cód SQL</comment>
<comment xml:lang="gl">código SQL</comment>
<comment xml:lang="he">קוד SQL</comment>
- <comment xml:lang="hr">SQL kod</comment>
+ <comment xml:lang="hr">SQL kôd</comment>
<comment xml:lang="hu">SQL-kód</comment>
<comment xml:lang="ia">Codice SQL</comment>
<comment xml:lang="id">Kode SQL</comment>
@@ -35276,7 +36359,7 @@
<comment xml:lang="pt">código SQL</comment>
<comment xml:lang="pt_BR">Código SQL</comment>
<comment xml:lang="ro">Cod SQL</comment>
- <comment xml:lang="ru">код SQL</comment>
+ <comment xml:lang="ru">Код SQL</comment>
<comment xml:lang="sk">Kód SQL</comment>
<comment xml:lang="sl">Datoteka kode SQL</comment>
<comment xml:lang="sq">Kod SQL</comment>
@@ -35330,7 +36413,7 @@
<comment xml:lang="pt">script Tcl</comment>
<comment xml:lang="pt_BR">Script Tcl</comment>
<comment xml:lang="ro">Script Tcl</comment>
- <comment xml:lang="ru">сценарий Tcl</comment>
+ <comment xml:lang="ru">Сценарий Tcl</comment>
<comment xml:lang="sk">Skript Tcl</comment>
<comment xml:lang="sl">Skriptna datoteka Tcl</comment>
<comment xml:lang="sq">Script Tcl</comment>
@@ -35348,6 +36431,7 @@
<mime-type type="text/x-tex">
<comment>TeX document</comment>
<comment xml:lang="ar">مستند TeX</comment>
+ <comment xml:lang="ast">Documentu TeX</comment>
<comment xml:lang="be@latin">Dakument TeX</comment>
<comment xml:lang="bg">Документ — TeX</comment>
<comment xml:lang="ca">document TeX</comment>
@@ -35385,7 +36469,7 @@
<comment xml:lang="pt">documento TeX</comment>
<comment xml:lang="pt_BR">Documento TeX</comment>
<comment xml:lang="ro">Document TeX</comment>
- <comment xml:lang="ru">документ TeX</comment>
+ <comment xml:lang="ru">Документ TeX</comment>
<comment xml:lang="sk">Dokument TeX</comment>
<comment xml:lang="sl">Dokument TeX</comment>
<comment xml:lang="sq">Dokument TeX</comment>
@@ -35415,6 +36499,7 @@
<mime-type type="text/x-texinfo">
<comment>TeXInfo document</comment>
<comment xml:lang="ar">مستند TeXInfo</comment>
+ <comment xml:lang="ast">Documentu TeXInfo</comment>
<comment xml:lang="az">TeXInfo sənədi</comment>
<comment xml:lang="be@latin">Dakument TeXInfo</comment>
<comment xml:lang="bg">Документ — TeXInfo</comment>
@@ -35453,7 +36538,7 @@
<comment xml:lang="pt">documento TeXInfo</comment>
<comment xml:lang="pt_BR">Documento TeXInfo</comment>
<comment xml:lang="ro">Document TexInfo</comment>
- <comment xml:lang="ru">документ TeXInfo</comment>
+ <comment xml:lang="ru">Документ TeXInfo</comment>
<comment xml:lang="sk">Dokument TeXInfo</comment>
<comment xml:lang="sl">Dokument TeXInfo</comment>
<comment xml:lang="sq">Dokument TeXInfo</comment>
@@ -35471,6 +36556,7 @@
<mime-type type="text/x-troff-me">
<comment>Troff ME input document</comment>
<comment xml:lang="ar">مستند Troff ME input</comment>
+ <comment xml:lang="ast">Documentu d'entrada de Troff ME</comment>
<comment xml:lang="be@latin">Uvodny dakument Troff ME</comment>
<comment xml:lang="bg">Изходен документ — Troff ME</comment>
<comment xml:lang="ca">document d'entrada Troff ME</comment>
@@ -35485,7 +36571,7 @@
<comment xml:lang="fi">Troff ME -syöteasiakirja</comment>
<comment xml:lang="fo">Troff ME inntaksskjal</comment>
<comment xml:lang="fr">document d'entrée Troff ME</comment>
- <comment xml:lang="ga">cáipéis ionchur Troff ME</comment>
+ <comment xml:lang="ga">cáipéis ionchurtha Troff ME</comment>
<comment xml:lang="gl">documento de entrada Troff ME</comment>
<comment xml:lang="he">מסמך קלט של Troff ME</comment>
<comment xml:lang="hr">Troff ME ulazni dokument</comment>
@@ -35507,7 +36593,7 @@
<comment xml:lang="pt">documento origem Troff ME</comment>
<comment xml:lang="pt_BR">Documento de entrada Troff ME</comment>
<comment xml:lang="ro">Document intrare Troff ME</comment>
- <comment xml:lang="ru">входной документ Troff ME</comment>
+ <comment xml:lang="ru">Входной документ Troff ME</comment>
<comment xml:lang="sk">Vstupný dokument Troff ME</comment>
<comment xml:lang="sl">Vnosni dokument Troff ME</comment>
<comment xml:lang="sq">Dokument i input Troff ME</comment>
@@ -35524,6 +36610,7 @@
<mime-type type="text/x-troff-mm">
<comment>Troff MM input document</comment>
<comment xml:lang="ar">مستند Troff MM input</comment>
+ <comment xml:lang="ast">Documentu d'entrada de Troff MM</comment>
<comment xml:lang="be@latin">Uvodny dakument Troff MM</comment>
<comment xml:lang="bg">Изходен документ — Troff MM</comment>
<comment xml:lang="ca">document d'entrada Troff MM</comment>
@@ -35538,7 +36625,7 @@
<comment xml:lang="fi">Troff MM -syöteasiakirja</comment>
<comment xml:lang="fo">Troff MM inntaksskjal</comment>
<comment xml:lang="fr">document d'entrée Troff MM</comment>
- <comment xml:lang="ga">cáipéis ionchur Troff MM</comment>
+ <comment xml:lang="ga">cáipéis ionchurtha Troff MM</comment>
<comment xml:lang="gl">documento de entrada Troff MM</comment>
<comment xml:lang="he">מסמך קלט של Troff MM</comment>
<comment xml:lang="hr">Troff MM ulazni dokument</comment>
@@ -35560,7 +36647,7 @@
<comment xml:lang="pt">documento origem Troff MM</comment>
<comment xml:lang="pt_BR">Documento de entrada Troff MM</comment>
<comment xml:lang="ro">Document intrare Troff MM</comment>
- <comment xml:lang="ru">входной документ Troff MM</comment>
+ <comment xml:lang="ru">Входной документ Troff MM</comment>
<comment xml:lang="sk">Vstupný dokument Troff MM</comment>
<comment xml:lang="sl">Vnosni dokument Troff MM</comment>
<comment xml:lang="sq">Dokument i input Troff MM</comment>
@@ -35577,6 +36664,7 @@
<mime-type type="text/x-troff-ms">
<comment>Troff MS input document</comment>
<comment xml:lang="ar">مستند Troff MS input</comment>
+ <comment xml:lang="ast">Documentu d'entrada de Troff MS</comment>
<comment xml:lang="be@latin">Uvodny dakument Troff MS</comment>
<comment xml:lang="bg">Изходен документ — Troff MS</comment>
<comment xml:lang="ca">document d'entrada Troff MS</comment>
@@ -35591,7 +36679,7 @@
<comment xml:lang="fi">Troff MS -syöteasiakirja</comment>
<comment xml:lang="fo">Troff MS inntaksskjal</comment>
<comment xml:lang="fr">document d'entrée Troff MS</comment>
- <comment xml:lang="ga">cáipéis ionchur Troff MS</comment>
+ <comment xml:lang="ga">cáipéis ionchurtha Troff MS</comment>
<comment xml:lang="gl">documento de entrada Troff MS</comment>
<comment xml:lang="he">מסמך קלט של Troff MS</comment>
<comment xml:lang="hr">Troff MS ulazni dokument</comment>
@@ -35613,7 +36701,7 @@
<comment xml:lang="pt">documento origem Troff MS</comment>
<comment xml:lang="pt_BR">Documento de entrada Troff MS</comment>
<comment xml:lang="ro">Document intrare Troff MS</comment>
- <comment xml:lang="ru">входной документ Troff MS</comment>
+ <comment xml:lang="ru">Входной документ Troff MS</comment>
<comment xml:lang="sk">Vstupný dokument Troff MS</comment>
<comment xml:lang="sl">Vnosni dokument Troff MS</comment>
<comment xml:lang="sq">Dokument i input Troff MS</comment>
@@ -35630,18 +36718,28 @@
<mime-type type="text/x-twig">
<comment>Twig template</comment>
<comment xml:lang="ca">plantilla Twig</comment>
+ <comment xml:lang="cs">šablona Twig</comment>
<comment xml:lang="da">Twig-skabelon</comment>
<comment xml:lang="de">Twig-Vorlage</comment>
+ <comment xml:lang="en_GB">Twig template</comment>
<comment xml:lang="es">plantilla de Twig</comment>
+ <comment xml:lang="eu">Twig txantiloia</comment>
<comment xml:lang="fr">modèle Twig</comment>
+ <comment xml:lang="ga">teimpléad Twig</comment>
<comment xml:lang="he">תבנית Twig</comment>
+ <comment xml:lang="hr">Twig predložak</comment>
<comment xml:lang="hu">Twig-sablon</comment>
+ <comment xml:lang="id">templat Twig</comment>
+ <comment xml:lang="it">Modello twig</comment>
<comment xml:lang="kk">Twig үлгісі</comment>
<comment xml:lang="ko">Twig 문서 서식</comment>
<comment xml:lang="pl">Szablon Twig</comment>
<comment xml:lang="pt_BR">Modelo Twig</comment>
- <comment xml:lang="ru">шаблон Twig</comment>
+ <comment xml:lang="ru">Шаблон Twig</comment>
<comment xml:lang="sk">Šablóna Twig</comment>
+ <comment xml:lang="sr">Твиг шаблон</comment>
+ <comment xml:lang="sv">Twig-mall</comment>
+ <comment xml:lang="tr">Twig şablonu</comment>
<comment xml:lang="uk">шаблон twig</comment>
<comment xml:lang="zh_CN">Twig 模板</comment>
<comment xml:lang="zh_TW">Twig 範本</comment>
@@ -35687,7 +36785,7 @@
<comment xml:lang="pt">tabela UIL do X-Motif</comment>
<comment xml:lang="pt_BR">Tabela UIL do X-Motif</comment>
<comment xml:lang="ro">Tabel X-Motif UIL</comment>
- <comment xml:lang="ru">таблица UIL X-Motif</comment>
+ <comment xml:lang="ru">Таблица UIL X-Motif</comment>
<comment xml:lang="sk">Tabuľka X-Motif UIL</comment>
<comment xml:lang="sl">Preglednica X-Motif UIL</comment>
<comment xml:lang="sq">Tabelë X-Motif UIL</comment>
@@ -35721,7 +36819,7 @@
<comment xml:lang="ga">suíomh acmhainne</comment>
<comment xml:lang="gl">localización do recurso</comment>
<comment xml:lang="he">מיקום של משאב</comment>
- <comment xml:lang="hr">položaj resursa</comment>
+ <comment xml:lang="hr">Lokacija resursa</comment>
<comment xml:lang="hu">erőforrás-hely</comment>
<comment xml:lang="ia">Loco de ressources</comment>
<comment xml:lang="id">lokasi sumber daya</comment>
@@ -35740,7 +36838,7 @@
<comment xml:lang="pt">localização de recurso</comment>
<comment xml:lang="pt_BR">Localização de recurso</comment>
<comment xml:lang="ro">locație de resursă</comment>
- <comment xml:lang="ru">расположение ресурса</comment>
+ <comment xml:lang="ru">Расположение ресурса</comment>
<comment xml:lang="sk">Umiestnenie zdroja</comment>
<comment xml:lang="sl">mesto vira</comment>
<comment xml:lang="sq">Pozicion rezerve</comment>
@@ -35765,6 +36863,7 @@
<comment xml:lang="es">archivo codificado con uuencode</comment>
<comment xml:lang="eu">uuencode-aturiko fitxategia</comment>
<comment xml:lang="fr">fichier uuencodé</comment>
+ <comment xml:lang="ga">comhad uuencoded</comment>
<comment xml:lang="gl">Ficheiro uuencoded</comment>
<comment xml:lang="he">קובץ בקידוד uu</comment>
<comment xml:lang="hr">uuencoded datoteka</comment>
@@ -35780,14 +36879,14 @@
<comment xml:lang="pl">Plik zakodowany za pomocą uuencode</comment>
<comment xml:lang="pt">ficheiro uuencoded</comment>
<comment xml:lang="pt_BR">Arquivo codificado UUE</comment>
- <comment xml:lang="ru">файл в кодировке uuencode</comment>
+ <comment xml:lang="ru">Файл, кодированный uuencode</comment>
<comment xml:lang="sk">Súbor v kódovaní uuencode</comment>
<comment xml:lang="sl">Datoteka uuencode</comment>
<comment xml:lang="sr">уукодирана датотека</comment>
<comment xml:lang="sv">uuencode-fil</comment>
<comment xml:lang="tr">uuencoded dosyası</comment>
<comment xml:lang="uk">файл даних у форматі UUE</comment>
- <comment xml:lang="zh_CN">未编码的文件</comment>
+ <comment xml:lang="zh_CN">Uuencode 文件</comment>
<comment xml:lang="zh_TW">uuencoded 檔</comment>
<sub-class-of type="text/plain"/>
<glob pattern="*.uue"/>
@@ -35834,7 +36933,7 @@
<comment xml:lang="pt">ficheiro XMI</comment>
<comment xml:lang="pt_BR">Arquivo XMI</comment>
<comment xml:lang="ro">Fișier XMI</comment>
- <comment xml:lang="ru">файл XMI</comment>
+ <comment xml:lang="ru">Файл XMI</comment>
<comment xml:lang="sk">Súbor XMI</comment>
<comment xml:lang="sl">Datoteka XMI</comment>
<comment xml:lang="sq">File XMI</comment>
@@ -35890,7 +36989,7 @@
<comment xml:lang="pt">ficheiro XSL FO</comment>
<comment xml:lang="pt_BR">Arquivo XSL FO</comment>
<comment xml:lang="ro">Fișier XSL FO</comment>
- <comment xml:lang="ru">файл XSL FO</comment>
+ <comment xml:lang="ru">Файл XSL FO</comment>
<comment xml:lang="sk">Súbor XSL FO</comment>
<comment xml:lang="sl">Datoteka XSL FO</comment>
<comment xml:lang="sq">File XSL FO</comment>
@@ -35911,6 +37010,7 @@
<mime-type type="text/x-iptables">
<comment>iptables configuration file</comment>
<comment xml:lang="ar">ملف تضبيط iptables</comment>
+ <comment xml:lang="ast">ficheru de configuración d'iptables</comment>
<comment xml:lang="be@latin">kanfihuracyjny fajł iptables</comment>
<comment xml:lang="bg">Настройки за iptables</comment>
<comment xml:lang="ca">fitxer de configuració d'iptables</comment>
@@ -35927,7 +37027,7 @@
<comment xml:lang="ga">comhad cumraíochta iptables</comment>
<comment xml:lang="gl">ficheiro de configuración de iptables</comment>
<comment xml:lang="he">קובץ הגדרה של iptables</comment>
- <comment xml:lang="hr">iptables datoteka s postavkama</comment>
+ <comment xml:lang="hr">iptables datoteka podešavanja</comment>
<comment xml:lang="hu">iptables beállítófájl</comment>
<comment xml:lang="ia">File de configuration IPTables</comment>
<comment xml:lang="id">berkas konfigurasi iptables</comment>
@@ -35945,7 +37045,7 @@
<comment xml:lang="pt">ficheiro de configuração iptables</comment>
<comment xml:lang="pt_BR">Arquivo de configuração do iptables</comment>
<comment xml:lang="ro">fișier configurare iptables</comment>
- <comment xml:lang="ru">файл настроек iptables</comment>
+ <comment xml:lang="ru">Файл настроек iptables</comment>
<comment xml:lang="sk">Súbor nastavení iptables</comment>
<comment xml:lang="sl">nastavitvena datoteka iptables</comment>
<comment xml:lang="sq">File konfigurimi iptables</comment>
@@ -35979,6 +37079,110 @@
</magic>
<glob pattern="*.iptables"/>
</mime-type>
+ <mime-type type="text/x-dbus-service">
+ <comment>D-Bus service file</comment>
+ <comment xml:lang="ca">fitxer de servei de D-Bus</comment>
+ <comment xml:lang="cs">soubor služby D-Bus</comment>
+ <comment xml:lang="de">D-Bus-Dienstdatei</comment>
+ <comment xml:lang="en_GB">D-Bus service file</comment>
+ <comment xml:lang="es">archivo de servicio de D-Bus</comment>
+ <comment xml:lang="eu">D-Bus zerbitzu fitxategia</comment>
+ <comment xml:lang="fi">D-Bus-palvelutiedosto</comment>
+ <comment xml:lang="fr">fichier de service D-Bus</comment>
+ <comment xml:lang="ga">comhad seirbhíse D-Bus</comment>
+ <comment xml:lang="hr">Datoteka D-Bus usluge</comment>
+ <comment xml:lang="hu">D-Bus szolgáltatás fájl</comment>
+ <comment xml:lang="id">berkas layanan D-Bus</comment>
+ <comment xml:lang="it">File servizio D-Bus</comment>
+ <comment xml:lang="kk">D-Bus қызметтік файлы</comment>
+ <comment xml:lang="ko">D-Bus 서비스 파일</comment>
+ <comment xml:lang="pl">Plik usługi D-Bus</comment>
+ <comment xml:lang="pt_BR">Arquivo de serviço do D-Bus</comment>
+ <comment xml:lang="ru">Файл службы D-Bus</comment>
+ <comment xml:lang="sk">Súbor služby D-Bus</comment>
+ <comment xml:lang="sr">датотека услуге Д-сабирнице</comment>
+ <comment xml:lang="sv">D-BUS-tjänstfil</comment>
+ <comment xml:lang="tr">D-Bus hizmeti dosyası</comment>
+ <comment xml:lang="uk">файл служби D-Bus</comment>
+ <comment xml:lang="zh_CN">D-Bus 服务文件</comment>
+ <comment xml:lang="zh_TW">D-Bus 服務檔</comment>
+ <sub-class-of type="text/plain"/>
+ <magic priority="50">
+ <match value="\n[D-BUS Service]\n" type="string" offset="0:256"/>
+ <match value="[D-BUS Service]\n" type="string" offset="0"/>
+ </magic>
+ <glob pattern="*.service"/>
+ </mime-type>
+ <mime-type type="text/x-systemd-unit">
+ <comment>systemd unit file</comment>
+ <comment xml:lang="ast">ficheru d'unidaes de systemd</comment>
+ <comment xml:lang="ca">fitxer d'unitat de systemd</comment>
+ <comment xml:lang="cs">jednotkový soubor systemd</comment>
+ <comment xml:lang="de">systemd-Einheitsdatei</comment>
+ <comment xml:lang="en_GB">systemd unit file</comment>
+ <comment xml:lang="es">archivo de unidad de systemd</comment>
+ <comment xml:lang="eu">systemd unitate fitxategia</comment>
+ <comment xml:lang="fi">systemd-yksikkötiedosto</comment>
+ <comment xml:lang="fr">fichier d'unité systemd</comment>
+ <comment xml:lang="ga">comhad aonaid systemd</comment>
+ <comment xml:lang="hr">Datoteka systemd jedinice</comment>
+ <comment xml:lang="hu">systemd egység fájl</comment>
+ <comment xml:lang="id">berkas unit systemd</comment>
+ <comment xml:lang="it">File unità systemd</comment>
+ <comment xml:lang="kk">systemd юнит файлы</comment>
+ <comment xml:lang="ko">systemd 유닛 파일</comment>
+ <comment xml:lang="pl">Plik jednostki systemd</comment>
+ <comment xml:lang="pt_BR">Arquivo de unit do systemd</comment>
+ <comment xml:lang="ru">Модульный файл Systemd</comment>
+ <comment xml:lang="sk">Súbor jednotky systemd</comment>
+ <comment xml:lang="sr">датотека јединице системд-а</comment>
+ <comment xml:lang="sv">systemd-enhetsfil</comment>
+ <comment xml:lang="tr">systemd birim dosyası</comment>
+ <comment xml:lang="uk">файл модуля systemd</comment>
+ <comment xml:lang="zh_CN">systemd 单元文件</comment>
+ <comment xml:lang="zh_TW">systemd 單位檔</comment>
+ <sub-class-of type="text/plain"/>
+ <magic priority="50">
+
+ <match value="\n[Unit]\n" type="string" offset="0:256"/>
+ <match value="\n[Install]\n" type="string" offset="0:256"/>
+ <match value="\n[Automount]\n" type="string" offset="0:256"/>
+
+ <match value="\n[Mount]\n" type="string" offset="0:256"/>
+ <match value="\n[Path]\n" type="string" offset="0:256"/>
+ <match value="\n[Scope]\n" type="string" offset="0:256"/>
+ <match value="\n[Service]\n" type="string" offset="0:256"/>
+ <match value="\n[Slice]\n" type="string" offset="0:256"/>
+ <match value="\n[Socket]\n" type="string" offset="0:256"/>
+ <match value="\n[Swap]\n" type="string" offset="0:256"/>
+
+ <match value="\n[Timer]\n" type="string" offset="0:256"/>
+
+
+ <match value="[Unit]\n" type="string" offset="0"/>
+ <match value="[Install]\n" type="string" offset="0"/>
+ <match value="[Automount]\n" type="string" offset="0"/>
+ <match value="[Mount]\n" type="string" offset="0"/>
+ <match value="[Path]\n" type="string" offset="0"/>
+ <match value="[Scope]\n" type="string" offset="0"/>
+ <match value="[Service]\n" type="string" offset="0"/>
+ <match value="[Slice]\n" type="string" offset="0"/>
+ <match value="[Socket]\n" type="string" offset="0"/>
+ <match value="[Swap]\n" type="string" offset="0"/>
+ <match value="[Timer]\n" type="string" offset="0"/>
+ </magic>
+ <glob pattern="*.automount"/>
+ <glob pattern="*.device"/>
+ <glob pattern="*.mount"/>
+ <glob pattern="*.path"/>
+ <glob pattern="*.scope"/>
+ <glob pattern="*.service"/>
+ <glob pattern="*.slice"/>
+ <glob pattern="*.socket"/>
+ <glob pattern="*.swap"/>
+ <glob pattern="*.target"/>
+ <glob pattern="*.timer"/>
+ </mime-type>
<mime-type type="application/xslt+xml">
<comment>XSLT stylesheet</comment>
<comment xml:lang="ar">نمط XSLT</comment>
@@ -36018,7 +37222,7 @@
<comment xml:lang="pt">folha de estilos XSLT</comment>
<comment xml:lang="pt_BR">Folha de estilo XSLT</comment>
<comment xml:lang="ro">Fișă de stil XSLT</comment>
- <comment xml:lang="ru">таблица стилей XSLT</comment>
+ <comment xml:lang="ru">Таблица стилей XSLT</comment>
<comment xml:lang="sk">Štýl XSLT</comment>
<comment xml:lang="sl">Slogovna predloga XSLT</comment>
<comment xml:lang="sq">Fletë stili XSLT</comment>
@@ -36077,7 +37281,7 @@
<comment xml:lang="pt">base de dados XMCD CD</comment>
<comment xml:lang="pt_BR">Banco de dados de CD XMCD</comment>
<comment xml:lang="ro">Bază de date XMCD CD</comment>
- <comment xml:lang="ru">база данных компакт-дисков XMCD</comment>
+ <comment xml:lang="ru">База данных компакт-дисков XMCD</comment>
<comment xml:lang="sk">Databáza XMCD CD</comment>
<comment xml:lang="sl">Podatkovna zbirka XMCD CD</comment>
<comment xml:lang="sq">Bazë me të dhëna XMCD CD</comment>
@@ -36096,6 +37300,7 @@
<mime-type type="application/xml">
<comment>XML document</comment>
<comment xml:lang="ar">مستند XML</comment>
+ <comment xml:lang="ast">Documentu XML</comment>
<comment xml:lang="be@latin">Dakument XML</comment>
<comment xml:lang="bg">Документ — XML</comment>
<comment xml:lang="ca">document XML</comment>
@@ -36131,7 +37336,7 @@
<comment xml:lang="pt">documento XML</comment>
<comment xml:lang="pt_BR">Documento XML</comment>
<comment xml:lang="ro">Document XML</comment>
- <comment xml:lang="ru">документ XML</comment>
+ <comment xml:lang="ru">Документ XML</comment>
<comment xml:lang="sk">Dokument XML</comment>
<comment xml:lang="sl">Dokument XML</comment>
<comment xml:lang="sq">Dokument XML</comment>
@@ -36159,6 +37364,7 @@
<mime-type type="application/xml-external-parsed-entity">
<comment>XML entities document</comment>
<comment xml:lang="ar">مستند كيانات XML</comment>
+ <comment xml:lang="ast">Documentu d'entidaes XML</comment>
<comment xml:lang="be@latin">Dakument elementaŭ XML</comment>
<comment xml:lang="bg">Документ — заместващи последователности в XML</comment>
<comment xml:lang="ca">document d'entitats XML</comment>
@@ -36193,7 +37399,7 @@
<comment xml:lang="pt">documento de entidades XML</comment>
<comment xml:lang="pt_BR">Documento de entidades XML</comment>
<comment xml:lang="ro">Document entități XML</comment>
- <comment xml:lang="ru">файл сущностей XML</comment>
+ <comment xml:lang="ru">Файл сущностей XML</comment>
<comment xml:lang="sk">Dokument entít XML</comment>
<comment xml:lang="sl">Dokument XML določil</comment>
<comment xml:lang="sq">Dokument njësish XML</comment>
@@ -36214,6 +37420,7 @@
<mime-type type="video/dv">
<comment>DV video</comment>
<comment xml:lang="ar">DV مرئي</comment>
+ <comment xml:lang="ast">Videu en DV</comment>
<comment xml:lang="be@latin">Videa DV</comment>
<comment xml:lang="bg">Видео — DV</comment>
<comment xml:lang="ca">vídeo DV</comment>
@@ -36231,7 +37438,7 @@
<comment xml:lang="ga">físeán DV</comment>
<comment xml:lang="gl">vídeo DV</comment>
<comment xml:lang="he">וידאו DV</comment>
- <comment xml:lang="hr">DV video</comment>
+ <comment xml:lang="hr">DV video snimka</comment>
<comment xml:lang="hu">DV videó</comment>
<comment xml:lang="ia">Video DV</comment>
<comment xml:lang="id">Video DV</comment>
@@ -36250,7 +37457,7 @@
<comment xml:lang="pt">vídeo DV</comment>
<comment xml:lang="pt_BR">Vídeo DV</comment>
<comment xml:lang="ro">Video DV</comment>
- <comment xml:lang="ru">видео DV</comment>
+ <comment xml:lang="ru">Видео DV</comment>
<comment xml:lang="sk">Video DV</comment>
<comment xml:lang="sl">Video datoteka DV</comment>
<comment xml:lang="sq">Video DV</comment>
@@ -36271,6 +37478,7 @@
<mime-type type="video/isivideo">
<comment>ISI video</comment>
<comment xml:lang="ar">مرئي ISI</comment>
+ <comment xml:lang="ast">Videu n'ISI</comment>
<comment xml:lang="az">ISI video faylı</comment>
<comment xml:lang="be@latin">Videa ISI</comment>
<comment xml:lang="bg">Видео — ISI</comment>
@@ -36290,7 +37498,7 @@
<comment xml:lang="ga">físeán ISI</comment>
<comment xml:lang="gl">vídeo ISI</comment>
<comment xml:lang="he">וידאו ISI</comment>
- <comment xml:lang="hr">ISI video</comment>
+ <comment xml:lang="hr">ISI video snimka</comment>
<comment xml:lang="hu">ISI-videó</comment>
<comment xml:lang="ia">Video ISI</comment>
<comment xml:lang="id">Video ISI</comment>
@@ -36309,7 +37517,7 @@
<comment xml:lang="pt">vídeo ISI</comment>
<comment xml:lang="pt_BR">Vídeo ISI</comment>
<comment xml:lang="ro">Video ISI</comment>
- <comment xml:lang="ru">видео ISI</comment>
+ <comment xml:lang="ru">Видео ISI</comment>
<comment xml:lang="sk">Video ISI</comment>
<comment xml:lang="sl">Video datoteka ISI</comment>
<comment xml:lang="sq">Video ISI</comment>
@@ -36336,10 +37544,10 @@
<comment xml:lang="fi">MPEG-2 -siirtobittivirta</comment>
<comment xml:lang="fo">MPEG-2 flutningsstreymur</comment>
<comment xml:lang="fr">flux de transport MPEG-2</comment>
- <comment xml:lang="ga">Sruth aistrithe MPEG-2</comment>
+ <comment xml:lang="ga">sruth aistrithe MPEG-2</comment>
<comment xml:lang="gl">fluxo de transporte MPEG-2</comment>
<comment xml:lang="he">העברת זרימה של MPEG-2</comment>
- <comment xml:lang="hr">MPEG-2 transportni tok</comment>
+ <comment xml:lang="hr">MPEG-2 transportno strujanje</comment>
<comment xml:lang="hu">MPEG-2 átviteli adatfolyam</comment>
<comment xml:lang="ia">Fluxo de transporto MPEG-2</comment>
<comment xml:lang="id">Stream transport MPEG-2</comment>
@@ -36356,7 +37564,7 @@
<comment xml:lang="pt">fluxo de transporte MPEG-2</comment>
<comment xml:lang="pt_BR">Fluxo de transporte de MPEG-2</comment>
<comment xml:lang="ro">Flux transport MPEG-2</comment>
- <comment xml:lang="ru">транспортный поток MPEG-2</comment>
+ <comment xml:lang="ru">Транспортный поток MPEG-2</comment>
<comment xml:lang="sk">MPEG-2 Transport Stream</comment>
<comment xml:lang="sl">Pretočni vir prenosega MPEG</comment>
<comment xml:lang="sr">МПЕГ-2 ток преноса</comment>
@@ -36401,6 +37609,7 @@
<mime-type type="video/mpeg">
<comment>MPEG video</comment>
<comment xml:lang="ar">MPEG مرئي</comment>
+ <comment xml:lang="ast">Videu en MPEG</comment>
<comment xml:lang="be@latin">Videa MPEG</comment>
<comment xml:lang="bg">Видео — MPEG</comment>
<comment xml:lang="ca">vídeo MPEG</comment>
@@ -36418,7 +37627,7 @@
<comment xml:lang="ga">físeán MPEG</comment>
<comment xml:lang="gl">vídeo MPEG</comment>
<comment xml:lang="he">וידאו MPEG</comment>
- <comment xml:lang="hr">MPEG video</comment>
+ <comment xml:lang="hr">MPEG video snimka</comment>
<comment xml:lang="hu">MPEG-videó</comment>
<comment xml:lang="ia">Video MPEG</comment>
<comment xml:lang="id">Video MPEG</comment>
@@ -36438,7 +37647,7 @@
<comment xml:lang="pt">vídeo MPEG</comment>
<comment xml:lang="pt_BR">Vídeo MPEG</comment>
<comment xml:lang="ro">Video MPEG</comment>
- <comment xml:lang="ru">видео MPEG</comment>
+ <comment xml:lang="ru">Видео MPEG</comment>
<comment xml:lang="sk">Video MPEG</comment>
<comment xml:lang="sl">Video datoteka MPEG</comment>
<comment xml:lang="sq">Video MPEG</comment>
@@ -36469,6 +37678,7 @@
</mime-type>
<mime-type type="video/vnd.mpegurl">
<comment>MPEG video (streamed)</comment>
+ <comment xml:lang="ast">Videu en MPEG (tresmitíu)</comment>
<comment xml:lang="bg">Видео — MPEG, поточно</comment>
<comment xml:lang="ca">vídeo MPEG (flux)</comment>
<comment xml:lang="cs">video MPEG (proud)</comment>
@@ -36480,6 +37690,7 @@
<comment xml:lang="eu">MPEG bideoa (korronte bidez)</comment>
<comment xml:lang="fi">MPEG-video (virtaus)</comment>
<comment xml:lang="fr">vidéo MPEG (flux)</comment>
+ <comment xml:lang="ga">físeán MPEG (sruthaithe)</comment>
<comment xml:lang="gl">vídeo MPEG (en stream)</comment>
<comment xml:lang="he">קובץ MPEG (בהזרמה)</comment>
<comment xml:lang="hr">MPEG video snimka (strujanje)</comment>
@@ -36497,7 +37708,7 @@
<comment xml:lang="pl">Plik wideo MPEG (strumień)</comment>
<comment xml:lang="pt">vídeo MPEG (em fluxo)</comment>
<comment xml:lang="pt_BR">Vídeo MPEG (fluxo)</comment>
- <comment xml:lang="ru">видео MPEG (потоковое)</comment>
+ <comment xml:lang="ru">Видео MPEG (потоковое)</comment>
<comment xml:lang="sk">MPEG video (streamované)</comment>
<comment xml:lang="sl">MPEG-video (pretočni)</comment>
<comment xml:lang="sr">МПЕГ видео (проточни)</comment>
@@ -36518,6 +37729,7 @@
<mime-type type="video/quicktime">
<comment>QuickTime video</comment>
<comment xml:lang="ar">QuickTime مرئي</comment>
+ <comment xml:lang="ast">Videu en QuickTime</comment>
<comment xml:lang="be@latin">Videa QuickTime</comment>
<comment xml:lang="bg">Видео — QuickTime</comment>
<comment xml:lang="ca">vídeo QuickTime</comment>
@@ -36535,7 +37747,7 @@
<comment xml:lang="ga">físeán QuickTime</comment>
<comment xml:lang="gl">vídeo QuickTime</comment>
<comment xml:lang="he">וידאו של QuickTime</comment>
- <comment xml:lang="hr">QuickTime video</comment>
+ <comment xml:lang="hr">QuickTime video snimka</comment>
<comment xml:lang="hu">QuickTime videó</comment>
<comment xml:lang="ia">Video QuickTime</comment>
<comment xml:lang="id">Video QuickTime</comment>
@@ -36554,7 +37766,7 @@
<comment xml:lang="pt">vídeo QuickTime</comment>
<comment xml:lang="pt_BR">Vídeo do QuickTime</comment>
<comment xml:lang="ro">Video QuickTime</comment>
- <comment xml:lang="ru">видео QuickTime</comment>
+ <comment xml:lang="ru">Видео QuickTime</comment>
<comment xml:lang="sk">Video QuickTime</comment>
<comment xml:lang="sl">Video datoteka QuickTime</comment>
<comment xml:lang="sq">Video QuickTime</comment>
@@ -36614,7 +37826,7 @@
<comment xml:lang="pt">imagem QuickTime</comment>
<comment xml:lang="pt_BR">Imagem do QuickTime</comment>
<comment xml:lang="ro">Imagine QuickTime</comment>
- <comment xml:lang="ru">изображение QuickTime</comment>
+ <comment xml:lang="ru">Изображение QuickTime</comment>
<comment xml:lang="sk">Obrázok QuickTime</comment>
<comment xml:lang="sl">Slikovna datoteka QuickTime</comment>
<comment xml:lang="sq">Figurë QuickTime</comment>
@@ -36631,9 +37843,44 @@
<glob pattern="*.qtif"/>
<glob pattern="*.qif"/>
</mime-type>
+ <mime-type type="image/ktx">
+ <comment>Khronos texture image</comment>
+ <comment xml:lang="ca">imatge de textura de Khronos</comment>
+ <comment xml:lang="cs">obrázek s texturou Khronos</comment>
+ <comment xml:lang="de">Khronos-Texturbild</comment>
+ <comment xml:lang="en_GB">Khronos texture image</comment>
+ <comment xml:lang="es">imagen de textura de Khronos</comment>
+ <comment xml:lang="fr">image de texture Khronos</comment>
+ <comment xml:lang="ga">íomhá uigeachta Khronos</comment>
+ <comment xml:lang="hr">Khronos tekstura slika</comment>
+ <comment xml:lang="hu">Khronos textúra kép</comment>
+ <comment xml:lang="id">citra tekstur Khronos</comment>
+ <comment xml:lang="it">Immagine texture Khronos</comment>
+ <comment xml:lang="kk">Khronos текстура суреті</comment>
+ <comment xml:lang="ko">크로노스 텍스처 파일</comment>
+ <comment xml:lang="pl">Obraz tekstury Khronos</comment>
+ <comment xml:lang="pt_BR">Imagem de textura do Khronos</comment>
+ <comment xml:lang="ru">Изображение текстуры Khronos</comment>
+ <comment xml:lang="sk">Obrázok textúry Khronos</comment>
+ <comment xml:lang="sr">слика Кронос текстуре</comment>
+ <comment xml:lang="sv">Khronos-texturbild</comment>
+ <comment xml:lang="tr">Khronos kaplama görüntüsü</comment>
+ <comment xml:lang="uk">зображення текстури Khronos</comment>
+ <comment xml:lang="zh_CN">Khronos 纹理图像</comment>
+ <comment xml:lang="zh_TW">Khronos 紋理影像</comment>
+ <magic priority="80">
+ <match value="0xAB4B5458" type="big32" offset="0">
+ <match value="0x203131BB" type="big32" offset="4">
+ <match value="0x0D0A1A0A" type="big32" offset="8"/>
+ </match>
+ </match>
+ </magic>
+ <glob pattern="*.ktx"/>
+ </mime-type>
<mime-type type="video/vnd.vivo">
<comment>Vivo video</comment>
<comment xml:lang="ar">Vivo مرئي</comment>
+ <comment xml:lang="ast">Videu en Vivo</comment>
<comment xml:lang="az">Vivo video faylı</comment>
<comment xml:lang="be@latin">Videa Vivo</comment>
<comment xml:lang="bg">Видео — Vivo</comment>
@@ -36653,7 +37900,7 @@
<comment xml:lang="ga">físeán Vivo</comment>
<comment xml:lang="gl">vídeo Vivo</comment>
<comment xml:lang="he">וידאו של Vivo</comment>
- <comment xml:lang="hr">Vivo video</comment>
+ <comment xml:lang="hr">Vivo video snimka</comment>
<comment xml:lang="hu">Vivo-videó</comment>
<comment xml:lang="ia">Video Vivo</comment>
<comment xml:lang="id">Video Vivo</comment>
@@ -36672,7 +37919,7 @@
<comment xml:lang="pt">vídeo Vivo</comment>
<comment xml:lang="pt_BR">Vídeo Vivo</comment>
<comment xml:lang="ro">Video Vivo</comment>
- <comment xml:lang="ru">видео Vivo</comment>
+ <comment xml:lang="ru">Видео Vivo</comment>
<comment xml:lang="sk">Video Vivo</comment>
<comment xml:lang="sl">Video datoteka Vivo</comment>
<comment xml:lang="sq">Video Vivo</comment>
@@ -36690,6 +37937,7 @@
<mime-type type="video/wavelet">
<comment>Wavelet video</comment>
<comment xml:lang="ar">Wavelet مرئي</comment>
+ <comment xml:lang="ast">Videu en Wavelet</comment>
<comment xml:lang="az">Wavelet video faylı</comment>
<comment xml:lang="be@latin">Videa Wavelet</comment>
<comment xml:lang="bg">Видео — Wavelet</comment>
@@ -36709,7 +37957,7 @@
<comment xml:lang="ga">físeán Wavelet</comment>
<comment xml:lang="gl">vídeo Wavelet</comment>
<comment xml:lang="he">וידאו של Wavelet</comment>
- <comment xml:lang="hr">Wavelet video</comment>
+ <comment xml:lang="hr">Wavelet video snimka</comment>
<comment xml:lang="hu">Wavelet-videó</comment>
<comment xml:lang="ia">Video Wavelet</comment>
<comment xml:lang="id">Video Wavelet</comment>
@@ -36728,7 +37976,7 @@
<comment xml:lang="pt">vídeo Wavelet</comment>
<comment xml:lang="pt_BR">Vídeo Wavelet</comment>
<comment xml:lang="ro">Video Wavelet</comment>
- <comment xml:lang="ru">видео Wavelet</comment>
+ <comment xml:lang="ru">Видео Wavelet</comment>
<comment xml:lang="sk">Video Wavelet</comment>
<comment xml:lang="sl">Video datoteka Wavelet</comment>
<comment xml:lang="sq">Video Wavelet</comment>
@@ -36782,7 +38030,7 @@
<comment xml:lang="pt">animação ANIM</comment>
<comment xml:lang="pt_BR">Animação ANIM</comment>
<comment xml:lang="ro">Animație ANIM</comment>
- <comment xml:lang="ru">анимация ANIM</comment>
+ <comment xml:lang="ru">Анимация ANIM</comment>
<comment xml:lang="sk">Animácia ANIM</comment>
<comment xml:lang="sl">Datoteka animacije ANIM</comment>
<comment xml:lang="sq">Animim ANIM</comment>
@@ -36833,7 +38081,7 @@
<comment xml:lang="pt">animação FLIC</comment>
<comment xml:lang="pt_BR">Animação FLIC</comment>
<comment xml:lang="ro">Animație FLIC</comment>
- <comment xml:lang="ru">анимация FLIC</comment>
+ <comment xml:lang="ru">Анимация FLIC</comment>
<comment xml:lang="sk">Animácia FLIC</comment>
<comment xml:lang="sl">Datoteka animacije FLIC</comment>
<comment xml:lang="sq">Animim FLIC</comment>
@@ -36856,6 +38104,7 @@
<mime-type type="application/x-hwp">
<comment>Haansoft Hangul document</comment>
<comment xml:lang="ar">مستند Haansoft Hangul</comment>
+ <comment xml:lang="ast">Documentu de Haansoft Hangul</comment>
<comment xml:lang="be@latin">Dakument Haansoft Hangul</comment>
<comment xml:lang="bg">Документ — Haansoft Hangul</comment>
<comment xml:lang="ca">document d'Haansoft Hangul</comment>
@@ -36890,7 +38139,7 @@
<comment xml:lang="pt">documento Haansoft Hangul</comment>
<comment xml:lang="pt_BR">Documento do Haansoft Hangul</comment>
<comment xml:lang="ro">Document Haansoft Hangul</comment>
- <comment xml:lang="ru">документ Haansoft Hangul</comment>
+ <comment xml:lang="ru">Документ Haansoft Hangul</comment>
<comment xml:lang="sk">Dokument Haansoft Hangul</comment>
<comment xml:lang="sl">Dokument Haansoft Hangul</comment>
<comment xml:lang="sq">Dokument Haansoft Hangul</comment>
@@ -36911,6 +38160,7 @@
<mime-type type="application/x-hwt">
<comment>Haansoft Hangul document template</comment>
<comment xml:lang="ar">قالب مستند Haansoft Hangul</comment>
+ <comment xml:lang="ast">Plantía de documentu de Haansoft Hangul</comment>
<comment xml:lang="be@latin">Šablon dakumentu Haansoft Hangul</comment>
<comment xml:lang="bg">Шаблон за документи — Haansoft Hangul</comment>
<comment xml:lang="ca">plantilla de document d'Haansoft Hangul</comment>
@@ -36945,7 +38195,7 @@
<comment xml:lang="pt">modelo de documento Haansoft Hangul</comment>
<comment xml:lang="pt_BR">Modelo de documento do Haansoft Hangul</comment>
<comment xml:lang="ro">Document șablon Haansoft Hangul</comment>
- <comment xml:lang="ru">шаблон документа Haansoft Hangul</comment>
+ <comment xml:lang="ru">Шаблон документа Haansoft Hangul</comment>
<comment xml:lang="sk">Šablóna dokumentu Haansoft Hangul</comment>
<comment xml:lang="sl">Predloga dokumenta Haansoft Hangul</comment>
<comment xml:lang="sq">Model dokumenti Haansoft Hangul</comment>
@@ -36999,7 +38249,7 @@
<comment xml:lang="pt">animação MNG</comment>
<comment xml:lang="pt_BR">Animação MNG</comment>
<comment xml:lang="ro">Animație MNG</comment>
- <comment xml:lang="ru">анимация MNG</comment>
+ <comment xml:lang="ru">Анимация MNG</comment>
<comment xml:lang="sk">Animácia MNG</comment>
<comment xml:lang="sl">Datoteka animacije MNG</comment>
<comment xml:lang="sq">Animim MNG</comment>
@@ -37020,6 +38270,7 @@
<mime-type type="application/vnd.ms-asf">
<comment>ASF video</comment>
<comment xml:lang="ar">ASF مرئي</comment>
+ <comment xml:lang="ast">Videu n'ASF</comment>
<comment xml:lang="be@latin">Videa ASF</comment>
<comment xml:lang="bg">Видео — ASF</comment>
<comment xml:lang="ca">vídeo ASF</comment>
@@ -37037,7 +38288,7 @@
<comment xml:lang="ga">físeán ASF</comment>
<comment xml:lang="gl">vídeo ASF</comment>
<comment xml:lang="he">וידאו ASF</comment>
- <comment xml:lang="hr">ASF video</comment>
+ <comment xml:lang="hr">ASF video snimka</comment>
<comment xml:lang="hu">ASF videó</comment>
<comment xml:lang="ia">Video ASF</comment>
<comment xml:lang="id">Video ASF</comment>
@@ -37056,7 +38307,7 @@
<comment xml:lang="pt">vídeo ASF</comment>
<comment xml:lang="pt_BR">Vídeo ASF</comment>
<comment xml:lang="ro">Video ASF</comment>
- <comment xml:lang="ru">видео ASF</comment>
+ <comment xml:lang="ru">Видео ASF</comment>
<comment xml:lang="sk">Video ASF</comment>
<comment xml:lang="sl">Video datoteka ASF</comment>
<comment xml:lang="sq">Video ASF</comment>
@@ -37115,7 +38366,7 @@
<comment xml:lang="pt">ficheiro Windows Media Station</comment>
<comment xml:lang="pt_BR">Arquivo de estação do Windows Media</comment>
<comment xml:lang="ro">Fișier Windows Media Station</comment>
- <comment xml:lang="ru">файл Windows Media Station</comment>
+ <comment xml:lang="ru">Файл Windows Media Station</comment>
<comment xml:lang="sk">Súbor Windows Media Station</comment>
<comment xml:lang="sl">Datoteka Windows Media Station</comment>
<comment xml:lang="sq">File Windows Media Station</comment>
@@ -37136,6 +38387,7 @@
<mime-type type="video/x-ms-wmv">
<comment>Windows Media video</comment>
<comment xml:lang="ar">Windows Media مرئي</comment>
+ <comment xml:lang="ast">Videu de Windows Media</comment>
<comment xml:lang="be@latin">Videa Windows Media</comment>
<comment xml:lang="bg">Видео — Windows Media</comment>
<comment xml:lang="ca">vídeo de Windows Media</comment>
@@ -37152,7 +38404,7 @@
<comment xml:lang="ga">físeán Windows Media</comment>
<comment xml:lang="gl">vídeo de Windows Media</comment>
<comment xml:lang="he">וידאו של Windows Media</comment>
- <comment xml:lang="hr">Windows Media video</comment>
+ <comment xml:lang="hr">Windows Media video snimka</comment>
<comment xml:lang="hu">Windows Media videó</comment>
<comment xml:lang="ia">Video Windows Media</comment>
<comment xml:lang="id">Video Windows Media</comment>
@@ -37170,7 +38422,7 @@
<comment xml:lang="pt">vídeo Windows Media</comment>
<comment xml:lang="pt_BR">Vídeo do Windows Media</comment>
<comment xml:lang="ro">Video Windows Media</comment>
- <comment xml:lang="ru">видео Windows Media</comment>
+ <comment xml:lang="ru">Видео Windows Media</comment>
<comment xml:lang="sk">Video Windows Media</comment>
<comment xml:lang="sl">Video datoteka Windows Media</comment>
<comment xml:lang="sq">Video Windows Media</comment>
@@ -37187,6 +38439,7 @@
<mime-type type="video/x-msvideo">
<comment>AVI video</comment>
<comment xml:lang="ar">AVI مرئي</comment>
+ <comment xml:lang="ast">Videu n'AVI</comment>
<comment xml:lang="az">AVI video faylı</comment>
<comment xml:lang="be@latin">Videa AVI</comment>
<comment xml:lang="bg">Видео — AVI</comment>
@@ -37206,7 +38459,7 @@
<comment xml:lang="ga">físeán AVI</comment>
<comment xml:lang="gl">vídeo AVI</comment>
<comment xml:lang="he">וידאו AVI</comment>
- <comment xml:lang="hr">AVI video</comment>
+ <comment xml:lang="hr">AVI video snimka</comment>
<comment xml:lang="hu">AVI-videó</comment>
<comment xml:lang="ia">Video AVI</comment>
<comment xml:lang="id">Video AVI</comment>
@@ -37226,7 +38479,7 @@
<comment xml:lang="pt">vídeo AVI</comment>
<comment xml:lang="pt_BR">Vídeo AVI</comment>
<comment xml:lang="ro">Video AVI</comment>
- <comment xml:lang="ru">видео AVI</comment>
+ <comment xml:lang="ru">Видео AVI</comment>
<comment xml:lang="sk">Video AVI</comment>
<comment xml:lang="sl">Video datoteka AVI</comment>
<comment xml:lang="sq">Video AVI</comment>
@@ -37259,6 +38512,7 @@
<mime-type type="video/x-nsv">
<comment>NullSoft video</comment>
<comment xml:lang="ar">NullSoft مرئي</comment>
+ <comment xml:lang="ast">Videu de NullSoft</comment>
<comment xml:lang="be@latin">Videa NullSoft</comment>
<comment xml:lang="bg">Видео — NullSoft</comment>
<comment xml:lang="ca">vídeo NullSoft</comment>
@@ -37276,7 +38530,7 @@
<comment xml:lang="ga">físeán NullSoft</comment>
<comment xml:lang="gl">vídeo de NullSoft</comment>
<comment xml:lang="he">וידאו של NullSot</comment>
- <comment xml:lang="hr">NullSoft video</comment>
+ <comment xml:lang="hr">NullSoft video snimka</comment>
<comment xml:lang="hu">NullSoft videó</comment>
<comment xml:lang="ia">Video NullSoft</comment>
<comment xml:lang="id">Video NullSoft</comment>
@@ -37294,7 +38548,7 @@
<comment xml:lang="pt">vídeo NullSoft</comment>
<comment xml:lang="pt_BR">Vídeo do NullSoft</comment>
<comment xml:lang="ro">Video NullSoft</comment>
- <comment xml:lang="ru">видео Nullsoft</comment>
+ <comment xml:lang="ru">Видео Nullsoft</comment>
<comment xml:lang="sk">Video NullSoft</comment>
<comment xml:lang="sl">Video datoteka NullSoft</comment>
<comment xml:lang="sq">Video NullSoft</comment>
@@ -37303,7 +38557,7 @@
<comment xml:lang="tr">Nullsoft videosu</comment>
<comment xml:lang="uk">відеокліп NullSoft</comment>
<comment xml:lang="vi">Ảnh động NullSoft</comment>
- <comment xml:lang="zh_CN">Nullsoft 视频</comment>
+ <comment xml:lang="zh_CN">NullSoft 视频</comment>
<comment xml:lang="zh_TW">NullSoft 視訊</comment>
<magic priority="50">
<match value="NSVf" type="string" offset="0"/>
@@ -37347,7 +38601,7 @@
<comment xml:lang="pt">ficheiro de fluxo SDP multicast</comment>
<comment xml:lang="pt_BR">Arquivo de canal multicast SDP</comment>
<comment xml:lang="ro">Fișier flux multicast SDP</comment>
- <comment xml:lang="ru">файл мультикаст-потока SDP</comment>
+ <comment xml:lang="ru">Файл мультикаст-потока SDP</comment>
<comment xml:lang="sk">Súbor viacsmerového vysielania prúdu SDP</comment>
<comment xml:lang="sl">Pretočni vir večsmernega oddajanja</comment>
<comment xml:lang="sq">File stream multicast SDP</comment>
@@ -37374,6 +38628,7 @@
<mime-type type="video/x-sgi-movie">
<comment>SGI video</comment>
<comment xml:lang="ar">SGI مرئي</comment>
+ <comment xml:lang="ast">Videu en SGI</comment>
<comment xml:lang="az">SGI video faylı</comment>
<comment xml:lang="be@latin">Videa SGI</comment>
<comment xml:lang="bg">Видео — SGI</comment>
@@ -37393,7 +38648,7 @@
<comment xml:lang="ga">físeán SGI</comment>
<comment xml:lang="gl">vídeo SGI</comment>
<comment xml:lang="he">וידאו SGI</comment>
- <comment xml:lang="hr">SGI video</comment>
+ <comment xml:lang="hr">SGI video snimka</comment>
<comment xml:lang="hu">SGI-videó</comment>
<comment xml:lang="ia">Video SGI</comment>
<comment xml:lang="id">Video SGI</comment>
@@ -37412,7 +38667,7 @@
<comment xml:lang="pt">vídeo SGI</comment>
<comment xml:lang="pt_BR">Vídeo SGI</comment>
<comment xml:lang="ro">Video SGI</comment>
- <comment xml:lang="ru">видео SGI</comment>
+ <comment xml:lang="ru">Видео SGI</comment>
<comment xml:lang="sk">Video SGI</comment>
<comment xml:lang="sl">Video datoteka SGI</comment>
<comment xml:lang="sq">Video SGI</comment>
@@ -37465,7 +38720,7 @@
<comment xml:lang="pt">pacote transferido eMusic</comment>
<comment xml:lang="pt_BR">Pacote de download do eMusic</comment>
<comment xml:lang="ro">pachet descărcare eMusic</comment>
- <comment xml:lang="ru">пакет загрузок eMusic</comment>
+ <comment xml:lang="ru">Пакет загрузок eMusic</comment>
<comment xml:lang="sk">Balíček sťahovania eMusic</comment>
<comment xml:lang="sl">Datoteka paketa eMusic</comment>
<comment xml:lang="sq">Paketë shkarkimi eMusic</comment>
@@ -37516,7 +38771,7 @@
<comment xml:lang="pt">dados geográficos KML</comment>
<comment xml:lang="pt_BR">Dados geográficos KML</comment>
<comment xml:lang="ro">Date geografice KML</comment>
- <comment xml:lang="ru">географические данные KML</comment>
+ <comment xml:lang="ru">Географические данные KML</comment>
<comment xml:lang="sk">Zemepisné údaje KML</comment>
<comment xml:lang="sl">Datoteka geografskih podatkov KML</comment>
<comment xml:lang="sr">КМЛ географски подаци</comment>
@@ -37549,7 +38804,7 @@
<comment xml:lang="ga">sonraí comhbhrúite geografacha KML</comment>
<comment xml:lang="gl">datos xeográficos KML comprimidos </comment>
<comment xml:lang="he">מידע גאוגרפי דחוס KML</comment>
- <comment xml:lang="hr">KML geografski komprimirani podaci</comment>
+ <comment xml:lang="hr">KML sažeti geografski podaci</comment>
<comment xml:lang="hu">KML tömörített földrajzi adatok</comment>
<comment xml:lang="ia">Datos geographic KML comprimite</comment>
<comment xml:lang="id">Data geografis KML terkompresi</comment>
@@ -37565,14 +38820,14 @@
<comment xml:lang="pt">dados geográficos comprimidos KML</comment>
<comment xml:lang="pt_BR">Dados geográficos KML compactados</comment>
<comment xml:lang="ro">Date geografice comprimate KML</comment>
- <comment xml:lang="ru">сжатые географические данные KML</comment>
+ <comment xml:lang="ru">Сжатые географические данные KML</comment>
<comment xml:lang="sk">Komprimované zemepisné údaje KML</comment>
<comment xml:lang="sl">Skrčeni geografski podatki KML</comment>
<comment xml:lang="sr">КМЛ географски запаковани подаци</comment>
<comment xml:lang="sv">KML geografiskt komprimerat data</comment>
<comment xml:lang="tr">KML sıkıştırılmış coğrafi verisi</comment>
<comment xml:lang="uk">стиснуті географічні дані KML</comment>
- <comment xml:lang="zh_CN">KML 压缩地理数据</comment>
+ <comment xml:lang="zh_CN">KML 地理压缩数据</comment>
<comment xml:lang="zh_TW">KML 地理壓縮資料</comment>
<acronym>KML</acronym>
<expanded-acronym>Keyhole Markup Language</expanded-acronym>
@@ -37588,6 +38843,7 @@
<comment xml:lang="en_GB">GeoJSON geospatial data</comment>
<comment xml:lang="es">datos geoespaciales en GeoJSON</comment>
<comment xml:lang="fr">données géospatiales GeoJSON</comment>
+ <comment xml:lang="ga">sonraí geospásúla GeoJSON</comment>
<comment xml:lang="hr">GeoJSON geoprostorni podaci</comment>
<comment xml:lang="hu">GeoJSON téradatok</comment>
<comment xml:lang="id">Data geospasial GeoJSON</comment>
@@ -37596,10 +38852,10 @@
<comment xml:lang="ko">GeoJSON 지리 정보 데이터</comment>
<comment xml:lang="pl">Dane geoprzestrzenne GeoJSON</comment>
<comment xml:lang="pt_BR">Dados geoespaciais GeoJSON</comment>
- <comment xml:lang="ru">геопространственные данные GeoJSON</comment>
+ <comment xml:lang="ru">Геопространственные данные GeoJSON</comment>
<comment xml:lang="sk">Geopriestorové údaje GeoJSON</comment>
<comment xml:lang="sr">ГеоЈСОН геопросторни подаци</comment>
- <comment xml:lang="sv">GeoJSON geospatial data</comment>
+ <comment xml:lang="sv">Geospatialt GeoJSON-data</comment>
<comment xml:lang="tr">GeoJSON coğrafi veriler</comment>
<comment xml:lang="uk">геопросторові дані GeoJSON</comment>
<comment xml:lang="zh_CN">GeoJSON 地理空间数据</comment>
@@ -37620,6 +38876,7 @@
<comment xml:lang="eu">GPX datu geografikoak</comment>
<comment xml:lang="fi">GPX-paikkatieto</comment>
<comment xml:lang="fr">données géographiques GPX</comment>
+ <comment xml:lang="ga">sonraí geografacha GPX</comment>
<comment xml:lang="he">נתונים גאוגרפיים GPX</comment>
<comment xml:lang="hr">GPX geografski podaci</comment>
<comment xml:lang="hu">GPX földrajzi adatok</comment>
@@ -37630,13 +38887,13 @@
<comment xml:lang="oc">Donadas geograficas GPX</comment>
<comment xml:lang="pl">Dane geograficzne GPX</comment>
<comment xml:lang="pt_BR">Dados geográficos GPX</comment>
- <comment xml:lang="ru">географические данные GPX</comment>
+ <comment xml:lang="ru">Географические данные GPX</comment>
<comment xml:lang="sk">Zemepisné údaje GPX</comment>
<comment xml:lang="sr">ГПИкс географски подаци</comment>
<comment xml:lang="sv">GPX geografisk data</comment>
<comment xml:lang="tr">GPX coğrafi verileri</comment>
<comment xml:lang="uk">географічні дані GPX</comment>
- <comment xml:lang="zh_CN">GPX 地理空间数据</comment>
+ <comment xml:lang="zh_CN">GPX 地理数据</comment>
<comment xml:lang="zh_TW">GPX 地理資料</comment>
<acronym>GPX</acronym>
<expanded-acronym>GPS Exchange Format</expanded-acronym>
@@ -37686,7 +38943,7 @@
<comment xml:lang="pt">ficheiro de definições Citrix ICA</comment>
<comment xml:lang="pt_BR">Arquivo de configuração do Citrix ICA</comment>
<comment xml:lang="ro">Fișier de configurări Citrix ICA</comment>
- <comment xml:lang="ru">файл настроек Citrix ICA</comment>
+ <comment xml:lang="ru">Файл настроек Citrix ICA</comment>
<comment xml:lang="sk">Súbor nastavení Citrix ICA</comment>
<comment xml:lang="sl">Nastavitvena datoteka Citrix ICA</comment>
<comment xml:lang="sq">File rregullimesh Citrix ICA</comment>
@@ -37706,6 +38963,7 @@
<mime-type type="application/vnd.mozilla.xul+xml">
<comment>XUL interface document</comment>
<comment xml:lang="ar">مستند واجهة XUL</comment>
+ <comment xml:lang="ast">Documentu d'interfaz XUL</comment>
<comment xml:lang="be@latin">Interfejsny dakument XUL</comment>
<comment xml:lang="bg">Документ — интерфейс за XUL</comment>
<comment xml:lang="ca">document d'interfície XUL</comment>
@@ -37740,7 +38998,7 @@
<comment xml:lang="pt">documento de ambiente XUL</comment>
<comment xml:lang="pt_BR">Documento de interface XUL</comment>
<comment xml:lang="ro">Document interfață XUL</comment>
- <comment xml:lang="ru">документ интерфейса XUL</comment>
+ <comment xml:lang="ru">Документ интерфейса XUL</comment>
<comment xml:lang="sk">Dokument rozhrania XUL</comment>
<comment xml:lang="sl">Dokument vmesnika XUL</comment>
<comment xml:lang="sq">Dokument interfaqe XUL</comment>
@@ -37792,7 +39050,7 @@
<comment xml:lang="pt">módulo de instalador XPInstall</comment>
<comment xml:lang="pt_BR">Módulo de instalador XPInstall</comment>
<comment xml:lang="ro">Modul de instalare XPInstall</comment>
- <comment xml:lang="ru">модуль установщика XPInstall</comment>
+ <comment xml:lang="ru">Модуль установщика XPInstall</comment>
<comment xml:lang="sk">Modul inštalátora XPInstall</comment>
<comment xml:lang="sl">modul namestilnika XPInstall</comment>
<comment xml:lang="sr">модул инсталатера Инсталирања ИксПе-а</comment>
@@ -37807,6 +39065,7 @@
<mime-type type="application/vnd.openxmlformats-officedocument.wordprocessingml.document">
<comment>Word 2007 document</comment>
<comment xml:lang="ar">مستند Word 2007</comment>
+ <comment xml:lang="ast">Documentu de Word 2007</comment>
<comment xml:lang="bg">Документ — Word 2007</comment>
<comment xml:lang="ca">document de Word 2007</comment>
<comment xml:lang="cs">dokument Word 2007</comment>
@@ -37838,7 +39097,7 @@
<comment xml:lang="pt">documento Word 2007</comment>
<comment xml:lang="pt_BR">Documento do Word 2007</comment>
<comment xml:lang="ro">Document Word 2007</comment>
- <comment xml:lang="ru">документ Word 2007</comment>
+ <comment xml:lang="ru">Документ Word 2007</comment>
<comment xml:lang="sk">Dokument Word 2007</comment>
<comment xml:lang="sl">Dokument Word 2007</comment>
<comment xml:lang="sr">документ Ворда 2007</comment>
@@ -37846,7 +39105,7 @@
<comment xml:lang="tr">Word 2007 belgesi</comment>
<comment xml:lang="uk">документ Word 2007</comment>
<comment xml:lang="vi">Tài liệu Word 2007</comment>
- <comment xml:lang="zh_CN">Microsoft Word 2007 文档</comment>
+ <comment xml:lang="zh_CN">Word 2007 文档</comment>
<comment xml:lang="zh_TW">Word 2007 文件</comment>
<glob pattern="*.docx"/>
<sub-class-of type="application/zip"/>
@@ -37854,6 +39113,7 @@
</mime-type>
<mime-type type="application/vnd.openxmlformats-officedocument.wordprocessingml.template">
<comment>Word 2007 document template</comment>
+ <comment xml:lang="ast">Plantía de documentu de Word 2007</comment>
<comment xml:lang="bg">Шаблон за документи — Word 2007</comment>
<comment xml:lang="ca">plantilla de document de Word 2007</comment>
<comment xml:lang="cs">šablona dokumentu Word 2007</comment>
@@ -37865,6 +39125,7 @@
<comment xml:lang="eu">Word 2007 dokumentuaren txantiloia</comment>
<comment xml:lang="fi">Word 2007 -asiakirjamalli</comment>
<comment xml:lang="fr">modèle de document Word 2007</comment>
+ <comment xml:lang="ga">teimpléad cháipéis Word 2007</comment>
<comment xml:lang="gl">Plantilla de documento de Word 2007</comment>
<comment xml:lang="he">תבנית מסמך של Word 2007</comment>
<comment xml:lang="hr">Word 2007 predložak dokumenta</comment>
@@ -37882,7 +39143,7 @@
<comment xml:lang="pl">Szablon dokumentu Word 2007</comment>
<comment xml:lang="pt">modelo de documento Word 2007</comment>
<comment xml:lang="pt_BR">Modelo de documento do Word 2007</comment>
- <comment xml:lang="ru">шаблон документа Word 2007</comment>
+ <comment xml:lang="ru">Шаблон документа Word 2007</comment>
<comment xml:lang="sk">Šablóna dokumentu Word 2007</comment>
<comment xml:lang="sl">Predloga dokumenta Word 2007</comment>
<comment xml:lang="sr">шаблон документа Ворда 2007</comment>
@@ -37929,7 +39190,7 @@
<comment xml:lang="pt">apresentação PowerPoint 2007</comment>
<comment xml:lang="pt_BR">Apresentação do PowerPoint 2007</comment>
<comment xml:lang="ro">Prezentare PowerPoint 2007</comment>
- <comment xml:lang="ru">презентация PowerPoint 2007</comment>
+ <comment xml:lang="ru">Презентация PowerPoint 2007</comment>
<comment xml:lang="sk">Prezentácia PowerPoint 2007</comment>
<comment xml:lang="sl">Predstavitev Microsoft PowerPoint 2007</comment>
<comment xml:lang="sr">презентација Пауер Поинта 2007</comment>
@@ -37937,7 +39198,7 @@
<comment xml:lang="tr">PowerPoint 2007 sunumu</comment>
<comment xml:lang="uk">презентація PowerPoint 2007</comment>
<comment xml:lang="vi">Trình diễn PowerPoint 2007</comment>
- <comment xml:lang="zh_CN">Microsoft PowerPoint 2007 演示文稿</comment>
+ <comment xml:lang="zh_CN">PowerPoint 2007 演示文稿</comment>
<comment xml:lang="zh_TW">PowerPoint 2007 簡報</comment>
<glob pattern="*.pptx"/>
<sub-class-of type="application/zip"/>
@@ -37956,9 +39217,10 @@
<comment xml:lang="eu">PowerPoint 2007 diapositiba</comment>
<comment xml:lang="fi">PowerPoint 2007 -dia</comment>
<comment xml:lang="fr">diapositive PowerPoint 2007</comment>
+ <comment xml:lang="ga">sleamhnán PowerPoint 2007</comment>
<comment xml:lang="gl">Diaporama de PowerPoint 2007</comment>
<comment xml:lang="he">שקופית של PowerPoint 2007</comment>
- <comment xml:lang="hr">PowerPoint 2007 slajd</comment>
+ <comment xml:lang="hr">PowerPoint 2007 slikovna prezentacija</comment>
<comment xml:lang="hu">PowerPoint 2007 dia</comment>
<comment xml:lang="ia">Diapositiva PowerPoint 2007</comment>
<comment xml:lang="id">Slide PowerPoint 2007</comment>
@@ -37973,14 +39235,14 @@
<comment xml:lang="pl">Slajd PowerPoint 2007</comment>
<comment xml:lang="pt">diapositivo PowerPoint 2007</comment>
<comment xml:lang="pt_BR">Slide do PowerPoint 2007</comment>
- <comment xml:lang="ru">слайд PowerPoint 2007</comment>
+ <comment xml:lang="ru">Слайд PowerPoint 2007</comment>
<comment xml:lang="sk">Snímka PowerPoint 2007</comment>
<comment xml:lang="sl">Prosojnica PowerPoint 2007</comment>
<comment xml:lang="sr">слајд Пауер Поинта 2007</comment>
<comment xml:lang="sv">PowerPoint 2007-bildspel</comment>
<comment xml:lang="tr">PowerPoint 2007 slaytı</comment>
<comment xml:lang="uk">слайд PowerPoint 2007</comment>
- <comment xml:lang="zh_CN">PowerPoint 2007 文稿</comment>
+ <comment xml:lang="zh_CN">PowerPoint 2007 幻灯片</comment>
<comment xml:lang="zh_TW">PowerPoint 2007 投影片</comment>
<glob pattern="*.sldx"/>
<sub-class-of type="application/zip"/>
@@ -38020,14 +39282,14 @@
<comment xml:lang="pt">espetáculo PowerPoint 2007</comment>
<comment xml:lang="pt_BR">Apresentação do PowerPoint 2007</comment>
<comment xml:lang="ro">Prezentare PowerPoint 2007</comment>
- <comment xml:lang="ru">презентация PowerPoint 2007</comment>
+ <comment xml:lang="ru">Презентация PowerPoint 2007</comment>
<comment xml:lang="sk">Ukážka PowerPoint 2007</comment>
<comment xml:lang="sl">Zagonska predstavitev PowerPoint 2007</comment>
<comment xml:lang="sr">приказ Пауер Поинта 2007</comment>
<comment xml:lang="sv">PowerPoint 2007-visning</comment>
<comment xml:lang="tr">PowerPoint 2007 gösterisi</comment>
<comment xml:lang="uk">показ слайдів PowerPoint 2007</comment>
- <comment xml:lang="zh_CN">Microsoft PowerPoint 2007 演示文稿</comment>
+ <comment xml:lang="zh_CN">PowerPoint 2007 放映</comment>
<comment xml:lang="zh_TW">PowerPoint 2007 展示</comment>
<glob pattern="*.ppsx"/>
<sub-class-of type="application/zip"/>
@@ -38046,6 +39308,7 @@
<comment xml:lang="eu">PowerPoint 2007 aurkezpen txantiloia</comment>
<comment xml:lang="fi">PowerPoint 2007 -esitysmalli</comment>
<comment xml:lang="fr">modèle de présentation PowerPoint 2007</comment>
+ <comment xml:lang="ga">teimpléad láithreoireachta PowerPoint 2007</comment>
<comment xml:lang="gl">modelo de presentación de PowerPoint 2007</comment>
<comment xml:lang="he">תבנית למצגת של PowerPoint 2007</comment>
<comment xml:lang="hr">PowerPoint 2007 predložak prezentacije</comment>
@@ -38063,7 +39326,7 @@
<comment xml:lang="pl">Szablon prezentacji PowerPoint 2007</comment>
<comment xml:lang="pt">modelo de apresentação PowerPoint 2007</comment>
<comment xml:lang="pt_BR">Modelo de apresentação do PowerPoint 2007</comment>
- <comment xml:lang="ru">шаблон презентации PowerPoint 2007</comment>
+ <comment xml:lang="ru">Шаблон презентации PowerPoint 2007</comment>
<comment xml:lang="sk">Šablóna prezentácie PowerPoint 2007</comment>
<comment xml:lang="sl">Predloga predstavitve PowerPoint 2007</comment>
<comment xml:lang="sr">шаблон презентације Пауер Поинта 2007</comment>
@@ -38111,7 +39374,7 @@
<comment xml:lang="pt">folha de cálculo Excel 2007</comment>
<comment xml:lang="pt_BR">Planilha do Excel 2007</comment>
<comment xml:lang="ro">Foaie de calcul Excel 2007</comment>
- <comment xml:lang="ru">электронная таблица Excel 2007</comment>
+ <comment xml:lang="ru">Электронная таблица Excel 2007</comment>
<comment xml:lang="sk">Zošit Excel 2007</comment>
<comment xml:lang="sl">Razpredelnica Microsoft Excel 2007</comment>
<comment xml:lang="sr">табела Ексела 2007</comment>
@@ -38119,7 +39382,7 @@
<comment xml:lang="tr">Excel 2007 çalışma sayfası</comment>
<comment xml:lang="uk">ел. таблиця Excel 2007</comment>
<comment xml:lang="vi">Bảng tính Excel 2007</comment>
- <comment xml:lang="zh_CN">Microsoft Excel 2007 工作簿</comment>
+ <comment xml:lang="zh_CN">Excel 2007 电子表格</comment>
<comment xml:lang="zh_TW">Excel 2007 試算表</comment>
<glob pattern="*.xlsx"/>
<sub-class-of type="application/zip"/>
@@ -38138,6 +39401,7 @@
<comment xml:lang="eu">Excel 2007 kalkulu-orri txantiloia</comment>
<comment xml:lang="fi">Excel 2007 -taulukkomalli</comment>
<comment xml:lang="fr">modèle de feuille de calcul Excel 2007</comment>
+ <comment xml:lang="ga">teimpléad scarbhileoige Excel 2007</comment>
<comment xml:lang="gl">modelo de folla de cálculo Excel 2007</comment>
<comment xml:lang="he">תבנית של גיליון נתונים של Excel 2007</comment>
<comment xml:lang="hr">Excel 2007 predložak proračunske tablice</comment>
@@ -38155,14 +39419,14 @@
<comment xml:lang="pl">Szablon arkusza Excel 2007</comment>
<comment xml:lang="pt">modelo de folha de cálculo Excel 2007</comment>
<comment xml:lang="pt_BR">Modelo de planilha do Excel 2007</comment>
- <comment xml:lang="ru">шаблон электронной таблицы Excel 2007</comment>
+ <comment xml:lang="ru">Шаблон электронной таблицы Excel 2007</comment>
<comment xml:lang="sk">Šablóna zošitu Excel 2007</comment>
<comment xml:lang="sl">Predloga razpredelnice Excel 2007</comment>
<comment xml:lang="sr">шаблон табеле Ексела 2007</comment>
<comment xml:lang="sv">Excel 2007-kalkylarksmall</comment>
<comment xml:lang="tr">Excel 2007 çalışma sayfası şablonu</comment>
<comment xml:lang="uk">шаблон електронної таблиці Excel 2007</comment>
- <comment xml:lang="zh_CN">Excel 2007 工作表模板</comment>
+ <comment xml:lang="zh_CN">Excel 2007 电子表格模板</comment>
<comment xml:lang="zh_TW">Excel 2007 試算表範本</comment>
<glob pattern="*.xltx"/>
<sub-class-of type="application/zip"/>
@@ -38171,6 +39435,7 @@
<mime-type type="application/x-t602">
<comment>T602 document</comment>
<comment xml:lang="ar">مستند T602</comment>
+ <comment xml:lang="ast">Documentu T602</comment>
<comment xml:lang="be@latin">Dakument T602</comment>
<comment xml:lang="bg">Документ — T602</comment>
<comment xml:lang="ca">document T602</comment>
@@ -38206,7 +39471,7 @@
<comment xml:lang="pt">documento T602</comment>
<comment xml:lang="pt_BR">Documento T602</comment>
<comment xml:lang="ro">Document T602</comment>
- <comment xml:lang="ru">документ T602</comment>
+ <comment xml:lang="ru">Документ T602</comment>
<comment xml:lang="sk">Dokument T602</comment>
<comment xml:lang="sl">Dokument T602</comment>
<comment xml:lang="sq">Dokument T602</comment>
@@ -38263,7 +39528,7 @@
<comment xml:lang="pt">definições de Cisco VPN</comment>
<comment xml:lang="pt_BR">Configurações de VPN da Cisco</comment>
<comment xml:lang="ro">Configurări VPN Cisco</comment>
- <comment xml:lang="ru">файл настроек Cisco VPN</comment>
+ <comment xml:lang="ru">Файл настроек Cisco VPN</comment>
<comment xml:lang="sk">Nastavenia Cisco VPN</comment>
<comment xml:lang="sl">Datoteka nastavitev Cisco VPN</comment>
<comment xml:lang="sq">Rregullime VPN Cisco</comment>
@@ -38285,6 +39550,7 @@
<mime-type type="application/vnd.iccprofile">
<comment>ICC profile</comment>
<comment xml:lang="ar">تشكيلة OCL</comment>
+ <comment xml:lang="ast">Perfil ICC</comment>
<comment xml:lang="bg">Цветови профил — OCL</comment>
<comment xml:lang="ca">perfil ICC</comment>
<comment xml:lang="cs">profil ICC</comment>
@@ -38317,14 +39583,14 @@
<comment xml:lang="pt">perfil ICC</comment>
<comment xml:lang="pt_BR">Perfil ICC</comment>
<comment xml:lang="ro">Profil ICC</comment>
- <comment xml:lang="ru">профиль ICC</comment>
+ <comment xml:lang="ru">Профиль ICC</comment>
<comment xml:lang="sk">Profil farieb ICC</comment>
<comment xml:lang="sl">Datoteka profila ICC</comment>
<comment xml:lang="sr">ИЦЦ профил</comment>
<comment xml:lang="sv">ICC-profil</comment>
<comment xml:lang="tr">ICC profili</comment>
<comment xml:lang="uk">профіль ICC</comment>
- <comment xml:lang="zh_CN">ICC 文件</comment>
+ <comment xml:lang="zh_CN">ICC 配置文件</comment>
<comment xml:lang="zh_TW">ICC 設定檔</comment>
<magic priority="50">
<match value="acsp" type="string" offset="36"/>
@@ -38366,7 +39632,7 @@
<comment xml:lang="pt">ficheiro de calibração de cor IT 8.7</comment>
<comment xml:lang="pt_BR">Arquivo de calibração de cor IT 8.7</comment>
<comment xml:lang="ro">Fișier de calibrare a culorii IT 8.7</comment>
- <comment xml:lang="ru">файл калибровки цвета IT 8.7</comment>
+ <comment xml:lang="ru">Файл калибровки цвета IT 8.7</comment>
<comment xml:lang="sk">Súbor kalibrácie farieb IT 8.7</comment>
<comment xml:lang="sl">Umeritvena datoteka barve IT 8.7</comment>
<comment xml:lang="sr">ИТ 8.7 датотека калибрације боје</comment>
@@ -38394,6 +39660,7 @@
<comment xml:lang="eu">CCMX kolore-kalibrazioaren fitxategia</comment>
<comment xml:lang="fi">CCMX-värikorjaustiedosto</comment>
<comment xml:lang="fr">fichier de correction colorimétrique CCMX</comment>
+ <comment xml:lang="ga">comhad ceartúchán dathanna CCMX</comment>
<comment xml:lang="gl">Ficheiro de corrección de cor CCMX</comment>
<comment xml:lang="he">קובץ תיקון צבע מסוג CCMX</comment>
<comment xml:lang="hr">CCMX datotkea ispravka boja</comment>
@@ -38409,7 +39676,7 @@
<comment xml:lang="pl">Plik korekcji kolorów CCMX</comment>
<comment xml:lang="pt">ficheiro de correção de cor CCMX</comment>
<comment xml:lang="pt_BR">Arquivo de correção de cor CCMX</comment>
- <comment xml:lang="ru">файл цветовой коррекции CCMX</comment>
+ <comment xml:lang="ru">Файл цветовой коррекции CCMX</comment>
<comment xml:lang="sk">Súbor korekcie farieb CCMX</comment>
<comment xml:lang="sl">Datoteka barvne poprave CCMX</comment>
<comment xml:lang="sr">ЦЦМИкс датотека поправке боје</comment>
@@ -38437,6 +39704,7 @@
<comment xml:lang="eu">WinHelp laguntza fitxategia</comment>
<comment xml:lang="fi">WinHelp-ohjetiedosto</comment>
<comment xml:lang="fr">fichier d'aide WinHelp</comment>
+ <comment xml:lang="ga">comhad cabhrach WinHelp</comment>
<comment xml:lang="gl">Ficheiro de axuda WinHelp</comment>
<comment xml:lang="he">קובץ עזרה מסוג WinHelp</comment>
<comment xml:lang="hr">WinHelp datoteka pomoći</comment>
@@ -38452,7 +39720,7 @@
<comment xml:lang="pl">Plik pomocy WinHelp</comment>
<comment xml:lang="pt">ficheiro de ajuda WinHelp</comment>
<comment xml:lang="pt_BR">Arquivo de ajuda WinHelp</comment>
- <comment xml:lang="ru">файл справки WinHelp</comment>
+ <comment xml:lang="ru">Файл справки WinHelp</comment>
<comment xml:lang="sk">Súbor Pomocníka WinHelp</comment>
<comment xml:lang="sl">Datoteka pomoči WinHelp</comment>
<comment xml:lang="sr">датотека помоћи Вин хелпа</comment>
@@ -38470,18 +39738,28 @@
<mime-type type="application/x-bsdiff">
<comment>binary differences between files</comment>
<comment xml:lang="ca">diferencies binàries entre fitxers</comment>
+ <comment xml:lang="cs">binární rozdíl mezi soubory</comment>
<comment xml:lang="da">binære forskelle mellem filer</comment>
<comment xml:lang="de">binäre Unterschiede zwischen Dateien</comment>
+ <comment xml:lang="en_GB">binary differences between files</comment>
<comment xml:lang="es">diferencias entre archivos binarios</comment>
+ <comment xml:lang="eu">fitxategi binarioen arteko ezberdinstasunak</comment>
<comment xml:lang="fr">différences binaires entre fichiers</comment>
+ <comment xml:lang="ga">difríochtaí dénártha idir comhaid</comment>
<comment xml:lang="he">הבדלים בינריים בין קבצים</comment>
+ <comment xml:lang="hr">Binarne razlike između datoteka</comment>
<comment xml:lang="hu">bináris különbségfájl</comment>
+ <comment xml:lang="id">perbedaan biner antar berkas</comment>
+ <comment xml:lang="it">Differenze binarie tra file</comment>
<comment xml:lang="kk">файлдар арасындағы бинарлық айырмашылықтар</comment>
<comment xml:lang="ko">바이너리 차이 비교 파일</comment>
<comment xml:lang="pl">Binarna różnica pomiędzy plikami</comment>
<comment xml:lang="pt_BR">Diferenças binárias entre arquivos</comment>
- <comment xml:lang="ru">двоичные различия между файлами</comment>
+ <comment xml:lang="ru">Двоичные различия между файлами</comment>
<comment xml:lang="sk">Binárne rozdiely medzi súbormi</comment>
+ <comment xml:lang="sr">бинарне разлике датотека</comment>
+ <comment xml:lang="sv">binära skillnader mellan filer</comment>
+ <comment xml:lang="tr">dosyalar arasındaki ikilik farklar</comment>
<comment xml:lang="uk">двійкова різниця між файлами</comment>
<comment xml:lang="zh_CN">文件的二进制区别</comment>
<comment xml:lang="zh_TW">檔案間的二進位差異</comment>
@@ -38513,7 +39791,7 @@
<comment xml:lang="ga">grianghraif dhigiteacha</comment>
<comment xml:lang="gl">fotos dixitais</comment>
<comment xml:lang="he">תמונות דיגיטליות</comment>
- <comment xml:lang="hr">digitalne fotografije</comment>
+ <comment xml:lang="hr">Digitalne fotografije</comment>
<comment xml:lang="hu">digitális fényképek</comment>
<comment xml:lang="ia">Photos digital</comment>
<comment xml:lang="id">foto digital</comment>
@@ -38530,7 +39808,7 @@
<comment xml:lang="pt">fotografias digitais</comment>
<comment xml:lang="pt_BR">Fotos digitais</comment>
<comment xml:lang="ro">fotografii digitale</comment>
- <comment xml:lang="ru">цифровые фотографии</comment>
+ <comment xml:lang="ru">Цифровые фотографии</comment>
<comment xml:lang="sk">Digitálne fotografie</comment>
<comment xml:lang="sl">digitalne fotografije</comment>
<comment xml:lang="sq">Fotografi dixhitale</comment>
@@ -38550,6 +39828,7 @@
<comment>Video CD</comment>
<comment xml:lang="ar">Video CD</comment>
+ <comment xml:lang="ast">CD de videu</comment>
<comment xml:lang="be@latin">Videa CD</comment>
<comment xml:lang="bg">CD — видео</comment>
<comment xml:lang="ca">Video CD</comment>
@@ -38564,7 +39843,7 @@
<comment xml:lang="fi">Video CD</comment>
<comment xml:lang="fo">Video CD</comment>
<comment xml:lang="fr">CD vidéo</comment>
- <comment xml:lang="ga">Video CD</comment>
+ <comment xml:lang="ga">dlúthdhiosca físe</comment>
<comment xml:lang="gl">Video CD</comment>
<comment xml:lang="he">תקליטור וידאו</comment>
<comment xml:lang="hr">Video CD</comment>
@@ -38584,7 +39863,7 @@
<comment xml:lang="pt">Video CD</comment>
<comment xml:lang="pt_BR">CD de vídeo</comment>
<comment xml:lang="ro">CD video</comment>
- <comment xml:lang="ru">видеодиск VCD</comment>
+ <comment xml:lang="ru">Видео CD</comment>
<comment xml:lang="sk">Video CD</comment>
<comment xml:lang="sl">Video CD</comment>
<comment xml:lang="sq">CD Video</comment>
@@ -38604,6 +39883,7 @@
<comment>Super Video CD</comment>
<comment xml:lang="ar">Super Video CD</comment>
+ <comment xml:lang="ast">CD de Super Video</comment>
<comment xml:lang="be@latin">Super Video CD</comment>
<comment xml:lang="bg">CD — супер видео</comment>
<comment xml:lang="ca">Super Video CD</comment>
@@ -38618,7 +39898,7 @@
<comment xml:lang="fi">Super Video CD</comment>
<comment xml:lang="fo">Super Video CD</comment>
<comment xml:lang="fr">Super VCD</comment>
- <comment xml:lang="ga">Super Video CD</comment>
+ <comment xml:lang="ga">dlúthdhiosca Super Video</comment>
<comment xml:lang="gl">Super vídeo CD</comment>
<comment xml:lang="he">Super Video CD</comment>
<comment xml:lang="hr">Super Video CD</comment>
@@ -38638,7 +39918,7 @@
<comment xml:lang="pt">Super Video CD</comment>
<comment xml:lang="pt_BR">CD de Super Vídeo (SVCD)</comment>
<comment xml:lang="ro">Super Video CD</comment>
- <comment xml:lang="ru">компакт-диск Super Video</comment>
+ <comment xml:lang="ru">Super Video CD</comment>
<comment xml:lang="sk">Super Video CD</comment>
<comment xml:lang="sl">Super Video CD</comment>
<comment xml:lang="sq">CD Super Video</comment>
@@ -38658,6 +39938,7 @@
<comment>video DVD</comment>
<comment xml:lang="ar">DVD مرئي</comment>
+ <comment xml:lang="ast">DVD de videu</comment>
<comment xml:lang="be@latin">videa DVD</comment>
<comment xml:lang="bg">DVD — видео</comment>
<comment xml:lang="ca">DVD-Video</comment>
@@ -38675,7 +39956,7 @@
<comment xml:lang="ga">DVD físe</comment>
<comment xml:lang="gl">DVD de vídeo</comment>
<comment xml:lang="he">DVD וידאו</comment>
- <comment xml:lang="hr">video DVD</comment>
+ <comment xml:lang="hr">Video DVD</comment>
<comment xml:lang="hu">video DVD</comment>
<comment xml:lang="ia">DVD video</comment>
<comment xml:lang="id">DVD video</comment>
@@ -38693,7 +39974,7 @@
<comment xml:lang="pt">DVD vídeo</comment>
<comment xml:lang="pt_BR">DVD de vídeo</comment>
<comment xml:lang="ro">DVD video</comment>
- <comment xml:lang="ru">видео-DVD</comment>
+ <comment xml:lang="ru">Видео DVD</comment>
<comment xml:lang="sk">DVD-Video</comment>
<comment xml:lang="sl">video DVD</comment>
<comment xml:lang="sq">DVD video</comment>
@@ -38750,7 +40031,7 @@
<comment xml:lang="pt">CD áudio</comment>
<comment xml:lang="pt_BR">CD de áudio</comment>
<comment xml:lang="ro">CD audio</comment>
- <comment xml:lang="ru">звуковой CD</comment>
+ <comment xml:lang="ru">Аудио CD</comment>
<comment xml:lang="sk">Zvukové CD</comment>
<comment xml:lang="sl">zvočni CD</comment>
<comment xml:lang="sq">CD audio</comment>
@@ -38800,7 +40081,7 @@
<comment xml:lang="pt">CD vazio</comment>
<comment xml:lang="pt_BR">Disco CD vazio</comment>
<comment xml:lang="ro">disc gol CD</comment>
- <comment xml:lang="ru">чистый компакт-диск</comment>
+ <comment xml:lang="ru">Чистый диск CD</comment>
<comment xml:lang="sk">Prázdny disk CD</comment>
<comment xml:lang="sl">prazen CD disk</comment>
<comment xml:lang="sq">Disk bosh CD</comment>
@@ -38850,7 +40131,7 @@
<comment xml:lang="pt">DVD vazio</comment>
<comment xml:lang="pt_BR">Disco DVD vazio</comment>
<comment xml:lang="ro">disc gol DVD</comment>
- <comment xml:lang="ru">чистый диск DVD</comment>
+ <comment xml:lang="ru">Чистый диск DVD</comment>
<comment xml:lang="sk">Prázdny disk DVD</comment>
<comment xml:lang="sl">prazen DVD disk</comment>
<comment xml:lang="sq">Disk bosh DVD</comment>
@@ -38900,7 +40181,7 @@
<comment xml:lang="pt">Blu-Ray vazio</comment>
<comment xml:lang="pt_BR">Disco Blu-ray vazio</comment>
<comment xml:lang="ro">disc gol Blu-ray</comment>
- <comment xml:lang="ru">чистый диск Blu-ray</comment>
+ <comment xml:lang="ru">Чистый диск Blu-ray</comment>
<comment xml:lang="sk">Prázdny disk Blu-ray</comment>
<comment xml:lang="sl">prazen Blu-Ray disk</comment>
<comment xml:lang="sq">Disk bosh Blu-ray</comment>
@@ -38950,7 +40231,7 @@
<comment xml:lang="pt">HD DVD vazio</comment>
<comment xml:lang="pt_BR">Disco HD DVD vazio</comment>
<comment xml:lang="ro">disc gol HD DVD</comment>
- <comment xml:lang="ru">чистый диск HD DVD</comment>
+ <comment xml:lang="ru">Чистый диск HD DVD</comment>
<comment xml:lang="sk">Prázdny disk HD DVD</comment>
<comment xml:lang="sl">prazen HD DVD disk</comment>
<comment xml:lang="sq">Disk bosh DVD HD</comment>
@@ -39001,7 +40282,7 @@
<comment xml:lang="pt">DVD áudio</comment>
<comment xml:lang="pt_BR">DVD de áudio</comment>
<comment xml:lang="ro">DVD audio</comment>
- <comment xml:lang="ru">звуковой DVD</comment>
+ <comment xml:lang="ru">Аудио DVD</comment>
<comment xml:lang="sk">Zvukové DVD</comment>
<comment xml:lang="sl">zvočni DVD</comment>
<comment xml:lang="sq">DVD audio</comment>
@@ -39022,6 +40303,7 @@
<comment>Blu-ray video disc</comment>
<comment xml:lang="ar">قرص بلو-راي مرئي</comment>
+ <comment xml:lang="ast">Discu Blu-ray de videu</comment>
<comment xml:lang="be@latin">Videadysk Blu-ray</comment>
<comment xml:lang="bg">Blu-ray — видео</comment>
<comment xml:lang="ca">disc de vídeo Blu-Ray</comment>
@@ -39056,7 +40338,7 @@
<comment xml:lang="pt">Blu-ray de vídeo</comment>
<comment xml:lang="pt_BR">Disco de vídeo Blu-ray</comment>
<comment xml:lang="ro">Disc video Blu-ray</comment>
- <comment xml:lang="ru">видеодиск Blu-ray</comment>
+ <comment xml:lang="ru">Видеодиск Blu-ray</comment>
<comment xml:lang="sk">Videodisk Blu-ray</comment>
<comment xml:lang="sl">Blu-ray video disk</comment>
<comment xml:lang="sq">Disk video Blu-ray</comment>
@@ -39077,6 +40359,7 @@
<comment>HD DVD video disc</comment>
<comment xml:lang="ar">قرص HD DVD مرئي</comment>
+ <comment xml:lang="ast">Discu HD DVD de videu</comment>
<comment xml:lang="be@latin">Videadysk HD DVD</comment>
<comment xml:lang="bg">HD DVD — видео</comment>
<comment xml:lang="ca">disc de vídeo HD-DVD</comment>
@@ -39110,7 +40393,7 @@
<comment xml:lang="pt">HD DVD de vídeo</comment>
<comment xml:lang="pt_BR">Disco de vídeo HD DVD</comment>
<comment xml:lang="ro">Disc video HD DVD</comment>
- <comment xml:lang="ru">видеодиск HD DVD</comment>
+ <comment xml:lang="ru">Видеодиск HD DVD</comment>
<comment xml:lang="sk">Videodisk HD DVD</comment>
<comment xml:lang="sl">HD DVD video disk</comment>
<comment xml:lang="sq">Disk video DVD HD</comment>
@@ -39142,9 +40425,10 @@
<comment xml:lang="eu">e-book irakurlea</comment>
<comment xml:lang="fi">e-kirjan lukulaite</comment>
<comment xml:lang="fr">lecteur de livre numérique</comment>
+ <comment xml:lang="ga">léitheoir r-leabhair</comment>
<comment xml:lang="gl">lector de libros electrónicos</comment>
<comment xml:lang="he">קורא ספרים אלקטרוניים</comment>
- <comment xml:lang="hr">čitač e-knjiga</comment>
+ <comment xml:lang="hr">Čitač e-knjiga</comment>
<comment xml:lang="hu">e-könyvolvasó</comment>
<comment xml:lang="ia">Lector de libro electronic</comment>
<comment xml:lang="id">Pembaca e-book</comment>
@@ -39158,7 +40442,7 @@
<comment xml:lang="pl">Czytnik e-booków</comment>
<comment xml:lang="pt">leitor de ebooks</comment>
<comment xml:lang="pt_BR">Leitor de e-book</comment>
- <comment xml:lang="ru">устройство для чтения электронных книг</comment>
+ <comment xml:lang="ru">Устройство для чтения электронных книг</comment>
<comment xml:lang="sk">Čítačka e-kníh</comment>
<comment xml:lang="sl">Bralnik elektronskih knjig</comment>
<comment xml:lang="sr">читач ел. књига</comment>
@@ -39190,7 +40474,7 @@
<comment xml:lang="fi">Picture CD</comment>
<comment xml:lang="fo">Picture CD</comment>
<comment xml:lang="fr">CD Picture</comment>
- <comment xml:lang="ga">Picture CD</comment>
+ <comment xml:lang="ga">dlúthdhiosca grianghraf</comment>
<comment xml:lang="gl">Picture CD</comment>
<comment xml:lang="he">תקליטור תמונות</comment>
<comment xml:lang="hr">Slikovni CD</comment>
@@ -39246,7 +40530,7 @@
<comment xml:lang="ga">seinnteoir iniompartha fuaime</comment>
<comment xml:lang="gl">dispositivo de son portábel</comment>
<comment xml:lang="he">נגן מוזיקה נייד</comment>
- <comment xml:lang="hr">prenosivi audio svirač</comment>
+ <comment xml:lang="hr">Prenosivi glazbeni svirač</comment>
<comment xml:lang="hu">hordozható zenelejátszó</comment>
<comment xml:lang="ia">Lector audio portabile</comment>
<comment xml:lang="id">pemutar audio portable</comment>
@@ -39263,7 +40547,7 @@
<comment xml:lang="pt">reprodutor áudio portátil</comment>
<comment xml:lang="pt_BR">Reprodutor de áudio portátil</comment>
<comment xml:lang="ro">player audio portabil</comment>
- <comment xml:lang="ru">портативный аудиопроигрыватель</comment>
+ <comment xml:lang="ru">Портативный аудиопроигрыватель</comment>
<comment xml:lang="sk">Prenosný hudobný prehrávač</comment>
<comment xml:lang="sl">prenosni predvajalnik zvoka</comment>
<comment xml:lang="sq">Lexues audio portativ</comment>
@@ -39296,7 +40580,7 @@
<comment xml:lang="ga">bogearraí</comment>
<comment xml:lang="gl">software</comment>
<comment xml:lang="he">תכנה</comment>
- <comment xml:lang="hr">softver</comment>
+ <comment xml:lang="hr">Softver</comment>
<comment xml:lang="hu">szoftver</comment>
<comment xml:lang="ia">Software</comment>
<comment xml:lang="id">peranti lunak</comment>
@@ -39314,7 +40598,7 @@
<comment xml:lang="pt">programa</comment>
<comment xml:lang="pt_BR">Aplicativo</comment>
<comment xml:lang="ro">software</comment>
- <comment xml:lang="ru">программное обеспечение</comment>
+ <comment xml:lang="ru">Программное обеспечение</comment>
<comment xml:lang="sk">Softvér</comment>
<comment xml:lang="sl">programska oprema</comment>
<comment xml:lang="sq">Software</comment>
@@ -39362,7 +40646,7 @@
<comment xml:lang="pt">programa UNIX</comment>
<comment xml:lang="pt_BR">Aplicativo UNIX</comment>
<comment xml:lang="ro">Software UNIX</comment>
- <comment xml:lang="ru">программа UNIX</comment>
+ <comment xml:lang="ru">Программа UNIX</comment>
<comment xml:lang="sk">Softvér UNIX</comment>
<comment xml:lang="sl">Programska datoteka UNIX</comment>
<comment xml:lang="sr">ЈУНИКС-ов софтвер</comment>
@@ -39414,7 +40698,7 @@
<comment xml:lang="pt">programa Windows</comment>
<comment xml:lang="pt_BR">Programa do Windows</comment>
<comment xml:lang="ro">Software Windows</comment>
- <comment xml:lang="ru">программа Windows</comment>
+ <comment xml:lang="ru">Программа Windows</comment>
<comment xml:lang="sk">Softvér Windows</comment>
<comment xml:lang="sl">Programska oprema za okolje Windows</comment>
<comment xml:lang="sr">Виндоузов софтвер</comment>
@@ -39430,9 +40714,9 @@
</treemagic>
</mime-type>
- <mime-type type="application/x-trig">
-
+ <mime-type type="application/trig">
<comment>TriG RDF document</comment>
+ <comment xml:lang="ast">Documentu RDF TriG</comment>
<comment xml:lang="ca">document TriG RDF</comment>
<comment xml:lang="cs">dokument Trig RDF</comment>
<comment xml:lang="da">TriG RDF-dokument</comment>
@@ -39443,6 +40727,7 @@
<comment xml:lang="eu">TriG RDF dokumentua</comment>
<comment xml:lang="fi">TriG RDF -asiakirja</comment>
<comment xml:lang="fr">document RDF TriG</comment>
+ <comment xml:lang="ga">cáipéis RDF TriG</comment>
<comment xml:lang="gl">Documento RDF TriG</comment>
<comment xml:lang="he">מסמך RDF של TriG</comment>
<comment xml:lang="hr">TriG RDF dokument</comment>
@@ -39469,6 +40754,7 @@
<expanded-acronym>TriG RDF Graph Triple Language</expanded-acronym>
<sub-class-of type="text/plain"/>
<glob pattern="*.trig"/>
+ <alias type="application/x-trig"/>
</mime-type>
<mime-type type="application/x-iwork-keynote-sffkey">
@@ -39483,6 +40769,7 @@
<comment xml:lang="eu">Apple Keynote 5 aurkezpena</comment>
<comment xml:lang="fi">Apple Keynote 5 -esitys</comment>
<comment xml:lang="fr">présentation Apple Keynote 5</comment>
+ <comment xml:lang="ga">láithreoireacht Apple Keynote 5</comment>
<comment xml:lang="gl">Presentación de Apple Keynote 5</comment>
<comment xml:lang="he">מצגת Apple Keynote 5</comment>
<comment xml:lang="hr">Apple Keynote 5 prezentacija</comment>
@@ -39528,6 +40815,7 @@
<comment xml:lang="eu">Adobe PageMaker</comment>
<comment xml:lang="fi">Adobe PageMaker</comment>
<comment xml:lang="fr">Adobe PageMaker</comment>
+ <comment xml:lang="ga">Adobe PageMaker</comment>
<comment xml:lang="gl">Adobe PageMaker</comment>
<comment xml:lang="he">Adobe PageMaker</comment>
<comment xml:lang="hr">Adobe PageMaker</comment>
@@ -39568,6 +40856,7 @@
<comment xml:lang="es">WAD de Doom</comment>
<comment xml:lang="eu">Doom WAD</comment>
<comment xml:lang="fr">WAD Doom</comment>
+ <comment xml:lang="ga">WAD Doom</comment>
<comment xml:lang="hr">Doom WAD</comment>
<comment xml:lang="hu">Doom WAD</comment>
<comment xml:lang="ia">WAD pro Doom</comment>
@@ -39608,6 +40897,7 @@
<comment xml:lang="eu">Amiga disko irudia</comment>
<comment xml:lang="fi">Amiga-levytiedosto</comment>
<comment xml:lang="fr">image disque Amiga</comment>
+ <comment xml:lang="ga">íomhá diosca Amiga</comment>
<comment xml:lang="he">דמות כונן Amiga</comment>
<comment xml:lang="hr">Amiga slika diska</comment>
<comment xml:lang="hu">Amiga lemezkép</comment>
@@ -39615,18 +40905,18 @@
<comment xml:lang="id">Image disk Amiga</comment>
<comment xml:lang="it">Disco immagine Amiga</comment>
<comment xml:lang="kk">Amiga диск бейнесі</comment>
- <comment xml:lang="ko">아미가 디스크 이미지</comment>
+ <comment xml:lang="ko">Amiga 디스크 이미지</comment>
<comment xml:lang="oc">imatge disc Amiga</comment>
<comment xml:lang="pl">Obraz dysku Amiga</comment>
<comment xml:lang="pt">imagem de disco Amiga</comment>
<comment xml:lang="pt_BR">Imagem de disco Amiga</comment>
- <comment xml:lang="ru">образ диска Amiga</comment>
+ <comment xml:lang="ru">Образ диска Amiga</comment>
<comment xml:lang="sk">Obraz disku Amiga</comment>
<comment xml:lang="sr">слика диска Амиге</comment>
<comment xml:lang="sv">Amiga-diskavbild</comment>
<comment xml:lang="tr">Amiga disk kalıbı</comment>
<comment xml:lang="uk">образ диска Amiga</comment>
- <comment xml:lang="zh_CN">Amiga 磁盘镜像</comment>
+ <comment xml:lang="zh_CN">Amiga 磁盘映像</comment>
<comment xml:lang="zh_TW">Amiga 磁碟映像檔</comment>
<magic priority="50">
<match value="DOS\x00" type="string" offset="0"/>
@@ -39637,19 +40927,31 @@
<mime-type type="application/vnd.flatpak">
<comment>Flatpak application bundle</comment>
<comment xml:lang="ca">paquet d'aplicació Flatpak</comment>
+ <comment xml:lang="cs">balíček Flatpak s aplikací</comment>
<comment xml:lang="da">Flatpak-programsamling</comment>
<comment xml:lang="de">Flatpak-Anwendungspaket</comment>
+ <comment xml:lang="en_GB">Flatpak application bundle</comment>
<comment xml:lang="es">paquete de aplicación Flatpak</comment>
+ <comment xml:lang="eu">Flatpak aplikazio bilduma</comment>
+ <comment xml:lang="fi">Flatpak-sovelluspaketti</comment>
<comment xml:lang="fr">lot applicatif Flatpak</comment>
+ <comment xml:lang="ga">burla feidhmchláir Flatpak</comment>
+ <comment xml:lang="he">חבילת יישומי Flatpak</comment>
+ <comment xml:lang="hr">Flatpak paket aplikacije</comment>
<comment xml:lang="hu">Flatpak alkalmazáscsomag</comment>
+ <comment xml:lang="id">bundel aplikasi Flatpak</comment>
+ <comment xml:lang="it">Bundle applicazione Flatpak</comment>
<comment xml:lang="kk">Flatpak қолданбалар дестесі</comment>
<comment xml:lang="ko">Flatpak 프로그램 번들</comment>
<comment xml:lang="pl">Pakiet programu Flatpak</comment>
<comment xml:lang="pt_BR">Pacote de aplicativo Flatpak</comment>
- <comment xml:lang="ru">пакет приложений Flatpak</comment>
+ <comment xml:lang="ru">Пакет приложения Flatpak</comment>
<comment xml:lang="sk">Balík aplikácií Flatpak</comment>
+ <comment xml:lang="sr">скуп програма Флатпака</comment>
+ <comment xml:lang="sv">Flatpak-programbunt</comment>
+ <comment xml:lang="tr">Flatpak uygulama paketi</comment>
<comment xml:lang="uk">пакунок із програмами Flatpak</comment>
- <comment xml:lang="zh_CN">Flatpak 应用包</comment>
+ <comment xml:lang="zh_CN">Flatpak 应用组合包</comment>
<comment xml:lang="zh_TW">Flatpak 應用程式套組</comment>
<generic-icon name="package-x-generic"/>
<magic priority="50">
@@ -39664,17 +40966,29 @@
<mime-type type="application/vnd.flatpak.repo">
<comment>Flatpak repository description</comment>
<comment xml:lang="ca">descripció de dipòsit de Flatpak</comment>
+ <comment xml:lang="cs">popis repozitáře Flatpak</comment>
<comment xml:lang="da">Flatpak-arkivbeskrivelse</comment>
<comment xml:lang="de">Flatpak-Repositoriumsbeschreibung</comment>
+ <comment xml:lang="en_GB">Flatpak repository description</comment>
<comment xml:lang="es">descripción de repositorio de Flatpak</comment>
+ <comment xml:lang="eu">Flatpak biltegi deskribapena</comment>
+ <comment xml:lang="fi">Flatpak-ohjelmistolähdekuvaus</comment>
<comment xml:lang="fr">description de dépôt Flatpak</comment>
+ <comment xml:lang="ga">cur síos ar stórlann Flatpak</comment>
+ <comment xml:lang="he">תיאור מאגר Flatpak</comment>
+ <comment xml:lang="hr">Flatpak opis repozitorija</comment>
<comment xml:lang="hu">Flatpak tárolóleírás</comment>
+ <comment xml:lang="id">deskripsi repositori Flatpak</comment>
+ <comment xml:lang="it">Descrizione repository Flatpack</comment>
<comment xml:lang="kk">Flatpak репозиторийі сипаттамасы</comment>
<comment xml:lang="ko">Flatpak 저장소 디스크립션</comment>
<comment xml:lang="pl">Opis repozytorium Flatpak</comment>
<comment xml:lang="pt_BR">Descrição de repositório Flatpak</comment>
- <comment xml:lang="ru">описание репозитория Flatpak</comment>
+ <comment xml:lang="ru">Описание репозитория Flatpak</comment>
<comment xml:lang="sk">Popis repozitára Flatpak</comment>
+ <comment xml:lang="sr">опис ризнице Флатпака</comment>
+ <comment xml:lang="sv">Flatpak-förrådsbeskrivning</comment>
+ <comment xml:lang="tr">Flatpak depo açıklaması</comment>
<comment xml:lang="uk">опис сховища Flatpak</comment>
<comment xml:lang="zh_CN">Flatpak 软件库描述</comment>
<comment xml:lang="zh_TW">Flatpak 軟體庫描述</comment>
@@ -39688,6 +41002,31 @@
<mime-type type="application/vnd.flatpak.ref">
<comment>Flatpak repository reference</comment>
+ <comment xml:lang="ca">referència de dipòsit Flatpak</comment>
+ <comment xml:lang="cs">odkaz na repozitář Flatpak</comment>
+ <comment xml:lang="de">Flatpak-Repositoriumsreferenz</comment>
+ <comment xml:lang="en_GB">Flatpak repository reference</comment>
+ <comment xml:lang="es">referencia a repositorio de Flatpak</comment>
+ <comment xml:lang="eu">Flatpak biltegi erreferentzia</comment>
+ <comment xml:lang="fi">Flatpak-ohjelmistolähdeviite</comment>
+ <comment xml:lang="fr">référence de dépôt Flatpak</comment>
+ <comment xml:lang="ga">tagairt do stórlann Flatpak</comment>
+ <comment xml:lang="hr">Flatpak preporučeni repozitorij</comment>
+ <comment xml:lang="hu">Flatpak tárolóhivatkozás</comment>
+ <comment xml:lang="id">acuan repositori Flatpak</comment>
+ <comment xml:lang="it">Riferimento repository Flatpack</comment>
+ <comment xml:lang="kk">Flatpak репозиторийіне сілтеме</comment>
+ <comment xml:lang="ko">Flatpak 저장소 참조</comment>
+ <comment xml:lang="pl">Odwołanie do repozytorium Flatpak</comment>
+ <comment xml:lang="pt_BR">Referência de repositório Flatpak</comment>
+ <comment xml:lang="ru">Ссылка на репозиторий Flatpak</comment>
+ <comment xml:lang="sk">Referencia repozitára Flatpak</comment>
+ <comment xml:lang="sr">упута ризнице Флатпака</comment>
+ <comment xml:lang="sv">Flatpak-förrådsreferens</comment>
+ <comment xml:lang="tr">Flatpak depo başvurusu</comment>
+ <comment xml:lang="uk">посилання на сховище Flatpak</comment>
+ <comment xml:lang="zh_CN">Flatpak 软件库引用</comment>
+ <comment xml:lang="zh_TW">Flatpak 軟體庫參照</comment>
<generic-icon name="package-x-generic"/>
<sub-class-of type="text/plain"/>
<magic priority="50">
@@ -39699,18 +41038,29 @@
<mime-type type="application/vnd.squashfs">
<comment>Squashfs filesystem</comment>
<comment xml:lang="ca">Sistema de fitxers Squashfs</comment>
+ <comment xml:lang="cs">souborový systém Squashfs</comment>
<comment xml:lang="da">Squashfs-filsystem</comment>
<comment xml:lang="de">Squashfs-Dateisystem</comment>
+ <comment xml:lang="en_GB">Squashfs filesystem</comment>
<comment xml:lang="es">sistema de archivos Squashfs</comment>
+ <comment xml:lang="eu">Squashfs fitxategi sistema</comment>
+ <comment xml:lang="fi">Squashfs-tiedostojärjestelmä</comment>
<comment xml:lang="fr">système de fichiers Squashfs</comment>
+ <comment xml:lang="ga">córas comhad Squashfs</comment>
<comment xml:lang="he">מערכת קבצים Squashfs</comment>
+ <comment xml:lang="hr">Squashfs datotečni sustav</comment>
<comment xml:lang="hu">Squashfs fájlrendszer</comment>
+ <comment xml:lang="id">sistem berkas Squashfs</comment>
+ <comment xml:lang="it">File system squashfs</comment>
<comment xml:lang="kk">Squashfs файлдық жүйесі</comment>
<comment xml:lang="ko">Squashfs 파일 시스템</comment>
<comment xml:lang="pl">System plików SquashFS</comment>
<comment xml:lang="pt_BR">Sistema de arquivos Squashfs</comment>
- <comment xml:lang="ru">файловая система Squashfs</comment>
+ <comment xml:lang="ru">Файловая система Squashfs</comment>
<comment xml:lang="sk">Systém súborov Squashfs</comment>
+ <comment xml:lang="sr">систем датотека Сквошфс</comment>
+ <comment xml:lang="sv">Squashfs-filsystem</comment>
+ <comment xml:lang="tr">Squashfs dosya sistemi</comment>
<comment xml:lang="uk">файлова система squashfs</comment>
<comment xml:lang="zh_CN">Squashfs 文件系统</comment>
<comment xml:lang="zh_TW">Squashfs 檔案系統</comment>
@@ -39721,21 +41071,77 @@
<glob pattern="*.sqsh"/>
</mime-type>
+
+ <mime-type type="application/vnd.appimage">
+ <comment>AppImage application bundle</comment>
+ <comment xml:lang="ca">paquet d'aplicació AppImage</comment>
+ <comment xml:lang="cs">balíček AppImage s aplikací</comment>
+ <comment xml:lang="da">Applmage-programsamling</comment>
+ <comment xml:lang="de">AppImage-Anwendungspaket</comment>
+ <comment xml:lang="en_GB">AppImage application bundle</comment>
+ <comment xml:lang="es">paquete de aplicación AppImage</comment>
+ <comment xml:lang="eu">AppImage aplikazio bilduma</comment>
+ <comment xml:lang="fi">AppImage-sovelluspaketti</comment>
+ <comment xml:lang="fr">lot applicatif AppImage</comment>
+ <comment xml:lang="ga">burla feidhmchláir AppImage</comment>
+ <comment xml:lang="he">חבילת יישומי AppImage</comment>
+ <comment xml:lang="hr">AppImage paket aplikacije</comment>
+ <comment xml:lang="hu">AppImage alkalmazáscsomag</comment>
+ <comment xml:lang="id">bundel aplikasi AppImage</comment>
+ <comment xml:lang="it">Bundle applicazione AppImage</comment>
+ <comment xml:lang="kk">AppImage қолданбалар дестесі</comment>
+ <comment xml:lang="ko">AppImage 프로그램 번들</comment>
+ <comment xml:lang="pl">Pakiet programu AppImage</comment>
+ <comment xml:lang="pt_BR">Pacote de aplicativo AppImage</comment>
+ <comment xml:lang="ru">Пакет приложения AppImage</comment>
+ <comment xml:lang="sk">Balík aplikácií AppImage</comment>
+ <comment xml:lang="sr">скуп програма Ап-слике</comment>
+ <comment xml:lang="sv">AppImage-programbunt</comment>
+ <comment xml:lang="tr">AppImage uygulama paketi</comment>
+ <comment xml:lang="uk">пакунок із програмами AppImage</comment>
+ <comment xml:lang="zh_CN">AppImage 应用组合包</comment>
+ <comment xml:lang="zh_TW">AppImage 應用程式套組</comment>
+ <sub-class-of type="application/x-executable"/>
+ <sub-class-of type="application/vnd.squashfs"/>
+ <generic-icon name="application-x-executable"/>
+ <magic priority="50">
+ <match value="ELF" type="string" offset="1">
+ <match value="0x41" type="byte" offset="8">
+ <match value="0x49" type="byte" offset="9">
+ <match value="0x02" type="byte" offset="10"/>
+ </match>
+ </match>
+ </match>
+ </magic>
+ <glob weight="60" pattern="*.appimage"/>
+ </mime-type>
+
<mime-type type="application/vnd.snap">
<comment>Snap package</comment>
<comment xml:lang="ca">Paquet Snap</comment>
+ <comment xml:lang="cs">balíček Snap</comment>
<comment xml:lang="da">Snap-pakke</comment>
<comment xml:lang="de">Snap-Paket</comment>
+ <comment xml:lang="en_GB">Snap package</comment>
<comment xml:lang="es">paquete Snap</comment>
+ <comment xml:lang="eu">Snap paketea</comment>
+ <comment xml:lang="fi">Snap-paketti</comment>
<comment xml:lang="fr">paquet Snap</comment>
+ <comment xml:lang="ga">pacáiste Snap</comment>
<comment xml:lang="he">חבילת Snap</comment>
+ <comment xml:lang="hr">Snap paket</comment>
<comment xml:lang="hu">Snap-csomag</comment>
+ <comment xml:lang="id">paket Snap</comment>
+ <comment xml:lang="it">Pacchetto snap</comment>
<comment xml:lang="kk">Snap дестесі</comment>
<comment xml:lang="ko">Snap 패키지</comment>
<comment xml:lang="pl">Pakiet Snap</comment>
<comment xml:lang="pt_BR">Pacote Snap</comment>
- <comment xml:lang="ru">пакет Snap</comment>
+ <comment xml:lang="ru">Пакет Snap</comment>
<comment xml:lang="sk">Balík Snap</comment>
+ <comment xml:lang="sr">Снап пакет</comment>
+ <comment xml:lang="sv">Snap-paket</comment>
+ <comment xml:lang="tr">Snap paketi</comment>
<comment xml:lang="uk">пакунок snap</comment>
<comment xml:lang="zh_CN">Snap 软件包</comment>
<comment xml:lang="zh_TW">Snap 軟體包</comment>
@@ -39743,4 +41149,85 @@
<sub-class-of type="application/vnd.squashfs"/>
</mime-type>
+
+ <mime-type type="model/stl">
+ <comment>STL 3D model</comment>
+ <acronym>STL</acronym>
+ <expanded-acronym>StereoLithography</expanded-acronym>
+ <magic priority="50">
+ <match value="solid" type="string" offset="0"/>
+ <match value="SOLID" type="string" offset="0"/>
+ </magic>
+ <glob pattern="*.stl"/>
+ <alias type="model/x.stl-ascii"/>
+ <alias type="model/x.stl-binary"/>
+ </mime-type>
+
+ <mime-type type="text/x.gcode">
+ <comment>G-code file</comment>
+ <comment xml:lang="ca">fitxer G-code</comment>
+ <comment xml:lang="cs">soubor G-code</comment>
+ <comment xml:lang="de">G-Code-Datei</comment>
+ <comment xml:lang="en_GB">G-code file</comment>
+ <comment xml:lang="es">archivo G-code</comment>
+ <comment xml:lang="eu">G-code fitxategia</comment>
+ <comment xml:lang="fi">G-code-tiedosto</comment>
+ <comment xml:lang="fr">fichier G-code</comment>
+ <comment xml:lang="ga">comhad G-code</comment>
+ <comment xml:lang="hr">G-kôd datoteka</comment>
+ <comment xml:lang="hu">G-code fájl</comment>
+ <comment xml:lang="id">berkas G-code</comment>
+ <comment xml:lang="it">File G-code</comment>
+ <comment xml:lang="kk">G-code файлы</comment>
+ <comment xml:lang="ko">지-코드 파일</comment>
+ <comment xml:lang="pl">Plik G-code</comment>
+ <comment xml:lang="pt_BR">Arquivo G-code</comment>
+ <comment xml:lang="ru">Файл G-code</comment>
+ <comment xml:lang="sk">Súbor G-code</comment>
+ <comment xml:lang="sr">датотека Г-ко̂да</comment>
+ <comment xml:lang="sv">G-code-fil</comment>
+ <comment xml:lang="tr">G-code dosyası</comment>
+ <comment xml:lang="uk">файл G-code</comment>
+ <comment xml:lang="zh_CN">G-code 文件</comment>
+ <comment xml:lang="zh_TW">G-code 檔案</comment>
+ <sub-class-of type="text/plain"/>
+ <generic-icon name="text-x-generic"/>
+ <glob pattern="*.gcode"/>
+ </mime-type>
+
+ <mime-type type="application/x-fds-disk">
+ <comment>Nintendo FDS disk image</comment>
+ <comment xml:lang="ca">Imatge de disc Nintendo FDS</comment>
+ <comment xml:lang="cs">obraz disku pro Nintendo FDS</comment>
+ <comment xml:lang="de">Nintendo-FDS-Datenträgerabbild</comment>
+ <comment xml:lang="en_GB">Nintendo FDS disk image</comment>
+ <comment xml:lang="es">imagen de disco FDS de Nintendo</comment>
+ <comment xml:lang="eu">Nintendo FDS disko irudia</comment>
+ <comment xml:lang="fi">Nintendo FDS -levykuva</comment>
+ <comment xml:lang="fr">image disque Nintendo FDS</comment>
+ <comment xml:lang="ga">íomhá diosca Nintendo FDS</comment>
+ <comment xml:lang="hr">Nintendo FDS slika diska</comment>
+ <comment xml:lang="hu">Nintendo FDS lemezkép</comment>
+ <comment xml:lang="id">image disk Nintendo FDS</comment>
+ <comment xml:lang="it">Immagine disco Nintendo FDS</comment>
+ <comment xml:lang="kk">Nintendo FDS диск бейнесі</comment>
+ <comment xml:lang="ko">닌텐도 FDS 디스크 이미지</comment>
+ <comment xml:lang="pl">Obraz dysku Nintendo FDS</comment>
+ <comment xml:lang="pt_BR">Imagem de disco Nintendo FDS</comment>
+ <comment xml:lang="ru">Образ диска Nintendo FDS</comment>
+ <comment xml:lang="sk">Obraz disku Nintendo FDS</comment>
+ <comment xml:lang="sr">Нинтендо ФДС слика диска</comment>
+ <comment xml:lang="sv">Nintendo FDS-diskavbild</comment>
+ <comment xml:lang="tr">Nintendo FDS disk kalıbı</comment>
+ <comment xml:lang="uk">образ диска FDS Nintendo</comment>
+ <comment xml:lang="zh_CN">任天堂 FDS 磁盘映像</comment>
+ <comment xml:lang="zh_TW">Nintendo FDS 磁碟映像檔</comment>
+ <acronym>FDS</acronym>
+ <expanded-acronym>Famicom Disk System</expanded-acronym>
+ <glob pattern="*.fds"/>
+ <magic>
+ <match value="*NINTENDO-HVC*" type="string" offset="1"/>
+ </magic>
+ </mime-type>
+
</mime-info>
diff --git a/src/corelib/mimetypes/mimetypes.pri b/src/corelib/mimetypes/mimetypes.pri
index 870b6c65a5..62bbe348e4 100644
--- a/src/corelib/mimetypes/mimetypes.pri
+++ b/src/corelib/mimetypes/mimetypes.pri
@@ -21,5 +21,5 @@ qtConfig(mimetype) {
mimetypes/qmimeglobpattern.cpp \
mimetypes/qmimeprovider.cpp
- RESOURCES += mimetypes/mimetypes.qrc
+ qtConfig(mimetype-database): RESOURCES += mimetypes/mimetypes.qrc
}
diff --git a/src/corelib/mimetypes/mimetypes.qrc b/src/corelib/mimetypes/mimetypes.qrc
index 19bc1d3e2a..4720bd302a 100644
--- a/src/corelib/mimetypes/mimetypes.qrc
+++ b/src/corelib/mimetypes/mimetypes.qrc
@@ -1,5 +1,5 @@
<RCC>
<qresource prefix="/qt-project.org/qmime/packages">
- <file alias="freedesktop.org.xml">mime/packages/freedesktop.org.xml</file>
+ <file alias="freedesktop.org.xml" compression-algorithm="best">mime/packages/freedesktop.org.xml</file>
</qresource>
</RCC>
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index bfe9be559a..24a7a35ea5 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -74,7 +74,6 @@ QMimeDatabasePrivate::QMimeDatabasePrivate()
QMimeDatabasePrivate::~QMimeDatabasePrivate()
{
- qDeleteAll(m_providers);
}
#ifdef QT_BUILD_INTERNAL
@@ -107,52 +106,52 @@ void QMimeDatabasePrivate::loadProviders()
mimeDirs.prepend(QLatin1String(":/qt-project.org/qmime"));
//qDebug() << "mime dirs:" << mimeDirs;
- QVector<QMimeProviderBase *> currentProviders = m_providers;
- m_providers.clear();
+ Providers currentProviders;
+ std::swap(m_providers, currentProviders);
m_providers.reserve(mimeDirs.size());
for (const QString &mimeDir : qAsConst(mimeDirs)) {
const QString cacheFile = mimeDir + QStringLiteral("/mime.cache");
QFileInfo fileInfo(cacheFile);
// Check if we already have a provider for this dir
- const auto it = std::find_if(currentProviders.begin(), currentProviders.end(), [mimeDir](QMimeProviderBase *prov) { return prov->directory() == mimeDir; });
+ const auto predicate = [mimeDir](const std::unique_ptr<QMimeProviderBase> &prov)
+ {
+ return prov && prov->directory() == mimeDir;
+ };
+ const auto it = std::find_if(currentProviders.begin(), currentProviders.end(), predicate);
if (it == currentProviders.end()) {
- QMimeProviderBase *provider = nullptr;
+ std::unique_ptr<QMimeProviderBase> provider;
#if defined(QT_USE_MMAP)
if (qEnvironmentVariableIsEmpty("QT_NO_MIME_CACHE") && fileInfo.exists()) {
- provider = new QMimeBinaryProvider(this, mimeDir);
+ provider.reset(new QMimeBinaryProvider(this, mimeDir));
//qDebug() << "Created binary provider for" << mimeDir;
if (!provider->isValid()) {
- delete provider;
- provider = nullptr;
+ provider.reset();
}
}
#endif
if (!provider) {
- provider = new QMimeXMLProvider(this, mimeDir);
+ provider.reset(new QMimeXMLProvider(this, mimeDir));
//qDebug() << "Created XML provider for" << mimeDir;
}
- m_providers.append(provider);
+ m_providers.push_back(std::move(provider));
} else {
- QMimeProviderBase *provider = *it;
- currentProviders.erase(it);
+ auto provider = std::move(*it); // take provider out of the vector
provider->ensureLoaded();
if (!provider->isValid()) {
- delete provider;
- provider = new QMimeXMLProvider(this, mimeDir);
+ provider.reset(new QMimeXMLProvider(this, mimeDir));
//qDebug() << "Created XML provider to replace binary provider for" << mimeDir;
}
- m_providers.append(provider);
+ m_providers.push_back(std::move(provider));
}
}
- qDeleteAll(currentProviders);
}
-QVector<QMimeProviderBase *> QMimeDatabasePrivate::providers()
+const QMimeDatabasePrivate::Providers &QMimeDatabasePrivate::providers()
{
#ifndef Q_OS_WASM // stub implementation always returns true
Q_ASSERT(!mutex.tryLock()); // caller should have locked mutex
#endif
- if (m_providers.isEmpty()) {
+ if (m_providers.empty()) {
loadProviders();
m_lastCheck.start();
} else {
@@ -164,8 +163,7 @@ QVector<QMimeProviderBase *> QMimeDatabasePrivate::providers()
QString QMimeDatabasePrivate::resolveAlias(const QString &nameOrAlias)
{
- const auto allProviders = providers();
- for (QMimeProviderBase *provider : allProviders) {
+ for (const auto &provider : providers()) {
const QString ret = provider->resolveAlias(nameOrAlias);
if (!ret.isEmpty())
return ret;
@@ -179,9 +177,8 @@ QString QMimeDatabasePrivate::resolveAlias(const QString &nameOrAlias)
*/
QMimeType QMimeDatabasePrivate::mimeTypeForName(const QString &nameOrAlias)
{
- const auto allProviders = providers();
const QString mimeName = resolveAlias(nameOrAlias);
- for (QMimeProviderBase *provider : allProviders) {
+ for (const auto &provider : providers()) {
const QMimeType mime = provider->mimeTypeForName(mimeName);
if (mime.isValid())
return mime;
@@ -205,8 +202,7 @@ QMimeGlobMatchResult QMimeDatabasePrivate::findByFileName(const QString &fileNam
{
QMimeGlobMatchResult result;
// TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly.
- const auto allProviders = providers();
- for (QMimeProviderBase *provider : allProviders)
+ for (const auto &provider : providers())
provider->addFileNameMatches(fileName, result);
return result;
}
@@ -227,8 +223,7 @@ void QMimeDatabasePrivate::loadGenericIcon(QMimeTypePrivate &mimePrivate)
QMutexLocker locker(&mutex);
if (mimePrivate.fromCache) {
mimePrivate.genericIconName.clear();
- const auto allProviders = providers();
- for (QMimeProviderBase *provider : allProviders) {
+ for (const auto &provider : providers()) {
provider->loadGenericIcon(mimePrivate);
if (!mimePrivate.genericIconName.isEmpty())
break;
@@ -241,8 +236,7 @@ void QMimeDatabasePrivate::loadIcon(QMimeTypePrivate &mimePrivate)
QMutexLocker locker(&mutex);
if (mimePrivate.fromCache) {
mimePrivate.iconName.clear();
- const auto allProviders = providers();
- for (QMimeProviderBase *provider : allProviders) {
+ for (const auto &provider : providers()) {
provider->loadIcon(mimePrivate);
if (!mimePrivate.iconName.isEmpty())
break;
@@ -276,8 +270,7 @@ QStringList QMimeDatabasePrivate::parents(const QString &mimeName)
{
Q_ASSERT(!mutex.tryLock());
QStringList result;
- const auto allProviders = providers();
- for (QMimeProviderBase *provider : allProviders)
+ for (const auto &provider : providers())
provider->addParents(mimeName, result);
if (result.isEmpty()) {
const QString parent = fallbackParent(mimeName);
@@ -291,8 +284,7 @@ QStringList QMimeDatabasePrivate::listAliases(const QString &mimeName)
{
QMutexLocker locker(&mutex);
QStringList result;
- const auto allProviders = providers();
- for (QMimeProviderBase *provider : allProviders)
+ for (const auto &provider : providers())
provider->addAliases(mimeName, result);
return result;
}
@@ -331,8 +323,7 @@ QMimeType QMimeDatabasePrivate::findByData(const QByteArray &data, int *accuracy
*accuracyPtr = 0;
QMimeType candidate;
- const auto allProviders = providers();
- for (QMimeProviderBase *provider : allProviders)
+ for (const auto &provider : providers())
provider->findByMagic(data, accuracyPtr, candidate);
if (candidate.isValid())
@@ -414,8 +405,7 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
QList<QMimeType> QMimeDatabasePrivate::allMimeTypes()
{
QList<QMimeType> result;
- const auto allProviders = providers();
- for (QMimeProviderBase *provider : allProviders)
+ for (const auto &provider : providers())
provider->addAllMimeTypes(result);
return result;
}
@@ -432,7 +422,7 @@ bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent)
toCheck.pop();
const auto parentList = parents(mimeName);
for (const QString &par : parentList)
- toCheck.push(par);
+ toCheck.push(resolveAlias(par));
}
return false;
}
diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h
index 1e605d9a24..d9cf446d44 100644
--- a/src/corelib/mimetypes/qmimedatabase_p.h
+++ b/src/corelib/mimetypes/qmimedatabase_p.h
@@ -63,6 +63,8 @@ QT_REQUIRE_CONFIG(mimetype);
#include <QtCore/qmutex.h>
#include <QtCore/qvector.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QIODevice;
@@ -72,7 +74,7 @@ class QMimeProviderBase;
class QMimeDatabasePrivate
{
public:
- Q_DISABLE_COPY(QMimeDatabasePrivate)
+ Q_DISABLE_COPY_MOVE(QMimeDatabasePrivate)
QMimeDatabasePrivate();
~QMimeDatabasePrivate();
@@ -102,11 +104,12 @@ public:
bool mimeInherits(const QString &mime, const QString &parent);
private:
- QVector<QMimeProviderBase *> providers();
+ using Providers = std::vector<std::unique_ptr<QMimeProviderBase>>;
+ const Providers &providers();
bool shouldCheck();
void loadProviders();
- mutable QVector<QMimeProviderBase *> m_providers;
+ mutable Providers m_providers;
QElapsedTimer m_lastCheck;
public:
diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp
index cd42b4da83..e353ba10cc 100644
--- a/src/corelib/mimetypes/qmimeglobpattern.cpp
+++ b/src/corelib/mimetypes/qmimeglobpattern.cpp
@@ -39,7 +39,7 @@
#include "qmimeglobpattern_p.h"
-#include <QRegExp>
+#include <QRegularExpression>
#include <QStringList>
#include <QDebug>
@@ -142,8 +142,8 @@ bool QMimeGlobPattern::matchFileName(const QString &inputFilename) const
return (m_pattern == filename);
// Other (quite rare) patterns, like "*.anim[1-9j]": use slow but correct method
- QRegExp rx(m_pattern, Qt::CaseSensitive, QRegExp::WildcardUnix);
- return rx.exactMatch(filename);
+ QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(m_pattern));
+ return rx.match(filename).hasMatch();
}
static bool isFastPattern(const QString &pattern)
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index aac51184a4..37c8e3b157 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -54,7 +54,9 @@
static void initResources()
{
+#if QT_CONFIG(mimetype_database)
Q_INIT_RESOURCE(mimetypes);
+#endif
}
QT_BEGIN_NAMESPACE
@@ -445,10 +447,10 @@ void QMimeBinaryProvider::addAllMimeTypes(QList<QMimeType> &result)
loadMimeTypeList();
if (result.isEmpty()) {
result.reserve(m_mimetypeNames.count());
- for (const QString &name : m_mimetypeNames)
+ for (const QString &name : qAsConst(m_mimetypeNames))
result.append(mimeTypeForNameUnchecked(name));
} else {
- for (const QString &name : m_mimetypeNames)
+ for (const QString &name : qAsConst(m_mimetypeNames))
if (std::find_if(result.constBegin(), result.constEnd(), [name](const QMimeType &mime) -> bool { return mime.name() == name; })
== result.constEnd())
result.append(mimeTypeForNameUnchecked(name));
diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h
index 875ff9e0eb..b6268210c0 100644
--- a/src/corelib/mimetypes/qmimeprovider_p.h
+++ b/src/corelib/mimetypes/qmimeprovider_p.h
@@ -97,17 +97,17 @@ public:
QMimeBinaryProvider(QMimeDatabasePrivate *db, const QString &directory);
virtual ~QMimeBinaryProvider();
- virtual bool isValid() override;
- virtual QMimeType mimeTypeForName(const QString &name) override;
+ bool isValid() override;
+ QMimeType mimeTypeForName(const QString &name) override;
void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
void addParents(const QString &mime, QStringList &result) override;
- virtual QString resolveAlias(const QString &name) override;
+ QString resolveAlias(const QString &name) override;
void addAliases(const QString &name, QStringList &result) override;
void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) override;
void addAllMimeTypes(QList<QMimeType> &result) override;
static void loadMimeTypePrivate(QMimeTypePrivate &);
- virtual void loadIcon(QMimeTypePrivate &) override;
- virtual void loadGenericIcon(QMimeTypePrivate &) override;
+ void loadIcon(QMimeTypePrivate &) override;
+ void loadGenericIcon(QMimeTypePrivate &) override;
void ensureLoaded() override;
private:
@@ -135,11 +135,11 @@ public:
QMimeXMLProvider(QMimeDatabasePrivate *db, const QString &directory);
~QMimeXMLProvider();
- virtual bool isValid() override;
- virtual QMimeType mimeTypeForName(const QString &name) override;
+ bool isValid() override;
+ QMimeType mimeTypeForName(const QString &name) override;
void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
void addParents(const QString &mime, QStringList &result) override;
- virtual QString resolveAlias(const QString &name) override;
+ QString resolveAlias(const QString &name) override;
void addAliases(const QString &name, QStringList &result) override;
void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) override;
void addAllMimeTypes(QList<QMimeType> &result) override;
diff --git a/src/corelib/mimetypes/qmimetypeparser_p.h b/src/corelib/mimetypes/qmimetypeparser_p.h
index 6e3f5fd556..d6a1444592 100644
--- a/src/corelib/mimetypes/qmimetypeparser_p.h
+++ b/src/corelib/mimetypes/qmimetypeparser_p.h
@@ -64,7 +64,7 @@ class QIODevice;
class QMimeTypeParserBase
{
- Q_DISABLE_COPY(QMimeTypeParserBase)
+ Q_DISABLE_COPY_MOVE(QMimeTypeParserBase)
public:
QMimeTypeParserBase() {}
diff --git a/src/corelib/platform/platform.pri b/src/corelib/platform/platform.pri
new file mode 100644
index 0000000000..1fe2db81b0
--- /dev/null
+++ b/src/corelib/platform/platform.pri
@@ -0,0 +1 @@
+wasm:include(wasm/wasm.pri)
diff --git a/src/corelib/platform/wasm/qstdweb.cpp b/src/corelib/platform/wasm/qstdweb.cpp
new file mode 100644
index 0000000000..198ce897ca
--- /dev/null
+++ b/src/corelib/platform/wasm/qstdweb.cpp
@@ -0,0 +1,236 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstdweb_p.h"
+
+#include <emscripten/bind.h>
+#include <cstdint>
+#include <iostream>
+
+QT_BEGIN_NAMESPACE
+
+namespace qstdweb {
+
+typedef double uint53_t; // see Number.MAX_SAFE_INTEGER
+
+ArrayBuffer::ArrayBuffer(const emscripten::val &arrayBuffer)
+ :m_arrayBuffer(arrayBuffer)
+{
+
+}
+
+uint32_t ArrayBuffer::byteLength() const
+{
+ if (m_arrayBuffer.isUndefined() || m_arrayBuffer.isNull())
+ return 0;
+
+ return m_arrayBuffer["byteLength"].as<uint32_t>();
+}
+
+Blob::Blob(const emscripten::val &blob)
+ :m_blob(blob)
+{
+
+}
+
+uint32_t Blob::size() const
+{
+ return m_blob["size"].as<uint32_t>();
+}
+
+File::File(const emscripten::val &file)
+:m_file(file)
+{
+
+}
+
+Blob File::slice(uint64_t begin, uint64_t end) const
+{
+ return Blob(m_file.call<emscripten::val>("slice", uint53_t(begin), uint53_t(end)));
+}
+
+std::string File::name() const
+{
+ return m_file["name"].as<std::string>();
+}
+
+uint64_t File::size() const
+{
+ return uint64_t(m_file["size"].as<uint53_t>());
+}
+
+FileList::FileList(const emscripten::val &fileList)
+ :m_fileList(fileList)
+{
+
+}
+
+int FileList::length() const
+{
+ return m_fileList["length"].as<int>();
+}
+
+File FileList::item(int index) const
+{
+ return File(m_fileList[index]);
+}
+
+File FileList::operator[](int index) const
+{
+ return item(index);
+}
+
+ArrayBuffer FileReader::result() const
+{
+ return ArrayBuffer(m_fileReader["result"]);
+}
+
+void FileReader::readAsArrayBuffer(const Blob &blob) const
+{
+ m_fileReader.call<void>("readAsArrayBuffer", blob.m_blob);
+}
+
+void FileReader::onLoad(const std::function<void ()> &onLoad)
+{
+ m_onLoad.reset(new EventCallback(m_fileReader, "load", onLoad));
+}
+
+void FileReader::onError(const std::function<void ()> &onError)
+{
+ m_onError.reset(new EventCallback(m_fileReader, "error", onError));
+}
+
+void FileReader::onAbort(const std::function<void ()> &onAbort)
+{
+ m_onAbort.reset(new EventCallback(m_fileReader, "abort", onAbort));
+}
+
+Uint8Array Uint8Array::heap()
+{
+ return Uint8Array(heap_());
+}
+
+Uint8Array::Uint8Array(const emscripten::val &uint8Array)
+: m_uint8Array(uint8Array)
+{
+
+}
+
+Uint8Array::Uint8Array(const ArrayBuffer &buffer)
+: m_uint8Array(Uint8Array::constructor_().new_(buffer.m_arrayBuffer))
+{
+
+}
+
+Uint8Array::Uint8Array(const ArrayBuffer &buffer, uint32_t offset, uint32_t length)
+: m_uint8Array(Uint8Array::constructor_().new_(buffer.m_arrayBuffer, offset, length))
+{
+
+}
+
+Uint8Array::Uint8Array(char *buffer, uint32_t size)
+:m_uint8Array(Uint8Array::constructor_().new_(Uint8Array::heap().buffer().m_arrayBuffer, uint32_t(buffer), size))
+{
+
+}
+
+ArrayBuffer Uint8Array::buffer() const
+{
+ return ArrayBuffer(m_uint8Array["buffer"]);
+}
+
+uint32_t Uint8Array::length() const
+{
+ return m_uint8Array["length"].as<uint32_t>();
+}
+
+void Uint8Array::set(const Uint8Array &source)
+{
+ m_uint8Array.call<void>("set", source.m_uint8Array); // copies source content
+}
+
+void Uint8Array::copyTo(char *destination) const
+{
+ Uint8Array(destination, length()).set(*this);
+}
+
+void Uint8Array::copy(char *destination, const Uint8Array &source)
+{
+ Uint8Array(destination, source.length()).set(source);
+}
+
+emscripten::val Uint8Array::heap_()
+{
+ return emscripten::val::module_property("HEAPU8");
+}
+
+emscripten::val Uint8Array::constructor_()
+{
+ return emscripten::val::global("Uint8Array");
+}
+
+// Registers a callback function for a named event on the given element. The event
+// name must be the name as returned by the Event.type property: e.g. "load", "error".
+EventCallback::EventCallback(emscripten::val element, const std::string &name, const std::function<void ()> &fn)
+:m_fn(fn)
+{
+ element.set(contextPropertyName(name).c_str(), emscripten::val(intptr_t(this)));
+ element.set((std::string("on") + name).c_str(), emscripten::val::module_property("qtStdWebEventCallbackActivate"));
+}
+
+void EventCallback::activate(emscripten::val event)
+{
+ emscripten::val target = event["target"];
+ std::string eventName = event["type"].as<std::string>();
+ EventCallback *that = reinterpret_cast<EventCallback *>(target[contextPropertyName(eventName).c_str()].as<intptr_t>());
+ that->m_fn();
+}
+
+std::string EventCallback::contextPropertyName(const std::string &eventName)
+{
+ return std::string("data-qtEventCallbackContext") + eventName;
+}
+
+EMSCRIPTEN_BINDINGS(qtStdwebCalback) {
+ emscripten::function("qtStdWebEventCallbackActivate", &EventCallback::activate);
+}
+
+} // namespace qstdweb
+
+QT_END_NAMESPACE
diff --git a/src/corelib/platform/wasm/qstdweb_p.h b/src/corelib/platform/wasm/qstdweb_p.h
new file mode 100644
index 0000000000..75c2ec34b1
--- /dev/null
+++ b/src/corelib/platform/wasm/qstdweb_p.h
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTDWEB_P_H
+#define QSTDWEB_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 <qglobal.h>
+#include <emscripten/val.h>
+#include <cstdint>
+#include <functional>
+
+QT_BEGIN_NAMESPACE
+
+namespace qstdweb {
+
+ // DOM API in C++, implemented using emscripten val.h and bind.h.
+ // This is private API and can be extened and changed as needed.
+
+ class ArrayBuffer;
+ class Blob;
+ class File;
+ class FileList;
+ class FileReader;
+ class Uint8Array;
+ class EventCallback;
+
+ class ArrayBuffer {
+ public:
+ explicit ArrayBuffer(const emscripten::val &arrayBuffer);
+ uint32_t byteLength() const;
+
+ private:
+ friend class Uint8Array;
+ emscripten::val m_arrayBuffer = emscripten::val::undefined();
+ };
+
+ class Blob {
+ public:
+ explicit Blob(const emscripten::val &blob);
+ uint32_t size() const;
+
+ private:
+ friend class FileReader;
+ emscripten::val m_blob = emscripten::val::undefined();
+ };
+
+ class File {
+ public:
+ File() = default;
+ explicit File(const emscripten::val &file);
+
+ Blob slice(uint64_t begin, uint64_t end) const;
+ std::string name() const;
+ uint64_t size() const;
+
+ private:
+ emscripten::val m_file = emscripten::val::undefined();
+ };
+
+ class FileList {
+ public:
+ FileList() = default;
+ explicit FileList(const emscripten::val &fileList);
+
+ int length() const;
+ File item(int index) const;
+ File operator[](int index) const;
+
+ private:
+ emscripten::val m_fileList = emscripten::val::undefined();
+ };
+
+ class FileReader {
+ public:
+ ArrayBuffer result() const;
+ void readAsArrayBuffer(const Blob &blob) const;
+
+ void onLoad(const std::function<void ()> &onLoad);
+ void onError(const std::function<void ()> &onError);
+ void onAbort(const std::function<void ()> &onAbort);
+
+ private:
+ emscripten::val m_fileReader = emscripten::val::global("FileReader").new_();
+ std::unique_ptr<EventCallback> m_onLoad;
+ std::unique_ptr<EventCallback> m_onError;
+ std::unique_ptr<EventCallback> m_onAbort;
+ };
+
+ class Uint8Array {
+ public:
+ static Uint8Array heap();
+ explicit Uint8Array(const emscripten::val &uint8Array);
+ explicit Uint8Array(const ArrayBuffer &buffer);
+ Uint8Array(const ArrayBuffer &buffer, uint32_t offset, uint32_t length);
+ Uint8Array(char *buffer, uint32_t size);
+
+ ArrayBuffer buffer() const;
+ uint32_t length() const;
+ void set(const Uint8Array &source);
+
+ void copyTo(char *destination) const;
+ static void copy(char *destination, const Uint8Array &source);
+ private:
+ static emscripten::val heap_();
+ static emscripten::val constructor_();
+ emscripten::val m_uint8Array = emscripten::val::undefined();
+ };
+
+ class EventCallback
+ {
+ public:
+ EventCallback(emscripten::val element, const std::string &name, const std::function<void ()> &fn);
+ static void activate(emscripten::val event);
+ private:
+ static std::string contextPropertyName(const std::string &eventName);
+ std::function<void ()> m_fn;
+ };
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/corelib/platform/wasm/wasm.pri b/src/corelib/platform/wasm/wasm.pri
new file mode 100644
index 0000000000..73447030fb
--- /dev/null
+++ b/src/corelib/platform/wasm/wasm.pri
@@ -0,0 +1,3 @@
+INCLUDEDIR += $$PWD
+HEADERS += $$PWD/qstdweb_p.h
+SOURCES += $$PWD/qstdweb.cpp
diff --git a/src/corelib/plugin/qfactoryinterface.h b/src/corelib/plugin/qfactoryinterface.h
index f306460690..3aec4ddd55 100644
--- a/src/corelib/plugin/qfactoryinterface.h
+++ b/src/corelib/plugin/qfactoryinterface.h
@@ -52,8 +52,9 @@ struct Q_CORE_EXPORT QFactoryInterface
virtual QStringList keys() const = 0;
};
-
+#ifndef Q_CLANG_QDOC
Q_DECLARE_INTERFACE(QFactoryInterface, "org.qt-project.Qt.QFactoryInterface")
+#endif
QT_END_NAMESPACE
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 29ef697fe8..0e32776c71 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -133,8 +133,8 @@ QT_BEGIN_NAMESPACE
The following code snippet loads a library, resolves the symbol
"mysymbol", and calls the function if everything succeeded. If
something goes wrong, e.g. the library file does not exist or the
- symbol is not defined, the function pointer will be 0 and won't be
- called.
+ symbol is not defined, the function pointer will be \nullptr and
+ won't be called.
\snippet code/src_corelib_plugin_qlibrary.cpp 0
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index 5aca22497a..676b5047d6 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -71,13 +72,27 @@ inline constexpr unsigned char qPluginArchRequirements()
}
typedef QObject *(*QtPluginInstanceFunction)();
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
typedef const char *(*QtPluginMetaDataFunction)();
+#else
+typedef QPair<const uchar *, size_t> (*QtPluginMetaDataFunction)();
+#endif
+
struct Q_CORE_EXPORT QStaticPlugin
{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+public:
+ constexpr QStaticPlugin(QtPluginInstanceFunction i, QtPluginMetaDataFunction m)
+ : instance(i), rawMetaData(m().first), rawMetaDataSize(m().second)
+ QtPluginInstanceFunction instance;
+private:
+ // ### Qt 6: revise, as this is not standard-layout
+ const void *rawMetaData;
+ qsizetype rawMetaDataSize
+#elif !defined(Q_QDOC)
// Note: This struct is initialized using an initializer list.
// As such, it cannot have any new constructors or variables.
-#ifndef Q_QDOC
QtPluginInstanceFunction instance;
QtPluginMetaDataFunction rawMetaData;
#else
@@ -148,6 +163,15 @@ void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
return plugin; \
}
+#elif QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+
+# define QT_MOC_EXPORT_PLUGIN(PLUGINCLASS, PLUGINCLASSNAME) \
+ Q_EXTERN_C Q_DECL_EXPORT \
+ auto qt_plugin_query_metadata() \
+ { return qMakePair<const void *, size_t>(qt_pluginMetaData, sizeof qt_pluginMetaData); } \
+ Q_EXTERN_C Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance() \
+ Q_PLUGIN_INSTANCE(PLUGINCLASS)
+
#else
# define QT_MOC_EXPORT_PLUGIN(PLUGINCLASS, PLUGINCLASSNAME) \
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp
index b113ca13ce..8bb5e1463a 100644
--- a/src/corelib/plugin/quuid.cpp
+++ b/src/corelib/plugin/quuid.cpp
@@ -112,7 +112,7 @@ static char *_q_uuidToHex(const QUuid &uuid, char *dst, QUuid::StringFormat mode
Parses the string representation of a UUID (with optional surrounding "{}")
by reading at most MaxStringUuidLength (38) characters from \a src, which
- may be \c nullptr. Stops at the first invalid character (which includes a
+ may be \nullptr. Stops at the first invalid character (which includes a
premature NUL).
Returns the successfully parsed QUuid, or a null QUuid in case of failure.
diff --git a/src/corelib/serialization/qcborarray.cpp b/src/corelib/serialization/qcborarray.cpp
index c56536cdb1..28ae40f3df 100644
--- a/src/corelib/serialization/qcborarray.cpp
+++ b/src/corelib/serialization/qcborarray.cpp
@@ -39,6 +39,7 @@
#include "qcborarray.h"
#include "qcborvalue_p.h"
+#include "qdatastream.h"
QT_BEGIN_NAMESPACE
@@ -1218,4 +1219,23 @@ QDebug operator<<(QDebug dbg, const QCborArray &a)
}
#endif
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &stream, const QCborArray &value)
+{
+ stream << value.toCborValue().toCbor();
+ return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, QCborArray &value)
+{
+ QByteArray buffer;
+ stream >> buffer;
+ QCborParserError parseError{};
+ value = QCborValue::fromCbor(buffer, &parseError).toArray();
+ if (parseError.error)
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return stream;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qcborarray.h b/src/corelib/serialization/qcborarray.h
index ed0f4912ba..e06544f245 100644
--- a/src/corelib/serialization/qcborarray.h
+++ b/src/corelib/serialization/qcborarray.h
@@ -47,6 +47,7 @@
QT_BEGIN_NAMESPACE
class QJsonArray;
+class QDataStream;
class QCborContainerPrivate;
class Q_CORE_EXPORT QCborArray
@@ -271,6 +272,7 @@ private:
void detach(qsizetype reserve = 0);
friend QCborValue;
+ friend QCborValueRef;
explicit QCborArray(QCborContainerPrivate &dd) noexcept;
QExplicitlySharedDataPointer<QCborContainerPrivate> d;
};
@@ -298,6 +300,11 @@ Q_CORE_EXPORT uint qHash(const QCborArray &array, uint seed = 0);
Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborArray &a);
#endif
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QCborArray &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QCborArray &);
+#endif
+
QT_END_NAMESPACE
#endif // QCBORARRAY_H
diff --git a/src/corelib/serialization/qcborcommon.h b/src/corelib/serialization/qcborcommon.h
index f8278f1649..3dfe50cd09 100644
--- a/src/corelib/serialization/qcborcommon.h
+++ b/src/corelib/serialization/qcborcommon.h
@@ -133,6 +133,11 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, QCborKnownTags tg);
Q_CORE_EXPORT QDebug operator<<(QDebug, QCborTag tg);
#endif
+#if !defined(QT_NO_DEBUG_STREAM)
+QDataStream &operator<<(QDataStream &ds, QCborSimpleType st);
+QDataStream &operator>>(QDataStream &ds, QCborSimpleType &st);
+#endif
+
inline uint qHash(QCborSimpleType tag, uint seed = 0)
{
return qHash(quint8(tag), seed);
diff --git a/src/corelib/serialization/qcbormap.cpp b/src/corelib/serialization/qcbormap.cpp
index 33f9249993..4b28ca4a2e 100644
--- a/src/corelib/serialization/qcbormap.cpp
+++ b/src/corelib/serialization/qcbormap.cpp
@@ -1763,4 +1763,23 @@ QDebug operator<<(QDebug dbg, const QCborMap &m)
}
#endif
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &stream, const QCborMap &value)
+{
+ stream << value.toCborValue().toCbor();
+ return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, QCborMap &value)
+{
+ QByteArray buffer;
+ stream >> buffer;
+ QCborParserError parseError{};
+ value = QCborValue::fromCbor(buffer, &parseError).toMap();
+ if (parseError.error)
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return stream;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qcbormap.h b/src/corelib/serialization/qcbormap.h
index 3eb2107691..4aea901eef 100644
--- a/src/corelib/serialization/qcbormap.h
+++ b/src/corelib/serialization/qcbormap.h
@@ -52,6 +52,7 @@ typedef QMap<QString, QVariant> QVariantMap;
template <class Key, class T> class QHash;
typedef QHash<QString, QVariant> QVariantHash;
class QJsonObject;
+class QDataStream;
class QCborContainerPrivate;
class Q_CORE_EXPORT QCborMap
@@ -117,6 +118,8 @@ public:
QCborValueRef item; // points to the value
friend class Iterator;
friend class QCborMap;
+ friend class QCborValue;
+ friend class QCborValueRef;
ConstIterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
public:
typedef std::random_access_iterator_tag iterator_category;
@@ -170,7 +173,7 @@ public:
: QCborMap()
{
detach(args.size());
- for (auto pair : args)
+ for (const auto &pair : args)
insert(pair.first, pair.second);
}
~QCborMap();
@@ -322,9 +325,10 @@ public:
QJsonObject toJsonObject() const;
private:
+ friend class QCborValue;
+ friend class QCborValueRef;
void detach(qsizetype reserve = 0);
- friend QCborValue;
explicit QCborMap(QCborContainerPrivate &dd) noexcept;
QExplicitlySharedDataPointer<QCborContainerPrivate> d;
};
@@ -352,6 +356,12 @@ Q_CORE_EXPORT uint qHash(const QCborMap &map, uint seed = 0);
Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborMap &m);
#endif
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QCborMap &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QCborMap &);
+#endif
+
+
QT_END_NAMESPACE
#endif // QCBORMAP_H
diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp
index d062cff067..20a7e14dde 100644
--- a/src/corelib/serialization/qcborstream.cpp
+++ b/src/corelib/serialization/qcborstream.cpp
@@ -44,6 +44,7 @@
#include <qbuffer.h>
#include <qdebug.h>
#include <qstack.h>
+#include <qdatastream.h>
QT_BEGIN_NAMESPACE
@@ -170,6 +171,21 @@ Q_CORE_EXPORT const char *qt_cbor_simpletype_id(QCborSimpleType st)
return nullptr;
}
+#if !defined(QT_NO_DATASTREAM)
+QDataStream &operator<<(QDataStream &ds, QCborSimpleType st)
+{
+ return ds << quint8(st);
+}
+
+QDataStream &operator>>(QDataStream &ds, QCborSimpleType &st)
+{
+ quint8 v;
+ ds >> v;
+ st = QCborSimpleType(v);
+ return ds;
+}
+#endif
+
#if !defined(QT_NO_DEBUG_STREAM)
QDebug operator<<(QDebug dbg, QCborSimpleType st)
{
diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp
index 80ef515fd2..288446878c 100644
--- a/src/corelib/serialization/qcborvalue.cpp
+++ b/src/corelib/serialization/qcborvalue.cpp
@@ -39,7 +39,7 @@
#include "qcborvalue.h"
#include "qcborvalue_p.h"
-
+#include "qdatastream.h"
#include "qcborarray.h"
#include "qcbormap.h"
#include "qcborstream.h"
@@ -108,7 +108,7 @@ QT_BEGIN_NAMESPACE
QCborValue can contain a value of "null", which is not of any specific type.
It resembles the C++ \c {std::nullptr_t} type, whose only possible value is
- \c nullptr. QCborValue has a constructor taking such a type and creates a
+ \nullptr. QCborValue has a constructor taking such a type and creates a
null QCborValue.
Null values are used to indicate that an optional value is not present. In
@@ -128,10 +128,11 @@ QT_BEGIN_NAMESPACE
Such values are completely valid and may appear in CBOR streams, unlike
JSON content and QJsonValue's undefined bit. But like QJsonValue's
- Undefined, it is returned by QCborArray::value() when out of range or
- QCborMap::operator[] when the key is not found in the container. It is not
- possible to tell such a case apart from the value of Undefined, so if that
- is required, check the QCborArray size and use the QCborMap iterator API.
+ Undefined, it is returned by a CBOR container's value() or read-only
+ operator[] for invalid look-ups (index out of range for QCborArray, or key
+ not found for QCborMap). It is not possible to tell such a case apart from
+ the value of Undefined, so if that is required, check the QCborArray size
+ and use the QCborMap iterator API.
\section1 Simple types
@@ -416,7 +417,7 @@ QT_BEGIN_NAMESPACE
using toSimpleType() as well as isSimpleType(st).
CBOR simple types are types that do not have any associated value, like
- C++'s \c{std::nullptr_t} type, whose only possible value is \c nullptr.
+ C++'s \c{std::nullptr_t} type, whose only possible value is \nullptr.
If \a st is \c{QCborSimpleType::Null}, the resulting QCborValue will be of
the \l{Type}{Null} type and similarly for \c{QCborSimpleType::Undefined}.
@@ -457,7 +458,7 @@ QT_BEGIN_NAMESPACE
\fn QCborValue::QCborValue(QCborValue &&other)
\overload
- Moves the contents of the \a other CBorValue object into this one and frees
+ Moves the contents of the \a other QCborValue object into this one and frees
the resources of this one.
*/
@@ -465,7 +466,7 @@ QT_BEGIN_NAMESPACE
\fn QCborValue &&QCborValue::operator=(QCborValue &&other)
\overload
- Moves the contents of the \a other CBorValue object into this one and frees
+ Moves the contents of the \a other QCborValue object into this one and frees
the resources of this one. Returns a reference to this object.
*/
@@ -1986,12 +1987,24 @@ QUuid QCborValue::toUuid(const QUuid &defaultValue) const
return QUuid::fromRfc4122(byteData->asByteArrayView());
}
-QCborArray QCborValue::toArray() const
-{
- return toArray(QCborArray());
-}
+/*!
+ \fn QCborArray QCborValue::toArray() const
+ \fn QCborArray QCborValue::toArray(const QCborArray &defaultValue) const
+
+ Returns the array value stored in this QCborValue, if it is of the array
+ type. Otherwise, it returns \a defaultValue.
+
+ Note that this function performs no conversion from other types to
+ QCborArray.
+
+ \sa isArray(), isByteArray(), isMap(), isContainer(), toMap()
+ */
/*!
+ \fn QCborArray QCborValueRef::toArray() const
+ \fn QCborArray QCborValueRef::toArray(const QCborArray &defaultValue) const
+ \internal
+
Returns the array value stored in this QCborValue, if it is of the array
type. Otherwise, it returns \a defaultValue.
@@ -2000,6 +2013,11 @@ QCborArray QCborValue::toArray() const
\sa isArray(), isByteArray(), isMap(), isContainer(), toMap()
*/
+QCborArray QCborValue::toArray() const
+{
+ return toArray(QCborArray());
+}
+
QCborArray QCborValue::toArray(const QCborArray &defaultValue) const
{
if (!isArray())
@@ -2011,12 +2029,24 @@ QCborArray QCborValue::toArray(const QCborArray &defaultValue) const
return dd ? QCborArray(*dd) : defaultValue;
}
-QCborMap QCborValue::toMap() const
-{
- return toMap(QCborMap());
-}
+/*!
+ \fn QCborMap QCborValue::toMap() const
+ \fn QCborMap QCborValue::toMap(const QCborMap &defaultValue) const
+
+ Returns the map value stored in this QCborValue, if it is of the map type.
+ Otherwise, it returns \a defaultValue.
+
+ Note that this function performs no conversion from other types to
+ QCborMap.
+
+ \sa isMap(), isArray(), isContainer(), toArray()
+ */
/*!
+ \fn QCborMap QCborValueRef::toMap() const
+ \fn QCborMap QCborValueRef::toMap(const QCborMap &defaultValue) const
+ \internal
+
Returns the map value stored in this QCborValue, if it is of the map type.
Otherwise, it returns \a defaultValue.
@@ -2025,6 +2055,11 @@ QCborMap QCborValue::toMap() const
\sa isMap(), isArray(), isContainer(), toArray()
*/
+QCborMap QCborValue::toMap() const
+{
+ return toMap(QCborMap());
+}
+
QCborMap QCborValue::toMap(const QCborMap &defaultValue) const
{
if (!isMap())
@@ -2077,15 +2112,16 @@ const QCborValue QCborValue::operator[](QLatin1String key) const
}
/*!
+ \overload
+
If this QCborValue is a QCborMap, searches elements for the value whose key
- matches \a key. If this is an array, returns the element whose index is \a
- key. If there's no matching value in the array or map, or if this
+ matches \a key. If this is a QCborArray, returns the element whose index is
+ \a key. If there's no matching value in the array or map, or if this
QCborValue object is not an array or map, returns the undefined value.
\sa operator[], QCborMap::operator[], QCborMap::value(),
QCborMap::find(), QCborArray::operator[], QCborArray::at()
*/
-
const QCborValue QCborValue::operator[](qint64 key) const
{
if (isMap())
@@ -2096,6 +2132,191 @@ const QCborValue QCborValue::operator[](qint64 key) const
}
/*!
+ \internal
+ */
+static Q_DECL_COLD_FUNCTION QCborMap arrayAsMap(const QCborArray &array)
+{
+ if (array.size())
+ qWarning("Using CBOR array as map forced conversion");
+ QCborMap map;
+ for (qsizetype i = array.size(); i-- > 0; ) {
+ QCborValue entry = array.at(i);
+ // Ignore padding entries that may have been added to grow the array
+ // when inserting past its end:
+ if (!entry.isInvalid())
+ map[i] = entry;
+ }
+ return map;
+}
+
+/*!
+ \internal
+ */
+static QCborContainerPrivate *maybeDetach(QCborContainerPrivate *container, qsizetype size)
+{
+ auto replace = QCborContainerPrivate::detach(container, size);
+ Q_ASSERT(replace);
+ if (replace != container) {
+ if (container)
+ container->deref();
+ replace->ref.ref();
+ }
+ return replace;
+}
+
+/*!
+ \internal
+ */
+static QCborContainerPrivate *maybeGrow(QCborContainerPrivate *container, qsizetype index)
+{
+ auto replace = QCborContainerPrivate::grow(container, index);
+ Q_ASSERT(replace);
+ if (replace != container) {
+ if (container)
+ container->deref();
+ replace->ref.ref();
+ }
+ if (replace->elements.size() == index)
+ replace->append(Undefined());
+ else
+ Q_ASSERT(replace->elements.size() > index);
+ return replace;
+}
+
+/*!
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map, with the given \a key. When this QCborValue is a QCborMap,
+ this function is equivalent to the matching operator[] on that map.
+
+ Before returning the reference: if this QCborValue was an array, it is first
+ converted to a map (so that \c{map[i]} is \c{array[i]} for each index, \c i,
+ with valid \c{array[i]}); otherwise, if it was not a map it will be
+ over-written with an empty map.
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+QCborValueRef QCborValue::operator[](const QString &key)
+{
+ if (!isMap())
+ *this = QCborValue(isArray() ? arrayAsMap(toArray()) : QCborMap());
+
+ const qsizetype size = container ? container->elements.size() : 0;
+ qsizetype index = size + 1;
+ bool found = false;
+ if (container) {
+ QCborMap proxy(*container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ container = maybeDetach(container, size + (found ? 0 : 2));
+ Q_ASSERT(container);
+ if (!found) {
+ container->append(key);
+ container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(container->elements.size() & 1));
+ Q_ASSERT(index < container->elements.size());
+ return { container, index };
+}
+
+/*!
+ \overload
+
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map, with the given \a key. When this QCborValue is a QCborMap,
+ this function is equivalent to the matching operator[] on that map.
+
+ Before returning the reference: if this QCborValue was an array, it is first
+ converted to a map (so that \c{map[i]} is \c{array[i]} for each index, \c i,
+ with valid \c{array[i]}); otherwise, if it was not a map it will be
+ over-written with an empty map.
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+QCborValueRef QCborValue::operator[](QLatin1String key)
+{
+ if (!isMap())
+ *this = QCborValue(isArray() ? arrayAsMap(toArray()) : QCborMap());
+
+ const qsizetype size = container ? container->elements.size() : 0;
+ qsizetype index = size + 1;
+ bool found = false;
+ if (container) {
+ QCborMap proxy(*container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ container = maybeDetach(container, size + (found ? 0 : 2));
+ Q_ASSERT(container);
+ if (!found) {
+ container->append(key);
+ container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(container->elements.size() & 1));
+ Q_ASSERT(index < container->elements.size());
+ return { container, index };
+}
+
+/*!
+ \overload
+
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map or array, with the given \a key. When this QCborValue is a
+ QCborMap or, for 0 <= key < 0x10000, a QCborArray, this function is
+ equivalent to the matching operator[] on that map or array.
+
+ Before returning the reference: if this QCborValue was an array but the key
+ is out of range, the array is first converted to a map (so that \c{map[i]}
+ is \c{array[i]} for each index, \c i, with valid \c{array[i]}); otherwise,
+ if it was not a map it will be over-written with an empty map.
+
+ \sa operator[], QCborMap::operator[], QCborMap::value(),
+ QCborMap::find(), QCborArray::operator[], QCborArray::at()
+ */
+QCborValueRef QCborValue::operator[](qint64 key)
+{
+ if (isArray() && key >= 0 && key < 0x10000) {
+ container = maybeGrow(container, key);
+ return { container, qsizetype(key) };
+ }
+ if (!isMap())
+ *this = QCborValue(isArray() ? arrayAsMap(toArray()) : QCborMap());
+
+ const qsizetype size = container ? container->elements.size() : 0;
+ Q_ASSERT(!(size & 1));
+ qsizetype index = size + 1;
+ bool found = false;
+ if (container) {
+ QCborMap proxy(*container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ container = maybeDetach(container, size + (found ? 0 : 2));
+ Q_ASSERT(container);
+ if (!found) {
+ container->append(key);
+ container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(container->elements.size() & 1));
+ Q_ASSERT(index < container->elements.size());
+ return { container, index };
+}
+
+/*!
Decodes one item from the CBOR stream found in \a reader and returns the
equivalent representation. This function is recursive: if the item is a map
or array, it will decode all items found in that map or array, until the
@@ -2359,6 +2580,255 @@ QCborValue::Type QCborValueRef::concreteType(QCborValueRef self) noexcept
return self.d->elements.at(self.i).type;
}
+/*!
+ If this QCborValueRef refers to a QCborMap, searches elements for the value
+ whose key matches \a key. If there's no key matching \a key in the map or if
+ this QCborValueRef object is not a map, returns the undefined value.
+
+ This function is equivalent to:
+
+ \code
+ value.toMap().value(key);
+ \endcode
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+const QCborValue QCborValueRef::operator[](const QString &key) const
+{
+ const QCborValue item = d->valueAt(i);
+ return item[key];
+}
+
+/*!
+ \overload
+
+ If this QCborValueRef refers to a QCborMap, searches elements for the value
+ whose key matches \a key. If there's no key matching \a key in the map or if
+ this QCborValueRef object is not a map, returns the undefined value.
+
+ This function is equivalent to:
+
+ \code
+ value.toMap().value(key);
+ \endcode
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+const QCborValue QCborValueRef::operator[](QLatin1String key) const
+{
+ const QCborValue item = d->valueAt(i);
+ return item[key];
+}
+
+/*!
+ \overload
+
+ If this QCborValueRef refers to a QCborMap, searches elements for the value
+ whose key matches \a key. If this is a QCborArray, returns the element whose
+ index is \a key. If there's no matching value in the array or map, or if
+ this QCborValueRef object is not an array or map, returns the undefined
+ value.
+
+ \sa operator[], QCborMap::operator[], QCborMap::value(),
+ QCborMap::find(), QCborArray::operator[], QCborArray::at()
+ */
+const QCborValue QCborValueRef::operator[](qint64 key) const
+{
+ const QCborValue item = d->valueAt(i);
+ return item[key];
+}
+
+/*!
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map, with the given \a key. When this QCborValueRef refers to a
+ QCborMap, this function is equivalent to the matching operator[] on that
+ map.
+
+ Before returning the reference: if the QCborValue referenced was an array,
+ it is first converted to a map (so that \c{map[i]} is \c{array[i]} for each
+ index, \c i, with valid \c{array[i]}); otherwise, if it was not a map it
+ will be over-written with an empty map.
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+QCborValueRef QCborValueRef::operator[](const QString &key)
+{
+ auto &e = d->elements[i];
+ qsizetype size = 0;
+ if (e.flags & QtCbor::Element::IsContainer) {
+ if (e.container) {
+ if (e.type == QCborValue::Array) {
+ QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container)));
+ qSwap(e.container, repack.container);
+ } else if (e.type != QCborValue::Map) {
+ e.container->deref();
+ e.container = nullptr;
+ }
+ }
+ e.type = QCborValue::Map;
+ if (e.container)
+ size = e.container->elements.size();
+ } else {
+ // Stomp any prior e.value, replace with a map (that we'll grow)
+ e.container = nullptr;
+ e.type = QCborValue::Map;
+ e.flags = QtCbor::Element::IsContainer;
+ }
+
+ qsizetype index = size + 1;
+ bool found = false;
+ if (e.container) {
+ QCborMap proxy(*e.container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ e.container = maybeDetach(e.container, size + (found ? 0 : 2));
+ Q_ASSERT(e.container);
+ if (!found) {
+ e.container->append(key);
+ e.container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(e.container->elements.size() & 1));
+ Q_ASSERT(index < e.container->elements.size());
+ return { e.container, index };
+}
+
+/*!
+ \overload
+
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map, with the given \a key. When this QCborValue is a QCborMap,
+ this function is equivalent to the matching operator[] on that map.
+
+ Before returning the reference: if the QCborValue referenced was an array,
+ it is first converted to a map (so that \c{map[i]} is \c{array[i]} for each
+ index, \c i, with valid \c{array[i]}); otherwise, if it was not a map it
+ will be over-written with an empty map.
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+QCborValueRef QCborValueRef::operator[](QLatin1String key)
+{
+ auto &e = d->elements[i];
+ qsizetype size = 0;
+ if (e.flags & QtCbor::Element::IsContainer) {
+ if (e.container) {
+ if (e.type == QCborValue::Array) {
+ QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container)));
+ qSwap(e.container, repack.container);
+ } else if (e.type != QCborValue::Map) {
+ e.container->deref();
+ e.container = nullptr;
+ }
+ }
+ e.type = QCborValue::Map;
+ if (e.container)
+ size = e.container->elements.size();
+ } else {
+ // Stomp any prior e.value, replace with a map (that we'll grow)
+ e.container = nullptr;
+ e.type = QCborValue::Map;
+ e.flags = QtCbor::Element::IsContainer;
+ }
+
+ qsizetype index = size + 1;
+ bool found = false;
+ if (e.container) {
+ QCborMap proxy(*e.container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ e.container = maybeDetach(e.container, size + (found ? 0 : 2));
+ Q_ASSERT(e.container);
+ if (!found) {
+ e.container->append(key);
+ e.container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(e.container->elements.size() & 1));
+ Q_ASSERT(index < e.container->elements.size());
+ return { e.container, index };
+}
+
+/*!
+ \overload
+
+ Returns a QCborValueRef that can be used to read or modify the entry in
+ this, as a map or array, with the given \a key. When this QCborValue is a
+ QCborMap or, for 0 <= key < 0x10000, a QCborArray, this function is
+ equivalent to the matching operator[] on that map or array.
+
+ Before returning the reference: if the QCborValue referenced was an array
+ but the key is out of range, the array is first converted to a map (so that
+ \c{map[i]} is \c{array[i]} for each index, \c i, with valid \c{array[i]});
+ otherwise, if it was not a map it will be over-written with an empty map.
+
+ \sa operator[], QCborMap::operator[], QCborMap::value(),
+ QCborMap::find(), QCborArray::operator[], QCborArray::at()
+ */
+QCborValueRef QCborValueRef::operator[](qint64 key)
+{
+ auto &e = d->elements[i];
+ if (e.type == QCborValue::Array && key >= 0 && key < 0x10000) {
+ e.container = maybeGrow(e.container, key);
+ return { e.container, qsizetype(key) };
+ }
+ qsizetype size = 0;
+ if (e.flags & QtCbor::Element::IsContainer) {
+ if (e.container) {
+ if (e.type == QCborValue::Array) {
+ QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container)));
+ qSwap(e.container, repack.container);
+ } else if (e.type != QCborValue::Map) {
+ e.container->deref();
+ e.container = nullptr;
+ }
+ }
+ e.type = QCborValue::Map;
+ if (e.container)
+ size = e.container->elements.size();
+ } else {
+ // Stomp any prior e.value, replace with a map (that we'll grow)
+ e.container = nullptr;
+ e.type = QCborValue::Map;
+ e.flags = QtCbor::Element::IsContainer;
+ }
+ Q_ASSERT(!(size & 1));
+
+ qsizetype index = size + 1;
+ bool found = false;
+ if (e.container) {
+ QCborMap proxy(*e.container);
+ auto it = proxy.constFind(key);
+ if (it < proxy.constEnd()) {
+ found = true;
+ index = it.item.i;
+ }
+ }
+
+ e.container = maybeDetach(e.container, size + (found ? 0 : 2));
+ Q_ASSERT(e.container);
+ if (!found) {
+ e.container->append(key);
+ e.container->append(QCborValue());
+ }
+ Q_ASSERT(index & 1 && !(e.container->elements.size() & 1));
+ Q_ASSERT(index < e.container->elements.size());
+ return { e.container, index };
+}
+
+
inline QCborArray::QCborArray(QCborContainerPrivate &dd) noexcept
: d(&dd)
{
@@ -2481,6 +2951,26 @@ QDebug operator<<(QDebug dbg, const QCborValue &v)
}
#endif
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &stream, const QCborValue &value)
+{
+ stream << QCborValue(value).toCbor();
+ return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, QCborValue &value)
+{
+ QByteArray buffer;
+ stream >> buffer;
+ QCborParserError parseError{};
+ value = QCborValue::fromCbor(buffer, &parseError);
+ if (parseError.error)
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return stream;
+}
+#endif
+
+
QT_END_NAMESPACE
#include "qcborarray.cpp"
diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h
index d6ba4e88d8..f542e44c47 100644
--- a/src/corelib/serialization/qcborvalue.h
+++ b/src/corelib/serialization/qcborvalue.h
@@ -69,6 +69,7 @@ class QCborArray;
class QCborMap;
class QCborStreamReader;
class QCborStreamWriter;
+class QDataStream;
struct QCborParserError
{
@@ -78,6 +79,7 @@ struct QCborParserError
QString errorString() const { return error.toString(); }
};
+class QCborValueRef;
class QCborContainerPrivate;
class Q_CORE_EXPORT QCborValue
{
@@ -242,20 +244,18 @@ public:
#endif
QUuid toUuid(const QUuid &defaultValue = {}) const;
-#ifdef Q_QDOC
- QCborArray toArray(const QCborArray &a = {}) const;
- QCborMap toMap(const QCborMap &m = {}) const;
-#else
// only forward-declared, need split functions
QCborArray toArray() const;
QCborArray toArray(const QCborArray &defaultValue) const;
QCborMap toMap() const;
QCborMap toMap(const QCborMap &defaultValue) const;
-#endif
const QCborValue operator[](const QString &key) const;
const QCborValue operator[](QLatin1String key) const;
const QCborValue operator[](qint64 key) const;
+ QCborValueRef operator[](qint64 key);
+ QCborValueRef operator[](QLatin1String key);
+ QCborValueRef operator[](const QString & key);
int compare(const QCborValue &other) const;
#if 0 && QT_HAS_INCLUDE(<compare>)
@@ -393,16 +393,18 @@ public:
QUuid toUuid(const QUuid &defaultValue = {}) const
{ return concrete().toUuid(defaultValue); }
-#ifdef Q_QDOC
- QCborArray toArray(const QCborArray &a = {}) const;
- QCborMap toMap(const QCborMap &m = {}) const;
-#else
// only forward-declared, need split functions. Implemented in qcbor{array,map}.h
QCborArray toArray() const;
QCborArray toArray(const QCborArray &a) const;
QCborMap toMap() const;
QCborMap toMap(const QCborMap &m) const;
-#endif
+
+ const QCborValue operator[](const QString &key) const;
+ const QCborValue operator[](QLatin1String key) const;
+ const QCborValue operator[](qint64 key) const;
+ QCborValueRef operator[](qint64 key);
+ QCborValueRef operator[](QLatin1String key);
+ QCborValueRef operator[](const QString & key);
int compare(const QCborValue &other) const
{ return concrete().compare(other); }
@@ -434,6 +436,7 @@ public:
{ return concrete().toDiagnosticNotation(opt); }
private:
+ friend class QCborValue;
friend class QCborArray;
friend class QCborMap;
friend class QCborContainerPrivate;
@@ -465,6 +468,11 @@ Q_CORE_EXPORT uint qHash(const QCborValue &value, uint seed = 0);
Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborValue &v);
#endif
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QCborValue &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QCborValue &);
+#endif
+
QT_END_NAMESPACE
#if defined(QT_X11_DEFINES_FOUND)
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp
index 951f6c9736..ead6ed5083 100644
--- a/src/corelib/serialization/qdatastream.cpp
+++ b/src/corelib/serialization/qdatastream.cpp
@@ -368,7 +368,7 @@ QDataStream::~QDataStream()
/*!
\fn QIODevice *QDataStream::device() const
- Returns the I/O device currently set, or 0 if no
+ Returns the I/O device currently set, or \nullptr if no
device is currently set.
\sa setDevice()
@@ -377,7 +377,7 @@ QDataStream::~QDataStream()
/*!
void QDataStream::setDevice(QIODevice *d)
- Sets the I/O device to \a d, which can be 0
+ Sets the I/O device to \a d, which can be \nullptr
to unset to current I/O device.
\sa device()
@@ -392,17 +392,18 @@ void QDataStream::setDevice(QIODevice *d)
dev = d;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
Unsets the I/O device.
- Use setDevice(0) instead.
+ Use setDevice(nullptr) instead.
*/
void QDataStream::unsetDevice()
{
- setDevice(0);
+ setDevice(nullptr);
}
-
+#endif
/*!
\fn bool QDataStream::atEnd() const
@@ -559,6 +560,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_10 Same as Qt_5_6
\value Qt_5_11 Same as Qt_5_6
\value Qt_5_12 Version 18 (Qt 5.12)
+ \value Qt_5_13 Version 19 (Qt 5.13)
\omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h
index eae0146553..81134f74b0 100644
--- a/src/corelib/serialization/qdatastream.h
+++ b/src/corelib/serialization/qdatastream.h
@@ -99,10 +99,11 @@ public:
Qt_5_10 = Qt_5_9,
Qt_5_11 = Qt_5_10,
Qt_5_12 = 18,
-#if QT_VERSION >= 0x050d00
+ Qt_5_13 = 19,
+#if QT_VERSION >= 0x050e00
#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif
- Qt_DefaultCompiledVersion = Qt_5_12
+ Qt_DefaultCompiledVersion = Qt_5_13
};
enum ByteOrder {
@@ -130,7 +131,10 @@ public:
QIODevice *device() const;
void setDevice(QIODevice *);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QDataStream::setDevice(nullptr) instead")
void unsetDevice();
+#endif
bool atEnd() const;
diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h
index feba1faac6..40b2414e4a 100644
--- a/src/corelib/serialization/qjson_p.h
+++ b/src/corelib/serialization/qjson_p.h
@@ -746,7 +746,7 @@ public:
bool valid() const;
private:
- Q_DISABLE_COPY(Data)
+ Q_DISABLE_COPY_MOVE(Data)
};
}
diff --git a/src/corelib/serialization/qjsonarray.cpp b/src/corelib/serialization/qjsonarray.cpp
index 1187bb03a3..7dfa9b43f0 100644
--- a/src/corelib/serialization/qjsonarray.cpp
+++ b/src/corelib/serialization/qjsonarray.cpp
@@ -675,6 +675,14 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
\sa begin(), constEnd()
*/
+/*! \fn QJsonArray::const_iterator QJsonArray::cbegin() const
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
+ in the array.
+
+ \sa begin(), cend()
+*/
+
/*! \fn QJsonArray::iterator QJsonArray::end()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item
@@ -696,6 +704,14 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
\sa constBegin(), end()
*/
+/*! \fn QJsonArray::const_iterator QJsonArray::cend() const
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
+ item after the last item in the array.
+
+ \sa cbegin(), end()
+*/
+
/*! \fn void QJsonArray::push_back(const QJsonValue &value)
This function is provided for STL compatibility. It is equivalent
@@ -1259,5 +1275,22 @@ QDebug operator<<(QDebug dbg, const QJsonArray &a)
}
#endif
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &stream, const QJsonArray &array)
+{
+ QJsonDocument doc{array};
+ stream << doc.toJson(QJsonDocument::Compact);
+ return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, QJsonArray &array)
+{
+ QJsonDocument doc;
+ stream >> doc;
+ array = doc.array();
+ return stream;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qjsonarray.h b/src/corelib/serialization/qjsonarray.h
index 5dff4a0aa9..ba346fb848 100644
--- a/src/corelib/serialization/qjsonarray.h
+++ b/src/corelib/serialization/qjsonarray.h
@@ -214,9 +214,11 @@ public:
inline iterator begin() { detach2(); return iterator(this, 0); }
inline const_iterator begin() const { return const_iterator(this, 0); }
inline const_iterator constBegin() const { return const_iterator(this, 0); }
+ inline const_iterator cbegin() const { return const_iterator(this, 0); }
inline iterator end() { detach2(); return iterator(this, size()); }
inline const_iterator end() const { return const_iterator(this, size()); }
inline const_iterator constEnd() const { return const_iterator(this, size()); }
+ inline const_iterator cend() const { return const_iterator(this, size()); }
iterator insert(iterator before, const QJsonValue &value) { insert(before.i, value); return before; }
iterator erase(iterator it) { removeAt(it.i); return it; }
@@ -271,6 +273,11 @@ Q_CORE_EXPORT uint qHash(const QJsonArray &array, uint seed = 0);
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &);
#endif
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QJsonArray &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QJsonArray &);
+#endif
+
QT_END_NAMESPACE
#endif // QJSONARRAY_H
diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp
index 4f756df97c..dc5f384108 100644
--- a/src/corelib/serialization/qjsoncbor.cpp
+++ b/src/corelib/serialization/qjsoncbor.cpp
@@ -824,7 +824,7 @@ QCborArray QCborArray::fromJsonArray(const QJsonArray &array)
{
QCborArray a;
a.detach(array.size());
- for (const QJsonValue v : array) {
+ for (const QJsonValue &v : array) {
if (v.isString())
a.d->append(v.toString());
else
diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp
index 0cd86d3ded..179a87c699 100644
--- a/src/corelib/serialization/qjsondocument.cpp
+++ b/src/corelib/serialization/qjsondocument.cpp
@@ -47,6 +47,7 @@
#include "qjsonwriter_p.h"
#include "qjsonparser_p.h"
#include "qjson_p.h"
+#include "qdatastream.h"
QT_BEGIN_NAMESPACE
@@ -657,4 +658,23 @@ QDebug operator<<(QDebug dbg, const QJsonDocument &o)
}
#endif
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &stream, const QJsonDocument &doc)
+{
+ stream << doc.toJson(QJsonDocument::Compact);
+ return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, QJsonDocument &doc)
+{
+ QByteArray buffer;
+ stream >> buffer;
+ QJsonParseError parseError{};
+ doc = QJsonDocument::fromJson(buffer, &parseError);
+ if (parseError.error && !buffer.isEmpty())
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return stream;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qjsondocument.h b/src/corelib/serialization/qjsondocument.h
index b784890c54..a749439b7d 100644
--- a/src/corelib/serialization/qjsondocument.h
+++ b/src/corelib/serialization/qjsondocument.h
@@ -172,6 +172,11 @@ Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonDocument)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonDocument &);
#endif
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QJsonDocument &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QJsonDocument &);
+#endif
+
QT_END_NAMESPACE
#endif // QJSONDOCUMENT_H
diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp
index 950bec535b..a9f25a119c 100644
--- a/src/corelib/serialization/qjsonobject.cpp
+++ b/src/corelib/serialization/qjsonobject.cpp
@@ -1320,4 +1320,21 @@ QDebug operator<<(QDebug dbg, const QJsonObject &o)
}
#endif
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &stream, const QJsonObject &object)
+{
+ QJsonDocument doc{object};
+ stream << doc.toJson(QJsonDocument::Compact);
+ return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, QJsonObject &object)
+{
+ QJsonDocument doc;
+ stream >> doc;
+ object = doc.object();
+ return stream;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h
index be42d3747a..80fe6b2f3f 100644
--- a/src/corelib/serialization/qjsonobject.h
+++ b/src/corelib/serialization/qjsonobject.h
@@ -268,6 +268,11 @@ Q_CORE_EXPORT uint qHash(const QJsonObject &object, uint seed = 0);
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
#endif
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QJsonObject &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QJsonObject &);
+#endif
+
QT_END_NAMESPACE
#endif // QJSONOBJECT_H
diff --git a/src/corelib/serialization/qjsonvalue.cpp b/src/corelib/serialization/qjsonvalue.cpp
index 2c04da4885..1fc610d7c7 100644
--- a/src/corelib/serialization/qjsonvalue.cpp
+++ b/src/corelib/serialization/qjsonvalue.cpp
@@ -45,6 +45,7 @@
#include <qvariant.h>
#include <qstringlist.h>
#include <qdebug.h>
+#include "qdatastream.h"
#ifndef QT_BOOTSTRAPPED
# include <qcborarray.h>
@@ -933,4 +934,78 @@ QDebug operator<<(QDebug dbg, const QJsonValue &o)
}
#endif
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &stream, const QJsonValue &v)
+{
+ quint8 type = v.t;
+ stream << type;
+ switch (type) {
+ case QJsonValue::Undefined:
+ case QJsonValue::Null:
+ break;
+ case QJsonValue::Bool:
+ stream << v.toBool();
+ break;
+ case QJsonValue::Double:
+ stream << v.toDouble();
+ break;
+ case QJsonValue::String:
+ stream << v.toString();
+ break;
+ case QJsonValue::Array:
+ stream << v.toArray();
+ break;
+ case QJsonValue::Object:
+ stream << v.toObject();
+ break;
+ }
+ return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, QJsonValue &v)
+{
+ quint8 type;
+ stream >> type;
+ switch (type) {
+ case QJsonValue::Undefined:
+ case QJsonValue::Null:
+ v = QJsonValue{QJsonValue::Type(type)};
+ break;
+ case QJsonValue::Bool: {
+ bool b;
+ stream >> b;
+ v = QJsonValue(b);
+ break;
+ } case QJsonValue::Double: {
+ double d;
+ stream >> d;
+ v = QJsonValue{d};
+ break;
+ } case QJsonValue::String: {
+ QString s;
+ stream >> s;
+ v = QJsonValue{s};
+ break;
+ }
+ case QJsonValue::Array: {
+ QJsonArray a;
+ stream >> a;
+ v = QJsonValue{a};
+ break;
+ }
+ case QJsonValue::Object: {
+ QJsonObject o;
+ stream >> o;
+ v = QJsonValue{o};
+ break;
+ }
+ default: {
+ stream.setStatus(QDataStream::ReadCorruptData);
+ v = QJsonValue{QJsonValue::Undefined};
+ }
+ }
+ return stream;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qjsonvalue.h b/src/corelib/serialization/qjsonvalue.h
index d8e121524d..0339eb59f7 100644
--- a/src/corelib/serialization/qjsonvalue.h
+++ b/src/corelib/serialization/qjsonvalue.h
@@ -152,6 +152,7 @@ private:
friend class QJsonObject;
friend class QCborValue;
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
+ friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QJsonValue &);
QJsonValue(QJsonPrivate::Data *d, QJsonPrivate::Base *b, const QJsonPrivate::Value& v);
void stringDataFromQStringHelper(const QString &string);
@@ -218,7 +219,6 @@ private:
uint index : 31;
};
-#ifndef Q_QDOC
// ### Qt 6: Get rid of these fake pointer classes
class QJsonValuePtr
{
@@ -243,7 +243,6 @@ public:
QJsonValueRef& operator*() { return valueRef; }
QJsonValueRef* operator->() { return &valueRef; }
};
-#endif
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonValue)
@@ -253,6 +252,11 @@ Q_CORE_EXPORT uint qHash(const QJsonValue &value, uint seed = 0);
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
#endif
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QJsonValue &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QJsonValue &);
+#endif
+
QT_END_NAMESPACE
#endif // QJSONVALUE_H
diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp
index fb7b677b2d..c9ba183a50 100644
--- a/src/corelib/serialization/qtextstream.cpp
+++ b/src/corelib/serialization/qtextstream.cpp
@@ -1332,7 +1332,7 @@ void QTextStream::setDevice(QIODevice *device)
/*!
Returns the current device associated with the QTextStream,
- or 0 if no device has been assigned.
+ or \nullptr if no device has been assigned.
\sa setDevice(), string()
*/
@@ -1369,8 +1369,8 @@ void QTextStream::setString(QString *string, QIODevice::OpenMode openMode)
}
/*!
- Returns the current string assigned to the QTextStream, or 0 if no
- string has been assigned.
+ Returns the current string assigned to the QTextStream, or
+ \nullptr if no string has been assigned.
\sa setString(), device()
*/
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
index 827996ee2d..0170be7602 100644
--- a/src/corelib/serialization/qxmlstream.cpp
+++ b/src/corelib/serialization/qxmlstream.cpp
@@ -223,7 +223,7 @@ QString QXmlStreamReaderPrivate::resolveUndeclaredEntity(const QString &name)
The stream reader does \e not take ownership of the resolver. It's
the callers responsibility to ensure that the resolver is valid
during the entire life-time of the stream reader object, or until
- another resolver or 0 is set.
+ another resolver or \nullptr is set.
\sa entityResolver()
*/
@@ -236,7 +236,7 @@ void QXmlStreamReader::setEntityResolver(QXmlStreamEntityResolver *resolver)
/*!
\since 4.4
- Returns the entity resolver, or 0 if there is no entity resolver.
+ Returns the entity resolver, or \nullptr if there is no entity resolver.
\sa setEntityResolver()
*/
@@ -480,7 +480,7 @@ void QXmlStreamReader::setDevice(QIODevice *device)
/*!
Returns the current device associated with the QXmlStreamReader,
- or 0 if no device has been assigned.
+ or \nullptr if no device has been assigned.
\sa setDevice()
*/
@@ -3315,7 +3315,7 @@ void QXmlStreamWriter::setDevice(QIODevice *device)
/*!
Returns the current device associated with the QXmlStreamWriter,
- or 0 if no device has been assigned.
+ or \nullptr if no device has been assigned.
\sa setDevice()
*/
diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g
index 10bfcd491c..e6328a11ac 100644
--- a/src/corelib/serialization/qxmlstream.g
+++ b/src/corelib/serialization/qxmlstream.g
@@ -41,6 +41,8 @@
%merged_output qxmlstream_p.h
+%expect 4
+
%token NOTOKEN
%token SPACE " "
%token LANGLE "<"
@@ -144,7 +146,12 @@
%start document
+
+
/.
+
+#include <QtCore/private/qglobal_p.h>
+
template <typename T> class QXmlStreamSimpleStack {
T *data;
int tos, cap;
@@ -155,7 +162,8 @@ public:
inline void reserve(int extraCapacity) {
if (tos + extraCapacity + 1 > cap) {
cap = qMax(tos + extraCapacity + 1, cap << 1 );
- data = reinterpret_cast<T *>(realloc(data, cap * sizeof(T)));
+ void *ptr = realloc(static_cast<void *>(data), cap * sizeof(T));
+ data = reinterpret_cast<T *>(ptr);
Q_CHECK_PTR(data);
}
}
@@ -753,7 +761,7 @@ bool QXmlStreamReaderPrivate::parse()
state_stack[tos] = 0;
return true;
} else if (act > 0) {
- if (++tos == stack_size-1)
+ if (++tos >= stack_size-1)
reallocateStack();
Value &val = sym_stack[tos];
@@ -890,7 +898,7 @@ doctype_decl ::= langle_bang DOCTYPE qname markup space_opt RANGLE;
/.
case $rule_number:
dtdName = symString(3);
- // fall through
+ Q_FALLTHROUGH();
./
doctype_decl ::= doctype_decl_start external_id space_opt markup space_opt RANGLE;
/.
diff --git a/src/corelib/statemachine/qabstractstate.cpp b/src/corelib/statemachine/qabstractstate.cpp
index 1a9ad4601d..0db44bc427 100644
--- a/src/corelib/statemachine/qabstractstate.cpp
+++ b/src/corelib/statemachine/qabstractstate.cpp
@@ -155,7 +155,8 @@ QAbstractState::~QAbstractState()
}
/*!
- Returns this state's parent state, or 0 if the state has no parent state.
+ Returns this state's parent state, or \nullptr if the state has no
+ parent state.
*/
QState *QAbstractState::parentState() const
{
@@ -166,8 +167,8 @@ QState *QAbstractState::parentState() const
}
/*!
- Returns the state machine that this state is part of, or 0 if the state is
- not part of a state machine.
+ Returns the state machine that this state is part of, or \nullptr if
+ the state is not part of a state machine.
*/
QStateMachine *QAbstractState::machine() const
{
diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp
index ebf33e120a..d841fd3c8b 100644
--- a/src/corelib/statemachine/qabstracttransition.cpp
+++ b/src/corelib/statemachine/qabstracttransition.cpp
@@ -195,8 +195,8 @@ QAbstractTransition::~QAbstractTransition()
}
/*!
- Returns the source state of this transition, or 0 if this transition has no
- source state.
+ Returns the source state of this transition, or \nullptr if this
+ transition has no source state.
*/
QState *QAbstractTransition::sourceState() const
{
@@ -205,14 +205,14 @@ QState *QAbstractTransition::sourceState() const
}
/*!
- Returns the target state of this transition, or 0 if the transition has no
- target.
+ Returns the target state of this transition, or \nullptr if the
+ transition has no target.
*/
QAbstractState *QAbstractTransition::targetState() const
{
Q_D(const QAbstractTransition);
if (d->targetStates.isEmpty())
- return 0;
+ return nullptr;
return d->targetStates.first().data();
}
@@ -325,8 +325,8 @@ void QAbstractTransition::setTransitionType(TransitionType type)
}
/*!
- Returns the state machine that this transition is part of, or 0 if the
- transition is not part of a state machine.
+ Returns the state machine that this transition is part of, or
+ \nullptr if the transition is not part of a state machine.
*/
QStateMachine *QAbstractTransition::machine() const
{
diff --git a/src/corelib/statemachine/qsignaleventgenerator_p.h b/src/corelib/statemachine/qsignaleventgenerator_p.h
index 271f6317bd..72592b8731 100644
--- a/src/corelib/statemachine/qsignaleventgenerator_p.h
+++ b/src/corelib/statemachine/qsignaleventgenerator_p.h
@@ -71,7 +71,7 @@ private:
void execute(void **_a);
private:
- Q_DISABLE_COPY(QSignalEventGenerator)
+ Q_DISABLE_COPY_MOVE(QSignalEventGenerator)
};
QT_END_NAMESPACE
diff --git a/src/corelib/statemachine/qsignaltransition_p.h b/src/corelib/statemachine/qsignaltransition_p.h
index 0666e600a4..b3de334677 100644
--- a/src/corelib/statemachine/qsignaltransition_p.h
+++ b/src/corelib/statemachine/qsignaltransition_p.h
@@ -70,7 +70,7 @@ public:
void unregister();
void maybeRegister();
- virtual void callOnTransition(QEvent *e) override;
+ void callOnTransition(QEvent *e) override;
const QObject *sender;
QByteArray signal;
diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp
index 2531874a87..ae13d4e4cf 100644
--- a/src/corelib/statemachine/qstate.cpp
+++ b/src/corelib/statemachine/qstate.cpp
@@ -473,7 +473,8 @@ void QState::onExit(QEvent *event)
}
/*!
- Returns this state's initial state, or 0 if the state has no initial state.
+ Returns this state's initial state, or \nullptr if the state has no
+ initial state.
*/
QAbstractState *QState::initialState() const
{
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 7388d496d9..ee3f7be279 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -1721,8 +1721,8 @@ QAbstractTransition *QStateMachinePrivate::createInitialTransition() const
: QAbstractTransition()
{ setTargetStates(targets); }
protected:
- virtual bool eventTest(QEvent *) override { return true; }
- virtual void onTransition(QEvent *) override {}
+ bool eventTest(QEvent *) override { return true; }
+ void onTransition(QEvent *) override {}
};
QState *root = rootState();
diff --git a/src/corelib/thread/qfuturewatcher.cpp b/src/corelib/thread/qfuturewatcher.cpp
index faeb6b3a28..4ee7693ace 100644
--- a/src/corelib/thread/qfuturewatcher.cpp
+++ b/src/corelib/thread/qfuturewatcher.cpp
@@ -479,7 +479,7 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event)
emit q->progressValueChanged(event->index1);
if (!event->text.isNull()) // ###
- q->progressTextChanged(event->text);
+ emit q->progressTextChanged(event->text);
break;
case QFutureCallOutEvent::ProgressRange:
emit q->progressRangeChanged(event->index1, event->index2);
diff --git a/src/corelib/thread/qresultstore.cpp b/src/corelib/thread/qresultstore.cpp
index e0ce1b4b78..1b3bc20eca 100644
--- a/src/corelib/thread/qresultstore.cpp
+++ b/src/corelib/thread/qresultstore.cpp
@@ -43,6 +43,21 @@ QT_BEGIN_NAMESPACE
namespace QtPrivate {
+/*!
+ \class QtPrivate::ResultItem
+ \internal
+ */
+
+/*!
+ \class QtPrivate::ResultIteratorBase
+ \internal
+ */
+
+/*!
+ \class QtPrivate::ResultStoreBase
+ \internal
+ */
+
ResultIteratorBase::ResultIteratorBase()
: mapIterator(QMap<int, ResultItem>::const_iterator()), m_vectorIndex(0) { }
ResultIteratorBase::ResultIteratorBase(QMap<int, ResultItem>::const_iterator _mapIterator, int _vectorIndex)
diff --git a/src/corelib/thread/qresultstore.h b/src/corelib/thread/qresultstore.h
index 39f0a6d1bb..1f29e8d187 100644
--- a/src/corelib/thread/qresultstore.h
+++ b/src/corelib/thread/qresultstore.h
@@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE
either individually or in batches.
*/
-#ifndef Q_QDOC
namespace QtPrivate {
@@ -196,7 +195,6 @@ public:
Q_DECLARE_TYPEINFO(QtPrivate::ResultItem, Q_PRIMITIVE_TYPE);
-#endif //Q_QDOC
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index aa04fb10ff..2e0b6f2bc0 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -606,7 +606,7 @@ bool QSemaphore::tryAcquire(int n, int timeout)
\fn QSemaphoreReleaser::semaphore() const
Returns a pointer to the QSemaphore object provided to the constructor,
- or by the last move assignment, if any. Otherwise, returns \c nullptr.
+ or by the last move assignment, if any. Otherwise, returns \nullptr.
*/
/*!
@@ -614,7 +614,7 @@ bool QSemaphore::tryAcquire(int n, int timeout)
Cancels this QSemaphoreReleaser such that the destructor will no longer
call \c{semaphore()->release()}. Returns the value of semaphore()
- before this call. After this call, semaphore() will return \c nullptr.
+ before this call. After this call, semaphore() will return \nullptr.
To enable again, assign a new QSemaphoreReleaser:
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 329caa02ba..a13f8ca215 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -100,6 +100,9 @@
#include <sys/neutrino.h>
#endif
+#if defined(Q_OS_WASM)
+#include <emscripten/val.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -499,6 +502,8 @@ int QThread::idealThreadCount() Q_DECL_NOTHROW
// as of aug 2008 VxWorks < 6.6 only supports one single core CPU
cores = 1;
# endif
+#elif defined(Q_OS_WASM)
+ cores = emscripten::val::global("navigator")["hardwareConcurrency"].as<int>();
#else
// the rest: Linux, Solaris, AIX, Tru64
cores = (int)sysconf(_SC_NPROCESSORS_ONLN);
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index a04536b18b..a91d833e3b 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -163,7 +163,7 @@ void QArrayData::deallocate(QArrayData *data, size_t objectSize,
#endif
Q_ASSERT_X(data == 0 || !data->ref.isStatic(), "QArrayData::deallocate",
- "Static data can not be deleted");
+ "Static data cannot be deleted");
::free(data);
}
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index c8bb384532..0f27071176 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -239,8 +239,8 @@ qCalculateGrowingBlockSize(size_t elementCount, size_t elementSize, size_t heade
Returns a duplicate string.
Allocates space for a copy of \a src, copies it, and returns a
- pointer to the copy. If \a src is nullptr, it immediately returns
- nullptr.
+ pointer to the copy. If \a src is \nullptr, it immediately returns
+ \nullptr.
Ownership is passed to the caller, so the returned string must be
deleted using \c delete[].
@@ -258,7 +258,7 @@ char *qstrdup(const char *src)
Copies all the characters up to and including the '\\0' from \a
src into \a dst and returns a pointer to \a dst. If \a src is
- nullptr, it immediately returns nullptr.
+ \nullptr, it immediately returns \nullptr.
This function assumes that \a dst is large enough to hold the
contents of \a src.
@@ -291,7 +291,7 @@ char *qstrcpy(char *dst, const char *src)
Copies at most \a len bytes from \a src (stopping at \a len or the
terminating '\\0' whichever comes first) into \a dst and returns a
pointer to \a dst. Guarantees that \a dst is '\\0'-terminated. If
- \a src or \a dst is nullptr, returns nullptr immediately.
+ \a src or \a dst is \nullptr, returns \nullptr immediately.
This function assumes that \a dst is at least \a len characters
long.
@@ -326,7 +326,7 @@ char *qstrncpy(char *dst, const char *src, uint len)
A safe \c strlen() function.
Returns the number of characters that precede the terminating '\\0',
- or 0 if \a str is nullptr.
+ or 0 if \a str is \nullptr.
\sa qstrnlen()
*/
@@ -338,7 +338,7 @@ char *qstrncpy(char *dst, const char *src, uint len)
A safe \c strnlen() function.
Returns the number of characters that precede the terminating '\\0', but
- at most \a maxlen. If \a str is nullptr, returns 0.
+ at most \a maxlen. If \a str is \nullptr, returns 0.
\sa qstrlen()
*/
@@ -352,10 +352,10 @@ char *qstrncpy(char *dst, const char *src, uint len)
is less than \a str2, 0 if \a str1 is equal to \a str2 or a
positive value if \a str1 is greater than \a str2.
- Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr.
+ Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr.
Special case 2: Returns an arbitrary non-zero value if \a str1 is
- nullptr or \a str2 is nullptr (but not both).
+ \nullptr or \a str2 is \nullptr (but not both).
\sa qstrncmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons},
QByteArray::compare()
@@ -378,10 +378,10 @@ int qstrcmp(const char *str1, const char *str2)
str1 is equal to \a str2 or a positive value if \a str1 is greater
than \a str2.
- Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr.
+ Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr.
- Special case 2: Returns a random non-zero value if \a str1 is nullptr
- or \a str2 is nullptr (but not both).
+ Special case 2: Returns a random non-zero value if \a str1 is \nullptr
+ or \a str2 is \nullptr (but not both).
\sa qstrcmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons},
QByteArray::compare()
@@ -398,10 +398,10 @@ int qstrcmp(const char *str1, const char *str2)
str1 is equal to \a str2 or a positive value if \a str1 is greater
than \a str2.
- Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr.
+ Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr.
- Special case 2: Returns a random non-zero value if \a str1 is nullptr
- or \a str2 is nullptr (but not both).
+ Special case 2: Returns a random non-zero value if \a str1 is \nullptr
+ or \a str2 is \nullptr (but not both).
\sa qstrcmp(), qstrncmp(), qstrnicmp(), {8-bit Character Comparisons},
QByteArray::compare()
@@ -491,10 +491,10 @@ int qstricmp(const char *str1, const char *str2)
is equal to \a str2 or a positive value if \a str1 is greater than \a
str2.
- Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr.
+ Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr.
- Special case 2: Returns a random non-zero value if \a str1 is nullptr
- or \a str2 is nullptr (but not both).
+ Special case 2: Returns a random non-zero value if \a str1 is \nullptr
+ or \a str2 is \nullptr (but not both).
\sa qstrcmp(), qstrncmp(), qstricmp(), {8-bit Character Comparisons},
QByteArray::compare()
@@ -523,7 +523,7 @@ int qstrnicmp(const char *str1, const char *str2, uint len)
A helper for QByteArray::compare. Compares \a len1 bytes from \a str1 to \a
len2 bytes from \a str2. If \a len2 is -1, then \a str2 is expected to be
- null-terminated.
+ '\\0'-terminated.
*/
int qstrnicmp(const char *str1, qsizetype len1, const char *str2, qsizetype len2)
{
@@ -1765,9 +1765,10 @@ void QByteArray::chop(int n)
If \a data is 0, a null byte array is constructed.
- If \a size is negative, \a data is assumed to point to a nul-terminated
- string and its length is determined dynamically. The terminating
- nul-character is not considered part of the byte array.
+ If \a size is negative, \a data is assumed to point to a
+ '\\0'-terminated string and its length is determined dynamically.
+ The terminating \\0 character is not considered part of the
+ byte array.
QByteArray makes a deep copy of the string data.
@@ -1924,7 +1925,7 @@ void QByteArray::expand(int i)
/*!
\internal
- Return a QByteArray that is sure to be NUL-terminated.
+ Return a QByteArray that is sure to be '\\0'-terminated.
By default, all QByteArray have an extra NUL at the end,
guaranteeing that assumption. However, if QByteArray::fromRawData
@@ -2336,8 +2337,8 @@ QByteArray &QByteArray::replace(int pos, int len, const QByteArray &after)
\overload
- Replaces \a len bytes from index position \a pos with the zero terminated
- string \a after.
+ Replaces \a len bytes from index position \a pos with the
+ '\\0'-terminated string \a after.
Notice: this can change the length of the byte array.
*/
@@ -2415,7 +2416,7 @@ QByteArray &QByteArray::replace(const char *c, const QByteArray &after)
Replaces every occurrence of the string \a before with the string \a after.
Since the sizes of the strings are given by \a bsize and \a asize, they
- may contain zero characters and do not need to be zero-terminated.
+ may contain zero characters and do not need to be '\\0'-terminated.
*/
QByteArray &QByteArray::replace(const char *before, int bsize, const char *after, int asize)
@@ -3882,9 +3883,7 @@ static qulonglong toIntegral_helper(const char *data, bool *ok, int base, qulong
template <typename T> static inline
T toIntegral_helper(const char *data, bool *ok, int base)
{
- // ### Qt6: use std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type
- const bool isUnsigned = T(0) < T(-1);
- typedef typename QtPrivate::QConditional<isUnsigned, qulonglong, qlonglong>::Type Int64;
+ using Int64 = typename std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type;
#if defined(QT_CHECK_RANGE)
if (base != 0 && (base < 2 || base > 36)) {
@@ -3914,7 +3913,7 @@ T toIntegral_helper(const char *data, bool *ok, int base)
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\note The conversion of the number is performed in the default C locale,
@@ -3940,7 +3939,7 @@ qlonglong QByteArray::toLongLong(bool *ok, int base) const
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\note The conversion of the number is performed in the default C locale,
@@ -3965,7 +3964,7 @@ qulonglong QByteArray::toULongLong(bool *ok, int base) const
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\snippet code/src_corelib_tools_qbytearray.cpp 36
@@ -3992,7 +3991,7 @@ int QByteArray::toInt(bool *ok, int base) const
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\note The conversion of the number is performed in the default C locale,
@@ -4019,7 +4018,7 @@ uint QByteArray::toUInt(bool *ok, int base) const
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\snippet code/src_corelib_tools_qbytearray.cpp 37
@@ -4047,7 +4046,7 @@ long QByteArray::toLong(bool *ok, int base) const
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\note The conversion of the number is performed in the default C locale,
@@ -4071,7 +4070,7 @@ ulong QByteArray::toULong(bool *ok, int base) const
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\note The conversion of the number is performed in the default C locale,
@@ -4096,7 +4095,7 @@ short QByteArray::toShort(bool *ok, int base) const
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\note The conversion of the number is performed in the default C locale,
@@ -4117,7 +4116,7 @@ ushort QByteArray::toUShort(bool *ok, int base) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for other reasons (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\snippet code/src_corelib_tools_qbytearray.cpp 38
@@ -4153,7 +4152,7 @@ double QByteArray::toDouble(bool *ok) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for other reasons (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\snippet code/src_corelib_tools_qbytearray.cpp 38float
@@ -4543,7 +4542,7 @@ QByteArray QByteArray::number(double n, char f, int prec)
\snippet code/src_corelib_tools_qbytearray.cpp 43
\warning A byte array created with fromRawData() is \e not
- null-terminated, unless the raw data contains a 0 character at
+ '\\0'-terminated, unless the raw data contains a 0 character at
position \a size. While that does not matter for QDataStream or
functions like indexOf(), passing the byte array to a function
accepting a \c{const char *} expected to be '\\0'-terminated will
diff --git a/src/corelib/tools/qbytearraylist.cpp b/src/corelib/tools/qbytearraylist.cpp
index c815e766ab..d04555ed4d 100644
--- a/src/corelib/tools/qbytearraylist.cpp
+++ b/src/corelib/tools/qbytearraylist.cpp
@@ -150,4 +150,26 @@ QByteArray QtPrivate::QByteArrayList_join(const QByteArrayList *that, const char
return res;
}
+/*!
+ \fn int QByteArrayList::indexOf(const char *needle, int from) const
+
+ Returns the index position of the first occurrence of \a needle in
+ the list, searching forward from index position \a from. Returns
+ -1 if no item matched.
+
+ \a needle must be NUL-terminated.
+
+ This overload doesn't require creating a QByteArray, thus saving a
+ memory allocation and some CPU time.
+
+ \since 5.13
+ \overload
+*/
+
+int QtPrivate::QByteArrayList_indexOf(const QByteArrayList *that, const char *needle, int from)
+{
+ const auto it = std::find_if(that->begin() + from, that->end(), [needle](const QByteArray &item) { return item == needle; });
+ return it == that->end() ? -1 : int(std::distance(that->begin(), it));
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qbytearraylist.h b/src/corelib/tools/qbytearraylist.h
index ed014dd157..d69e8bb54b 100644
--- a/src/corelib/tools/qbytearraylist.h
+++ b/src/corelib/tools/qbytearraylist.h
@@ -50,21 +50,22 @@ QT_BEGIN_NAMESPACE
typedef QListIterator<QByteArray> QByteArrayListIterator;
typedef QMutableListIterator<QByteArray> QMutableByteArrayListIterator;
-#ifndef Q_QDOC
+#ifndef Q_CLANG_QDOC
typedef QList<QByteArray> QByteArrayList;
namespace QtPrivate {
QByteArray Q_CORE_EXPORT QByteArrayList_join(const QByteArrayList *that, const char *separator, int separatorLength);
+ int Q_CORE_EXPORT QByteArrayList_indexOf(const QByteArrayList *that, const char *needle, int from);
}
#endif
-#ifdef Q_QDOC
+#ifdef Q_CLANG_QDOC
class QByteArrayList : public QList<QByteArray>
#else
template <> struct QListSpecialMethods<QByteArray>
#endif
{
-#ifndef Q_QDOC
+#ifndef Q_CLANG_QDOC
protected:
~QListSpecialMethods() {}
#endif
@@ -76,6 +77,9 @@ public:
inline QByteArray join(char sep) const
{ return QtPrivate::QByteArrayList_join(self(), &sep, 1); }
+ inline int indexOf(const char *needle, int from = 0) const
+ { return QtPrivate::QByteArrayList_indexOf(self(), needle, from); }
+
private:
typedef QList<QByteArray> Self;
Self *self() { return static_cast<Self *>(this); }
diff --git a/src/corelib/tools/qcache.qdoc b/src/corelib/tools/qcache.qdoc
index 31dfcb42cf..ffc21318f4 100644
--- a/src/corelib/tools/qcache.qdoc
+++ b/src/corelib/tools/qcache.qdoc
@@ -70,7 +70,7 @@
To look up objects in the cache, use object() or
operator[](). This function looks up an object by its key, and
returns either a pointer to the cached object (which is owned by
- the cache) or 0.
+ the cache) or \nullptr.
If you want to remove an object from the cache for a particular key,
call remove(). This will also delete the object. If you want to
@@ -171,7 +171,7 @@
/*! \fn template <class Key, class T> T *QCache<Key, T>::object(const Key &key) const
- Returns the object associated with key \a key, or 0 if the key does
+ Returns the object associated with key \a key, or \nullptr if the key does
not exist in the cache.
\warning The returned object is owned by QCache and may be
@@ -190,7 +190,7 @@
/*! \fn template <class Key, class T> T *QCache<Key, T>::operator[](const Key &key) const
- Returns the object associated with key \a key, or 0 if the key does
+ Returns the object associated with key \a key, or \nullptr if the key does
not exist in the cache.
This is the same as object().
diff --git a/src/corelib/tools/qcollator_p.h b/src/corelib/tools/qcollator_p.h
index 361c3fb987..fc2d434a8d 100644
--- a/src/corelib/tools/qcollator_p.h
+++ b/src/corelib/tools/qcollator_p.h
@@ -122,7 +122,7 @@ public:
void cleanup();
private:
- Q_DISABLE_COPY(QCollatorPrivate)
+ Q_DISABLE_COPY_MOVE(QCollatorPrivate)
};
class QCollatorSortKeyPrivate : public QSharedData
@@ -139,7 +139,7 @@ public:
CollatorKeyType m_key;
private:
- Q_DISABLE_COPY(QCollatorSortKeyPrivate)
+ Q_DISABLE_COPY_MOVE(QCollatorSortKeyPrivate)
};
diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp
index 279d6565da..6817d73143 100644
--- a/src/corelib/tools/qcommandlineparser.cpp
+++ b/src/corelib/tools/qcommandlineparser.cpp
@@ -589,7 +589,7 @@ static void showParserMessage(const QString &message, MessageType type)
void QCommandLineParser::process(const QStringList &arguments)
{
if (!d->parse(arguments)) {
- showParserMessage(errorText() + QLatin1Char('\n'), ErrorMessage);
+ showParserMessage(QCoreApplication::applicationName() + QLatin1String(": ") + errorText() + QLatin1Char('\n'), ErrorMessage);
qt_call_post_routines();
::exit(EXIT_FAILURE);
}
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 3cba786865..80d6dada60 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -2183,16 +2183,6 @@ int QTime::elapsed() const
typedef QDateTimePrivate::QDateTimeShortData ShortData;
typedef QDateTimePrivate::QDateTimeData QDateTimeData;
-// Calls the platform variant of tzset
-static void qt_tzset()
-{
-#if defined(Q_OS_WIN)
- _tzset();
-#else
- tzset();
-#endif // Q_OS_WIN
-}
-
// Returns the platform variant of timezone, i.e. the standard time offset
// The timezone external variable is documented as always holding the
// Standard Time offset as seconds west of Greenwich, i.e. UTC+01:00 is -3600
@@ -2290,7 +2280,7 @@ static qint64 qt_mktime(QDate *date, QTime *time, QDateTimePrivate::DaylightStat
#if defined(Q_OS_WIN)
int hh = local.tm_hour;
#endif // Q_OS_WIN
- time_t secsSinceEpoch = mktime(&local);
+ time_t secsSinceEpoch = qMkTime(&local);
if (secsSinceEpoch != time_t(-1)) {
*date = QDate(local.tm_year + 1900, local.tm_mon + 1, local.tm_mday);
*time = QTime(local.tm_hour, local.tm_min, local.tm_sec, msec);
@@ -2349,10 +2339,10 @@ static bool qt_localtime(qint64 msecsSinceEpoch, QDate *localDate, QTime *localT
tm local;
bool valid = false;
- // localtime() is required to work as if tzset() was called before it.
- // localtime_r() does not have this requirement, so make an explicit call.
+ // localtime() is specified to work as if it called tzset().
+ // localtime_r() does not have this constraint, so make an explicit call.
// The explicit call should also request the timezone info be re-parsed.
- qt_tzset();
+ qTzSet();
#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
// Use the reentrant version of localtime() where available
// as is thread-safe and doesn't use a shared static data area
@@ -2434,7 +2424,7 @@ static bool epochMSecsToLocalTime(qint64 msecs, QDate *localDate, QTime *localTi
if (msecs < 0) {
// Docs state any LocalTime before 1970-01-01 will *not* have any Daylight Time applied
// Instead just use the standard offset from UTC to convert to UTC time
- qt_tzset();
+ qTzSet();
msecsToTime(msecs - qt_timezone() * 1000, localDate, localTime);
if (daylightStatus)
*daylightStatus = QDateTimePrivate::StandardTime;
@@ -2497,7 +2487,7 @@ static qint64 localMSecsToEpochMSecs(qint64 localMsecs,
}
} else {
// If we don't call mktime then need to call tzset to get offset
- qt_tzset();
+ qTzSet();
}
// Time is clearly before 1970-01-01 so just use standard offset to convert
qint64 utcMsecs = localMsecs + qt_timezone() * 1000;
diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h
index 2f98cf5cc1..63be0952ff 100644
--- a/src/corelib/tools/qfreelist_p.h
+++ b/src/corelib/tools/qfreelist_p.h
@@ -187,7 +187,7 @@ class QFreeList
QAtomicInt _next;
// QFreeList is not copyable
- Q_DISABLE_COPY(QFreeList)
+ Q_DISABLE_COPY_MOVE(QFreeList)
public:
Q_DECL_CONSTEXPR inline QFreeList();
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 17aba8035b..6f8084c676 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -48,6 +48,23 @@
QT_BEGIN_NAMESPACE
/*
+ ### Qt 5:
+ ### This needs to be removed for next releases of Qt. It is a workaround for vc++ because
+ ### Qt exports QPolygon and QPolygonF that inherit QVector<QPoint> and
+ ### QVector<QPointF> respectively.
+*/
+
+#if defined(Q_CC_MSVC) && defined(QT_BUILD_CORE_LIB)
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <QtCore/qpoint.h>
+QT_END_INCLUDE_NAMESPACE
+
+template class Q_CORE_EXPORT QVector<QPointF>;
+template class Q_CORE_EXPORT QVector<QPoint>;
+#endif
+
+
+/*
QList as an array-list combines the easy-of-use of a random
access interface with fast list operations and the low memory
management overhead of an array. Accessing elements by index,
@@ -948,6 +965,14 @@ void **QListData::erase(void **xi)
/*! \fn template <class T> void QList<T>::swap(int i, int j)
+ \obsolete Use swapItemsAt()
+
+ \sa move(), swapItemsAt()
+*/
+
+/*! \fn template <class T> void QList<T>::swapItemsAt(int i, int j)
+ \since 5.13
+
Exchange the item at index position \a i with the item at index
position \a j. This function assumes that both \a i and \a j are
at least 0 but less than size(). To avoid failure, test that both
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 49ccbc9c9f..6643288bd5 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -45,6 +45,7 @@
#include <QtCore/qrefcount.h>
#include <QtCore/qarraydata.h>
#include <QtCore/qhashfunctions.h>
+#include <QtCore/qvector.h>
#include <iterator>
#include <list>
@@ -117,6 +118,11 @@ struct Q_CORE_EXPORT QListData {
inline void **end() const Q_DECL_NOTHROW { return d->array + d->end; }
};
+namespace QtPrivate {
+ template <typename V, typename U> int indexOf(const QList<V> &list, const U &u, int from);
+ template <typename V, typename U> int lastIndexOf(const QList<V> &list, const U &u, int from);
+}
+
template <typename T>
class QList
#ifndef Q_QDOC
@@ -135,6 +141,8 @@ public:
QListData::InlineWithPaddingLayout
>::type>::type {};
private:
+ template <typename V, typename U> friend int QtPrivate::indexOf(const QList<V> &list, const U &u, int from);
+ template <typename V, typename U> friend int QtPrivate::lastIndexOf(const QList<V> &list, const U &u, int from);
struct Node { void *v;
#if defined(Q_CC_BOR)
Q_INLINE_TEMPLATE T &t();
@@ -213,7 +221,11 @@ public:
T takeFirst();
T takeLast();
void move(int from, int to);
- void swap(int i, int j);
+ void swapItemsAt(int i, int j);
+#if QT_DEPRECATED_SINCE(5, 13) && QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ QT_DEPRECATED_X("Use QList<T>::swapItemsAt()")
+ void swap(int i, int j) { swapItemsAt(i, j); }
+#endif
int indexOf(const T &t, int from = 0) const;
int lastIndexOf(const T &t, int from = -1) const;
bool contains(const T &t) const;
@@ -689,7 +701,7 @@ inline void QList<T>::replace(int i, const T &t)
}
template <typename T>
-inline void QList<T>::swap(int i, int j)
+inline void QList<T>::swapItemsAt(int i, int j)
{
Q_ASSERT_X(i >= 0 && i < p.size() && j >= 0 && j < p.size(),
"QList<T>::swap", "index out of range");
@@ -970,35 +982,57 @@ inline void QList<T>::append(const QList<T> &t)
template <typename T>
Q_OUTOFLINE_TEMPLATE int QList<T>::indexOf(const T &t, int from) const
{
+ return QtPrivate::indexOf<T, T>(*this, t, from);
+}
+
+namespace QtPrivate
+{
+template <typename T, typename U>
+int indexOf(const QList<T> &list, const U &u, int from)
+{
+ typedef typename QList<T>::Node Node;
+
if (from < 0)
- from = qMax(from + p.size(), 0);
- if (from < p.size()) {
- Node *n = reinterpret_cast<Node *>(p.at(from -1));
- Node *e = reinterpret_cast<Node *>(p.end());
+ from = qMax(from + list.p.size(), 0);
+ if (from < list.p.size()) {
+ Node *n = reinterpret_cast<Node *>(list.p.at(from -1));
+ Node *e = reinterpret_cast<Node *>(list.p.end());
while (++n != e)
- if (n->t() == t)
- return int(n - reinterpret_cast<Node *>(p.begin()));
+ if (n->t() == u)
+ return int(n - reinterpret_cast<Node *>(list.p.begin()));
}
return -1;
}
+}
template <typename T>
Q_OUTOFLINE_TEMPLATE int QList<T>::lastIndexOf(const T &t, int from) const
{
+ return QtPrivate::lastIndexOf<T, T>(*this, t, from);
+}
+
+namespace QtPrivate
+{
+template <typename T, typename U>
+int lastIndexOf(const QList<T> &list, const U &u, int from)
+{
+ typedef typename QList<T>::Node Node;
+
if (from < 0)
- from += p.size();
- else if (from >= p.size())
- from = p.size()-1;
+ from += list.p.size();
+ else if (from >= list.p.size())
+ from = list.p.size()-1;
if (from >= 0) {
- Node *b = reinterpret_cast<Node *>(p.begin());
- Node *n = reinterpret_cast<Node *>(p.at(from + 1));
+ Node *b = reinterpret_cast<Node *>(list.p.begin());
+ Node *n = reinterpret_cast<Node *>(list.p.at(from + 1));
while (n-- != b) {
- if (n->t() == t)
+ if (n->t() == u)
return n - b;
}
}
return -1;
}
+}
template <typename T>
Q_OUTOFLINE_TEMPLATE bool QList<T>::contains(const T &t) const
@@ -1051,6 +1085,37 @@ inline int QList<T>::count_impl(const T &t, QListData::ArrayCompatibleLayout) co
t));
}
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QVector<T> QList<T>::toVector() const
+{
+ QVector<T> result(size());
+ for (int i = 0; i < size(); ++i)
+ result[i] = at(i);
+ return result;
+}
+
+template <typename T>
+QList<T> QList<T>::fromVector(const QVector<T> &vector)
+{
+ return vector.toList();
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QList<T> QVector<T>::toList() const
+{
+ QList<T> result;
+ result.reserve(size());
+ for (int i = 0; i < size(); ++i)
+ result.append(at(i));
+ return result;
+}
+
+template <typename T>
+QVector<T> QVector<T>::fromList(const QList<T> &list)
+{
+ return list.toVector();
+}
+
Q_DECLARE_SEQUENTIAL_ITERATOR(List)
Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(List)
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index df768fb875..ebb6c97975 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -620,13 +620,18 @@ static QLocalePrivate *c_private()
*/
/*!
- Constructs a QSystemLocale object. The constructor will automatically
- install this object as the system locale and remove any earlier installed
- system locales.
+ Constructs a QSystemLocale object.
+
+ The constructor will automatically install this object as the system locale,
+ if there's not one active. It also resets the flag that'll prompt
+ QLocale::system() to re-initialize its data, so that instantiating a
+ QSystemLocale transiently (doesn't install the transient as system locale if
+ there was one already and) triggers an update to the system locale's data.
*/
QSystemLocale::QSystemLocale()
{
- _systemLocale = this;
+ if (!_systemLocale)
+ _systemLocale = this;
globalLocaleData.m_language_id = 0;
}
@@ -656,15 +661,17 @@ static const QSystemLocale *systemLocale()
return QSystemLocale_globalSystemLocale();
}
-void QLocalePrivate::updateSystemPrivate()
+static void updateSystemPrivate()
{
- // this function is NOT thread-safe!
+ // This function is NOT thread-safe!
+ // It *should not* be called by anything but systemData()
const QSystemLocale *sys_locale = systemLocale();
// tell the object that the system locale has changed.
sys_locale->query(QSystemLocale::LocaleChanged, QVariant());
- globalLocaleData = *sys_locale->fallbackUiLocale().d->m_data;
+ // Populate global with fallback as basis:
+ globalLocaleData = *sys_locale->fallbackUiLocaleData();
QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
if (!res.isNull()) {
@@ -715,7 +722,7 @@ static const QLocaleData *systemData()
static QBasicMutex systemDataMutex;
systemDataMutex.lock();
if (globalLocaleData.m_language_id == 0)
- QLocalePrivate::updateSystemPrivate();
+ updateSystemPrivate();
systemDataMutex.unlock();
}
@@ -1180,9 +1187,7 @@ static qulonglong toIntegral_helper(const QLocaleData *d, QStringView str, bool
template <typename T> static inline
T toIntegral_helper(const QLocalePrivate *d, QStringView str, bool *ok)
{
- // ### Qt6: use std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type
- const bool isUnsigned = T(0) < T(-1);
- typedef typename QtPrivate::QConditional<isUnsigned, qulonglong, qlonglong>::Type Int64;
+ using Int64 = typename std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type;
// we select the right overload by the last, unused parameter
Int64 val = toIntegral_helper(d->m_data, str, ok, d->m_numberOptions, Int64());
@@ -1260,7 +1265,7 @@ QString QLocale::scriptToString(QLocale::Script script)
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1278,7 +1283,7 @@ short QLocale::toShort(const QString &s, bool *ok) const
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1296,7 +1301,7 @@ ushort QLocale::toUShort(const QString &s, bool *ok) const
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1314,7 +1319,7 @@ int QLocale::toInt(const QString &s, bool *ok) const
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1328,11 +1333,53 @@ uint QLocale::toUInt(const QString &s, bool *ok) const
}
/*!
+ Returns the long int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toULong(), toDouble(), toString()
+
+ \since 5.13
+ */
+
+
+long QLocale::toLong(const QString &s, bool *ok) const
+{
+ return toIntegral_helper<long>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned long int represented by the localized
+ string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toLong(), toInt(), toDouble(), toString()
+
+ \since 5.13
+*/
+
+ulong QLocale::toULong(const QString &s, bool *ok) const
+{
+ return toIntegral_helper<ulong>(d, s, ok);
+}
+
+/*!
Returns the long long int represented by the localized string \a s.
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1352,7 +1399,7 @@ qlonglong QLocale::toLongLong(const QString &s, bool *ok) const
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1371,7 +1418,7 @@ qulonglong QLocale::toULongLong(const QString &s, bool *ok) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for any other reason (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function does not fall back to the 'C' locale if the string
@@ -1393,7 +1440,7 @@ float QLocale::toFloat(const QString &s, bool *ok) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for any other reason (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function does not fall back to the 'C' locale if the string
@@ -1419,7 +1466,7 @@ double QLocale::toDouble(const QString &s, bool *ok) const
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1439,7 +1486,7 @@ short QLocale::toShort(const QStringRef &s, bool *ok) const
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1459,7 +1506,7 @@ ushort QLocale::toUShort(const QStringRef &s, bool *ok) const
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1479,7 +1526,7 @@ int QLocale::toInt(const QStringRef &s, bool *ok) const
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1495,11 +1542,53 @@ uint QLocale::toUInt(const QStringRef &s, bool *ok) const
}
/*!
+ Returns the long int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toULong(), toDouble(), toString()
+
+ \since 5.13
+ */
+
+
+long QLocale::toLong(const QStringRef &s, bool *ok) const
+{
+ return toIntegral_helper<long>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned long int represented by the localized
+ string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toLong(), toInt(), toDouble(), toString()
+
+ \since 5.13
+ */
+
+ulong QLocale::toULong(const QStringRef &s, bool *ok) const
+{
+ return toIntegral_helper<ulong>(d, s, ok);
+}
+
+/*!
Returns the long long int represented by the localized string \a s.
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1521,7 +1610,7 @@ qlonglong QLocale::toLongLong(const QStringRef &s, bool *ok) const
If the conversion fails the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1542,7 +1631,7 @@ qulonglong QLocale::toULongLong(const QStringRef &s, bool *ok) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for any other reason (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function does not fall back to the 'C' locale if the string
@@ -1566,7 +1655,7 @@ float QLocale::toFloat(const QStringRef &s, bool *ok) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for any other reason (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function does not fall back to the 'C' locale if the string
@@ -1595,7 +1684,7 @@ double QLocale::toDouble(const QStringRef &s, bool *ok) const
If the conversion fails, the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1615,7 +1704,7 @@ short QLocale::toShort(QStringView s, bool *ok) const
If the conversion fails, the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1635,7 +1724,7 @@ ushort QLocale::toUShort(QStringView s, bool *ok) const
If the conversion fails, the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1655,7 +1744,7 @@ int QLocale::toInt(QStringView s, bool *ok) const
If the conversion fails, the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1671,11 +1760,53 @@ uint QLocale::toUInt(QStringView s, bool *ok) const
}
/*!
+ Returns the long int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toULong(), toDouble(), toString()
+
+ \since 5.13
+ */
+
+
+long QLocale::toLong(QStringView s, bool *ok) const
+{
+ return toIntegral_helper<long>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned long int represented by the localized
+ string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toLong(), toInt(), toDouble(), toString()
+
+ \since 5.13
+ */
+
+ulong QLocale::toULong(QStringView s, bool *ok) const
+{
+ return toIntegral_helper<ulong>(d, s, ok);
+}
+
+/*!
Returns the long long int represented by the localized string \a s.
If the conversion fails, the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1697,7 +1828,7 @@ qlonglong QLocale::toLongLong(QStringView s, bool *ok) const
If the conversion fails, the function returns 0.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1718,7 +1849,7 @@ qulonglong QLocale::toULongLong(QStringView s, bool *ok) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for any other reason (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
This function ignores leading and trailing whitespace.
@@ -1739,7 +1870,7 @@ float QLocale::toFloat(QStringView s, bool *ok) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for any other reason (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
Unlike QString::toDouble(), this function does not fall back to
@@ -2365,7 +2496,6 @@ QString QLocale::toString(double i, char f, int prec) const
QLocale QLocale::system()
{
- // this function is NOT thread-safe!
QT_PREPEND_NAMESPACE(systemData)(); // trigger updating of the system data if necessary
if (systemLocalePrivate.isDestroyed())
return QLocale(QLocale::C);
@@ -3891,6 +4021,19 @@ QString QLocale::toCurrencyString(double value, const QString &symbol, int preci
\sa formattedDataSize()
*/
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \obsolete
+
+ Use the const version instead.
+*/
+QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats format)
+{
+ const auto *that = this;
+ return that->formattedDataSize(bytes, precision, format);
+}
+#endif
+
/*!
\since 5.10
@@ -3907,7 +4050,7 @@ QString QLocale::toCurrencyString(double value, const QString &symbol, int preci
whereas \c DataSizeSIFormat uses the older SI quantifiers k, M, etc., and
\c DataSizeTraditionalFormat abuses them.
*/
-QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats format)
+QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats format) const
{
int power, base = 1000;
if (!bytes) {
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index f3afb8c406..2b4f131552 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -436,6 +436,11 @@ public:
Cantonese = 357,
Osage = 358,
Tangut = 359,
+ Ido = 360,
+ Lojban = 361,
+ Sicilian = 362,
+ SouthernKurdish = 363,
+ WesternBalochi = 364,
Afan = Oromo,
Bhutani = Dzongkha,
@@ -452,7 +457,7 @@ public:
Twi = Akan,
Uigur = Uighur,
- LastLanguage = Tangut
+ LastLanguage = WesternBalochi
};
enum Script {
@@ -956,6 +961,8 @@ public:
ushort toUShort(const QString &s, bool *ok = nullptr) const;
int toInt(const QString &s, bool *ok = nullptr) const;
uint toUInt(const QString &s, bool *ok = nullptr) const;
+ long toLong(const QString &s, bool *ok = nullptr) const;
+ ulong toULong(const QString &s, bool *ok = nullptr) const;
qlonglong toLongLong(const QString &s, bool *ok = nullptr) const;
qulonglong toULongLong(const QString &s, bool *ok = nullptr) const;
float toFloat(const QString &s, bool *ok = nullptr) const;
@@ -965,6 +972,8 @@ public:
ushort toUShort(const QStringRef &s, bool *ok = nullptr) const;
int toInt(const QStringRef &s, bool *ok = nullptr) const;
uint toUInt(const QStringRef &s, bool *ok = nullptr) const;
+ long toLong(const QStringRef &s, bool *ok = nullptr) const;
+ ulong toULong(const QStringRef &s, bool *ok = nullptr) const;
qlonglong toLongLong(const QStringRef &s, bool *ok = nullptr) const;
qulonglong toULongLong(const QStringRef &s, bool *ok = nullptr) const;
float toFloat(const QStringRef &s, bool *ok = nullptr) const;
@@ -975,6 +984,8 @@ public:
ushort toUShort(QStringView s, bool *ok = nullptr) const;
int toInt(QStringView s, bool *ok = nullptr) const;
uint toUInt(QStringView s, bool *ok = nullptr) const;
+ long toLong(QStringView s, bool *ok = nullptr) const;
+ ulong toULong(QStringView s, bool *ok = nullptr) const;
qlonglong toLongLong(QStringView s, bool *ok = nullptr) const;
qulonglong toULongLong(QStringView s, bool *ok = nullptr) const;
float toFloat(QStringView s, bool *ok = nullptr) const;
@@ -982,6 +993,8 @@ public:
QString toString(qlonglong i) const;
QString toString(qulonglong i) const;
+ inline QString toString(long i) const;
+ inline QString toString(ulong i) const;
inline QString toString(short i) const;
inline QString toString(ushort i) const;
inline QString toString(int i) const;
@@ -1061,7 +1074,10 @@ public:
{ return toCurrencyString(double(i), symbol, precision); }
#endif
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QString formattedDataSize(qint64 bytes, int precision = 2, DataSizeFormats format = DataSizeIecFormat);
+#endif
+ QString formattedDataSize(qint64 bytes, int precision = 2, DataSizeFormats format = DataSizeIecFormat) const;
QStringList uiLanguages() const;
@@ -1091,6 +1107,7 @@ public:
private:
QLocale(QLocalePrivate &dd);
friend class QLocalePrivate;
+ friend class QSystemLocale;
friend Q_CORE_EXPORT uint qHash(const QLocale &key, uint seed) Q_DECL_NOTHROW;
QSharedDataPointer<QLocalePrivate> d;
@@ -1098,6 +1115,10 @@ private:
Q_DECLARE_SHARED(QLocale)
Q_DECLARE_OPERATORS_FOR_FLAGS(QLocale::NumberOptions)
+inline QString QLocale::toString(long i) const
+ { return toString(qlonglong(i)); }
+inline QString QLocale::toString(ulong i) const
+ { return toString(qulonglong(i)); }
inline QString QLocale::toString(short i) const
{ return toString(qlonglong(i)); }
inline QString QLocale::toString(ushort i) const
diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc
index 76ca909d83..91b0ab6442 100644
--- a/src/corelib/tools/qlocale.qdoc
+++ b/src/corelib/tools/qlocale.qdoc
@@ -105,42 +105,80 @@
\value AnyLanguage
\value C The "C" locale is identical in behavior to English/UnitedStates.
+
\value Abkhazian
- \value Oromo
\value Afan Obsolete, please use Oromo
\value Afar
\value Afrikaans
+ \value Aghem
+ \value Ahom Since Qt 5.7
+ \value Akan
+ \value Akkadian Since Qt 5.1
\value Akoose Since Qt 5.3
\value Albanian
+ \value AmericanSignLanguage Since Qt 5.7
\value Amharic
+ \value AncientEgyptian Since Qt 5.1
+ \value AncientGreek Since Qt 5.1
+ \value AncientNorthArabian Since Qt 5.5
\value Arabic
+ \value Aragonese Since Qt 5.1
+ \value Aramaic Since Qt 5.1
+ \value ArdhamagadhiPrakrit Since Qt 5.7
\value Armenian
\value Assamese
+ \value Asturian
+ \value Asu
+ \value Atsam
\value Avaric
+ \value Avestan
\value Aymara
\value Azerbaijani
+ \value Bafia
+ \value Balinese Since Qt 5.1
+ \value Bambara
+ \value Bamun Since Qt 5.1
+ \value Basaa
\value Bashkir
\value Basque
+ \value Bassa Since Qt 5.5
+ \value BatakToba Since Qt 5.1
+ \value Belarusian
+ \value Bemba
+ \value Bena
\value Bengali
- \value Dzongkha
+ \value Bhojpuri Since Qt 5.7
\value Bhutani Obsolete, please use Dzongkha
\value Bihari
\value Bislama
- \value Bosnian
+ \value Blin
\value Bodo
+ \value Bosnian
\value Breton
+ \value Buginese Since Qt 5.1
+ \value Buhid Since Qt 5.1
\value Bulgarian
\value Burmese
- \value Belarusian
\value Byelorussian Obsolete, please use Belarusian
- \value Khmer
\value Cambodian Obsolete, please use Khmer
+ \value Cantonese Since Qt 5.7
+ \value Carian Since Qt 5.1
\value Catalan
+ \value CentralKurdish Since Qt 5.5
+ \value CentralMoroccoTamazight
+ \value Chakma Since Qt 5.1
\value Chamorro
\value Chechen
+ \value Cherokee
+ \value Chewa Obsolete, please use Nyanja
+ \value Chiga
\value Chinese
\value Church
\value Chuvash
+ \value ClassicalMandaic Since Qt 5.1
+ \value Colognian
+ \value CongoSwahili
+ \value Coptic Since Qt 5.1
\value Cornish
\value Corsican
\value Cree
@@ -148,33 +186,58 @@
\value Czech
\value Danish
\value Divehi
+ \value Dogri Since Qt 5.1
+ \value Duala
\value Dutch
+ \value Dzongkha
+ \value EasternCham Since Qt 5.1
+ \value EasternKayah Since Qt 5.1
+ \value Embu
\value English
\value Esperanto
\value Estonian
+ \value Etruscan Since Qt 5.1
+ \value Ewe
+ \value Ewondo
\value Faroese
\value Fijian
+ \value Filipino
\value Finnish
\value French
- \value WesternFrisian same as Frisian
\value Frisian same as WesternFrisian
+ \value Friulian
+ \value Fulah
+ \value Ga
\value Gaelic
\value Galician
+ \value Ganda
+ \value Geez
\value Georgian
\value German
+ \value Gothic Since Qt 5.1
\value Greek
\value Greenlandic
\value Guarani
\value Gujarati
+ \value Gusii
\value Haitian
+ \value Hanunoo Since Qt 5.1
\value Hausa
+ \value Hawaiian
\value Hebrew
\value Herero
+ \value HieroglyphicLuwian Since Qt 5.7
\value Hindi
\value HiriMotu
+ \value HmongNjua Since Qt 5.5
+ \value Ho Since Qt 5.5
\value Hungarian
\value Icelandic
+ \value Ido Since Qt 5.12
+ \value Igbo
+ \value InariSami Since Qt 5.5
\value Indonesian
+ \value Ingush Since Qt 5.1
\value Interlingua
\value Interlingue
\value Inuktitut
@@ -183,306 +246,244 @@
\value Italian
\value Japanese
\value Javanese
+ \value Jju
+ \value JolaFonyi
+ \value Kabuverdianu
+ \value Kabyle
+ \value Kako
+ \value Kalenjin
+ \value Kamba
\value Kannada
\value Kanuri
\value Kashmiri
\value Kazakh
+ \value Kenyang Since Qt 5.5
+ \value Khmer
+ \value Kiche Since Qt 5.5
+ \value Kikuyu
\value Kinyarwanda
\value Kirghiz
\value Komi
\value Kongo
+ \value Konkani
\value Korean
+ \value Koro
+ \value KoyraboroSenni
+ \value KoyraChiini
+ \value Kpelle
\value Kurdish
- \value Rundi
\value Kurundi Obsolete, please use Rundi
\value Kwanyama
+ \value Kwasio
\value Lakota Since Qt 5.3
+ \value Langi
\value Lao
+ \value LargeFloweryMiao Since Qt 5.1
\value Latin
\value Latvian
+ \value Lepcha Since Qt 5.1
+ \value Lezghian Since Qt 5.5
\value Limburgish
+ \value Limbu Since Qt 5.1
+ \value LinearA Since Qt 5.5
\value Lingala
+ \value Lisu Since Qt 5.1
+ \value LiteraryChinese Since Qt 5.7
\value Lithuanian
+ \value Lojban Since Qt 5.12
+ \value LowerSorbian Since Qt 5.5
+ \value LowGerman
\value LubaKatanga
+ \value LuleSami Since Qt 5.5
+ \value Luo
+ \value Lu Since Qt 5.1
\value Luxembourgish
- \value Marshallese
+ \value Luyia
+ \value Lycian Since Qt 5.1
+ \value Lydian Since Qt 5.1
\value Macedonian
+ \value Machame
+ \value Maithili Since Qt 5.5
+ \value MakhuwaMeetto
+ \value Makonde
\value Malagasy
\value Malay
\value Malayalam
\value Maltese
+ \value Mandingo Since Qt 5.1
+ \value ManichaeanMiddlePersian Since Qt 5.5
+ \value Manipuri Since Qt 5.1
\value Manx
\value Maori
+ \value Mapuche Since Qt 5.5
\value Marathi
+ \value Marshallese
+ \value Masai
+ \value Mazanderani Since Qt 5.7
+ \value Mende Since Qt 5.5
+ \value Meroitic Since Qt 5.1
+ \value Meru
+ \value Meta
+ \value Mohawk Since Qt 5.5
\value Moldavian Obsolete, please use Romanian
\value Mongolian
+ \value Mono Since Qt 5.5
+ \value Morisyen
+ \value Mru Since Qt 5.7
+ \value Mundang
+ \value Nama
\value NauruLanguage
\value Navaho
\value Ndonga
\value Nepali
- \value Norwegian same as NorwegianBokmal
+ \value Newari Since Qt 5.7
+ \value Ngiemboon
+ \value Ngomba
+ \value Nko Since Qt 5.5
+ \value NorthernLuri Since Qt 5.7
+ \value NorthernSami
+ \value NorthernSotho
+ \value NorthernThai Since Qt 5.1
+ \value NorthNdebele
\value NorwegianBokmal same as Norwegian
\value NorwegianNynorsk
+ \value Norwegian same as NorwegianBokmal
+ \value Nuer
+ \value Nyanja
+ \value Nyankole
\value Occitan
\value Ojibwa
+ \value OldIrish Since Qt 5.1
+ \value OldNorse Since Qt 5.1
+ \value OldPersian Since Qt 5.1
+ \value OldTurkish Since Qt 5.1
\value Oriya
+ \value Oromo
+ \value Osage Since Qt 5.7
\value Ossetic
+ \value Pahlavi Since Qt 5.1
+ \value Palauan Since Qt 5.7
\value Pali
+ \value Papiamento Since Qt 5.7
+ \value Parthian Since Qt 5.1
\value Pashto
\value Persian
+ \value Phoenician Since Qt 5.1
\value Polish
\value Portuguese
+ \value PrakritLanguage Since Qt 5.1
+ \value Prussian Since Qt 5.5
\value Punjabi
\value Quechua
- \value Romansh
+ \value Rejang Since Qt 5.1
\value RhaetoRomance Obsolete, please use Romansh
\value Romanian
+ \value Romansh
+ \value Rombo
+ \value Rundi
\value Russian
+ \value Rwa
+ \value Sabaean Since Qt 5.1
+ \value Saho
+ \value Sakha
+ \value Samaritan Since Qt 5.1
+ \value Samburu
\value Samoan
\value Sango
+ \value Sangu
\value Sanskrit
+ \value Santali Since Qt 5.1
+ \value Saraiki Since Qt 5.7
\value Sardinian
+ \value Saurashtra Since Qt 5.1
+ \value Sena
\value Serbian
\value SerboCroatian Obsolete, please use Serbian
- \value SouthernSotho
- \value Tswana
+ \value Shambala
\value Shona
+ \value SichuanYi
+ \value Sicilian Since Qt 5.12
+ \value Sidamo
\value Sindhi
\value Sinhala
- \value Swati
+ \value SkoltSami Since Qt 5.5
\value Slovak
\value Slovenian
+ \value Soga
\value Somali
+ \value Sora Since Qt 5.1
+ \value SouthernKurdish Since Qt 5.12
+ \value SouthernSami Since Qt 5.5
+ \value SouthernSotho
+ \value SouthNdebele
\value Spanish
\value StandardMoroccanTamazight Since Qt 5.3
\value Sundanese
\value Swahili
+ \value Swati
\value Swedish
+ \value SwissGerman
+ \value Sylheti Since Qt 5.1
+ \value Syriac
+ \value Tachelhit
\value Tagalog Obsolete, please use Filipino
+ \value Tagbanwa Since Qt 5.1
\value Tahitian
+ \value TaiDam Since Qt 5.1
+ \value TaiNua Since Qt 5.1
+ \value Taita
\value Tajik
\value Tamil
+ \value Tangut Since Qt 5.7
+ \value Taroko
+ \value Tasawaq
\value Tatar
+ \value TedimChin Since Qt 5.5
\value Telugu
+ \value Teso
\value Thai
\value Tibetan
+ \value Tigre
\value Tigrinya
+ \value TokelauLanguage Since Qt 5.7
+ \value TokPisin Since Qt 5.7
\value Tongan
\value Tsonga
+ \value Tswana
\value Turkish
\value Turkmen
+ \value TuvaluLanguage Since Qt 5.7
\value Twi Obsolete, please use Akan
+ \value Tyap
+ \value Ugaritic Since Qt 5.1
\value Uighur
\value Uigur Obsolete, please use Uighur
\value Ukrainian
+ \value UncodedLanguages Since Qt 5.7
+ \value UpperSorbian Since Qt 5.5
\value Urdu
\value Uzbek
+ \value Vai
+ \value Venda
\value Vietnamese
\value Volapuk
+ \value Vunjo
+ \value Walamo
\value Walloon
+ \value Walser
+ \value Warlpiri Since Qt 5.5
\value Welsh
+ \value WesternBalochi Since Qt 5.12
+ \value WesternFrisian same as Frisian
\value Wolof
\value Xhosa
+ \value Yangben
\value Yiddish
\value Yoruba
+ \value Zarma
\value Zhuang
\value Zulu
- \value Bosnian
- \value Divehi
- \value Manx
- \value Cornish
- \value Akan
- \value Konkani
- \value Ga
- \value Igbo
- \value Kamba
- \value Syriac
- \value Blin
- \value Geez
- \value Koro
- \value Sidamo
- \value Atsam
- \value Tigre
- \value Jju
- \value Friulian
- \value Venda
- \value Ewe
- \value Walamo
- \value Hawaiian
- \value Tyap
- \value Nyanja
- \value Chewa Obsolete, please use Nyanja
- \value Filipino
- \value SwissGerman
- \value SichuanYi
- \value Kpelle
- \value LowGerman
- \value SouthNdebele
- \value NorthernSotho
- \value NorthernSami
- \value Taroko
- \value Gusii
- \value Taita
- \value Fulah
- \value Kikuyu
- \value Samburu
- \value Sena
- \value NorthNdebele
- \value Rombo
- \value Tachelhit
- \value Kabyle
- \value Nyankole
- \value Bena
- \value Vunjo
- \value Bambara
- \value Embu
- \value Cherokee
- \value Morisyen
- \value Makonde
- \value Langi
- \value Ganda
- \value Bemba
- \value Kabuverdianu
- \value Meru
- \value Kalenjin
- \value Nama
- \value Machame
- \value Colognian
- \value Masai
- \value Soga
- \value Luyia
- \value Asu
- \value Teso
- \value Saho
- \value KoyraChiini
- \value Rwa
- \value Luo
- \value Chiga
- \value CentralMoroccoTamazight
- \value KoyraboroSenni
- \value Shambala
- \value Aghem
- \value Basaa
- \value Zarma
- \value Duala
- \value JolaFonyi
- \value Ewondo
- \value Bafia
- \value MakhuwaMeetto
- \value Mundang
- \value Kwasio
- \value Nuer
- \value Sakha
- \value Sangu
- \value CongoSwahili
- \value Tasawaq
- \value Vai
- \value Walser
- \value Yangben
- \value Avestan
- \value Asturian
- \value Ngomba
- \value Kako
- \value Meta
- \value Ngiemboon
- \value Aragonese
- \value Akkadian
- \value AncientEgyptian
- \value AncientGreek
- \value Aramaic
- \value Balinese
- \value Bamun
- \value BatakToba
- \value Buginese
- \value Buhid
- \value Carian
- \value Chakma
- \value ClassicalMandaic
- \value Coptic
- \value Dogri
- \value EasternCham
- \value EasternKayah
- \value Etruscan
- \value Gothic
- \value Hanunoo
- \value Ingush
- \value LargeFloweryMiao
- \value Lepcha
- \value Limbu
- \value Lisu
- \value Lu
- \value Lycian
- \value Lydian
- \value Mandingo
- \value Manipuri
- \value Meroitic
- \value NorthernThai
- \value OldIrish
- \value OldNorse
- \value OldPersian
- \value OldTurkish
- \value Pahlavi
- \value Parthian
- \value Phoenician
- \value PrakritLanguage
- \value Rejang
- \value Sabaean
- \value Samaritan
- \value Santali
- \value Saurashtra
- \value Sora
- \value Sylheti
- \value Tagbanwa
- \value TaiDam
- \value TaiNua
- \value Ugaritic
- \value Mapuche Since Qt 5.5
- \value CentralKurdish Since Qt 5.5
- \value LowerSorbian Since Qt 5.5
- \value UpperSorbian Since Qt 5.5
- \value Kenyang Since Qt 5.5
- \value Mohawk Since Qt 5.5
- \value Nko Since Qt 5.5
- \value Prussian Since Qt 5.5
- \value Kiche Since Qt 5.5
- \value SouthernSami Since Qt 5.5
- \value LuleSami Since Qt 5.5
- \value InariSami Since Qt 5.5
- \value SkoltSami Since Qt 5.5
- \value Warlpiri Since Qt 5.5
- \value ManichaeanMiddlePersian Since Qt 5.5
- \value Mende Since Qt 5.5
- \value AncientNorthArabian Since Qt 5.5
- \value LinearA Since Qt 5.5
- \value HmongNjua Since Qt 5.5
- \value Ho Since Qt 5.5
- \value Lezghian Since Qt 5.5
- \value Bassa Since Qt 5.5
- \value Mono Since Qt 5.5
- \value TedimChin Since Qt 5.5
- \value Maithili Since Qt 5.5
- \value LowerSorbian Since Qt 5.5
- \value UpperSorbian Since Qt 5.5
- \value Ahom Since Qt 5.7
- \value AmericanSignLanguage Since Qt 5.7
- \value ArdhamagadhiPrakrit Since Qt 5.7
- \value Bhojpuri Since Qt 5.7
- \value Cantonese Since Qt 5.7
- \value HieroglyphicLuwian Since Qt 5.7
- \value LiteraryChinese Since Qt 5.7
- \value Mazanderani Since Qt 5.7
- \value Mru Since Qt 5.7
- \value Newari Since Qt 5.7
- \value NorthernLuri Since Qt 5.7
- \value Osage Since Qt 5.7
- \value Palauan Since Qt 5.7
- \value Papiamento Since Qt 5.7
- \value Saraiki Since Qt 5.7
- \value Tangut Since Qt 5.7
- \value TokelauLanguage Since Qt 5.7
- \value TokPisin Since Qt 5.7
- \value TuvaluLanguage Since Qt 5.7
- \value UncodedLanguages Since Qt 5.7
+
\omitvalue LastLanguage
\sa language(), languageToString()
@@ -494,7 +495,9 @@
This enumerated type is used to specify a country.
\value AnyCountry
+
\value Afghanistan
+ \value AlandIslands
\value Albania
\value Algeria
\value AmericanSamoa
@@ -506,6 +509,7 @@
\value Argentina
\value Armenia
\value Aruba
+ \value AscensionIsland
\value Australia
\value Austria
\value Azerbaijan
@@ -520,11 +524,13 @@
\value Bermuda
\value Bhutan
\value Bolivia
+ \value Bonaire
\value BosniaAndHerzegowina
\value Botswana
\value BouvetIsland
\value Brazil
\value BritishIndianOceanTerritory
+ \value BritishVirginIslands
\value Brunei
\value Bulgaria
\value BurkinaFaso
@@ -536,6 +542,7 @@
\value CapeVerde
\value CaymanIslands
\value CentralAfricanRepublic
+ \value CeutaAndMelilla
\value Chad
\value Chile
\value China
@@ -544,18 +551,19 @@
\value CocosIslands
\value Colombia
\value Comoros
- \value CongoKinshasa
\value CongoBrazzaville
- \value DemocraticRepublicOfCongo Obsolete, please use CongoKinshasa
- \value PeoplesRepublicOfCongo Obsolete, please use CongoBrazzaville
+ \value CongoKinshasa
\value CookIslands
\value CostaRica
- \value IvoryCoast
\value Croatia
\value Cuba
+ \value CuraSao
\value Cyprus
\value CzechRepublic
+ \value DemocraticRepublicOfCongo Obsolete, please use CongoKinshasa
+ \value DemocraticRepublicOfKorea Obsolete, please use NorthKorea
\value Denmark
+ \value DiegoGarcia
\value Djibouti
\value Dominica
\value DominicanRepublic
@@ -604,19 +612,18 @@
\value Iran
\value Iraq
\value Ireland
+ \value IsleOfMan
\value Israel
\value Italy
+ \value IvoryCoast
\value Jamaica
\value Japan
+ \value Jersey
\value Jordan
\value Kazakhstan
\value Kenya
\value Kiribati
- \value NorthKorea
- \value SouthKorea
- \value DemocraticRepublicOfKorea Obsolete, please use NorthKorea
- \value RepublicOfKorea Obsolete, please use SouthKorea
- \value Kosovo
+ \value Kosovo Since Qt 5.2
\value Kuwait
\value Kyrgyzstan
\value Laos
@@ -648,6 +655,7 @@
\value Moldova
\value Monaco
\value Mongolia
+ \value Montenegro
\value Montserrat
\value Morocco
\value Mozambique
@@ -664,6 +672,7 @@
\value Niue
\value NorfolkIsland
\value NorthernMarianaIslands
+ \value NorthKorea
\value Norway
\value Oman
\value OutlyingOceania Since Qt 5.7
@@ -673,6 +682,7 @@
\value Panama
\value PapuaNewGuinea
\value Paraguay
+ \value PeoplesRepublicOfCongo Obsolete, please use CongoBrazzaville
\value Peru
\value Philippines
\value Pitcairn
@@ -680,32 +690,39 @@
\value Portugal
\value PuertoRico
\value Qatar
+ \value RepublicOfKorea Obsolete, please use SouthKorea
\value Reunion
\value Romania
- \value Russia same as RussianFederation
\value RussianFederation same as Russia
+ \value Russia same as RussianFederation
\value Rwanda
+ \value SaintBarthelemy
+ \value SaintHelena
\value SaintKittsAndNevis
\value SaintLucia
+ \value SaintMartin
+ \value SaintPierreAndMiquelon
\value SaintVincentAndTheGrenadines
\value Samoa
\value SanMarino
\value SaoTomeAndPrincipe
\value SaudiArabia
\value Senegal
+ \value Serbia
\value Seychelles
\value SierraLeone
\value Singapore
+ \value SintMaarten
\value Slovakia
\value Slovenia
\value SolomonIslands
\value Somalia
\value SouthAfrica
\value SouthGeorgiaAndTheSouthSandwichIslands
+ \value SouthKorea
+ \value SouthSudan
\value Spain
\value SriLanka
- \value SaintHelena
- \value SaintPierreAndMiquelon
\value Sudan
\value Suriname
\value SvalbardAndJanMayenIslands
@@ -723,6 +740,7 @@
\value Tokelau Obsolete, please use TokelauCountry
\value Tonga
\value TrinidadAndTobago
+ \value TristanDaCunha
\value Tunisia
\value Turkey
\value Turkmenistan
@@ -735,35 +753,20 @@
\value UnitedKingdom
\value UnitedStates
\value UnitedStatesMinorOutlyingIslands
+ \value UnitedStatesVirginIslands
\value Uruguay
\value Uzbekistan
\value Vanuatu
\value VaticanCityState
\value Venezuela
\value Vietnam
- \value BritishVirginIslands
- \value UnitedStatesVirginIslands
\value WallisAndFutunaIslands
\value WesternSahara
\value World Since Qt 5.12
\value Yemen
\value Zambia
\value Zimbabwe
- \value Montenegro
- \value Serbia
- \value SaintBarthelemy
- \value SaintMartin
- \value AscensionIsland
- \value AlandIslands
- \value DiegoGarcia
- \value CeutaAndMelilla
- \value IsleOfMan
- \value Jersey
- \value TristanDaCunha
- \value SouthSudan
- \value CuraSao
- \value Bonaire
- \value SintMaarten
+
\omitvalue LastCountry
\sa country(), countryToString()
@@ -775,135 +778,136 @@
This enumerated type is used to specify a script.
\value AnyScript
+
\value AdlamScript Since Qt 5.7
\value AhomScript Since Qt 5.7
\value AnatolianHieroglyphsScript Since Qt 5.7
\value ArabicScript
\value ArmenianScript
- \value AvestanScript
- \value BalineseScript
- \value BamumScript
+ \value AvestanScript Since Qt 5.1
+ \value BalineseScript Since Qt 5.1
+ \value BamumScript Since Qt 5.1
\value BassaVahScript Since Qt 5.5
- \value BatakScript
+ \value BatakScript Since Qt 5.1
\value BengaliScript
\value BhaiksukiScript Since Qt 5.7
- \value BopomofoScript
- \value BrahmiScript
- \value BrailleScript
- \value BugineseScript
- \value BuhidScript
- \value CanadianAboriginalScript
- \value CarianScript
+ \value BopomofoScript Since Qt 5.1
+ \value BrahmiScript Since Qt 5.1
+ \value BrailleScript Since Qt 5.1
+ \value BugineseScript Since Qt 5.1
+ \value BuhidScript Since Qt 5.1
+ \value CanadianAboriginalScript Since Qt 5.1
+ \value CarianScript Since Qt 5.1
\value CaucasianAlbanianScript Since Qt 5.5
- \value ChakmaScript
- \value ChamScript
+ \value ChakmaScript Since Qt 5.1
+ \value ChamScript Since Qt 5.1
\value CherokeeScript
- \value CopticScript
- \value CypriotScript
+ \value CopticScript Since Qt 5.1
+ \value CuneiformScript Since Qt 5.1
+ \value CypriotScript Since Qt 5.1
\value CyrillicScript
- \value DeseretScript
+ \value DeseretScript Since Qt 5.1
\value DevanagariScript
\value DuployanScript Since Qt 5.5
- \value EgyptianHieroglyphsScript
+ \value EgyptianHieroglyphsScript Since Qt 5.1
\value ElbasanScript Since Qt 5.5
\value EthiopicScript
- \value FraserScript
+ \value FraserScript Since Qt 5.1
\value GeorgianScript
- \value GlagoliticScript
- \value GothicScript
+ \value GlagoliticScript Since Qt 5.1
+ \value GothicScript Since Qt 5.1
\value GranthaScript Since Qt 5.5
\value GreekScript
\value GujaratiScript
\value GurmukhiScript
- \value HanScript
- \value HangulScript
- \value HanunooScript
+ \value HangulScript Since Qt 5.1
+ \value HanScript Since Qt 5.1
+ \value HanunooScript Since Qt 5.1
\value HanWithBopomofoScript Since Qt 5.7
\value HatranScript Since Qt 5.7
\value HebrewScript
- \value HiraganaScript
- \value ImperialAramaicScript
- \value InscriptionalPahlaviScript
- \value InscriptionalParthianScript
+ \value HiraganaScript Since Qt 5.1
+ \value ImperialAramaicScript Since Qt 5.1
+ \value InscriptionalPahlaviScript Since Qt 5.1
+ \value InscriptionalParthianScript Since Qt 5.1
\value JamoScript Since Qt 5.7
\value JapaneseScript
- \value JavaneseScript
- \value KaithiScript
+ \value JavaneseScript Since Qt 5.1
+ \value KaithiScript Since Qt 5.1
\value KannadaScript
- \value KatakanaScript
- \value KayahLiScript
- \value KharoshthiScript
- \value KhmerScript
+ \value KatakanaScript Since Qt 5.1
+ \value KayahLiScript Since Qt 5.1
+ \value KharoshthiScript Since Qt 5.1
+ \value KhmerScript Since Qt 5.1
\value KhojkiScript Since Qt 5.5
\value KhudawadiScript Since Qt 5.5
\value KoreanScript
- \value LannaScript
+ \value LannaScript Since Qt 5.1
\value LaoScript
\value LatinScript
- \value LepchaScript
- \value LimbuScript
+ \value LepchaScript Since Qt 5.1
+ \value LimbuScript Since Qt 5.1
\value LinearAScript Since Qt 5.5
- \value LinearBScript
- \value LycianScript
- \value LydianScript
+ \value LinearBScript Since Qt 5.1
+ \value LycianScript Since Qt 5.1
+ \value LydianScript Since Qt 5.1
\value MahajaniScript Since Qt 5.5
\value MalayalamScript
- \value MandaeanScript
+ \value MandaeanScript Since Qt 5.1
\value ManichaeanScript Since Qt 5.5
\value MarchenScript Since Qt 5.7
- \value MeiteiMayekScript
+ \value MeiteiMayekScript Since Qt 5.1
\value MendeKikakuiScript Since Qt 5.5
- \value MeroiticScript
- \value MeroiticCursiveScript
+ \value MeroiticCursiveScript Since Qt 5.1
+ \value MeroiticScript Since Qt 5.1
\value ModiScript Since Qt 5.5
\value MongolianScript
\value MroScript Since Qt 5.5
\value MultaniScript Since Qt 5.7
\value MyanmarScript
\value NabataeanScript Since Qt 5.5
- \value NkoScript
\value NewaScript Since Qt 5.7
- \value NewTaiLueScript
- \value OghamScript
- \value OlChikiScript
- \value OldItalicScript
+ \value NewTaiLueScript Since Qt 5.1
+ \value NkoScript Since Qt 5.1
+ \value OghamScript Since Qt 5.1
+ \value OlChikiScript Since Qt 5.1
\value OldHungarianScript Since Qt 5.7
+ \value OldItalicScript Since Qt 5.1
\value OldNorthArabianScript Since Qt 5.5
\value OldPermicScript Since Qt 5.5
- \value OldPersianScript
- \value OldSouthArabianScript
+ \value OldPersianScript Since Qt 5.1
+ \value OldSouthArabianScript Since Qt 5.1
\value OriyaScript
- \value OrkhonScript
+ \value OrkhonScript Since Qt 5.1
\value OsageScript Since Qt 5.7
- \value OsmanyaScript
+ \value OsmanyaScript Since Qt 5.1
\value PahawhHmongScript Since Qt 5.5
\value PalmyreneScript Since Qt 5.5
\value PauCinHauScript Since Qt 5.5
- \value PhagsPaScript
- \value PhoenicianScript
- \value PollardPhoneticScript
+ \value PhagsPaScript Since Qt 5.1
+ \value PhoenicianScript Since Qt 5.1
+ \value PollardPhoneticScript Since Qt 5.1
\value PsalterPahlaviScript Since Qt 5.5
- \value RejangScript
- \value RunicScript
- \value SamaritanScript
- \value SaurashtraScript
- \value SharadaScript
- \value ShavianScript
+ \value RejangScript Since Qt 5.1
+ \value RunicScript Since Qt 5.1
+ \value SamaritanScript Since Qt 5.1
+ \value SaurashtraScript Since Qt 5.1
+ \value SharadaScript Since Qt 5.1
+ \value ShavianScript Since Qt 5.1
\value SiddhamScript Since Qt 5.5
\value SignWritingScript Since Qt 5.7
- \value SimplifiedHanScript same as SimplifiedChineseScript
\value SimplifiedChineseScript same as SimplifiedHanScript
+ \value SimplifiedHanScript same as SimplifiedChineseScript
\value SinhalaScript
- \value SoraSompengScript
- \value CuneiformScript
- \value SundaneseScript
- \value SylotiNagriScript
+ \value SoraSompengScript Since Qt 5.1
+ \value SundaneseScript Since Qt 5.1
+ \value SylotiNagriScript Since Qt 5.1
\value SyriacScript
- \value TagalogScript
- \value TagbanwaScript
- \value TaiLeScript
- \value TaiVietScript
- \value TakriScript
+ \value TagalogScript Since Qt 5.1
+ \value TagbanwaScript Since Qt 5.1
+ \value TaiLeScript Since Qt 5.1
+ \value TaiVietScript Since Qt 5.1
+ \value TakriScript Since Qt 5.1
\value TamilScript
\value TangutScript Since Qt 5.7
\value TeluguScript
@@ -912,12 +916,13 @@
\value TibetanScript
\value TifinaghScript
\value TirhutaScript Since Qt 5.5
- \value TraditionalHanScript same as TraditionalChineseScript
\value TraditionalChineseScript same as TraditionalHanScript
- \value UgariticScript
+ \value TraditionalHanScript same as TraditionalChineseScript
+ \value UgariticScript Since Qt 5.1
\value VaiScript
\value VarangKshitiScript Since Qt 5.5
\value YiScript
+
\omitvalue LastScript
\sa script(), scriptToString(), languageToString()
@@ -1158,6 +1163,30 @@
currency string.
*/
+/*!
+\fn QString QLocale::toString(long i) const
+
+\overload
+
+\sa toLong()
+*/
+
+/*!
+\fn QString QLocale::toString(ulong i) const
+
+\overload
+
+\sa toULong()
+*/
+
+/*!
+\fn QString QLocale::toString(ushort i) const
+
+\overload
+
+\sa toUShort()
+*/
+
/*!
\fn QString QLocale::toString(short i) const
diff --git a/src/corelib/tools/qlocale_data_p.h b/src/corelib/tools/qlocale_data_p.h
index 507afdcecd..58e71e1dcc 100644
--- a/src/corelib/tools/qlocale_data_p.h
+++ b/src/corelib/tools/qlocale_data_p.h
@@ -77,7 +77,7 @@ static const int ImperialMeasurementSystemsCount =
// GENERATED PART STARTS HERE
/*
- This part of the file was generated on 2018-10-19 from the
+ This part of the file was generated on 2018-11-08 from the
Common Locale Data Repository v34
http://www.unicode.org/cldr/
@@ -122,6 +122,7 @@ static const QLocaleId likely_subtags[] = {
{ 195, 0, 0 }, { 195, 7, 239 }, // bem -> bem_Latn_ZM
{ 186, 0, 0 }, { 186, 7, 210 }, // bez -> bez_Latn_TZ
{ 20, 0, 0 }, { 20, 2, 33 }, // bg -> bg_Cyrl_BG
+ { 364, 0, 0 }, { 364, 1, 163 }, // bgn -> bgn_Arab_PK
{ 343, 0, 0 }, { 343, 13, 100 }, // bho -> bho_Deva_IN
{ 18, 0, 0 }, { 18, 7, 229 }, // bi -> bi_Latn_VU
{ 270, 0, 0 }, { 270, 7, 170 }, // bku -> bku_Latn_PH
@@ -224,10 +225,12 @@ static const QLocaleId likely_subtags[] = {
{ 168, 0, 0 }, { 168, 34, 44 }, // ii -> ii_Yiii_CN
{ 56, 0, 0 }, { 56, 7, 225 }, // ik -> ik_Latn_US
{ 281, 0, 0 }, { 281, 2, 178 }, // inh -> inh_Cyrl_RU
+ { 360, 0, 0 }, { 360, 7, 260 }, // io -> io_Latn_001
{ 51, 0, 0 }, { 51, 7, 99 }, // is -> is_Latn_IS
{ 58, 0, 0 }, { 58, 7, 106 }, // it -> it_Latn_IT
{ 55, 0, 0 }, { 55, 44, 38 }, // iu -> iu_Cans_CA
{ 59, 0, 0 }, { 59, 19, 108 }, // ja -> ja_Jpan_JP
+ { 361, 0, 0 }, { 361, 7, 260 }, // jbo -> jbo_Latn_001
{ 257, 0, 0 }, { 257, 7, 37 }, // jgo -> jgo_Latn_CM
{ 200, 0, 0 }, { 200, 7, 210 }, // jmc -> jmc_Latn_TZ
{ 60, 0, 0 }, { 60, 7, 101 }, // jv -> jv_Latn_ID
@@ -385,10 +388,12 @@ static const QLocaleId likely_subtags[] = {
{ 305, 0, 0 }, { 305, 90, 100 }, // saz -> saz_Saur_IN
{ 249, 0, 0 }, { 249, 7, 210 }, // sbp -> sbp_Latn_TZ
{ 115, 0, 0 }, { 115, 7, 106 }, // sc -> sc_Latn_IT
+ { 362, 0, 0 }, { 362, 7, 106 }, // scn -> scn_Latn_IT
{ 105, 0, 0 }, { 105, 1, 163 }, // sd -> sd_Arab_PK
{ 105, 13, 0 }, { 105, 13, 100 }, // sd_Deva -> sd_Deva_IN
{ 105, 111, 0 }, { 105, 111, 100 }, // sd_Khoj -> sd_Khoj_IN
{ 105, 125, 0 }, { 105, 125, 100 }, // sd_Sind -> sd_Sind_IN
+ { 363, 0, 0 }, { 363, 1, 102 }, // sdh -> sdh_Arab_IR
{ 173, 0, 0 }, { 173, 7, 161 }, // se -> se_Latn_NO
{ 180, 0, 0 }, { 180, 7, 146 }, // seh -> seh_Latn_MZ
{ 213, 0, 0 }, { 213, 7, 132 }, // ses -> ses_Latn_ML
@@ -1252,6 +1257,11 @@ static const quint16 locale_index[] = {
574, // Cantonese
0, // Osage
0, // Tangut
+ 576, // Ido
+ 577, // Lojban
+ 578, // Sicilian
+ 579, // Southern Kurdish
+ 580, // Western Balochi
0 // trailing 0
};
@@ -1592,13 +1602,13 @@ static const QLocaleData locale_data[] = {
{ 98, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 16581,48 , 16629,91 , 16720,24 , 16581,48 , 16629,91 , 16720,24 , 8692,28 , 8720,66 , 8786,14 , 8692,28 , 8720,66 , 8786,14 , 226,2 , 216,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 11499,25 , 4,4 , 36,5 , 3506,5 , 3511,22 , 0, 0, 1, 6, 7 }, // Sango/Latin/Central African Republic
{ 99, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 121,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 7, 7 }, // Sanskrit/Devanagari/India
{ 100, 2, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 16744,48 , 16792,81 , 12698,24 , 16744,48 , 16792,81 , 12698,24 , 8800,28 , 8828,52 , 8880,14 , 8800,28 , 8828,52 , 8880,14 , 228,9 , 218,8 , 803,7 , 5,17 , 22,23 , {82,83,68}, 288,3 , 11524,58 , 13,5 , 4,0 , 3533,6 , 3539,6 , 0, 0, 1, 6, 7 }, // Serbian/Cyrillic/Serbia
- { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 16873,50 , 16792,81 , 12698,24 , 16744,48 , 16792,81 , 12698,24 , 8894,26 , 8920,55 , 8880,14 , 8894,26 , 8920,55 , 8880,14 , 237,11 , 218,8 , 803,7 , 5,17 , 22,23 , {66,65,77}, 291,2 , 11582,174 , 13,5 , 4,0 , 3533,6 , 3545,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Bosnia And Herzegowina
- { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 16923,58 , 16792,81 , 12698,24 , 16923,58 , 16792,81 , 12698,24 , 8975,33 , 8920,55 , 8880,14 , 8975,33 , 8920,55 , 8880,14 , 237,11 , 218,8 , 803,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11756,23 , 13,5 , 4,0 , 3533,6 , 3564,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro
- { 100, 2, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 16923,58 , 16792,81 , 12698,24 , 16923,58 , 16792,81 , 12698,24 , 8975,33 , 8828,52 , 8880,14 , 8975,33 , 8828,52 , 8880,14 , 228,9 , 218,8 , 803,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11756,23 , 13,5 , 4,0 , 3533,6 , 3573,6 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Kosovo
- { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 16981,50 , 17031,81 , 9742,24 , 17112,48 , 17031,81 , 9742,24 , 9008,26 , 9034,57 , 2102,14 , 9008,26 , 9034,57 , 2102,14 , 248,11 , 226,8 , 296,7 , 5,17 , 22,23 , {66,65,77}, 144,2 , 11779,174 , 13,5 , 4,0 , 3579,6 , 620,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Bosnia And Herzegowina
- { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17160,58 , 17031,81 , 9742,24 , 17160,58 , 17031,81 , 9742,24 , 9091,33 , 9034,57 , 2102,14 , 9091,33 , 9034,57 , 2102,14 , 248,11 , 226,8 , 296,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11953,23 , 13,5 , 4,0 , 3579,6 , 3585,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro
- { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17112,48 , 17031,81 , 9742,24 , 17112,48 , 17031,81 , 9742,24 , 9124,28 , 9152,54 , 2102,14 , 9124,28 , 9152,54 , 2102,14 , 259,9 , 226,8 , 296,7 , 5,17 , 22,23 , {82,83,68}, 288,3 , 11976,58 , 13,5 , 4,0 , 3579,6 , 3594,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia
- { 100, 7, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17160,58 , 17031,81 , 9742,24 , 17160,58 , 17031,81 , 9742,24 , 9091,33 , 9152,54 , 2102,14 , 9091,33 , 9152,54 , 2102,14 , 259,9 , 226,8 , 296,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11953,23 , 13,5 , 4,0 , 3579,6 , 3600,6 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Kosovo
+ { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 16873,50 , 16923,81 , 9742,24 , 17004,48 , 16923,81 , 9742,24 , 8894,26 , 8920,57 , 2102,14 , 8894,26 , 8920,57 , 2102,14 , 237,11 , 226,8 , 296,7 , 5,17 , 22,23 , {66,65,77}, 144,2 , 11582,174 , 13,5 , 4,0 , 3545,6 , 620,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Bosnia And Herzegowina
+ { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17052,58 , 16923,81 , 9742,24 , 17052,58 , 16923,81 , 9742,24 , 8977,33 , 8920,57 , 2102,14 , 8977,33 , 8920,57 , 2102,14 , 237,11 , 226,8 , 296,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11756,23 , 13,5 , 4,0 , 3545,6 , 3551,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro
+ { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17004,48 , 16923,81 , 9742,24 , 17004,48 , 16923,81 , 9742,24 , 9010,28 , 9038,54 , 2102,14 , 9010,28 , 9038,54 , 2102,14 , 248,9 , 226,8 , 296,7 , 5,17 , 22,23 , {82,83,68}, 288,3 , 11779,58 , 13,5 , 4,0 , 3545,6 , 3560,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia
+ { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17110,50 , 16792,81 , 12698,24 , 16744,48 , 16792,81 , 12698,24 , 9092,26 , 9118,55 , 8880,14 , 9092,26 , 9118,55 , 8880,14 , 257,11 , 218,8 , 803,7 , 5,17 , 22,23 , {66,65,77}, 291,2 , 11837,174 , 13,5 , 4,0 , 3533,6 , 3566,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Bosnia And Herzegowina
+ { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17160,58 , 16792,81 , 12698,24 , 17160,58 , 16792,81 , 12698,24 , 9173,33 , 9118,55 , 8880,14 , 9173,33 , 9118,55 , 8880,14 , 257,11 , 218,8 , 803,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 12011,23 , 13,5 , 4,0 , 3533,6 , 3585,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro
+ { 100, 2, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17160,58 , 16792,81 , 12698,24 , 17160,58 , 16792,81 , 12698,24 , 9173,33 , 8828,52 , 8880,14 , 9173,33 , 8828,52 , 8880,14 , 228,9 , 218,8 , 803,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 12011,23 , 13,5 , 4,0 , 3533,6 , 3594,6 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Kosovo
+ { 100, 7, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17052,58 , 16923,81 , 9742,24 , 17052,58 , 16923,81 , 9742,24 , 8977,33 , 9038,54 , 2102,14 , 8977,33 , 9038,54 , 2102,14 , 248,9 , 226,8 , 296,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11756,23 , 13,5 , 4,0 , 3545,6 , 3600,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 , 610,9 , 610,9 , 156,8 , 1094,23 , 37,5 , 8,10 , 17218,63 , 17281,82 , 11058,24 , 17363,60 , 17423,86 , 11058,24 , 9206,28 , 9234,61 , 9295,14 , 9309,28 , 9337,61 , 9295,14 , 268,15 , 234,15 , 45,4 , 5,17 , 22,23 , {71,69,76}, 228,1 , 12034,17 , 8,5 , 4,0 , 3606,4 , 3610,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 , 610,9 , 610,9 , 156,8 , 1094,23 , 37,5 , 8,10 , 17218,63 , 17281,82 , 11058,24 , 17363,60 , 17423,86 , 11058,24 , 9206,28 , 9234,61 , 9295,14 , 9309,28 , 9337,61 , 9295,14 , 268,15 , 234,15 , 45,4 , 5,17 , 22,23 , {82,85,66}, 123,1 , 12051,17 , 8,5 , 4,0 , 3606,4 , 3621,6 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Russia
{ 102, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Southern Sotho/Latin/South Africa
@@ -1684,7 +1694,7 @@ static const QLocaleData locale_data[] = {
{ 140, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 842,9 , 851,8 , 547,6 , 35,18 , 37,5 , 8,10 , 23839,48 , 23887,91 , 134,24 , 23839,48 , 23887,91 , 23978,24 , 12558,28 , 12586,74 , 12660,14 , 12558,28 , 12586,74 , 12660,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 14929,67 , 4,4 , 4,0 , 4446,7 , 4453,17 , 2, 1, 7, 6, 7 }, // Zulu/Latin/South Africa
{ 141, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 495,10 , 478,17 , 37,5 , 441,16 , 5656,48 , 14503,83 , 134,24 , 24002,59 , 14503,83 , 134,24 , 12674,28 , 12702,51 , 2293,14 , 12753,28 , 12702,51 , 2293,14 , 414,9 , 380,11 , 45,4 , 5,17 , 22,23 , {78,79,75}, 190,2 , 9840,44 , 13,5 , 4,0 , 4470,7 , 4477,5 , 2, 0, 1, 6, 7 }, // Norwegian Nynorsk/Latin/Norway
{ 142, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 8216, 8217, 0,6 , 0,6 , 163,7 , 163,7 , 1507,11 , 450,19 , 37,5 , 8,10 , 8336,48 , 24061,83 , 9742,24 , 8336,48 , 24061,83 , 9742,24 , 2016,28 , 2044,58 , 2102,14 , 2016,28 , 2044,58 , 2116,14 , 423,10 , 391,7 , 296,7 , 5,17 , 22,23 , {66,65,77}, 144,2 , 14996,170 , 13,5 , 4,0 , 4482,8 , 620,19 , 2, 1, 1, 6, 7 }, // Bosnian/Latin/Bosnia And Herzegowina
- { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 24144,48 , 24192,83 , 12698,24 , 24144,48 , 24192,83 , 12698,24 , 12781,28 , 12809,56 , 8880,14 , 12781,28 , 12809,56 , 8880,14 , 228,9 , 398,7 , 45,4 , 5,17 , 22,23 , {66,65,77}, 291,2 , 15166,151 , 13,5 , 4,0 , 4490,8 , 3545,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/Bosnia And Herzegowina
+ { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 24144,48 , 24192,83 , 12698,24 , 24144,48 , 24192,83 , 12698,24 , 12781,28 , 12809,56 , 8880,14 , 12781,28 , 12809,56 , 8880,14 , 228,9 , 398,7 , 45,4 , 5,17 , 22,23 , {66,65,77}, 291,2 , 15166,151 , 13,5 , 4,0 , 4490,8 , 3566,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/Bosnia And Herzegowina
{ 143, 29, 131, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,86,82}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 5, 6, 7 }, // Divehi/Thaana/Maldives
{ 144, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 80,17 , 37,5 , 8,10 , 24275,102 , 24377,140 , 158,27 , 24275,102 , 24377,140 , 158,27 , 12865,30 , 12895,57 , 85,14 , 12865,30 , 12895,57 , 85,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {71,66,80}, 119,1 , 0,7 , 4,4 , 4,0 , 4498,5 , 4503,12 , 2, 1, 1, 6, 7 }, // Manx/Latin/Isle Of Man
{ 145, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 97,16 , 37,5 , 8,10 , 24517,46 , 24563,130 , 158,27 , 24517,46 , 24563,130 , 158,27 , 12952,28 , 12980,61 , 85,14 , 12952,28 , 12980,61 , 85,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {71,66,80}, 119,1 , 0,7 , 4,4 , 4,0 , 4515,8 , 4523,14 , 2, 1, 1, 6, 7 }, // Cornish/Latin/United Kingdom
@@ -1833,6 +1843,11 @@ static const QLocaleData locale_data[] = {
{ 349, 1, 103, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 39219,77 , 39219,77 , 158,27 , 39219,77 , 39219,77 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,81,68}, 44,5 , 0,7 , 8,5 , 4,0 , 5865,11 , 0,0 , 0, 0, 6, 5, 6 }, // Northern Luri/Arabic/Iraq
{ 357, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 1010,5 , 1010,5 , 394,8 , 423,14 , 198,6 , 215,13 , 4423,39 , 4423,39 , 158,27 , 4423,39 , 4423,39 , 158,27 , 1953,28 , 1953,28 , 1981,14 , 1953,28 , 1953,28 , 1981,14 , 58,2 , 55,2 , 45,4 , 5,17 , 22,23 , {72,75,68}, 134,3 , 17327,11 , 4,4 , 4,0 , 5876,2 , 5878,14 , 2, 1, 7, 6, 7 }, // Cantonese/Traditional Han/Hong Kong
{ 357, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 1010,5 , 1010,5 , 394,8 , 402,13 , 198,6 , 204,11 , 4423,39 , 4462,38 , 158,27 , 4423,39 , 4462,38 , 158,27 , 1932,21 , 1953,28 , 1981,14 , 1932,21 , 1953,28 , 1981,14 , 58,2 , 55,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 133,1 , 3122,13 , 4,4 , 4,0 , 5892,2 , 5894,7 , 2, 1, 7, 6, 7 }, // Cantonese/Simplified Han/China
+ { 360, 7, 260, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Ido/Latin/World
+ { 361, 7, 260, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Lojban/Latin/World
+ { 362, 7, 106, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Sicilian/Latin/Italy
+ { 363, 1, 102, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,82,82}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 6, 5, 5 }, // Southern Kurdish/Arabic/Iran
+ { 364, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {80,75,82}, 176,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Western Balochi/Arabic/Pakistan
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 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
};
@@ -2860,24 +2875,24 @@ static const ushort months_data[] = {
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, 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, 0x3b, 0x444, 0x435, 0x431,
-0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443,
-0x43b, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434,
-0x435, 0x446, 0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x431, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f,
-0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b,
-0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x432, 0x2e, 0x3b, 0x434, 0x435, 0x446, 0x2e,
-0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61,
-0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x74, 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, 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, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b,
-0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70,
-0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x42f, 0x43d,
+0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62,
+0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75,
+0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x74, 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, 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, 0x2e, 0x3b, 0x66, 0x65, 0x62,
+0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b,
+0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b,
+0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, 0x3b, 0x43c, 0x430,
+0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430,
+0x432, 0x433, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, 0x435, 0x446, 0x3b,
+0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x431, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b,
+0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43f,
+0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x432, 0x2e, 0x3b, 0x434, 0x435, 0x446, 0x2e, 0x3b, 0x42f, 0x43d,
0x432, 0x2e, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x2e, 0x3b, 0x410, 0x43f, 0x440, 0x2e, 0x3b,
0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x2e, 0x3b, 0x421,
0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x41e, 0x43a, 0x442, 0x2e, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x414, 0x435, 0x43a, 0x2e,
@@ -4429,23 +4444,23 @@ static const ushort days_data[] = {
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, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b,
-0x43d, 0x435, 0x434, 0x458, 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, 0x43d, 0x435, 0x434, 0x2e, 0x3b,
-0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x443, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435,
-0x442, 0x2e, 0x3b, 0x441, 0x443, 0x431, 0x2e, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x3b, 0x73,
-0x72, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x6a, 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, 0x69, 0x6a, 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, 0x6e, 0x65, 0x64, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e,
-0x3b, 0x75, 0x74, 0x2e, 0x3b, 0x73, 0x72, 0x2e, 0x3b, 0x10d, 0x65, 0x74, 0x2e, 0x3b, 0x70, 0x65, 0x74, 0x2e, 0x3b, 0x73,
-0x75, 0x62, 0x2e, 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, 0x446, 0x431, 0x3b, 0x41a, 0x440, 0x441, 0x3b, 0x414, 0x446, 0x433, 0x3b, 0x4d4, 0x440,
+0x43d, 0x3b, 0x43f, 0x3b, 0x443, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f,
+0x6e, 0x3b, 0x75, 0x74, 0x3b, 0x73, 0x72, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b,
+0x6e, 0x65, 0x64, 0x6a, 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, 0x69, 0x6a, 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, 0x6e, 0x65, 0x64,
+0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x75, 0x74, 0x2e, 0x3b, 0x73, 0x72, 0x2e, 0x3b, 0x10d, 0x65, 0x74, 0x2e, 0x3b,
+0x70, 0x65, 0x74, 0x2e, 0x3b, 0x73, 0x75, 0x62, 0x2e, 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, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435,
+0x434, 0x458, 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, 0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f, 0x43e,
+0x43d, 0x2e, 0x3b, 0x443, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, 0x442, 0x2e,
+0x3b, 0x441, 0x443, 0x431, 0x2e, 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, 0x4d5, 0x433, 0x3b, 0x426, 0x44b, 0x43f, 0x43f, 0x4d5, 0x440, 0x4d5, 0x43c, 0x3b, 0x41c,
@@ -5138,9 +5153,9 @@ static const ushort am_data[] = {
0x101, 0x6e, 0x74, 0x254, 0x301, 0x6e, 0x67, 0x254, 0x301, 0x70, 0x72, 0x69, 0x65, 0x161, 0x70, 0x69, 0x65, 0x74, 0x43f, 0x440,
0x435, 0x442, 0x43f, 0x43b, 0x430, 0x434, 0x43d, 0x435, 0x50, 0x47, 0x92e, 0x2e, 0x92a, 0x942, 0x2e, 0x4af, 0x2e, 0x4e9, 0x2e, 0x63a,
0x2e, 0x645, 0x2e, 0x642, 0x628, 0x644, 0x200c, 0x627, 0x632, 0x638, 0x647, 0x631, 0x64, 0x61, 0x20, 0x6d, 0x61, 0x6e, 0x68, 0xe3,
-0xa2a, 0xa42, 0x2e, 0xa26, 0xa41, 0x2e, 0x4e, 0x44, 0x43f, 0x440, 0x435, 0x20, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x43f, 0x440, 0x438,
-0x458, 0x435, 0x20, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x70, 0x72, 0x69, 0x6a, 0x65, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x70,
-0x72, 0x65, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x4d5, 0x43c, 0x431, 0x438, 0x441, 0x431, 0x43e, 0x43d, 0x44b, 0x20, 0x440, 0x430,
+0xa2a, 0xa42, 0x2e, 0xa26, 0xa41, 0x2e, 0x4e, 0x44, 0x43f, 0x440, 0x435, 0x20, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x70, 0x72, 0x69,
+0x6a, 0x65, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x70, 0x72, 0x65, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x43f, 0x440, 0x438,
+0x458, 0x435, 0x20, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x4d5, 0x43c, 0x431, 0x438, 0x441, 0x431, 0x43e, 0x43d, 0x44b, 0x20, 0x440, 0x430,
0x437, 0x43c, 0x4d5, 0x635, 0x628, 0x62d, 0x60c, 0x20, 0x645, 0x646, 0x62c, 0x647, 0x646, 0x62f, 0xdb4, 0xdd9, 0x2e, 0xdc0, 0x2e, 0x73,
0x6e, 0x2e, 0x66, 0x6d, 0x43f, 0x435, 0x2e, 0x20, 0x447, 0x43e, 0x2e, 0xbae, 0xbc1, 0xbb1, 0xbcd, 0xbaa, 0xb95, 0xbb2, 0xbcd, 0xe01,
0xe48, 0xe2d, 0xe19, 0xe40, 0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0xf66, 0xf94, 0xf0b, 0xf51, 0xfb2, 0xf7c, 0xf0b, 0x1295, 0x1309, 0x1206, 0x20,
@@ -5814,29 +5829,29 @@ static const ushort currency_display_name_data[] = {
0x3b, 0x3b, 0x3b, 0x3b, 0x421, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x438, 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, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440,
-0x430, 0x3b, 0x411, 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, 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, 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, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x42,
-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,
+0x430, 0x3b, 0x42, 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, 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, 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, 0x3b, 0x73,
-0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x41b, 0x430, 0x440, 0x3b, 0x3b, 0x43b,
+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, 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, 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, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x411, 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,
+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, 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, 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, 0x67e, 0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0x64a, 0x20, 0x631,
@@ -6291,9 +6306,9 @@ static const ushort endonyms_data[] = {
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, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x421,
-0x440, 0x431, 0x438, 0x458, 0x430, 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, 0x73,
-0x72, 0x70, 0x73, 0x6b, 0x69, 0x43, 0x72, 0x6e, 0x61, 0x20, 0x47, 0x6f, 0x72, 0x61, 0x53, 0x72, 0x62, 0x69, 0x6a, 0x61,
+0x440, 0x431, 0x438, 0x458, 0x430, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x43, 0x72, 0x6e, 0x61, 0x20, 0x47, 0x6f, 0x72, 0x61,
+0x53, 0x72, 0x62, 0x69, 0x6a, 0x61, 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, 0x63, 0x68, 0x69, 0x53, 0x68, 0x6f, 0x6e, 0x61, 0x633, 0x646, 0x68c, 0x64a, 0x67e,
0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0xdc3, 0xdd2, 0xd82, 0xdc4, 0xdbd, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a,
@@ -6773,6 +6788,11 @@ static const char language_name_list[] =
"Cantonese\0"
"Osage\0"
"Tangut\0"
+"Ido\0"
+"Lojban\0"
+"Sicilian\0"
+"Southern Kurdish\0"
+"Western Balochi\0"
;
static const quint16 language_name_index[] = {
@@ -7136,6 +7156,11 @@ static const quint16 language_name_index[] = {
3050, // Cantonese
3060, // Osage
3066, // Tangut
+ 3073, // Ido
+ 3077, // Lojban
+ 3084, // Sicilian
+ 3093, // Southern Kurdish
+ 3110, // Western Balochi
};
static const char script_name_list[] =
@@ -8319,6 +8344,11 @@ static const unsigned char language_code_list[] =
"yue" // Cantonese
"osa" // Osage
"txg" // Tangut
+"io\0" // Ido
+"jbo" // Lojban
+"scn" // Sicilian
+"sdh" // Southern Kurdish
+"bgn" // Western Balochi
;
static const unsigned char script_code_list[] =
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 7487c9128c..70430beb00 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -66,6 +66,7 @@
QT_BEGIN_NAMESPACE
#ifndef QT_NO_SYSTEMLOCALE
+struct QLocaleData;
class Q_CORE_EXPORT QSystemLocale
{
public:
@@ -126,6 +127,7 @@ public:
virtual QVariant query(QueryType type, QVariant in) const;
virtual QLocale fallbackUiLocale() const;
+ inline const QLocaleData *fallbackUiLocaleData() const;
private:
QSystemLocale(bool);
friend class QSystemLocaleSingleton;
@@ -371,8 +373,6 @@ public:
QLocale::MeasurementSystem measurementSystem() const;
- static void updateSystemPrivate();
-
QString dateTimeToString(QStringView format, const QDateTime &datetime,
const QDate &dateOnly, const QTime &timeOnly,
const QLocale *q) const;
@@ -382,6 +382,10 @@ public:
QLocale::NumberOptions m_numberOptions;
};
+#ifndef QT_NO_SYSTEMLOCALE
+const QLocaleData *QSystemLocale::fallbackUiLocaleData() const { return fallbackUiLocale().d->m_data; }
+#endif
+
template <>
inline QLocalePrivate *QSharedDataPointer<QLocalePrivate>::clone()
{
diff --git a/src/corelib/tools/qmakearray_p.h b/src/corelib/tools/qmakearray_p.h
index ae4d7f07c6..71441c2c27 100644
--- a/src/corelib/tools/qmakearray_p.h
+++ b/src/corelib/tools/qmakearray_p.h
@@ -111,10 +111,10 @@ struct QuickSortFilter<Predicate, QuickSortData<Head, Tail...>>
using TailFilteredData = typename QuickSortFilter<
Predicate, QuickSortData<Tail...>>::Type;
- using Type = typename QConditional<
+ using Type = typename std::conditional<
Predicate<Head>::value,
decltype(quickSortConcat(QuickSortData<Head> {}, TailFilteredData{})),
- TailFilteredData>::Type;
+ TailFilteredData>::type;
};
template <template <typename> class Predicate>
diff --git a/src/corelib/tools/qoffsetstringarray_p.h b/src/corelib/tools/qoffsetstringarray_p.h
new file mode 100644
index 0000000000..4dd9e9603b
--- /dev/null
+++ b/src/corelib/tools/qoffsetstringarray_p.h
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOFFSETSTRINGARRAY_P_H
+#define QOFFSETSTRINGARRAY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qglobal_p.h"
+
+#include <tuple>
+#include <array>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtPrivate {
+template<int N, int O, int I, int ... Idx>
+struct OffsetSequenceHelper : OffsetSequenceHelper<N - 1, O + I, Idx..., O> { };
+
+template<int Last, int I, int S, int ... Idx>
+struct OffsetSequenceHelper<1, Last, I, S, Idx...> : IndexesList<Last + I, Idx..., Last>
+{
+ static const constexpr auto Length = Last + I;
+ using Type = typename std::conditional<
+ Last <= std::numeric_limits<quint8>::max(),
+ quint8,
+ typename std::conditional<
+ Last <= std::numeric_limits<quint16>::max(),
+ quint16,
+ int>::type
+ >::type;
+};
+
+template<int ... Idx>
+struct OffsetSequence : OffsetSequenceHelper<sizeof ... (Idx), 0, Idx..., 0> { };
+
+template<int N>
+struct StaticString
+{
+ const char data[N];
+};
+
+
+template<>
+struct StaticString<0>
+{
+ static constexpr int size() noexcept
+ {
+ return 0;
+ }
+};
+
+template<typename, typename>
+struct StaticStringBuilder;
+
+template<int ... I1, int ... I2>
+struct StaticStringBuilder<IndexesList<I1...>, IndexesList<I2...>>
+{
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_MSVC(4100) // The formal parameter is not referenced in the body of the function.
+ // The unreferenced parameter is ignored.
+ // It happens when 'rs' is StaticString<0>
+ template<int N1, int N2>
+ static constexpr StaticString<N1 + N2> concatenate(
+ const char (&ls)[N1], const StaticString<N2> &rs) noexcept
+ {
+ return StaticString<N1 + N2>{{ls[I1]..., rs.data[I2]...}};
+ }
+QT_WARNING_POP
+};
+
+template<int Sum>
+constexpr StaticString<0> staticString() noexcept
+{
+ return StaticString<0>{};
+}
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_MSVC(4503)
+template<int Sum, int I, int ... Ix>
+constexpr StaticString<Sum> staticString(const char (&s)[I], const char (&...sx)[Ix]) noexcept
+{
+ return StaticStringBuilder<
+ makeIndexSequence<I>,
+ makeIndexSequence<Sum - I>>::concatenate(s, staticString<Sum - I>(sx...));
+}
+QT_WARNING_POP
+} // namespace QtPrivate
+
+template<typename T, int SizeString, int SizeOffsets>
+class QOffsetStringArray
+{
+public:
+ using Type = T;
+
+ template<int ... Ox>
+ constexpr QOffsetStringArray(const QtPrivate::StaticString<SizeString> &str,
+ QtPrivate::IndexesList<SizeString, Ox...>) noexcept
+ : m_string(str),
+ m_offsets{Ox...}
+ { }
+
+ constexpr inline const char *operator[](const int index) const noexcept
+ {
+ return m_string.data + m_offsets[qBound(int(0), index, SizeOffsets - 1)];
+ }
+
+ constexpr inline const char *at(const int index) const noexcept
+ {
+ return m_string.data + m_offsets[index];
+ }
+
+ constexpr inline const char *str() const { return m_string.data; }
+ constexpr inline const T *offsets() const { return m_offsets; }
+ constexpr inline int count() const { return SizeOffsets; };
+
+ static constexpr const auto sizeString = SizeString;
+ static constexpr const auto sizeOffsets = SizeOffsets;
+
+private:
+ QtPrivate::StaticString<SizeString> m_string;
+ const T m_offsets[SizeOffsets];
+};
+
+template<typename T, int N, int ... Ox>
+constexpr QOffsetStringArray<T, N, sizeof ... (Ox)> qOffsetStringArray(
+ const QtPrivate::StaticString<N> &string,
+ QtPrivate::IndexesList<N, Ox...> offsets) noexcept
+{
+ return QOffsetStringArray<T, N, sizeof ... (Ox)>(
+ string,
+ offsets);
+}
+
+template<int ... Nx>
+struct QOffsetStringArrayRet
+{
+ using Offsets = QtPrivate::OffsetSequence<Nx...>;
+ using Type = QOffsetStringArray<typename Offsets::Type, Offsets::Length, sizeof ... (Nx)>;
+};
+
+template<int ... Nx>
+constexpr auto qOffsetStringArray(const char (&...strings)[Nx]) noexcept -> typename QOffsetStringArrayRet<Nx...>::Type
+{
+ using Offsets = QtPrivate::OffsetSequence<Nx...>;
+ return qOffsetStringArray<typename Offsets::Type>(
+ QtPrivate::staticString<Offsets::Length>(strings...), Offsets{});
+}
+
+QT_END_NAMESPACE
+
+#endif // QOFFSETSTRINGARRAY_P_H
diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp
index c334f71fa0..dcfda40eda 100644
--- a/src/corelib/tools/qshareddata.cpp
+++ b/src/corelib/tools/qshareddata.cpp
@@ -368,7 +368,7 @@ QT_BEGIN_NAMESPACE
*/
/*! \fn template <class T> bool QSharedDataPointer<T>::operator!() const
- Returns \c true if the \e{d pointer} of \e this is null.
+ Returns \c true if the \e{d pointer} of \e this is \nullptr.
*/
/*! \fn template <class T> void QSharedDataPointer<T>::detach()
@@ -583,7 +583,7 @@ QT_BEGIN_NAMESPACE
\since 5.12
Returns a pointer to the shared object, and resets \e this to be null.
- That is, this function sets the \e{d pointer} of \e this to \c nullptr.
+ That is, this function sets the \e{d pointer} of \e this to \nullptr.
*/
/*! \fn template <class T> QExplicitlySharedDataPointer<T>::operator bool () const
@@ -591,7 +591,7 @@ QT_BEGIN_NAMESPACE
*/
/*! \fn template <class T> bool QExplicitlySharedDataPointer<T>::operator!() const
- Returns \c true if the \e{d pointer} of \e this is null.
+ Returns \c true if the \e{d pointer} of \e this is \nullptr.
*/
/*! \fn template <class T> void QExplicitlySharedDataPointer<T>::detach()
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index 6ab84cf3d8..62b76c5bb7 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -379,7 +379,7 @@
You can inherit this class when you need to create a QSharedPointer
from any instance of a class; for instance, from within the
object itself. The key point is that the technique of
- just returning QSharedPointer<T>(this) can not be used, because
+ just returning QSharedPointer<T>(this) cannot be used, because
this winds up creating multiple distinct QSharedPointer objects
with separate reference counts. For this reason you must never
create more than one QSharedPointer from the same raw pointer.
@@ -579,8 +579,8 @@
/*!
\fn template <class T> bool QSharedPointer<T>::operator !() const
- Returns \c true if this object is null. This function is suitable
- for use in \tt if-constructs, like:
+ Returns \c true if this object is \nullptr. This function is
+ suitable for use in \tt if-constructs, like:
\snippet code/src_corelib_tools_qsharedpointer.cpp 5
@@ -854,8 +854,8 @@
/*!
\fn template <class T> bool QWeakPointer<T>::operator !() const
- Returns \c true if this object is null. This function is suitable
- for use in \tt if-constructs, like:
+ Returns \c true if this object is \nullptr. This function is
+ suitable for use in \tt if-constructs, like:
\snippet code/src_corelib_tools_qsharedpointer.cpp 9
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index e44307f28d..ddd715f745 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -533,7 +533,7 @@ Q_CORE_EXPORT QBasicAtomicInteger<quint64> qt_cpu_features[1] = { Q_BASIC_ATOMIC
Q_CORE_EXPORT QBasicAtomicInteger<unsigned> qt_cpu_features[2] = { Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0) };
#endif
-void qDetectCpuFeatures()
+quint64 qDetectCpuFeatures()
{
quint64 f = detectProcessorFeatures();
QByteArray disable = qgetenv("QT_NO_CPU_FEATURE");
@@ -567,6 +567,7 @@ void qDetectCpuFeatures()
#ifndef Q_ATOMIC_INT64_IS_SUPPORTED
qt_cpu_features[1].store(f >> 32);
#endif
+ return f;
}
void qDumpCPUFeatures()
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index 9f1321df94..c36e1e484f 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -344,7 +344,7 @@ extern Q_CORE_EXPORT QBasicAtomicInteger<quint64> qt_cpu_features[1];
#else
extern Q_CORE_EXPORT QBasicAtomicInteger<unsigned> qt_cpu_features[2];
#endif
-Q_CORE_EXPORT void qDetectCpuFeatures();
+Q_CORE_EXPORT quint64 qDetectCpuFeatures();
static inline quint64 qCpuFeatures()
{
@@ -353,11 +353,7 @@ static inline quint64 qCpuFeatures()
features |= quint64(qt_cpu_features[1].load()) << 32;
#endif
if (Q_UNLIKELY(features == 0)) {
- qDetectCpuFeatures();
- features = qt_cpu_features[0].load();
-#ifndef Q_ATOMIC_INT64_IS_SUPPORTED
- features |= quint64(qt_cpu_features[1].load()) << 32;
-#endif
+ features = qDetectCpuFeatures();
Q_ASSUME(features != 0);
}
return features;
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index d8bfb69a8b..9d6e0cbdd8 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -120,7 +120,7 @@ QT_BEGIN_NAMESPACE
* Whenever multiple alternatives are equivalent or near so, we prefer the one
* using instructions from SSE2, since SSE2 is guaranteed to be enabled for all
* 64-bit builds and we enable it for 32-bit builds by default. Use of higher
- * SSE versions should be done when there's a clear performance benefit and
+ * SSE versions should be done when there is a clear performance benefit and
* requires fallback code to SSE2, if it exists.
*
* Performance measurement in the past shows that most strings are short in
@@ -1468,7 +1468,7 @@ const QString::Null QString::null = { };
In all of the QString functions that take \c{const char *}
parameters, the \c{const char *} is interpreted as a classic
C-style '\\0'-terminated string encoded in UTF-8. It is legal for
- the \c{const char *} parameter to be 0.
+ the \c{const char *} parameter to be \nullptr.
You can also provide string data as an array of \l{QChar}s:
@@ -1552,7 +1552,7 @@ const QString::Null QString::null = { };
functions. The former searches forward starting from a given index
position, the latter searches backward. Both return the index
position of the character or substring if they find it; otherwise,
- they return -1. For example, here's a typical loop that finds all
+ they return -1. For example, here is a typical loop that finds all
occurrences of a particular substring:
\snippet qstring/main.cpp 6
@@ -2041,7 +2041,7 @@ const QString::Null QString::null = { };
the size of wchar. If wchar is 4 bytes, the \a string is interpreted as UCS-4,
if wchar is 2 bytes it is interpreted as UTF-16.
- If \a size is -1 (default), the \a string has to be 0 terminated.
+ If \a size is -1 (default), the \a string has to be \\0'-terminated.
\sa fromUtf16(), fromLatin1(), fromLocal8Bit(), fromUtf8(), fromUcs4(), fromStdWString()
*/
@@ -2107,7 +2107,7 @@ int QString::toUcs4_helper(const ushort *uc, int length, uint *out)
If \a unicode is 0, a null string is constructed.
- If \a size is negative, \a unicode is assumed to point to a nul-terminated
+ If \a size is negative, \a unicode is assumed to point to a \\0'-terminated
array and its length is determined dynamically. The terminating
nul-character is not considered part of the string.
@@ -5448,7 +5448,7 @@ static QVector<uint> qt_convert_to_ucs4(QStringView string);
this string is replaced by the Unicode's replacement character
(QChar::ReplacementCharacter, which corresponds to \c{U+FFFD}).
- The returned vector is not NUL terminated.
+ The returned vector is not \\0'-terminated.
\sa fromUtf8(), toUtf8(), toLatin1(), toLocal8Bit(), QTextCodec, fromUcs4(), toWCharArray()
*/
@@ -5480,7 +5480,7 @@ static QVector<uint> qt_convert_to_ucs4(QStringView string)
this string is replaced by the Unicode's replacement character
(QChar::ReplacementCharacter, which corresponds to \c{U+FFFD}).
- The returned vector is not NUL terminated.
+ The returned vector is not \\0'-terminated.
\sa QString::toUcs4(), QStringView::toUcs4(), QtPrivate::convertToLatin1(),
QtPrivate::convertToLocal8Bit(), QtPrivate::convertToUtf8()
@@ -5638,8 +5638,7 @@ QString QString::fromUtf8_helper(const char *str, int size)
Returns a QString initialized with the first \a size characters
of the Unicode string \a unicode (ISO-10646-UTF-16 encoded).
- If \a size is -1 (default), \a unicode must be terminated
- with a 0.
+ If \a size is -1 (default), \a unicode must be \\0'-terminated.
This function checks for a Byte Order Mark (BOM). If it is missing,
host byte order is assumed.
@@ -5670,8 +5669,7 @@ QString QString::fromUtf16(const ushort *unicode, int size)
Returns a QString initialized with the first \a size characters
of the Unicode string \a str (ISO-10646-UTF-16 encoded).
- If \a size is -1 (default), \a str must be terminated
- with a 0.
+ If \a size is -1 (default), \a str must be \\0'-terminated.
This function checks for a Byte Order Mark (BOM). If it is missing,
host byte order is assumed.
@@ -5691,8 +5689,7 @@ QString QString::fromUtf16(const ushort *unicode, int size)
Returns a QString initialized with the first \a size characters
of the Unicode string \a str (ISO-10646-UCS-4 encoded).
- If \a size is -1 (default), \a str must be terminated
- with a 0.
+ If \a size is -1 (default), \a str must be \\0'-terminated.
\sa toUcs4(), fromUtf16(), utf16(), setUtf16(), fromWCharArray(), fromStdU32String()
*/
@@ -5703,8 +5700,7 @@ QString QString::fromUtf16(const ushort *unicode, int size)
Returns a QString initialized with the first \a size characters
of the Unicode string \a unicode (ISO-10646-UCS-4 encoded).
- If \a size is -1 (default), \a unicode must be terminated
- with a 0.
+ If \a size is -1 (default), \a unicode must be \\0'-terminated.
\sa toUcs4(), fromUtf16(), utf16(), setUtf16(), fromWCharArray(), fromStdU32String()
*/
@@ -6714,7 +6710,7 @@ namespace QUnicodeTables {
this function requires to be a valid, empty string) and \c{s} contains the
only copy of the string, without reallocation (thus, \a it is still valid).
- There's one pathological case left: when the in-place conversion needs to
+ There is one pathological case left: when the in-place conversion needs to
reallocate memory to grow the buffer. In that case, we need to adjust the \a
it pointer.
*/
@@ -6872,7 +6868,7 @@ QString &QString::sprintf(const char *cformat, ...)
\warning We do not recommend using QString::asprintf() in new Qt
code. Instead, consider using QTextStream or arg(), both of
which support Unicode strings seamlessly and are type-safe.
- Here's an example that uses QTextStream:
+ Here is an example that uses QTextStream:
\snippet qstring/main.cpp 64
@@ -7233,7 +7229,7 @@ QString QString::vasprintf(const char *cformat, va_list ap)
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -7275,7 +7271,7 @@ qlonglong QString::toIntegral_helper(const QChar *data, int len, bool *ok, int b
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -7319,7 +7315,7 @@ qulonglong QString::toIntegral_helper(const QChar *data, uint len, bool *ok, int
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -7350,7 +7346,7 @@ long QString::toLong(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -7380,7 +7376,7 @@ ulong QString::toULong(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -7409,7 +7405,7 @@ int QString::toInt(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -7438,7 +7434,7 @@ uint QString::toUInt(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -7467,7 +7463,7 @@ short QString::toShort(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -7498,7 +7494,7 @@ ushort QString::toUShort(bool *ok, int base) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for other reasons (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\snippet qstring/main.cpp 66
@@ -7537,7 +7533,7 @@ double QString::toDouble(bool *ok) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for other reasons (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
\warning The QString content may only contain valid numerical characters
@@ -7839,7 +7835,7 @@ QStringList QString::split(const QString &sep, SplitBehavior behavior, Qt::CaseS
the result.
\note All references are valid as long this string is alive. Destroying this
- string will cause all references be dangling pointers.
+ string will cause all references to be dangling pointers.
\since 5.4
\sa QStringRef split()
@@ -7873,7 +7869,7 @@ QVector<QStringRef> QString::splitRef(QChar sep, SplitBehavior behavior, Qt::Cas
the result.
\note All references are valid as long this string is alive. Destroying this
- string will cause all references be dangling pointers.
+ string will cause all references to be dangling pointers.
\since 5.4
*/
@@ -7922,17 +7918,17 @@ static ResultList splitString(const QString &source, MidMethod mid, const QRegEx
does not match anywhere in the string, split() returns a
single-element list containing this string.
- Here's an example where we extract the words in a sentence
+ Here is an example where we extract the words in a sentence
using one or more whitespace characters as the separator:
\snippet qstring/main.cpp 59
- Here's a similar example, but this time we use any sequence of
+ Here is a similar example, but this time we use any sequence of
non-word characters as the separator:
\snippet qstring/main.cpp 60
- Here's a third example where we use a zero-length assertion,
+ Here is a third example where we use a zero-length assertion,
\b{\\b} (word boundary), to split the string into an
alternating sequence of non-word and word tokens:
@@ -7955,7 +7951,7 @@ QStringList QString::split(const QRegExp &rx, SplitBehavior behavior) const
single-element vector containing this string reference.
\note All references are valid as long this string is alive. Destroying this
- string will cause all references be dangling pointers.
+ string will cause all references to be dangling pointers.
\sa QStringRef split()
*/
@@ -8004,17 +8000,17 @@ static ResultList splitString(const QString &source, MidMethod mid, const QRegul
does not match anywhere in the string, split() returns a
single-element list containing this string.
- Here's an example where we extract the words in a sentence
+ Here is an example where we extract the words in a sentence
using one or more whitespace characters as the separator:
\snippet qstring/main.cpp 90
- Here's a similar example, but this time we use any sequence of
+ Here is a similar example, but this time we use any sequence of
non-word characters as the separator:
\snippet qstring/main.cpp 91
- Here's a third example where we use a zero-length assertion,
+ Here is a third example where we use a zero-length assertion,
\b{\\b} (word boundary), to split the string into an
alternating sequence of non-word and word tokens:
@@ -8037,7 +8033,7 @@ QStringList QString::split(const QRegularExpression &re, SplitBehavior behavior)
single-element vector containing this string reference.
\note All references are valid as long this string is alive. Destroying this
- string will cause all references be dangling pointers.
+ string will cause all references to be dangling pointers.
\sa split() QStringRef
*/
@@ -9174,7 +9170,7 @@ bool QString::isRightToLeft() const
to create a deep copy of the data, ensuring that the raw data
isn't modified.
- Here's an example of how we can use a QRegularExpression on raw data in
+ Here is an example of how we can use a QRegularExpression on raw data in
memory without requiring to copy the data into a QString:
\snippet qstring/main.cpp 22
@@ -9442,11 +9438,11 @@ QString &QString::setRawData(const QChar *unicode, int size)
The range \c{[first,last)} must remain valid for the lifetime of
this Latin-1 string object.
- Passing \c nullptr as \a first is safe if \a last is \c nullptr,
+ Passing \nullptr as \a first is safe if \a last is \nullptr,
too, and results in a null Latin-1 string.
The behavior is undefined if \a last precedes \a first, \a first
- is \c nullptr and \a last is not, or if \c{last - first >
+ is \nullptr and \a last is not, or if \c{last - first >
INT_MAX}.
*/
@@ -10354,7 +10350,7 @@ ownership of it, no memory is freed when instances are destroyed.
Returns a Unicode representation of the string reference. Since
the data stems directly from the referenced string, it is not
- null-terminated unless the string reference includes the string's
+ \\0'-terminated unless the string reference includes the string's
null terminator.
\sa string()
@@ -11896,7 +11892,7 @@ QByteArray QStringRef::toUtf8() const
this string is replaced by the Unicode's replacement character
(QChar::ReplacementCharacter, which corresponds to \c{U+FFFD}).
- The returned vector is not NUL terminated.
+ The returned vector is not \\0'-terminated.
\sa toUtf8(), toLatin1(), toLocal8Bit(), QTextCodec
*/
@@ -11935,7 +11931,7 @@ QStringRef QStringRef::trimmed() const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -11960,7 +11956,7 @@ qint64 QStringRef::toLongLong(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -11987,7 +11983,7 @@ quint64 QStringRef::toULongLong(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -12014,7 +12010,7 @@ long QStringRef::toLong(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -12040,7 +12036,7 @@ ulong QStringRef::toULong(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -12065,7 +12061,7 @@ int QStringRef::toInt(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -12090,7 +12086,7 @@ uint QStringRef::toUInt(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -12115,7 +12111,7 @@ short QStringRef::toShort(bool *ok, int base) const
base, which is 10 by default and must be between 2 and 36, or 0.
Returns 0 if the conversion fails.
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
If \a base is 0, the C language convention is used: If the string
@@ -12142,7 +12138,7 @@ ushort QStringRef::toUShort(bool *ok, int base) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for other reasons (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
The string conversion will always happen in the 'C' locale. For locale
@@ -12168,7 +12164,7 @@ double QStringRef::toDouble(bool *ok) const
Returns an infinity if the conversion overflows or 0.0 if the
conversion fails for other reasons (e.g. underflow).
- If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
The string conversion will always happen in the 'C' locale. For locale
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 6be3dcdbe1..da76601e88 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -899,10 +899,8 @@ private:
template <typename T> static
T toIntegral_helper(const QChar *data, int len, bool *ok, int base)
{
- // ### Qt6: use std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type
- const bool isUnsigned = T(0) < T(-1);
- typedef typename QtPrivate::QConditional<isUnsigned, qulonglong, qlonglong>::Type Int64;
- typedef typename QtPrivate::QConditional<isUnsigned, uint, int>::Type Int32;
+ using Int64 = typename std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type;
+ using Int32 = typename std::conditional<std::is_unsigned<T>::value, uint, int>::type;
// we select the right overload by casting size() to int or uint
Int64 val = toIntegral_helper(data, Int32(len), ok, base);
diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp
index cf150c2a1b..cc6eaf8ad2 100644
--- a/src/corelib/tools/qstringlist.cpp
+++ b/src/corelib/tools/qstringlist.cpp
@@ -376,6 +376,56 @@ bool QtPrivate::QStringList_contains(const QStringList *that, QLatin1String str,
return stringList_contains(*that, str, cs);
}
+/*!
+ \fn bool QStringList::indexOf(QStringView str, int from) const
+ \overload
+ \since 5.13
+
+ Returns the index position of the first occurrence of \a str in
+ the list, searching forward from index position \a from. Returns
+ -1 if no item matched.
+
+ \sa lastIndexOf(), contains()
+ */
+
+/*!
+ \fn bool QStringList::indexOf(QLatin1String str, int from) const
+ \overload
+ \since 5.13
+
+ Returns the index position of the first occurrence of \a str in
+ the list, searching forward from index position \a from. Returns
+ -1 if no item matched.
+
+ \sa lastIndexOf(), contains()
+ */
+
+/*!
+ \fn bool QStringList::lastIndexOf(QStringView str, int from) const
+ \overload
+ \since 5.13
+
+ Returns the index position of the last occurrence of \a str in
+ the list, searching backward from index position \a from. If \a
+ from is -1 (the default), the search starts at the last item.
+ Returns -1 if no item matched.
+
+ \sa indexOf(), contains()
+ */
+
+/*!
+ \fn bool QStringList::lastIndexOf(QLatin1String str, int from) const
+ \overload
+ \since 5.13
+
+ Returns the index position of the last occurrence of \a str in
+ the list, searching backward from index position \a from. If \a
+ from is -1 (the default), the search starts at the last item.
+ Returns -1 if no item matched.
+
+ \sa indexOf(), contains()
+ */
+
#ifndef QT_NO_REGEXP
/*!
\fn QStringList QStringList::filter(const QRegExp &rx) const
@@ -780,7 +830,7 @@ int QtPrivate::QStringList_removeDuplicates(QStringList *that)
continue;
++setSize;
if (j != i)
- that->swap(i, j);
+ that->swapItemsAt(i, j);
++j;
}
if (n != j)
diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/tools/qstringlist.h
index 10cbad04d6..b6c48488df 100644
--- a/src/corelib/tools/qstringlist.h
+++ b/src/corelib/tools/qstringlist.h
@@ -132,6 +132,12 @@ public:
inline QStringList &operator<<(const QList<QString> &l)
{ *this += l; return *this; }
+ inline int indexOf(QStringView str, int from = 0) const;
+ inline int indexOf(QLatin1String str, int from = 0) const;
+
+ inline int lastIndexOf(QStringView str, int from = -1) const;
+ inline int lastIndexOf(QLatin1String str, int from = -1) const;
+
#ifndef QT_NO_REGEXP
inline int indexOf(const QRegExp &rx, int from = 0) const;
inline int lastIndexOf(const QRegExp &rx, int from = -1) const;
@@ -249,6 +255,26 @@ inline QStringList operator+(const QList<QString> &one, const QStringList &other
return n;
}
+inline int QStringList::indexOf(QStringView string, int from) const
+{
+ return QtPrivate::indexOf<QString, QStringView>(*this, string, from);
+}
+
+inline int QStringList::indexOf(QLatin1String string, int from) const
+{
+ return QtPrivate::indexOf<QString, QLatin1String>(*this, string, from);
+}
+
+inline int QStringList::lastIndexOf(QStringView string, int from) const
+{
+ return QtPrivate::lastIndexOf<QString, QStringView>(*this, string, from);
+}
+
+inline int QStringList::lastIndexOf(QLatin1String string, int from) const
+{
+ return QtPrivate::lastIndexOf<QString, QLatin1String>(*this, string, from);
+}
+
#ifndef QT_NO_REGEXP
inline QStringList &QListSpecialMethods<QString>::replaceInStrings(const QRegExp &rx, const QString &after)
{
diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp
index a7d9426fa6..b97e989110 100644
--- a/src/corelib/tools/qstringview.cpp
+++ b/src/corelib/tools/qstringview.cpp
@@ -232,9 +232,9 @@ QT_BEGIN_NAMESPACE
The range \c{[str,len)} must remain valid for the lifetime of this string view object.
- Passing \c nullptr as \a str is safe if \a len is 0, too, and results in a null string view.
+ Passing \nullptr as \a str is safe if \a len is 0, too, and results in a null string view.
- The behavior is undefined if \a len is negative or, when positive, if \a str is \c nullptr.
+ The behavior is undefined if \a len is negative or, when positive, if \a str is \nullptr.
This constructor only participates in overload resolution if \c Char is a compatible
character type. The compatible character types are: \c QChar, \c ushort, \c char16_t and
@@ -249,11 +249,11 @@ QT_BEGIN_NAMESPACE
The range \c{[first,last)} must remain valid for the lifetime of
this string view object.
- Passing \c nullptr as \a first is safe if \a last is nullptr, too,
+ Passing \c \nullptr as \a first is safe if \a last is \nullptr, too,
and results in a null string view.
The behavior is undefined if \a last precedes \a first, or \a first
- is \c nullptr and \a last is not.
+ is \nullptr and \a last is not.
This constructor only participates in overload resolution if \c Char
is a compatible character type. The compatible character types
@@ -269,7 +269,7 @@ QT_BEGIN_NAMESPACE
\a str must remain valid for the lifetime of this string view object.
- Passing \c nullptr as \a str is safe and results in a null string view.
+ Passing \nullptr as \a str is safe and results in a null string view.
This constructor only participates in overload resolution if \a
str is not an array and if \c Char is a compatible character
@@ -332,7 +332,7 @@ QT_BEGIN_NAMESPACE
The string view will be empty if and only if \c{str.empty()}. It is unspecified
whether this constructor can result in a null string view (\c{str.data()} would
- have to return \c nullptr for this).
+ have to return \nullptr for this).
\sa isNull(), isEmpty()
*/
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 30fd7b2865..988d5a9e1b 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -42,7 +42,6 @@
#include <QtCore/qalgorithms.h>
#include <QtCore/qiterator.h>
-#include <QtCore/qlist.h>
#include <QtCore/qrefcount.h>
#include <QtCore/qarraydata.h>
#include <QtCore/qhashfunctions.h>
@@ -94,7 +93,13 @@ public:
void reserve(int size);
inline void squeeze()
{
- reallocData(d->size, d->size);
+ if (d->size < int(d->alloc)) {
+ if (!d->size) {
+ *this = QVector<T>();
+ return;
+ }
+ realloc(d->size);
+ }
if (d->capacityReserved) {
// capacity reserved in a read only memory would be useless
// this checks avoid writing to such memory.
@@ -297,9 +302,10 @@ public:
inline std::vector<T> toStdVector() const
{ return std::vector<T>(d->begin(), d->end()); }
private:
- // ### Qt6: remove const from int parameters
+ // ### Qt6: remove methods, they are unused
void reallocData(const int size, const int alloc, QArrayData::AllocationOptions options = QArrayData::Default);
void reallocData(const int sz) { reallocData(sz, d->alloc); }
+ void realloc(int alloc, QArrayData::AllocationOptions options = QArrayData::Default);
void freeData(Data *d);
void defaultConstruct(T *from, T *to);
void copyConstruct(const T *srcFrom, const T *srcTo, T *dstFrom);
@@ -387,7 +393,7 @@ void QVector<T>::detach()
d = Data::unsharableEmpty();
else
#endif
- reallocData(d->size, int(d->alloc));
+ realloc(int(d->alloc));
}
Q_ASSERT(isDetached());
}
@@ -396,7 +402,7 @@ template <typename T>
void QVector<T>::reserve(int asize)
{
if (asize > int(d->alloc))
- reallocData(d->size, asize);
+ realloc(asize);
if (isDetached()
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
&& d != Data::unsharableEmpty()
@@ -409,21 +415,26 @@ void QVector<T>::reserve(int asize)
template <typename T>
void QVector<T>::resize(int asize)
{
- int newAlloc;
- const int oldAlloc = int(d->alloc);
- QArrayData::AllocationOptions opt;
-
- if (asize > oldAlloc) { // there is not enough space
- newAlloc = asize;
- opt = QArrayData::Grow;
- } else {
- newAlloc = oldAlloc;
+ if (asize == d->size)
+ return;
+ if (asize > int(d->alloc) || !isDetached()) { // there is not enough space
+ QArrayData::AllocationOptions opt = asize > int(d->alloc) ? QArrayData::Grow : QArrayData::Default;
+ realloc(qMax(int(d->alloc), asize), opt);
}
- reallocData(asize, newAlloc, opt);
+ if (asize < d->size)
+ destruct(begin() + asize, end());
+ else
+ defaultConstruct(end(), begin() + asize);
+ d->size = asize;
}
template <typename T>
inline void QVector<T>::clear()
-{ resize(0); }
+{
+ if (!d->size)
+ return;
+ destruct(begin(), end());
+ d->size = 0;
+}
template <typename T>
inline const T &QVector<T>::at(int i) const
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::at", "index out of range");
@@ -654,6 +665,76 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo
Q_ASSERT(d->size == asize);
}
+template<typename T>
+void QVector<T>::realloc(int aalloc, QArrayData::AllocationOptions options)
+{
+ Q_ASSERT(aalloc >= d->size);
+ Data *x = d;
+
+ const bool isShared = d->ref.isShared();
+
+ QT_TRY {
+ // allocate memory
+ x = Data::allocate(aalloc, options);
+ Q_CHECK_PTR(x);
+ // aalloc is bigger then 0 so it is not [un]sharedEmpty
+#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
+ Q_ASSERT(x->ref.isSharable() || options.testFlag(QArrayData::Unsharable));
+#endif
+ Q_ASSERT(!x->ref.isStatic());
+ x->size = d->size;
+
+ T *srcBegin = d->begin();
+ T *srcEnd = d->end();
+ T *dst = x->begin();
+
+ if (!QTypeInfoQuery<T>::isRelocatable || (isShared && QTypeInfo<T>::isComplex)) {
+ QT_TRY {
+ if (isShared || !std::is_nothrow_move_constructible<T>::value) {
+ // we can not move the data, we need to copy construct it
+ while (srcBegin != srcEnd)
+ new (dst++) T(*srcBegin++);
+ } else {
+ while (srcBegin != srcEnd)
+ new (dst++) T(std::move(*srcBegin++));
+ }
+ } QT_CATCH (...) {
+ // destruct already copied objects
+ destruct(x->begin(), dst);
+ QT_RETHROW;
+ }
+ } else {
+ ::memcpy(static_cast<void *>(dst), static_cast<void *>(srcBegin), (srcEnd - srcBegin) * sizeof(T));
+ dst += srcEnd - srcBegin;
+ }
+
+ } QT_CATCH (...) {
+ Data::deallocate(x);
+ QT_RETHROW;
+ }
+ x->capacityReserved = d->capacityReserved;
+
+ Q_ASSERT(d != x);
+ if (!d->ref.deref()) {
+ if (!QTypeInfoQuery<T>::isRelocatable || !aalloc || (isShared && QTypeInfo<T>::isComplex)) {
+ // data was copy constructed, we need to call destructors
+ // or if !alloc we did nothing to the old 'd'.
+ freeData(d);
+ } else {
+ Data::deallocate(d);
+ }
+ }
+ d = x;
+
+ Q_ASSERT(d->data());
+ Q_ASSERT(uint(d->size) <= d->alloc);
+#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
+ Q_ASSERT(d != Data::unsharableEmpty());
+#endif
+ Q_ASSERT(d != Data::sharedNull());
+ Q_ASSERT(d->alloc >= uint(aalloc));
+}
+
#if defined(Q_CC_MSVC)
QT_WARNING_POP
#endif
@@ -679,7 +760,7 @@ void QVector<T>::append(const T &t)
if (!isDetached() || isTooSmall) {
T copy(t);
QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default);
- reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt);
+ realloc(isTooSmall ? d->size + 1 : d->alloc, opt);
if (QTypeInfo<T>::isComplex)
new (d->end()) T(qMove(copy));
@@ -702,7 +783,7 @@ void QVector<T>::append(T &&t)
const bool isTooSmall = uint(d->size + 1) > d->alloc;
if (!isDetached() || isTooSmall) {
QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default);
- reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt);
+ realloc(isTooSmall ? d->size + 1 : d->alloc, opt);
}
new (d->end()) T(std::move(t));
@@ -717,13 +798,11 @@ void QVector<T>::removeLast()
Q_ASSERT(!isEmpty());
Q_ASSERT(d->alloc);
- if (!d->ref.isShared()) {
- --d->size;
- if (QTypeInfo<T>::isComplex)
- (d->data() + d->size)->~T();
- } else {
- reallocData(d->size - 1);
- }
+ if (d->ref.isShared())
+ detach();
+ --d->size;
+ if (QTypeInfo<T>::isComplex)
+ (d->data() + d->size)->~T();
}
template <typename T>
@@ -735,7 +814,7 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
if (n != 0) {
const T copy(t);
if (!isDetached() || d->size + n > int(d->alloc))
- reallocData(d->size, d->size + n, QArrayData::Grow);
+ realloc(d->size + n, QArrayData::Grow);
if (!QTypeInfoQuery<T>::isRelocatable) {
T *b = d->end();
T *i = d->end() + n;
@@ -768,7 +847,7 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, T &&t)
const auto offset = std::distance(d->begin(), before);
if (!isDetached() || d->size + 1 > int(d->alloc))
- reallocData(d->size, d->size + 1, QArrayData::Grow);
+ realloc(d->size + 1, QArrayData::Grow);
if (!QTypeInfoQuery<T>::isRelocatable) {
T *i = d->end();
T *j = i + 1;
@@ -870,14 +949,14 @@ QVector<T> &QVector<T>::fill(const T &from, int asize)
template <typename T>
QVector<T> &QVector<T>::operator+=(const QVector &l)
{
- if (d == Data::sharedNull()) {
+ if (d->size == 0) {
*this = l;
} else {
uint newSize = d->size + l.d->size;
const bool isTooSmall = newSize > d->alloc;
if (!isDetached() || isTooSmall) {
QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default);
- reallocData(d->size, isTooSmall ? newSize : d->alloc, opt);
+ realloc(isTooSmall ? newSize : d->alloc, opt);
}
if (d->alloc) {
@@ -960,7 +1039,7 @@ Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int len) const
}
QVector<T> midResult;
- midResult.reallocData(0, len);
+ midResult.realloc(len);
T *srcFrom = d->begin() + pos;
T *srcTo = d->begin() + pos + len;
midResult.copyConstruct(srcFrom, srcTo, midResult.data());
@@ -968,37 +1047,6 @@ Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int len) const
return midResult;
}
-template <typename T>
-Q_OUTOFLINE_TEMPLATE QList<T> QVector<T>::toList() const
-{
- QList<T> result;
- result.reserve(size());
- for (int i = 0; i < size(); ++i)
- result.append(at(i));
- return result;
-}
-
-template <typename T>
-Q_OUTOFLINE_TEMPLATE QVector<T> QList<T>::toVector() const
-{
- QVector<T> result(size());
- for (int i = 0; i < size(); ++i)
- result[i] = at(i);
- return result;
-}
-
-template <typename T>
-QVector<T> QVector<T>::fromList(const QList<T> &list)
-{
- return list.toVector();
-}
-
-template <typename T>
-QList<T> QList<T>::fromVector(const QVector<T> &vector)
-{
- return vector.toList();
-}
-
Q_DECLARE_SEQUENTIAL_ITERATOR(Vector)
Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Vector)
@@ -1046,20 +1094,12 @@ inline bool operator>=(const QVector<T> &lhs, const QVector<T> &rhs)
### QVector<QPointF> respectively.
*/
-#ifdef Q_CC_MSVC
+#if defined(Q_CC_MSVC) && !defined(QT_BUILD_CORE_LIB)
QT_BEGIN_INCLUDE_NAMESPACE
#include <QtCore/qpoint.h>
QT_END_INCLUDE_NAMESPACE
-
-#ifndef Q_TEMPLATE_EXTERN
-#if defined(QT_BUILD_CORE_LIB)
-#define Q_TEMPLATE_EXTERN
-#else
-#define Q_TEMPLATE_EXTERN extern
-#endif
-#endif
-Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPointF>;
-Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPoint>;
+extern template class Q_CORE_EXPORT QVector<QPointF>;
+extern template class Q_CORE_EXPORT QVector<QPoint>;
#endif
QVector<uint> QStringView::toUcs4() const { return QtPrivate::convertToUcs4(*this); }
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index dc28e0e0a2..995bab694e 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -39,6 +39,7 @@ HEADERS += \
tools/qmargins.h \
tools/qmessageauthenticationcode.h \
tools/qcontiguouscache.h \
+ tools/qoffsetstringarray_p.h \
tools/qpair.h \
tools/qpoint.h \
tools/qqueue.h \
diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro
index ce799e0951..920a04315d 100644
--- a/src/dbus/dbus.pro
+++ b/src/dbus/dbus.pro
@@ -20,7 +20,7 @@ DEFINES += QT_NO_FOREACH
QMAKE_DOCS = $$PWD/doc/qtdbus.qdocconf
-PUB_HEADERS = qtdbusglobal.h \
+HEADERS += qtdbusglobal.h \
qdbusargument.h \
qdbusconnectioninterface.h \
qdbuserror.h \
@@ -38,8 +38,7 @@ PUB_HEADERS = qtdbusglobal.h \
qdbuscontext.h \
qdbusvirtualobject.h \
qdbusservicewatcher.h \
- qdbusunixfiledescriptor.h
-HEADERS += $$PUB_HEADERS \
+ qdbusunixfiledescriptor.h \
qtdbusglobal_p.h \
qdbusconnection_p.h \
qdbusconnectionmanager_p.h \
diff --git a/src/dbus/dbus_minimal_p.h b/src/dbus/dbus_minimal_p.h
index 869c02b59d..243c8ceaba 100644
--- a/src/dbus/dbus_minimal_p.h
+++ b/src/dbus/dbus_minimal_p.h
@@ -53,7 +53,7 @@
extern "C" {
-// Equivalent to dbus-arch-deps.h
+// Equivalent to dbus-arch-deps.h (generated from dbus-arch-deps.h.in)
typedef qint64 dbus_int64_t;
typedef quint64 dbus_uint64_t;
typedef qint32 dbus_int32_t;
@@ -78,7 +78,7 @@ struct DBusWatch;
// which carry the following copyright:
/*
* Copyright (C) 2002, 2003 CodeFactory AB
- * Copyright (C) 2004, 2005 Red Hat, Inc.
+ * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
*
* Licensed under the Academic Free License version 2.1
*
@@ -103,6 +103,20 @@ typedef dbus_uint32_t dbus_unichar_t;
typedef dbus_uint32_t dbus_bool_t;
/* dbus-shared.h */
+typedef enum
+{
+ DBUS_BUS_SESSION, /**< The login session bus */
+ DBUS_BUS_SYSTEM, /**< The systemwide bus */
+ DBUS_BUS_STARTER /**< The bus that started us, if any */
+} DBusBusType;
+
+typedef enum
+{
+ DBUS_HANDLER_RESULT_HANDLED, /**< Message has had its effect - no need to run more handlers. */
+ DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect - see if other handlers want it. */
+ DBUS_HANDLER_RESULT_NEED_MEMORY /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */
+} DBusHandlerResult;
+
#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local"
@@ -124,20 +138,6 @@ typedef dbus_uint32_t dbus_bool_t;
#define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 /**< The given name does not exist on the bus */
#define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /**< Service is not an owner of the given name */
-typedef enum
-{
- DBUS_BUS_SESSION, /**< The login session bus */
- DBUS_BUS_SYSTEM, /**< The systemwide bus */
- DBUS_BUS_STARTER /**< The bus that started us, if any */
-} DBusBusType;
-
-typedef enum
-{
- DBUS_HANDLER_RESULT_HANDLED, /**< Message has had its effect - no need to run more handlers. */
- DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect - see if other handlers want it. */
- DBUS_HANDLER_RESULT_NEED_MEMORY /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */
-} DBusHandlerResult;
-
/* dbus-memory.h */
typedef void (* DBusFreeFunction) (void *memory);
diff --git a/src/dbus/doc/qtdbus.qdocconf b/src/dbus/doc/qtdbus.qdocconf
index 69eaa0eec3..4ff7242b25 100644
--- a/src/dbus/doc/qtdbus.qdocconf
+++ b/src/dbus/doc/qtdbus.qdocconf
@@ -21,6 +21,8 @@ excludedirs += ../../../examples/widgets/doc
examplesinstallpath = dbus
+tagfile = qtdbus.tags
+
depends += qtdoc qtcore
# The following parameters are for creating a qhp file, the qhelpgenerator
diff --git a/src/dbus/qdbusargument.cpp b/src/dbus/qdbusargument.cpp
index a33c4f8363..2d1373006d 100644
--- a/src/dbus/qdbusargument.cpp
+++ b/src/dbus/qdbusargument.cpp
@@ -267,7 +267,7 @@ bool QDBusArgumentPrivate::checkReadAndDetach(QDBusArgumentPrivate *&d)
*/
/*!
- \fn qdbus_cast(const QDBusArgument &arg)
+ \fn template<typename T> T qdbus_cast(const QDBusArgument &arg, T*)
\relates QDBusArgument
\since 4.2
diff --git a/src/dbus/qdbusargument.h b/src/dbus/qdbusargument.h
index a6d4e9cd25..94a89a4e08 100644
--- a/src/dbus/qdbusargument.h
+++ b/src/dbus/qdbusargument.h
@@ -158,22 +158,15 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusArgument)
QT_BEGIN_NAMESPACE
-template<typename T> inline T qdbus_cast(const QDBusArgument &arg
-#ifndef Q_QDOC
-, T * = nullptr
-#endif
- )
+// ### Qt6: remove the defaulted T * = nullptr from these two (MSVC6 work-around):
+template<typename T> inline T qdbus_cast(const QDBusArgument &arg, T * = nullptr)
{
T item;
arg >> item;
return item;
}
-template<typename T> inline T qdbus_cast(const QVariant &v
-#ifndef Q_QDOC
-, T * = nullptr
-#endif
- )
+template<typename T> inline T qdbus_cast(const QVariant &v, T * = nullptr)
{
int id = v.userType();
if (id == qMetaTypeId<QDBusArgument>())
diff --git a/src/dbus/qdbusargument_p.h b/src/dbus/qdbusargument_p.h
index 559f8b1186..b678b9606f 100644
--- a/src/dbus/qdbusargument_p.h
+++ b/src/dbus/qdbusargument_p.h
@@ -155,7 +155,7 @@ public:
bool skipSignature;
private:
- Q_DISABLE_COPY(QDBusMarshaller)
+ Q_DISABLE_COPY_MOVE(QDBusMarshaller)
};
class QDBusDemarshaller: public QDBusArgumentPrivate
@@ -208,7 +208,7 @@ public:
QDBusDemarshaller *parent;
private:
- Q_DISABLE_COPY(QDBusDemarshaller)
+ Q_DISABLE_COPY_MOVE(QDBusDemarshaller)
QString toStringUnchecked();
QDBusObjectPath toObjectPathUnchecked();
QDBusSignature toSignatureUnchecked();
diff --git a/src/dbus/qdbusconnection.h b/src/dbus/qdbusconnection.h
index ca7adfaaeb..3711981f78 100644
--- a/src/dbus/qdbusconnection.h
+++ b/src/dbus/qdbusconnection.h
@@ -122,9 +122,7 @@ public:
SubPath = 0x1
// Reserved = 0xff000000
};
-#ifndef Q_QDOC
Q_DECLARE_FLAGS(VirtualObjectRegisterOptions, VirtualObjectRegisterOption)
-#endif
enum ConnectionCapability {
UnixFileDescriptorPassing = 0x0001
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index 444d4727fd..7769b9ea71 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -94,7 +94,7 @@ class QDBusServer;
class QDBusErrorInternal
{
mutable DBusError error;
- Q_DISABLE_COPY(QDBusErrorInternal)
+ Q_DISABLE_COPY_MOVE(QDBusErrorInternal)
public:
inline QDBusErrorInternal() { q_dbus_error_init(&error); }
inline ~QDBusErrorInternal() { q_dbus_error_free(&error); }
@@ -121,6 +121,15 @@ public:
QSocketNotifier *write;
};
+ struct ArgMatchRules {
+ QStringList args;
+ QString arg0namespace;
+ bool operator==(const ArgMatchRules &other) const {
+ return args == other.args &&
+ arg0namespace == other.arg0namespace;
+ }
+ };
+
struct SignalHook
{
inline SignalHook() : obj(0), midx(-1) { }
@@ -128,7 +137,7 @@ public:
QObject* obj;
int midx;
QVector<int> params;
- QStringList argumentMatch;
+ ArgMatchRules argumentMatch;
QByteArray matchRule;
};
@@ -207,12 +216,19 @@ public:
QDBusMessage sendWithReplyLocal(const QDBusMessage &message);
QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
const char *returnMethod, const char *errorMethod,int timeout = -1);
+
bool connectSignal(const QString &service, const QString &path, const QString& interface,
const QString &name, const QStringList &argumentMatch, const QString &signature,
QObject *receiver, const char *slot);
bool disconnectSignal(const QString &service, const QString &path, const QString& interface,
const QString &name, const QStringList &argumentMatch, const QString &signature,
QObject *receiver, const char *slot);
+ bool connectSignal(const QString &service, const QString &path, const QString& interface,
+ const QString &name, const ArgMatchRules &argumentMatch, const QString &signature,
+ QObject *receiver, const char *slot);
+ bool disconnectSignal(const QString &service, const QString &path, const QString& interface,
+ const QString &name, const ArgMatchRules &argumentMatch, const QString &signature,
+ QObject *receiver, const char *slot);
void registerObject(const ObjectTreeNode *node);
void unregisterObject(const QString &path, QDBusConnection::UnregisterMode mode);
void connectRelay(const QString &service,
@@ -332,7 +348,7 @@ public:
static bool prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
const QString &service,
const QString &path, const QString &interface, const QString &name,
- const QStringList &argMatch,
+ const ArgMatchRules &argMatch,
QObject *receiver, const char *signal, int minMIdx,
bool buildSignature);
static DBusHandlerResult messageFilter(DBusConnection *, DBusMessage *, void *);
diff --git a/src/dbus/qdbuserror.cpp b/src/dbus/qdbuserror.cpp
index e966f9dcde..decd345ece 100644
--- a/src/dbus/qdbuserror.cpp
+++ b/src/dbus/qdbuserror.cpp
@@ -41,6 +41,7 @@
#include <qdebug.h>
#include <qvarlengtharray.h>
+#include <private/qoffsetstringarray_p.h>
#ifndef QT_BOOTSTRAPPED
#include "qdbus_symbols_p.h"
@@ -52,110 +53,46 @@
QT_BEGIN_NAMESPACE
-/*
- * Use the following Perl script to generate the error string index list:
-===== PERL SCRIPT ====
-print "static const char errorMessages_string[] =\n";
-$counter = 0;
-$i = 0;
-while (<STDIN>) {
- chomp;
- print " \"$_\\0\"\n";
- $sizes[$i++] = $counter;
- $counter += 1 + length $_;
-}
-print " \"\\0\";\n\nstatic const int errorMessages_indices[] = {\n ";
-for ($j = 0; $j < $i; ++$j) {
- printf "$sizes[$j], ";
-}
-print "0\n};\n";
-===== PERL SCRIPT ====
-
- * The input data is as follows:
-other
-org.freedesktop.DBus.Error.Failed
-org.freedesktop.DBus.Error.NoMemory
-org.freedesktop.DBus.Error.ServiceUnknown
-org.freedesktop.DBus.Error.NoReply
-org.freedesktop.DBus.Error.BadAddress
-org.freedesktop.DBus.Error.NotSupported
-org.freedesktop.DBus.Error.LimitsExceeded
-org.freedesktop.DBus.Error.AccessDenied
-org.freedesktop.DBus.Error.NoServer
-org.freedesktop.DBus.Error.Timeout
-org.freedesktop.DBus.Error.NoNetwork
-org.freedesktop.DBus.Error.AddressInUse
-org.freedesktop.DBus.Error.Disconnected
-org.freedesktop.DBus.Error.InvalidArgs
-org.freedesktop.DBus.Error.UnknownMethod
-org.freedesktop.DBus.Error.TimedOut
-org.freedesktop.DBus.Error.InvalidSignature
-org.freedesktop.DBus.Error.UnknownInterface
-org.freedesktop.DBus.Error.UnknownObject
-org.freedesktop.DBus.Error.UnknownProperty
-org.freedesktop.DBus.Error.PropertyReadOnly
-org.qtproject.QtDBus.Error.InternalError
-org.qtproject.QtDBus.Error.InvalidService
-org.qtproject.QtDBus.Error.InvalidObjectPath
-org.qtproject.QtDBus.Error.InvalidInterface
-org.qtproject.QtDBus.Error.InvalidMember
-*/
-
-// in the same order as KnownErrors!
-static const char errorMessages_string[] =
- "other\0"
- "org.freedesktop.DBus.Error.Failed\0"
- "org.freedesktop.DBus.Error.NoMemory\0"
- "org.freedesktop.DBus.Error.ServiceUnknown\0"
- "org.freedesktop.DBus.Error.NoReply\0"
- "org.freedesktop.DBus.Error.BadAddress\0"
- "org.freedesktop.DBus.Error.NotSupported\0"
- "org.freedesktop.DBus.Error.LimitsExceeded\0"
- "org.freedesktop.DBus.Error.AccessDenied\0"
- "org.freedesktop.DBus.Error.NoServer\0"
- "org.freedesktop.DBus.Error.Timeout\0"
- "org.freedesktop.DBus.Error.NoNetwork\0"
- "org.freedesktop.DBus.Error.AddressInUse\0"
- "org.freedesktop.DBus.Error.Disconnected\0"
- "org.freedesktop.DBus.Error.InvalidArgs\0"
- "org.freedesktop.DBus.Error.UnknownMethod\0"
- "org.freedesktop.DBus.Error.TimedOut\0"
- "org.freedesktop.DBus.Error.InvalidSignature\0"
- "org.freedesktop.DBus.Error.UnknownInterface\0"
- "org.freedesktop.DBus.Error.UnknownObject\0"
- "org.freedesktop.DBus.Error.UnknownProperty\0"
- "org.freedesktop.DBus.Error.PropertyReadOnly\0"
- "org.qtproject.QtDBus.Error.InternalError\0"
- "org.qtproject.QtDBus.Error.InvalidService\0"
- "org.qtproject.QtDBus.Error.InvalidObjectPath\0"
- "org.qtproject.QtDBus.Error.InvalidInterface\0"
- "org.qtproject.QtDBus.Error.InvalidMember\0"
- "\0";
-
-static const int errorMessages_indices[] = {
- 0, 6, 40, 76, 118, 153, 191, 231,
- 273, 313, 349, 384, 421, 461, 501, 540,
- 581, 617, 661, 705, 746, 789, 833, 874,
- 916, 961, 1005
-};
-
-static const int errorMessages_count = sizeof errorMessages_indices /
- sizeof errorMessages_indices[0];
-
-static inline const char *get(QDBusError::ErrorType code)
-{
- int intcode = qBound(0, int(code) - int(QDBusError::Other), errorMessages_count);
- return errorMessages_string + errorMessages_indices[intcode];
-}
+static constexpr const auto errorMessages = qOffsetStringArray(
+ "NoError",
+ "other",
+ "org.freedesktop.DBus.Error.Failed",
+ "org.freedesktop.DBus.Error.NoMemory",
+ "org.freedesktop.DBus.Error.ServiceUnknown",
+ "org.freedesktop.DBus.Error.NoReply",
+ "org.freedesktop.DBus.Error.BadAddress",
+ "org.freedesktop.DBus.Error.NotSupported",
+ "org.freedesktop.DBus.Error.LimitsExceeded",
+ "org.freedesktop.DBus.Error.AccessDenied",
+ "org.freedesktop.DBus.Error.NoServer",
+ "org.freedesktop.DBus.Error.Timeout",
+ "org.freedesktop.DBus.Error.NoNetwork",
+ "org.freedesktop.DBus.Error.AddressInUse",
+ "org.freedesktop.DBus.Error.Disconnected",
+ "org.freedesktop.DBus.Error.InvalidArgs",
+ "org.freedesktop.DBus.Error.UnknownMethod",
+ "org.freedesktop.DBus.Error.TimedOut",
+ "org.freedesktop.DBus.Error.InvalidSignature",
+ "org.freedesktop.DBus.Error.UnknownInterface",
+ "org.freedesktop.DBus.Error.UnknownObject",
+ "org.freedesktop.DBus.Error.UnknownProperty",
+ "org.freedesktop.DBus.Error.PropertyReadOnly",
+ "org.qtproject.QtDBus.Error.InternalError",
+ "org.qtproject.QtDBus.Error.InvalidService",
+ "org.qtproject.QtDBus.Error.InvalidObjectPath",
+ "org.qtproject.QtDBus.Error.InvalidInterface",
+ "org.qtproject.QtDBus.Error.InvalidMember",
+ ""
+);
#ifndef QT_BOOTSTRAPPED
static inline QDBusError::ErrorType get(const char *name)
{
if (!name || !*name)
return QDBusError::NoError;
- for (int i = 0; i < errorMessages_count; ++i)
- if (strcmp(name, errorMessages_string + errorMessages_indices[i]) == 0)
- return QDBusError::ErrorType(i + int(QDBusError::Other));
+ for (int i = 0; i < errorMessages.count(); ++i)
+ if (strcmp(name, errorMessages.at(i)) == 0)
+ return QDBusError::ErrorType(i);
return QDBusError::Other;
}
#endif
@@ -301,7 +238,7 @@ QDBusError::QDBusError(const QDBusMessage &qdmsg)
QDBusError::QDBusError(ErrorType error, const QString &mess)
: code(error)
{
- nm = QLatin1String(::get(error));
+ nm = QLatin1String(errorMessages[error]);
msg = mess;
}
@@ -397,7 +334,7 @@ bool QDBusError::isValid() const
*/
QString QDBusError::errorString(ErrorType error)
{
- return QLatin1String(::get(error));
+ return QLatin1String(errorMessages[error]);
}
#ifndef QT_NO_DEBUG_STREAM
@@ -418,3 +355,11 @@ QDebug operator<<(QDebug dbg, const QDBusError &msg)
QT_END_NAMESPACE
#endif // QT_NO_DBUS
+
+/*
+MSVC2015 has the warning C4503 at the end of the file:
+QtPrivate::StaticStringBuilder<QtPrivate::IndexesList<...> - decorated name length exceeded, name was truncated
+It is used by qOffsetStringArray in a constexpr evaulation and this code does not exist in the object file,
+but we still have the warning or even error with -WX flag
+*/
+QT_WARNING_DISABLE_MSVC(4503)
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index dfef25e3a8..1125480447 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -338,7 +338,7 @@ void QDBusConnectionPrivate::_q_newConnection(QDBusConnectionPrivate *newConnect
static QByteArray buildMatchRule(const QString &service,
const QString &objectPath, const QString &interface,
- const QString &member, const QStringList &argMatch, const QString & /*signature*/)
+ const QString &member, const QDBusConnectionPrivate::ArgMatchRules &argMatch, const QString & /*signature*/)
{
QString result = QLatin1String("type='signal',");
QString keyValue = QLatin1String("%1='%2',");
@@ -353,11 +353,14 @@ static QByteArray buildMatchRule(const QString &service,
result += keyValue.arg(QLatin1String("member"), member);
// add the argument string-matching now
- if (!argMatch.isEmpty()) {
+ if (!argMatch.args.isEmpty()) {
keyValue = QLatin1String("arg%1='%2',");
- for (int i = 0; i < argMatch.count(); ++i)
- if (!argMatch.at(i).isNull())
- result += keyValue.arg(i).arg(argMatch.at(i));
+ for (int i = 0; i < argMatch.args.count(); ++i)
+ if (!argMatch.args.at(i).isNull())
+ result += keyValue.arg(i).arg(argMatch.args.at(i));
+ }
+ if (!argMatch.arg0namespace.isEmpty()) {
+ result += QStringLiteral("arg0namespace='%1',").arg(argMatch.arg0namespace);
}
result.chop(1); // remove ending comma
@@ -456,21 +459,26 @@ static QObject *findChildObject(const QDBusConnectionPrivate::ObjectTreeNode *ro
return 0;
}
-static QStringList matchArgsForService(const QString &service, QDBusServiceWatcher::WatchMode mode)
+static QDBusConnectionPrivate::ArgMatchRules matchArgsForService(const QString &service, QDBusServiceWatcher::WatchMode mode)
{
- QStringList matchArgs;
- matchArgs << service;
+ QDBusConnectionPrivate::ArgMatchRules matchArgs;
+ if (service.endsWith(QLatin1Char('*'))) {
+ matchArgs.arg0namespace = service.chopped(1);
+ matchArgs.args << QString();
+ }
+ else
+ matchArgs.args << service;
switch (mode) {
case QDBusServiceWatcher::WatchForOwnerChange:
break;
case QDBusServiceWatcher::WatchForRegistration:
- matchArgs << QString::fromLatin1("", 0);
+ matchArgs.args << QString::fromLatin1("", 0);
break;
case QDBusServiceWatcher::WatchForUnregistration:
- matchArgs << QString() << QString::fromLatin1("", 0);
+ matchArgs.args << QString() << QString::fromLatin1("", 0);
break;
}
return matchArgs;
@@ -1311,7 +1319,7 @@ int QDBusConnectionPrivate::findSlot(QObject* obj, const QByteArray &normalizedN
bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
const QString &service,
const QString &path, const QString &interface, const QString &name,
- const QStringList &argMatch,
+ const ArgMatchRules &argMatch,
QObject *receiver, const char *signal, int minMIdx,
bool buildSignature)
{
@@ -1621,14 +1629,14 @@ void QDBusConnectionPrivate::handleSignal(const QString &key, const QDBusMessage
continue;
if (hook.signature.isEmpty() && !hook.signature.isNull() && !msg.signature().isEmpty())
continue;
- if (!hook.argumentMatch.isEmpty()) {
+ if (!hook.argumentMatch.args.isEmpty()) {
const QVariantList arguments = msg.arguments();
- if (hook.argumentMatch.size() > arguments.size())
+ if (hook.argumentMatch.args.size() > arguments.size())
continue;
bool matched = true;
- for (int i = 0; i < hook.argumentMatch.size(); ++i) {
- const QString &param = hook.argumentMatch.at(i);
+ for (int i = 0; i < hook.argumentMatch.args.size(); ++i) {
+ const QString &param = hook.argumentMatch.args.at(i);
if (param.isNull())
continue; // don't try to match against this
if (param == arguments.at(i).toString())
@@ -1639,7 +1647,15 @@ void QDBusConnectionPrivate::handleSignal(const QString &key, const QDBusMessage
if (!matched)
continue;
}
-
+ if (!hook.argumentMatch.arg0namespace.isEmpty()) {
+ const QVariantList arguments = msg.arguments();
+ if (arguments.size() < 1)
+ continue;
+ const QString param = arguments.at(0).toString();
+ if (param != hook.argumentMatch.arg0namespace
+ && !param.startsWith(hook.argumentMatch.arg0namespace + QLatin1Char('.')))
+ continue;
+ }
activateSignal(hook, msg);
}
}
@@ -2181,11 +2197,22 @@ void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall, void *
}
}
+
bool QDBusConnectionPrivate::connectSignal(const QString &service,
const QString &path, const QString &interface, const QString &name,
const QStringList &argumentMatch, const QString &signature,
QObject *receiver, const char *slot)
{
+ ArgMatchRules rules;
+ rules.args = argumentMatch;
+ return connectSignal(service, path, interface, name, rules, signature, receiver, slot);
+}
+
+bool QDBusConnectionPrivate::connectSignal(const QString &service,
+ const QString &path, const QString &interface, const QString &name,
+ const ArgMatchRules &argumentMatch, const QString &signature,
+ QObject *receiver, const char *slot)
+{
// check the slot
QDBusConnectionPrivate::SignalHook hook;
QString key;
@@ -2242,9 +2269,11 @@ bool QDBusConnectionPrivate::addSignalHook(const QString &key, const SignalHook
WatchedServicesHash::mapped_type &data = watchedServices[hook.service];
if (++data.refcount == 1) {
// we need to watch for this service changing
+ ArgMatchRules rules;
+ rules.args << hook.service;
q_dbus_bus_add_match(connection,
buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(),
- QDBusUtil::nameOwnerChanged(), QStringList() << hook.service, QString()),
+ QDBusUtil::nameOwnerChanged(), rules, QString()),
NULL);
data.owner = getNameOwnerNoCache(hook.service);
qDBusDebug() << this << "Watching service" << hook.service << "for owner changes (current owner:"
@@ -2257,8 +2286,18 @@ bool QDBusConnectionPrivate::addSignalHook(const QString &key, const SignalHook
}
bool QDBusConnectionPrivate::disconnectSignal(const QString &service,
+ const QString &path, const QString &interface, const QString &name,
+ const QStringList &argumentMatch, const QString &signature,
+ QObject *receiver, const char *slot)
+{
+ ArgMatchRules rules;
+ rules.args = argumentMatch;
+ return disconnectSignal(service, path, interface, name, rules, signature, receiver, slot);
+}
+
+bool QDBusConnectionPrivate::disconnectSignal(const QString &service,
const QString &path, const QString &interface, const QString &name,
- const QStringList &argumentMatch, const QString &signature,
+ const ArgMatchRules &argumentMatch, const QString &signature,
QObject *receiver, const char *slot)
{
// check the slot
@@ -2289,7 +2328,7 @@ bool QDBusConnectionPrivate::removeSignalHook(const QString &key, const SignalHo
entry.signature == hook.signature &&
entry.obj == hook.obj &&
entry.midx == hook.midx &&
- entry.argumentMatch == hook.argumentMatch) {
+ entry.argumentMatch.args == hook.argumentMatch.args) {
// no need to compare the parameters if it's the same slot
removeSignalHookNoLock(it);
return true; // it was there
@@ -2331,9 +2370,11 @@ QDBusConnectionPrivate::removeSignalHookNoLock(SignalHookHash::Iterator it)
if (sit != watchedServices.end()) {
if (--sit.value().refcount == 0) {
watchedServices.erase(sit);
+ ArgMatchRules rules;
+ rules.args << hook.service;
q_dbus_bus_remove_match(connection,
buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(),
- QDBusUtil::nameOwnerChanged(), QStringList() << hook.service, QString()),
+ QDBusUtil::nameOwnerChanged(), rules, QString()),
NULL);
}
}
@@ -2394,7 +2435,7 @@ void QDBusConnectionPrivate::connectRelay(const QString &service,
QByteArray sig;
sig.append(QSIGNAL_CODE + '0');
sig.append(signal.methodSignature());
- if (!prepareHook(hook, key, service, path, interface, QString(), QStringList(), receiver, sig,
+ if (!prepareHook(hook, key, service, path, interface, QString(), ArgMatchRules(), receiver, sig,
QDBusAbstractInterface::staticMetaObject.methodCount(), true))
return; // don't connect
@@ -2415,7 +2456,7 @@ void QDBusConnectionPrivate::disconnectRelay(const QString &service,
QByteArray sig;
sig.append(QSIGNAL_CODE + '0');
sig.append(signal.methodSignature());
- if (!prepareHook(hook, key, service, path, interface, QString(), QStringList(), receiver, sig,
+ if (!prepareHook(hook, key, service, path, interface, QString(), ArgMatchRules(), receiver, sig,
QDBusAbstractInterface::staticMetaObject.methodCount(), true))
return; // don't disconnect
@@ -2448,7 +2489,7 @@ bool QDBusConnectionPrivate::shouldWatchService(const QString &service)
*/
void QDBusConnectionPrivate::watchService(const QString &service, QDBusServiceWatcher::WatchMode mode, QObject *obj, const char *member)
{
- QStringList matchArgs = matchArgsForService(service, mode);
+ ArgMatchRules matchArgs = matchArgsForService(service, mode);
connectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), QDBusUtil::nameOwnerChanged(),
matchArgs, QString(), obj, member);
}
@@ -2463,7 +2504,7 @@ void QDBusConnectionPrivate::watchService(const QString &service, QDBusServiceWa
*/
void QDBusConnectionPrivate::unwatchService(const QString &service, QDBusServiceWatcher::WatchMode mode, QObject *obj, const char *member)
{
- QStringList matchArgs = matchArgsForService(service, mode);
+ ArgMatchRules matchArgs = matchArgsForService(service, mode);
disconnectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), QDBusUtil::nameOwnerChanged(),
matchArgs, QString(), obj, member);
}
diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp
index 2a31dd950a..4d0131afff 100644
--- a/src/dbus/qdbuspendingcall.cpp
+++ b/src/dbus/qdbuspendingcall.cpp
@@ -311,7 +311,7 @@ QDBusPendingCall &QDBusPendingCall::operator=(const QDBusPendingCall &other)
\sa QDBusPendingReply::isFinished()
*/
/*!
- \fn bool QDBusPendingReply::isFinished() const
+ \fn template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> bool QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::isFinished() const
Returns \c true if the pending call has finished processing and the
reply has been received. If this function returns \c true, the
@@ -340,7 +340,7 @@ void QDBusPendingCall::waitForFinished()
}
/*!
- \fn bool QDBusPendingReply::isValid() const
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> bool QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::isValid() const
Returns \c true if the reply contains a normal reply message, false
if it contains anything else.
@@ -357,7 +357,7 @@ bool QDBusPendingCall::isValid() const
}
/*!
- \fn bool QDBusPendingReply::isError() const
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> bool QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::isError() const
Returns \c true if the reply contains an error message, false if it
contains a normal method reply.
@@ -374,7 +374,7 @@ bool QDBusPendingCall::isError() const
}
/*!
- \fn QDBusError QDBusPendingReply::error() const
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusError QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::error() const
Retrieves the error content of the reply message, if it has
finished processing. If the reply message has not finished
@@ -395,7 +395,7 @@ QDBusError QDBusPendingCall::error() const
}
/*!
- \fn QDBusMessage QDBusPendingReply::reply() const
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusMessage QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::reply() const
Retrieves the reply message received for the asynchronous call
that was sent, if it has finished processing. If the pending call
@@ -445,7 +445,7 @@ bool QDBusPendingCall::setReplyCallback(QObject *target, const char *member)
\since 4.6
Creates a QDBusPendingCall object based on the error condition
\a error. The resulting pending call object will be in the
- "finished" state and QDBusPendingReply::isError() will return true.
+ "finished" state and QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::isError() will return true.
\sa fromCompletedCall()
*/
diff --git a/src/dbus/qdbuspendingcall.h b/src/dbus/qdbuspendingcall.h
index ec8ba6c541..24b1d6a7ca 100644
--- a/src/dbus/qdbuspendingcall.h
+++ b/src/dbus/qdbuspendingcall.h
@@ -67,7 +67,7 @@ public:
void swap(QDBusPendingCall &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
-#ifndef Q_QDOC
+#ifndef Q_CLANG_QDOC
// pretend that they aren't here
bool isFinished() const;
void waitForFinished();
diff --git a/src/dbus/qdbuspendingreply.cpp b/src/dbus/qdbuspendingreply.cpp
index fef6f36432..6aec571563 100644
--- a/src/dbus/qdbuspendingreply.cpp
+++ b/src/dbus/qdbuspendingreply.cpp
@@ -94,7 +94,7 @@
*/
/*!
- \fn QDBusPendingReply::QDBusPendingReply()
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::QDBusPendingReply()
Creates an empty QDBusPendingReply object. Without assigning a
QDBusPendingCall object to this reply, QDBusPendingReply cannot do
@@ -102,7 +102,7 @@
*/
/*!
- \fn QDBusPendingReply::QDBusPendingReply(const QDBusPendingReply &other)
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::QDBusPendingReply(const QDBusPendingReply &other)
Creates a copy of the \a other QDBusPendingReply object. Just like
QDBusPendingCall and QDBusPendingCallWatcher, this QDBusPendingReply
@@ -111,7 +111,7 @@
*/
/*!
- \fn QDBusPendingReply::QDBusPendingReply(const QDBusPendingCall &call)
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::QDBusPendingReply(const QDBusPendingCall &call)
Creates a QDBusPendingReply object that will take its contents from
the \a call pending asynchronous call. This QDBusPendingReply object
@@ -119,7 +119,7 @@
*/
/*!
- \fn QDBusPendingReply::QDBusPendingReply(const QDBusMessage &message)
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::QDBusPendingReply(const QDBusMessage &message)
Creates a QDBusPendingReply object that will take its contents from
the message \a message. In this case, this object will be already
@@ -129,7 +129,7 @@
*/
/*!
- \fn QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingReply &other)
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply &QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::operator=(const QDBusPendingReply &other)
Makes a copy of \a other and drops the reference to the current
pending call. If the current reference is to an unfinished pending
@@ -139,7 +139,7 @@
*/
/*!
- \fn QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingCall &call)
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply &QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::operator=(const QDBusPendingCall &call)
Makes this object take its contents from the \a call pending call
and drops the reference to the current pending call. If the
@@ -149,7 +149,7 @@
*/
/*!
- \fn QDBusPendingReply &QDBusPendingReply::operator=(const QDBusMessage &message)
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply &QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::operator=(const QDBusMessage &message)
Makes this object take its contents from the \a message message
and drops the reference to the current pending call. If the
@@ -171,7 +171,7 @@
*/
/*!
- \fn int QDBusPendingReply::count() const
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> int QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::count() const
Return the number of arguments the reply is supposed to have. This
number matches the number of non-void template parameters in this
@@ -183,7 +183,7 @@
*/
/*!
- \fn QVariant QDBusPendingReply::argumentAt(int index) const
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QVariant QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::argumentAt(int index) const
Returns the argument at position \a index in the reply's
contents. If the reply doesn't have that many elements, this
@@ -198,12 +198,7 @@
*/
/*!
- \typedef QDBusPendingReply::T1
- \internal
- */
-
-/*!
- \fn T1 QDBusPendingReply::value() const
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> T1 QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::value() const
Returns the first argument in this reply, cast to type \c T1 (the
first template parameter of this class). This is equivalent to
@@ -221,7 +216,7 @@
*/
/*!
- \fn QDBusPendingReply::operator T1() const
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::operator T1() const
Returns the first argument in this reply, cast to type \c T1 (the
first template parameter of this class). This is equivalent to
@@ -239,7 +234,7 @@
*/
/*!
- \fn void QDBusPendingReply::waitForFinished()
+ \fn template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> void QDBusPendingReply<T1, T2, T3, T4, T5, T6, T7, T8>::waitForFinished()
Suspends the execution of the calling thread until the reply is
received and processed. After this function returns, isFinished()
diff --git a/src/dbus/qdbuspendingreply.h b/src/dbus/qdbuspendingreply.h
index 4d2c3a7c5a..bc5cd92c84 100644
--- a/src/dbus/qdbuspendingreply.h
+++ b/src/dbus/qdbuspendingreply.h
@@ -108,10 +108,8 @@ namespace QDBusPendingReplyTypes {
template <> struct NotVoid<void> { typedef TypeIsVoid Type; };
} // namespace QDBusPendingReplyTypes
-#ifndef Q_CLANG_QDOC
template<typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
-#endif
class QDBusPendingReply:
#ifdef Q_CLANG_QDOC
public QDBusPendingCall
@@ -171,7 +169,6 @@ public:
QDBusError error() const;
QDBusMessage reply() const;
- typedef QVariant T1;
inline T1 value() const;
inline operator T1() const;
#else
diff --git a/src/dbus/qdbusreply.cpp b/src/dbus/qdbusreply.cpp
index ab361f1674..6abfaf174c 100644
--- a/src/dbus/qdbusreply.cpp
+++ b/src/dbus/qdbusreply.cpp
@@ -81,7 +81,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn template<typename T> QDBusReply<T>::QDBusReply(const QDBusPendingReply &reply)
+ \fn template<typename T> QDBusReply<T>::QDBusReply(const QDBusPendingReply<T> &reply)
Constructs a QDBusReply object from the pending reply message, \a reply.
*/
diff --git a/src/dbus/qdbusreply.h b/src/dbus/qdbusreply.h
index 177b6c6e89..869687ac85 100644
--- a/src/dbus/qdbusreply.h
+++ b/src/dbus/qdbusreply.h
@@ -82,14 +82,10 @@ public:
other.waitForFinished();
return *this = other.reply();
}
-#if defined(Q_CLANG_QDOC)
- inline QDBusReply(const QDBusPendingReply &reply) { }
-#else
inline QDBusReply(const QDBusPendingReply<T> &reply)
{
*this = static_cast<QDBusPendingCall>(reply);
}
-#endif
inline QDBusReply(const QDBusError &dbusError = QDBusError())
: m_error(dbusError), m_data(Type())
diff --git a/src/dbus/qdbusservicewatcher.cpp b/src/dbus/qdbusservicewatcher.cpp
index 0c2fb9118f..b0bfe7254d 100644
--- a/src/dbus/qdbusservicewatcher.cpp
+++ b/src/dbus/qdbusservicewatcher.cpp
@@ -139,6 +139,17 @@ void QDBusServiceWatcherPrivate::removeService(const QString &service)
QDBusConnectionInterface::serviceOwnerChanged() signal because it allows
one to receive only the signals for which the class is interested in.
+ Ending a service name with the character '*' will match all service names
+ within the specified namespace.
+
+ For example "com.example.backend1*" will match
+ \list
+ \li com.example.backend1
+ \li com.example.backend1.foo
+ \li com.example.backend1.foo.bar
+ \endlist
+ Substrings in the same domain will not be matched, i.e "com.example.backend12".
+
\sa QDBusConnection
*/
diff --git a/src/dbus/qdbusutil.cpp b/src/dbus/qdbusutil.cpp
index 28341a71a8..dc94897ac4 100644
--- a/src/dbus/qdbusutil.cpp
+++ b/src/dbus/qdbusutil.cpp
@@ -331,8 +331,8 @@ namespace QDBusUtil
/*!
\internal
- \fn bool QDBusUtil::isValidPartOfObjectPath(const QStringRef &part)
- See QDBusUtil::isValidObjectPath
+ \fn bool isValidPartOfObjectPath(const QStringRef &part)
+ See isValidObjectPath
*/
bool isValidPartOfObjectPath(const QStringRef &part)
{
@@ -349,13 +349,13 @@ namespace QDBusUtil
/*!
\internal
- \fn bool QDBusUtil::isValidPartOfObjectPath(const QString &part)
+ \fn bool isValidPartOfObjectPath(const QString &part)
\overload
*/
/*!
- \fn bool QDBusUtil::isValidInterfaceName(const QString &ifaceName)
+ \fn bool isValidInterfaceName(const QString &ifaceName)
Returns \c true if this is \a ifaceName is a valid interface name.
Valid interface names must:
@@ -384,7 +384,7 @@ namespace QDBusUtil
}
/*!
- \fn bool QDBusUtil::isValidUniqueConnectionName(const QStringRef &connName)
+ \fn bool isValidUniqueConnectionName(const QStringRef &connName)
Returns \c true if \a connName is a valid unique connection name.
Unique connection names start with a colon (":") and are followed by a list of dot-separated
@@ -414,13 +414,13 @@ namespace QDBusUtil
}
/*!
- \fn bool QDBusUtil::isValidUniqueConnectionName(const QString &connName)
+ \fn bool isValidUniqueConnectionName(const QString &connName)
\overload
*/
/*!
- \fn bool QDBusUtil::isValidBusName(const QString &busName)
+ \fn bool isValidBusName(const QString &busName)
Returns \c true if \a busName is a valid bus name.
A valid bus name is either a valid unique connection name or follows the rules:
@@ -462,7 +462,7 @@ namespace QDBusUtil
}
/*!
- \fn bool QDBusUtil::isValidMemberName(const QStringRef &memberName)
+ \fn bool isValidMemberName(const QStringRef &memberName)
Returns \c true if \a memberName is a valid member name. A valid member name does not exceed
255 characters in length, is not empty, is composed only of ASCII letters, digits and
underscores, but does not start with a digit.
@@ -482,13 +482,13 @@ namespace QDBusUtil
}
/*!
- \fn bool QDBusUtil::isValidMemberName(const QString &memberName)
+ \fn bool isValidMemberName(const QString &memberName)
\overload
*/
/*!
- \fn bool QDBusUtil::isValidErrorName(const QString &errorName)
+ \fn bool isValidErrorName(const QString &errorName)
Returns \c true if \a errorName is a valid error name. Valid error names are valid interface
names and vice-versa, so this function is actually an alias for isValidInterfaceName.
*/
@@ -498,7 +498,7 @@ namespace QDBusUtil
}
/*!
- \fn bool QDBusUtil::isValidObjectPath(const QString &path)
+ \fn bool isValidObjectPath(const QString &path)
Returns \c true if \a path is valid object path.
Valid object paths follow the rules:
@@ -529,7 +529,7 @@ namespace QDBusUtil
}
/*!
- \fn bool QDBusUtil::isValidBasicType(int type)
+ \fn bool isValidBasicType(int type)
Returns \c true if \a c is a valid, basic D-Bus type.
*/
bool isValidBasicType(int c)
@@ -538,7 +538,7 @@ namespace QDBusUtil
}
/*!
- \fn bool QDBusUtil::isValidFixedType(int type)
+ \fn bool isValidFixedType(int type)
Returns \c true if \a c is a valid, fixed D-Bus type.
*/
bool isValidFixedType(int c)
@@ -548,7 +548,7 @@ namespace QDBusUtil
/*!
- \fn bool QDBusUtil::isValidSignature(const QString &signature)
+ \fn bool isValidSignature(const QString &signature)
Returns \c true if \a signature is a valid D-Bus type signature for one or more types.
This function returns \c true if it can all of \a signature into valid, individual types and no
characters remain in \a signature.
@@ -569,7 +569,7 @@ namespace QDBusUtil
}
/*!
- \fn bool QDBusUtil::isValidSingleSignature(const QString &signature)
+ \fn bool isValidSingleSignature(const QString &signature)
Returns \c true if \a signature is a valid D-Bus type signature for exactly one full type. This
function tries to convert the type signature into a D-Bus type and, if it succeeds and no
characters remain in the signature, it returns \c true.
diff --git a/src/dbus/qt_attribution.json b/src/dbus/qt_attribution.json
index 69d946ba5c..33eaee1ed1 100644
--- a/src/dbus/qt_attribution.json
+++ b/src/dbus/qt_attribution.json
@@ -7,7 +7,7 @@
"Description": "D-Bus is a message bus system, a simple way for applications to talk to one another.",
"Homepage": "https://www.freedesktop.org/wiki/Software/dbus/",
"Version": "Minimal supported is 1.2, compatible up to ...",
- "Version": "1.12",
+ "Version": "dbus-1.12.12",
"LicenseId": "AFL-2.1 OR GPL-2.0-or-later",
"License": "Academic Free License v2.1, or GNU General Public License v2.0 or later",
"LicenseFile": "LIBDBUS-1-LICENSE.txt",
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index 1309f17efd..e2163b06d0 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -966,8 +966,10 @@ protected:
int m_lastColumn;
};
+#ifndef Q_CLANG_QDOC
#define QAccessibleInterface_iid "org.qt-project.Qt.QAccessibleInterface"
Q_DECLARE_INTERFACE(QAccessibleInterface, QAccessibleInterface_iid)
+#endif
Q_GUI_EXPORT const char *qAccessibleRoleString(QAccessible::Role role);
Q_GUI_EXPORT const char *qAccessibleEventString(QAccessible::Event event);
diff --git a/src/gui/accessible/qaccessibleobject.h b/src/gui/accessible/qaccessibleobject.h
index 81479c32ab..fd07d33a18 100644
--- a/src/gui/accessible/qaccessibleobject.h
+++ b/src/gui/accessible/qaccessibleobject.h
@@ -65,7 +65,7 @@ public:
QAccessibleInterface *childAt(int x, int y) const override;
protected:
- virtual ~QAccessibleObject();
+ ~QAccessibleObject();
private:
QAccessibleObjectPrivate *d;
diff --git a/src/gui/configure.json b/src/gui/configure.json
index e4f25ab313..59c06af97f 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -1106,7 +1106,7 @@
"angle": {
"label": "ANGLE",
"autoDetect": "features.opengles2 || features.opengl-dynamic",
- "condition": "features.dxguid && tests.fxc && (features.direct3d9 || (config.winrt && features.direct3d11 && libs.d3dcompiler))",
+ "condition": "!features.opengl-desktop && features.dxguid && tests.fxc && (features.direct3d9 || (config.winrt && features.direct3d11 && libs.d3dcompiler))",
"output": [
"publicFeature",
{ "type": "define", "name": "QT_OPENGL_ES_2_ANGLE" },
@@ -1309,9 +1309,9 @@
},
"opengles2": {
"label": "OpenGL ES 2.0",
- "enable": "input.opengl == 'es2'",
+ "enable": "input.opengl == 'es2' || input.angle == 'yes'",
"disable": "input.opengl == 'desktop' || input.opengl == 'dynamic' || input.opengl == 'no'",
- "condition": "config.win32 || (!config.watchos && !features.opengl-desktop && libs.opengl_es2)",
+ "condition": "(config.win32 && !features.opengl-dynamic) || (!config.watchos && !features.opengl-desktop && libs.opengl_es2)",
"output": [
"publicFeature",
"publicQtConfig",
@@ -1345,6 +1345,7 @@
},
"opengl-desktop": {
"label": "Desktop OpenGL",
+ "autoDetect": "!config.win32",
"enable": "input.opengl == 'desktop'",
"disable": "input.opengl == 'es2' || input.opengl == 'dynamic' || input.opengl == 'no'",
"condition": "(config.win32 && !config.winrt && !features.opengles2 && (config.msvc || libs.opengl))
@@ -1352,8 +1353,7 @@
},
"opengl-dynamic": {
"label": "Dynamic OpenGL",
- "enable": "input.opengl == 'dynamic'",
- "autoDetect": false,
+ "disable": "input.angle == 'yes' || input.opengl == 'no' || input.opengl == 'desktop'",
"condition": "config.win32 && !config.winrt",
"output": [
{ "type": "publicFeature", "name": "dynamicgl" },
@@ -1388,7 +1388,7 @@
"eglfs": {
"label": "EGLFS",
"section": "Platform plugins",
- "condition": "!config.android && !config.darwin && !config.win32 && features.egl",
+ "condition": "!config.android && !config.darwin && !config.win32 && !config.wasm && features.egl",
"output": [ "privateFeature" ]
},
"eglfs_brcm": {
diff --git a/src/gui/doc/snippets/clipboard/clipwindow.cpp b/src/gui/doc/snippets/clipboard/clipwindow.cpp
index bf1b2d904b..d1b39070fa 100644
--- a/src/gui/doc/snippets/clipboard/clipwindow.cpp
+++ b/src/gui/doc/snippets/clipboard/clipwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "clipwindow.h"
@@ -67,10 +67,11 @@ ClipWindow::ClipWindow(QWidget *parent)
previousItems = new QListWidget(centralWidget);
//! [0]
- connect(clipboard, SIGNAL(dataChanged()), this, SLOT(updateClipboard()));
+ connect(clipboard, &QClipboard::dataChanged,
+ this, &ClipWindow::updateClipboard);
//! [0]
- connect(mimeTypeCombo, SIGNAL(activated(QString)),
- this, SLOT(updateData(QString)));
+ connect(mimeTypeCombo, QOverload<QString>::of(&QComboBox::activated),
+ this, &ClipWindow::updateData);
QVBoxLayout *currentLayout = new QVBoxLayout(currentItem);
currentLayout->addWidget(mimeTypeLabel);
diff --git a/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp b/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp
index 40893fae87..4266da0a11 100644
--- a/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp
+++ b/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp
@@ -73,8 +73,8 @@ for (int i = 0; i < 4; ++i) {
//! [2]
QTreeView *treeView = new QTreeView(this);
treeView->setModel(myStandardItemModel);
-connect(treeView, SIGNAL(clicked(QModelIndex)),
- this, SLOT(clicked(QModelIndex)));
+connect(treeView, &QTreeView::clicked,
+ this, &MyWidget::clicked);
//! [2]
diff --git a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp
index 7c5c387a5a..a399d444e1 100644
--- a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp
+++ b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp
@@ -64,7 +64,8 @@ MyMainWidget::MyMainWidget(QWidget *parent)
:QWidget(parent)
{
QGuiApplication::setFallbackSessionManagementEnabled(false);
- connect(qApp, SIGNAL(commitDataRequest(QSessionManager)), SLOT(commitData(QSessionManager)));
+ connect(qApp, &QGuiApplication::commitDataRequest,
+ this, &MyMainWidget::commitData);
}
void MyMainWidget::commitData(QSessionManager& manager)
@@ -102,12 +103,14 @@ appname -session id
//! [3]
-foreach (const QString &command, mySession.restartCommand())
+const QStringList commands = mySession.restartCommand();
+for (const QString &command : commands)
do_something(command);
//! [3]
//! [4]
-foreach (const QString &command, mySession.discardCommand())
+const QStringList commands = mySession.discardCommand();
+for (const QString &command : mySession.discardCommand())
do_something(command);
//! [4]
diff --git a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication_x11.cpp b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication_x11.cpp
index e91aa3d548..961ecd6cde 100644
--- a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication_x11.cpp
+++ b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication_x11.cpp
@@ -49,7 +49,7 @@
****************************************************************************/
//! [0]
-QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
calculateHugeMandelbrot(); // lunch time...
-QApplication::restoreOverrideCursor();
+QGuiApplication::restoreOverrideCursor();
//! [0]
diff --git a/src/gui/doc/snippets/draganddrop/mainwindow.cpp b/src/gui/doc/snippets/draganddrop/mainwindow.cpp
index 551114856e..11311a0b57 100644
--- a/src/gui/doc/snippets/draganddrop/mainwindow.cpp
+++ b/src/gui/doc/snippets/draganddrop/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "dragwidget.h"
#include "mainwindow.h"
@@ -64,10 +64,10 @@ MainWindow::MainWindow(QWidget *parent)
QLabel *dataLabel = new QLabel(tr("Amount of data (bytes):"), centralWidget);
dragWidget = new DragWidget(centralWidget);
- connect(dragWidget, SIGNAL(mimeTypes(QStringList)),
- this, SLOT(setMimeTypes(QStringList)));
- connect(dragWidget, SIGNAL(dragResult(QString)),
- this, SLOT(setDragResult(QString)));
+ connect(dragWidget, &DragWidget::mimeTypes,
+ this, &MainWindow::setMimeTypes);
+ connect(dragWidget, &DragWidget:dragResult,
+ this, &MainWindow::setDragResult);
QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
mainLayout->addWidget(mimeTypeLabel);
diff --git a/src/gui/doc/snippets/picture/picture.cpp b/src/gui/doc/snippets/picture/picture.cpp
index 3a7676f60a..863476fdbf 100644
--- a/src/gui/doc/snippets/picture/picture.cpp
+++ b/src/gui/doc/snippets/picture/picture.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
void myProcessing(const QString &)
{
@@ -85,8 +85,8 @@ int main()
{
// FORMATS
//! [2]
- QStringList list = QPicture::inputFormatList();
- foreach (const QString &string, list)
+ const QStringList list = QPicture::inputFormatList();
+ for (const QString &string : list)
myProcessing(string);
//! [2]
}
@@ -94,8 +94,8 @@ int main()
{
// OUTPUT
//! [3]
- QStringList list = QPicture::outputFormatList();
- foreach (const QString &string, list)
+ const QStringList list = QPicture::outputFormatList();
+ for (const QString &string : list)
myProcessing(string);
//! [3]
}
diff --git a/src/gui/doc/snippets/qfontdatabase/main.cpp b/src/gui/doc/snippets/qfontdatabase/main.cpp
index ae078f374d..5a5aa7b485 100644
--- a/src/gui/doc/snippets/qfontdatabase/main.cpp
+++ b/src/gui/doc/snippets/qfontdatabase/main.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
int main(int argc, char **argv)
{
@@ -60,16 +60,19 @@ int main(int argc, char **argv)
fontTree.setColumnCount(2);
fontTree.setHeaderLabels(QStringList() << "Font" << "Smooth Sizes");
- foreach (const QString &family, database.families()) {
+ const QStringList fontFamilies = database.families();
+ for (const QString &family : fontFamilies) {
QTreeWidgetItem *familyItem = new QTreeWidgetItem(&fontTree);
familyItem->setText(0, family);
- foreach (const QString &style, database.styles(family)) {
+ const QStringList fontStyles = database.styles(family);
+ for (const QString &style : fontStyles) {
QTreeWidgetItem *styleItem = new QTreeWidgetItem(familyItem);
styleItem->setText(0, style);
QString sizes;
- foreach (int points, database.smoothSizes(family, style))
+ const QList<int> smoothSizes = database.smoothSizes(family, style)
+ for (int points : smoothSizes)
sizes += QString::number(points) + ' ';
styleItem->setText(1, sizes.trimmed());
diff --git a/src/gui/doc/snippets/separations/screenwidget.cpp b/src/gui/doc/snippets/separations/screenwidget.cpp
index 6f8be49bfa..d562991d26 100644
--- a/src/gui/doc/snippets/separations/screenwidget.cpp
+++ b/src/gui/doc/snippets/separations/screenwidget.cpp
@@ -105,8 +105,8 @@ ScreenWidget::ScreenWidget(QWidget *parent, QColor initialColor,
//invertButton->setOn(inverted);
invertButton->setEnabled(false);
- connect(colorButton, SIGNAL(clicked()), this, SLOT(setColor()));
- connect(invertButton, SIGNAL(clicked()), this, SLOT(invertImage()));
+ connect(colorButton, &QPushButton::clicked, this, &ScreenWidget::setColor);
+ connect(invertButton, &QPushButton::clicked, this, &ScreenWidget::invertImage);
QGridLayout *gridLayout = new QGridLayout;
gridLayout->addWidget(imageLabel, 0, 0, 1, 2);
diff --git a/src/gui/doc/snippets/separations/viewer.cpp b/src/gui/doc/snippets/separations/viewer.cpp
index 641294ea35..018b397f1a 100644
--- a/src/gui/doc/snippets/separations/viewer.cpp
+++ b/src/gui/doc/snippets/separations/viewer.cpp
@@ -58,7 +58,7 @@ A main menu provides entries for selecting files, and adjusting the
brightness of the separations.
*/
-#include <QtGui>
+#include <QtWidgets>
#include "finalwidget.h"
#include "screenwidget.h"
@@ -126,11 +126,11 @@ void Viewer::createMenus()
menuBar()->addMenu(fileMenu);
menuBar()->addMenu(brightnessMenu);
- connect(openAction, SIGNAL(triggered()), this, SLOT(chooseFile()));
- connect(saveAction, SIGNAL(triggered()), this, SLOT(saveImage()));
- connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
- connect(brightnessMenu, SIGNAL(triggered(QAction*)), this,
- SLOT(setBrightness(QAction*)));
+ connect(openAction, &QAction::triggered, this, &Viewer::chooseFile);
+ connect(saveAction, &QAction::triggered, this, &Viewer::saveImage);
+ connect(quitAction, &QAction::triggered, qApp, QApplication::quit);
+ connect(brightnessMenu, &QMenu::triggered,
+ this, &Viewer::setBrightness);
}
/*
@@ -160,9 +160,9 @@ QFrame* Viewer::createCentralWidget()
yellowWidget = new ScreenWidget(frame, Qt::yellow, tr("Yellow"),
ScreenWidget::Yellow, labelSize);
- connect(cyanWidget, SIGNAL(imageChanged()), this, SLOT(createImage()));
- connect(magentaWidget, SIGNAL(imageChanged()), this, SLOT(createImage()));
- connect(yellowWidget, SIGNAL(imageChanged()), this, SLOT(createImage()));
+ connect(cyanWidget, &ScreenWidget::imageChanged, this, &Viewer::createImage);
+ connect(magentaWidget, &ScreenWidget::imageChanged, this, &Viewer::createImage);
+ connect(yellowWidget, &ScreenWidget::imageChanged, this, &Viewer::createImage);
grid->addWidget(finalWidget, 0, 0, Qt::AlignTop | Qt::AlignHCenter);
grid->addWidget(cyanWidget, 0, 1, Qt::AlignTop | Qt::AlignHCenter);
diff --git a/src/gui/doc/snippets/textblock-fragments/mainwindow.cpp b/src/gui/doc/snippets/textblock-fragments/mainwindow.cpp
index bcc5c7dc30..bf864ce48d 100644
--- a/src/gui/doc/snippets/textblock-fragments/mainwindow.cpp
+++ b/src/gui/doc/snippets/textblock-fragments/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
#include "xmlwriter.h"
@@ -73,9 +73,9 @@ MainWindow::MainWindow()
editor = new QTextEdit(this);
- connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile()));
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
- connect(calendarAction, SIGNAL(triggered()), this, SLOT(insertCalendar()));
+ connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
+ connect(quitAction, &QAction::triggered, this, &MainWindow::close);
+ connect(calendarAction, &QAction::triggered, this, &MainWindow::insertCalendar);
setCentralWidget(editor);
setWindowTitle(tr("Text Document Writer"));
diff --git a/src/gui/doc/snippets/textdocument-blocks/mainwindow.cpp b/src/gui/doc/snippets/textdocument-blocks/mainwindow.cpp
index f512cf0dc6..a5801da67e 100644
--- a/src/gui/doc/snippets/textdocument-blocks/mainwindow.cpp
+++ b/src/gui/doc/snippets/textdocument-blocks/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
#include "xmlwriter.h"
@@ -75,9 +75,9 @@ MainWindow::MainWindow()
editor = new QTextEdit(this);
//! [0]
- connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile()));
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
- connect(calendarAction, SIGNAL(triggered()), this, SLOT(insertCalendar()));
+ connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
+ connect(quitAction, &QAction::triggered, this, &MainWindow::close);
+ connect(calendarAction, &QAction::triggered, this, &MainWindow::insertCalendar);
setCentralWidget(editor);
setWindowTitle(tr("Text Document Writer"));
diff --git a/src/gui/doc/snippets/textdocument-frames/mainwindow.cpp b/src/gui/doc/snippets/textdocument-frames/mainwindow.cpp
index f15ad45f2e..edfadb4c77 100644
--- a/src/gui/doc/snippets/textdocument-frames/mainwindow.cpp
+++ b/src/gui/doc/snippets/textdocument-frames/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
#include "xmlwriter.h"
@@ -64,7 +64,7 @@ MainWindow::MainWindow()
quitAction->setShortcut(tr("Ctrl+Q"));
menuBar()->addMenu(fileMenu);
- editor = new QTextEdit();
+ editor = new QTextEdit;
QTextCursor cursor(editor->textCursor());
cursor.movePosition(QTextCursor::Start);
@@ -130,8 +130,8 @@ MainWindow::MainWindow()
plainCharFormat);
- connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile()));
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
+ connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
+ connect(quitAction, &QAction::triggered, this, &MainWindow::close);
setCentralWidget(editor);
setWindowTitle(tr("Text Document Frames"));
diff --git a/src/gui/doc/snippets/textdocument-lists/mainwindow.cpp b/src/gui/doc/snippets/textdocument-lists/mainwindow.cpp
index 15a2752c8b..785f7ebcc9 100644
--- a/src/gui/doc/snippets/textdocument-lists/mainwindow.cpp
+++ b/src/gui/doc/snippets/textdocument-lists/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
@@ -88,7 +88,8 @@ MainWindow::MainWindow()
document = new QTextDocument(this);
editor->setDocument(document);
- connect(editor, SIGNAL(selectionChanged()), this, SLOT(updateMenus()));
+ connect(editor, &QTextEdit::selectionChanged,
+ this, &MainWindow::updateMenus);
updateMenus();
diff --git a/src/gui/doc/snippets/textdocument-printing/mainwindow.cpp b/src/gui/doc/snippets/textdocument-printing/mainwindow.cpp
index 40459b49da..a7bd90a9f1 100644
--- a/src/gui/doc/snippets/textdocument-printing/mainwindow.cpp
+++ b/src/gui/doc/snippets/textdocument-printing/mainwindow.cpp
@@ -74,7 +74,7 @@ MainWindow::MainWindow()
document = new QTextDocument(this);
editor->setDocument(document);
- connect(editor, SIGNAL(selectionChanged()), this, SLOT(updateMenus()));
+ connect(editor, &QTextEdit::selectionChanged, this, &MainWindow::updateMenus);
setCentralWidget(editor);
setWindowTitle(tr("Text Document Writer"));
diff --git a/src/gui/doc/snippets/textdocument-selections/mainwindow.cpp b/src/gui/doc/snippets/textdocument-selections/mainwindow.cpp
index 8ac3913f3c..9253e87670 100644
--- a/src/gui/doc/snippets/textdocument-selections/mainwindow.cpp
+++ b/src/gui/doc/snippets/textdocument-selections/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
@@ -90,7 +90,8 @@ MainWindow::MainWindow()
document = new QTextDocument(this);
editor->setDocument(document);
- connect(editor, SIGNAL(selectionChanged()), this, SLOT(updateMenus()));
+ connect(editor, &QTextEdit::selectionChanged,
+ this, &MainWindow::updateMenus);
setCentralWidget(editor);
setWindowTitle(tr("Text Document Writer"));
diff --git a/src/gui/doc/snippets/textdocument-tables/mainwindow.cpp b/src/gui/doc/snippets/textdocument-tables/mainwindow.cpp
index 061c191f1c..bd976a8ce4 100644
--- a/src/gui/doc/snippets/textdocument-tables/mainwindow.cpp
+++ b/src/gui/doc/snippets/textdocument-tables/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
#include "xmlwriter.h"
@@ -132,9 +132,9 @@ MainWindow::MainWindow()
}
//! [8]
- connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile()));
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
- connect(showTableAction, SIGNAL(triggered()), this, SLOT(showTable()));
+ connect(saveAction, &QAction:triggered, this, &MainWindow::saveFile);
+ connect(quitAction, &QAction:triggered, this, &MainWindow::close);
+ connect(showTableAction, &QAction:triggered, this, &MainWindow::showTable);
setCentralWidget(editor);
setWindowTitle(tr("Text Document Tables"));
diff --git a/src/gui/doc/src/richtext.qdoc b/src/gui/doc/src/richtext.qdoc
index a0f739d418..a8ba076e3d 100644
--- a/src/gui/doc/src/richtext.qdoc
+++ b/src/gui/doc/src/richtext.qdoc
@@ -1197,6 +1197,9 @@
\row \li \c text-transform
\li [ uppercase | lowercase ]
\li Select the transformation that will be performed on the text prior to displaying it.
+ \row \li \c font-kerning
+ \li [ normal | none ]
+ \li Enables or disables kerning between text characters.
\row \li \c font-variant
\li small-caps
\li Perform the smallcaps transformation on the text prior to displaying it.
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index 06c9cd3939..edf8124081 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -48,6 +48,7 @@ include(opengl/opengl.pri)
qtConfig(animation): include(animation/animation.pri)
include(itemmodels/itemmodels.pri)
include(vulkan/vulkan.pri)
+include(platform/platform.pri)
QMAKE_LIBS += $$QMAKE_LIBS_GUI
diff --git a/src/gui/image/qbitmap.cpp b/src/gui/image/qbitmap.cpp
index 2453242fa8..455045eb57 100644
--- a/src/gui/image/qbitmap.cpp
+++ b/src/gui/image/qbitmap.cpp
@@ -310,6 +310,7 @@ QBitmap QBitmap::transformed(const QTransform &matrix) const
return bm;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\overload
\obsolete
@@ -321,5 +322,6 @@ QBitmap QBitmap::transformed(const QMatrix &matrix) const
{
return transformed(QTransform(matrix));
}
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/image/qbitmap.h b/src/gui/image/qbitmap.h
index 188064fccf..f7895bb1e0 100644
--- a/src/gui/image/qbitmap.h
+++ b/src/gui/image/qbitmap.h
@@ -76,7 +76,10 @@ public:
static QBitmap fromData(const QSize &size, const uchar *bits,
QImage::Format monoFormat = QImage::Format_MonoLSB);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QBitmap::transformed(QTransform) instead")
QBitmap transformed(const QMatrix &) const;
+#endif
QBitmap transformed(const QTransform &matrix) const;
typedef QExplicitlySharedDataPointer<QPlatformPixmap> DataPtr;
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index 7257853c3e..7f8e072322 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -866,10 +866,12 @@ void QBmpHandler::setOption(ImageOption option, const QVariant &value)
Q_UNUSED(value);
}
+#if QT_DEPRECATED_SINCE(5, 13)
QByteArray QBmpHandler::name() const
{
return formatName();
}
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/image/qbmphandler_p.h b/src/gui/image/qbmphandler_p.h
index 56b39dd0f0..33b5b9c501 100644
--- a/src/gui/image/qbmphandler_p.h
+++ b/src/gui/image/qbmphandler_p.h
@@ -113,8 +113,9 @@ public:
bool read(QImage *image) override;
bool write(const QImage &image) override;
+#if QT_DEPRECATED_SINCE(5, 13)
QByteArray name() const override;
-
+#endif
static bool canRead(QIODevice *device);
QVariant option(ImageOption option) const override;
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index c362d0dc3f..c3c4b24678 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -315,9 +315,9 @@ QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::St
% HexString<uint>(actualSize.height());
if (mode == QIcon::Active) {
- if (QPixmapCache::find(key % HexString<uint>(mode), pm))
+ if (QPixmapCache::find(key % HexString<uint>(mode), &pm))
return pm; // horray
- if (QPixmapCache::find(key % HexString<uint>(QIcon::Normal), pm)) {
+ if (QPixmapCache::find(key % HexString<uint>(QIcon::Normal), &pm)) {
QPixmap active = pm;
if (QGuiApplication *guiApp = qobject_cast<QGuiApplication *>(qApp))
active = static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(guiApp))->applyQIconStyleHelper(QIcon::Active, pm);
@@ -326,7 +326,7 @@ QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::St
}
}
- if (!QPixmapCache::find(key % HexString<uint>(mode), pm)) {
+ if (!QPixmapCache::find(key % HexString<uint>(mode), &pm)) {
if (pm.size() != actualSize)
pm = pm.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
if (pe->mode != mode && mode != QIcon::Normal) {
@@ -1080,11 +1080,12 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State
if (!d) {
QFileInfo info(fileName);
- QIconEngine *engine = iconEngineFromSuffix(fileName, info.suffix());
+ QString suffix = info.suffix();
#if QT_CONFIG(mimetype)
- if (!engine)
- engine = iconEngineFromSuffix(fileName, QMimeDatabase().mimeTypeForFile(info).preferredSuffix());
+ if (suffix.isEmpty())
+ suffix = QMimeDatabase().mimeTypeForFile(info).preferredSuffix(); // determination from contents
#endif // mimetype
+ QIconEngine *engine = iconEngineFromSuffix(fileName, suffix);
d = new QIconPrivate(engine ? engine : new QPixmapIconEngine);
}
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index 6a4fc8927a..8870950982 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
class QIconPrivate;
class QIconEngine;
+class QPainter;
class Q_GUI_EXPORT QIcon
{
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index ed6f23ee56..f3857259ed 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -117,7 +117,7 @@ QImageData::QImageData()
*/
QImageData * QImageData::create(const QSize &size, QImage::Format format)
{
- if (!size.isValid() || format == QImage::Format_Invalid)
+ if (size.isEmpty() || format == QImage::Format_Invalid)
return nullptr; // invalid parameter(s)
int width = size.width();
@@ -288,6 +288,7 @@ bool QImageData::checkForAlphaPixels() const
case QImage::Format_BGR30:
case QImage::Format_RGB30:
case QImage::Format_Grayscale8:
+ case QImage::Format_Grayscale16:
case QImage::Format_RGBX64:
break;
case QImage::Format_Invalid:
@@ -710,6 +711,7 @@ bool QImageData::checkForAlphaPixels() const
\value Format_A2RGB30_Premultiplied The image is stored using a 32-bit premultiplied ARGB format (2-10-10-10). (added in Qt 5.4)
\value Format_Alpha8 The image is stored using an 8-bit alpha only format. (added in Qt 5.5)
\value Format_Grayscale8 The image is stored using an 8-bit grayscale format. (added in Qt 5.5)
+ \value Format_Grayscale16 The image is stored using an 16-bit grayscale format. (added in Qt 5.13)
\value Format_RGBX64 The image is stored using a 64-bit halfword-ordered RGB(x) format (16-16-16-16).
This is the same as the Format_RGBX64 except alpha must always be 65535. (added in Qt 5.12)
\value Format_RGBA64 The image is stored using a 64-bit halfword-ordered RGBA format (16-16-16-16). (added in Qt 5.12)
@@ -1464,6 +1466,7 @@ void QImage::setDevicePixelRatio(qreal scaleFactor)
d->devicePixelRatio = scaleFactor;
}
+#if QT_DEPRECATED_SINCE(5, 10)
/*!
\since 4.6
\obsolete
@@ -1480,6 +1483,7 @@ int QImage::byteCount() const
Q_ASSERT(!d || d->nbytes < std::numeric_limits<int>::max());
return d ? int(d->nbytes) : 0;
}
+#endif
/*!
\since 5.10
@@ -2061,6 +2065,7 @@ static bool highColorPrecision(QImage::Format format)
case QImage::Format_RGBX64:
case QImage::Format_RGBA64:
case QImage::Format_RGBA64_Premultiplied:
+ case QImage::Format_Grayscale16:
return true;
default:
break;
@@ -2082,13 +2087,7 @@ QImage QImage::convertToFormat_helper(Format format, Qt::ImageConversionFlags fl
Image_Converter converter = qimage_converter_map[d->format][format];
if (!converter && format > QImage::Format_Indexed8 && d->format > QImage::Format_Indexed8) {
if (highColorPrecision(format) && highColorPrecision(d->format)) {
- // Convert over RGBA64_Premultiplied
- if (format == QImage::Format_RGBA64_Premultiplied)
- converter = convert_generic_to_rgb64;
- else {
- Q_ASSERT(d->format != QImage::Format_RGBA64_Premultiplied);
- return convertToFormat(Format_RGBA64_Premultiplied, flags).convertToFormat(format, flags);
- }
+ converter = convert_generic_to_rgb64;
} else
converter = convert_generic;
}
@@ -2269,6 +2268,29 @@ bool QImage::reinterpretAsFormat(Format format)
}
/*!
+ \since 5.13
+
+ Detach and convert the image to the given \a format in place.
+
+ The specified image conversion \a flags control how the image data
+ is handled during the conversion process.
+
+ \sa convertToFormat()
+*/
+
+void QImage::convertTo(Format format, Qt::ImageConversionFlags flags)
+{
+ if (!d || format == QImage::Format_Invalid)
+ return;
+
+ detach();
+ if (convertToFormat_inplace(format, flags))
+ return;
+
+ *this = convertToFormat_helper(format, flags);
+}
+
+/*!
\fn bool QImage::valid(const QPoint &pos) const
Returns \c true if \a pos is a valid coordinate pair within the
@@ -2554,6 +2576,10 @@ QColor QImage::pixelColor(int x, int y) const
case Format_RGBA64_Premultiplied:
c = reinterpret_cast<const QRgba64 *>(s)[x];
break;
+ case Format_Grayscale16: {
+ quint16 v = reinterpret_cast<const quint16 *>(s)[x];
+ return QColor(qRgba64(v, v, v, 0xffff));
+ }
default:
c = QRgba64::fromArgb32(pixel(x, y));
break;
@@ -2664,6 +2690,7 @@ bool QImage::allGray() const
case Format_Alpha8:
return false;
case Format_Grayscale8:
+ case Format_Grayscale16:
return true;
case Format_RGB32:
case Format_ARGB32:
@@ -2730,7 +2757,7 @@ bool QImage::isGrayscale() const
if (d->format == QImage::Format_Alpha8)
return false;
- if (d->format == QImage::Format_Grayscale8)
+ if (d->format == QImage::Format_Grayscale8 || d->format == QImage::Format_Grayscale16)
return true;
switch (depth()) {
@@ -3369,6 +3396,7 @@ QImage QImage::rgbSwapped_helper() const
break;
case Format_Alpha8:
case Format_Grayscale8:
+ case Format_Grayscale16:
return *this;
case Format_Mono:
case Format_MonoLSB:
@@ -3480,6 +3508,7 @@ void QImage::rgbSwapped_inplace()
break;
case Format_Alpha8:
case Format_Grayscale8:
+ case Format_Grayscale16:
return;
case Format_Mono:
case Format_MonoLSB:
@@ -5374,6 +5403,19 @@ static Q_CONSTEXPR QPixelFormat pixelformats[] = {
/*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
/*INTERPRETATION*/ QPixelFormat::UnsignedShort,
/*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
+ //QImage::Format_Grayscale16:
+ QPixelFormat(QPixelFormat::Grayscale,
+ /*GRAY*/ 16,
+ /*SECOND*/ 0,
+ /*THIRD*/ 0,
+ /*FOURTH*/ 0,
+ /*FIFTH*/ 0,
+ /*ALPHA*/ 0,
+ /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
+ /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
+ /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
+ /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
+ /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
};
Q_STATIC_ASSERT(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats);
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 6505fd5845..8335e117f2 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -128,10 +128,7 @@ public:
Format_RGBX64,
Format_RGBA64,
Format_RGBA64_Premultiplied,
-#if 0
- // reserved for future use
Format_Grayscale16,
-#endif
#ifndef Q_QDOC
NImageFormats
#endif
@@ -199,6 +196,8 @@ public:
Q_REQUIRED_RESULT QImage convertToFormat(Format f, const QVector<QRgb> &colorTable, Qt::ImageConversionFlags flags = Qt::AutoColor) const;
bool reinterpretAsFormat(Format f);
+ void convertTo(Format f, Qt::ImageConversionFlags flags = Qt::AutoColor);
+
int width() const;
int height() const;
QSize size() const;
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 215dd33499..82ffb8af8b 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -223,18 +223,29 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
void convert_generic_to_rgb64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
- Q_ASSERT(dest->format == QImage::Format_RGBA64_Premultiplied);
+ Q_ASSERT(dest->format > QImage::Format_Indexed8);
Q_ASSERT(src->format > QImage::Format_Indexed8);
+ QRgba64 buf[BufferSize];
+ QRgba64 *buffer = buf;
const QPixelLayout *srcLayout = &qPixelLayouts[src->format];
+ const QPixelLayout *destLayout = &qPixelLayouts[dest->format];
const uchar *srcData = src->data;
uchar *destData = dest->data;
const FetchAndConvertPixelsFunc64 fetch = srcLayout->fetchToRGBA64PM;
+ const ConvertAndStorePixelsFunc64 store = qStoreFromRGBA64PM[dest->format];
for (int y = 0; y < src->height; ++y) {
- const QRgba64 *ptr = fetch((QRgba64*)destData, srcData, 0, src->width, nullptr, nullptr);
- if (ptr != (const QRgba64*)destData) {
- memcpy(destData, ptr, dest->bytes_per_line);
+ int x = 0;
+ while (x < src->width) {
+ int l = src->width - x;
+ if (destLayout->bpp == QPixelLayout::BPP64)
+ buffer = reinterpret_cast<QRgba64 *>(destData) + x;
+ else
+ l = qMin(l, BufferSize);
+ const QRgba64 *ptr = fetch(buffer, srcData, x, l, nullptr, nullptr);
+ store(destData, ptr, x, l, nullptr, nullptr);
+ x += l;
}
srcData += src->bytes_per_line;
destData += dest->bytes_per_line;
@@ -1205,33 +1216,6 @@ static void convert_RGBA64_to_ARGB32(QImageData *dest, const QImageData *src, Qt
}
template<bool RGBA>
-static void convert_RGBA64PM_to_ARGB32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied);
- Q_ASSERT(RGBA || dest->format == QImage::Format_ARGB32);
- Q_ASSERT(!RGBA || 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 >> 3) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data);
- uint *dest_data = reinterpret_cast<uint *>(dest->data);
-
- for (int i = 0; i < src->height; ++i) {
- const QRgba64 *end = src_data + src->width;
- while (src_data < end) {
- QRgba64 s = src_data->unpremultiplied();
- *dest_data = RGBA ? ARGB2RGBA(s.toArgb32()) : s.toArgb32();
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-template<bool RGBA>
static void convert_ARGB32_to_RGBA64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
Q_ASSERT(RGBA || src->format == QImage::Format_ARGB32);
@@ -1240,74 +1224,14 @@ static void convert_ARGB32_to_RGBA64(QImageData *dest, const QImageData *src, Qt
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 >> 3) - dest->width;
- const uint *src_data = reinterpret_cast<const uint *>(src->data);
- QRgba64 *dest_data = reinterpret_cast<QRgba64 *>(dest->data);
-
- for (int i = 0; i < src->height; ++i) {
- const uint *end = src_data + src->width;
- while (src_data < end) {
- if (RGBA)
- *dest_data = QRgba64::fromArgb32(RGBA2ARGB(*src_data));
- else
- *dest_data = QRgba64::fromArgb32(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-template<QtPixelOrder PixelOrder>
-static void convert_RGBA64PM_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_BGR30);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 3) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data);
- uint *dest_data = reinterpret_cast<uint *>(dest->data);
-
- for (int i = 0; i < src->height; ++i) {
- const QRgba64 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = 0xc0000000 | qConvertRgb64ToRgb30<PixelOrder>(src_data->unpremultiplied());
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-template<QtPixelOrder PixelOrder>
-static void convert_RGBA64PM_to_A2RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_A2RGB30_Premultiplied
- || dest->format == QImage::Format_A2BGR30_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 3) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data);
- uint *dest_data = reinterpret_cast<uint *>(dest->data);
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+ const FetchAndConvertPixelsFunc64 fetch = qPixelLayouts[src->format + 1].fetchToRGBA64PM;
for (int i = 0; i < src->height; ++i) {
- const QRgba64 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = qConvertRgb64ToRgb30<PixelOrder>(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
+ fetch(reinterpret_cast<QRgba64 *>(dest_data), src_data, 0, src->width, nullptr, nullptr);
+ src_data += src->bytes_per_line;;
+ dest_data += dest->bytes_per_line;
}
}
@@ -1447,6 +1371,56 @@ static bool convert_RGBA64PM_to_RGBA64_inplace(QImageData *data, Qt::ImageConver
return true;
}
+static void convert_gray16_to_RGBA64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Grayscale16);
+ Q_ASSERT(dest->format == QImage::Format_RGBA64 || dest->format == QImage::Format_RGBX64 ||
+ dest->format == QImage::Format_RGBA64_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const qsizetype sbpl = src->bytes_per_line;
+ const qsizetype dbpl = dest->bytes_per_line;
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint16 *src_line = reinterpret_cast<const quint16 *>(src_data);
+ QRgba64 *dest_line = reinterpret_cast<QRgba64 *>(dest_data);
+ for (int j = 0; j < src->width; ++j) {
+ quint16 s = src_line[j];
+ dest_line[j] = qRgba64(s, s, s, 0xFFFF);
+ }
+ src_data += sbpl;
+ dest_data += dbpl;
+ }
+}
+
+static void convert_RGBA64_to_gray16(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(dest->format == QImage::Format_Grayscale16);
+ Q_ASSERT(src->format == QImage::Format_RGBX64 ||
+ src->format == QImage::Format_RGBA64_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const qsizetype sbpl = src->bytes_per_line;
+ const qsizetype dbpl = dest->bytes_per_line;
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgba64 *src_line = reinterpret_cast<const QRgba64 *>(src_data);
+ quint16 *dest_line = reinterpret_cast<quint16 *>(dest_data);
+ for (int j = 0; j < src->width; ++j) {
+ QRgba64 s = src_line[j].unpremultiplied();
+ dest_line[j] = qGray(s.red(), s.green(), s.blue());
+ }
+ src_data += sbpl;
+ dest_data += dbpl;
+ }
+}
+
static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
{
QVector<QRgb> colorTable = ctbl;
@@ -2291,7 +2265,7 @@ static bool convert_Grayscale8_to_Indexed8_inplace(QImageData *data, Qt::ImageCo
Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
{
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
},
{
0,
@@ -2312,7 +2286,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Mono
{
@@ -2334,7 +2308,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_MonoLSB
{
@@ -2359,7 +2333,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0, 0, 0, 0, 0,
convert_Indexed8_to_Alpha8,
convert_Indexed8_to_Grayscale8,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_Indexed8
{
@@ -2387,7 +2361,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGB_to_RGB30<PixelOrderRGB, false>,
0,
0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_RGB32
{
@@ -2417,7 +2391,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0, 0,
0,
convert_ARGB32_to_RGBA64<false>,
- 0
+ 0, 0
}, // Format_ARGB32
{
@@ -2442,7 +2416,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_ARGB_to_RGBA,
0, 0, 0, 0,
0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_ARGB32_Premultiplied
{
@@ -2464,7 +2438,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB16
{
@@ -2486,7 +2460,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8565_Premultiplied
{
@@ -2508,7 +2482,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB666
{
@@ -2530,7 +2504,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB6666_Premultiplied
{
@@ -2552,7 +2526,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB555
{
@@ -2574,7 +2548,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8555_Premultiplied
{
@@ -2597,7 +2571,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGB888_to_RGB<true>,
convert_RGB888_to_RGB<true>,
convert_RGB888_to_RGB<true>,
- 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB888
{
@@ -2619,7 +2593,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB444
{
@@ -2640,7 +2614,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB4444_Premultiplied
{
0,
@@ -2667,7 +2641,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGB_to_RGB30<PixelOrderRGB, true>,
0,
0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_RGBX8888
{
0,
@@ -2696,7 +2670,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0, 0,
0,
convert_ARGB32_to_RGBA64<true>,
- 0
+ 0, 0
}, // Format_RGBA8888
{
@@ -2718,7 +2692,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGBA8888_Premultiplied
{
@@ -2746,7 +2720,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_BGR30_to_RGB30,
convert_BGR30_to_RGB30,
0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_BGR30
{
0,
@@ -2773,8 +2747,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_A2RGB30_PM_to_RGB30<true>,
convert_BGR30_to_RGB30,
0, 0,
- 0, 0, 0
- }, // Format_BGR30A2_Premultiplied
+ 0, 0, 0, 0
+ }, // Format_A2BGR30_Premultiplied
{
0,
0,
@@ -2799,7 +2773,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_BGR30_to_RGB30,
0,
convert_passthrough,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0
}, // Format_RGB30
{
0,
@@ -2826,8 +2800,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_A2RGB30_PM_to_RGB30<false>,
0,
0, 0,
- 0, 0, 0
- }, // Format_RGB30A2_Premultiplied
+ 0, 0, 0, 0
+ }, // Format_A2RGB30_Premultiplied
{
0,
0,
@@ -2846,7 +2820,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Alpha8
{
0,
@@ -2872,7 +2846,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, // self
convert_passthrough,
- convert_passthrough
+ convert_passthrough,
+ convert_RGBA64_to_gray16
}, // Format_RGBX64
{
0,
@@ -2898,7 +2873,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0, 0,
convert_RGBA64_to_RGBx64,
0, // self
- convert_RGBA64_to_RGBA64PM
+ convert_RGBA64_to_RGBA64PM,
+ 0
}, // Format_RGBA64
{
0,
@@ -2906,7 +2882,6 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_RGBA64PM_to_ARGB32<false>,
0,
0,
0,
@@ -2918,29 +2893,58 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_RGBA64PM_to_ARGB32<true>,
0,
- convert_RGBA64PM_to_RGB30<PixelOrderBGR>,
- convert_RGBA64PM_to_A2RGB30<PixelOrderBGR>,
- convert_RGBA64PM_to_RGB30<PixelOrderRGB>,
- convert_RGBA64PM_to_A2RGB30<PixelOrderRGB>,
+ 0,
+ 0,
+ 0, 0, 0, 0,
0, 0,
convert_RGBA64PM_to_RGBA64<true>,
convert_RGBA64PM_to_RGBA64<false>,
- 0 // self
- } // Format_RGBA64_Premultiplied
+ 0, // self
+ convert_RGBA64_to_gray16
+ }, // Format_RGBA64_Premultiplied
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, 0,
+ convert_gray16_to_RGBA64,
+ convert_gray16_to_RGBA64,
+ convert_gray16_to_RGBA64,
+ 0 // self
+ }, // Format_Grayscale16
};
InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
{
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
},
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Mono
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_MonoLSB
{
0,
@@ -2964,7 +2968,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0, 0, 0, 0, 0,
convert_Indexed8_to_Alpha8_inplace,
convert_Indexed8_to_Grayscale8_inplace,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_Indexed8
{
0,
@@ -2991,7 +2995,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_RGB_to_RGB30_inplace<PixelOrderRGB, false>,
0,
0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_RGB32
{
0,
@@ -3018,7 +3022,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_RGB_to_RGB30_inplace<PixelOrderRGB, false>,
0,
0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_ARGB32
{
0,
@@ -3042,34 +3046,34 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_ARGB_to_RGBA_inplace<QImage::Format_RGBA8888_Premultiplied>,
0, 0, 0, 0,
0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_ARGB32_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB16
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8565_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB666
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB6666_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB555
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8555_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB888
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB444
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB4444_Premultiplied
{
0,
@@ -3096,7 +3100,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_RGB_to_RGB30_inplace<PixelOrderRGB, true>,
0,
0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_RGBX8888
{
0,
@@ -3123,7 +3127,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_RGB_to_RGB30_inplace<PixelOrderRGB, true>,
0,
0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_RGBA8888
{
0,
@@ -3145,7 +3149,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGBA8888_Premultiplied
{
0,
@@ -3172,7 +3176,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_BGR30_to_RGB30_inplace,
convert_BGR30_to_A2RGB30_inplace,
0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_BGR30
{
0,
@@ -3198,8 +3202,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0, // self
convert_A2RGB30_PM_to_RGB30_inplace<true>,
convert_BGR30_to_RGB30_inplace,
- 0, 0, 0, 0, 0
- }, // Format_BGR30A2_Premultiplied
+ 0, 0, 0, 0, 0, 0
+ }, // Format_A2BGR30_Premultiplied
{
0,
0,
@@ -3224,7 +3228,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_BGR30_to_A2RGB30_inplace,
0, // self
convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied>,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0
}, // Format_RGB30
{
0,
@@ -3251,8 +3255,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_A2RGB30_PM_to_RGB30_inplace<false>,
0, // self
0, 0,
- 0, 0, 0
- }, // Format_RGB30A2_Premultiplied
+ 0, 0, 0, 0
+ }, // Format_A2RGB30_Premultiplied
{
0,
0,
@@ -3276,7 +3280,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0, 0, 0, 0,
0, // self
0,
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_Alpha8
{
0,
@@ -3301,26 +3305,32 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0, 0, 0, 0,
0,
0, // self
- 0, 0, 0
+ 0, 0, 0, 0
}, // Format_Grayscale8
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, // self
convert_passthrough_inplace<QImage::Format_RGBA64>,
convert_passthrough_inplace<QImage::Format_RGBA64_Premultiplied>,
+ 0
}, // Format_RGBX64
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
convert_RGBA64_to_RGBx64_inplace,
0, // self
- convert_RGBA64_to_RGBA64PM_inplace
+ convert_RGBA64_to_RGBA64PM_inplace,
+ 0
}, // Format_RGBA64
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
convert_RGBA64PM_to_RGBA64_inplace<true>,
convert_RGBA64PM_to_RGBA64_inplace<false>,
- 0 // self
- } // Format_RGBA64_Premultiplied
+ 0, // self
+ 0
+ }, // Format_RGBA64_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_Grayscale16
};
static void qInitImageConversions()
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index a0a3b5406e..d88ad2d1d2 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -195,6 +195,7 @@ inline int qt_depthForFormat(QImage::Format format)
case QImage::Format_RGB16:
case QImage::Format_RGB444:
case QImage::Format_ARGB4444_Premultiplied:
+ case QImage::Format_Grayscale16:
depth = 16;
break;
case QImage::Format_RGB666:
diff --git a/src/gui/image/qimageiohandler.cpp b/src/gui/image/qimageiohandler.cpp
index 5d1f8fa91f..0e7b541cf2 100644
--- a/src/gui/image/qimageiohandler.cpp
+++ b/src/gui/image/qimageiohandler.cpp
@@ -340,7 +340,7 @@ void QImageIOHandler::setDevice(QIODevice *device)
/*!
Returns the device currently assigned to the QImageIOHandler. If
- not device has been assigned, 0 is returned.
+ not device has been assigned, \nullptr is returned.
*/
QIODevice *QImageIOHandler::device() const
{
@@ -416,6 +416,7 @@ QByteArray QImageIOHandler::format() const
\sa read(), QIODevice::peek()
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -426,6 +427,7 @@ QByteArray QImageIOHandler::name() const
{
return format();
}
+#endif
/*!
Writes the image \a image to the assigned device. Returns \c true on
diff --git a/src/gui/image/qimageiohandler.h b/src/gui/image/qimageiohandler.h
index 35984dd6a5..c20b84afbb 100644
--- a/src/gui/image/qimageiohandler.h
+++ b/src/gui/image/qimageiohandler.h
@@ -69,7 +69,10 @@ public:
void setFormat(const QByteArray &format) const;
QByteArray format() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QImageIOHandler::format() instead")
virtual QByteArray name() const;
+#endif
virtual bool canRead() const = 0;
virtual bool read(QImage *image) = 0;
@@ -141,7 +144,7 @@ class Q_GUI_EXPORT QImageIOPlugin : public QObject
Q_OBJECT
public:
explicit QImageIOPlugin(QObject *parent = nullptr);
- virtual ~QImageIOPlugin();
+ ~QImageIOPlugin();
enum Capability {
CanRead = 0x1,
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 0fb1d808e5..61f20e0c65 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -526,7 +526,7 @@ bool QImageReaderPrivate::initHandler()
// Try the most probable extension first
int currentFormatIndex = extensions.indexOf(format.toLower());
if (currentFormatIndex > 0)
- extensions.swap(0, currentFormatIndex);
+ extensions.swapItemsAt(0, currentFormatIndex);
}
int currentExtension = 0;
@@ -756,13 +756,13 @@ void QImageReader::setDevice(QIODevice *device)
d->device = device;
d->deleteDevice = false;
delete d->handler;
- d->handler = 0;
+ d->handler = nullptr;
d->text.clear();
}
/*!
- Returns the device currently assigned to QImageReader, or 0 if no
- device has been assigned.
+ Returns the device currently assigned to QImageReader, or \nullptr
+ if no device has been assigned.
*/
QIODevice *QImageReader::device() const
{
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index d3f9a9b881..ec66588ddf 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -407,8 +407,8 @@ void QImageWriter::setDevice(QIODevice *device)
}
/*!
- Returns the device currently assigned to QImageWriter, or 0 if no
- device has been assigned.
+ Returns the device currently assigned to QImageWriter, or \nullptr
+ if no device has been assigned.
*/
QIODevice *QImageWriter::device() const
{
@@ -648,6 +648,7 @@ QImageIOHandler::Transformations QImageWriter::transformation() const
return d->transformation;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -679,6 +680,7 @@ QString QImageWriter::description() const
{
return d->description;
}
+#endif
/*!
\since 4.1
diff --git a/src/gui/image/qimagewriter.h b/src/gui/image/qimagewriter.h
index 29c06ccdd2..ef84a59b7c 100644
--- a/src/gui/image/qimagewriter.h
+++ b/src/gui/image/qimagewriter.h
@@ -100,9 +100,12 @@ public:
QImageIOHandler::Transformations transformation() const;
void setTransformation(QImageIOHandler::Transformations orientation);
- // Obsolete as of 4.1
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QImageWriter::setText() instead")
void setDescription(const QString &description);
+ QT_DEPRECATED_X("Use QImageReader::text() instead")
QString description() const;
+#endif
void setText(const QString &key, const QString &text);
diff --git a/src/gui/image/qmovie.cpp b/src/gui/image/qmovie.cpp
index 7d17b7d5ef..79203c7b98 100644
--- a/src/gui/image/qmovie.cpp
+++ b/src/gui/image/qmovie.cpp
@@ -659,7 +659,7 @@ void QMovie::setDevice(QIODevice *device)
/*!
Returns the device QMovie reads image data from. If no device has
- currently been assigned, 0 is returned.
+ currently been assigned, \nullptr is returned.
\sa setDevice(), fileName()
*/
diff --git a/src/gui/image/qpaintengine_pic_p.h b/src/gui/image/qpaintengine_pic_p.h
index c3044796ad..c9e4b43197 100644
--- a/src/gui/image/qpaintengine_pic_p.h
+++ b/src/gui/image/qpaintengine_pic_p.h
@@ -103,7 +103,7 @@ protected:
QPicturePaintEngine(QPaintEnginePrivate &dptr);
private:
- Q_DISABLE_COPY(QPicturePaintEngine)
+ Q_DISABLE_COPY_MOVE(QPicturePaintEngine)
void writeCmdLength(int pos, const QRectF &r, bool corr);
};
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index 2f2f85f68d..56b82abcfa 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -858,7 +858,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords)
break;
case QPicturePrivate::PdcSetWXform:
s >> i_8;
- painter->setMatrixEnabled(i_8);
+ painter->setWorldMatrixEnabled(i_8);
break;
case QPicturePrivate::PdcSetWMatrix:
if (d->formatMajor >= 8) {
@@ -1200,8 +1200,8 @@ QT_END_INCLUDE_NAMESPACE
\obsolete
Returns a string that specifies the picture format of the file \a
- fileName, or 0 if the file cannot be read or if the format is not
- recognized.
+ fileName, or \nullptr if the file cannot be read or if the format
+ is not recognized.
\sa load(), save()
*/
@@ -1543,7 +1543,7 @@ const QPicture &QPictureIO::picture() const { return d->pi; }
int QPictureIO::status() const { return d->iostat; }
/*!
- Returns the picture format string or 0 if no format has been
+ Returns the picture format string or \nullptr if no format has been
explicitly set.
*/
const char *QPictureIO::format() const { return d->frmt; }
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 7e862e9826..5b4d218603 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -858,6 +858,7 @@ bool QPixmap::doImageIO(QImageWriter *writer, int quality) const
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -878,6 +879,14 @@ void QPixmap::fill(const QPaintDevice *device, const QPoint &p)
Use QPainter or the fill(QColor) overload instead.
*/
+void QPixmap::fill(const QPaintDevice *device, int xofs, int yofs)
+{
+ Q_UNUSED(device)
+ Q_UNUSED(xofs)
+ Q_UNUSED(yofs)
+ qWarning("this function is deprecated, ignored");
+}
+#endif
/*!
@@ -961,6 +970,7 @@ static void sendResizeEvents(QWidget *target)
}
#endif
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -984,6 +994,14 @@ QPixmap QPixmap::grabWidget(QObject *widget, const QRect &rectangle)
Use QWidget::grab() instead.
*/
+QPixmap QPixmap::grabWidget(QObject *widget, int x, int y, int w, int h)
+{
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ return grabWidget(widget, QRect(x, y, w, h));
+QT_WARNING_POP
+}
+#endif
/*****************************************************************************
QPixmap stream functions
@@ -1358,12 +1376,6 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
The cacheKey() function returns a number that uniquely
identifies the contents of the QPixmap object.
- The x11Info() function returns information about the configuration
- of the X display used by the screen to which the pixmap currently
- belongs. The x11PictureHandle() function returns the X11 Picture
- handle of the pixmap for XRender support. Note that the two latter
- functions are only available on x11.
-
\endtable
\section1 Pixmap Conversion
@@ -1394,9 +1406,6 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
function returns the actual matrix used for transforming the
pixmap.
- \note When using the native X11 graphics system, the pixmap
- becomes invalid when the QApplication instance is destroyed.
-
\sa QBitmap, QImage, QImageReader, QImageWriter
*/
@@ -1604,6 +1613,7 @@ QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionF
return QPixmap(data.take());
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn QPixmap QPixmap::grabWindow(WId window, int x, int y, int
width, int height)
@@ -1657,6 +1667,7 @@ QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
" Defaulting to primary screen.");
return QGuiApplication::primaryScreen()->grabWindow(window, x, y, w, h);
}
+#endif
/*!
\internal
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index 55cca7a766..13c81f18d0 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -94,8 +94,12 @@ public:
static int defaultDepth();
void fill(const QColor &fillColor = Qt::white);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QPainter or fill(QColor)")
void fill(const QPaintDevice *device, const QPoint &ofs);
- inline void fill(const QPaintDevice *device, int xofs, int yofs) { fill(device, QPoint(xofs, yofs)); }
+ QT_DEPRECATED_X("Use QPainter or fill(QColor)")
+ void fill(const QPaintDevice *device, int xofs, int yofs);
+#endif
QBitmap mask() const;
void setMask(const QBitmap &);
@@ -111,10 +115,14 @@ public:
#endif
QBitmap createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode = Qt::MaskInColor) const;
- static QPixmap grabWindow(WId, int x=0, int y=0, int w=-1, int h=-1);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QScreen::grabWindow() instead")
+ static QPixmap grabWindow(WId, int x = 0, int y = 0, int w = -1, int h = -1);
+ QT_DEPRECATED_X("Use QWidget::grab() instead")
static QPixmap grabWidget(QObject *widget, const QRect &rect);
- static inline QPixmap grabWidget(QObject *widget, int x=0, int y=0, int w=-1, int h=-1)
- { return grabWidget(widget, QRect(x, y, w, h)); }
+ QT_DEPRECATED_X("Use QWidget::grab() instead")
+ static QPixmap grabWidget(QObject *widget, int x = 0, int y = 0, int w = -1, int h = -1);
+#endif
inline QPixmap scaled(int w, int h, Qt::AspectRatioMode aspectMode = Qt::IgnoreAspectRatio,
Qt::TransformationMode mode = Qt::FastTransformation) const
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 13c1c29d5b..2732bbd197 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -203,6 +203,9 @@ void QRasterPlatformPixmap::fill(const QColor &color)
pixel = qAlpha(color.rgba());
} else if (image.format() == QImage::Format_Grayscale8) {
pixel = qGray(color.rgba());
+ } else if (image.format() == QImage::Format_Grayscale16) {
+ QRgba64 c = color.rgba64();
+ pixel = qGray(c.red(), c.green(), c.blue());
} else
{
pixel = 0;
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
index b5f8d43041..3a2db74098 100644
--- a/src/gui/image/qpixmap_win.cpp
+++ b/src/gui/image/qpixmap_win.cpp
@@ -210,7 +210,7 @@ static QImage copyImageData(const BITMAPINFOHEADER &header, const RGBQUAD *color
class DisplayHdc
{
- Q_DISABLE_COPY(DisplayHdc)
+ Q_DISABLE_COPY_MOVE(DisplayHdc)
public:
DisplayHdc() : m_displayDc(GetDC(nullptr)) {}
~DisplayHdc() { ReleaseDC(nullptr, m_displayDc); }
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index 3d1652f68b..66907bebd7 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -469,10 +469,13 @@ QPixmapCacheEntry::~QPixmapCacheEntry()
pm_cache()->releaseKey(key);
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
\overload
+ Use bool find(const QString &, QPixmap *) instead.
+
Returns the pixmap associated with the \a key in the cache, or
null if there is no such pixmap.
@@ -494,13 +497,14 @@ QPixmap *QPixmapCache::find(const QString &key)
/*!
\obsolete
- Use bool find(const QString&, QPixmap*) instead.
+ Use bool find(const QString &, QPixmap *) instead.
*/
-bool QPixmapCache::find(const QString &key, QPixmap& pixmap)
+bool QPixmapCache::find(const QString &key, QPixmap &pixmap)
{
return find(key, &pixmap);
}
+#endif
/*!
Looks for a cached pixmap associated with the given \a key in the cache.
@@ -513,7 +517,7 @@ bool QPixmapCache::find(const QString &key, QPixmap& pixmap)
\snippet code/src_gui_image_qpixmapcache.cpp 1
*/
-bool QPixmapCache::find(const QString &key, QPixmap* pixmap)
+bool QPixmapCache::find(const QString &key, QPixmap *pixmap)
{
QPixmap *ptr = pm_cache()->object(key);
if (ptr && pixmap)
@@ -530,7 +534,7 @@ bool QPixmapCache::find(const QString &key, QPixmap* pixmap)
\since 4.6
*/
-bool QPixmapCache::find(const Key &key, QPixmap* pixmap)
+bool QPixmapCache::find(const Key &key, QPixmap *pixmap)
{
//The key is not valid anymore, a flush happened before probably
if (!key.d || !key.d->isValid)
diff --git a/src/gui/image/qpixmapcache.h b/src/gui/image/qpixmapcache.h
index ea10ab1b76..12d05b00f3 100644
--- a/src/gui/image/qpixmapcache.h
+++ b/src/gui/image/qpixmapcache.h
@@ -76,8 +76,12 @@ public:
static int cacheLimit();
static void setCacheLimit(int);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use bool find(const QString &, QPixmap *) instead")
static QPixmap *find(const QString &key);
+ QT_DEPRECATED_X("Use bool find(const QString &, QPixmap *) instead")
static bool find(const QString &key, QPixmap &pixmap);
+#endif
static bool find(const QString &key, QPixmap *pixmap);
static bool find(const Key &key, QPixmap *pixmap);
static bool insert(const QString &key, const QPixmap &pixmap);
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 808037f434..140196004b 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -266,6 +266,18 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
else if (g == 1)
image.setColor(0, qRgba(255, 255, 255, 0));
}
+ } else if (bit_depth == 16
+ && png_get_channels(png_ptr, info_ptr) == 1
+ && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ if (image.size() != QSize(width, height) || image.format() != QImage::Format_Grayscale16) {
+ image = QImage(width, height, QImage::Format_Grayscale16);
+ if (image.isNull())
+ return;
+ }
+
+ png_read_update_info(png_ptr, info_ptr);
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
+ png_set_swap(png_ptr);
} else if (bit_depth == 16) {
bool hasMask = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
if (!hasMask)
@@ -687,7 +699,7 @@ QImage::Format QPngHandlerPrivate::readImageFormat()
if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) {
format = QImage::Format_Mono;
} else if (bit_depth == 16) {
- format = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ? QImage::Format_RGBA64 : QImage::Format_RGBX64;
+ format = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ? QImage::Format_RGBA64 : QImage::Format_Grayscale16;
} else if (bit_depth == 8 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
format = QImage::Format_Grayscale8;
} else {
@@ -861,7 +873,8 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i
else
color_type = PNG_COLOR_TYPE_PALETTE;
}
- else if (image.format() == QImage::Format_Grayscale8)
+ else if (image.format() == QImage::Format_Grayscale8
+ || image.format() == QImage::Format_Grayscale16)
color_type = PNG_COLOR_TYPE_GRAY;
else if (image.hasAlphaChannel())
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
@@ -877,6 +890,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i
case QImage::Format_RGBX64:
case QImage::Format_RGBA64:
case QImage::Format_RGBA64_Premultiplied:
+ case QImage::Format_Grayscale16:
bpc = 16;
break;
default:
@@ -988,6 +1002,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i
case QImage::Format_RGBX64:
case QImage::Format_RGBA64:
case QImage::Format_RGBA64_Premultiplied:
+ case QImage::Format_Grayscale16:
png_set_swap(png_ptr);
break;
default:
@@ -1018,6 +1033,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i
case QImage::Format_MonoLSB:
case QImage::Format_Indexed8:
case QImage::Format_Grayscale8:
+ case QImage::Format_Grayscale16:
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_RGB888:
@@ -1181,10 +1197,12 @@ void QPngHandler::setOption(ImageOption option, const QVariant &value)
d->scaledSize = value.toSize();
}
+#if QT_DEPRECATED_SINCE(5, 13)
QByteArray QPngHandler::name() const
{
return "png";
}
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/image/qpnghandler_p.h b/src/gui/image/qpnghandler_p.h
index 4ca716e7c2..5d4da97395 100644
--- a/src/gui/image/qpnghandler_p.h
+++ b/src/gui/image/qpnghandler_p.h
@@ -69,7 +69,9 @@ public:
bool read(QImage *image) override;
bool write(const QImage &image) override;
+#if QT_DEPRECATED_SINCE(5, 13)
QByteArray name() const override;
+#endif
QVariant option(ImageOption option) const override;
void setOption(ImageOption option, const QVariant &value) override;
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index 53e3fa293d..13ee2eadd2 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -68,13 +68,19 @@ static int read_pbm_int(QIODevice *d)
char c;
int val = -1;
bool digit;
+ bool hasOverflow = false;
for (;;) {
if (!d->getChar(&c)) // end of file
break;
digit = isdigit((uchar) c);
if (val != -1) {
if (digit) {
- val = 10*val + c - '0';
+ const int cValue = c - '0';
+ if (val <= (INT_MAX - cValue) / 10) {
+ val = 10*val + cValue;
+ } else {
+ hasOverflow = true;
+ }
continue;
} else {
if (c == '#') // comment
@@ -91,7 +97,7 @@ static int read_pbm_int(QIODevice *d)
else
break;
}
- return val;
+ return hasOverflow ? -1 : val;
}
static bool read_pbm_header(QIODevice *device, char& type, int& w, int& h, int& mcc)
@@ -123,7 +129,7 @@ static bool read_pbm_header(QIODevice *device, char& type, int& w, int& h, int&
static inline QRgb scale_pbm_color(quint16 mx, quint16 rv, quint16 gv, quint16 bv)
{
- return QRgba64::fromRgba64((rv * 0xffff) / mx, (gv * 0xffff) / mx, (bv * 0xffff) / mx, 0xffff).toArgb32();
+ return QRgba64::fromRgba64((rv * 0xffffu) / mx, (gv * 0xffffu) / mx, (bv * 0xffffu) / mx, 0xffff).toArgb32();
}
static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, QImage *outImage)
@@ -252,7 +258,7 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
}
} else {
while (n--) {
- *p++ = read_pbm_int(device) * 255 / mcc;
+ *p++ = (read_pbm_int(device) & 0xffff) * 255 / mcc;
}
}
} else { // 32 bits
@@ -570,10 +576,12 @@ void QPpmHandler::setOption(ImageOption option, const QVariant &value)
subType = value.toByteArray().toLower();
}
+#if QT_DEPRECATED_SINCE(5, 13)
QByteArray QPpmHandler::name() const
{
return subType.isEmpty() ? QByteArray("ppm") : subType;
}
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/image/qppmhandler_p.h b/src/gui/image/qppmhandler_p.h
index 1c6fbd6869..f3c9d0f139 100644
--- a/src/gui/image/qppmhandler_p.h
+++ b/src/gui/image/qppmhandler_p.h
@@ -67,7 +67,9 @@ public:
bool read(QImage *image) override;
bool write(const QImage &image) override;
+#if QT_DEPRECATED_SINCE(5, 13)
QByteArray name() const override;
+#endif
static bool canRead(QIODevice *device, QByteArray *subType = 0);
diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp
index 7ba44049b4..65a5b63bc7 100644
--- a/src/gui/image/qxbmhandler.cpp
+++ b/src/gui/image/qxbmhandler.cpp
@@ -356,10 +356,12 @@ void QXbmHandler::setOption(ImageOption option, const QVariant &value)
fileName = value.toString();
}
+#if QT_DEPRECATED_SINCE(5, 13)
QByteArray QXbmHandler::name() const
{
return "xbm";
}
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/image/qxbmhandler_p.h b/src/gui/image/qxbmhandler_p.h
index 26439af527..ae590a1944 100644
--- a/src/gui/image/qxbmhandler_p.h
+++ b/src/gui/image/qxbmhandler_p.h
@@ -66,7 +66,9 @@ public:
bool read(QImage *image) override;
bool write(const QImage &image) override;
+#if QT_DEPRECATED_SINCE(5, 13)
QByteArray name() const override;
+#endif
static bool canRead(QIODevice *device);
diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp
index 17272ffe69..a32dfda96d 100644
--- a/src/gui/image/qxpmhandler.cpp
+++ b/src/gui/image/qxpmhandler.cpp
@@ -1287,10 +1287,12 @@ void QXpmHandler::setOption(ImageOption option, const QVariant &value)
fileName = value.toString();
}
+#if QT_DEPRECATED_SINCE(5, 13)
QByteArray QXpmHandler::name() const
{
return "xpm";
}
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/image/qxpmhandler_p.h b/src/gui/image/qxpmhandler_p.h
index f118bf2309..a4dd88cd17 100644
--- a/src/gui/image/qxpmhandler_p.h
+++ b/src/gui/image/qxpmhandler_p.h
@@ -68,7 +68,9 @@ public:
static bool canRead(QIODevice *device);
+#if QT_DEPRECATED_SINCE(5, 13)
QByteArray name() const override;
+#endif
QVariant option(ImageOption option) const override;
void setOption(ImageOption option, const QVariant &value) override;
diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp
index 7afad95bd9..3e3c7a6211 100644
--- a/src/gui/itemmodels/qstandarditemmodel.cpp
+++ b/src/gui/itemmodels/qstandarditemmodel.cpp
@@ -1905,7 +1905,7 @@ QStandardItem *QStandardItem::takeChild(int row, int column)
/*!
Removes \a row without deleting the row items, and returns a list of
pointers to the removed items. For items in the row that have not been
- set, the corresponding pointers in the list will be 0.
+ set, the corresponding pointers in the list will be \nullptr.
\sa removeRow(), insertRow(), takeColumn()
*/
@@ -1939,7 +1939,7 @@ QList<QStandardItem*> QStandardItem::takeRow(int row)
/*!
Removes \a column without deleting the column items, and returns a list of
pointers to the removed items. For items in the column that have not been
- set, the corresponding pointers in the list will be 0.
+ set, the corresponding pointers in the list will be \nullptr.
\sa removeColumn(), insertColumn(), takeRow()
*/
@@ -2718,7 +2718,7 @@ QStandardItem *QStandardItemModel::takeItem(int row, int column)
Removes the given \a row without deleting the row items, and returns a
list of pointers to the removed items. The model releases ownership of the
items. For items in the row that have not been set, the corresponding
- pointers in the list will be 0.
+ pointers in the list will be \nullptr.
\sa takeColumn()
*/
@@ -2734,7 +2734,7 @@ QList<QStandardItem*> QStandardItemModel::takeRow(int row)
Removes the given \a column without deleting the column items, and returns
a list of pointers to the removed items. The model releases ownership of
the items. For items in the column that have not been set, the
- corresponding pointers in the list will be 0.
+ corresponding pointers in the list will be \nullptr.
\sa takeRow()
*/
@@ -3010,6 +3010,11 @@ bool QStandardItemModel::setData(const QModelIndex &index, const QVariant &value
return true;
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \reimp
+ */
+#else
/*!
\since 5.12
Removes the data stored in all the roles for the given \a index.
@@ -3018,6 +3023,7 @@ bool QStandardItemModel::setData(const QModelIndex &index, const QVariant &value
\sa setData(), data()
*/
+#endif
bool QStandardItemModel::clearItemData(const QModelIndex &index)
{
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
diff --git a/src/gui/itemmodels/qstandarditemmodel_p.h b/src/gui/itemmodels/qstandarditemmodel_p.h
index 00e83f7b08..23d2938bc4 100644
--- a/src/gui/itemmodels/qstandarditemmodel_p.h
+++ b/src/gui/itemmodels/qstandarditemmodel_p.h
@@ -207,7 +207,7 @@ class QStandardItemModelPrivate : public QAbstractItemModelPrivate
public:
QStandardItemModelPrivate();
- virtual ~QStandardItemModelPrivate();
+ ~QStandardItemModelPrivate();
void init();
diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp
index a76150d91d..267c079ad9 100644
--- a/src/gui/kernel/qclipboard.cpp
+++ b/src/gui/kernel/qclipboard.cpp
@@ -439,7 +439,7 @@ void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode)
\fn QMimeData *QClipboard::mimeData(Mode mode) const
Returns a pointer to a QMimeData representation of the current
- clipboard data (can be NULL if the given \a mode is not
+ clipboard data (can be \nullptr if the given \a mode is not
supported by the platform).
The \a mode argument is used to control which part of the system
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index bb81ca109a..9e4787589f 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -564,8 +564,8 @@ void QCursor::setShape(Qt::CursorShape shape)
}
/*!
- Returns the cursor bitmap, or 0 if it is one of the standard
- cursors.
+ Returns the cursor bitmap, or \nullptr if it is one of the
+ standard cursors.
*/
const QBitmap *QCursor::bitmap() const
{
@@ -575,8 +575,8 @@ const QBitmap *QCursor::bitmap() const
}
/*!
- Returns the cursor bitmap mask, or 0 if it is one of the standard
- cursors.
+ Returns the cursor bitmap mask, or \nullptr if it is one of the
+ standard cursors.
*/
const QBitmap *QCursor::mask() const
diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h
index 5f6db07987..8f8eb03f87 100644
--- a/src/gui/kernel/qdnd_p.h
+++ b/src/gui/kernel/qdnd_p.h
@@ -110,7 +110,7 @@ private:
QDrag *m_object;
static QDragManager *m_instance;
- Q_DISABLE_COPY(QDragManager)
+ Q_DISABLE_COPY_MOVE(QDragManager)
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qdrag.cpp b/src/gui/kernel/qdrag.cpp
index bb0e490aa0..dcd0d13d5c 100644
--- a/src/gui/kernel/qdrag.cpp
+++ b/src/gui/kernel/qdrag.cpp
@@ -284,6 +284,7 @@ Qt::DropAction QDrag::exec(Qt::DropActions supportedActions, Qt::DropAction defa
return d->executed_action;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -311,6 +312,7 @@ Qt::DropAction QDrag::start(Qt::DropActions request)
d->executed_action = QDragManager::self()->drag(this);
return d->executed_action;
}
+#endif
/*!
Sets the drag \a cursor for the \a action. This allows you
diff --git a/src/gui/kernel/qdrag.h b/src/gui/kernel/qdrag.h
index 27b9c2c88f..7acd5088bd 100644
--- a/src/gui/kernel/qdrag.h
+++ b/src/gui/kernel/qdrag.h
@@ -74,7 +74,10 @@ public:
QObject *source() const;
QObject *target() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QDrag::exec() instead")
Qt::DropAction start(Qt::DropActions supportedActions = Qt::CopyAction);
+#endif
Qt::DropAction exec(Qt::DropActions supportedActions = Qt::MoveAction);
Qt::DropAction exec(Qt::DropActions supportedActions, Qt::DropAction defaultAction);
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index fd01f8bb7b..4e0c45d8ae 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -208,6 +208,8 @@ bool QGuiApplicationPrivate::obey_desktop_settings = true;
QInputDeviceManager *QGuiApplicationPrivate::m_inputDeviceManager = 0;
+qreal QGuiApplicationPrivate::m_maxDevicePixelRatio = 0.0;
+
static qreal fontSmoothingGamma = 1.7;
extern void qRegisterGuiVariant();
@@ -1021,7 +1023,7 @@ QList<QScreen *> QGuiApplication::screens()
}
/*!
- Returns the screen at \a point, or \c nullptr if outside of any screen.
+ Returns the screen at \a point, or \nullptr if outside of any screen.
The \a point is in relation to the virtualGeometry() of each set of virtual
siblings. If the point maps to more than one set of virtual siblings the first
@@ -1093,17 +1095,19 @@ QScreen *QGuiApplication::screenAt(const QPoint &point)
*/
qreal QGuiApplication::devicePixelRatio() const
{
- // Cache topDevicePixelRatio, iterate through the screen list once only.
- static qreal topDevicePixelRatio = 0.0;
- if (!qFuzzyIsNull(topDevicePixelRatio)) {
- return topDevicePixelRatio;
- }
+ if (!qFuzzyIsNull(QGuiApplicationPrivate::m_maxDevicePixelRatio))
+ return QGuiApplicationPrivate::m_maxDevicePixelRatio;
- topDevicePixelRatio = 1.0; // make sure we never return 0.
+ QGuiApplicationPrivate::m_maxDevicePixelRatio = 1.0; // make sure we never return 0.
for (QScreen *screen : qAsConst(QGuiApplicationPrivate::screen_list))
- topDevicePixelRatio = qMax(topDevicePixelRatio, screen->devicePixelRatio());
+ QGuiApplicationPrivate::m_maxDevicePixelRatio = qMax(QGuiApplicationPrivate::m_maxDevicePixelRatio, screen->devicePixelRatio());
+
+ return QGuiApplicationPrivate::m_maxDevicePixelRatio;
+}
- return topDevicePixelRatio;
+void QGuiApplicationPrivate::resetCachedDevicePixelRatio()
+{
+ m_maxDevicePixelRatio = 0.0;
}
/*!
@@ -1168,7 +1172,7 @@ static void init_platform(const QString &pluginNamesWithArguments, const QString
QStringList plugins = pluginNamesWithArguments.split(QLatin1Char(';'));
QStringList platformArguments;
QStringList availablePlugins = QPlatformIntegrationFactory::keys(platformPluginPath);
- for (auto pluginArgument : plugins) {
+ for (const auto &pluginArgument : plugins) {
// Split into platform name and arguments
QStringList arguments = pluginArgument.split(QLatin1Char(':'));
const QString name = arguments.takeFirst().toLower();
@@ -2183,8 +2187,6 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
#endif // QT_CONFIG(wheelevent)
}
-// Remember, Qt convention is: keyboard state is state *before*
-
void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
{
QWindow *window = e->window.data();
@@ -2423,9 +2425,9 @@ void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePr
window->d_func()->resizeEventPending = false;
if (actualGeometry.width() != lastReportedGeometry.width())
- window->widthChanged(actualGeometry.width());
+ emit window->widthChanged(actualGeometry.width());
if (actualGeometry.height() != lastReportedGeometry.height())
- window->heightChanged(actualGeometry.height());
+ emit window->heightChanged(actualGeometry.height());
}
if (isMove) {
@@ -2434,9 +2436,9 @@ void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePr
QGuiApplication::sendSpontaneousEvent(window, &e);
if (actualGeometry.x() != lastReportedGeometry.x())
- window->xChanged(actualGeometry.x());
+ emit window->xChanged(actualGeometry.x());
if (actualGeometry.y() != lastReportedGeometry.y())
- window->yChanged(actualGeometry.y());
+ emit window->yChanged(actualGeometry.y());
}
}
@@ -3000,6 +3002,8 @@ void QGuiApplicationPrivate::processScreenGeometryChange(QWindowSystemInterfaceP
for (QScreen* sibling : siblings)
emit sibling->virtualGeometryChanged(sibling->virtualGeometry());
}
+
+ resetCachedDevicePixelRatio();
}
void QGuiApplicationPrivate::processScreenLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e)
@@ -3015,6 +3019,8 @@ void QGuiApplicationPrivate::processScreenLogicalDotsPerInchChange(QWindowSystem
s->d_func()->logicalDpi = QDpi(e->dpiX, e->dpiY);
emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch());
+
+ resetCachedDevicePixelRatio();
}
void QGuiApplicationPrivate::processScreenRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e)
@@ -3070,41 +3076,8 @@ void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::E
/*! \internal
- This function updates an internal state to keep the source compatibility. Documentation of
- QGuiApplication::mouseButtons() states - "The current state is updated synchronously as
- the event queue is emptied of events that will spontaneously change the mouse state
- (QEvent::MouseButtonPress and QEvent::MouseButtonRelease events)". But internally we have
- been updating these state variables from various places to keep buttons returned by
- mouseButtons() in sync with the systems state. This is not the documented behavior.
-
- ### Qt6 - Remove QGuiApplication::mouseButtons()/keyboardModifiers() API? And here
- are the reasons:
-
- - It is an easy to misuse API by:
-
- a) Application developers: The only place where the values of this API can be trusted is
- when using within mouse handling callbacks. In these callbacks we work with the state
- that was provided directly by the windowing system. Anywhere else it might not reflect what
- user wrongly expects. We might not always receive a matching mouse release for a press event
- (e.g. When dismissing a popup window on X11. Or when dnd enter Qt application with mouse
- button down, we update mouse_buttons and then dnd leaves Qt application and does a drop
- somewhere else) and hence mouseButtons() will be out-of-sync from users perspective, see
- for example QTBUG-33161. BUT THIS IS NOT HOW THE API IS SUPPOSED TO BE USED. Since the only
- safe place to use this API is from mouse event handlers, we might as well deprecate it and
- pass down the button state if we are not already doing that everywhere where it matters.
-
- b) Qt framework developers:
-
- We see users complaining, we start adding hacks everywhere just to keep buttons in sync ;)
- There are corner cases that can not be solved and adding this kind of hacks is never ending
- task.
-
- - Real mouse events, tablet mouse events, etc: all go through QGuiApplication::processMouseEvent,
- and all share mouse_buttons. What if we want to support multiple mice in future? The API must
- go.
-
- - Motivation why this API is public is not clear. Could the same be achieved by a user by
- installing an event filter?
+ This function updates an internal state to keep the source compatibility.
+ ### Qt 6 - Won't need after QTBUG-73829
*/
static void updateMouseAndModifierButtonState(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
{
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index 02dffef0fe..5ea72fa0f6 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -86,7 +86,7 @@ public:
#else
QGuiApplication(int &argc, char **argv, int = ApplicationFlags);
#endif
- virtual ~QGuiApplication();
+ ~QGuiApplication();
static void setApplicationDisplayName(const QString &name);
static QString applicationDisplayName();
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 042a36c31f..63646dcd50 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -311,6 +311,8 @@ public:
static void setApplicationState(Qt::ApplicationState state, bool forcePropagate = false);
+ static void resetCachedDevicePixelRatio();
+
protected:
virtual void notifyThemeChanged();
virtual void sendApplicationPaletteChange(bool toAllWidgets = false, const char *className = nullptr);
@@ -331,6 +333,10 @@ private:
bool ownGlobalShareContext;
static QInputDeviceManager *m_inputDeviceManager;
+
+ // Cache the maximum device pixel ratio, to iterate through the screen list
+ // only the first time it's required, or when devices are added or removed.
+ static qreal m_maxDevicePixelRatio;
};
Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k);
diff --git a/src/gui/kernel/qkeymapper_p.h b/src/gui/kernel/qkeymapper_p.h
index aeec7b7414..8364557020 100644
--- a/src/gui/kernel/qkeymapper_p.h
+++ b/src/gui/kernel/qkeymapper_p.h
@@ -76,7 +76,7 @@ public:
private:
friend QKeyMapperPrivate *qt_keymapper_private();
Q_DECLARE_PRIVATE(QKeyMapper)
- Q_DISABLE_COPY(QKeyMapper)
+ Q_DISABLE_COPY_MOVE(QKeyMapper)
};
struct KeyboardLayoutItem;
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index a428da8ca4..74bf6e6b47 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -1221,10 +1221,12 @@ QString QKeySequence::encodeString(int key)
static inline void addKey(QString &str, const QString &theKey, QKeySequence::SequenceFormat format)
{
if (!str.isEmpty()) {
- if (format == QKeySequence::NativeText)
+ if (format == QKeySequence::NativeText) {
+ //: Key separator in shortcut string
str += QCoreApplication::translate("QShortcut", "+");
- else
+ } else {
str += QLatin1Char('+');
+ }
}
str += theKey;
diff --git a/src/gui/kernel/qoffscreensurface.h b/src/gui/kernel/qoffscreensurface.h
index 9d4839cb25..1b9e7c00ca 100644
--- a/src/gui/kernel/qoffscreensurface.h
+++ b/src/gui/kernel/qoffscreensurface.h
@@ -60,7 +60,7 @@ public:
// ### Qt 6: merge overloads
explicit QOffscreenSurface(QScreen *screen, QObject *parent);
explicit QOffscreenSurface(QScreen *screen = nullptr);
- virtual ~QOffscreenSurface();
+ ~QOffscreenSurface();
SurfaceType surfaceType() const override;
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 9a6f879431..bf3403f2e4 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -414,15 +414,14 @@ int QOpenGLContextPrivate::maxTextureSize()
/*!
Returns the last context which called makeCurrent in the current thread,
- or 0, if no context is current.
+ or \nullptr, if no context is current.
*/
QOpenGLContext* QOpenGLContext::currentContext()
{
QGuiGLThreadContext *threadContext = qwindow_context_storage()->localData();
- if (threadContext) {
+ if (threadContext)
return threadContext->context;
- }
- return 0;
+ return nullptr;
}
/*!
@@ -1236,7 +1235,8 @@ void QOpenGLContext::deleteQGLContext()
Returns the platform-specific handle for the OpenGL implementation that
is currently in use. (for example, a HMODULE on Windows)
- On platforms that do not use dynamic GL switch the return value is null.
+ On platforms that do not use dynamic GL switching, the return value
+ is \nullptr.
The library might be GL-only, meaning that windowing system interface
functions (for example EGL) may live in another, separate library.
diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h
index 4f2f951d61..2849d0c58e 100644
--- a/src/gui/kernel/qopenglcontext_p.h
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -97,7 +97,7 @@ private:
friend class QOpenGLContextGroupPrivate;
friend class QOpenGLMultiGroupSharedResource;
- Q_DISABLE_COPY(QOpenGLSharedResource)
+ Q_DISABLE_COPY_MOVE(QOpenGLSharedResource)
};
class Q_GUI_EXPORT QOpenGLSharedResourceGuard : public QOpenGLSharedResource
@@ -219,7 +219,7 @@ public:
requestedFormat = QSurfaceFormat::defaultFormat();
}
- virtual ~QOpenGLContextPrivate()
+ ~QOpenGLContextPrivate()
{
//do not delete the QOpenGLContext handle here as it is deleted in
//QWidgetPrivate::deleteTLSysExtra()
diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp
index 9ccfb9b819..b4383c5bfc 100644
--- a/src/gui/kernel/qpalette.cpp
+++ b/src/gui/kernel/qpalette.cpp
@@ -941,7 +941,8 @@ qint64 QPalette::cacheKey() const
}
/*!
- Returns a new QPalette that has attributes copied from \a other.
+ Returns a new QPalette that is a union of this instance and \a other.
+ Color roles set in this instance take precedence.
*/
QPalette QPalette::resolve(const QPalette &other) const
{
@@ -959,6 +960,7 @@ QPalette QPalette::resolve(const QPalette &other) const
if (!(data.resolve_mask & (1<<role)))
for(int grp = 0; grp < (int)NColorGroups; grp++)
palette.d->br[grp][role] = other.d->br[grp][role];
+ palette.data.resolve_mask |= other.data.resolve_mask;
return palette;
}
@@ -981,7 +983,7 @@ QPalette QPalette::resolve(const QPalette &other) const
#ifndef QT_NO_DATASTREAM
static const int NumOldRoles = 7;
-static const int oldRoles[7] = { QPalette::Foreground, QPalette::Background, QPalette::Light,
+static const int oldRoles[7] = { QPalette::WindowText, QPalette::Window, QPalette::Light,
QPalette::Dark, QPalette::Mid, QPalette::Text, QPalette::Base };
/*!
diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h
index 071eddbc4d..e931e01480 100644
--- a/src/gui/kernel/qpalette.h
+++ b/src/gui/kernel/qpalette.h
@@ -98,7 +98,10 @@ public:
ToolTipBase, ToolTipText,
PlaceholderText,
NColorRoles = PlaceholderText + 1,
- Foreground = WindowText, Background = Window
+#if QT_DEPRECATED_SINCE(5, 13)
+ Foreground Q_DECL_ENUMERATOR_DEPRECATED_X("Use QPalette::WindowText instead") = WindowText,
+ Background Q_DECL_ENUMERATOR_DEPRECATED_X("Use QPalette::Window instead") = Window
+#endif
};
Q_ENUM(ColorRole)
@@ -121,7 +124,6 @@ public:
inline const QColor &color(ColorRole cr) const { return color(Current, cr); }
inline const QBrush &brush(ColorRole cr) const { return brush(Current, cr); }
- inline const QBrush &foreground() const { return brush(WindowText); }
inline const QBrush &windowText() const { return brush(WindowText); }
inline const QBrush &button() const { return brush(Button); }
inline const QBrush &light() const { return brush(Light); }
@@ -132,7 +134,6 @@ public:
inline const QBrush &alternateBase() const { return brush(AlternateBase); }
inline const QBrush &toolTipBase() const { return brush(ToolTipBase); }
inline const QBrush &toolTipText() const { return brush(ToolTipText); }
- inline const QBrush &background() const { return brush(Window); }
inline const QBrush &window() const { return brush(Window); }
inline const QBrush &midlight() const { return brush(Midlight); }
inline const QBrush &brightText() const { return brush(BrightText); }
@@ -143,6 +144,12 @@ public:
inline const QBrush &link() const { return brush(Link); }
inline const QBrush &linkVisited() const { return brush(LinkVisited); }
inline const QBrush &placeholderText() const { return brush(PlaceholderText); }
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QPalette::windowText() instead")
+ inline const QBrush &foreground() const { return windowText(); }
+ QT_DEPRECATED_X("Use QPalette::window() instead")
+ inline const QBrush &background() const { return window(); }
+#endif
bool operator==(const QPalette &p) const;
inline bool operator!=(const QPalette &p) const { return !(operator==(p)); }
diff --git a/src/gui/kernel/qplatformclipboard.h b/src/gui/kernel/qplatformclipboard.h
index 60733b0a9f..3220201720 100644
--- a/src/gui/kernel/qplatformclipboard.h
+++ b/src/gui/kernel/qplatformclipboard.h
@@ -61,6 +61,9 @@ QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QPlatformClipboard
{
public:
+ Q_DISABLE_COPY_MOVE(QPlatformClipboard)
+
+ QPlatformClipboard() = default;
virtual ~QPlatformClipboard();
virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard);
diff --git a/src/gui/kernel/qplatformcursor.cpp b/src/gui/kernel/qplatformcursor.cpp
index 76e38ab12d..49eff2ad23 100644
--- a/src/gui/kernel/qplatformcursor.cpp
+++ b/src/gui/kernel/qplatformcursor.cpp
@@ -89,7 +89,7 @@ QT_BEGIN_NAMESPACE
set or the system default cursor should take effect.
\a window is a pointer to the window currently displayed at QCursor::pos(). Note
- that this may be 0 if the current position is not occupied by a displayed widget.
+ that this may be \nullptr if the current position is not occupied by a displayed widget.
\sa QCursor::pos()
*/
diff --git a/src/gui/kernel/qplatformcursor.h b/src/gui/kernel/qplatformcursor.h
index 40e8a562f8..f36a73c861 100644
--- a/src/gui/kernel/qplatformcursor.h
+++ b/src/gui/kernel/qplatformcursor.h
@@ -78,6 +78,8 @@ private:
class Q_GUI_EXPORT QPlatformCursor : public QObject {
public:
+ Q_DISABLE_COPY_MOVE(QPlatformCursor)
+
enum Capability {
OverrideCursor = 0x1
};
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp
index 628ad06478..d14d575056 100644
--- a/src/gui/kernel/qplatformdialoghelper.cpp
+++ b/src/gui/kernel/qplatformdialoghelper.cpp
@@ -41,6 +41,7 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QVariant>
+#include <QtCore/QRegularExpression>
#include <QtCore/QSharedData>
#if QT_CONFIG(settings)
#include <QtCore/QSettings>
@@ -63,6 +64,18 @@ QT_BEGIN_NAMESPACE
*/
+/*!
+ \enum QPlatformDialogHelper::StyleHint
+
+ This enum type specifies platform-specific style hints.
+
+ \value DialogIsQtWindow Indicates that a platform-specific dialog is implemented
+ as in-process Qt window. It allows to prevent blocking the
+ dialog by an invisible proxy Qt dialog.
+
+ \sa styleHint()
+*/
+
static const int buttonRoleLayouts[2][6][14] =
{
// Qt::Horizontal
@@ -767,18 +780,19 @@ void QPlatformFileDialogHelper::setOptions(const QSharedPointer<QFileDialogOptio
m_options = options;
}
-const char *QPlatformFileDialogHelper::filterRegExp =
+const char QPlatformFileDialogHelper::filterRegExp[] =
"^(.*)\\(([a-zA-Z0-9_.,*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
// Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)"
QStringList QPlatformFileDialogHelper::cleanFilterList(const QString &filter)
{
- QRegExp regexp(QString::fromLatin1(filterRegExp));
+ QRegularExpression regexp(QString::fromLatin1(filterRegExp));
Q_ASSERT(regexp.isValid());
QString f = filter;
- int i = regexp.indexIn(f);
- if (i >= 0)
- f = regexp.cap(2);
+ QRegularExpressionMatch match;
+ filter.indexOf(regexp, 0, &match);
+ if (match.hasMatch())
+ f = match.captured(2);
return f.split(QLatin1Char(' '), QString::SkipEmptyParts);
}
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index bfcb658172..f09bec12da 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -80,6 +80,7 @@ class Q_GUI_EXPORT QPlatformDialogHelper : public QObject
Q_OBJECT
public:
enum StyleHint {
+ DialogIsQtWindow
};
enum DialogCode { Rejected, Accepted };
@@ -153,7 +154,7 @@ public:
Q_ENUM(ButtonLayout)
QPlatformDialogHelper();
- virtual ~QPlatformDialogHelper();
+ ~QPlatformDialogHelper();
virtual QVariant styleHint(StyleHint hint) const;
@@ -413,7 +414,7 @@ public:
void setOptions(const QSharedPointer<QFileDialogOptions> &options);
static QStringList cleanFilterList(const QString &filter);
- static const char *filterRegExp;
+ static const char filterRegExp[];
Q_SIGNALS:
void fileSelected(const QUrl &file);
diff --git a/src/gui/kernel/qplatformdrag.h b/src/gui/kernel/qplatformdrag.h
index 9d4e352b4b..0c99539357 100644
--- a/src/gui/kernel/qplatformdrag.h
+++ b/src/gui/kernel/qplatformdrag.h
@@ -91,6 +91,8 @@ class Q_GUI_EXPORT QPlatformDrag
{
Q_DECLARE_PRIVATE(QPlatformDrag)
public:
+ Q_DISABLE_COPY_MOVE(QPlatformDrag)
+
QPlatformDrag();
virtual ~QPlatformDrag();
@@ -108,8 +110,6 @@ public:
private:
QPlatformDragPrivate *d_ptr;
-
- Q_DISABLE_COPY(QPlatformDrag)
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformgraphicsbuffer.cpp b/src/gui/kernel/qplatformgraphicsbuffer.cpp
index d361a8fc12..73ec033e19 100644
--- a/src/gui/kernel/qplatformgraphicsbuffer.cpp
+++ b/src/gui/kernel/qplatformgraphicsbuffer.cpp
@@ -184,7 +184,7 @@ void QPlatformGraphicsBuffer::unlock()
\fn QPlatformGraphicsBuffer::doLock(AccessTypes access, const QRect &rect = QRect())
This function should be reimplemented by subclasses. If one of the \a
- access types specified can not be locked, then all should fail and this
+ access types specified cannot be locked, then all should fail and this
function should return false.
\a rect is the subrect which is desired to be locked. This
diff --git a/src/gui/kernel/qplatformgraphicsbuffer.h b/src/gui/kernel/qplatformgraphicsbuffer.h
index 11566e1201..9004116ea4 100644
--- a/src/gui/kernel/qplatformgraphicsbuffer.h
+++ b/src/gui/kernel/qplatformgraphicsbuffer.h
@@ -80,7 +80,7 @@ public:
};
Q_ENUM(Origin);
- virtual ~QPlatformGraphicsBuffer();
+ ~QPlatformGraphicsBuffer();
AccessTypes isLocked() const { return m_lock_access; }
bool lock(AccessTypes access, const QRect &rect = QRect());
diff --git a/src/gui/kernel/qplatforminputcontext.h b/src/gui/kernel/qplatforminputcontext.h
index 26d40cd2c6..ad0e5bcf35 100644
--- a/src/gui/kernel/qplatforminputcontext.h
+++ b/src/gui/kernel/qplatforminputcontext.h
@@ -67,7 +67,7 @@ public:
};
QPlatformInputContext();
- virtual ~QPlatformInputContext();
+ ~QPlatformInputContext();
virtual bool isValid() const;
virtual bool hasCapability(Capability capability) const;
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index ac4d12b024..490cfc6178 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -291,7 +291,7 @@ QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::Pix
platform implementation is responsible for querying the configuriation from the provided
native context.
- Returns a pointer to a QPlatformOpenGLContext instance or \c NULL if the context could
+ Returns a pointer to a QPlatformOpenGLContext instance or \nullptr if the context could
not be created.
\sa QOpenGLContext
@@ -462,42 +462,6 @@ QList<int> QPlatformIntegration::possibleKeys(const QKeyEvent *) const
return QList<int>();
}
-/*!
- \deprecated Use QWindowSystemInterface::handleScreenAdded instead.
-*/
-void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
-{
- QWindowSystemInterface::handleScreenAdded(ps, isPrimary);
-}
-
-/*!
- \deprecated Use QWindowSystemInterface::handleScreenRemoved instead.
-*/
-void QPlatformIntegration::removeScreen(QScreen *screen)
-{
- const bool wasPrimary = (!QGuiApplicationPrivate::screen_list.isEmpty() && QGuiApplicationPrivate::screen_list.at(0) == screen);
- QGuiApplicationPrivate::screen_list.removeOne(screen);
-
- if (wasPrimary && qGuiApp && !QGuiApplicationPrivate::screen_list.isEmpty())
- emit qGuiApp->primaryScreenChanged(QGuiApplicationPrivate::screen_list.at(0));
-}
-
-/*!
- \deprecated Use QWindowSystemInterface::handleScreenRemoved instead.
-*/
-void QPlatformIntegration::destroyScreen(QPlatformScreen *platformScreen)
-{
- QWindowSystemInterface::handleScreenRemoved(platformScreen);
-}
-
-/*!
- \deprecated Use QWindowSystemInterface::handlePrimaryScreenChanged instead.
-*/
-void QPlatformIntegration::setPrimaryScreen(QPlatformScreen *newPrimary)
-{
- QWindowSystemInterface::handlePrimaryScreenChanged(newPrimary);
-}
-
QStringList QPlatformIntegration::themeNames() const
{
return QStringList();
@@ -602,7 +566,7 @@ void QPlatformIntegration::setApplicationIcon(const QIcon &icon) const
pointer to the instance for which a platform-specific backend needs to be
created.
- Returns a pointer to a QPlatformOpenGLContext instance or \c NULL if the context could
+ Returns a pointer to a QPlatformOpenGLContext instance or \nullptr if the context could
not be created.
\sa QVulkanInstance
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index 1179daeb32..389b35dbc0 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -84,6 +84,8 @@ class QVulkanInstance;
class Q_GUI_EXPORT QPlatformIntegration
{
public:
+ Q_DISABLE_COPY_MOVE(QPlatformIntegration)
+
enum Capability {
ThreadedPixmaps = 1,
OpenGL,
@@ -190,10 +192,6 @@ public:
#endif
virtual void setApplicationIcon(const QIcon &icon) const;
-#if QT_DEPRECATED_SINCE(5, 12)
- QT_DEPRECATED_X("Use QWindowSystemInterface::handleScreenRemoved") void removeScreen(QScreen *screen);
-#endif
-
virtual void beep() const;
#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
@@ -201,11 +199,7 @@ public:
#endif
protected:
-#if QT_DEPRECATED_SINCE(5, 12)
- QT_DEPRECATED_X("Use QWindowSystemInterface::handleScreenAdded") void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
- QT_DEPRECATED_X("Use QWindowSystemInterface::handleScreenRemoved") void destroyScreen(QPlatformScreen *screen);
- QT_DEPRECATED_X("Use QWindowSystemInterface::handlePrimaryScreenChanged") void setPrimaryScreen(QPlatformScreen *newPrimary);
-#endif
+ QPlatformIntegration() = default;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index 21ae75ba8f..9c5876550a 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -62,10 +62,6 @@ QPlatformScreen::~QPlatformScreen()
Q_D(QPlatformScreen);
if (d->screen) {
qWarning("Manually deleting a QPlatformScreen. Call QWindowSystemInterface::handleScreenRemoved instead.");
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED
- QGuiApplicationPrivate::platformIntegration()->removeScreen(d->screen);
-QT_WARNING_POP
delete d->screen;
}
}
diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h
index e9d64c8a29..b9ecc80320 100644
--- a/src/gui/kernel/qplatformscreen.h
+++ b/src/gui/kernel/qplatformscreen.h
@@ -80,6 +80,8 @@ class Q_GUI_EXPORT QPlatformScreen
Q_DECLARE_PRIVATE(QPlatformScreen)
public:
+ Q_DISABLE_COPY_MOVE(QPlatformScreen)
+
enum SubpixelAntialiasingType { // copied from qfontengine_p.h since we can't include private headers
Subpixel_None,
Subpixel_RGB,
@@ -164,8 +166,6 @@ protected:
QScopedPointer<QPlatformScreenPrivate> d_ptr;
private:
- Q_DISABLE_COPY(QPlatformScreen)
-
friend class QScreenPrivate;
};
diff --git a/src/gui/kernel/qplatformservices.h b/src/gui/kernel/qplatformservices.h
index 339bbfde3f..5de96cfa7d 100644
--- a/src/gui/kernel/qplatformservices.h
+++ b/src/gui/kernel/qplatformservices.h
@@ -58,6 +58,8 @@ class QUrl;
class Q_GUI_EXPORT QPlatformServices
{
public:
+ Q_DISABLE_COPY_MOVE(QPlatformServices)
+
QPlatformServices();
virtual ~QPlatformServices() { }
diff --git a/src/gui/kernel/qplatformsessionmanager.h b/src/gui/kernel/qplatformsessionmanager.h
index ca7cab389b..c6c3984816 100644
--- a/src/gui/kernel/qplatformsessionmanager.h
+++ b/src/gui/kernel/qplatformsessionmanager.h
@@ -64,6 +64,8 @@ QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QPlatformSessionManager
{
public:
+ Q_DISABLE_COPY_MOVE(QPlatformSessionManager)
+
explicit QPlatformSessionManager(const QString &id, const QString &key);
virtual ~QPlatformSessionManager();
@@ -101,8 +103,6 @@ private:
QStringList m_restartCommand;
QStringList m_discardCommand;
QSessionManager::RestartHint m_restartHint;
-
- Q_DISABLE_COPY(QPlatformSessionManager)
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformsurface.h b/src/gui/kernel/qplatformsurface.h
index 4d8854fb40..475f3ef330 100644
--- a/src/gui/kernel/qplatformsurface.h
+++ b/src/gui/kernel/qplatformsurface.h
@@ -65,6 +65,8 @@ class QDebug;
class Q_GUI_EXPORT QPlatformSurface
{
public:
+ Q_DISABLE_COPY_MOVE(QPlatformSurface)
+
virtual ~QPlatformSurface();
virtual QSurfaceFormat format() const = 0;
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 1d6049a98d..54c8c70025 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -76,6 +76,8 @@ class Q_GUI_EXPORT QPlatformTheme
{
Q_DECLARE_PRIVATE(QPlatformTheme)
public:
+ Q_DISABLE_COPY_MOVE(QPlatformTheme)
+
enum ThemeHint {
CursorFlashTime,
KeyboardInputInterval,
@@ -324,8 +326,6 @@ public:
protected:
explicit QPlatformTheme(QPlatformThemePrivate *priv);
QScopedPointer<QPlatformThemePrivate> d_ptr;
-private:
- Q_DISABLE_COPY(QPlatformTheme)
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 24cfd32ace..562289a8c9 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -90,11 +90,11 @@ QWindow *QPlatformWindow::window() const
}
/*!
- Returns the parent platform window (or 0 if orphan).
+ Returns the parent platform window (or \nullptr if orphan).
*/
QPlatformWindow *QPlatformWindow::parent() const
{
- return window()->parent() ? window()->parent()->handle() : 0;
+ return window()->parent() ? window()->parent()->handle() : nullptr;
}
/*!
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index 075ac0f82b..4d48cc2f13 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -71,6 +71,8 @@ class Q_GUI_EXPORT QPlatformWindow : public QPlatformSurface
{
Q_DECLARE_PRIVATE(QPlatformWindow)
public:
+ Q_DISABLE_COPY_MOVE(QPlatformWindow)
+
explicit QPlatformWindow(QWindow *window);
~QPlatformWindow() override;
@@ -164,8 +166,6 @@ protected:
static QSize constrainWindowSize(const QSize &size);
QScopedPointer<QPlatformWindowPrivate> d_ptr;
-private:
- Q_DISABLE_COPY(QPlatformWindow)
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index f208eb02be..952023dd1b 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -106,9 +106,18 @@ void QScreenPrivate::setPlatformScreen(QPlatformScreen *screen)
*/
QScreen::~QScreen()
{
- if (!qApp)
+ // Remove screen
+ const bool wasPrimary = QGuiApplication::primaryScreen() == this;
+ QGuiApplicationPrivate::screen_list.removeOne(this);
+ QGuiApplicationPrivate::resetCachedDevicePixelRatio();
+
+ if (!qGuiApp)
return;
+ QScreen *newPrimaryScreen = QGuiApplication::primaryScreen();
+ if (wasPrimary && newPrimaryScreen)
+ emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
+
// Allow clients to manage windows that are affected by the screen going
// away, before we fall back to moving them to the primary screen.
emit qApp->screenRemoved(this);
@@ -116,11 +125,8 @@ QScreen::~QScreen()
if (QGuiApplication::closingDown())
return;
- QScreen *primaryScreen = QGuiApplication::primaryScreen();
- if (this == primaryScreen)
- return;
-
- bool movingFromVirtualSibling = primaryScreen && primaryScreen->handle()->virtualSiblings().contains(handle());
+ bool movingFromVirtualSibling = newPrimaryScreen
+ && newPrimaryScreen->handle()->virtualSiblings().contains(handle());
// Move any leftover windows to the primary screen
const auto allWindows = QGuiApplication::allWindows();
@@ -129,7 +135,7 @@ QScreen::~QScreen()
continue;
const bool wasVisible = window->isVisible();
- window->setScreen(primaryScreen);
+ window->setScreen(newPrimaryScreen);
// Re-show window if moved from a virtual sibling screen. Otherwise
// leave it up to the application developer to show the window.
diff --git a/src/gui/kernel/qsessionmanager_p.h b/src/gui/kernel/qsessionmanager_p.h
index 954443430e..d07d9b5eb8 100644
--- a/src/gui/kernel/qsessionmanager_p.h
+++ b/src/gui/kernel/qsessionmanager_p.h
@@ -69,7 +69,7 @@ public:
QSessionManagerPrivate(const QString &id,
const QString &key);
- virtual ~QSessionManagerPrivate();
+ ~QSessionManagerPrivate();
QPlatformSessionManager *platformSessionManager;
};
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index 3bb42c1c0b..0395c1db38 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -175,7 +175,7 @@ int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::Short
/*! \internal
Removes a shortcut from the global map.
- If \a owner is 0, all entries in the map with the key sequence specified
+ If \a owner is \nullptr, all entries in the map with the key sequence specified
is removed. If \a key is null, all sequences for \a owner is removed from
the map. If \a id is 0, any identical \a key sequences owned by \a owner
are removed.
@@ -222,7 +222,7 @@ int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key
/*! \internal
Changes the enable state of a shortcut to \a enable.
- If \a owner is 0, all entries in the map with the key sequence specified
+ If \a owner is \nullptr, all entries in the map with the key sequence specified
is removed. If \a key is null, all sequences for \a owner is removed from
the map. If \a id is 0, any identical \a key sequences owned by \a owner
are changed.
@@ -260,7 +260,7 @@ int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const
/*! \internal
Changes the auto repeat state of a shortcut to \a enable.
- If \a owner is 0, all entries in the map with the key sequence specified
+ If \a owner is \nullptr, all entries in the map with the key sequence specified
is removed. If \a key is null, all sequences for \a owner is removed from
the map. If \a id is 0, any identical \a key sequences owned by \a owner
are changed.
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
index f9e8a83a39..8638b05155 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -71,7 +71,7 @@ class QScreen;
class Q_GUI_EXPORT QBasicDrag : public QPlatformDrag, public QObject
{
public:
- virtual ~QBasicDrag();
+ ~QBasicDrag();
virtual Qt::DropAction drag(QDrag *drag) override;
void cancelDrag() override;
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 48060a2c37..9b5b7a6f1e 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -69,29 +69,17 @@ class QStyleHintsPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QStyleHints)
public:
- inline QStyleHintsPrivate()
- : m_mouseDoubleClickInterval(-1)
- , m_mousePressAndHoldInterval(-1)
- , m_startDragDistance(-1)
- , m_startDragTime(-1)
- , m_keyboardInputInterval(-1)
- , m_cursorFlashTime(-1)
- , m_tabFocusBehavior(-1)
- , m_uiEffects(-1)
- , m_wheelScrollLines(-1)
- , m_mouseQuickSelectionThreshold(-1)
- {}
-
- int m_mouseDoubleClickInterval;
- int m_mousePressAndHoldInterval;
- int m_startDragDistance;
- int m_startDragTime;
- int m_keyboardInputInterval;
- int m_cursorFlashTime;
- int m_tabFocusBehavior;
- int m_uiEffects;
- int m_wheelScrollLines;
- int m_mouseQuickSelectionThreshold;
+ int m_mouseDoubleClickInterval = -1;
+ int m_mousePressAndHoldInterval = -1;
+ int m_startDragDistance = -1;
+ int m_startDragTime = -1;
+ int m_keyboardInputInterval = -1;
+ int m_cursorFlashTime = -1;
+ int m_tabFocusBehavior = -1;
+ int m_uiEffects = -1;
+ int m_showShortcutsInContextMenus = -1;
+ int m_wheelScrollLines = -1;
+ int m_mouseQuickSelectionThreshold = -1;
};
/*!
@@ -371,10 +359,25 @@ bool QStyleHints::showIsMaximized() const
\since 5.10
\brief \c true if the platform normally shows shortcut key sequences in
context menus, otherwise \c false.
+
+ Since Qt 5.13, the setShowShortcutsInContextMenus() function can be used to
+ override the platform default.
*/
bool QStyleHints::showShortcutsInContextMenus() const
{
- return themeableHint(QPlatformTheme::ShowShortcutsInContextMenus, QPlatformIntegration::ShowShortcutsInContextMenus).toBool();
+ Q_D(const QStyleHints);
+ return d->m_showShortcutsInContextMenus >= 0
+ ? d->m_showShortcutsInContextMenus != 0
+ : themeableHint(QPlatformTheme::ShowShortcutsInContextMenus, QPlatformIntegration::ShowShortcutsInContextMenus).toBool();
+}
+
+void QStyleHints::setShowShortcutsInContextMenus(bool s)
+{
+ Q_D(QStyleHints);
+ if (s != showShortcutsInContextMenus()) {
+ d->m_showShortcutsInContextMenus = s ? 1 : 0;
+ emit showShortcutsInContextMenusChanged(s);
+ }
}
/*!
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index 7b0683e9b1..9091db9624 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -64,7 +64,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject
Q_PROPERTY(bool setFocusOnTouchRelease READ setFocusOnTouchRelease STORED false CONSTANT FINAL)
Q_PROPERTY(bool showIsFullScreen READ showIsFullScreen STORED false CONSTANT FINAL)
Q_PROPERTY(bool showIsMaximized READ showIsMaximized STORED false CONSTANT FINAL)
- Q_PROPERTY(bool showShortcutsInContextMenus READ showShortcutsInContextMenus STORED false CONSTANT FINAL)
+ Q_PROPERTY(bool showShortcutsInContextMenus READ showShortcutsInContextMenus WRITE setShowShortcutsInContextMenus NOTIFY showShortcutsInContextMenusChanged FINAL)
Q_PROPERTY(int startDragDistance READ startDragDistance NOTIFY startDragDistanceChanged FINAL)
Q_PROPERTY(int startDragTime READ startDragTime NOTIFY startDragTimeChanged FINAL)
Q_PROPERTY(int startDragVelocity READ startDragVelocity STORED false CONSTANT FINAL)
@@ -93,6 +93,7 @@ public:
bool showIsFullScreen() const;
bool showIsMaximized() const;
bool showShortcutsInContextMenus() const;
+ void setShowShortcutsInContextMenus(bool showShortcutsInContextMenus);
int passwordMaskDelay() const;
QChar passwordMaskCharacter() const;
qreal fontSmoothingGamma() const;
@@ -117,6 +118,7 @@ Q_SIGNALS:
void startDragTimeChanged(int startDragTime);
void tabFocusBehaviorChanged(Qt::TabFocusBehavior tabFocusBehavior);
void useHoverEffectsChanged(bool useHoverEffects);
+ void showShortcutsInContextMenusChanged(bool);
void wheelScrollLinesChanged(int scrollLines);
void mouseQuickSelectionThresholdChanged(int threshold);
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 453aa1ed83..590e2a85bb 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -166,7 +166,7 @@ QWindow::QWindow(QScreen *targetScreen)
static QWindow *nonDesktopParent(QWindow *parent)
{
if (parent && parent->type() == Qt::Desktop) {
- qWarning("QWindows can not be reparented into desktop windows");
+ qWarning("QWindows cannot be reparented into desktop windows");
return nullptr;
}
@@ -688,7 +688,8 @@ QWindow *QWindow::parent() const
Sets the \a parent Window. This will lead to the windowing system managing
the clip of the window, so it will be clipped to the \a parent window.
- Setting \a parent to be 0 will make the window become a top level window.
+ Setting \a parent to be \nullptr will make the window become a top level
+ window.
If \a parent is a window created by fromWinId(), then the current window
will be embedded inside \a parent, if the platform supports it.
@@ -1330,16 +1331,18 @@ Qt::WindowStates QWindow::windowStates() const
*/
/*!
- Sets the transient \a parent
+ \property QWindow::transientParent
+ \brief the window for which this window is a transient pop-up
+ \since 5.13
This is a hint to the window manager that this window is a dialog or pop-up
- on behalf of the given window.
+ on behalf of the transient parent.
In order to cause the window to be centered above its transient parent by
default, depending on the window manager, it may also be necessary to call
setFlags() with a suitable \l Qt::WindowType (such as \c Qt::Dialog).
- \sa transientParent(), parent()
+ \sa parent()
*/
void QWindow::setTransientParent(QWindow *parent)
{
@@ -1349,26 +1352,35 @@ void QWindow::setTransientParent(QWindow *parent)
return;
}
if (parent == this) {
- qWarning() << "transient parent" << parent << "can not be same as window";
+ qWarning() << "transient parent" << parent << "cannot be same as window";
return;
}
d->transientParent = parent;
QGuiApplicationPrivate::updateBlockedStatus(this);
+ emit transientParentChanged(parent);
}
-/*!
- Returns the transient parent of the window.
-
- \sa setTransientParent(), parent()
-*/
QWindow *QWindow::transientParent() const
{
Q_D(const QWindow);
return d->transientParent.data();
}
+/*
+ The setter for the QWindow::transientParent property.
+ The only reason this exists is to set the transientParentPropertySet flag
+ so that Qt Quick knows whether it was set programmatically (because of
+ Window declaration context) or because the user set the property.
+*/
+void QWindowPrivate::setTransientParent(QWindow *parent)
+{
+ Q_Q(QWindow);
+ q->setTransientParent(parent);
+ transientParentPropertySet = true;
+}
+
/*!
\enum QWindow::AncestorMode
diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h
index 439e62d0bd..1be3c845fe 100644
--- a/src/gui/kernel/qwindow.h
+++ b/src/gui/kernel/qwindow.h
@@ -123,6 +123,7 @@ class Q_GUI_EXPORT QWindow : public QObject, public QSurface
Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged REVISION 1)
Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation WRITE reportContentOrientationChange NOTIFY contentOrientationChanged)
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged REVISION 1)
+ Q_PRIVATE_PROPERTY(QWindow::d_func(), QWindow* transientParent MEMBER transientParent WRITE setTransientParent NOTIFY transientParentChanged REVISION 13)
public:
enum Visibility {
@@ -143,7 +144,7 @@ public:
explicit QWindow(QScreen *screen = nullptr);
explicit QWindow(QWindow *parent);
- virtual ~QWindow();
+ ~QWindow();
void setSurfaceType(SurfaceType surfaceType);
SurfaceType surfaceType() const override;
@@ -336,6 +337,8 @@ Q_SIGNALS:
Q_REVISION(1) void opacityChanged(qreal opacity);
+ Q_REVISION(13) void transientParentChanged(QWindow *transientParent);
+
protected:
virtual void exposeEvent(QExposeEvent *);
virtual void resizeEvent(QResizeEvent *);
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 5103d97c6d..b8fa77bef0 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -149,6 +149,7 @@ public:
void disconnectFromScreen();
void emitScreenChangedRecursion(QScreen *newScreen);
QScreen *screenForGeometry(const QRect &rect);
+ void setTransientParent(QWindow *parent);
virtual void clearFocusObject();
virtual QRectF closestAcceptableGeometry(const QRectF &rect) const;
@@ -199,6 +200,7 @@ public:
bool blockedByModalWindow;
bool updateRequestPending;
+ bool transientParentPropertySet = false;
QPointer<QWindow> transientParent;
QPointer<QScreen> topLevelScreen;
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index b0f2869128..759671fbd7 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -800,6 +800,8 @@ void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrima
else
QGuiApplicationPrivate::screen_list.append(screen);
+ QGuiApplicationPrivate::resetCachedDevicePixelRatio();
+
emit qGuiApp->screenAdded(screen);
if (isPrimary)
@@ -816,11 +818,6 @@ void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrima
*/
void QWindowSystemInterface::handleScreenRemoved(QPlatformScreen *platformScreen)
{
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED
- QGuiApplicationPrivate::platformIntegration()->removeScreen(platformScreen->screen());
-QT_WARNING_POP
-
// Important to keep this order since the QSceen doesn't own the platform screen
delete platformScreen->screen();
delete platformScreen;
@@ -840,7 +837,7 @@ void QWindowSystemInterface::handlePrimaryScreenChanged(QPlatformScreen *newPrim
if (indexOfScreen == 0)
return;
- QGuiApplicationPrivate::screen_list.swap(0, indexOfScreen);
+ QGuiApplicationPrivate::screen_list.swapItemsAt(0, indexOfScreen);
emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
}
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index cea02fb8b7..6c818a9030 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -508,7 +508,7 @@ public:
}
}
private:
- Q_DISABLE_COPY(WindowSystemEventList)
+ Q_DISABLE_COPY_MOVE(WindowSystemEventList)
};
static WindowSystemEventList windowSystemEventQueue;
diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp
index 987cbe7c12..2b1e57a4bb 100644
--- a/src/gui/opengl/qopengl.cpp
+++ b/src/gui/opengl/qopengl.cpp
@@ -54,8 +54,6 @@
#include <QtCore/QFile>
#include <QtCore/QDir>
-#include <set>
-
QT_BEGIN_NAMESPACE
#if defined(QT_OPENGL_3)
@@ -536,13 +534,4 @@ QOpenGLConfig::Gpu QOpenGLConfig::Gpu::fromContext()
return gpu;
}
-Q_GUI_EXPORT std::set<QByteArray> *qgpu_features(const QString &filename)
-{
- const QSet<QString> features = QOpenGLConfig::gpuFeatures(QOpenGLConfig::Gpu::fromContext(), filename);
- std::set<QByteArray> *result = new std::set<QByteArray>;
- for (const QString &feature : features)
- result->insert(feature.toUtf8());
- return result;
-}
-
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglcustomshaderstage_p.h b/src/gui/opengl/qopenglcustomshaderstage_p.h
index f4a71af88e..ce3e9efd23 100644
--- a/src/gui/opengl/qopenglcustomshaderstage_p.h
+++ b/src/gui/opengl/qopenglcustomshaderstage_p.h
@@ -80,7 +80,7 @@ protected:
private:
QOpenGLCustomShaderStagePrivate* d_ptr;
- Q_DISABLE_COPY(QOpenGLCustomShaderStage)
+ Q_DISABLE_COPY_MOVE(QOpenGLCustomShaderStage)
};
diff --git a/src/gui/opengl/qopenglext.h b/src/gui/opengl/qopenglext.h
index 856adb679e..63873476e4 100644
--- a/src/gui/opengl/qopenglext.h
+++ b/src/gui/opengl/qopenglext.h
@@ -468,9 +468,14 @@ GLAPI void APIENTRY glBlendEquation (GLenum mode);
#ifndef GL_VERSION_1_5
#define GL_VERSION_1_5 1
-#include <stddef.h>
-typedef ptrdiff_t GLsizeiptr;
-typedef ptrdiff_t GLintptr;
+#ifdef _WIN64
+typedef signed long long int GLsizeiptr;
+typedef signed long long int GLintptr;
+#else
+typedef signed long int GLsizeiptr;
+typedef signed long int GLintptr;
+#endif
+
#define GL_BUFFER_SIZE 0x8764
#define GL_BUFFER_USAGE 0x8765
#define GL_QUERY_COUNTER_BITS 0x8864
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index cae3d516c4..e7631b09ce 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -249,7 +249,7 @@ QOpenGLFramebufferObjectFormat::~QOpenGLFramebufferObjectFormat()
If the desired amount of samples per pixel is not supported by the hardware
then the maximum number of samples per pixel will be used. Note that
- multisample framebuffer objects can not be bound as textures. Also, the
+ multisample framebuffer objects cannot be bound as textures. Also, the
\c{GL_EXT_framebuffer_multisample} extension is required to create a
framebuffer with more than one sample per pixel.
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 92770cb55f..8ec814296a 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -206,7 +206,8 @@ QOpenGLFunctions::QOpenGLFunctions()
/*!
Constructs a function resolver for \a context. If \a context
- is null, then the resolver will be created for the current QOpenGLContext.
+ is \nullptr, then the resolver will be created for the current
+ QOpenGLContext.
The context or another context in the group must be current.
@@ -5035,8 +5036,8 @@ QOpenGLExtraFunctions::QOpenGLExtraFunctions()
}
/*!
- Constructs a function resolver for context. If \a context is null, then
- the resolver will be created for the current QOpenGLContext.
+ Constructs a function resolver for context. If \a context is \nullptr,
+ then the resolver will be created for the current QOpenGLContext.
The context or another context in the group must be current.
diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h
index 00287b0665..4554291bbd 100644
--- a/src/gui/opengl/qopenglfunctions.h
+++ b/src/gui/opengl/qopenglfunctions.h
@@ -228,26 +228,8 @@ struct QOpenGLFunctionsPrivate;
#undef glTexLevelParameteriv
#if defined(Q_CLANG_QDOC)
-#undef GLint
-typedef int GLint;
-#undef GLsizei
-typedef int GLsizei;
-#undef GLuint
-typedef unsigned int GLuint;
-#undef GLubyte
-typedef unsigned int GLubyte;
-#undef GLenum
-typedef unsigned int GLenum;
#undef GLbitfield
typedef unsigned int GLbitfield;
-#undef GLfloat
-typedef float GLfloat;
-#undef GLclampf
-typedef float GLclampf;
-#undef GLboolean
-typedef bool GLboolean;
-#undef GLvoid
-typedef void GLvoid;
#undef GLchar
typedef char GLchar;
#endif
diff --git a/src/gui/opengl/qopenglpaintdevice.h b/src/gui/opengl/qopenglpaintdevice.h
index 300002a9c1..54118f2926 100644
--- a/src/gui/opengl/qopenglpaintdevice.h
+++ b/src/gui/opengl/qopenglpaintdevice.h
@@ -59,7 +59,7 @@ public:
QOpenGLPaintDevice();
explicit QOpenGLPaintDevice(const QSize &size);
QOpenGLPaintDevice(int width, int height);
- virtual ~QOpenGLPaintDevice();
+ ~QOpenGLPaintDevice();
int devType() const override { return QInternal::OpenGL; }
QPaintEngine *paintEngine() const override;
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index 001cb839fa..042b9ebd79 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -1574,14 +1574,15 @@ void QOpenGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, c
case QImage::Format_Alpha8:
if (ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::TextureRGFormats)) {
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::AlphaImageSrc);
- bindOption = QOpenGLTextureUploader::UseRedFor8BitBindOption;
+ bindOption = QOpenGLTextureUploader::UseRedForAlphaAndLuminanceBindOption;
} else
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);
break;
case QImage::Format_Grayscale8:
+ case QImage::Format_Grayscale16:
if (ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::TextureRGFormats)) {
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::GrayscaleImageSrc);
- bindOption = QOpenGLTextureUploader::UseRedFor8BitBindOption;
+ bindOption = QOpenGLTextureUploader::UseRedForAlphaAndLuminanceBindOption;
} else
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);
break;
diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h
index 0541ce6168..15ac240b89 100644
--- a/src/gui/opengl/qopenglpaintengine_p.h
+++ b/src/gui/opengl/qopenglpaintengine_p.h
@@ -166,7 +166,7 @@ public:
bool shouldDrawCachedGlyphs(QFontEngine *, const QTransform &) const override;
private:
- Q_DISABLE_COPY(QOpenGL2PaintEngineEx)
+ Q_DISABLE_COPY_MOVE(QOpenGL2PaintEngineEx)
friend class QOpenGLEngineShaderManager;
};
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
index c39177080d..f225d5dc75 100644
--- a/src/gui/opengl/qopenglshaderprogram.cpp
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -3667,7 +3667,8 @@ QVector<float> QOpenGLShaderProgram::defaultInnerTessellationLevels() const
Language (GLSL) are supported on this system; false otherwise.
The \a context is used to resolve the GLSL extensions.
- If \a context is null, then QOpenGLContext::currentContext() is used.
+ If \a context is \nullptr, then QOpenGLContext::currentContext()
+ is used.
*/
bool QOpenGLShaderProgram::hasOpenGLShaderPrograms(QOpenGLContext *context)
{
@@ -3694,7 +3695,8 @@ void QOpenGLShaderProgram::shaderDestroyed()
this system; false otherwise.
The \a context is used to resolve the GLSL extensions.
- If \a context is null, then QOpenGLContext::currentContext() is used.
+ If \a context is \nullptr, then QOpenGLContext::currentContext()
+ is used.
*/
bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context)
{
diff --git a/src/gui/opengl/qopenglshaderprogram.h b/src/gui/opengl/qopenglshaderprogram.h
index 84eb8d6956..c79101fd4d 100644
--- a/src/gui/opengl/qopenglshaderprogram.h
+++ b/src/gui/opengl/qopenglshaderprogram.h
@@ -50,13 +50,6 @@
#include <QtGui/qvector4d.h>
#include <QtGui/qmatrix4x4.h>
-#if defined(Q_CLANG_QDOC)
-#undef GLint
-typedef int GLint;
-#undef GLfloat
-typedef double GLfloat;
-#endif
-
QT_BEGIN_NAMESPACE
@@ -80,7 +73,7 @@ public:
Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit)
explicit QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent = nullptr);
- virtual ~QOpenGLShader();
+ ~QOpenGLShader();
QOpenGLShader::ShaderType shaderType() const;
@@ -115,7 +108,7 @@ class Q_GUI_EXPORT QOpenGLShaderProgram : public QObject
Q_OBJECT
public:
explicit QOpenGLShaderProgram(QObject *parent = nullptr);
- virtual ~QOpenGLShaderProgram();
+ ~QOpenGLShaderProgram();
bool addShader(QOpenGLShader *shader);
void removeShader(QOpenGLShader *shader);
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index 5b7956d31e..e04a00e592 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -4114,7 +4114,7 @@ QOpenGLTexture::DepthStencilMode QOpenGLTexture::depthStencilMode() const
*/
-/*
+/*!
\since 5.5
Sets the texture comparison function on this texture to \a function. The texture
diff --git a/src/gui/opengl/qopengltextureuploader.cpp b/src/gui/opengl/qopengltextureuploader.cpp
index 03b5cb6eb5..b8b532b3d0 100644
--- a/src/gui/opengl/qopengltextureuploader.cpp
+++ b/src/gui/opengl/qopengltextureuploader.cpp
@@ -104,7 +104,7 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
const bool isOpenGLES3orBetter = context->isOpenGLES() && context->format().majorVersion() >= 3;
const bool sRgbBinding = (options & SRgbBindOption);
Q_ASSERT(isOpenGL12orBetter || context->isOpenGLES());
- Q_ASSERT((options & (SRgbBindOption | UseRedFor8BitBindOption)) != (SRgbBindOption | UseRedFor8BitBindOption));
+ Q_ASSERT((options & (SRgbBindOption | UseRedForAlphaAndLuminanceBindOption)) != (SRgbBindOption | UseRedForAlphaAndLuminanceBindOption));
switch (image.format()) {
case QImage::Format_RGB32:
@@ -208,7 +208,7 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
if (sRgbBinding) {
// Always needs conversion
break;
- } else if (options & UseRedFor8BitBindOption) {
+ } else if (options & UseRedForAlphaAndLuminanceBindOption) {
externalFormat = internalFormat = GL_RED;
pixelType = GL_UNSIGNED_BYTE;
targetFormat = image.format();
@@ -218,7 +218,7 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
if (sRgbBinding) {
// Always needs conversion
break;
- } else if (options & UseRedFor8BitBindOption) {
+ } else if (options & UseRedForAlphaAndLuminanceBindOption) {
externalFormat = internalFormat = GL_RED;
pixelType = GL_UNSIGNED_BYTE;
targetFormat = image.format();
@@ -238,7 +238,7 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
if (sRgbBinding) {
// Always needs conversion
break;
- } else if (options & UseRedFor8BitBindOption) {
+ } else if (options & UseRedForAlphaAndLuminanceBindOption) {
externalFormat = internalFormat = GL_RED;
pixelType = GL_UNSIGNED_BYTE;
targetFormat = image.format();
@@ -254,6 +254,26 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
targetFormat = image.format();
}
break;
+ case QImage::Format_Grayscale16:
+ if (sRgbBinding) {
+ // Always needs conversion
+ break;
+ } else if (options & UseRedForAlphaAndLuminanceBindOption) {
+ externalFormat = internalFormat = GL_RED;
+ pixelType = GL_UNSIGNED_SHORT;
+ targetFormat = image.format();
+ } else if (context->isOpenGLES() || context->format().profile() != QSurfaceFormat::CoreProfile) {
+ externalFormat = internalFormat = GL_LUMINANCE;
+ pixelType = GL_UNSIGNED_SHORT;
+ targetFormat = image.format();
+ } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
+ GLint swizzle[4] = { GL_RED, GL_RED, GL_RED, GL_ONE };
+ funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
+ externalFormat = internalFormat = GL_RED;
+ pixelType = GL_UNSIGNED_SHORT;
+ targetFormat = image.format();
+ }
+ break;
default:
break;
}
diff --git a/src/gui/opengl/qopengltextureuploader_p.h b/src/gui/opengl/qopengltextureuploader_p.h
index d758b3787b..0dcf709d7e 100644
--- a/src/gui/opengl/qopengltextureuploader_p.h
+++ b/src/gui/opengl/qopengltextureuploader_p.h
@@ -65,7 +65,7 @@ public:
enum BindOption {
NoBindOption = 0x0000,
PremultipliedAlphaBindOption = 0x0001,
- UseRedFor8BitBindOption = 0x0002,
+ UseRedForAlphaAndLuminanceBindOption = 0x0002,
SRgbBindOption = 0x0004,
PowerOfTwoBindOption = 0x0008
};
diff --git a/src/gui/opengl/qopenglversionfunctions.h b/src/gui/opengl/qopenglversionfunctions.h
index 3af1ed0466..f828e5668b 100644
--- a/src/gui/opengl/qopenglversionfunctions.h
+++ b/src/gui/opengl/qopenglversionfunctions.h
@@ -214,6 +214,7 @@ public:
virtual bool initializeOpenGLFunctions();
+ Q_DISABLE_COPY(QAbstractOpenGLFunctions)
Q_DECLARE_PRIVATE(QAbstractOpenGLFunctions)
protected:
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index d935deb4d6..3fab903c4d 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -208,7 +208,7 @@ static bool isRasterSurface(QWindow *window)
The \a window must either be the top level window represented by
this backingstore, or a non-transient child of that window. Passing
- \c nullptr falls back to using the backingstore's top level window.
+ \nullptr falls back to using the backingstore's top level window.
If the \a window is a child window, the \a region should be in child window
coordinates, and the \a offset should be the child window's offset in relation
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 2dd5144e40..348eceb47f 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -187,19 +187,11 @@ void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl,
#endif
if (const_alpha == 256) {
- if (w <= 64) {
- while (h--) {
- QT_MEMCPY_USHORT(dst, src, w);
- dst += dbpl;
- src += sbpl;
- }
- } else {
- int length = w << 1;
- while (h--) {
- memcpy(dst, src, length);
- dst += dbpl;
- src += sbpl;
- }
+ int length = w << 1;
+ while (h--) {
+ memcpy(dst, src, length);
+ dst += dbpl;
+ src += sbpl;
}
} else if (const_alpha != 0) {
quint16 *d = (quint16 *) dst;
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index bcc23fa683..ed575abf54 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -111,7 +111,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
QString key = QLatin1String("$qt-brush$")
% HexString<uint>(brushStyle)
% QLatin1Char(invert ? '1' : '0');
- if (!QPixmapCache::find(key, pm)) {
+ if (!QPixmapCache::find(key, &pm)) {
pm = QBitmap::fromData(QSize(8, 8), qt_patternForBrush(brushStyle, invert),
QImage::Format_MonoLSB);
QPixmapCache::insert(key, pm);
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index e5bac84df9..07202f5b1c 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -2500,6 +2500,15 @@ QColor QColor::fromHslF(qreal h, qreal s, qreal l, qreal a)
return color;
}
+/*!
+ \obsolete
+
+ Use the \c const overload instead.
+*/
+void QColor::getCmyk(int *c, int *m, int *y, int *k, int *a)
+{
+ const_cast<const QColor *>(this)->getCmyk(c, m, y, k, a);
+}
/*!
Sets the contents pointed to by \a c, \a m, \a y, \a k, and \a a, to the
@@ -2511,7 +2520,7 @@ QColor QColor::fromHslF(qreal h, qreal s, qreal l, qreal a)
\sa setCmyk(), {QColor#The CMYK Color Model}{The CMYK Color Model}
*/
-void QColor::getCmyk(int *c, int *m, int *y, int *k, int *a)
+void QColor::getCmyk(int *c, int *m, int *y, int *k, int *a) const
{
if (!c || !m || !y || !k)
return;
@@ -2531,6 +2540,16 @@ void QColor::getCmyk(int *c, int *m, int *y, int *k, int *a)
}
/*!
+ \obsolete
+
+ Use the \c const overload instead.
+*/
+void QColor::getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a)
+{
+ const_cast<const QColor *>(this)->getCmykF(c, m, y, k, a);
+}
+
+/*!
Sets the contents pointed to by \a c, \a m, \a y, \a k, and \a a, to the
cyan, magenta, yellow, black, and alpha-channel (transparency) components
of the color's CMYK value.
@@ -2540,7 +2559,7 @@ void QColor::getCmyk(int *c, int *m, int *y, int *k, int *a)
\sa setCmykF(), {QColor#The CMYK Color Model}{The CMYK Color Model}
*/
-void QColor::getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a)
+void QColor::getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a) const
{
if (!c || !m || !y || !k)
return;
@@ -2689,18 +2708,13 @@ QColor QColor::fromCmykF(qreal c, qreal m, qreal y, qreal k, qreal a)
recommend using the darker() function for this purpose. If the \a factor
is 0 or negative, the return value is unspecified.
- The function converts the current RGB color to HSV, multiplies the value
- (V) component by \a factor and converts the color back to RGB.
+ The function converts the current color to HSV, multiplies the value
+ (V) component by \a factor and converts the color back to it's original
+ color spec.
\sa darker(), isValid()
*/
-
-/*!
- \obsolete
-
- Use lighter(\a factor) instead.
-*/
-QColor QColor::light(int factor) const Q_DECL_NOTHROW
+QColor QColor::lighter(int factor) const Q_DECL_NOTHROW
{
if (factor <= 0) // invalid lightness factor
return *this;
@@ -2739,18 +2753,13 @@ QColor QColor::light(int factor) const Q_DECL_NOTHROW
but we recommend using the lighter() function for this purpose. If the
\a factor is 0 or negative, the return value is unspecified.
- The function converts the current RGB color to HSV, divides the value (V)
- component by \a factor and converts the color back to RGB.
+ The function converts the current color to HSV, divides the value (V)
+ component by \a factor and converts the color back to it's original
+ color spec.
\sa lighter(), isValid()
*/
-
-/*!
- \obsolete
-
- Use darker(\a factor) instead.
-*/
-QColor QColor::dark(int factor) const Q_DECL_NOTHROW
+QColor QColor::darker(int factor) const Q_DECL_NOTHROW
{
if (factor <= 0) // invalid darkness factor
return *this;
@@ -2764,6 +2773,28 @@ QColor QColor::dark(int factor) const Q_DECL_NOTHROW
return hsv.convertTo(cspec);
}
+#if QT_DEPRECATED_SINCE(5, 13)
+/*!
+ \obsolete
+
+ Use lighter(\a factor) instead.
+*/
+QColor QColor::light(int factor) const Q_DECL_NOTHROW
+{
+ return lighter(factor);
+}
+
+/*!
+ \obsolete
+
+ Use darker(\a factor) instead.
+*/
+QColor QColor::dark(int factor) const Q_DECL_NOTHROW
+{
+ return darker(factor);
+}
+#endif
+
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
/*!
Assigns a copy of \a color to this color, and returns a reference to it.
diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h
index f7a9e9db59..4822612cf8 100644
--- a/src/gui/painting/qcolor.h
+++ b/src/gui/painting/qcolor.h
@@ -172,10 +172,12 @@ public:
qreal yellowF() const Q_DECL_NOTHROW;
qreal blackF() const Q_DECL_NOTHROW;
- void getCmyk(int *c, int *m, int *y, int *k, int *a = nullptr);
+ void getCmyk(int *c, int *m, int *y, int *k, int *a = nullptr); // ### Qt 6: remove
+ void getCmyk(int *c, int *m, int *y, int *k, int *a = nullptr) const;
void setCmyk(int c, int m, int y, int k, int a = 255);
- void getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a = nullptr);
+ void getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a = nullptr); // ### Qt 6: remove
+ void getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a = nullptr) const;
void setCmykF(qreal c, qreal m, qreal y, qreal k, qreal a = 1.0);
int hslHue() const Q_DECL_NOTHROW; // 0 <= hue < 360
@@ -217,9 +219,13 @@ public:
static QColor fromHsl(int h, int s, int l, int a = 255);
static QColor fromHslF(qreal h, qreal s, qreal l, qreal a = 1.0);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QColor::lighter() instead")
Q_REQUIRED_RESULT QColor light(int f = 150) const Q_DECL_NOTHROW;
- Q_REQUIRED_RESULT QColor lighter(int f = 150) const Q_DECL_NOTHROW;
+ QT_DEPRECATED_X("Use QColor::darker() instead")
Q_REQUIRED_RESULT QColor dark(int f = 200) const Q_DECL_NOTHROW;
+#endif
+ Q_REQUIRED_RESULT QColor lighter(int f = 150) const Q_DECL_NOTHROW;
Q_REQUIRED_RESULT QColor darker(int f = 200) const Q_DECL_NOTHROW;
bool operator==(const QColor &c) const Q_DECL_NOTHROW;
@@ -306,12 +312,6 @@ inline QColor::QColor(const QColor &acolor) Q_DECL_NOTHROW
inline bool QColor::isValid() const Q_DECL_NOTHROW
{ return cspec != Invalid; }
-inline QColor QColor::lighter(int f) const Q_DECL_NOTHROW
-{ return light(f); }
-
-inline QColor QColor::darker(int f) const Q_DECL_NOTHROW
-{ return dark(f); }
-
QT_END_NAMESPACE
#endif // QCOLOR_H
diff --git a/src/gui/painting/qcompositionfunctions.cpp b/src/gui/painting/qcompositionfunctions.cpp
index 027bf23115..5c1afe8425 100644
--- a/src/gui/painting/qcompositionfunctions.cpp
+++ b/src/gui/painting/qcompositionfunctions.cpp
@@ -1107,7 +1107,7 @@ static inline uint multiply_op_rgb64(uint dst, uint src, uint da, uint sa)
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(uint *dest, int length, uint color, const T &coverage)
+static inline void comp_func_solid_Multiply_impl(uint *dest, int length, uint color, const T &coverage)
{
int sa = qAlpha(color);
int sr = qRed(color);
@@ -1130,7 +1130,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(uint *dest,
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+static inline void comp_func_solid_Multiply_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
{
uint sa = color.alpha();
uint sr = color.red();
@@ -1169,7 +1169,7 @@ void QT_FASTCALL comp_func_solid_Multiply_rgb64(QRgba64 *dest, int length, QRgba
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Multiply_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
uint d = dest[i];
@@ -1190,7 +1190,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(uint *Q_DECL_REST
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Multiply_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
QRgba64 d = dest[i];
@@ -1231,7 +1231,7 @@ void QT_FASTCALL comp_func_Multiply_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const Q
= Sca + Dca - Sca.Dca
*/
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Screen_impl(uint *dest, int length, uint color, const T &coverage)
+static inline void comp_func_solid_Screen_impl(uint *dest, int length, uint color, const T &coverage)
{
int sa = qAlpha(color);
int sr = qRed(color);
@@ -1254,7 +1254,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Screen_impl(uint *dest, i
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Screen_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+static inline void comp_func_solid_Screen_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
{
uint sa = color.alpha();
uint sr = color.red();
@@ -1293,7 +1293,7 @@ void QT_FASTCALL comp_func_solid_Screen_rgb64(QRgba64 *dest, int length, QRgba64
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Screen_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
uint d = dest[i];
@@ -1314,7 +1314,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(uint *Q_DECL_RESTRI
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Screen_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
QRgba64 d = dest[i];
@@ -1375,7 +1375,7 @@ static inline uint overlay_op_rgb64(uint dst, uint src, uint da, uint sa)
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(uint *dest, int length, uint color, const T &coverage)
+static inline void comp_func_solid_Overlay_impl(uint *dest, int length, uint color, const T &coverage)
{
int sa = qAlpha(color);
int sr = qRed(color);
@@ -1398,7 +1398,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(uint *dest,
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+static inline void comp_func_solid_Overlay_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
{
uint sa = color.alpha();
uint sr = color.red();
@@ -1437,7 +1437,7 @@ void QT_FASTCALL comp_func_solid_Overlay_rgb64(QRgba64 *dest, int length, QRgba6
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Overlay_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
uint d = dest[i];
@@ -1458,7 +1458,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(uint *Q_DECL_RESTR
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Overlay_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
QRgba64 d = dest[i];
@@ -1509,7 +1509,7 @@ static inline uint darken_op_rgb64(uint dst, uint src, uint da, uint sa)
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(uint *dest, int length, uint color, const T &coverage)
+static inline void comp_func_solid_Darken_impl(uint *dest, int length, uint color, const T &coverage)
{
int sa = qAlpha(color);
int sr = qRed(color);
@@ -1532,7 +1532,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(uint *dest, i
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+static inline void comp_func_solid_Darken_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
{
uint sa = color.alpha();
uint sr = color.red();
@@ -1571,7 +1571,7 @@ void QT_FASTCALL comp_func_solid_Darken_rgb64(QRgba64 *dest, int length, QRgba64
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Darken_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
uint d = dest[i];
@@ -1592,7 +1592,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(uint *Q_DECL_RESTRI
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Darken_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
QRgba64 d = dest[i];
@@ -1643,7 +1643,7 @@ static inline uint lighten_op_rgb64(uint dst, uint src, uint da, uint sa)
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(uint *dest, int length, uint color, const T &coverage)
+static inline void comp_func_solid_Lighten_impl(uint *dest, int length, uint color, const T &coverage)
{
int sa = qAlpha(color);
int sr = qRed(color);
@@ -1666,7 +1666,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(uint *dest,
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+static inline void comp_func_solid_Lighten_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
{
uint sa = color.alpha();
uint sr = color.red();
@@ -1705,7 +1705,7 @@ void QT_FASTCALL comp_func_solid_Lighten_rgb64(QRgba64 *dest, int length, QRgba6
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Lighten_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
uint d = dest[i];
@@ -1726,7 +1726,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(uint *Q_DECL_RESTR
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Lighten_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
QRgba64 d = dest[i];
@@ -1795,7 +1795,7 @@ static inline uint color_dodge_op_rgb64(qint64 dst, qint64 src, qint64 da, qint6
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(uint *dest, int length, uint color, const T &coverage)
+static inline void comp_func_solid_ColorDodge_impl(uint *dest, int length, uint color, const T &coverage)
{
int sa = qAlpha(color);
int sr = qRed(color);
@@ -1818,7 +1818,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(uint *des
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+static inline void comp_func_solid_ColorDodge_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
{
uint sa = color.alpha();
uint sr = color.red();
@@ -1857,7 +1857,7 @@ void QT_FASTCALL comp_func_solid_ColorDodge_rgb64(QRgba64 *dest, int length, QRg
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_ColorDodge_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
uint d = dest[i];
@@ -1878,7 +1878,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(uint *Q_DECL_RE
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_ColorDodge_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
QRgba64 d = dest[i];
@@ -1947,7 +1947,7 @@ static inline uint color_burn_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(uint *dest, int length, uint color, const T &coverage)
+static inline void comp_func_solid_ColorBurn_impl(uint *dest, int length, uint color, const T &coverage)
{
int sa = qAlpha(color);
int sr = qRed(color);
@@ -1970,7 +1970,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(uint *dest
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+static inline void comp_func_solid_ColorBurn_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
{
uint sa = color.alpha();
uint sr = color.red();
@@ -2009,7 +2009,7 @@ void QT_FASTCALL comp_func_solid_ColorBurn_rgb64(QRgba64 *dest, int length, QRgb
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_ColorBurn_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
uint d = dest[i];
@@ -2030,7 +2030,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(uint *Q_DECL_RES
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_ColorBurn_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
QRgba64 d = dest[i];
@@ -2093,7 +2093,7 @@ static inline uint hardlight_op_rgb64(uint dst, uint src, uint da, uint sa)
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(uint *dest, int length, uint color, const T &coverage)
+static inline void comp_func_solid_HardLight_impl(uint *dest, int length, uint color, const T &coverage)
{
int sa = qAlpha(color);
int sr = qRed(color);
@@ -2116,7 +2116,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(uint *dest
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+static inline void comp_func_solid_HardLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
{
uint sa = color.alpha();
uint sr = color.red();
@@ -2155,7 +2155,7 @@ void QT_FASTCALL comp_func_solid_HardLight_rgb64(QRgba64 *dest, int length, QRgb
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_HardLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
uint d = dest[i];
@@ -2176,7 +2176,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(uint *Q_DECL_RES
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_HardLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
QRgba64 d = dest[i];
@@ -2252,7 +2252,7 @@ static inline uint soft_light_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(uint *dest, int length, uint color, const T &coverage)
+static inline void comp_func_solid_SoftLight_impl(uint *dest, int length, uint color, const T &coverage)
{
int sa = qAlpha(color);
int sr = qRed(color);
@@ -2275,7 +2275,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(uint *dest
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+static inline void comp_func_solid_SoftLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
{
uint sa = color.alpha();
uint sr = color.red();
@@ -2314,7 +2314,7 @@ void QT_FASTCALL comp_func_solid_SoftLight_rgb64(QRgba64 *dest, int length, QRgb
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_SoftLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
uint d = dest[i];
@@ -2335,7 +2335,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(uint *Q_DECL_RES
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_SoftLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
QRgba64 d = dest[i];
@@ -2386,7 +2386,7 @@ static inline uint difference_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(uint *dest, int length, uint color, const T &coverage)
+static inline void comp_func_solid_Difference_impl(uint *dest, int length, uint color, const T &coverage)
{
int sa = qAlpha(color);
int sr = qRed(color);
@@ -2409,7 +2409,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(uint *des
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+static inline void comp_func_solid_Difference_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
{
uint sa = color.alpha();
uint sr = color.red();
@@ -2448,7 +2448,7 @@ void QT_FASTCALL comp_func_solid_Difference_rgb64(QRgba64 *dest, int length, QRg
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Difference_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
uint d = dest[i];
@@ -2469,7 +2469,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(uint *Q_DECL_RE
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Difference_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
QRgba64 d = dest[i];
@@ -2509,7 +2509,7 @@ void QT_FASTCALL comp_func_Difference_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const
Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
*/
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void QT_FASTCALL comp_func_solid_Exclusion_impl(uint *dest, int length, uint color, const T &coverage)
+static inline void QT_FASTCALL comp_func_solid_Exclusion_impl(uint *dest, int length, uint color, const T &coverage)
{
int sa = qAlpha(color);
int sr = qRed(color);
@@ -2532,7 +2532,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void QT_FASTCALL comp_func_solid_Exclusion_imp
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void QT_FASTCALL comp_func_solid_Exclusion_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
+static inline void QT_FASTCALL comp_func_solid_Exclusion_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
{
uint sa = color.alpha();
uint sr = color.red();
@@ -2572,7 +2572,7 @@ void QT_FASTCALL comp_func_solid_Exclusion_rgb64(QRgba64 *dest, int length, QRgb
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Exclusion_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
uint d = dest[i];
@@ -2593,7 +2593,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(uint *Q_DECL_RES
}
template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
+static inline void comp_func_Exclusion_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
{
for (int i = 0; i < length; ++i) {
QRgba64 d = dest[i];
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
index 436a62d486..0fb89a75b5 100644
--- a/src/gui/painting/qcosmeticstroker.cpp
+++ b/src/gui/painting/qcosmeticstroker.cpp
@@ -289,7 +289,7 @@ void QCosmeticStroker::setup()
drawCaps = state->lastPen.capStyle() != Qt::FlatCap;
if (strokeSelection & FastDraw) {
- color = multiplyAlpha256(state->penData.solid.color, opacity).toArgb32();
+ color = multiplyAlpha256(state->penData.solidColor, opacity).toArgb32();
QRasterBuffer *buffer = state->penData.rasterBuffer;
pixels = (uint *)buffer->buffer();
ppl = buffer->stride<quint32>();
diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h
index 7cac2ac358..28d5f6d6c5 100644
--- a/src/gui/painting/qdatabuffer_p.h
+++ b/src/gui/painting/qdatabuffer_p.h
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
template <typename Type> class QDataBuffer
{
- Q_DISABLE_COPY(QDataBuffer)
+ Q_DISABLE_COPY_MOVE(QDataBuffer)
public:
QDataBuffer(int res)
{
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index ca3590e280..2dd18f6dfc 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -55,6 +55,7 @@
#endif
#include <private/qguiapplication_p.h>
#include <private/qrgba64_p.h>
+#include <qendian.h>
#include <qloggingcategory.h>
#include <qmath.h>
@@ -856,6 +857,44 @@ static const QRgba64 *QT_FASTCALL fetchGrayscale8ToRGB64(QRgba64 *buffer, const
return buffer;
}
+static void QT_FASTCALL convertGrayscale16ToRGB32(uint *buffer, int count, const QVector<QRgb> *)
+{
+ for (int i = 0; i < count; ++i) {
+ const uint x = qt_div_257(buffer[i]);
+ buffer[i] = qRgb(x, x, x);
+ }
+}
+
+static const uint *QT_FASTCALL fetchGrayscale16ToRGB32(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ const unsigned short *s = reinterpret_cast<const unsigned short *>(src) + index;
+ for (int i = 0; i < count; ++i) {
+ const uint x = qt_div_257(s[i]);
+ buffer[i] = qRgb(x, x, x);
+ }
+ return buffer;
+}
+
+static const QRgba64 *QT_FASTCALL convertGrayscale16ToRGBA64(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ const unsigned short *s = reinterpret_cast<const unsigned short *>(src);
+ for (int i = 0; i < count; ++i)
+ buffer[i] = QRgba64::fromRgba64(s[i], s[i], s[i], 65535);
+ return buffer;
+}
+
+static const QRgba64 *QT_FASTCALL fetchGrayscale16ToRGBA64(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ const unsigned short *s = reinterpret_cast<const unsigned short *>(src) + index;
+ for (int i = 0; i < count; ++i) {
+ buffer[i] = QRgba64::fromRgba64(s[i], s[i], s[i], 65535);
+ }
+ return buffer;
+}
+
static void QT_FASTCALL storeARGB32FromARGB32PM(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
@@ -1047,18 +1086,8 @@ static const QRgba64 *QT_FASTCALL fetchRGB32ToRGB64(QRgba64 *buffer, const uchar
static const QRgba64 *QT_FASTCALL convertARGB32ToRGBA64PM(QRgba64 *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
-#ifdef __SSE2__
- qConvertARGB32PMToRGBA64PM_sse2<false, false>(buffer, src, count);
- for (int i = 0; i < count; ++i)
- buffer[i] = buffer[i].premultiplied();
-#elif defined(__ARM_NEON__)
- qConvertARGB32PMToRGBA64PM_neon<false, false>(buffer, src, count);
- for (int i = 0; i < count; ++i)
- buffer[i] = buffer[i].premultiplied();
-#else
for (int i = 0; i < count; ++i)
buffer[i] = QRgba64::fromArgb32(src[i]).premultiplied();
-#endif
return buffer;
}
@@ -1110,18 +1139,8 @@ static const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM(QRgba64 *buffer, const u
static const QRgba64 *QT_FASTCALL convertRGBA8888ToRGBA64PM(QRgba64 *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
-#ifdef __SSE2__
- qConvertARGB32PMToRGBA64PM_sse2<true, false>(buffer, src, count);
- for (int i = 0; i < count; ++i)
- buffer[i] = buffer[i].premultiplied();
-#elif defined(__ARM_NEON__)
- qConvertARGB32PMToRGBA64PM_neon<true, false>(buffer, src, count);
- for (int i = 0; i < count; ++i)
- buffer[i] = buffer[i].premultiplied();
-#else
for (int i = 0; i < count; ++i)
buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i])).premultiplied();
-#endif
return buffer;
}
@@ -1361,6 +1380,22 @@ static void QT_FASTCALL storeGrayscale8FromARGB32PM(uchar *dest, const uint *src
dest[index + i] = qGray(qUnpremultiply(src[i]));
}
+static void QT_FASTCALL storeGrayscale16FromRGB32(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ unsigned short *d = reinterpret_cast<unsigned short *>(dest) + index;
+ for (int i = 0; i < count; ++i)
+ d[i] = qGray(src[i]) * 257;
+}
+
+static void QT_FASTCALL storeGrayscale16FromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ unsigned short *d = reinterpret_cast<unsigned short *>(dest) + index;
+ for (int i = 0; i < count; ++i)
+ d[i] = qGray(qUnpremultiply(src[i])) * 257;
+}
+
static const uint *QT_FASTCALL fetchRGB64ToRGB32(uint *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
@@ -1487,7 +1522,11 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = {
{ true, true, QPixelLayout::BPP64, nullptr,
convertPassThrough, nullptr,
fetchRGB64ToRGB32, fetchPassThrough64,
- storeRGB64FromRGB32, storeRGB64FromRGB32 } // Format_RGBA64_Premultiplied
+ storeRGB64FromRGB32, storeRGB64FromRGB32 }, // Format_RGBA64_Premultiplied
+ { false, false, QPixelLayout::BPP16, nullptr,
+ convertGrayscale16ToRGB32, convertGrayscale16ToRGBA64,
+ fetchGrayscale16ToRGB32, fetchGrayscale16ToRGBA64,
+ storeGrayscale16FromARGB32PM, storeGrayscale16FromRGB32 } // Format_Grayscale16
};
Q_STATIC_ASSERT(sizeof(qPixelLayouts) / sizeof(*qPixelLayouts) == QImage::NImageFormats);
@@ -1563,6 +1602,16 @@ static void QT_FASTCALL storeRGBA64PMFromRGBA64PM(uchar *dest, const QRgba64 *sr
memcpy(d, src, count * sizeof(QRgba64));
}
+static void QT_FASTCALL storeGray16FromRGBA64PM(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ quint16 *d = reinterpret_cast<quint16*>(dest) + index;
+ for (int i = 0; i < count; ++i) {
+ QRgba64 s = src[i].unpremultiplied();
+ d[i] = qGray(s.red(), s.green(), s.blue());
+ }
+}
+
ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats] = {
nullptr,
nullptr,
@@ -1591,7 +1640,8 @@ ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats] = {
storeGenericFromRGBA64PM<QImage::Format_Grayscale8>,
storeRGBX64FromRGBA64PM,
storeRGBA64FromRGBA64PM,
- storeRGBA64PMFromRGBA64PM
+ storeRGBA64PMFromRGBA64PM,
+ storeGray16FromRGBA64PM
};
/*
@@ -1695,6 +1745,7 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] =
destFetch, // Format_RGBX64
destFetch, // Format_RGBA64
destFetch, // Format_RGBA64_Premultiplied
+ destFetch, // Format_Grayscale16
};
static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
@@ -1727,6 +1778,7 @@ static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
destFetchRGB64, // Format_RGBX64
destFetch64, // Format_RGBA64
destFetchRGB64, // Format_RGBA64_Premultiplied
+ destFetch64, // Format_Grayscale16
};
/*
@@ -1880,6 +1932,7 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] =
destStore, // Format_RGBX64
destStore, // Format_RGBA64
destStore, // Format_RGBA64_Premultiplied
+ destStore, // Format_Grayscale16
};
static DestStoreProc64 destStoreProc64[QImage::NImageFormats] =
@@ -1911,7 +1964,8 @@ static DestStoreProc64 destStoreProc64[QImage::NImageFormats] =
destStore64, // Format_Grayscale8
0, // Format_RGBX64
destStore64RGBA64, // Format_RGBA64
- 0 // Format_RGBA64_Premultiplied
+ 0, // Format_RGBA64_Premultiplied
+ destStore64, // Format_Grayscale16
};
/*
@@ -3838,6 +3892,7 @@ static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = {
fetchUntransformed, // RGBX64
fetchUntransformed, // RGBA64
fetchUntransformed, // RGBA64_Premultiplied
+ fetchUntransformed, // Grayscale16
};
static const SourceFetchProc sourceFetchGeneric[NBlendTypes] = {
@@ -4232,7 +4287,7 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
switch(data->type) {
case QSpanData::Solid:
- solidSource = data->solid.color.isOpaque();
+ solidSource = data->solidColor.isOpaque();
op.srcFetch = 0;
op.srcFetch64 = 0;
break;
@@ -4280,7 +4335,7 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
}
++spans;
}
- if (!alphaSpans) {
+ if (!alphaSpans && spanCount > 0) {
// If all spans are opaque we do not need to fetch dest.
// But don't clear passthrough destFetch as they are just as fast and save destStore.
if (op.destFetch != destFetchARGB32P)
@@ -4301,23 +4356,62 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
return op;
}
+static void spanfill_from_first(QRasterBuffer *rasterBuffer, QPixelLayout::BPP bpp, int x, int y, int length)
+{
+ switch (bpp) {
+ case QPixelLayout::BPP64: {
+ quint64 *dest = reinterpret_cast<quint64 *>(rasterBuffer->scanLine(y)) + x;
+ qt_memfill_template(dest + 1, dest[0], length - 1);
+ break;
+ }
+ case QPixelLayout::BPP32: {
+ quint32 *dest = reinterpret_cast<quint32 *>(rasterBuffer->scanLine(y)) + x;
+ qt_memfill_template(dest + 1, dest[0], length - 1);
+ break;
+ }
+ case QPixelLayout::BPP24: {
+ quint24 *dest = reinterpret_cast<quint24 *>(rasterBuffer->scanLine(y)) + x;
+ qt_memfill_template(dest + 1, dest[0], length - 1);
+ break;
+ }
+ case QPixelLayout::BPP16: {
+ quint16 *dest = reinterpret_cast<quint16 *>(rasterBuffer->scanLine(y)) + x;
+ qt_memfill_template(dest + 1, dest[0], length - 1);
+ break;
+ }
+ case QPixelLayout::BPP8: {
+ uchar *dest = rasterBuffer->scanLine(y) + x;
+ memset(dest + 1, dest[0], length - 1);
+ break;
+ }
+ default:
+ Q_UNREACHABLE();
+ }
+}
// -------------------- blend methods ---------------------
-#if !defined(Q_CC_SUN)
-static
-#endif
-void blend_color_generic(int count, const QSpan *spans, void *userData)
+static void blend_color_generic(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
uint buffer[BufferSize];
- Operator op = getOperator(data, spans, count);
- const uint color = data->solid.color.toArgb32();
+ Operator op = getOperator(data, nullptr, 0);
+ const uint color = data->solidColor.toArgb32();
+ bool solidFill = data->rasterBuffer->compositionMode == QPainter::CompositionMode_Source
+ || (data->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver && qAlpha(color) == 255);
+ QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
while (count--) {
int x = spans->x;
int length = spans->len;
+ if (solidFill && bpp >= QPixelLayout::BPP8 && spans->coverage == 255 && length) {
+ // If dest doesn't matter we don't need to bother with blending or converting all the identical pixels
+ op.destStore(data->rasterBuffer, x, spans->y, &color, 1);
+ spanfill_from_first(data->rasterBuffer, bpp, x, spans->y, length);
+ length = 0;
+ }
+
while (length) {
int l = qMin(BufferSize, length);
uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans->y, l);
@@ -4335,15 +4429,15 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- const Operator op = getOperator(data, spans, count);
- const uint color = data->solid.color.toArgb32();
+ const Operator op = getOperator(data, nullptr, 0);
+ const uint color = data->solidColor.toArgb32();
if (op.mode == QPainter::CompositionMode_Source) {
// inline for performance
while (count--) {
uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x;
if (spans->coverage == 255) {
- QT_MEMFILL_UINT(target, spans->len, color);
+ qt_memfill(target, color, spans->len);
} else {
uint c = BYTE_MUL(color, spans->coverage);
int ialpha = 255 - spans->coverage;
@@ -4365,29 +4459,26 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData)
void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- Operator op = getOperator(data, spans, count);
+ Operator op = getOperator(data, nullptr, 0);
if (!op.funcSolid64) {
qCDebug(lcQtGuiDrawHelper, "blend_color_generic_rgb64: unsupported 64bit blend attempted, falling back to 32-bit");
return blend_color_generic(count, spans, userData);
}
alignas(8) QRgba64 buffer[BufferSize];
- const QRgba64 color = data->solid.color;
+ const QRgba64 color = data->solidColor;
bool solidFill = data->rasterBuffer->compositionMode == QPainter::CompositionMode_Source
|| (data->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver && color.isOpaque());
- bool isBpp32 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP32;
+ QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp;
while (count--) {
int x = spans->x;
int length = spans->len;
- if (solidFill && isBpp32 && spans->coverage == 255) {
+ if (solidFill && bpp >= QPixelLayout::BPP8 && spans->coverage == 255 && length) {
// If dest doesn't matter we don't need to bother with blending or converting all the identical pixels
- if (length > 0) {
- op.destStore64(data->rasterBuffer, x, spans->y, &color, 1);
- uint *dest = (uint*)data->rasterBuffer->scanLine(spans->y) + x;
- qt_memfill32(dest + 1, dest[0], length - 1);
- length = 0;
- }
+ op.destStore64(data->rasterBuffer, x, spans->y, &color, 1);
+ spanfill_from_first(data->rasterBuffer, bpp, x, spans->y, length);
+ length = 0;
}
while (length) {
@@ -4413,16 +4504,16 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData)
from qt_gradient_quint16 with minimal overhead.
*/
QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
- if (mode == QPainter::CompositionMode_SourceOver && data->solid.color.isOpaque())
+ if (mode == QPainter::CompositionMode_SourceOver && data->solidColor.isOpaque())
mode = QPainter::CompositionMode_Source;
if (mode == QPainter::CompositionMode_Source) {
// inline for performance
- ushort c = data->solid.color.toRgb16();
+ ushort c = data->solidColor.toRgb16();
while (count--) {
ushort *target = ((ushort *)data->rasterBuffer->scanLine(spans->y)) + spans->x;
if (spans->coverage == 255) {
- QT_MEMFILL_USHORT(target, spans->len, c);
+ qt_memfill(target, c, spans->len);
} else {
ushort color = BYTE_MUL_RGB16(c, spans->coverage);
int ialpha = 255 - spans->coverage;
@@ -4439,7 +4530,7 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData)
if (mode == QPainter::CompositionMode_SourceOver) {
while (count--) {
- uint color = BYTE_MUL(data->solid.color.toArgb32(), spans->coverage);
+ uint color = BYTE_MUL(data->solidColor.toArgb32(), spans->coverage);
int ialpha = qAlpha(~color);
ushort c = qConvertRgb32To16(color);
ushort *target = ((ushort *)data->rasterBuffer->scanLine(spans->y)) + spans->x;
@@ -5216,6 +5307,7 @@ void qBlendTexture(int count, const QSpan *spans, void *userData)
case QImage::Format_RGBX64:
case QImage::Format_RGBA64:
case QImage::Format_RGBA64_Premultiplied:
+ case QImage::Format_Grayscale16:
proc = processTextureSpansGeneric64[blendType];
break;
case QImage::Format_Invalid:
@@ -5228,7 +5320,111 @@ void qBlendTexture(int count, const QSpan *spans, void *userData)
proc(count, spans, userData);
}
-template <class DST> Q_STATIC_TEMPLATE_FUNCTION
+static void blend_vertical_gradient_argb(int count, const QSpan *spans, void *userData)
+{
+ QSpanData *data = reinterpret_cast<QSpanData *>(userData);
+
+ LinearGradientValues linear;
+ getLinearGradientValues(&linear, data);
+
+ CompositionFunctionSolid funcSolid =
+ functionForModeSolid[data->rasterBuffer->compositionMode];
+
+ /*
+ The logic for vertical gradient calculations is a mathematically
+ reduced copy of that in fetchLinearGradient() - which is basically:
+
+ qreal ry = data->m22 * (y + 0.5) + data->dy;
+ qreal t = linear.dy*ry + linear.off;
+ t *= (GRADIENT_STOPTABLE_SIZE - 1);
+ quint32 color =
+ qt_gradient_pixel_fixed(&data->gradient,
+ int(t * FIXPT_SIZE));
+
+ This has then been converted to fixed point to improve performance.
+ */
+ const int gss = GRADIENT_STOPTABLE_SIZE - 1;
+ int yinc = int((linear.dy * data->m22 * gss) * FIXPT_SIZE);
+ int off = int((((linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss) * FIXPT_SIZE));
+
+ while (count--) {
+ int y = spans->y;
+ int x = spans->x;
+
+ quint32 *dst = (quint32 *)(data->rasterBuffer->scanLine(y)) + x;
+ quint32 color =
+ qt_gradient_pixel_fixed(&data->gradient, yinc * y + off);
+
+ funcSolid(dst, spans->len, color, spans->coverage);
+ ++spans;
+ }
+}
+
+template<ProcessSpans blend_color>
+static void blend_vertical_gradient(int count, const QSpan *spans, void *userData)
+{
+ QSpanData *data = reinterpret_cast<QSpanData *>(userData);
+
+ LinearGradientValues linear;
+ getLinearGradientValues(&linear, data);
+
+ // Based on the same logic as blend_vertical_gradient_argb.
+
+ const int gss = GRADIENT_STOPTABLE_SIZE - 1;
+ int yinc = int((linear.dy * data->m22 * gss) * FIXPT_SIZE);
+ int off = int((((linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss) * FIXPT_SIZE));
+
+ while (count--) {
+ int y = spans->y;
+
+ data->solidColor = qt_gradient_pixel64_fixed(&data->gradient, yinc * y + off);
+ blend_color(1, spans, userData);
+ ++spans;
+ }
+}
+
+void qBlendGradient(int count, const QSpan *spans, void *userData)
+{
+ QSpanData *data = reinterpret_cast<QSpanData *>(userData);
+ bool isVerticalGradient =
+ data->txop <= QTransform::TxScale &&
+ data->type == QSpanData::LinearGradient &&
+ data->gradient.linear.end.x == data->gradient.linear.origin.x;
+ switch (data->rasterBuffer->format) {
+ case QImage::Format_RGB16:
+ if (isVerticalGradient)
+ return blend_vertical_gradient<blend_color_rgb16>(count, spans, userData);
+ return blend_src_generic(count, spans, userData);
+ case QImage::Format_RGB32:
+ case QImage::Format_ARGB32_Premultiplied:
+ if (isVerticalGradient)
+ return blend_vertical_gradient_argb(count, spans, userData);
+ return blend_src_generic(count, spans, userData);
+#if defined(__SSE2__) || defined(__ARM_NEON__) || (Q_PROCESSOR_WORDSIZE == 8)
+ case QImage::Format_ARGB32:
+ case QImage::Format_RGBA8888:
+#endif
+ case QImage::Format_BGR30:
+ case QImage::Format_A2BGR30_Premultiplied:
+ case QImage::Format_RGB30:
+ case QImage::Format_A2RGB30_Premultiplied:
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied:
+ if (isVerticalGradient)
+ return blend_vertical_gradient<blend_color_generic_rgb64>(count, spans, userData);
+ return blend_src_generic_rgb64(count, spans, userData);
+ case QImage::Format_Invalid:
+ break;
+ default:
+ if (isVerticalGradient)
+ return blend_vertical_gradient<blend_color_generic>(count, spans, userData);
+ return blend_src_generic(count, spans, userData);
+ }
+ Q_UNREACHABLE();
+}
+
+template <class DST> static
inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer,
int x, int y, DST color,
const uchar *map,
@@ -5290,103 +5486,6 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer,
}
}
-static void qt_gradient_argb32(int count, const QSpan *spans, void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- bool isVerticalGradient =
- data->txop <= QTransform::TxScale &&
- data->type == QSpanData::LinearGradient &&
- data->gradient.linear.end.x == data->gradient.linear.origin.x;
-
- if (isVerticalGradient) {
- LinearGradientValues linear;
- getLinearGradientValues(&linear, data);
-
- CompositionFunctionSolid funcSolid =
- functionForModeSolid[data->rasterBuffer->compositionMode];
-
- /*
- The logic for vertical gradient calculations is a mathematically
- reduced copy of that in fetchLinearGradient() - which is basically:
-
- qreal ry = data->m22 * (y + 0.5) + data->dy;
- qreal t = linear.dy*ry + linear.off;
- t *= (GRADIENT_STOPTABLE_SIZE - 1);
- quint32 color =
- qt_gradient_pixel_fixed(&data->gradient,
- int(t * FIXPT_SIZE));
-
- This has then been converted to fixed point to improve performance.
- */
- const int gss = GRADIENT_STOPTABLE_SIZE - 1;
- int yinc = int((linear.dy * data->m22 * gss) * FIXPT_SIZE);
- int off = int((((linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss) * FIXPT_SIZE));
-
- while (count--) {
- int y = spans->y;
- int x = spans->x;
-
- quint32 *dst = (quint32 *)(data->rasterBuffer->scanLine(y)) + x;
- quint32 color =
- qt_gradient_pixel_fixed(&data->gradient, yinc * y + off);
-
- funcSolid(dst, spans->len, color, spans->coverage);
- ++spans;
- }
-
- } else {
- blend_src_generic(count, spans, userData);
- }
-}
-
-static void qt_gradient_quint16(int count, const QSpan *spans, void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- bool isVerticalGradient =
- data->txop <= QTransform::TxScale &&
- data->type == QSpanData::LinearGradient &&
- data->gradient.linear.end.x == data->gradient.linear.origin.x;
-
- if (isVerticalGradient) {
-
- LinearGradientValues linear;
- getLinearGradientValues(&linear, data);
-
- /*
- The logic for vertical gradient calculations is a mathematically
- reduced copy of that in fetchLinearGradient() - which is basically:
-
- qreal ry = data->m22 * (y + 0.5) + data->dy;
- qreal t = linear.dy*ry + linear.off;
- t *= (GRADIENT_STOPTABLE_SIZE - 1);
- quint32 color =
- qt_gradient_pixel_fixed(&data->gradient,
- int(t * FIXPT_SIZE));
-
- This has then been converted to fixed point to improve performance.
- */
- const int gss = GRADIENT_STOPTABLE_SIZE - 1;
- int yinc = int((linear.dy * data->m22 * gss) * FIXPT_SIZE);
- int off = int((((linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss) * FIXPT_SIZE));
-
- // Save the fillData since we overwrite it when setting solid.color.
- QGradientData gradient = data->gradient;
- while (count--) {
- int y = spans->y;
-
- data->solid.color = QRgba64::fromArgb32(qt_gradient_pixel_fixed(&gradient, yinc * y + off));
- blend_color_rgb16(1, spans, userData);
- ++spans;
- }
- data->gradient = gradient;
-
- } else {
- blend_src_generic(count, spans, userData);
- }
-}
-
inline static void qt_bitmapblit_argb32(QRasterBuffer *rasterBuffer,
int x, int y, const QRgba64 &color,
const uchar *map,
@@ -6007,29 +6106,25 @@ static void qt_rectfill_quint64(QRasterBuffer *rasterBuffer,
DrawHelper qDrawHelper[QImage::NImageFormats] =
{
// Format_Invalid,
- { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0 },
// Format_Mono,
{
blend_color_generic,
- blend_src_generic,
0, 0, 0, 0
},
// Format_MonoLSB,
{
blend_color_generic,
- blend_src_generic,
0, 0, 0, 0
},
// Format_Indexed8,
{
blend_color_generic,
- blend_src_generic,
0, 0, 0, 0
},
// Format_RGB32,
{
blend_color_argb,
- qt_gradient_argb32,
qt_bitmapblit_argb32,
qt_alphamapblit_argb32,
qt_alphargbblit_argb32,
@@ -6038,7 +6133,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_ARGB32,
{
blend_color_generic,
- blend_src_generic,
qt_bitmapblit_argb32,
qt_alphamapblit_argb32,
qt_alphargbblit_argb32,
@@ -6047,7 +6141,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_ARGB32_Premultiplied
{
blend_color_argb,
- qt_gradient_argb32,
qt_bitmapblit_argb32,
qt_alphamapblit_argb32,
qt_alphargbblit_argb32,
@@ -6056,7 +6149,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGB16
{
blend_color_rgb16,
- qt_gradient_quint16,
qt_bitmapblit_quint16,
qt_alphamapblit_quint16,
qt_alphargbblit_generic,
@@ -6065,7 +6157,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_ARGB8565_Premultiplied
{
blend_color_generic,
- blend_src_generic,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6074,7 +6165,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGB666
{
blend_color_generic,
- blend_src_generic,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6083,7 +6173,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_ARGB6666_Premultiplied
{
blend_color_generic,
- blend_src_generic,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6092,7 +6181,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGB555
{
blend_color_generic,
- blend_src_generic,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6101,7 +6189,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_ARGB8555_Premultiplied
{
blend_color_generic,
- blend_src_generic,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6110,7 +6197,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGB888
{
blend_color_generic,
- blend_src_generic,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6119,7 +6205,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGB444
{
blend_color_generic,
- blend_src_generic,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6128,7 +6213,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_ARGB4444_Premultiplied
{
blend_color_generic,
- blend_src_generic,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6137,7 +6221,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGBX8888
{
blend_color_generic,
- blend_src_generic,
qt_bitmapblit_rgba8888,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6146,7 +6229,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGBA8888
{
blend_color_generic,
- blend_src_generic,
qt_bitmapblit_rgba8888,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6155,7 +6237,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGB8888_Premultiplied
{
blend_color_generic,
- blend_src_generic,
qt_bitmapblit_rgba8888,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6164,7 +6245,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_BGR30
{
blend_color_generic_rgb64,
- blend_src_generic_rgb64,
qt_bitmapblit_rgb30<PixelOrderBGR>,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6173,7 +6253,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_A2BGR30_Premultiplied
{
blend_color_generic_rgb64,
- blend_src_generic_rgb64,
qt_bitmapblit_rgb30<PixelOrderBGR>,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6182,7 +6261,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGB30
{
blend_color_generic_rgb64,
- blend_src_generic_rgb64,
qt_bitmapblit_rgb30<PixelOrderRGB>,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6191,7 +6269,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_A2RGB30_Premultiplied
{
blend_color_generic_rgb64,
- blend_src_generic_rgb64,
qt_bitmapblit_rgb30<PixelOrderRGB>,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6200,7 +6277,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_Alpha8
{
blend_color_generic,
- blend_src_generic,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6209,7 +6285,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_Grayscale8
{
blend_color_generic,
- blend_src_generic,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6218,7 +6293,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGBX64
{
blend_color_generic_rgb64,
- blend_src_generic_rgb64,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6227,7 +6301,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGBA64
{
blend_color_generic_rgb64,
- blend_src_generic_rgb64,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
@@ -6236,82 +6309,98 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGBA64_Premultiplied
{
blend_color_generic_rgb64,
- blend_src_generic_rgb64,
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
qt_rectfill_quint64
},
+ // Format_Grayscale16
+ {
+ blend_color_generic_rgb64,
+ 0,
+ qt_alphamapblit_generic,
+ qt_alphargbblit_generic,
+ qt_rectfill_quint16
+ },
};
-#if defined(Q_CC_MSVC) && !defined(_MIPS_)
-template <class T>
-inline void qt_memfill_template(T *dest, T color, int count)
+#if !defined(__SSE2__)
+void qt_memfill64(quint64 *dest, quint64 color, qsizetype count)
{
- while (count--)
- *dest++ = color;
+ qt_memfill_template<quint64>(dest, color, count);
}
+#endif
-#else
-
-template <class T>
-inline void qt_memfill_template(T *dest, T color, int count)
+#if defined(QT_COMPILER_SUPPORTS_SSSE3) && defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG)
+__attribute__((optimize("no-tree-vectorize")))
+#endif
+void qt_memfill24(quint24 *dest, quint24 color, qsizetype count)
{
- int n = (count + 7) / 8;
- switch (count & 0x07)
- {
- case 0: do { *dest++ = color; Q_FALLTHROUGH();
- case 7: *dest++ = color; Q_FALLTHROUGH();
- case 6: *dest++ = color; Q_FALLTHROUGH();
- case 5: *dest++ = color; Q_FALLTHROUGH();
- case 4: *dest++ = color; Q_FALLTHROUGH();
- case 3: *dest++ = color; Q_FALLTHROUGH();
- case 2: *dest++ = color; Q_FALLTHROUGH();
- case 1: *dest++ = color;
- } while (--n > 0);
- }
-}
+# ifdef QT_COMPILER_SUPPORTS_SSSE3
+ extern void qt_memfill24_ssse3(quint24 *, quint24, qsizetype);
+ if (qCpuHasFeature(SSSE3))
+ return qt_memfill24_ssse3(dest, color, count);
+# endif
-template <>
-inline void qt_memfill_template(quint16 *dest, quint16 value, int count)
-{
- if (count < 3) {
- switch (count) {
- case 2: *dest++ = value; Q_FALLTHROUGH();
- case 1: *dest = value;
- }
+ const quint32 v = color;
+ quint24 *end = dest + count;
+
+ // prolog: align dest to 32bit
+ while ((quintptr(dest) & 0x3) && dest < end) {
+ *dest++ = v;
+ }
+ if (dest >= end)
return;
+
+ const uint val1 = qFromBigEndian((v << 8) | (v >> 16));
+ const uint val2 = qFromBigEndian((v << 16) | (v >> 8));
+ const uint val3 = qFromBigEndian((v << 24) | (v >> 0));
+
+ for ( ; dest <= (end - 4); dest += 4) {
+ quint32 *dst = reinterpret_cast<quint32 *>(dest);
+ dst[0] = val1;
+ dst[1] = val2;
+ dst[2] = val3;
}
- const int align = (quintptr)(dest) & 0x3;
- switch (align) {
- case 2: *dest++ = value; --count;
+ // less than 4px left
+ switch (end - dest) {
+ case 3:
+ *dest++ = v;
+ Q_FALLTHROUGH();
+ case 2:
+ *dest++ = v;
+ Q_FALLTHROUGH();
+ case 1:
+ *dest++ = v;
+ }
+}
+
+void qt_memfill16(quint16 *dest, quint16 value, qsizetype count)
+{
+ const int align = quintptr(dest) & 0x3;
+ if (align) {
+ *dest++ = value;
+ --count;
}
- const quint32 value32 = (value << 16) | value;
- qt_memfill(reinterpret_cast<quint32*>(dest), value32, count / 2);
if (count & 0x1)
dest[count - 1] = value;
-}
-#endif
-void qt_memfill64(quint64 *dest, quint64 color, int count)
-{
- qt_memfill_template<quint64>(dest, color, count);
+ const quint32 value32 = (value << 16) | value;
+ qt_memfill32(reinterpret_cast<quint32*>(dest), value32, count / 2);
}
-#if !defined(__SSE2__)
-void qt_memfill16(quint16 *dest, quint16 color, int count)
-{
- qt_memfill_template<quint16>(dest, color, count);
-}
-#endif
#if !defined(__SSE2__) && !defined(__ARM_NEON__) && !defined(__MIPS_DSP__)
-void qt_memfill32(quint32 *dest, quint32 color, int count)
+void qt_memfill32(quint32 *dest, quint32 color, qsizetype count)
{
qt_memfill_template<quint32>(dest, color, count);
}
#endif
+#ifdef __SSE2__
+decltype(qt_memfill32_sse2) *qt_memfill32 = nullptr;
+decltype(qt_memfill64_sse2) *qt_memfill64 = nullptr;
+#endif
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
template<QtPixelOrder> void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count, const QVector<QRgb> *, QDitherInfo *);
@@ -6325,6 +6414,10 @@ static void qInitDrawhelperFunctions()
qInitBlendFunctions();
#ifdef __SSE2__
+# ifndef __AVX2__
+ qt_memfill32 = qt_memfill32_sse2;
+ qt_memfill64 = qt_memfill64_sse2;
+# endif
qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
@@ -6401,6 +6494,14 @@ static void qInitDrawhelperFunctions()
const QVector<QRgb> *, QDitherInfo *);
extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_sse4(uint *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
+ extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_sse4(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
extern void QT_FASTCALL storeARGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
extern void QT_FASTCALL storeRGBA8888FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
@@ -6413,10 +6514,18 @@ static void qInitDrawhelperFunctions()
const QVector<QRgb> *, QDitherInfo *);
extern void QT_FASTCALL destStore64ARGB32_sse4(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length);
extern void QT_FASTCALL destStore64RGBA8888_sse4(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length);
+# ifndef __AVX2__
qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_sse4;
qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4;
qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_sse4;
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4;
+ qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_sse4;
+ qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_sse4;
+ qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4;
+ qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4;
+ qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4;
+ qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4;
+# endif
qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_sse4;
qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_sse4;
qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_sse4;
@@ -6431,6 +6540,8 @@ static void qInitDrawhelperFunctions()
#if defined(QT_COMPILER_SUPPORTS_AVX2)
if (qCpuHasFeature(ArchHaswell)) {
+ qt_memfill32 = qt_memfill32_avx2;
+ qt_memfill64 = qt_memfill64_avx2;
extern void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h, int const_alpha);
@@ -6470,6 +6581,26 @@ static void qInitDrawhelperFunctions()
bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2;
bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_avx2;
bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2;
+
+ extern void QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, int count, const QVector<QRgb> *);
+ extern void QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, int count, const QVector<QRgb> *);
+ extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_avx2(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_avx2(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_avx2;
+ qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_avx2;
+ qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_avx2;
+ qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2;
+
+ extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *, const uint *, int, const QVector<QRgb> *, QDitherInfo *);
+ extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_avx2(QRgba64 *, const uint *, int count, const QVector<QRgb> *, QDitherInfo *);
+ extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_avx2(QRgba64 *, const uchar *, int, int, const QVector<QRgb> *, QDitherInfo *);
+ extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_avx2(QRgba64 *, const uchar *, int, int, const QVector<QRgb> *, QDitherInfo *);
+ qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_avx2;
+ qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_avx2;
+ qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_avx2;
+ qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_avx2;
}
#endif
@@ -6505,6 +6636,14 @@ static void qInitDrawhelperFunctions()
const QVector<QRgb> *, QDitherInfo *);
extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
+ extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_neon(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_neon(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
extern void QT_FASTCALL storeARGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
extern void QT_FASTCALL storeRGBA8888FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
@@ -6514,10 +6653,16 @@ static void qInitDrawhelperFunctions()
qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_neon;
qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_neon;
qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_neon;
+ qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_neon;
+ qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_neon;
qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_neon;
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_neon;
qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_neon;
+ qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon;
+ qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon;
qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_neon;
+ qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon;
+ qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon;
#endif
#if defined(ENABLE_PIXMAN_DRAWHELPERS)
diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp
index ec6643deed..2b3cc9b226 100644
--- a/src/gui/painting/qdrawhelper_avx2.cpp
+++ b/src/gui/painting/qdrawhelper_avx2.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -38,6 +39,7 @@
****************************************************************************/
#include "qdrawhelper_p.h"
+#include "qdrawhelper_x86_p.h"
#include "qdrawingprimitive_sse2_p.h"
#include "qrgba64_p.h"
@@ -53,7 +55,8 @@ enum {
// Vectorized blend functions:
// See BYTE_MUL_SSE2 for details.
-inline static void BYTE_MUL_AVX2(__m256i &pixelVector, const __m256i &alphaChannel, const __m256i &colorMask, const __m256i &half)
+inline static void Q_DECL_VECTORCALL
+BYTE_MUL_AVX2(__m256i &pixelVector, __m256i alphaChannel, __m256i colorMask, __m256i half)
{
__m256i pixelVectorAG = _mm256_srli_epi16(pixelVector, 8);
__m256i pixelVectorRB = _mm256_and_si256(pixelVector, colorMask);
@@ -72,7 +75,8 @@ inline static void BYTE_MUL_AVX2(__m256i &pixelVector, const __m256i &alphaChann
pixelVector = _mm256_or_si256(pixelVectorAG, pixelVectorRB);
}
-inline static void BYTE_MUL_RGB64_AVX2(__m256i &pixelVector, const __m256i &alphaChannel, const __m256i &colorMask, const __m256i &half)
+inline static void Q_DECL_VECTORCALL
+BYTE_MUL_RGB64_AVX2(__m256i &pixelVector, __m256i alphaChannel, __m256i colorMask, __m256i half)
{
__m256i pixelVectorAG = _mm256_srli_epi32(pixelVector, 16);
__m256i pixelVectorRB = _mm256_and_si256(pixelVector, colorMask);
@@ -92,7 +96,8 @@ inline static void BYTE_MUL_RGB64_AVX2(__m256i &pixelVector, const __m256i &alph
}
// See INTERPOLATE_PIXEL_255_SSE2 for details.
-inline static void INTERPOLATE_PIXEL_255_AVX2(const __m256i &srcVector, __m256i &dstVector, const __m256i &alphaChannel, const __m256i &oneMinusAlphaChannel, const __m256i &colorMask, const __m256i &half)
+inline static void Q_DECL_VECTORCALL
+INTERPOLATE_PIXEL_255_AVX2(__m256i srcVector, __m256i &dstVector, __m256i alphaChannel, __m256i oneMinusAlphaChannel, __m256i colorMask, __m256i half)
{
const __m256i srcVectorAG = _mm256_srli_epi16(srcVector, 8);
const __m256i dstVectorAG = _mm256_srli_epi16(dstVector, 8);
@@ -114,7 +119,8 @@ inline static void INTERPOLATE_PIXEL_255_AVX2(const __m256i &srcVector, __m256i
dstVector = _mm256_or_si256(finalAG, finalRB);
}
-inline static void INTERPOLATE_PIXEL_RGB64_AVX2(const __m256i &srcVector, __m256i &dstVector, const __m256i &alphaChannel, const __m256i &oneMinusAlphaChannel, const __m256i &colorMask, const __m256i &half)
+inline static void Q_DECL_VECTORCALL
+INTERPOLATE_PIXEL_RGB64_AVX2(__m256i srcVector, __m256i &dstVector, __m256i alphaChannel, __m256i oneMinusAlphaChannel, __m256i colorMask, __m256i half)
{
const __m256i srcVectorAG = _mm256_srli_epi32(srcVector, 16);
const __m256i dstVectorAG = _mm256_srli_epi32(dstVector, 16);
@@ -138,7 +144,7 @@ inline static void INTERPOLATE_PIXEL_RGB64_AVX2(const __m256i &srcVector, __m256
// See BLEND_SOURCE_OVER_ARGB32_SSE2 for details.
-inline static void BLEND_SOURCE_OVER_ARGB32_AVX2(quint32 *dst, const quint32 *src, const int length)
+inline static void Q_DECL_VECTORCALL BLEND_SOURCE_OVER_ARGB32_AVX2(quint32 *dst, const quint32 *src, const int length)
{
const __m256i half = _mm256_set1_epi16(0x80);
const __m256i one = _mm256_set1_epi16(0xff);
@@ -209,7 +215,8 @@ inline static void BLEND_SOURCE_OVER_ARGB32_AVX2(quint32 *dst, const quint32 *sr
// See BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2 for details.
-inline static void BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(quint32 *dst, const quint32 *src, const int length, const int const_alpha)
+inline static void Q_DECL_VECTORCALL
+BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(quint32 *dst, const quint32 *src, const int length, const int const_alpha)
{
int x = 0;
@@ -316,6 +323,66 @@ void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels, int dbpl,
}
}
+static Q_NEVER_INLINE
+void Q_DECL_VECTORCALL qt_memfillXX_avx2(uchar *dest, __m256i value256, qsizetype bytes)
+{
+ __m128i value128 = _mm256_castsi256_si128(value256);
+
+ // main body
+ __m256i *dst256 = reinterpret_cast<__m256i *>(dest);
+ uchar *end = dest + bytes;
+ while (reinterpret_cast<uchar *>(dst256 + 4) <= end) {
+ _mm256_storeu_si256(dst256 + 0, value256);
+ _mm256_storeu_si256(dst256 + 1, value256);
+ _mm256_storeu_si256(dst256 + 2, value256);
+ _mm256_storeu_si256(dst256 + 3, value256);
+ dst256 += 4;
+ }
+
+ // first epilogue: fewer than 128 bytes / 32 entries
+ bytes = end - reinterpret_cast<uchar *>(dst256);
+ switch (bytes / sizeof(value256)) {
+ case 3: _mm256_storeu_si256(dst256++, value256); Q_FALLTHROUGH();
+ case 2: _mm256_storeu_si256(dst256++, value256); Q_FALLTHROUGH();
+ case 1: _mm256_storeu_si256(dst256++, value256);
+ }
+
+ // second epilogue: fewer than 32 bytes
+ __m128i *dst128 = reinterpret_cast<__m128i *>(dst256);
+ if (bytes & sizeof(value128))
+ _mm_storeu_si128(dst128++, value128);
+
+ // third epilogue: fewer than 16 bytes
+ if (bytes & 8)
+ _mm_storel_epi64(reinterpret_cast<__m128i *>(end - 8), value128);
+}
+
+void qt_memfill64_avx2(quint64 *dest, quint64 value, qsizetype count)
+{
+#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
+ // work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80820
+ __m128i value64 = _mm_set_epi64x(0, value); // _mm_cvtsi64_si128(value);
+# ifdef Q_PROCESSOR_X86_64
+ asm ("" : "+x" (value64));
+# endif
+ __m256i value256 = _mm256_broadcastq_epi64(value64);
+#else
+ __m256i value256 = _mm256_set1_epi64x(value);
+#endif
+
+ qt_memfillXX_avx2(reinterpret_cast<uchar *>(dest), value256, count * sizeof(quint64));
+}
+
+void qt_memfill32_avx2(quint32 *dest, quint32 value, qsizetype count)
+{
+ if (count % 2) {
+ // odd number of pixels, round to even
+ *dest++ = value;
+ --count;
+ }
+ qt_memfillXX_avx2(reinterpret_cast<uchar *>(dest), _mm256_set1_epi32(value), count * sizeof(quint32));
+}
+
void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha)
{
Q_ASSERT(const_alpha < 256);
@@ -928,6 +995,233 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint *
}
}
+static inline __m256i epilogueMaskFromCount(qsizetype count)
+{
+ Q_ASSERT(count > 0);
+ static const __m256i offsetMask = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
+ return _mm256_add_epi32(offsetMask, _mm256_set1_epi32(-count));
+}
+
+template<bool RGBA>
+static void convertARGBToARGB32PM_avx2(uint *buffer, const uint *src, qsizetype count)
+{
+ qsizetype i = 0;
+ const __m256i alphaMask = _mm256_set1_epi32(0xff000000);
+ const __m256i rgbaMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15));
+ const __m256i shuffleMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(6, 7, 6, 7, 6, 7, 6, 7, 14, 15, 14, 15, 14, 15, 14, 15));
+ const __m256i half = _mm256_set1_epi16(0x0080);
+ const __m256i zero = _mm256_setzero_si256();
+
+ for (; i < count - 7; i += 8) {
+ __m256i srcVector = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(src + i));
+ if (!_mm256_testz_si256(srcVector, alphaMask)) {
+ // keep the two _mm_test[zc]_siXXX next to each other
+ bool cf = _mm256_testc_si256(srcVector, alphaMask);
+ if (RGBA)
+ srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask);
+ if (!cf) {
+ __m256i src1 = _mm256_unpacklo_epi8(srcVector, zero);
+ __m256i src2 = _mm256_unpackhi_epi8(srcVector, zero);
+ __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask);
+ __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask);
+ src1 = _mm256_mullo_epi16(src1, alpha1);
+ src2 = _mm256_mullo_epi16(src2, alpha2);
+ src1 = _mm256_add_epi16(src1, _mm256_srli_epi16(src1, 8));
+ src2 = _mm256_add_epi16(src2, _mm256_srli_epi16(src2, 8));
+ src1 = _mm256_add_epi16(src1, half);
+ src2 = _mm256_add_epi16(src2, half);
+ src1 = _mm256_srli_epi16(src1, 8);
+ src2 = _mm256_srli_epi16(src2, 8);
+ src1 = _mm256_blend_epi16(src1, alpha1, 0x88);
+ src2 = _mm256_blend_epi16(src2, alpha2, 0x88);
+ srcVector = _mm256_packus_epi16(src1, src2);
+ _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), srcVector);
+ } else {
+ if (buffer != src || RGBA)
+ _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), srcVector);
+ }
+ } else {
+ _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), zero);
+ }
+ }
+
+ if (i < count) {
+ const __m256i epilogueMask = epilogueMaskFromCount(count - i);
+ __m256i srcVector = _mm256_maskload_epi32(reinterpret_cast<const int *>(src + i), epilogueMask);
+ const __m256i epilogueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, epilogueMask);
+
+ if (!_mm256_testz_si256(srcVector, epilogueAlphaMask)) {
+ // keep the two _mm_test[zc]_siXXX next to each other
+ bool cf = _mm256_testc_si256(srcVector, epilogueAlphaMask);
+ if (RGBA)
+ srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask);
+ if (!cf) {
+ __m256i src1 = _mm256_unpacklo_epi8(srcVector, zero);
+ __m256i src2 = _mm256_unpackhi_epi8(srcVector, zero);
+ __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask);
+ __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask);
+ src1 = _mm256_mullo_epi16(src1, alpha1);
+ src2 = _mm256_mullo_epi16(src2, alpha2);
+ src1 = _mm256_add_epi16(src1, _mm256_srli_epi16(src1, 8));
+ src2 = _mm256_add_epi16(src2, _mm256_srli_epi16(src2, 8));
+ src1 = _mm256_add_epi16(src1, half);
+ src2 = _mm256_add_epi16(src2, half);
+ src1 = _mm256_srli_epi16(src1, 8);
+ src2 = _mm256_srli_epi16(src2, 8);
+ src1 = _mm256_blend_epi16(src1, alpha1, 0x88);
+ src2 = _mm256_blend_epi16(src2, alpha2, 0x88);
+ srcVector = _mm256_packus_epi16(src1, src2);
+ _mm256_maskstore_epi32(reinterpret_cast<int *>(buffer + i), epilogueMask, srcVector);
+ } else {
+ if (buffer != src || RGBA)
+ _mm256_maskstore_epi32(reinterpret_cast<int *>(buffer + i), epilogueMask, srcVector);
+ }
+ } else {
+ _mm256_maskstore_epi32(reinterpret_cast<int *>(buffer + i), epilogueMask, zero);
+ }
+ }
+}
+
+void QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, int count, const QVector<QRgb> *)
+{
+ convertARGBToARGB32PM_avx2<false>(buffer, buffer, count);
+}
+
+void QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, int count, const QVector<QRgb> *)
+{
+ convertARGBToARGB32PM_avx2<true>(buffer, buffer, count);
+}
+
+const uint *QT_FASTCALL fetchARGB32ToARGB32PM_avx2(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToARGB32PM_avx2<false>(buffer, reinterpret_cast<const uint *>(src) + index, count);
+ return buffer;
+}
+
+const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_avx2(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToARGB32PM_avx2<true>(buffer, reinterpret_cast<const uint *>(src) + index, count);
+ return buffer;
+}
+
+template<bool RGBA>
+static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizetype count)
+{
+ qsizetype i = 0;
+ const __m256i alphaMask = _mm256_set1_epi32(0xff000000);
+ const __m256i rgbaMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15));
+ const __m256i shuffleMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(6, 7, 6, 7, 6, 7, 6, 7, 14, 15, 14, 15, 14, 15, 14, 15));
+ const __m256i zero = _mm256_setzero_si256();
+
+ for (; i < count - 7; i += 8) {
+ __m256i dst1, dst2;
+ __m256i srcVector = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(src + i));
+ if (!_mm256_testz_si256(srcVector, alphaMask)) {
+ // keep the two _mm_test[zc]_siXXX next to each other
+ bool cf = _mm256_testc_si256(srcVector, alphaMask);
+ if (!RGBA)
+ srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask);
+
+ // The two unpack instructions unpack the low and upper halves of
+ // each 128-bit half of the 256-bit register. Here's the tracking
+ // of what's where: (p is 32-bit, P is 64-bit)
+ // as loaded: [ p1, p2, p3, p4; p5, p6, p7, p8 ]
+ // after permute4x64 [ p1, p2, p5, p6; p3, p4, p7, p8 ]
+ // after unpacklo/hi [ P1, P2; P3, P4 ] [ P5, P6; P7, P8 ]
+ srcVector = _mm256_permute4x64_epi64(srcVector, _MM_SHUFFLE(3, 1, 2, 0));
+
+ const __m256i src1 = _mm256_unpacklo_epi8(srcVector, srcVector);
+ const __m256i src2 = _mm256_unpackhi_epi8(srcVector, srcVector);
+ if (!cf) {
+ const __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask);
+ const __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask);
+ dst1 = _mm256_mulhi_epu16(src1, alpha1);
+ dst2 = _mm256_mulhi_epu16(src2, alpha2);
+ dst1 = _mm256_add_epi16(dst1, _mm256_srli_epi16(dst1, 15));
+ dst2 = _mm256_add_epi16(dst2, _mm256_srli_epi16(dst2, 15));
+ dst1 = _mm256_blend_epi16(dst1, src1, 0x88);
+ dst2 = _mm256_blend_epi16(dst2, src2, 0x88);
+ } else {
+ dst1 = src1;
+ dst2 = src2;
+ }
+ } else {
+ dst1 = dst2 = zero;
+ }
+ _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), dst1);
+ _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i) + 1, dst2);
+ }
+
+ if (i < count) {
+ __m256i epilogueMask = epilogueMaskFromCount(count - i);
+ const __m256i epilogueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, epilogueMask);
+ __m256i dst1, dst2;
+ __m256i srcVector = _mm256_maskload_epi32(reinterpret_cast<const int *>(src + i), epilogueMask);
+
+ if (!_mm256_testz_si256(srcVector, epilogueAlphaMask)) {
+ // keep the two _mm_test[zc]_siXXX next to each other
+ bool cf = _mm256_testc_si256(srcVector, epilogueAlphaMask);
+ if (!RGBA)
+ srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask);
+ srcVector = _mm256_permute4x64_epi64(srcVector, _MM_SHUFFLE(3, 1, 2, 0));
+ const __m256i src1 = _mm256_unpacklo_epi8(srcVector, srcVector);
+ const __m256i src2 = _mm256_unpackhi_epi8(srcVector, srcVector);
+ if (!cf) {
+ const __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask);
+ const __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask);
+ dst1 = _mm256_mulhi_epu16(src1, alpha1);
+ dst2 = _mm256_mulhi_epu16(src2, alpha2);
+ dst1 = _mm256_add_epi16(dst1, _mm256_srli_epi16(dst1, 15));
+ dst2 = _mm256_add_epi16(dst2, _mm256_srli_epi16(dst2, 15));
+ dst1 = _mm256_blend_epi16(dst1, src1, 0x88);
+ dst2 = _mm256_blend_epi16(dst2, src2, 0x88);
+ } else {
+ dst1 = src1;
+ dst2 = src2;
+ }
+ } else {
+ dst1 = dst2 = zero;
+ }
+ epilogueMask = _mm256_permute4x64_epi64(epilogueMask, _MM_SHUFFLE(3, 1, 2, 0));
+ _mm256_maskstore_epi64(reinterpret_cast<qint64 *>(buffer + i),
+ _mm256_unpacklo_epi32(epilogueMask, epilogueMask),
+ dst1);
+ _mm256_maskstore_epi64(reinterpret_cast<qint64 *>(buffer + i + 4),
+ _mm256_unpackhi_epi32(epilogueMask, epilogueMask),
+ dst2);
+ }
+}
+
+const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToRGBA64PM_avx2<false>(buffer, src, count);
+ return buffer;
+}
+
+const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToRGBA64PM_avx2<true>(buffer, src, count);
+ return buffer;
+}
+
+const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_avx2(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToRGBA64PM_avx2<false>(buffer, reinterpret_cast<const uint *>(src) + index, count);
+ return buffer;
+}
+
+const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_avx2(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToRGBA64PM_avx2<true>(buffer, reinterpret_cast<const uint *>(src) + index, count);
+ return buffer;
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/gui/painting/qdrawhelper_mips_dsp.cpp b/src/gui/painting/qdrawhelper_mips_dsp.cpp
index e92a6606de..17597deb1d 100644
--- a/src/gui/painting/qdrawhelper_mips_dsp.cpp
+++ b/src/gui/painting/qdrawhelper_mips_dsp.cpp
@@ -43,7 +43,7 @@
QT_BEGIN_NAMESPACE
-void qt_memfill32(quint32 *dest, quint32 color, int count)
+void qt_memfill32(quint32 *dest, quint32 color, qsizetype count)
{
qt_memfill32_asm_mips_dsp(dest, color, count);
}
diff --git a/src/gui/painting/qdrawhelper_mips_dsp_p.h b/src/gui/painting/qdrawhelper_mips_dsp_p.h
index 36c4af2732..a3d0410274 100644
--- a/src/gui/painting/qdrawhelper_mips_dsp_p.h
+++ b/src/gui/painting/qdrawhelper_mips_dsp_p.h
@@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
#if defined(QT_COMPILER_SUPPORTS_MIPS_DSP)
-extern "C" void qt_memfill32_asm_mips_dsp(quint32 *dest, quint32 value, int count);
+extern "C" void qt_memfill32_asm_mips_dsp(quint32 *dest, quint32 value, qsizetype count);
extern "C" void comp_func_SourceOver_asm_mips_dsp(uint *dest, const uint *src, int length, uint const_alpha);
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index 3fbd651f96..8196a87b24 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -47,7 +47,7 @@
QT_BEGIN_NAMESPACE
-void qt_memfill32(quint32 *dest, quint32 value, int count)
+void qt_memfill32(quint32 *dest, quint32 value, qsizetype count)
{
const int epilogueSize = count % 16;
#if defined(Q_CC_GHS) || defined(Q_CC_MSVC)
@@ -802,7 +802,7 @@ void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer, int x, int
void QT_FASTCALL comp_func_solid_SourceOver_neon(uint *destPixels, int length, uint color, uint const_alpha)
{
if ((const_alpha & qAlpha(color)) == 255) {
- QT_MEMFILL_UINT(destPixels, length, color);
+ qt_memfill32(destPixels, color, length);
} else {
if (const_alpha != 255)
color = BYTE_MUL(color, const_alpha);
@@ -1160,6 +1160,72 @@ static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int
}
}
+template<bool RGBA>
+static inline void convertARGB32ToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count)
+{
+ if (count <= 0)
+ return;
+
+ const uint8x8_t shuffleMask = { 3, 3, 3, 3, 7, 7, 7, 7};
+ const uint64x2_t blendMask = vdupq_n_u64(Q_UINT64_C(0xffff000000000000));
+
+ int i = 0;
+ for (; i < count-3; i += 4) {
+ uint32x4_t vs32 = vld1q_u32(src + i);
+ uint32x4_t alphaVector = vshrq_n_u32(vs32, 24);
+#if defined(Q_PROCESSOR_ARM_64)
+ uint32_t alphaSum = vaddvq_u32(alphaVector);
+#else
+ // no vaddvq_u32
+ uint32x2_t tmp = vpadd_u32(vget_low_u32(alphaVector), vget_high_u32(alphaVector));
+ uint32_t alphaSum = vget_lane_u32(vpadd_u32(tmp, tmp), 0);
+#endif
+ if (alphaSum) {
+ if (!RGBA)
+ vs32 = vrgba2argb(vs32);
+ const uint8x16_t vs8 = vreinterpretq_u8_u32(vs32);
+ const uint8x16x2_t v = vzipq_u8(vs8, vs8);
+ if (alphaSum != 255 * 4) {
+ const uint8x8_t s1 = vreinterpret_u8_u32(vget_low_u32(vs32));
+ const uint8x8_t s2 = vreinterpret_u8_u32(vget_high_u32(vs32));
+ const uint8x8_t alpha1 = vtbl1_u8(s1, shuffleMask);
+ const uint8x8_t alpha2 = vtbl1_u8(s2, shuffleMask);
+ uint16x8_t src1 = vmull_u8(s1, alpha1);
+ uint16x8_t src2 = vmull_u8(s2, alpha2);
+ // convert from 0->(255x255) to 0->(255x257)
+ src1 = vsraq_n_u16(src1, src1, 7);
+ src2 = vsraq_n_u16(src2, src2, 7);
+
+ // now restore alpha from the trivial conversion
+ const uint64x2_t d1 = vbslq_u64(blendMask, vreinterpretq_u64_u8(v.val[0]), vreinterpretq_u64_u16(src1));
+ const uint64x2_t d2 = vbslq_u64(blendMask, vreinterpretq_u64_u8(v.val[1]), vreinterpretq_u64_u16(src2));
+
+ vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u64(d1));
+ buffer += 2;
+ vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u64(d2));
+ buffer += 2;
+ } else {
+ vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u8(v.val[0]));
+ buffer += 2;
+ vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u8(v.val[1]));
+ buffer += 2;
+ }
+ } else {
+ vst1q_u16((uint16_t *)buffer, vdupq_n_u16(0));
+ buffer += 2;
+ vst1q_u16((uint16_t *)buffer, vdupq_n_u16(0));
+ buffer += 2;
+ }
+ }
+
+ SIMD_EPILOGUE(i, count, 3) {
+ uint s = src[i];
+ if (RGBA)
+ s = RGBA2ARGB(s);
+ *buffer++ = QRgba64::fromArgb32(s).premultiplied();
+ }
+}
+
static inline float32x4_t reciprocal_mul_ps(float32x4_t a, float mul)
{
float32x4_t ia = vrecpeq_f32(a); // estimate 1/a
@@ -1269,6 +1335,34 @@ const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *
return buffer;
}
+const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGB32ToRGBA64PM_neon<false>(buffer, src, count);
+ return buffer;
+}
+
+const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGB32ToRGBA64PM_neon<true>(buffer, src, count);
+ return buffer;
+}
+
+const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_neon(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGB32ToRGBA64PM_neon<false>(buffer, reinterpret_cast<const uint *>(src) + index, count);
+ return buffer;
+}
+
+const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_neon(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGB32ToRGBA64PM_neon<true>(buffer, reinterpret_cast<const uint *>(src) + index, count);
+ return buffer;
+}
+
void QT_FASTCALL storeRGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h
index 40475a9bde..19e1f21a3b 100644
--- a/src/gui/painting/qdrawhelper_neon_p.h
+++ b/src/gui/painting/qdrawhelper_neon_p.h
@@ -123,7 +123,7 @@ void qt_transform_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl,
const QTransform &targetRectTransform,
int const_alpha);
-void qt_memfill32_neon(quint32 *dest, quint32 value, int count);
+void qt_memfill32_neon(quint32 *dest, quint32 value, qsizetype count);
void qt_memrotate90_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl);
void qt_memrotate270_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl);
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index fb08261205..37108949d6 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -69,14 +69,18 @@
QT_BEGIN_NAMESPACE
#if defined(Q_CC_GNU)
-# define Q_STATIC_TEMPLATE_FUNCTION static
# define Q_DECL_RESTRICT __restrict__
+# if defined(Q_PROCESSOR_X86_32) && defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
+# define Q_DECL_VECTORCALL __attribute__((sseregparm,regparm(3)))
+# else
+# define Q_DECL_VECTORCALL
+# endif
#elif defined(Q_CC_MSVC)
-# define Q_STATIC_TEMPLATE_FUNCTION static
# define Q_DECL_RESTRICT __restrict
+# define Q_DECL_VECTORCALL __vectorcall
#else
-# define Q_STATIC_TEMPLATE_FUNCTION static
# define Q_DECL_RESTRICT
+# define Q_DECL_VECTORCALL
#endif
static const uint AMASK = 0xff000000;
@@ -149,7 +153,6 @@ typedef void (*MemRotateFunc)(const uchar *srcPixels, int w, int h, int sbpl, uc
struct DrawHelper {
ProcessSpans blendColor;
- ProcessSpans blendGradient;
BitmapBlitFunc bitmapBlit;
AlphamapBlitFunc alphamapBlit;
AlphaRGBBlitFunc alphaRGBBlit;
@@ -162,10 +165,33 @@ extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::N
extern DrawHelper qDrawHelper[QImage::NImageFormats];
+struct quint24 {
+ quint24() = default;
+ quint24(uint value)
+ {
+ data[0] = uchar(value >> 16);
+ data[1] = uchar(value >> 8);
+ data[2] = uchar(value);
+ }
+ operator uint() const
+ {
+ return data[2] | (data[1] << 8) | (data[0] << 16);
+ }
+
+ uchar data[3];
+};
+
+void qBlendGradient(int count, const QSpan *spans, void *userData);
void qBlendTexture(int count, const QSpan *spans, void *userData);
-extern void qt_memfill64(quint64 *dest, quint64 value, int count);
-extern void qt_memfill32(quint32 *dest, quint32 value, int count);
-extern void qt_memfill16(quint16 *dest, quint16 value, int count);
+#ifdef __SSE2__
+extern void (*qt_memfill64)(quint64 *dest, quint64 value, qsizetype count);
+extern void (*qt_memfill32)(quint32 *dest, quint32 value, qsizetype count);
+#else
+extern void qt_memfill64(quint64 *dest, quint64 value, qsizetype count);
+extern void qt_memfill32(quint32 *dest, quint32 value, qsizetype count);
+#endif
+extern void qt_memfill24(quint24 *dest, quint24 value, qsizetype count);
+extern void qt_memfill16(quint16 *dest, quint16 value, qsizetype count);
typedef void (QT_FASTCALL *CompositionFunction)(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha);
typedef void (QT_FASTCALL *CompositionFunction64)(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha);
@@ -222,11 +248,6 @@ struct Operator
class QRasterPaintEngine;
-struct QSolidData
-{
- QRgba64 color;
-};
-
struct QLinearGradientData
{
struct {
@@ -331,8 +352,8 @@ struct QSpanData
int fast_matrix : 1;
bool bilinear;
QImage *tempImage;
+ QRgba64 solidColor;
union {
- QSolidData solid;
QGradientData gradient;
QTextureData texture;
};
@@ -858,6 +879,8 @@ static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16_32(uint x, uint a) {
// qt_div_255 is a fast rounded division by 255 using an approximation that is accurate for all positive 16-bit integers
static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
+static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_257_floor(uint x) { return (x - (x >> 8)) >> 8; }
+static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_257(uint x) { return qt_div_257_floor(x + 128); }
static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c)
@@ -868,76 +891,63 @@ static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c)
return a;
}
-struct quint24 {
- quint24() = default;
- quint24(uint value);
- operator uint() const;
- uchar data[3];
-};
-
-inline quint24::quint24(uint value)
+template <class T> inline void qt_memfill_template(T *dest, T color, qsizetype count)
{
- data[0] = uchar(value >> 16);
- data[1] = uchar(value >> 8);
- data[2] = uchar(value);
+ if (!count)
+ return;
+
+ qsizetype n = (count + 7) / 8;
+ switch (count & 0x07)
+ {
+ case 0: do { *dest++ = color; Q_FALLTHROUGH();
+ case 7: *dest++ = color; Q_FALLTHROUGH();
+ case 6: *dest++ = color; Q_FALLTHROUGH();
+ case 5: *dest++ = color; Q_FALLTHROUGH();
+ case 4: *dest++ = color; Q_FALLTHROUGH();
+ case 3: *dest++ = color; Q_FALLTHROUGH();
+ case 2: *dest++ = color; Q_FALLTHROUGH();
+ case 1: *dest++ = color;
+ } while (--n > 0);
+ }
}
-inline quint24::operator uint() const
+template <class T> inline void qt_memfill(T *dest, T value, qsizetype count)
{
- return data[2] | (data[1] << 8) | (data[0] << 16);
+ qt_memfill_template(dest, value, count);
}
-template <class T> Q_STATIC_TEMPLATE_FUNCTION
-void qt_memfill(T *dest, T value, int count);
-
-template<> inline void qt_memfill(quint64 *dest, quint64 color, int count)
+template<> inline void qt_memfill(quint64 *dest, quint64 color, qsizetype count)
{
qt_memfill64(dest, color, count);
}
-template<> inline void qt_memfill(quint32 *dest, quint32 color, int count)
+template<> inline void qt_memfill(quint32 *dest, quint32 color, qsizetype count)
{
qt_memfill32(dest, color, count);
}
-template<> inline void qt_memfill(quint16 *dest, quint16 color, int count)
+template<> inline void qt_memfill(quint24 *dest, quint24 color, qsizetype count)
{
- qt_memfill16(dest, color, count);
+ qt_memfill24(dest, color, count);
}
-template<> inline void qt_memfill(quint8 *dest, quint8 color, int count)
+template<> inline void qt_memfill(quint16 *dest, quint16 color, qsizetype count)
{
- memset(dest, color, count);
+ qt_memfill16(dest, color, count);
}
-template <class T>
-inline void qt_memfill(T *dest, T value, int count)
+template<> inline void qt_memfill(quint8 *dest, quint8 color, qsizetype count)
{
- if (!count)
- return;
-
- int n = (count + 7) / 8;
- switch (count & 0x07)
- {
- case 0: do { *dest++ = value; Q_FALLTHROUGH();
- case 7: *dest++ = value; Q_FALLTHROUGH();
- case 6: *dest++ = value; Q_FALLTHROUGH();
- case 5: *dest++ = value; Q_FALLTHROUGH();
- case 4: *dest++ = value; Q_FALLTHROUGH();
- case 3: *dest++ = value; Q_FALLTHROUGH();
- case 2: *dest++ = value; Q_FALLTHROUGH();
- case 1: *dest++ = value;
- } while (--n > 0);
- }
+ memset(dest, color, count);
}
-template <class T> Q_STATIC_TEMPLATE_FUNCTION
+template <class T> static
inline void qt_rectfill(T *dest, T value,
int x, int y, int width, int height, qsizetype stride)
{
char *d = reinterpret_cast<char*>(dest + x) + y * stride;
if (uint(stride) == (width * sizeof(T))) {
- qt_memfill(reinterpret_cast<T*>(d), value, width * height);
+ qt_memfill(reinterpret_cast<T*>(d), value, qsizetype(width) * height);
} else {
for (int j = 0; j < height; ++j) {
dest = reinterpret_cast<T*>(d);
@@ -947,52 +957,6 @@ inline void qt_rectfill(T *dest, T value,
}
}
-#define QT_MEMFILL_UINT(dest, length, color) \
- qt_memfill<quint32>(dest, color, length);
-
-#define QT_MEMFILL_USHORT(dest, length, color) \
- qt_memfill<quint16>(dest, color, length);
-
-#define QT_MEMCPY_REV_UINT(dest, src, length) \
-do { \
- /* Duff's device */ \
- uint *_d = (uint*)(dest) + length; \
- const uint *_s = (uint*)(src) + length; \
- int n = ((length) + 7) / 8; \
- switch ((length) & 0x07) \
- { \
- case 0: do { *--_d = *--_s; Q_FALLTHROUGH(); \
- case 7: *--_d = *--_s; Q_FALLTHROUGH(); \
- case 6: *--_d = *--_s; Q_FALLTHROUGH(); \
- case 5: *--_d = *--_s; Q_FALLTHROUGH(); \
- case 4: *--_d = *--_s; Q_FALLTHROUGH(); \
- case 3: *--_d = *--_s; Q_FALLTHROUGH(); \
- case 2: *--_d = *--_s; Q_FALLTHROUGH(); \
- case 1: *--_d = *--_s; \
- } while (--n > 0); \
- } \
-} while (false)
-
-#define QT_MEMCPY_USHORT(dest, src, length) \
-do { \
- /* Duff's device */ \
- ushort *_d = (ushort*)(dest); \
- const ushort *_s = (const ushort*)(src); \
- int n = ((length) + 7) / 8; \
- switch ((length) & 0x07) \
- { \
- case 0: do { *_d++ = *_s++; Q_FALLTHROUGH(); \
- case 7: *_d++ = *_s++; Q_FALLTHROUGH(); \
- case 6: *_d++ = *_s++; Q_FALLTHROUGH(); \
- case 5: *_d++ = *_s++; Q_FALLTHROUGH(); \
- case 4: *_d++ = *_s++; Q_FALLTHROUGH(); \
- case 3: *_d++ = *_s++; Q_FALLTHROUGH(); \
- case 2: *_d++ = *_s++; Q_FALLTHROUGH(); \
- case 1: *_d++ = *_s++; \
- } while (--n > 0); \
- } \
-} while (false)
-
inline ushort qConvertRgb32To16(uint c)
{
return (((c) >> 3) & 0x001f)
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index 3212ffdd2d..c82f41ec88 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -233,19 +233,71 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u
}
}
-void qt_memfill32(quint32 *dest, quint32 value, int count)
+#ifndef __AVX2__
+static Q_NEVER_INLINE
+void Q_DECL_VECTORCALL qt_memfillXX_aligned(void *dest, __m128i value128, quintptr bytecount)
{
- if (count < 7) {
+ __m128i *dst128 = reinterpret_cast<__m128i *>(dest);
+ __m128i *end128 = reinterpret_cast<__m128i *>(static_cast<uchar *>(dest) + bytecount);
+
+ while (dst128 + 4 <= end128) {
+ _mm_store_si128(dst128 + 0, value128);
+ _mm_store_si128(dst128 + 1, value128);
+ _mm_store_si128(dst128 + 2, value128);
+ _mm_store_si128(dst128 + 3, value128);
+ dst128 += 4;
+ }
+
+ bytecount %= 4 * sizeof(__m128i);
+ switch (bytecount / sizeof(__m128i)) {
+ case 3: _mm_store_si128(dst128++, value128); Q_FALLTHROUGH();
+ case 2: _mm_store_si128(dst128++, value128); Q_FALLTHROUGH();
+ case 1: _mm_store_si128(dst128++, value128);
+ }
+}
+
+void qt_memfill64_sse2(quint64 *dest, quint64 value, qsizetype count)
+{
+ quintptr misaligned = quintptr(dest) % sizeof(__m128i);
+ if (misaligned && count) {
+#if defined(Q_PROCESSOR_X86_32)
+ // Before SSE came out, the alignment of the stack used to be only 4
+ // bytes and some OS/ABIs (notably, code generated by MSVC) still only
+ // align to that. In any case, we cannot count on the alignment of
+ // quint64 to be 8 -- see QtPrivate::AlignOf_WorkaroundForI386Abi in
+ // qglobal.h.
+ //
+ // If the pointer is not aligned to at least 8 bytes, then we'll never
+ // in turn hit a multiple of 16 for the qt_memfillXX_aligned call
+ // below.
+ if (Q_UNLIKELY(misaligned % sizeof(quint64)))
+ return qt_memfill_template(dest, value, count);
+#endif
+
+ *dest++ = value;
+ --count;
+ }
+
+ if (count % 2) {
+ dest[count - 1] = value;
+ --count;
+ }
+
+ qt_memfillXX_aligned(dest, _mm_set1_epi64x(value), count * sizeof(quint64));
+}
+
+void qt_memfill32_sse2(quint32 *dest, quint32 value, qsizetype count)
+{
+ if (count < 4) {
+ // this simplifies the code below: the first switch can fall through
+ // without checking the value of count
switch (count) {
- case 6: *dest++ = value; Q_FALLTHROUGH();
- case 5: *dest++ = value; Q_FALLTHROUGH();
- case 4: *dest++ = value; Q_FALLTHROUGH();
case 3: *dest++ = value; Q_FALLTHROUGH();
case 2: *dest++ = value; Q_FALLTHROUGH();
case 1: *dest = value;
}
return;
- };
+ }
const int align = (quintptr)(dest) & 0xf;
switch (align) {
@@ -263,25 +315,9 @@ void qt_memfill32(quint32 *dest, quint32 value, int count)
}
}
- int count128 = count / 4;
- __m128i *dst128 = reinterpret_cast<__m128i*>(dest);
- __m128i *end128 = dst128 + count128;
- const __m128i value128 = _mm_set_epi32(value, value, value, value);
-
- while (dst128 + 3 < end128) {
- _mm_stream_si128(dst128 + 0, value128);
- _mm_stream_si128(dst128 + 1, value128);
- _mm_stream_si128(dst128 + 2, value128);
- _mm_stream_si128(dst128 + 3, value128);
- dst128 += 4;
- }
-
- switch (count128 & 0x3) {
- case 3: _mm_stream_si128(dst128++, value128); Q_FALLTHROUGH();
- case 2: _mm_stream_si128(dst128++, value128); Q_FALLTHROUGH();
- case 1: _mm_stream_si128(dst128++, value128);
- }
+ qt_memfillXX_aligned(dest, _mm_set1_epi32(value), count * sizeof(quint32));
}
+#endif // !__AVX2__
void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha)
{
@@ -314,28 +350,6 @@ void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, u
}
}
-void qt_memfill16(quint16 *dest, quint16 value, int count)
-{
- if (count < 3) {
- switch (count) {
- case 2: *dest++ = value; Q_FALLTHROUGH();
- case 1: *dest = value;
- }
- return;
- }
-
- const int align = (quintptr)(dest) & 0x3;
- switch (align) {
- case 2: *dest++ = value; --count;
- }
-
- const quint32 value32 = (value << 16) | value;
- qt_memfill32(reinterpret_cast<quint32*>(dest), value32, count / 2);
-
- if (count & 0x1)
- dest[count - 1] = value;
-}
-
void qt_bitmapblit32_sse2_base(QRasterBuffer *rasterBuffer, int x, int y,
quint32 color,
const uchar *src, int width, int height, int stride)
@@ -440,30 +454,30 @@ public:
union Vect_buffer_i { Int32x4 v; int i[4]; };
union Vect_buffer_f { Float32x4 v; float f[4]; };
- static inline Float32x4 v_dup(float x) { return _mm_set1_ps(x); }
- static inline Float32x4 v_dup(double x) { return _mm_set1_ps(x); }
- static inline Int32x4 v_dup(int x) { return _mm_set1_epi32(x); }
- static inline Int32x4 v_dup(uint x) { return _mm_set1_epi32(x); }
+ static inline Float32x4 Q_DECL_VECTORCALL v_dup(float x) { return _mm_set1_ps(x); }
+ static inline Float32x4 Q_DECL_VECTORCALL v_dup(double x) { return _mm_set1_ps(x); }
+ static inline Int32x4 Q_DECL_VECTORCALL v_dup(int x) { return _mm_set1_epi32(x); }
+ static inline Int32x4 Q_DECL_VECTORCALL v_dup(uint x) { return _mm_set1_epi32(x); }
- static inline Float32x4 v_add(Float32x4 a, Float32x4 b) { return _mm_add_ps(a, b); }
- static inline Int32x4 v_add(Int32x4 a, Int32x4 b) { return _mm_add_epi32(a, b); }
+ static inline Float32x4 Q_DECL_VECTORCALL v_add(Float32x4 a, Float32x4 b) { return _mm_add_ps(a, b); }
+ static inline Int32x4 Q_DECL_VECTORCALL v_add(Int32x4 a, Int32x4 b) { return _mm_add_epi32(a, b); }
- static inline Float32x4 v_max(Float32x4 a, Float32x4 b) { return _mm_max_ps(a, b); }
- static inline Float32x4 v_min(Float32x4 a, Float32x4 b) { return _mm_min_ps(a, b); }
- static inline Int32x4 v_min_16(Int32x4 a, Int32x4 b) { return _mm_min_epi16(a, b); }
+ static inline Float32x4 Q_DECL_VECTORCALL v_max(Float32x4 a, Float32x4 b) { return _mm_max_ps(a, b); }
+ static inline Float32x4 Q_DECL_VECTORCALL v_min(Float32x4 a, Float32x4 b) { return _mm_min_ps(a, b); }
+ static inline Int32x4 Q_DECL_VECTORCALL v_min_16(Int32x4 a, Int32x4 b) { return _mm_min_epi16(a, b); }
- static inline Int32x4 v_and(Int32x4 a, Int32x4 b) { return _mm_and_si128(a, b); }
+ static inline Int32x4 Q_DECL_VECTORCALL v_and(Int32x4 a, Int32x4 b) { return _mm_and_si128(a, b); }
- static inline Float32x4 v_sub(Float32x4 a, Float32x4 b) { return _mm_sub_ps(a, b); }
- static inline Int32x4 v_sub(Int32x4 a, Int32x4 b) { return _mm_sub_epi32(a, b); }
+ static inline Float32x4 Q_DECL_VECTORCALL v_sub(Float32x4 a, Float32x4 b) { return _mm_sub_ps(a, b); }
+ static inline Int32x4 Q_DECL_VECTORCALL v_sub(Int32x4 a, Int32x4 b) { return _mm_sub_epi32(a, b); }
- static inline Float32x4 v_mul(Float32x4 a, Float32x4 b) { return _mm_mul_ps(a, b); }
+ static inline Float32x4 Q_DECL_VECTORCALL v_mul(Float32x4 a, Float32x4 b) { return _mm_mul_ps(a, b); }
- static inline Float32x4 v_sqrt(Float32x4 x) { return _mm_sqrt_ps(x); }
+ static inline Float32x4 Q_DECL_VECTORCALL v_sqrt(Float32x4 x) { return _mm_sqrt_ps(x); }
- static inline Int32x4 v_toInt(Float32x4 x) { return _mm_cvttps_epi32(x); }
+ static inline Int32x4 Q_DECL_VECTORCALL v_toInt(Float32x4 x) { return _mm_cvttps_epi32(x); }
- static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return _mm_castps_si128(_mm_cmpgt_ps(a, b)); }
+ static inline Int32x4 Q_DECL_VECTORCALL v_greaterOrEqual(Float32x4 a, Float32x4 b) { return _mm_castps_si128(_mm_cmpgt_ps(a, b)); }
};
const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data,
diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp
index f6c2f11eaf..d9a687b1b4 100644
--- a/src/gui/painting/qdrawhelper_sse4.cpp
+++ b/src/gui/painting/qdrawhelper_sse4.cpp
@@ -45,6 +45,7 @@
QT_BEGIN_NAMESPACE
+#ifndef __AVX2__
template<bool RGBA>
static void convertARGBToARGB32PM_sse4(uint *buffer, const uint *src, int count)
{
@@ -94,7 +95,55 @@ static void convertARGBToARGB32PM_sse4(uint *buffer, const uint *src, int count)
}
}
-static inline __m128 reciprocal_mul_ps(__m128 a, float mul)
+template<bool RGBA>
+static void convertARGBToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int count)
+{
+ int i = 0;
+ const __m128i alphaMask = _mm_set1_epi32(0xff000000);
+ const __m128i rgbaMask = _mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15);
+ const __m128i shuffleMask = _mm_setr_epi8(6, 7, 6, 7, 6, 7, 6, 7, 14, 15, 14, 15, 14, 15, 14, 15);
+ const __m128i zero = _mm_setzero_si128();
+
+ for (; i < count - 3; i += 4) {
+ __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[i]);
+ if (!_mm_testz_si128(srcVector, alphaMask)) {
+ bool cf = _mm_testc_si128(srcVector, alphaMask);
+
+ if (!RGBA)
+ srcVector = _mm_shuffle_epi8(srcVector, rgbaMask);
+ const __m128i src1 = _mm_unpacklo_epi8(srcVector, srcVector);
+ const __m128i src2 = _mm_unpackhi_epi8(srcVector, srcVector);
+ if (!cf) {
+ __m128i alpha1 = _mm_shuffle_epi8(src1, shuffleMask);
+ __m128i alpha2 = _mm_shuffle_epi8(src2, shuffleMask);
+ __m128i dst1 = _mm_mulhi_epu16(src1, alpha1);
+ __m128i dst2 = _mm_mulhi_epu16(src2, alpha2);
+ // Map 0->0xfffe to 0->0xffff
+ dst1 = _mm_add_epi16(dst1, _mm_srli_epi16(dst1, 15));
+ dst2 = _mm_add_epi16(dst2, _mm_srli_epi16(dst2, 15));
+ // correct alpha value:
+ dst1 = _mm_blend_epi16(dst1, src1, 0x88);
+ dst2 = _mm_blend_epi16(dst2, src2, 0x88);
+ _mm_storeu_si128((__m128i *)&buffer[i], dst1);
+ _mm_storeu_si128((__m128i *)&buffer[i + 2], dst2);
+ } else {
+ _mm_storeu_si128((__m128i *)&buffer[i], src1);
+ _mm_storeu_si128((__m128i *)&buffer[i + 2], src2);
+ }
+ } else {
+ _mm_storeu_si128((__m128i *)&buffer[i], zero);
+ _mm_storeu_si128((__m128i *)&buffer[i + 2], zero);
+ }
+ }
+
+ SIMD_EPILOGUE(i, count, 3) {
+ const uint s = RGBA ? RGBA2ARGB(src[i]) : src[i];
+ buffer[i] = QRgba64::fromArgb32(s).premultiplied();
+ }
+}
+#endif // __AVX2__
+
+static inline __m128 Q_DECL_VECTORCALL reciprocal_mul_ps(__m128 a, float mul)
{
__m128 ia = _mm_rcp_ps(a); // Approximate 1/a
// Improve precision of ia using Newton-Raphson
@@ -259,6 +308,7 @@ static inline void convertARGBFromRGBA64PM_sse4(uint *buffer, const QRgba64 *src
}
}
+#ifndef __AVX2__
void QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, int count, const QVector<QRgb> *)
{
convertARGBToARGB32PM_sse4<false>(buffer, buffer, count);
@@ -269,6 +319,20 @@ void QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, int count, const Q
convertARGBToARGB32PM_sse4<true>(buffer, buffer, count);
}
+const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToRGBA64PM_sse4<false>(buffer, src, count);
+ return buffer;
+}
+
+const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToRGBA64PM_sse4<true>(buffer, src, count);
+ return buffer;
+}
+
const uint *QT_FASTCALL fetchARGB32ToARGB32PM_sse4(uint *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
@@ -283,6 +347,21 @@ const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_sse4(uint *buffer, const uchar *
return buffer;
}
+const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_sse4(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToRGBA64PM_sse4<false>(buffer, reinterpret_cast<const uint *>(src) + index, count);
+ return buffer;
+}
+
+const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToRGBA64PM_sse4<true>(buffer, reinterpret_cast<const uint *>(src) + index, count);
+ return buffer;
+}
+#endif // __AVX2__
+
void QT_FASTCALL storeRGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp
index 42d760d5cc..35d61c3e6c 100644
--- a/src/gui/painting/qdrawhelper_ssse3.cpp
+++ b/src/gui/painting/qdrawhelper_ssse3.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -79,55 +80,58 @@ QT_BEGIN_NAMESPACE
// The computation being done is:
// result = s + d * (1-alpha)
// with shortcuts if fully opaque or fully transparent.
-#define BLEND_SOURCE_OVER_ARGB32_SSSE3(dst, src, length, nullVector, half, one, colorMask, alphaMask) { \
- int x = 0; \
-\
- /* First, get dst aligned. */ \
- ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \
- blend_pixel(dst[x], src[x]); \
- } \
-\
- const int minusOffsetToAlignSrcOn16Bytes = (reinterpret_cast<quintptr>(&(src[x])) >> 2) & 0x3;\
-\
- if (!minusOffsetToAlignSrcOn16Bytes) {\
- /* src is aligned, usual algorithm but with aligned operations.\
- See the SSE2 version for more documentation on the algorithm itself. */\
- const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);\
- for (; x < length-3; x += 4) { \
- const __m128i srcVector = _mm_load_si128((const __m128i *)&src[x]); \
- const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \
- if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \
- _mm_store_si128((__m128i *)&dst[x], srcVector); \
- } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { \
- __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); \
- alphaChannel = _mm_sub_epi16(one, alphaChannel); \
- const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); \
- __m128i destMultipliedByOneMinusAlpha; \
- BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); \
- const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); \
- _mm_store_si128((__m128i *)&dst[x], result); \
- } \
- } /* end for() */\
- } else if ((length - x) >= 8) {\
- /* We use two vectors to extract the src: prevLoaded for the first pixels, lastLoaded for the current pixels. */\
- __m128i srcVectorPrevLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]);\
- const int palignrOffset = minusOffsetToAlignSrcOn16Bytes << 2;\
-\
- const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);\
- switch (palignrOffset) {\
- case 4:\
- BLENDING_LOOP(4, length)\
- break;\
- case 8:\
- BLENDING_LOOP(8, length)\
- break;\
- case 12:\
- BLENDING_LOOP(12, length)\
- break;\
- }\
- }\
- for (; x < length; ++x) \
- blend_pixel(dst[x], src[x]); \
+static inline void Q_DECL_VECTORCALL
+BLEND_SOURCE_OVER_ARGB32_SSSE3(quint32 *dst, const quint32 *src, int length,
+ __m128i nullVector, __m128i half, __m128i one, __m128i colorMask, __m128i alphaMask)
+{
+ int x = 0;
+
+ /* First, get dst aligned. */
+ ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) {
+ blend_pixel(dst[x], src[x]);
+ }
+
+ const int minusOffsetToAlignSrcOn16Bytes = (reinterpret_cast<quintptr>(&(src[x])) >> 2) & 0x3;
+
+ if (!minusOffsetToAlignSrcOn16Bytes) {
+ /* src is aligned, usual algorithm but with aligned operations.
+ See the SSE2 version for more documentation on the algorithm itself. */
+ const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);
+ for (; x < length-3; x += 4) {
+ const __m128i srcVector = _mm_load_si128((const __m128i *)&src[x]);
+ const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask);
+ if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) {
+ _mm_store_si128((__m128i *)&dst[x], srcVector);
+ } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) {
+ __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask);
+ alphaChannel = _mm_sub_epi16(one, alphaChannel);
+ const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]);
+ __m128i destMultipliedByOneMinusAlpha;
+ BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half);
+ const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha);
+ _mm_store_si128((__m128i *)&dst[x], result);
+ }
+ } /* end for() */
+ } else if ((length - x) >= 8) {
+ /* We use two vectors to extract the src: prevLoaded for the first pixels, lastLoaded for the current pixels. */
+ __m128i srcVectorPrevLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]);
+ const int palignrOffset = minusOffsetToAlignSrcOn16Bytes << 2;
+
+ const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);
+ switch (palignrOffset) {
+ case 4:
+ BLENDING_LOOP(4, length)
+ break;
+ case 8:
+ BLENDING_LOOP(8, length)
+ break;
+ case 12:
+ BLENDING_LOOP(12, length)
+ break;
+ }
+ }
+ for (; x < length; ++x)
+ blend_pixel(dst[x], src[x]);
}
void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl,
@@ -185,6 +189,71 @@ const uint * QT_FASTCALL qt_fetchUntransformed_888_ssse3(uint *buffer, const Ope
return buffer;
}
+void qt_memfill24_ssse3(quint24 *dest, quint24 color, qsizetype count)
+{
+ // LCM of 12 and 16 bytes is 48 bytes (16 px)
+ quint32 v = color;
+ __m128i m = _mm_cvtsi32_si128(v);
+ quint24 *end = dest + count;
+
+ constexpr uchar x = 2, y = 1, z = 0;
+ Q_DECL_ALIGN(__m128i) static const uchar
+ shuffleMask[16 + 1] = { x, y, z, x, y, z, x, y, z, x, y, z, x, y, z, x, y };
+
+ __m128i mval1 = _mm_shuffle_epi8(m, _mm_load_si128(reinterpret_cast<const __m128i *>(shuffleMask)));
+ __m128i mval2 = _mm_shuffle_epi8(m, _mm_loadu_si128(reinterpret_cast<const __m128i *>(shuffleMask + 1)));
+ __m128i mval3 = _mm_alignr_epi8(mval2, mval1, 2);
+
+ for ( ; dest + 16 <= end; dest += 16) {
+#ifdef __AVX__
+ // Store using 32-byte AVX instruction
+ __m256 mval12 = _mm256_castps128_ps256(_mm_castsi128_ps(mval1));
+ mval12 = _mm256_insertf128_ps(mval12, _mm_castsi128_ps(mval2), 1);
+ _mm256_storeu_ps(reinterpret_cast<float *>(dest), mval12);
+#else
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 0, mval1);
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 1, mval2);
+#endif
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 2, mval3);
+ }
+
+ if (count < 3) {
+ if (count > 1)
+ end[-2] = v;
+ if (count)
+ end[-1] = v;
+ return;
+ }
+
+ // less than 16px/48B left
+ uchar *ptr = reinterpret_cast<uchar *>(dest);
+ uchar *ptr_end = reinterpret_cast<uchar *>(end);
+ qptrdiff left = ptr_end - ptr;
+ if (left >= 24) {
+ // 8px/24B or more left
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(ptr) + 0, mval1);
+ _mm_storel_epi64(reinterpret_cast<__m128i *>(ptr) + 1, mval2);
+ ptr += 24;
+ left -= 24;
+ }
+
+ // less than 8px/24B left
+
+ if (left >= 16) {
+ // but more than 5px/15B left
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(ptr) , mval1);
+ } else if (left >= 8) {
+ // but more than 2px/6B left
+ _mm_storel_epi64(reinterpret_cast<__m128i *>(ptr), mval1);
+ }
+
+ if (left) {
+ // 1 or 2px left
+ // store 8 bytes ending with the right values (will overwrite a bit)
+ _mm_storel_epi64(reinterpret_cast<__m128i *>(ptr_end - 8), mval2);
+ }
+}
+
QT_END_NAMESPACE
#endif // QT_COMPILER_SUPPORTS_SSSE3
diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h
index cefc213999..5749d8c9fb 100644
--- a/src/gui/painting/qdrawhelper_x86_p.h
+++ b/src/gui/painting/qdrawhelper_x86_p.h
@@ -57,8 +57,8 @@
QT_BEGIN_NAMESPACE
#ifdef __SSE2__
-void qt_memfill32(quint32 *dest, quint32 value, int count);
-void qt_memfill16(quint16 *dest, quint16 value, int count);
+void qt_memfill64_sse2(quint64 *dest, quint64 value, qsizetype count);
+void qt_memfill32_sse2(quint32 *dest, quint32 value, qsizetype count);
void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y,
const QRgba64 &color,
const uchar *src, int width, int height, int stride);
@@ -79,6 +79,9 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
extern CompositionFunction qt_functionForMode_SSE2[];
extern CompositionFunctionSolid qt_functionForModeSolid_SSE2[];
+
+void qt_memfill64_avx2(quint64 *dest, quint64 value, qsizetype count);
+void qt_memfill32_avx2(quint32 *dest, quint32 value, qsizetype count);
#endif // __SSE2__
static const int numCompositionFunctions = 38;
diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h
index b237ea1611..cc8d230fa8 100644
--- a/src/gui/painting/qdrawingprimitive_sse2_p.h
+++ b/src/gui/painting/qdrawingprimitive_sse2_p.h
@@ -42,7 +42,7 @@
#include <QtGui/private/qtguiglobal_p.h>
#include <private/qsimd_p.h>
-#include "qdrawhelper_p.h"
+#include "qdrawhelper_x86_p.h"
#include "qrgba64_p.h"
#ifdef __SSE2__
@@ -232,7 +232,7 @@ QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
#if QT_COMPILER_SUPPORTS_HERE(SSE4_1)
QT_FUNCTION_TARGET(SSE2)
-Q_ALWAYS_INLINE void reciprocal_mul_ss(__m128 &ia, const __m128 a, float mul)
+Q_ALWAYS_INLINE void Q_DECL_VECTORCALL reciprocal_mul_ss(__m128 &ia, const __m128 a, float mul)
{
ia = _mm_rcp_ss(a); // Approximate 1/a
// Improve precision of ia using Newton-Raphson
diff --git a/src/gui/painting/qimagescale_sse4.cpp b/src/gui/painting/qimagescale_sse4.cpp
index 34d6b3882e..5861a2e2ff 100644
--- a/src/gui/painting/qimagescale_sse4.cpp
+++ b/src/gui/painting/qimagescale_sse4.cpp
@@ -39,6 +39,7 @@
#include "qimagescale_p.h"
#include "qimage.h"
+#include <private/qdrawhelper_x86_p.h>
#include <private/qsimd_p.h>
#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
@@ -47,7 +48,8 @@ QT_BEGIN_NAMESPACE
using namespace QImageScale;
-inline static __m128i qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, const __m128i vxyap, const __m128i vCxy)
+inline static __m128i Q_DECL_VECTORCALL
+qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, const __m128i vxyap, const __m128i vCxy)
{
__m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix));
__m128i vx = _mm_mullo_epi32(vpix, vxyap);
diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp
index 43aeff3268..9cb787fb2c 100644
--- a/src/gui/painting/qmemrotate.cpp
+++ b/src/gui/painting/qmemrotate.cpp
@@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE
static const int tileSize = 32;
template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
+static
inline void qt_memrotate90_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride)
{
sstride /= sizeof(T);
@@ -103,7 +103,7 @@ inline void qt_memrotate90_tiled(const T *src, int w, int h, int sstride, T *des
}
template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
+static
inline void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest,
int dstride)
{
@@ -131,7 +131,7 @@ inline void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int sstrid
}
template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
+static
inline void qt_memrotate270_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride)
{
sstride /= sizeof(T);
@@ -190,7 +190,7 @@ inline void qt_memrotate270_tiled(const T *src, int w, int h, int sstride, T *de
}
template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
+static
inline void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest,
int dstride)
{
@@ -219,7 +219,7 @@ inline void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int sstri
template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
+static
inline void qt_memrotate90_template(const T *src, int srcWidth, int srcHeight, int srcStride,
T *dest, int dstStride)
{
@@ -246,7 +246,7 @@ inline void qt_memrotate90_template<quint64>(const quint64 *src, int w, int h, i
}
template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
+static
inline void qt_memrotate180_template(const T *src, int w, int h, int sstride, T *dest, int dstride)
{
const char *s = (const char*)(src) + (h - 1) * sstride;
@@ -261,7 +261,7 @@ inline void qt_memrotate180_template(const T *src, int w, int h, int sstride, T
}
template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
+static
inline void qt_memrotate270_template(const T *src, int srcWidth, int srcHeight, int srcStride,
T *dest, int dstStride)
{
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 90b6d16551..d3404c6575 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -873,7 +873,7 @@ void QRasterPaintEngine::updateRasterState()
&& s->intOpacity == 256
&& (mode == QPainter::CompositionMode_Source
|| (mode == QPainter::CompositionMode_SourceOver
- && s->penData.solid.color.isOpaque()));
+ && s->penData.solidColor.isOpaque()));
}
s->dirty = 0;
@@ -1536,9 +1536,9 @@ static void fillRect_normalized(const QRect &r, QSpanData *data,
if (data->fillRect && (mode == QPainter::CompositionMode_Source
|| (mode == QPainter::CompositionMode_SourceOver
- && data->solid.color.isOpaque())))
+ && data->solidColor.isOpaque())))
{
- data->fillRect(data->rasterBuffer, x1, y1, width, height, data->solid.color);
+ data->fillRect(data->rasterBuffer, x1, y1, width, height, data->solidColor);
return;
}
}
@@ -1900,9 +1900,9 @@ void QRasterPaintEngine::fillRect(const QRectF &r, const QColor &color)
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
- d->solid_color_filler.solid.color = qPremultiply(combineAlpha256(color.rgba64(), s->intOpacity));
+ d->solid_color_filler.solidColor = qPremultiply(combineAlpha256(color.rgba64(), s->intOpacity));
- if (d->solid_color_filler.solid.color.isTransparent()
+ if (d->solid_color_filler.solidColor.isTransparent()
&& s->composition_mode == QPainter::CompositionMode_SourceOver) {
return;
}
@@ -2356,14 +2356,14 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
case QImage::Format_A2BGR30_Premultiplied:
case QImage::Format_A2RGB30_Premultiplied:
// Combine premultiplied color with the opacity set on the painter.
- d->solid_color_filler.solid.color = multiplyAlpha256(QRgba64::fromArgb32(color), s->intOpacity);
+ d->solid_color_filler.solidColor = multiplyAlpha256(QRgba64::fromArgb32(color), s->intOpacity);
break;
default:
- d->solid_color_filler.solid.color = qPremultiply(combineAlpha256(QRgba64::fromArgb32(color), s->intOpacity));
+ d->solid_color_filler.solidColor = qPremultiply(combineAlpha256(QRgba64::fromArgb32(color), s->intOpacity));
break;
}
- if (d->solid_color_filler.solid.color.isTransparent() && s->composition_mode == QPainter::CompositionMode_SourceOver)
+ if (d->solid_color_filler.solidColor.isTransparent() && s->composition_mode == QPainter::CompositionMode_SourceOver)
return;
d->solid_color_filler.clip = d->clip();
@@ -2713,20 +2713,20 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx
if (unclipped) {
if (depth == 1) {
if (s->penData.bitmapBlit) {
- s->penData.bitmapBlit(rb, rx, ry, s->penData.solid.color,
+ s->penData.bitmapBlit(rb, rx, ry, s->penData.solidColor,
scanline, w, h, bpl);
return;
}
} else if (depth == 8) {
if (s->penData.alphamapBlit) {
- s->penData.alphamapBlit(rb, rx, ry, s->penData.solid.color,
+ s->penData.alphamapBlit(rb, rx, ry, s->penData.solidColor,
scanline, w, h, bpl, 0, useGammaCorrection);
return;
}
} else if (depth == 32) {
// (A)RGB Alpha mask where the alpha component is not used.
if (s->penData.alphaRGBBlit) {
- s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solid.color,
+ s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solidColor,
(const uint *) scanline, w, h, bpl / 4, 0, useGammaCorrection);
return;
}
@@ -2755,10 +2755,10 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx
ry = ny;
}
if (depth == 8)
- s->penData.alphamapBlit(rb, rx, ry, s->penData.solid.color,
+ s->penData.alphamapBlit(rb, rx, ry, s->penData.solidColor,
scanline, w, h, bpl, clip, useGammaCorrection);
else if (depth == 32)
- s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solid.color,
+ s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solidColor,
(const uint *) scanline, w, h, bpl / 4, clip, useGammaCorrection);
return;
}
@@ -3436,7 +3436,7 @@ bool QRasterPaintEngine::requiresPretransformedGlyphPositions(QFontEngine *fontE
}
/*!
- Indicates whether glyph caching is supported by the font engine
+ Returns whether glyph caching is supported by the font engine
\a fontEngine with the given transform \a m applied.
*/
bool QRasterPaintEngine::shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &m) const
@@ -3835,7 +3835,6 @@ QImage::Format QRasterBuffer::prepare(QImage *image)
bytes_per_line = image->bytesPerLine();
format = image->format();
- drawHelper = qDrawHelper + format;
if (image->depth() == 1 && image->colorTable().size() == 2) {
monoDestinationWithClut = true;
const QVector<QRgb> colorTable = image->colorTable();
@@ -3883,51 +3882,15 @@ void QClipData::initialize()
Q_CHECK_PTR(m_clipLines);
QT_TRY {
- m_spans = (QSpan *)malloc(clipSpanHeight*sizeof(QSpan));
allocated = clipSpanHeight;
- Q_CHECK_PTR(m_spans);
-
QT_TRY {
- if (hasRectClip) {
- int y = 0;
- while (y < ymin) {
- m_clipLines[y].spans = 0;
- m_clipLines[y].count = 0;
- ++y;
- }
-
- const int len = clipRect.width();
- count = 0;
- while (y < ymax) {
- QSpan *span = m_spans + count;
- span->x = xmin;
- span->len = len;
- span->y = y;
- span->coverage = 255;
- ++count;
-
- m_clipLines[y].spans = span;
- m_clipLines[y].count = 1;
- ++y;
- }
-
- while (y < clipSpanHeight) {
- m_clipLines[y].spans = 0;
- m_clipLines[y].count = 0;
- ++y;
- }
- } else if (hasRegionClip) {
-
+ if (hasRegionClip) {
const auto rects = clipRegion.begin();
const int numRects = clipRegion.rectCount();
-
- { // resize
- const int maxSpans = (ymax - ymin) * numRects;
- if (maxSpans > allocated) {
- m_spans = q_check_ptr((QSpan *)realloc(m_spans, maxSpans * sizeof(QSpan)));
- allocated = maxSpans;
- }
- }
+ const int maxSpans = (ymax - ymin) * numRects;
+ allocated = qMax(allocated, maxSpans);
+ m_spans = (QSpan *)malloc(allocated * sizeof(QSpan));
+ Q_CHECK_PTR(m_spans);
int y = 0;
int firstInBand = 0;
@@ -3974,6 +3937,40 @@ void QClipData::initialize()
++y;
}
+ return;
+ }
+
+ m_spans = (QSpan *)malloc(allocated * sizeof(QSpan));
+ Q_CHECK_PTR(m_spans);
+
+ if (hasRectClip) {
+ int y = 0;
+ while (y < ymin) {
+ m_clipLines[y].spans = 0;
+ m_clipLines[y].count = 0;
+ ++y;
+ }
+
+ const int len = clipRect.width();
+ count = 0;
+ while (y < ymax) {
+ QSpan *span = m_spans + count;
+ span->x = xmin;
+ span->len = len;
+ span->y = y;
+ span->coverage = 255;
+ ++count;
+
+ m_clipLines[y].spans = span;
+ m_clipLines[y].count = 1;
+ ++y;
+ }
+
+ while (y < clipSpanHeight) {
+ m_clipLines[y].spans = 0;
+ m_clipLines[y].count = 0;
+ ++y;
+ }
}
} QT_CATCH(...) {
free(m_spans); // have to free m_spans again or someone might think that we were successfully initialized.
@@ -4596,8 +4593,8 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
case Qt::SolidPattern: {
type = Solid;
QColor c = qbrush_color(brush);
- solid.color = qPremultiply(combineAlpha256(c.rgba64(), alpha));
- if (solid.color.isTransparent() && compositionMode == QPainter::CompositionMode_SourceOver)
+ solidColor = qPremultiply(combineAlpha256(c.rgba64(), alpha));
+ if (solidColor.isTransparent() && compositionMode == QPainter::CompositionMode_SourceOver)
type = None;
break;
}
@@ -4723,17 +4720,19 @@ void QSpanData::adjustSpanMethods()
case None:
unclipped_blend = 0;
break;
- case Solid:
- unclipped_blend = rasterBuffer->drawHelper->blendColor;
- bitmapBlit = rasterBuffer->drawHelper->bitmapBlit;
- alphamapBlit = rasterBuffer->drawHelper->alphamapBlit;
- alphaRGBBlit = rasterBuffer->drawHelper->alphaRGBBlit;
- fillRect = rasterBuffer->drawHelper->fillRect;
+ case Solid: {
+ const DrawHelper &drawHelper = qDrawHelper[rasterBuffer->format];
+ unclipped_blend = drawHelper.blendColor;
+ bitmapBlit = drawHelper.bitmapBlit;
+ alphamapBlit = drawHelper.alphamapBlit;
+ alphaRGBBlit = drawHelper.alphaRGBBlit;
+ fillRect = drawHelper.fillRect;
break;
+ }
case LinearGradient:
case RadialGradient:
case ConicalGradient:
- unclipped_blend = rasterBuffer->drawHelper->blendGradient;
+ unclipped_blend = qBlendGradient;
break;
case Texture:
unclipped_blend = qBlendTexture;
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 14eddf07b1..881144d1c2 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -471,7 +471,6 @@ public:
QPainter::CompositionMode compositionMode;
QImage::Format format;
- DrawHelper *drawHelper;
QImage colorizeBitmap(const QImage &image, const QColor &color);
private:
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index f4cbf15fc7..22d3fb3001 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -439,6 +439,9 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
}
}
+ if (d->activeStroker == &d->stroker)
+ d->stroker.setForceOpen(path.hasExplicitOpen());
+
const QPainterPath::ElementType *types = path.elements();
const qreal *points = path.points();
int pointCount = path.elementCount();
@@ -1097,7 +1100,7 @@ bool QPaintEngineEx::shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTran
}(), 2);
qreal pixelSize = fontEngine->fontDef.pixelSize;
- return (pixelSize * pixelSize * qAbs(m.determinant())) < maxCachedGlyphSizeSquared;
+ return (pixelSize * pixelSize * qAbs(m.determinant())) <= maxCachedGlyphSizeSquared;
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index b70b29e54e..95e6bda78b 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1437,6 +1437,13 @@ void QPainterPrivate::updateState(QPainterState *newState)
by slightly less than half a pixel. Also will treat default constructed pens
as cosmetic. Potentially useful when porting a Qt 4 application to Qt 5.
+ \value LosslessImageRendering Use a lossless image rendering, whenever possible.
+ Currently, this hint is only used when QPainter is employed to output a PDF
+ file through QPrinter or QPdfWriter, where drawImage()/drawPixmap() calls
+ will encode images using a lossless compression algorithm instead of lossy
+ JPEG compression.
+ This value was added in Qt 5.13.
+
\sa renderHints(), setRenderHint(), {QPainter#Rendering
Quality}{Rendering Quality}, {Concentric Circles Example}
@@ -1514,7 +1521,7 @@ QPainter::~QPainter()
/*!
Returns the paint device on which this painter is currently
- painting, or 0 if the painter is not active.
+ painting, or \nullptr if the painter is not active.
\sa isActive()
*/
@@ -1540,6 +1547,7 @@ bool QPainter::isActive() const
return d->engine;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Initializes the painters pen, background and font to the same as
the given \a device.
@@ -1567,7 +1575,7 @@ void QPainter::initFrom(const QPaintDevice *device)
d->engine->setDirty(QPaintEngine::DirtyFont);
}
}
-
+#endif
/*!
Saves the current painter state (pushes the state onto a stack). A
@@ -2878,6 +2886,7 @@ void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
d->updateState(d->state);
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\since 4.2
\obsolete
@@ -2972,7 +2981,10 @@ void QPainter::setMatrix(const QMatrix &matrix, bool combine)
const QMatrix &QPainter::matrix() const
{
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
return worldMatrix();
+QT_WARNING_POP
}
@@ -3041,7 +3053,7 @@ void QPainter::resetMatrix()
{
resetTransform();
}
-
+#endif
/*!
\since 4.2
@@ -3092,6 +3104,7 @@ bool QPainter::worldMatrixEnabled() const
return d->state->WxF;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -3117,6 +3130,7 @@ bool QPainter::matrixEnabled() const
{
return worldMatrixEnabled();
}
+#endif
/*!
Scales the coordinate system by (\a{sx}, \a{sy}).
@@ -4175,6 +4189,7 @@ void QPainter::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius,
Draws the given rectangle \a x, \a y, \a w, \a h with rounded corners.
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -4202,6 +4217,10 @@ void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
Draws the rectangle \a r with rounded corners.
*/
+void QPainter::drawRoundRect(const QRect &rect, int xRnd, int yRnd)
+{
+ drawRoundedRect(QRectF(rect), xRnd, yRnd, Qt::RelativeSize);
+}
/*!
\obsolete
@@ -4212,6 +4231,11 @@ void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
Draws the rectangle \a x, \a y, \a w, \a h with rounded corners.
*/
+void QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd)
+{
+ drawRoundedRect(QRectF(x, y, w, h), xRnd, yRnd, Qt::RelativeSize);
+}
+#endif
/*!
\fn void QPainter::drawEllipse(const QRectF &rectangle)
@@ -6203,7 +6227,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
% HexString<qreal>(pen.widthF());
QPixmap pixmap;
- if (QPixmapCache::find(key, pixmap))
+ if (QPixmapCache::find(key, &pixmap))
return pixmap;
const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio
@@ -7371,6 +7395,7 @@ void QPainter::setViewTransformEnabled(bool enable)
d->updateMatrix();
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\threadsafe
@@ -7451,6 +7476,7 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
Q_UNUSED(offset)
return 0;
}
+#endif
void qt_format_text(const QFont &fnt, const QRectF &_r,
int tf, const QString& str, QRectF *brect,
@@ -8060,6 +8086,7 @@ QFont QPaintEngineState::font() const
return static_cast<const QPainterState *>(this)->font;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\since 4.2
\obsolete
@@ -8082,6 +8109,7 @@ QMatrix QPaintEngineState::matrix() const
return st->matrix.toAffine();
}
+#endif
/*!
\since 4.3
@@ -8321,7 +8349,7 @@ void QPainter::resetTransform()
d->state->ww = d->state->vw = d->device->metric(QPaintDevice::PdmWidth);
d->state->wh = d->state->vh = d->device->metric(QPaintDevice::PdmHeight);
d->state->worldMatrix = QTransform();
- setMatrixEnabled(false);
+ setWorldMatrixEnabled(false);
setViewTransformEnabled(false);
if (d->extended)
d->extended->transformChanged();
diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
index 482f5fb63d..843f24e3e1 100644
--- a/src/gui/painting/qpainter.h
+++ b/src/gui/painting/qpainter.h
@@ -91,7 +91,8 @@ public:
SmoothPixmapTransform = 0x04,
HighQualityAntialiasing = 0x08,
NonCosmeticDefaultPen = 0x10,
- Qt4CompatiblePainting = 0x20
+ Qt4CompatiblePainting = 0x20,
+ LosslessImageRendering = 0x40,
};
Q_FLAG(RenderHint)
@@ -131,7 +132,10 @@ public:
bool end();
bool isActive() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use begin(QPaintDevice*) instead")
void initFrom(const QPaintDevice *device);
+#endif
enum CompositionMode {
CompositionMode_SourceOver,
@@ -231,28 +235,40 @@ public:
void restore();
// XForm functions
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use setTransform() instead")
void setMatrix(const QMatrix &matrix, bool combine = false);
+ QT_DEPRECATED_X("Use transform() instead")
const QMatrix &matrix() const;
+ QT_DEPRECATED_X("Use deviceTransform() instead")
const QMatrix &deviceMatrix() const;
+ QT_DEPRECATED_X("Use resetTransform() instead")
void resetMatrix();
+#endif
void setTransform(const QTransform &transform, bool combine = false);
const QTransform &transform() const;
const QTransform &deviceTransform() const;
void resetTransform();
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use setWorldTransform() instead")
void setWorldMatrix(const QMatrix &matrix, bool combine = false);
+ QT_DEPRECATED_X("Use worldTransform() instead")
const QMatrix &worldMatrix() const;
+ QT_DEPRECATED_X("Use combinedTransform() instead")
+ QMatrix combinedMatrix() const;
+ QT_DEPRECATED_X("Use setWorldMatrixEnabled() instead")
+ void setMatrixEnabled(bool enabled);
+ QT_DEPRECATED_X("Use worldMatrixEnabled() instead")
+ bool matrixEnabled() const;
+#endif
void setWorldTransform(const QTransform &matrix, bool combine = false);
const QTransform &worldTransform() const;
- QMatrix combinedMatrix() const;
QTransform combinedTransform() const;
- void setMatrixEnabled(bool enabled);
- bool matrixEnabled() const;
-
void setWorldMatrixEnabled(bool enabled);
bool worldMatrixEnabled() const;
@@ -354,9 +370,14 @@ public:
inline void drawRoundedRect(const QRect &rect, qreal xRadius, qreal yRadius,
Qt::SizeMode mode = Qt::AbsoluteSize);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use drawRoundedRect(..., Qt::RelativeSize) instead")
void drawRoundRect(const QRectF &r, int xround = 25, int yround = 25);
- inline void drawRoundRect(int x, int y, int w, int h, int = 25, int = 25);
- inline void drawRoundRect(const QRect &r, int xround = 25, int yround = 25);
+ QT_DEPRECATED_X("Use drawRoundedRect(..., Qt::RelativeSize) instead")
+ void drawRoundRect(int x, int y, int w, int h, int = 25, int = 25);
+ QT_DEPRECATED_X("Use drawRoundedRect(..., Qt::RelativeSize) instead")
+ void drawRoundRect(const QRect &r, int xround = 25, int yround = 25);
+#endif
void drawTiledPixmap(const QRectF &rect, const QPixmap &pm, const QPointF &offset = QPointF());
inline void drawTiledPixmap(int x, int y, int w, int h, const QPixmap &, int sx=0, int sy=0);
@@ -463,10 +484,15 @@ public:
QPaintEngine *paintEngine() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QWidget::render() instead")
static void setRedirected(const QPaintDevice *device, QPaintDevice *replacement,
const QPoint& offset = QPoint());
+ QT_DEPRECATED_X("Use QWidget::render() instead")
static QPaintDevice *redirected(const QPaintDevice *device, QPoint *offset = nullptr);
+ QT_DEPRECATED_X("Use QWidget::render() instead")
static void restoreRedirected(const QPaintDevice *device);
+#endif
void beginNativePainting();
void endNativePainting();
@@ -628,16 +654,6 @@ inline void QPainter::drawPoints(const QPolygon &points)
drawPoints(points.constData(), points.size());
}
-inline void QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd)
-{
- drawRoundRect(QRectF(x, y, w, h), xRnd, yRnd);
-}
-
-inline void QPainter::drawRoundRect(const QRect &rect, int xRnd, int yRnd)
-{
- drawRoundRect(QRectF(rect), xRnd, yRnd);
-}
-
inline void QPainter::drawRoundedRect(int x, int y, int w, int h, qreal xRadius, qreal yRadius,
Qt::SizeMode mode)
{
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index 2d44577310..930180e9fa 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtCore/qvarlengtharray.h>
#include <QtGui/private/qtguiglobal_p.h>
#include "QtGui/qbrush.h"
#include "QtGui/qfont.h"
@@ -202,7 +203,7 @@ public:
QPainterPrivate **d_ptrs;
QPainterState *state;
- QVector<QPainterState*> states;
+ QVarLengthArray<QPainterState *, 8> states;
mutable QPainterDummyState *dummyState;
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index c5ccf0003d..42f94d038f 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -629,6 +629,55 @@ QPainterPath::~QPainterPath()
}
/*!
+ Clears the path elements stored.
+
+ This allows the path to reuse previous memory allocations.
+
+ \sa reserve(), capacity()
+ \since 5.13
+*/
+void QPainterPath::clear()
+{
+ if (!d_ptr)
+ return;
+
+ detach();
+ d_func()->clear();
+}
+
+/*!
+ Reserves a given amount of elements in QPainterPath's internal memory.
+
+ Attempts to allocate memory for at least \a size elements.
+
+ \sa clear(), capacity(), QVector::reserve()
+ \since 5.13
+*/
+void QPainterPath::reserve(int size)
+{
+ Q_D(QPainterPath);
+ if ((!d && size > 0) || (d && d->elements.capacity() < size)) {
+ detach();
+ d->elements.reserve(size);
+ }
+}
+
+/*!
+ Returns the number of elements allocated by the QPainterPath.
+
+ \sa clear(), reserve()
+ \since 5.13
+*/
+int QPainterPath::capacity() const
+{
+ Q_D(QPainterPath);
+ if (d)
+ return d->elements.capacity();
+
+ return 0;
+}
+
+/*!
Closes the current subpath by drawing a line to the beginning of
the subpath, automatically starting a new path. The current point
of the new path is (0, 0).
@@ -2271,13 +2320,19 @@ static inline bool epsilonCompare(const QPointF &a, const QPointF &b, const QSiz
bool QPainterPath::operator==(const QPainterPath &path) const
{
QPainterPathData *d = reinterpret_cast<QPainterPathData *>(d_func());
- if (path.d_func() == d)
+ QPainterPathData *other_d = path.d_func();
+ if (other_d == d)
return true;
- else if (!d || !path.d_func())
+ else if (!d || !other_d) {
+ if (!d && other_d->elements.empty() && other_d->fillRule == Qt::OddEvenFill)
+ return true;
+ if (!other_d && d && d->elements.empty() && d->fillRule == Qt::OddEvenFill)
+ return true;
return false;
- else if (d->fillRule != path.d_func()->fillRule)
+ }
+ else if (d->fillRule != other_d->fillRule)
return false;
- else if (d->elements.size() != path.d_func()->elements.size())
+ else if (d->elements.size() != other_d->elements.size())
return false;
const qreal qt_epsilon = sizeof(qreal) == sizeof(double) ? 1e-12 : qreal(1e-5);
@@ -2287,8 +2342,8 @@ bool QPainterPath::operator==(const QPainterPath &path) const
epsilon.rheight() *= qt_epsilon;
for (int i = 0; i < d->elements.size(); ++i)
- if (d->elements.at(i).type != path.d_func()->elements.at(i).type
- || !epsilonCompare(d->elements.at(i), path.d_func()->elements.at(i), epsilon))
+ if (d->elements.at(i).type != other_d->elements.at(i).type
+ || !epsilonCompare(d->elements.at(i), other_d->elements.at(i), epsilon))
return false;
return true;
@@ -3187,6 +3242,7 @@ void QPainterPath::addRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadi
Adds the given rectangle \a x, \a y, \a w, \a h with rounded corners to the path.
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -3253,6 +3309,17 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd)
\sa addRoundedRect()
*/
+void QPainterPath::addRoundRect(const QRectF &rect,
+ int roundness)
+{
+ int xRnd = roundness;
+ int yRnd = roundness;
+ if (rect.width() > rect.height())
+ xRnd = int(roundness * rect.height()/rect.width());
+ else
+ yRnd = int(roundness * rect.width()/rect.height());
+ addRoundedRect(rect, xRnd, yRnd, Qt::RelativeSize);
+}
/*!
\obsolete
@@ -3269,6 +3336,11 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd)
\sa addRoundedRect()
*/
+void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h,
+ int xRnd, int yRnd)
+{
+ addRoundedRect(QRectF(x, y, w, h), xRnd, yRnd, Qt::RelativeSize);
+}
/*!
\obsolete
@@ -3288,6 +3360,12 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd)
\sa addRoundedRect()
*/
+void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h,
+ int roundness)
+{
+ addRoundedRect(QRectF(x, y, w, h), roundness, Qt::RelativeSize);
+}
+#endif
/*!
\since 4.3
@@ -3342,6 +3420,7 @@ QPainterPath QPainterPath::subtracted(const QPainterPath &p) const
return clipper.clip(QPathClipper::BoolSub);
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\since 4.3
\obsolete
@@ -3354,6 +3433,7 @@ QPainterPath QPainterPath::subtractedInverted(const QPainterPath &p) const
{
return p.subtracted(*this);
}
+#endif
/*!
\since 4.4
diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h
index db39c1c5a0..a69a192767 100644
--- a/src/gui/painting/qpainterpath.h
+++ b/src/gui/painting/qpainterpath.h
@@ -97,8 +97,13 @@ public:
{ qSwap(d_ptr, other.d_ptr); return *this; }
#endif
~QPainterPath();
+
inline void swap(QPainterPath &other) Q_DECL_NOEXCEPT { d_ptr.swap(other.d_ptr); }
+ void clear();
+ void reserve(int size);
+ int capacity() const;
+
void closeSubpath();
void moveTo(const QPointF &p);
@@ -138,12 +143,18 @@ public:
qreal xRadius, qreal yRadius,
Qt::SizeMode mode = Qt::AbsoluteSize);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use addRoundedRect(..., Qt::RelativeSize) instead")
void addRoundRect(const QRectF &rect, int xRnd, int yRnd);
- inline void addRoundRect(qreal x, qreal y, qreal w, qreal h,
- int xRnd, int yRnd);
- inline void addRoundRect(const QRectF &rect, int roundness);
- inline void addRoundRect(qreal x, qreal y, qreal w, qreal h,
- int roundness);
+ QT_DEPRECATED_X("Use addRoundedRect(..., Qt::RelativeSize) instead")
+ void addRoundRect(qreal x, qreal y, qreal w, qreal h,
+ int xRnd, int yRnd);
+ QT_DEPRECATED_X("Use addRoundedRect(..., Qt::RelativeSize) instead")
+ void addRoundRect(const QRectF &rect, int roundness);
+ QT_DEPRECATED_X("Use addRoundedRect(..., Qt::RelativeSize) instead")
+ void addRoundRect(qreal x, qreal y, qreal w, qreal h,
+ int roundness);
+#endif
void connectPath(const QPainterPath &path);
@@ -188,7 +199,10 @@ public:
Q_REQUIRED_RESULT QPainterPath united(const QPainterPath &r) const;
Q_REQUIRED_RESULT QPainterPath intersected(const QPainterPath &r) const;
Q_REQUIRED_RESULT QPainterPath subtracted(const QPainterPath &r) const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use r.subtracted() instead")
Q_REQUIRED_RESULT QPainterPath subtractedInverted(const QPainterPath &r) const;
+#endif
Q_REQUIRED_RESULT QPainterPath simplified() const;
@@ -333,30 +347,6 @@ inline void QPainterPath::addRoundedRect(qreal x, qreal y, qreal w, qreal h,
addRoundedRect(QRectF(x, y, w, h), xRadius, yRadius, mode);
}
-inline void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h,
- int xRnd, int yRnd)
-{
- addRoundRect(QRectF(x, y, w, h), xRnd, yRnd);
-}
-
-inline void QPainterPath::addRoundRect(const QRectF &rect,
- int roundness)
-{
- int xRnd = roundness;
- int yRnd = roundness;
- if (rect.width() > rect.height())
- xRnd = int(roundness * rect.height()/rect.width());
- else
- yRnd = int(roundness * rect.width()/rect.height());
- addRoundRect(rect, xRnd, yRnd);
-}
-
-inline void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h,
- int roundness)
-{
- addRoundRect(QRectF(x, y, w, h), roundness);
-}
-
inline void QPainterPath::addText(qreal x, qreal y, const QFont &f, const QString &text)
{
addText(QPointF(x, y), f, text);
diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h
index 92d9a4ea66..a36c8005bc 100644
--- a/src/gui/painting/qpainterpath_p.h
+++ b/src/gui/painting/qpainterpath_p.h
@@ -157,7 +157,7 @@ public:
QVectorPath path;
private:
- Q_DISABLE_COPY(QVectorPathConverter)
+ Q_DISABLE_COPY_MOVE(QVectorPathConverter)
};
class QPainterPathData : public QPainterPathPrivate
@@ -194,6 +194,7 @@ public:
inline bool isClosed() const;
inline void close();
inline void maybeMoveTo();
+ inline void clear();
const QVectorPath &vectorPath() {
if (!pathConverter)
@@ -290,6 +291,25 @@ inline void QPainterPathData::maybeMoveTo()
}
}
+inline void QPainterPathData::clear()
+{
+ Q_ASSERT(ref.load() == 1);
+
+ elements.clear();
+
+ cStart = 0;
+
+ bounds = {};
+ controlBounds = {};
+
+ require_moveTo = false;
+ dirtyBounds = false;
+ dirtyControlBounds = false;
+ convex = false;
+
+ delete pathConverter;
+ pathConverter = nullptr;
+}
#define KAPPA qreal(0.5522847498)
diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h
index 64e684e1ad..c25a479807 100644
--- a/src/gui/painting/qpathclipper_p.h
+++ b/src/gui/painting/qpathclipper_p.h
@@ -86,7 +86,7 @@ public:
static QPainterPath intersect(const QPainterPath &path, const QRectF &rect);
private:
- Q_DISABLE_COPY(QPathClipper)
+ Q_DISABLE_COPY_MOVE(QPathClipper)
enum ClipperMode {
ClipMode, // do the full clip
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index ae3df6f9ec..6bdc82a8e9 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -856,7 +856,6 @@ void QPdfEngine::drawRects (const QRectF *rects, int rectCount)
if (!d->hasPen && !d->hasBrush)
return;
- QBrush penBrush = d->pen.brush();
if (d->simplePen || !d->hasPen) {
// draw strokes natively in this case for better output
if(!d->simplePen && !d->stroker.matrix.isIdentity())
@@ -949,7 +948,8 @@ void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, con
QPixmap pm = sourceRect != pixmap.rect() ? pixmap.copy(sourceRect) : pixmap;
QImage image = pm.toImage();
bool bitmap = true;
- const int object = d->addImage(image, &bitmap, pm.cacheKey());
+ const bool lossless = painter()->testRenderHint(QPainter::LosslessImageRendering);
+ const int object = d->addImage(image, &bitmap, lossless, pm.cacheKey());
if (object < 0)
return;
@@ -988,7 +988,8 @@ void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const Q
QRect sourceRect = sr.toRect();
QImage im = sourceRect != image.rect() ? image.copy(sourceRect) : image;
bool bitmap = true;
- const int object = d->addImage(im, &bitmap, im.cacheKey());
+ const bool lossless = painter()->testRenderHint(QPainter::LosslessImageRendering);
+ const int object = d->addImage(im, &bitmap, lossless, im.cacheKey());
if (object < 0)
return;
@@ -1541,7 +1542,7 @@ bool QPdfEngine::end()
Q_D(QPdfEngine);
d->writeTail();
- d->stream->unsetDevice();
+ d->stream->setDevice(nullptr);
qDeleteAll(d->fonts);
d->fonts.clear();
@@ -2633,6 +2634,8 @@ int QPdfEnginePrivate::addConstantAlphaObject(int brushAlpha, int penAlpha)
int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor, int *gStateObject)
{
+ Q_Q(QPdfEngine);
+
int paintType = 2; // Uncolored tiling
int w = 8;
int h = 8;
@@ -2662,7 +2665,8 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor,
return 0;
QImage image = brush.textureImage();
bool bitmap = true;
- imageObject = addImage(image, &bitmap, image.cacheKey());
+ const bool lossless = q->painter()->testRenderHint(QPainter::LosslessImageRendering);
+ imageObject = addImage(image, &bitmap, lossless, image.cacheKey());
if (imageObject != -1) {
QImage::Format f = image.format();
if (f != QImage::Format_MonoLSB && f != QImage::Format_Mono) {
@@ -2724,7 +2728,7 @@ static inline bool is_monochrome(const QVector<QRgb> &colorTable)
/*!
* Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.
*/
-int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no)
+int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, bool lossless, qint64 serial_no)
{
if (img.isNull())
return -1;
@@ -2785,7 +2789,7 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
bool hasAlpha = false;
bool hasMask = false;
- if (QImageWriter::supportedImageFormats().contains("jpeg") && !grayscale) {
+ if (QImageWriter::supportedImageFormats().contains("jpeg") && !grayscale && !lossless) {
QBuffer buffer(&imageData);
QImageWriter writer(&buffer, "jpeg");
writer.setQuality(94);
diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h
index e2526de67d..e337c61f64 100644
--- a/src/gui/painting/qpdf_p.h
+++ b/src/gui/painting/qpdf_p.h
@@ -242,7 +242,7 @@ public:
void writeHeader();
void writeTail();
- int addImage(const QImage &image, bool *bitmap, qint64 serial_no);
+ int addImage(const QImage &image, bool *bitmap, bool lossless, qint64 serial_no);
int addConstantAlphaObject(int brushAlpha, int penAlpha = 255);
int addBrushPattern(const QTransform &matrix, bool *specifyColor, int *gStateObject);
diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp
index 6c85d65538..258939a763 100644
--- a/src/gui/painting/qpdfwriter.cpp
+++ b/src/gui/painting/qpdfwriter.cpp
@@ -76,7 +76,7 @@ public:
: QPagedPaintDevicePrivate(), pd(d)
{}
- virtual ~QPdfPagedPaintDevicePrivate()
+ ~QPdfPagedPaintDevicePrivate()
{}
bool setPageLayout(const QPageLayout &newPageLayout) override
diff --git a/src/gui/painting/qrgba64.h b/src/gui/painting/qrgba64.h
index 0e5344cacb..0e0b567890 100644
--- a/src/gui/painting/qrgba64.h
+++ b/src/gui/painting/qrgba64.h
@@ -118,7 +118,27 @@ public:
Q_DECL_CONSTEXPR quint8 alpha8() const { return div_257(alpha()); }
Q_DECL_CONSTEXPR uint toArgb32() const
{
+#if defined(__cpp_constexpr) && __cpp_constexpr-0 >= 201304
+ quint64 br = rgba & Q_UINT64_C(0xffff0000ffff);
+ quint64 ag = (rgba >> 16) & Q_UINT64_C(0xffff0000ffff);
+ br += Q_UINT64_C(0x8000000080);
+ ag += Q_UINT64_C(0x8000000080);
+ br = (br - ((br >> 8) & Q_UINT64_C(0xffff0000ffff))) >> 8;
+ ag = (ag - ((ag >> 8) & Q_UINT64_C(0xffff0000ffff)));
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ return ((br << 24) & 0xff000000)
+ | ((ag >> 24) & 0xff0000)
+ | ((br >> 24) & 0xff00)
+ | ((ag >> 8) & 0xff);
+#else
+ return ((ag >> 16) & 0xff000000)
+ | ((br << 16) & 0xff0000)
+ | (ag & 0xff00)
+ | ((br >> 32) & 0xff);
+#endif
+#else
return uint((alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8());
+#endif
}
Q_DECL_CONSTEXPR ushort toRgb16() const
{
@@ -131,11 +151,20 @@ public:
return *this;
if (isTransparent())
return QRgba64::fromRgba64(0);
- const quint32 a = alpha();
- const quint16 r = div_65535(red() * a);
- const quint16 g = div_65535(green() * a);
- const quint16 b = div_65535(blue() * a);
- return fromRgba64(r, g, b, quint16(a));
+ const quint64 a = alpha();
+ quint64 br = (rgba & Q_UINT64_C(0xffff0000ffff)) * a;
+ quint64 ag = ((rgba >> 16) & Q_UINT64_C(0xffff0000ffff)) * a;
+ br = (br + ((br >> 16) & Q_UINT64_C(0xffff0000ffff)) + Q_UINT64_C(0x800000008000));
+ ag = (ag + ((ag >> 16) & Q_UINT64_C(0xffff0000ffff)) + Q_UINT64_C(0x800000008000));
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ ag = ag & Q_UINT64_C(0xffff0000ffff0000);
+ br = (br >> 16) & Q_UINT64_C(0xffff00000000);
+ return fromRgba64(a | br | ag);
+#else
+ br = (br >> 16) & Q_UINT64_C(0xffff0000ffff);
+ ag = ag & Q_UINT64_C(0xffff0000);
+ return fromRgba64((a << 48) | br | ag);
+#endif
}
Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied() const
@@ -163,7 +192,6 @@ private:
static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE quint8 div_257_floor(uint x) { return quint8((x - (x >> 8)) >> 8); }
static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE quint8 div_257(quint16 x) { return div_257_floor(x + 128U); }
- static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE quint16 div_65535(uint x) { return quint16((x + (x>>16) + 0x8000U) >> 16); }
Q_DECL_RELAXED_CONSTEXPR Q_ALWAYS_INLINE QRgba64 unpremultiplied_32bit() const
{
if (isOpaque() || isTransparent())
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index 292952b7c0..c01531caf2 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -369,7 +369,8 @@ void QStrokerOps::strokeEllipse(const QRectF &rect, void *data, const QTransform
QStroker::QStroker()
: m_capStyle(SquareJoin), m_joinStyle(FlatJoin),
m_back1X(0), m_back1Y(0),
- m_back2X(0), m_back2Y(0)
+ m_back2X(0), m_back2Y(0),
+ m_forceOpen(false)
{
m_strokeWidth = qt_real_to_fixed(1);
m_miterLimit = qt_real_to_fixed(2);
@@ -749,7 +750,7 @@ template <class Iterator> bool qt_stroke_side(Iterator *it,
}
}
- if (start == prev) {
+ if (start == prev && !stroker->forceOpen()) {
// closed subpath, join first and last point
#ifdef QPP_STROKE_DEBUG
qDebug("\n ---> (side) closed subpath");
diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h
index 1a7c184e1a..722a0904f3 100644
--- a/src/gui/painting/qstroker_p.h
+++ b/src/gui/painting/qstroker_p.h
@@ -222,6 +222,9 @@ public:
void setMiterLimit(qfixed length) { m_miterLimit = length; }
qfixed miterLimit() const { return m_miterLimit; }
+ void setForceOpen(bool state) { m_forceOpen = state; }
+ bool forceOpen() { return m_forceOpen; }
+
void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join);
inline void emitMoveTo(qfixed x, qfixed y);
inline void emitLineTo(qfixed x, qfixed y);
@@ -247,6 +250,8 @@ protected:
qfixed m_back2X;
qfixed m_back2Y;
+
+ bool m_forceOpen;
};
class Q_GUI_EXPORT QDashStroker : public QStrokerOps
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 040d33fc2a..816514a695 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -1517,8 +1517,23 @@ QRegion QTransform::map(const QRegion &r) const
return copy;
}
- if (t == TxScale && r.rectCount() == 1)
- return QRegion(mapRect(r.boundingRect()));
+ if (t == TxScale) {
+ QRegion res;
+ if (m11() < 0 || m22() < 0) {
+ for (const QRect &rect : r)
+ res += mapRect(rect);
+ } else {
+ QVarLengthArray<QRect, 32> rects;
+ rects.reserve(r.rectCount());
+ for (const QRect &rect : r) {
+ QRect nr = mapRect(rect);
+ if (!nr.isEmpty())
+ rects.append(nr);
+ }
+ res.setRects(rects.constData(), rects.count());
+ }
+ return res;
+ }
QPainterPath p = map(qt_regionToPath(r));
return p.toFillPolygon(QTransform()).toPolygon();
@@ -2144,13 +2159,14 @@ QTransform::operator QVariant() const
\sa inverted()
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn qreal QTransform::det() const
\obsolete
Returns the matrix's determinant. Use determinant() instead.
*/
-
+#endif
/*!
\fn qreal QTransform::m11() const
diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h
index 63c4a241c1..1e322d435a 100644
--- a/src/gui/painting/qtransform.h
+++ b/src/gui/painting/qtransform.h
@@ -98,7 +98,10 @@ public:
TransformationType type() const;
inline qreal determinant() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use determinant() instead")
qreal det() const;
+#endif
qreal m11() const;
qreal m12() const;
@@ -242,10 +245,12 @@ inline qreal QTransform::determinant() const
return affine._m11*(m_33*affine._m22-affine._dy*m_23) -
affine._m21*(m_33*affine._m12-affine._dy*m_13)+affine._dx*(m_23*affine._m12-affine._m22*m_13);
}
+#if QT_DEPRECATED_SINCE(5, 13)
inline qreal QTransform::det() const
{
return determinant();
}
+#endif
inline qreal QTransform::m11() const
{
return affine._m11;
diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h
index d1b08ed423..1b649a5d2a 100644
--- a/src/gui/painting/qvectorpath_p.h
+++ b/src/gui/painting/qvectorpath_p.h
@@ -99,7 +99,8 @@ public:
// Shape rendering specifiers...
OddEvenFill = 0x1000,
WindingFill = 0x2000,
- ImplicitClose = 0x4000
+ ImplicitClose = 0x4000,
+ ExplicitOpen = 0x8000
};
// ### Falcon: introduca a struct XY for points so lars is not so confused...
@@ -124,6 +125,7 @@ public:
inline bool isCacheable() const { return m_hints & ShouldUseCacheHint; }
inline bool hasImplicitClose() const { return m_hints & ImplicitClose; }
+ inline bool hasExplicitOpen() const { return m_hints & ExplicitOpen; }
inline bool hasWindingFill() const { return m_hints & WindingFill; }
inline void makeCacheable() const { m_hints |= ShouldUseCacheHint; m_cache = 0; }
@@ -142,7 +144,7 @@ public:
case QPaintEngine::ConvexMode: return ConvexPolygonHint | ImplicitClose;
case QPaintEngine::OddEvenMode: return PolygonHint | OddEvenFill | ImplicitClose;
case QPaintEngine::WindingMode: return PolygonHint | WindingFill | ImplicitClose;
- case QPaintEngine::PolylineMode: return PolygonHint;
+ case QPaintEngine::PolylineMode: return PolygonHint | ExplicitOpen;
default: return 0;
}
}
@@ -194,7 +196,7 @@ public:
private:
- Q_DISABLE_COPY(QVectorPath)
+ Q_DISABLE_COPY_MOVE(QVectorPath)
const QPainterPath::ElementType *m_elements;
const qreal *m_points;
diff --git a/src/gui/platform/platform.pri b/src/gui/platform/platform.pri
new file mode 100644
index 0000000000..1fe2db81b0
--- /dev/null
+++ b/src/gui/platform/platform.pri
@@ -0,0 +1 @@
+wasm:include(wasm/wasm.pri)
diff --git a/src/gui/platform/wasm/qwasmlocalfileaccess.cpp b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp
new file mode 100644
index 0000000000..83f9415c69
--- /dev/null
+++ b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmlocalfileaccess_p.h"
+#include <private/qstdweb_p.h>
+#include <emscripten.h>
+#include <emscripten/bind.h>
+#include <emscripten/html5.h>
+#include <emscripten/val.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QWasmLocalFileAccess {
+
+void streamFile(const qstdweb::File &file, uint32_t offset, uint32_t length, char *buffer, const std::function<void ()> &completed)
+{
+ // Read file in chunks in order to avoid holding two copies in memory at the same time
+ const uint32_t chunkSize = 256 * 1024;
+ const uint32_t end = offset + length;
+ // assert end < file.size
+ auto fileReader = std::make_shared<qstdweb::FileReader>();
+
+ auto chunkCompleted = std::make_shared<std::function<void (uint32_t, char *buffer)>>();
+ *chunkCompleted = [=](uint32_t chunkBegin, char *chunkBuffer) mutable {
+
+ // Copy current chunk from JS memory to Wasm memory
+ qstdweb::ArrayBuffer result = fileReader->result();
+ qstdweb::Uint8Array(result).copyTo(chunkBuffer);
+
+ // Read next chunk if not at buffer end
+ uint32_t nextChunkBegin = std::min(chunkBegin + result.byteLength(), end);
+ uint32_t nextChunkEnd = std::min(nextChunkBegin + chunkSize, end);
+ if (nextChunkBegin == end) {
+ completed();
+ chunkCompleted.reset();
+ return;
+ }
+ char *nextChunkBuffer = chunkBuffer + result.byteLength();
+ fileReader->onLoad([=]() { (*chunkCompleted)(nextChunkBegin, nextChunkBuffer); });
+ qstdweb::Blob blob = file.slice(nextChunkBegin, nextChunkEnd);
+ fileReader->readAsArrayBuffer(blob);
+ };
+
+ // Read first chunk. First iteration is a dummy iteration with no available data.
+ (*chunkCompleted)(offset, buffer);
+}
+
+void streamFile(const qstdweb::File &file, char *buffer, const std::function<void ()> &completed)
+{
+ streamFile(file, 0, file.size(), buffer, completed);
+}
+
+void readFiles(const qstdweb::FileList &fileList,
+ const std::function<char *(uint64_t size, const std::string name)> &acceptFile,
+ const std::function<void ()> &fileDataReady)
+{
+ auto readFile = std::make_shared<std::function<void(int)>>();
+
+ *readFile = [=](int fileIndex) mutable {
+ // Stop when all files have been processed
+ if (fileIndex >= fileList.length()) {
+ readFile.reset();
+ return;
+ }
+
+ const qstdweb::File file = fileList[fileIndex];
+
+ // Ask caller if the file should be accepted
+ char *buffer = acceptFile(file.size(), file.name());
+ if (buffer == nullptr) {
+ (*readFile)(fileIndex + 1);
+ return;
+ }
+
+ // Read file data into caller-provided buffer
+ streamFile(file, buffer, [=]() {
+ fileDataReady();
+ (*readFile)(fileIndex + 1);
+ });
+ };
+
+ (*readFile)(0);
+}
+
+typedef std::function<void (const qstdweb::FileList &fileList)> OpenFileDialogCallback;
+void openFileDialog(const std::string &accept, FileSelectMode fileSelectMode,
+ const OpenFileDialogCallback &filesSelected)
+{
+ // Create file input html element which will display a native file dialog
+ // and call back to our onchange handler once the user has selected
+ // one or more files.
+ emscripten::val document = emscripten::val::global("document");
+ emscripten::val input = document.call<emscripten::val>("createElement", std::string("input"));
+ input.set("type", "file");
+ input.set("style", "display:none");
+ input.set("accept", emscripten::val(accept));
+ input.set("multiple", emscripten::val(fileSelectMode == MultipleFiles));
+
+ // Note: there is no event in case the user cancels the file dialog.
+ static std::unique_ptr<qstdweb::EventCallback> changeEvent;
+ auto callback = [=]() { filesSelected(qstdweb::FileList(input["files"])); };
+ changeEvent.reset(new qstdweb::EventCallback(input, "change", callback));
+
+ // Activate file input
+ emscripten::val body = document["body"];
+ body.call<void>("appendChild", input);
+ input.call<void>("click");
+ body.call<void>("removeChild", input);
+}
+
+void openFiles(const std::string &accept, FileSelectMode fileSelectMode,
+ const std::function<void (int fileCount)> &fileDialogClosed,
+ const std::function<char *(uint64_t size, const std::string name)> &acceptFile,
+ const std::function<void()> &fileDataReady)
+{
+ openFileDialog(accept, fileSelectMode, [=](const qstdweb::FileList &files) {
+ fileDialogClosed(files.length());
+ readFiles(files, acceptFile, fileDataReady);
+ });
+}
+
+void openFile(const std::string &accept,
+ const std::function<void (bool fileSelected)> &fileDialogClosed,
+ const std::function<char *(uint64_t size, const std::string name)> &acceptFile,
+ const std::function<void()> &fileDataReady)
+{
+ auto fileDialogClosedWithInt = [=](int fileCount) { fileDialogClosed(fileCount != 0); };
+ openFiles(accept, FileSelectMode::SingleFile, fileDialogClosedWithInt, acceptFile, fileDataReady);
+}
+
+} // namespace QWasmLocalFileAccess
+
+QT_END_NAMESPACE
diff --git a/src/gui/platform/wasm/qwasmlocalfileaccess_p.h b/src/gui/platform/wasm/qwasmlocalfileaccess_p.h
new file mode 100644
index 0000000000..794db8d9b2
--- /dev/null
+++ b/src/gui/platform/wasm/qwasmlocalfileaccess_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMLOCALFILEACCESS_P_H
+#define QWASMLOCALFILEACCESS_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 <qglobal.h>
+#include <cstdint>
+#include <functional>
+
+QT_BEGIN_NAMESPACE
+
+namespace QWasmLocalFileAccess {
+
+enum FileSelectMode { SingleFile, MultipleFiles };
+
+void openFiles(const std::string &accept, FileSelectMode fileSelectMode,
+ const std::function<void (int fileCount)> &fileDialogClosed,
+ const std::function<char *(uint64_t size, const std::string name)> &acceptFile,
+ const std::function<void()> &fileDataReady);
+
+void openFile(const std::string &accept,
+ const std::function<void (bool fileSelected)> &fileDialogClosed,
+ const std::function<char *(uint64_t size, const std::string name)> &acceptFile,
+ const std::function<void()> &fileDataReady);
+
+} // namespace QWasmLocalFileAccess
+
+QT_END_NAMESPACE
+
+#endif // QWASMLOCALFILEACCESS_P_H
diff --git a/src/gui/platform/wasm/wasm.pri b/src/gui/platform/wasm/wasm.pri
new file mode 100644
index 0000000000..1b5d7eadb5
--- /dev/null
+++ b/src/gui/platform/wasm/wasm.pri
@@ -0,0 +1,3 @@
+INCLUDEDIR += $$PWD
+HEADERS += $$PWD/qwasmlocalfileaccess_p.h
+SOURCES += $$PWD/qwasmlocalfileaccess.cpp
diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h
index 8fea27f772..3371401420 100644
--- a/src/gui/text/qabstracttextdocumentlayout.h
+++ b/src/gui/text/qabstracttextdocumentlayout.h
@@ -143,7 +143,9 @@ public:
virtual void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format) = 0;
};
+#ifndef Q_CLANG_QDOC
Q_DECLARE_INTERFACE(QTextObjectInterface, "org.qt-project.Qt.QTextObjectInterface")
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 325fd26a31..dc7e128bcd 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -115,6 +115,7 @@ static const QCssKnownValue properties[NumProperties - 1] = {
{ "float", Float },
{ "font", Font },
{ "font-family", FontFamily },
+ { "font-kerning", FontKerning },
{ "font-size", FontSize },
{ "font-style", FontStyle },
{ "font-variant", FontVariant },
@@ -368,6 +369,7 @@ static inline bool isInheritable(Property propertyId)
{
switch (propertyId) {
case Font:
+ case FontKerning:
case FontFamily:
case FontSize:
case FontStyle:
@@ -721,7 +723,8 @@ static ColorData parseColorValue(QCss::Value v)
if (lst.count() != 2)
return ColorData();
- if ((lst.at(0).compare(QLatin1String("palette"), Qt::CaseInsensitive)) == 0) {
+ const QString &identifier = lst.at(0);
+ if ((identifier.compare(QLatin1String("palette"), Qt::CaseInsensitive)) == 0) {
int role = findKnownValue(lst.at(1).trimmed(), values, NumKnownValues);
if (role >= Value_FirstColorRole && role <= Value_LastColorRole)
return (QPalette::ColorRole)(role-Value_FirstColorRole);
@@ -729,8 +732,16 @@ static ColorData parseColorValue(QCss::Value v)
return ColorData();
}
- bool rgb = lst.at(0).startsWith(QLatin1String("rgb"));
- bool rgba = lst.at(0).startsWith(QLatin1String("rgba"));
+ const bool rgb = identifier.startsWith(QLatin1String("rgb"));
+ const bool hsv = !rgb && identifier.startsWith(QLatin1String("hsv"));
+ const bool hsl = !rgb && !hsv && identifier.startsWith(QLatin1String("hsl"));
+
+ if (!rgb && !hsv && !hsl)
+ return ColorData();
+
+ const bool hasAlpha = identifier.size() == 4 && identifier.at(3) == QLatin1Char('a');
+ if (identifier.size() > 3 && !hasAlpha)
+ return ColorData();
Parser p(lst.at(1));
if (!p.testExpr())
@@ -743,7 +754,8 @@ static ColorData parseColorValue(QCss::Value v)
for (int i = 0; i < qMin(tokenCount, 7); i += 2) {
if (colorDigits.at(i).type == Value::Percentage) {
- colorDigits[i].variant = colorDigits.at(i).variant.toReal() * (255. / 100.);
+ const qreal maxRange = (rgb || i != 0) ? 255. : 359.;
+ colorDigits[i].variant = colorDigits.at(i).variant.toReal() * (maxRange / 100.);
colorDigits[i].type = Value::Number;
} else if (colorDigits.at(i).type != Value::Number) {
return ColorData();
@@ -754,20 +766,29 @@ static ColorData parseColorValue(QCss::Value v)
if (tokenCount < 5)
return ColorData();
+ // ### Qt6: replace this with a check and return invalid color when token count does not match
+ if (hasAlpha && tokenCount != 7)
+ qWarning("QCssParser::parseColorValue: Specified color with alpha value but no alpha given: '%s'", qPrintable(lst.join(QLatin1Char(' '))));
+ if (!hasAlpha && tokenCount != 5)
+ qWarning("QCssParser::parseColorValue: Specified color without alpha value but alpha given: '%s'", qPrintable(lst.join(QLatin1Char(' '))));
+
int v1 = colorDigits.at(0).variant.toInt();
int v2 = colorDigits.at(2).variant.toInt();
int v3 = colorDigits.at(4).variant.toInt();
int alpha = 255;
- if (tokenCount >= 7) {
+ if (tokenCount == 7) {
int alphaValue = colorDigits.at(6).variant.toInt();
- if (rgba && alphaValue <= 1)
+ if (alphaValue <= 1)
alpha = colorDigits.at(6).variant.toReal() * 255.;
else
alpha = alphaValue;
}
- return rgb ? QColor::fromRgb(v1, v2, v3, alpha)
- : QColor::fromHsv(v1, v2, v3, alpha);
+ if (rgb)
+ return QColor::fromRgb(v1, v2, v3, alpha);
+ if (hsv)
+ return QColor::fromHsv(v1, v2, v3, alpha);
+ return QColor::fromHsl(v1, v2, v3, alpha);
}
static QColor colorFromData(const ColorData& c, const QPalette &pal)
@@ -1142,6 +1163,19 @@ static bool setFontStyleFromValue(const QCss::Value &value, QFont *font)
return false;
}
+static bool setFontKerningFromValue(const QCss::Value &value, QFont *font)
+{
+ if (value.type != Value::KnownIdentifier)
+ return false ;
+ switch (value.variant.toInt()) {
+ case Value_Normal: font->setKerning(true); return true;
+ case Value_None: font->setKerning(false); return true;
+ case Value_Auto: return true;
+ default: break;
+ }
+ return false;
+}
+
static bool setFontWeightFromValue(const QCss::Value &value, QFont *font)
{
if (value.type == Value::KnownIdentifier) {
@@ -1166,11 +1200,13 @@ static bool setFontWeightFromValue(const QCss::Value &value, QFont *font)
static bool setFontFamilyFromValues(const QVector<QCss::Value> &values, QFont *font, int start = 0)
{
QString family;
+ QStringList families;
bool shouldAddSpace = false;
for (int i = start; i < values.count(); ++i) {
const QCss::Value &v = values.at(i);
if (v.type == Value::TermOperatorComma) {
- family += QLatin1Char(',');
+ families << family;
+ family.clear();
shouldAddSpace = false;
continue;
}
@@ -1182,9 +1218,12 @@ static bool setFontFamilyFromValues(const QVector<QCss::Value> &values, QFont *f
family += str;
shouldAddSpace = true;
}
- if (family.isEmpty())
+ if (!family.isEmpty())
+ families << family;
+ if (families.isEmpty())
return false;
- font->setFamily(family);
+ font->setFamily(families.at(0));
+ font->setFamilies(families);
return true;
}
@@ -1274,6 +1313,7 @@ bool ValueExtractor::extractFont(QFont *font, int *fontSizeAdjustment)
case FontStyle: setFontStyleFromValue(val, font); break;
case FontWeight: setFontWeightFromValue(val, font); break;
case FontFamily: setFontFamilyFromValues(decl.d->values, font); break;
+ case FontKerning: setFontKerningFromValue(val, font); break;
case TextDecoration: setTextDecorationFromValues(decl.d->values, font); break;
case Font: parseShorthandFontProperty(decl.d->values, font, fontSizeAdjustment); break;
case FontVariant: setFontVariantFromValue(val, font); break;
@@ -1968,7 +2008,7 @@ bool StyleSelector::basicSelectorMatches(const BasicSelector &sel, NodePtr node)
}
void StyleSelector::matchRule(NodePtr node, const StyleRule &rule, StyleSheetOrigin origin,
- int depth, QMap<uint, StyleRule> *weightedRules)
+ int depth, QMultiMap<uint, StyleRule> *weightedRules)
{
for (int j = 0; j < rule.selectors.count(); ++j) {
const Selector& selector = rule.selectors.at(j);
@@ -1982,7 +2022,7 @@ void StyleSelector::matchRule(NodePtr node, const StyleRule &rule, StyleSheetOri
newRule.selectors[0] = selector;
}
//We might have rules with the same weight if they came from a rule with several selectors
- weightedRules->insertMulti(weight, newRule);
+ weightedRules->insert(weight, newRule);
}
}
}
@@ -1995,7 +2035,7 @@ QVector<StyleRule> StyleSelector::styleRulesForNode(NodePtr node)
if (styleSheets.isEmpty())
return rules;
- QMap<uint, StyleRule> weightedRules; // (spec, rule) that will be sorted below
+ QMultiMap<uint, StyleRule> weightedRules; // (spec, rule) that will be sorted below
//prune using indexed stylesheet
for (int sheetIdx = 0; sheetIdx < styleSheets.count(); ++sheetIdx) {
diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h
index c1594531ea..860bbe382a 100644
--- a/src/gui/text/qcssparser_p.h
+++ b/src/gui/text/qcssparser_p.h
@@ -195,6 +195,7 @@ enum Property {
QtListNumberSuffix,
LineHeight,
QtLineHeightType,
+ FontKerning,
NumProperties
};
@@ -673,7 +674,7 @@ public:
Qt::CaseSensitivity nameCaseSensitivity;
private:
void matchRule(NodePtr node, const StyleRule &rules, StyleSheetOrigin origin,
- int depth, QMap<uint, StyleRule> *weightedRules);
+ int depth, QMultiMap<uint, StyleRule> *weightedRules);
bool selectorMatches(const Selector &rule, NodePtr node);
bool basicSelectorMatches(const BasicSelector &rule, NodePtr node);
};
diff --git a/src/gui/text/qcssscanner.cpp b/src/gui/text/qcssscanner.cpp
index 33dc01c8bc..d48cbb71d7 100644
--- a/src/gui/text/qcssscanner.cpp
+++ b/src/gui/text/qcssscanner.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -37,7 +37,7 @@
**
****************************************************************************/
-// auto generated. DO NOT EDIT.
+// auto generated by qtbase/util/lexgen/. DO NOT EDIT.
class QCssScanner_Generated
{
public:
@@ -75,23 +75,23 @@ int QCssScanner_Generated::lex()
// initial state
ch = next();
if (ch.unicode() >= 9 && ch.unicode() <= 10)
- goto state_1;
+ goto state_4;
if (ch.unicode() >= 12 && ch.unicode() <= 13)
- goto state_1;
+ goto state_4;
if (ch.unicode() == 32)
- goto state_1;
+ goto state_4;
if (ch.unicode() == 33) {
token = QCss::EXCLAMATION_SYM;
goto found;
}
if (ch.unicode() == 34)
- goto state_3;
+ goto state_2;
if (ch.unicode() == 35)
- goto state_4;
+ goto state_1;
if (ch.unicode() == 36)
- goto state_5;
- if (ch.unicode() == 39)
goto state_6;
+ if (ch.unicode() == 39)
+ goto state_5;
if (ch.unicode() == 40) {
token = QCss::LPAREN;
goto found;
@@ -101,17 +101,17 @@ int QCssScanner_Generated::lex()
goto found;
}
if (ch.unicode() == 42)
- goto state_9;
+ goto state_8;
if (ch.unicode() == 43)
- goto state_10;
+ goto state_7;
if (ch.unicode() == 44)
- goto state_11;
+ goto state_14;
if (ch.unicode() == 45)
- goto state_12;
- if (ch.unicode() == 46)
goto state_13;
+ if (ch.unicode() == 46)
+ goto state_12;
if (ch.unicode() == 47)
- goto state_14;
+ goto state_11;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
goto state_15;
if (ch.unicode() == 58) {
@@ -123,64 +123,56 @@ int QCssScanner_Generated::lex()
goto found;
}
if (ch.unicode() == 60)
- goto state_18;
+ goto state_20;
if (ch.unicode() == 61) {
token = QCss::EQUAL;
goto found;
}
if (ch.unicode() == 62)
- goto state_20;
+ goto state_18;
if (ch.unicode() == 64)
- goto state_21;
+ goto state_26;
if (ch.unicode() == 91) {
token = QCss::LBRACKET;
goto found;
}
if (ch.unicode() == 92)
- goto state_23;
+ goto state_30;
if (ch.unicode() == 93) {
token = QCss::RBRACKET;
goto found;
}
if (ch.unicode() == 94)
- goto state_25;
+ goto state_28;
if (ch.unicode() == 95)
- goto state_26;
+ goto state_21;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_26;
+ goto state_21;
if (ch.unicode() == 123)
- goto state_27;
+ goto state_22;
if (ch.unicode() == 124)
- goto state_28;
+ goto state_25;
if (ch.unicode() == 125) {
token = QCss::RBRACE;
goto found;
}
if (ch.unicode() == 126)
- goto state_30;
+ goto state_23;
goto out;
state_1:
- lastAcceptingPos = pos;
- token = QCss::S;
ch = next();
- if (ch.unicode() >= 9 && ch.unicode() <= 10)
- goto state_31;
- if (ch.unicode() >= 12 && ch.unicode() <= 13)
+ if (ch.unicode() == 45)
goto state_31;
- if (ch.unicode() == 32)
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
goto state_31;
- if (ch.unicode() == 43)
- goto state_10;
- if (ch.unicode() == 44)
- goto state_11;
- if (ch.unicode() == 62)
- goto state_20;
- if (ch.unicode() == 123)
- goto state_27;
- if (ch.unicode() == 126)
+ if (ch.unicode() == 92)
goto state_32;
+ if (ch.unicode() == 95)
+ goto state_31;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_31;
goto out;
- state_3:
+ state_2:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
@@ -204,93 +196,101 @@ int QCssScanner_Generated::lex()
goto state_33;
goto out;
state_4:
+ lastAcceptingPos = pos;
+ token = QCss::S;
ch = next();
- if (ch.unicode() == 45)
- goto state_36;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ if (ch.unicode() >= 9 && ch.unicode() <= 10)
goto state_36;
- if (ch.unicode() == 92)
- goto state_37;
- if (ch.unicode() == 95)
+ if (ch.unicode() >= 12 && ch.unicode() <= 13)
goto state_36;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ if (ch.unicode() == 32)
goto state_36;
+ if (ch.unicode() == 43)
+ goto state_7;
+ if (ch.unicode() == 44)
+ goto state_14;
+ if (ch.unicode() == 62)
+ goto state_18;
+ if (ch.unicode() == 123)
+ goto state_22;
+ if (ch.unicode() == 126)
+ goto state_37;
goto out;
state_5:
- ch = next();
- if (ch.unicode() == 61) {
- token = QCss::ENDSWITH;
- goto found;
- }
- goto out;
- state_6:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
- state_9:
- lastAcceptingPos = pos;
- token = QCss::STAR;
+ state_6:
ch = next();
if (ch.unicode() == 61) {
- token = QCss::CONTAINS;
+ token = QCss::ENDSWITH;
goto found;
}
goto out;
- state_10:
+ state_7:
lastAcceptingPos = pos;
token = QCss::PLUS;
goto out;
+ state_8:
+ lastAcceptingPos = pos;
+ token = QCss::STAR;
+ ch = next();
+ if (ch.unicode() == 61) {
+ token = QCss::CONTAINS;
+ goto found;
+ }
+ goto out;
state_11:
lastAcceptingPos = pos;
- token = QCss::COMMA;
+ token = QCss::SLASH;
+ ch = next();
+ if (ch.unicode() == 42) {
+ token = handleCommentStart();
+ goto found;
+ }
goto out;
state_12:
lastAcceptingPos = pos;
+ token = QCss::DOT;
+ ch = next();
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_44;
+ goto out;
+ state_13:
+ lastAcceptingPos = pos;
token = QCss::MINUS;
ch = next();
if (ch.unicode() == 45)
- goto state_43;
+ goto state_45;
if (ch.unicode() == 92)
- goto state_23;
+ goto state_30;
if (ch.unicode() == 95)
- goto state_26;
+ goto state_21;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_26;
- goto out;
- state_13:
- lastAcceptingPos = pos;
- token = QCss::DOT;
- ch = next();
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_44;
+ goto state_21;
goto out;
state_14:
lastAcceptingPos = pos;
- token = QCss::SLASH;
- ch = next();
- if (ch.unicode() == 42) {
- token = handleCommentStart();
- goto found;
- }
+ token = QCss::COMMA;
goto out;
state_15:
lastAcceptingPos = pos;
@@ -299,68 +299,70 @@ int QCssScanner_Generated::lex()
if (ch.unicode() == 37)
goto state_46;
if (ch.unicode() == 45)
- goto state_47;
- if (ch.unicode() == 46)
goto state_48;
+ if (ch.unicode() == 46)
+ goto state_47;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
goto state_49;
if (ch.unicode() == 92)
- goto state_50;
- if (ch.unicode() == 95)
goto state_51;
+ if (ch.unicode() == 95)
+ goto state_50;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_51;
+ goto state_50;
goto out;
state_18:
+ lastAcceptingPos = pos;
+ token = QCss::GREATER;
+ goto out;
+ state_20:
ch = next();
if (ch.unicode() == 33)
goto state_52;
goto out;
- state_20:
- lastAcceptingPos = pos;
- token = QCss::GREATER;
- goto out;
state_21:
+ lastAcceptingPos = pos;
+ token = QCss::IDENT;
ch = next();
- if (ch.unicode() == 45)
+ if (ch.unicode() == 40)
goto state_53;
- if (ch.unicode() == 92)
+ if (ch.unicode() == 45)
goto state_54;
- if (ch.unicode() == 95)
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_54;
+ if (ch.unicode() == 92)
goto state_55;
+ if (ch.unicode() == 95)
+ goto state_54;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_55;
+ goto state_54;
+ goto out;
+ state_22:
+ lastAcceptingPos = pos;
+ token = QCss::LBRACE;
goto out;
state_23:
+ lastAcceptingPos = pos;
+ token = QCss::TILDE;
ch = next();
- if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_56;
- if (ch.unicode() == 11)
- goto state_56;
- if (ch.unicode() >= 14 && ch.unicode() <= 47)
- goto state_56;
- if (ch.unicode() >= 58 && ch.unicode() <= 96)
- goto state_56;
- if (ch.unicode() >= 103)
- goto state_56;
+ if (ch.unicode() == 61) {
+ token = QCss::INCLUDES;
+ goto found;
+ }
goto out;
state_25:
+ lastAcceptingPos = pos;
+ token = QCss::OR;
ch = next();
if (ch.unicode() == 61) {
- token = QCss::BEGINSWITH;
+ token = QCss::DASHMATCH;
goto found;
}
goto out;
state_26:
- lastAcceptingPos = pos;
- token = QCss::IDENT;
ch = next();
- if (ch.unicode() == 40)
- goto state_58;
if (ch.unicode() == 45)
- goto state_59;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_59;
+ goto state_58;
if (ch.unicode() == 92)
goto state_60;
if (ch.unicode() == 95)
@@ -368,52 +370,53 @@ int QCssScanner_Generated::lex()
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
goto state_59;
goto out;
- state_27:
- lastAcceptingPos = pos;
- token = QCss::LBRACE;
- goto out;
state_28:
- lastAcceptingPos = pos;
- token = QCss::OR;
ch = next();
if (ch.unicode() == 61) {
- token = QCss::DASHMATCH;
+ token = QCss::BEGINSWITH;
goto found;
}
goto out;
state_30:
- lastAcceptingPos = pos;
- token = QCss::TILDE;
ch = next();
- if (ch.unicode() == 61) {
- token = QCss::INCLUDES;
- goto found;
- }
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_62;
+ if (ch.unicode() == 11)
+ goto state_62;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_62;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_62;
+ if (ch.unicode() >= 103)
+ goto state_62;
goto out;
state_31:
lastAcceptingPos = pos;
- token = QCss::S;
+ token = QCss::HASH;
ch = next();
- if (ch.unicode() >= 9 && ch.unicode() <= 10)
- goto state_31;
- if (ch.unicode() >= 12 && ch.unicode() <= 13)
- goto state_31;
- if (ch.unicode() == 32)
- goto state_31;
- if (ch.unicode() == 43)
- goto state_10;
- if (ch.unicode() == 44)
- goto state_11;
- if (ch.unicode() == 62)
- goto state_20;
- if (ch.unicode() == 123)
- goto state_27;
- if (ch.unicode() == 126)
- goto state_32;
+ if (ch.unicode() == 45)
+ goto state_63;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_63;
+ if (ch.unicode() == 92)
+ goto state_64;
+ if (ch.unicode() == 95)
+ goto state_63;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_63;
goto out;
state_32:
- lastAcceptingPos = pos;
- token = QCss::TILDE;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_65;
+ if (ch.unicode() == 11)
+ goto state_65;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_65;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_65;
+ if (ch.unicode() >= 103)
+ goto state_65;
goto out;
state_33:
lastAcceptingPos = pos;
@@ -445,78 +448,75 @@ int QCssScanner_Generated::lex()
state_35:
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_63;
+ goto state_66;
if (ch.unicode() == 10)
- goto state_64;
+ goto state_67;
if (ch.unicode() == 11)
- goto state_63;
+ goto state_66;
if (ch.unicode() == 12)
- goto state_65;
+ goto state_69;
if (ch.unicode() == 13)
- goto state_66;
+ goto state_68;
if (ch.unicode() >= 14 && ch.unicode() <= 47)
- goto state_63;
+ goto state_66;
if (ch.unicode() >= 58 && ch.unicode() <= 96)
- goto state_63;
+ goto state_66;
if (ch.unicode() >= 103)
- goto state_63;
+ goto state_66;
goto out;
state_36:
lastAcceptingPos = pos;
- token = QCss::HASH;
+ token = QCss::S;
ch = next();
- if (ch.unicode() == 45)
- goto state_67;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_67;
- if (ch.unicode() == 92)
- goto state_68;
- if (ch.unicode() == 95)
- goto state_67;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_67;
+ if (ch.unicode() >= 9 && ch.unicode() <= 10)
+ goto state_36;
+ if (ch.unicode() >= 12 && ch.unicode() <= 13)
+ goto state_36;
+ if (ch.unicode() == 32)
+ goto state_36;
+ if (ch.unicode() == 43)
+ goto state_7;
+ if (ch.unicode() == 44)
+ goto state_14;
+ if (ch.unicode() == 62)
+ goto state_18;
+ if (ch.unicode() == 123)
+ goto state_22;
+ if (ch.unicode() == 126)
+ goto state_37;
goto out;
state_37:
- ch = next();
- if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_69;
- if (ch.unicode() == 11)
- goto state_69;
- if (ch.unicode() >= 14 && ch.unicode() <= 47)
- goto state_69;
- if (ch.unicode() >= 58 && ch.unicode() <= 96)
- goto state_69;
- if (ch.unicode() >= 103)
- goto state_69;
+ lastAcceptingPos = pos;
+ token = QCss::TILDE;
goto out;
- state_39:
+ state_38:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
- state_40:
+ state_39:
lastAcceptingPos = pos;
token = QCss::STRING;
goto out;
- state_41:
+ state_40:
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
goto state_70;
@@ -525,9 +525,9 @@ int QCssScanner_Generated::lex()
if (ch.unicode() == 11)
goto state_70;
if (ch.unicode() == 12)
- goto state_72;
- if (ch.unicode() == 13)
goto state_73;
+ if (ch.unicode() == 13)
+ goto state_72;
if (ch.unicode() >= 14 && ch.unicode() <= 47)
goto state_70;
if (ch.unicode() >= 58 && ch.unicode() <= 96)
@@ -535,13 +535,6 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 103)
goto state_70;
goto out;
- state_43:
- ch = next();
- if (ch.unicode() == 62) {
- token = QCss::CDC;
- goto found;
- }
- goto out;
state_44:
lastAcceptingPos = pos;
token = QCss::NUMBER;
@@ -549,15 +542,22 @@ int QCssScanner_Generated::lex()
if (ch.unicode() == 37)
goto state_46;
if (ch.unicode() == 45)
- goto state_47;
+ goto state_48;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_75;
+ goto state_74;
if (ch.unicode() == 92)
- goto state_50;
- if (ch.unicode() == 95)
goto state_51;
+ if (ch.unicode() == 95)
+ goto state_50;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_51;
+ goto state_50;
+ goto out;
+ state_45:
+ ch = next();
+ if (ch.unicode() == 62) {
+ token = QCss::CDC;
+ goto found;
+ }
goto out;
state_46:
lastAcceptingPos = pos;
@@ -565,17 +565,17 @@ int QCssScanner_Generated::lex()
goto out;
state_47:
ch = next();
- if (ch.unicode() == 92)
- goto state_50;
- if (ch.unicode() == 95)
- goto state_51;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_51;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_44;
goto out;
state_48:
ch = next();
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_44;
+ if (ch.unicode() == 92)
+ goto state_51;
+ if (ch.unicode() == 95)
+ goto state_50;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_50;
goto out;
state_49:
lastAcceptingPos = pos;
@@ -584,45 +584,45 @@ int QCssScanner_Generated::lex()
if (ch.unicode() == 37)
goto state_46;
if (ch.unicode() == 45)
- goto state_47;
- if (ch.unicode() == 46)
goto state_48;
+ if (ch.unicode() == 46)
+ goto state_47;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
goto state_49;
if (ch.unicode() == 92)
- goto state_50;
- if (ch.unicode() == 95)
goto state_51;
+ if (ch.unicode() == 95)
+ goto state_50;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_51;
+ goto state_50;
goto out;
state_50:
+ lastAcceptingPos = pos;
+ token = QCss::LENGTH;
ch = next();
- if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_76;
- if (ch.unicode() == 11)
+ if (ch.unicode() == 45)
goto state_76;
- if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
goto state_76;
- if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ if (ch.unicode() == 92)
+ goto state_77;
+ if (ch.unicode() == 95)
goto state_76;
- if (ch.unicode() >= 103)
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
goto state_76;
goto out;
state_51:
- lastAcceptingPos = pos;
- token = QCss::LENGTH;
ch = next();
- if (ch.unicode() == 45)
- goto state_77;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_77;
- if (ch.unicode() == 92)
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_78;
+ if (ch.unicode() == 11)
+ goto state_78;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_78;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_78;
+ if (ch.unicode() >= 103)
goto state_78;
- if (ch.unicode() == 95)
- goto state_77;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_77;
goto out;
state_52:
ch = next();
@@ -630,15 +630,27 @@ int QCssScanner_Generated::lex()
goto state_79;
goto out;
state_53:
+ lastAcceptingPos = pos;
+ token = QCss::FUNCTION;
+ goto out;
+ state_54:
+ lastAcceptingPos = pos;
+ token = QCss::IDENT;
ch = next();
- if (ch.unicode() == 92)
+ if (ch.unicode() == 40)
+ goto state_53;
+ if (ch.unicode() == 45)
goto state_54;
- if (ch.unicode() == 95)
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_54;
+ if (ch.unicode() == 92)
goto state_55;
+ if (ch.unicode() == 95)
+ goto state_54;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_55;
+ goto state_54;
goto out;
- state_54:
+ state_55:
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
goto state_80;
@@ -651,7 +663,16 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 103)
goto state_80;
goto out;
- state_55:
+ state_58:
+ ch = next();
+ if (ch.unicode() == 92)
+ goto state_60;
+ if (ch.unicode() == 95)
+ goto state_59;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_59;
+ goto out;
+ state_59:
lastAcceptingPos = pos;
token = QCss::ATKEYWORD_SYM;
ch = next();
@@ -666,58 +687,80 @@ int QCssScanner_Generated::lex()
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
goto state_81;
goto out;
- state_56:
+ state_60:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_83;
+ if (ch.unicode() == 11)
+ goto state_83;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_83;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_83;
+ if (ch.unicode() >= 103)
+ goto state_83;
+ goto out;
+ state_62:
lastAcceptingPos = pos;
token = QCss::IDENT;
ch = next();
if (ch.unicode() == 40)
- goto state_58;
+ goto state_53;
if (ch.unicode() == 45)
- goto state_59;
+ goto state_54;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_59;
+ goto state_54;
if (ch.unicode() == 92)
- goto state_60;
+ goto state_55;
if (ch.unicode() == 95)
- goto state_59;
+ goto state_54;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_59;
- goto out;
- state_58:
- lastAcceptingPos = pos;
- token = QCss::FUNCTION;
+ goto state_54;
goto out;
- state_59:
+ state_63:
lastAcceptingPos = pos;
- token = QCss::IDENT;
+ token = QCss::HASH;
ch = next();
- if (ch.unicode() == 40)
- goto state_58;
if (ch.unicode() == 45)
- goto state_59;
+ goto state_63;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_59;
+ goto state_63;
if (ch.unicode() == 92)
- goto state_60;
+ goto state_64;
if (ch.unicode() == 95)
- goto state_59;
+ goto state_63;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_59;
+ goto state_63;
goto out;
- state_60:
+ state_64:
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_83;
+ goto state_84;
if (ch.unicode() == 11)
- goto state_83;
+ goto state_84;
if (ch.unicode() >= 14 && ch.unicode() <= 47)
- goto state_83;
+ goto state_84;
if (ch.unicode() >= 58 && ch.unicode() <= 96)
- goto state_83;
+ goto state_84;
if (ch.unicode() >= 103)
- goto state_83;
+ goto state_84;
goto out;
- state_63:
+ state_65:
+ lastAcceptingPos = pos;
+ token = QCss::HASH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_63;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_63;
+ if (ch.unicode() == 92)
+ goto state_64;
+ if (ch.unicode() == 95)
+ goto state_63;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_63;
+ goto out;
+ state_66:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
@@ -740,7 +783,7 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 123)
goto state_33;
goto out;
- state_64:
+ state_67:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
@@ -763,12 +806,14 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 123)
goto state_33;
goto out;
- state_65:
+ state_68:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
goto state_33;
+ if (ch.unicode() == 10)
+ goto state_85;
if (ch.unicode() == 11)
goto state_33;
if (ch.unicode() >= 14 && ch.unicode() <= 33)
@@ -786,14 +831,12 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 123)
goto state_33;
goto out;
- state_66:
+ state_69:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
goto state_33;
- if (ch.unicode() == 10)
- goto state_84;
if (ch.unicode() == 11)
goto state_33;
if (ch.unicode() >= 14 && ch.unicode() <= 33)
@@ -811,191 +854,133 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 123)
goto state_33;
goto out;
- state_67:
- lastAcceptingPos = pos;
- token = QCss::HASH;
- ch = next();
- if (ch.unicode() == 45)
- goto state_67;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_67;
- if (ch.unicode() == 92)
- goto state_68;
- if (ch.unicode() == 95)
- goto state_67;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_67;
- goto out;
- state_68:
- ch = next();
- if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_85;
- if (ch.unicode() == 11)
- goto state_85;
- if (ch.unicode() >= 14 && ch.unicode() <= 47)
- goto state_85;
- if (ch.unicode() >= 58 && ch.unicode() <= 96)
- goto state_85;
- if (ch.unicode() >= 103)
- goto state_85;
- goto out;
- state_69:
- lastAcceptingPos = pos;
- token = QCss::HASH;
- ch = next();
- if (ch.unicode() == 45)
- goto state_67;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_67;
- if (ch.unicode() == 92)
- goto state_68;
- if (ch.unicode() == 95)
- goto state_67;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_67;
- goto out;
state_70:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
state_71:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
state_72:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
+ if (ch.unicode() == 10)
+ goto state_86;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
state_73:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
- if (ch.unicode() == 10)
- goto state_86;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
- state_75:
+ state_74:
lastAcceptingPos = pos;
token = QCss::NUMBER;
ch = next();
if (ch.unicode() == 37)
goto state_46;
if (ch.unicode() == 45)
- goto state_47;
+ goto state_48;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_75;
+ goto state_74;
if (ch.unicode() == 92)
- goto state_50;
- if (ch.unicode() == 95)
goto state_51;
+ if (ch.unicode() == 95)
+ goto state_50;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_51;
+ goto state_50;
goto out;
state_76:
lastAcceptingPos = pos;
token = QCss::LENGTH;
ch = next();
if (ch.unicode() == 45)
- goto state_77;
+ goto state_76;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_77;
+ goto state_76;
if (ch.unicode() == 92)
- goto state_78;
- if (ch.unicode() == 95)
- goto state_77;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_77;
- goto out;
- state_77:
- lastAcceptingPos = pos;
- token = QCss::LENGTH;
- ch = next();
- if (ch.unicode() == 45)
goto state_77;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_77;
- if (ch.unicode() == 92)
- goto state_78;
if (ch.unicode() == 95)
- goto state_77;
+ goto state_76;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_77;
+ goto state_76;
goto out;
- state_78:
+ state_77:
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
goto state_87;
@@ -1008,6 +993,21 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 103)
goto state_87;
goto out;
+ state_78:
+ lastAcceptingPos = pos;
+ token = QCss::LENGTH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_76;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_76;
+ if (ch.unicode() == 92)
+ goto state_77;
+ if (ch.unicode() == 95)
+ goto state_76;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_76;
+ goto out;
state_79:
ch = next();
if (ch.unicode() == 45) {
@@ -1017,18 +1017,20 @@ int QCssScanner_Generated::lex()
goto out;
state_80:
lastAcceptingPos = pos;
- token = QCss::ATKEYWORD_SYM;
+ token = QCss::IDENT;
ch = next();
+ if (ch.unicode() == 40)
+ goto state_53;
if (ch.unicode() == 45)
- goto state_81;
+ goto state_54;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_81;
+ goto state_54;
if (ch.unicode() == 92)
- goto state_82;
+ goto state_55;
if (ch.unicode() == 95)
- goto state_81;
+ goto state_54;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_81;
+ goto state_54;
goto out;
state_81:
lastAcceptingPos = pos;
@@ -1060,23 +1062,36 @@ int QCssScanner_Generated::lex()
goto out;
state_83:
lastAcceptingPos = pos;
- token = QCss::IDENT;
+ token = QCss::ATKEYWORD_SYM;
ch = next();
- if (ch.unicode() == 40)
- goto state_58;
if (ch.unicode() == 45)
- goto state_59;
+ goto state_81;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_59;
+ goto state_81;
if (ch.unicode() == 92)
- goto state_60;
+ goto state_82;
if (ch.unicode() == 95)
- goto state_59;
+ goto state_81;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_59;
+ goto state_81;
goto out;
state_84:
lastAcceptingPos = pos;
+ token = QCss::HASH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_63;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_63;
+ if (ch.unicode() == 92)
+ goto state_64;
+ if (ch.unicode() == 95)
+ goto state_63;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_63;
+ goto out;
+ state_85:
+ lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
@@ -1098,58 +1113,43 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 123)
goto state_33;
goto out;
- state_85:
- lastAcceptingPos = pos;
- token = QCss::HASH;
- ch = next();
- if (ch.unicode() == 45)
- goto state_67;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_67;
- if (ch.unicode() == 92)
- goto state_68;
- if (ch.unicode() == 95)
- goto state_67;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_67;
- goto out;
state_86:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
state_87:
lastAcceptingPos = pos;
token = QCss::LENGTH;
ch = next();
if (ch.unicode() == 45)
- goto state_77;
+ goto state_76;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_77;
+ goto state_76;
if (ch.unicode() == 92)
- goto state_78;
- if (ch.unicode() == 95)
goto state_77;
+ if (ch.unicode() == 95)
+ goto state_76;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_77;
+ goto state_76;
goto out;
state_89:
lastAcceptingPos = pos;
@@ -1176,4 +1176,3 @@ int QCssScanner_Generated::lex()
}
return token;
}
-
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 69255fd59d..a51e98ce85 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -116,7 +116,17 @@ bool QFontDef::exactMatch(const QFontDef &other) const
if (stretch != 0 && other.stretch != 0 && stretch != other.stretch)
return false;
+ if (families.size() != other.families.size())
+ return false;
+
QString this_family, this_foundry, other_family, other_foundry;
+ for (int i = 0; i < families.size(); ++i) {
+ QFontDatabase::parseFontName(families.at(i), this_foundry, this_family);
+ QFontDatabase::parseFontName(other.families.at(i), other_foundry, other_family);
+ if (this_family != other_family || this_foundry != other_foundry)
+ return false;
+ }
+
QFontDatabase::parseFontName(family, this_foundry, this_family);
QFontDatabase::parseFontName(other.family, other_foundry, other_family);
@@ -261,6 +271,9 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
if (! (mask & QFont::FamilyResolved))
request.family = other->request.family;
+ if (!(mask & QFont::FamiliesResolved))
+ request.families = other->request.families;
+
if (! (mask & QFont::StyleNameResolved))
request.styleName = other->request.styleName;
@@ -340,7 +353,7 @@ QFontEngineData::~QFontEngineData()
\class QFont
\reentrant
- \brief The QFont class specifies a font used for drawing text.
+ \brief The QFont class specifies a query for a font used for drawing text.
\ingroup painting
\ingroup appearance
@@ -348,6 +361,7 @@ QFontEngineData::~QFontEngineData()
\ingroup richtext-processing
\inmodule QtGui
+ QFont can be regarded as a query for one or more fonts on the system.
When you create a QFont object you specify various attributes that
you want the font to have. Qt will use the font with the specified
@@ -355,9 +369,15 @@ QFontEngineData::~QFontEngineData()
matching installed font. The attributes of the font that is
actually used are retrievable from a QFontInfo object. If the
window system provides an exact match exactMatch() returns \c true.
- Use QFontMetrics to get measurements, e.g. the pixel length of a
+ Use QFontMetricsF to get measurements, e.g. the pixel length of a
string using QFontMetrics::width().
+ Attributes which are not specifically set will not affect the font
+ selection algorithm, and default values will be preferred instead.
+
+ To load a specific physical font, typically represented by a single file,
+ use QRawFont instead.
+
Note that a QGuiApplication instance must exist before a QFont can be
used. You can set the application's default font with
QGuiApplication::setFont().
@@ -390,8 +410,6 @@ QFontEngineData::~QFontEngineData()
setStyleHint(). The default family (corresponding to the current
style hint) is returned by defaultFamily().
- The font-matching algorithm has a lastResortFamily() and
- lastResortFont() in cases where a suitable match cannot be found.
You can provide substitutions for font family names using
insertSubstitution() and insertSubstitutions(). Substitutions can
be removed with removeSubstitutions(). Use substitute() to retrieve
@@ -419,18 +437,21 @@ QFontEngineData::~QFontEngineData()
\target fontmatching
The font matching algorithm works as follows:
\list 1
- \li The specified font family is searched for.
- \li If not found, the styleHint() is used to select a replacement
- family.
- \li Each replacement font family is searched for.
- \li If none of these are found or there was no styleHint(), "helvetica"
- will be searched for.
- \li If "helvetica" isn't found Qt will try the lastResortFamily().
- \li If the lastResortFamily() isn't found Qt will try the
- lastResortFont() which will always return a name of some kind.
+ \li The specified font families (set by setFamilies()) are searched for.
+ \li If not found, then if set the specified font family exists and can be used to represent
+ the writing system in use, it will be selected.
+ \li If not, a replacement font that supports the writing system is
+ selected. The font matching algorithm will try to find the
+ best match for all the properties set in the QFont. How this is
+ done varies from platform to platform.
+ \li If no font exists on the system that can support the text,
+ then special "missing character" boxes will be shown in its place.
\endlist
- Note that the actual font matching algorithm varies from platform to platform.
+ \note If the selected font, though supporting the writing system in general,
+ is missing glyphs for one or more specific characters, then Qt will try to
+ find a fallback font for this or these particular characters. This feature
+ can be disabled using QFont::NoFontMerging style strategy.
In Windows a request for the "Courier" font is automatically changed to
"Courier New", an improved version of Courier that allows for smooth scaling.
@@ -499,6 +520,7 @@ QFontEngineData::~QFontEngineData()
individually and then considered resolved.
\value FamilyResolved
+ \value FamiliesResolved
\value SizeResolved
\value StyleHintResolved
\value StyleStrategyResolved
@@ -540,14 +562,25 @@ QFontEngineData::~QFontEngineData()
\since 5.2
*/
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
/*!
+ \obsolete
Constructs a font from \a font for use on the paint device \a pd.
*/
QFont::QFont(const QFont &font, QPaintDevice *pd)
+ : QFont(font, static_cast<const QPaintDevice*>(pd))
+{}
+#endif
+
+/*!
+ \since 5.13
+ Constructs a font from \a font for use on the paint device \a pd.
+*/
+QFont::QFont(const QFont &font, const QPaintDevice *pd)
: resolve_mask(font.resolve_mask)
{
- Q_ASSERT(pd != 0);
- int dpi = pd->logicalDpiY();
+ Q_ASSERT(pd);
+ const int dpi = pd->logicalDpiY();
const int screen = 0;
if (font.d->dpi != dpi || font.d->screen != screen ) {
d = new QFontPrivate(*font.d);
@@ -1684,6 +1717,7 @@ bool QFont::operator<(const QFont &f) const
if (r1.stretch != r2.stretch) return r1.stretch < r2.stretch;
if (r1.styleHint != r2.styleHint) return r1.styleHint < r2.styleHint;
if (r1.styleStrategy != r2.styleStrategy) return r1.styleStrategy < r2.styleStrategy;
+ if (r1.families != r2.families) return r1.families < r2.families;
if (r1.family != r2.family) return r1.family < r2.family;
if (f.d->capital != d->capital) return f.d->capital < d->capital;
@@ -2133,21 +2167,22 @@ void QFont::cacheStatistics()
{
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn QString QFont::lastResortFamily() const
- Returns the "last resort" font family name.
+ \obsolete
- The current implementation tries a wide variety of common fonts,
- returning the first one it finds. Is is possible that no family is
- found in which case an empty string is returned.
+ This function is deprecated and is not in use by the font
+ selection algorithm in Qt 5. It always returns "helvetica".
\sa lastResortFont()
*/
QString QFont::lastResortFamily() const
{
- return QString::fromLatin1("helvetica");
+ return QStringLiteral("helvetica");
}
+#endif
extern QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style,
QFont::StyleHint styleHint, QChar::Script script);
@@ -2169,34 +2204,66 @@ QString QFont::defaultFamily() const
return QString();
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn QString QFont::lastResortFont() const
- Returns a "last resort" font name for the font matching algorithm.
- This is used if the last resort family is not available. It will
- always return a name, if necessary returning something like
- "fixed" or "system".
+ \obsolete
+
+ Deprecated function. Since Qt 5.0, this is not used by the font selection algorithm. For
+ compatibility it remains in the API, but will always return the same value as lastResortFamily().
+*/
+QString QFont::lastResortFont() const
+{
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ return lastResortFamily();
+QT_WARNING_POP
+}
+#endif
+
+/*!
+ \since 5.13
+
+ Returns the requested font family names, i.e. the names set in the last
+ setFamilies() call or via the constructor. Otherwise it returns an
+ empty list.
+
+ \sa setFamily(), setFamilies(), family(), substitutes(), substitute()
+*/
+
+QStringList QFont::families() const
+{
+ return d->request.families;
+}
- The current implementation tries a wide variety of common fonts,
- returning the first one it finds. The implementation may change
- at any time, but this function will always return a string
- containing something.
+/*!
+ \since 5.13
- It is theoretically possible that there really isn't a
- lastResortFont() in which case Qt will abort with an error
- message. We have not been able to identify a case where this
- happens. Please \l{bughowto.html}{report it as a bug} if
- it does, preferably with a list of the fonts you have installed.
+ Sets the list of family names for the font. The names are case
+ insensitive and may include a foundry name. The first family in
+ \a families will be set as the main family for the font.
- \sa lastResortFamily()
+ Each family name entry in \a families may optionally also include a
+ foundry name, e.g. "Helvetica [Cronyx]". If the family is
+ available from more than one foundry and the foundry isn't
+ specified, an arbitrary foundry is chosen. If the family isn't
+ available a family will be set using the \l{QFont}{font matching}
+ algorithm.
+
+ \sa family(), families(), setFamily(), setStyleHint(), QFontInfo
*/
-QString QFont::lastResortFont() const
+
+void QFont::setFamilies(const QStringList &families)
{
- qFatal("QFont::lastResortFont: Cannot find any reasonable font");
- // Shut compiler up
- return QString();
+ if ((resolve_mask & QFont::FamiliesResolved) && d->request.families == families)
+ return;
+ detach();
+ d->request.families = families;
+ resolve_mask |= QFont::FamiliesResolved;
}
+
/*****************************************************************************
QFont stream functions
*****************************************************************************/
@@ -2261,6 +2328,8 @@ QDataStream &operator<<(QDataStream &s, const QFont &font)
s << (quint8)font.d->request.hintingPreference;
if (s.version() >= QDataStream::Qt_5_6)
s << (quint8)font.d->capital;
+ if (s.version() >= QDataStream::Qt_5_13)
+ s << font.d->request.families;
return s;
}
@@ -2356,6 +2425,11 @@ QDataStream &operator>>(QDataStream &s, QFont &font)
s >> value;
font.d->capital = QFont::Capitalization(value);
}
+ if (s.version() >= QDataStream::Qt_5_13) {
+ QStringList value;
+ s >> value;
+ font.d->request.families = value;
+ }
return s;
}
@@ -2879,9 +2953,9 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMu
data.timestamp = ++current_timestamp;
if (insertMulti)
- engineCache.insertMulti(key, data);
- else
engineCache.insert(key, data);
+ else
+ engineCache.replace(key, data);
// only increase the cost if this is the first time we insert the engine
if (++engineCacheCount[engine] == 1)
increaseCost(engine->cache_cost);
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index 9c250c82c3..e86f06353a 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -164,13 +164,17 @@ public:
WordSpacingResolved = 0x4000,
HintingPreferenceResolved = 0x8000,
StyleNameResolved = 0x10000,
- AllPropertiesResolved = 0x1ffff
+ FamiliesResolved = 0x20000,
+ AllPropertiesResolved = 0x3ffff
};
QFont();
QFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false);
- QFont(const QFont &, QPaintDevice *pd);
- QFont(const QFont &);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ QFont(const QFont &font, QPaintDevice *pd);
+#endif
+ QFont(const QFont &font, const QPaintDevice *pd);
+ QFont(const QFont &font);
~QFont();
void swap(QFont &other)
@@ -179,6 +183,9 @@ public:
QString family() const;
void setFamily(const QString &);
+ QStringList families() const;
+ void setFamilies(const QStringList &);
+
QString styleName() const;
void setStyleName(const QString &);
@@ -282,8 +289,10 @@ public:
static void cacheStatistics();
QString defaultFamily() const;
- QString lastResortFamily() const;
- QString lastResortFont() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED QString lastResortFamily() const;
+ QT_DEPRECATED QString lastResortFont() const;
+#endif
QFont resolve(const QFont &) const;
inline uint resolve() const { return resolve_mask; }
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index c5847f532b..e86ec31e47 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -78,6 +78,7 @@ struct QFontDef
}
QString family;
+ QStringList families;
QString styleName;
QStringList fallBackFamilies;
@@ -109,6 +110,7 @@ struct QFontDef
&& styleStrategy == other.styleStrategy
&& ignorePitch == other.ignorePitch && fixedPitch == other.fixedPitch
&& family == other.family
+ && families == other.families
&& styleName == other.styleName
&& hintingPreference == other.hintingPreference
;
@@ -122,6 +124,7 @@ struct QFontDef
if (styleHint != other.styleHint) return styleHint < other.styleHint;
if (styleStrategy != other.styleStrategy) return styleStrategy < other.styleStrategy;
if (family != other.family) return family < other.family;
+ if (families != other.families) return families < other.families;
if (styleName != other.styleName)
return styleName < other.styleName;
if (hintingPreference != other.hintingPreference) return hintingPreference < other.hintingPreference;
@@ -144,6 +147,7 @@ inline uint qHash(const QFontDef &fd, uint seed = 0) Q_DECL_NOTHROW
^ qHash(fd.ignorePitch)
^ qHash(fd.fixedPitch)
^ qHash(fd.family, seed)
+ ^ qHash(fd.families, seed)
^ qHash(fd.styleName)
^ qHash(fd.hintingPreference)
;
@@ -161,7 +165,7 @@ public:
QFontEngine *engines[QChar::ScriptCount];
private:
- Q_DISABLE_COPY(QFontEngineData)
+ Q_DISABLE_COPY_MOVE(QFontEngineData)
};
@@ -270,7 +274,7 @@ public:
uint hits;
};
- typedef QMap<Key,Engine> EngineCache;
+ typedef QMultiMap<Key,Engine> EngineCache;
EngineCache engineCache;
QHash<QFontEngine *, int> engineCacheCount;
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 196eebb353..fa9573441a 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -696,20 +696,20 @@ static QStringList familyList(const QFontDef &req)
{
// list of families to try
QStringList family_list;
- if (req.family.isEmpty())
- return family_list;
- const auto list = req.family.splitRef(QLatin1Char(','));
- const int numFamilies = list.size();
- family_list.reserve(numFamilies);
- for (int i = 0; i < numFamilies; ++i) {
- QStringRef str = list.at(i).trimmed();
- if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"')))
- || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\''))))
- str = str.mid(1, str.length() - 2);
- family_list << str.toString();
+ family_list << req.families;
+ if (!req.family.isEmpty()) {
+ const auto list = req.family.splitRef(QLatin1Char(','));
+ const int numFamilies = list.size();
+ family_list.reserve(numFamilies);
+ for (int i = 0; i < numFamilies; ++i) {
+ QStringRef str = list.at(i).trimmed();
+ if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"')))
+ || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\''))))
+ str = str.mid(1, str.length() - 2);
+ family_list << str.toString();
+ }
}
-
// append the substitute list for each family in family_list
for (int i = 0, size = family_list.size(); i < size; ++i)
family_list += QFont::substitutes(family_list.at(i));
@@ -2688,9 +2688,8 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
}
QString family_name, foundry_name;
-
- parseFontName(request.family, foundry_name, family_name);
-
+ const QString requestFamily = request.families.size() > 0 ? request.families.at(0) : request.family;
+ parseFontName(requestFamily, foundry_name, family_name);
QtFontDesc desc;
QList<int> blackListed;
int index = match(multi ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed);
@@ -2703,8 +2702,8 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
// Don't pass empty family names to the platform font database, since it will then invoke its own matching
// and we will be out of sync with the matched font.
- if (fontDef.family.isEmpty())
- fontDef.family = desc.family->name;
+ if (fontDef.families.isEmpty() && fontDef.family.isEmpty())
+ fontDef.families = QStringList(desc.family->name);
engine = loadEngine(script, fontDef, desc.family, desc.foundry, desc.style, desc.size);
@@ -2717,13 +2716,13 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
}
if (!engine) {
- if (!request.family.isEmpty()) {
+ if (!requestFamily.isEmpty()) {
QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
if (styleHint == QFont::AnyStyle && request.fixedPitch)
styleHint = QFont::TypeWriter;
QStringList fallbacks = request.fallBackFamilies
- + fallbacksForFamily(request.family,
+ + fallbacksForFamily(requestFamily,
QFont::Style(request.style),
styleHint,
QChar::Script(script));
@@ -2741,7 +2740,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
index = match(multi ? QChar::Script_Common : script, def, def.family, QLatin1String(""), &desc, blackListed);
if (index >= 0) {
QFontDef loadDef = def;
- if (loadDef.family.isEmpty())
+ if (loadDef.families.isEmpty() && loadDef.family.isEmpty())
loadDef.family = desc.family->name;
engine = loadEngine(script, loadDef, desc.family, desc.foundry, desc.style, desc.size);
if (engine)
@@ -2782,7 +2781,10 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
// look for the requested font in the engine data cache
// note: fallBackFamilies are not respected in the EngineData cache key;
// join them with the primary selection family to avoid cache misses
- req.family = fallBackFamilies.join(QLatin1Char(','));
+ if (!d->request.family.isEmpty())
+ req.family = fallBackFamilies.join(QLatin1Char(','));
+ if (!d->request.families.isEmpty())
+ req.families = fallBackFamilies;
d->engineData = fontCache->findEngineData(req);
if (!d->engineData) {
@@ -2803,14 +2805,14 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
req.fallBackFamilies = fallBackFamilies;
if (!req.fallBackFamilies.isEmpty())
- req.family = req.fallBackFamilies.takeFirst();
+ req.families = QStringList(req.fallBackFamilies.takeFirst());
// list of families to try
QStringList family_list;
- if (!req.family.isEmpty()) {
+ if (!req.families.isEmpty()) {
// Add primary selection
- family_list << req.family;
+ family_list << req.families.at(0);
// add the default family
QString defaultFamily = QGuiApplication::font().family();
@@ -2824,11 +2826,11 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
for (; !fe && it != end; ++it) {
- req.family = *it;
+ req.families = QStringList(*it);
fe = QFontDatabase::findFont(req, script);
if (fe) {
- if (fe->type() == QFontEngine::Box && !req.family.isEmpty()) {
+ if (fe->type() == QFontEngine::Box && !req.families.at(0).isEmpty()) {
if (fe->ref.load() == 0)
delete fe;
fe = 0;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index eb7e416dd1..1719855e68 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1022,8 +1022,8 @@ void QFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metr
Returns \c true if the font table idetified by \a tag exists in the font;
returns \c false otherwise.
- If \a buffer is NULL, stores the size of the buffer required for the font table data,
- in bytes, in \a length. If \a buffer is not NULL and the capacity
+ If \a buffer is \nullptr, stores the size of the buffer required for the font table data,
+ in bytes, in \a length. If \a buffer is not \nullptr and the capacity
of the buffer, passed in \a length, is sufficient to store the font table data,
also copies the font table data to \a buffer.
@@ -1843,6 +1843,7 @@ QFontEngine *QFontEngineMulti::loadEngine(int at)
QFontDef request(fontDef);
request.styleStrategy |= QFont::NoFontMerging;
request.family = fallbackFamilyAt(at - 1);
+ request.families = QStringList(request.family);
// At this point, the main script of the text has already been considered
// when fetching the list of fallback families from the database, and the
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 407559ad51..c8dc8d676e 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -156,6 +156,8 @@ QFontMetrics::QFontMetrics(const QFont &font)
}
/*!
+ \since 5.13
+ \fn QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice)
Constructs a font metrics object for \a font and \a paintdevice.
The font metrics will be compatible with the paintdevice passed.
@@ -168,9 +170,21 @@ QFontMetrics::QFontMetrics(const QFont &font)
passed in the constructor at the time it is created, and is not
updated if the font's attributes are changed later.
*/
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \fn QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
+ \obsolete
+ Identical to QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice)
+*/
+
+
QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
+#else
+QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice)
+#endif
{
- int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
+ const int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
const int screen = 0;
if (font.d->dpi != dpi || font.d->screen != screen ) {
d = new QFontPrivate(*font.d);
@@ -1127,6 +1141,8 @@ QFontMetricsF::QFontMetricsF(const QFont &font)
}
/*!
+ \fn QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice)
+ \since 5.13
Constructs a font metrics object for \a font and \a paintdevice.
The font metrics will be compatible with the paintdevice passed.
@@ -1139,7 +1155,20 @@ QFontMetricsF::QFontMetricsF(const QFont &font)
passed in the constructor at the time it is created, and is not
updated if the font's attributes are changed later.
*/
+
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \fn QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
+ \obsolete
+ Identical to QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice)
+*/
+
+
QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
+#else
+QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice)
+#endif
{
int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
const int screen = 0;
diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h
index b6167a1d47..61931fa9bc 100644
--- a/src/gui/text/qfontmetrics.h
+++ b/src/gui/text/qfontmetrics.h
@@ -59,7 +59,19 @@ class Q_GUI_EXPORT QFontMetrics
{
public:
explicit QFontMetrics(const QFont &);
- QFontMetrics(const QFont &, QPaintDevice *pd);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ QFontMetrics(const QFont &font, QPaintDevice *pd);
+#ifndef Q_QDOC
+ // the template is necessary to make QFontMetrics(font,nullptr) and QFontMetrics(font,NULL)
+ // not ambiguous. Implementation detail that should not be documented.
+ template<char = 0>
+#endif
+ QFontMetrics(const QFont &font, const QPaintDevice *pd)
+ : QFontMetrics(font, const_cast<QPaintDevice*>(pd))
+ {}
+#else
+ QFontMetrics(const QFont &font, const QPaintDevice *pd);
+#endif
QFontMetrics(const QFontMetrics &);
~QFontMetrics();
@@ -92,8 +104,11 @@ public:
int rightBearing(QChar) const;
#if QT_DEPRECATED_SINCE(5, 11)
+ QT_DEPRECATED_X("Use QFontMetrics::horizontalAdvance")
int width(const QString &, int len = -1) const;
+ QT_DEPRECATED_X("Use QFontMetrics::horizontalAdvance")
int width(const QString &, int len, int flags) const;
+ QT_DEPRECATED_X("Use QFontMetrics::horizontalAdvance")
int width(QChar) const;
#endif
@@ -137,8 +152,20 @@ Q_DECLARE_SHARED(QFontMetrics)
class Q_GUI_EXPORT QFontMetricsF
{
public:
- explicit QFontMetricsF(const QFont &);
- QFontMetricsF(const QFont &, QPaintDevice *pd);
+ explicit QFontMetricsF(const QFont &font);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ QFontMetricsF(const QFont &font, QPaintDevice *pd);
+#ifndef Q_QDOC
+ // the template is necessary to make QFontMetrics(font,nullptr) and QFontMetrics(font,NULL)
+ // not ambiguous. Implementation detail that should not be documented.
+ template<char = 0>
+#endif
+ QFontMetricsF(const QFont &font, const QPaintDevice *pd)
+ : QFontMetricsF(font, const_cast<QPaintDevice*>(pd))
+ {}
+#else
+ QFontMetricsF(const QFont &font, const QPaintDevice *pd);
+#endif
QFontMetricsF(const QFontMetrics &);
QFontMetricsF(const QFontMetricsF &);
~QFontMetricsF();
diff --git a/src/gui/text/qsyntaxhighlighter.h b/src/gui/text/qsyntaxhighlighter.h
index d87f89f0fd..ad0d50a4c0 100644
--- a/src/gui/text/qsyntaxhighlighter.h
+++ b/src/gui/text/qsyntaxhighlighter.h
@@ -64,7 +64,7 @@ class Q_GUI_EXPORT QSyntaxHighlighter : public QObject
public:
explicit QSyntaxHighlighter(QObject *parent);
explicit QSyntaxHighlighter(QTextDocument *parent);
- virtual ~QSyntaxHighlighter();
+ ~QSyntaxHighlighter();
void setDocument(QTextDocument *doc);
QTextDocument *document() const;
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 4f187c6701..fd3473b32e 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -2663,10 +2663,10 @@ void QTextHtmlExporter::emitFragment(const QTextFragment &fragment)
bool closeAnchor = false;
if (format.isAnchor()) {
- const QString name = format.anchorName();
- if (!name.isEmpty()) {
+ const auto names = format.anchorNames();
+ if (!names.isEmpty()) {
html += QLatin1String("<a name=\"");
- html += name.toHtmlEscaped();
+ html += names.constFirst().toHtmlEscaped();
html += QLatin1String("\"></a>");
}
const QString href = format.anchorHref();
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index 66e038122c..c0a0c1a177 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -275,7 +275,7 @@ void QTextDocumentPrivate::clear()
init();
cursors = oldCursors;
inContentsChange = true;
- q->contentsChange(0, len, 0);
+ emit q->contentsChange(0, len, 0);
inContentsChange = false;
if (lout)
lout->documentChanged(0, len, 0);
diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp
index 6b3604afb5..aef4ea1522 100644
--- a/src/gui/text/qtextdocumentfragment.cpp
+++ b/src/gui/text/qtextdocumentfragment.cpp
@@ -542,8 +542,10 @@ void QTextHtmlImporter::import()
}
}
- if (currentNode->charFormat.isAnchor() && !currentNode->charFormat.anchorName().isEmpty()) {
- namedAnchors.append(currentNode->charFormat.anchorName());
+ if (currentNode->charFormat.isAnchor()) {
+ const auto names = currentNode->charFormat.anchorNames();
+ if (!names.isEmpty())
+ namedAnchors.append(names.constFirst());
}
if (appendNodeText())
diff --git a/src/gui/text/qtextdocumentfragment_p.h b/src/gui/text/qtextdocumentfragment_p.h
index 02a6a429fa..de01a02fbb 100644
--- a/src/gui/text/qtextdocumentfragment_p.h
+++ b/src/gui/text/qtextdocumentfragment_p.h
@@ -109,7 +109,7 @@ public:
uint importedFromPlainText : 1;
private:
- Q_DISABLE_COPY(QTextDocumentFragmentPrivate)
+ Q_DISABLE_COPY_MOVE(QTextDocumentFragmentPrivate)
};
#ifndef QT_NO_TEXTHTMLPARSER
diff --git a/src/gui/text/qtextdocumentwriter.cpp b/src/gui/text/qtextdocumentwriter.cpp
index 5ea04fe9e9..42e623153a 100644
--- a/src/gui/text/qtextdocumentwriter.cpp
+++ b/src/gui/text/qtextdocumentwriter.cpp
@@ -206,8 +206,8 @@ void QTextDocumentWriter::setDevice (QIODevice *device)
}
/*!
- Returns the device currently assigned, or 0 if no device has been
- assigned.
+ Returns the device currently assigned, or \nullptr if no device
+ has been assigned.
*/
QIODevice *QTextDocumentWriter::device () const
{
@@ -270,7 +270,7 @@ bool QTextDocumentWriter::write(const QTextDocument *document)
#ifndef QT_NO_TEXTHTMLPARSER
if (format == "html" || format == "htm") {
if (!d->device->isWritable() && ! d->device->open(QIODevice::WriteOnly)) {
- qWarning("QTextDocumentWriter::write: the device can not be opened for writing");
+ qWarning("QTextDocumentWriter::write: the device cannot be opened for writing");
return false;
}
QTextStream ts(d->device);
@@ -284,7 +284,7 @@ bool QTextDocumentWriter::write(const QTextDocument *document)
#endif
if (format == "txt" || format == "plaintext") {
if (!d->device->isWritable() && ! d->device->open(QIODevice::WriteOnly)) {
- qWarning("QTextDocumentWriter::write: the device can not be opened for writing");
+ qWarning("QTextDocumentWriter::write: the device cannot be opened for writing");
return false;
}
QTextStream ts(d->device);
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 919cdf3ff1..4a2985f74c 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -361,6 +361,12 @@ void QTextFormatPrivate::recalcFont() const
case QTextFormat::FontFamily:
f.setFamily(props.at(i).value.toString());
break;
+ case QTextFormat::FontFamilies:
+ f.setFamilies(props.at(i).value.toStringList());
+ break;
+ case QTextFormat::FontStyleName:
+ f.setStyleName(props.at(i).value.toString());
+ break;
case QTextFormat::FontPointSize:
f.setPointSizeF(props.at(i).value.toReal());
break;
@@ -562,6 +568,8 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
Character properties
\value FontFamily
+ \value FontFamilies
+ \value FontStyleName
\value FontPointSize
\value FontPixelSize
\value FontSizeAdjustment Specifies the change in size given to the fontsize already set using
@@ -1391,6 +1399,41 @@ QTextCharFormat::QTextCharFormat(const QTextFormat &fmt)
\sa font()
*/
+/*!
+ \fn void QTextCharFormat::setFontFamilies(const QStringList &families)
+ \since 5.13
+
+ Sets the text format's font \a families.
+
+ \sa setFont()
+*/
+
+/*!
+ \fn QStringList QTextCharFormat::fontFamilies() const
+ \since 5.13
+
+ Returns the text format's font families.
+
+ \sa font()
+*/
+
+/*!
+ \fn void QTextCharFormat::setFontStyleName(const QString &styleName)
+ \since 5.13
+
+ Sets the text format's font \a styleName.
+
+ \sa setFont(), QFont::setStyleName()
+*/
+
+/*!
+ \fn QStringList QTextCharFormat::fontStyleName() const
+ \since 5.13
+
+ Returns the text format's font style name.
+
+ \sa font(), QFont::styleName()
+*/
/*!
\fn void QTextCharFormat::setFontPointSize(qreal size)
@@ -1744,6 +1787,7 @@ void QTextCharFormat::setUnderlineStyle(UnderlineStyle style)
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn void QTextCharFormat::setAnchorName(const QString &name)
\obsolete
@@ -1754,6 +1798,7 @@ void QTextCharFormat::setUnderlineStyle(UnderlineStyle style)
hyperlink, the destination must be set with setAnchorHref() and
the anchor must be enabled with setAnchor().
*/
+#endif
/*!
\fn void QTextCharFormat::setAnchorNames(const QStringList &names)
@@ -1764,6 +1809,7 @@ void QTextCharFormat::setUnderlineStyle(UnderlineStyle style)
the anchor must be enabled with setAnchor().
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn QString QTextCharFormat::anchorName() const
\obsolete
@@ -1783,6 +1829,7 @@ QString QTextCharFormat::anchorName() const
return QString();
return prop.toString();
}
+#endif
/*!
\fn QStringList QTextCharFormat::anchorNames() const
@@ -1920,6 +1967,11 @@ void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavi
if (mask & QFont::FamilyResolved)
setFontFamily(font.family());
+ if (mask & QFont::FamiliesResolved)
+ setFontFamilies(font.families());
+ if (mask & QFont::StyleNameResolved)
+ setFontStyleName(font.styleName());
+
if (mask & QFont::SizeResolved) {
const qreal pointSize = font.pointSizeF();
if (pointSize > 0) {
diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h
index a8e573d5a4..80d8e82694 100644
--- a/src/gui/text/qtextformat.h
+++ b/src/gui/text/qtextformat.h
@@ -188,6 +188,8 @@ public:
FontStyleStrategy = 0x1FE4,
FontKerning = 0x1FE5,
FontHintingPreference = 0x1FE6,
+ FontFamilies = 0x1FE7,
+ FontStyleName = 0x1FE8,
FontFamily = 0x2000,
FontPointSize = 0x2001,
FontSizeAdjustment = 0x2002,
@@ -428,6 +430,16 @@ public:
inline QString fontFamily() const
{ return stringProperty(FontFamily); }
+ inline void setFontFamilies(const QStringList &families)
+ { setProperty(FontFamilies, QVariant(families)); }
+ inline QVariant fontFamilies() const
+ { return property(FontFamilies); }
+
+ inline void setFontStyleName(const QString &styleName)
+ { setProperty(FontStyleName, styleName); }
+ inline QVariant fontStyleName() const
+ { return property(FontStyleName); }
+
inline void setFontPointSize(qreal size)
{ setProperty(FontPointSize, size); }
inline qreal fontPointSize() const
@@ -540,9 +552,13 @@ public:
inline QString anchorHref() const
{ return stringProperty(AnchorHref); }
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use setAnchorNames() instead")
inline void setAnchorName(const QString &name)
{ setAnchorNames(QStringList(name)); }
+ QT_DEPRECATED_X("Use anchorNames() instead")
QString anchorName() const;
+#endif
inline void setAnchorNames(const QStringList &names)
{ setProperty(AnchorName, names); }
diff --git a/src/gui/text/qtextformat_p.h b/src/gui/text/qtextformat_p.h
index 3557c17a97..001a243e84 100644
--- a/src/gui/text/qtextformat_p.h
+++ b/src/gui/text/qtextformat_p.h
@@ -104,7 +104,7 @@ public:
private:
QFont defaultFnt;
- Q_DISABLE_COPY(QTextFormatCollection)
+ Q_DISABLE_COPY_MOVE(QTextFormatCollection)
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index c9a2a33e5a..adc3b138f7 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -861,7 +861,8 @@ QString QTextHtmlParser::parseWord()
++pos;
while (pos < len) {
QChar c = txt.at(pos++);
- if (c == QLatin1Char('\''))
+ // Allow for escaped single quotes as they may be part of the string
+ if (c == QLatin1Char('\'') && (txt.length() > 1 && txt.at(pos - 2) != QLatin1Char('\\')))
break;
else
word += c;
@@ -1543,7 +1544,7 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
if (key == QLatin1String("href"))
node->charFormat.setAnchorHref(value);
else if (key == QLatin1String("name"))
- node->charFormat.setAnchorName(value);
+ node->charFormat.setAnchorNames({value});
break;
case Html_img:
if (key == QLatin1String("src") || key == QLatin1String("source")) {
@@ -1683,7 +1684,7 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
node->charFormat.setToolTip(value);
} else if (key == QLatin1String("id")) {
node->charFormat.setAnchor(true);
- node->charFormat.setAnchorName(value);
+ node->charFormat.setAnchorNames({value});
}
}
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index f3f0caa379..a3e194f835 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -344,6 +344,8 @@ QTextLayout::QTextLayout(const QString& text)
}
/*!
+ \since 5.13
+ \fn QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
Constructs a text layout to lay out the given \a text with the specified
\a font.
@@ -351,11 +353,20 @@ QTextLayout::QTextLayout(const QString& text)
the paint device, \a paintdevice. If \a paintdevice is 0 the
calculations will be done in screen metrics.
*/
-QTextLayout::QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice)
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \fn QTextLayout::QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice)
+ \obsolete
+ Identical to QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
+*/
+
+QTextLayout::QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice)
+#else
+QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
+#endif
{
- QFont f(font);
- if (paintdevice)
- f = QFont(font, paintdevice);
+ const QFont f(paintdevice ? QFont(font, paintdevice) : font);
d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f);
}
@@ -1127,8 +1138,6 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRang
QPainterPath textDoneRegion;
for (int i = 0; i < selections.size(); ++i) {
FormatRange selection = selections.at(i);
- const QBrush bg = selection.format.background();
-
QPainterPath region;
region.setFillRule(Qt::WindingFill);
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index 67bc75a6b8..a29791534e 100644
--- a/src/gui/text/qtextlayout.h
+++ b/src/gui/text/qtextlayout.h
@@ -107,7 +107,19 @@ public:
// does itemization
QTextLayout();
QTextLayout(const QString& text);
- QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice = nullptr);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice = nullptr);
+#ifndef Q_QDOC
+ // the template is necessary to make QTextLayout(font,text,nullptr) and QTextLayout(font,text,NULL)
+ // not ambiguous. Implementation detail that should not be documented.
+ template<char = 0>
+#endif
+ QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
+ : QTextLayout(text, font, const_cast<QPaintDevice*>(paintdevice))
+ {}
+#else
+ QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice = nullptr);
+#endif
QTextLayout(const QTextBlock &b);
~QTextLayout();
diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp
index bec33d5f4d..5857afa048 100644
--- a/src/gui/text/qtextlist.cpp
+++ b/src/gui/text/qtextlist.cpp
@@ -100,6 +100,7 @@ public:
\sa QTextBlock, QTextListFormat, QTextCursor
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn bool QTextList::isEmpty() const
\obsolete
@@ -111,6 +112,7 @@ public:
\sa count()
*/
+#endif
/*! \internal
*/
diff --git a/src/gui/text/qtextlist.h b/src/gui/text/qtextlist.h
index 3967787f03..cfb9f9456f 100644
--- a/src/gui/text/qtextlist.h
+++ b/src/gui/text/qtextlist.h
@@ -59,8 +59,11 @@ public:
int count() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use count() instead")
inline bool isEmpty() const
{ return count() == 0; }
+#endif
QTextBlock item(int i) const;
diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index 0ed8be8530..18c5a4f3dd 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -704,8 +704,8 @@ QTextFrame::iterator &QTextFrame::iterator::operator=(const iterator &other) Q_D
#endif
/*!
- Returns the current frame pointed to by the iterator, or 0 if the
- iterator currently points to a block.
+ Returns the current frame pointed to by the iterator, or \nullptr
+ if the iterator currently points to a block.
\sa currentBlock()
*/
@@ -1291,12 +1291,12 @@ QVector<QTextLayout::FormatRange> QTextBlock::textFormats() const
}
/*!
- Returns the text document this text block belongs to, or 0 if the
- text block does not belong to any document.
+ Returns the text document this text block belongs to, or \nullptr
+ if the text block does not belong to any document.
*/
const QTextDocument *QTextBlock::document() const
{
- return p ? p->document() : 0;
+ return p ? p->document() : nullptr;
}
/*!
@@ -1306,7 +1306,7 @@ const QTextDocument *QTextBlock::document() const
QTextList *QTextBlock::textList() const
{
if (!isValid())
- return 0;
+ return nullptr;
const QTextBlockFormat fmt = blockFormat();
QTextObject *obj = p->document()->objectForFormat(fmt);
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index 103e0a8222..a62e7e425a 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -89,7 +89,7 @@ public:
contentStream = device;
}
- virtual ~QXmlStreamStrategy()
+ ~QXmlStreamStrategy()
{
if (contentStream)
contentStream->close();
@@ -496,10 +496,12 @@ void QTextOdfWriter::writeFormats(QXmlStreamWriter &writer, const QSet<int> &for
else
writeFrameFormat(writer, textFormat.toFrameFormat(), formatIndex);
break;
+#if QT_DEPRECATED_SINCE(5, 3)
case QTextFormat::TableFormat:
// this case never happens, because TableFormat is a FrameFormat
Q_UNREACHABLE();
break;
+#endif
}
}
@@ -886,26 +888,30 @@ void QTextOdfWriter::tableCellStyleElement(QXmlStreamWriter &writer, const int &
if (hasBorder) {
writer.writeAttribute(foNS, QString::fromLatin1("border"),
pixelToPoint(tableFormatTmp.border()) + QLatin1String(" ")
- + borderStyleName(tableFormatTmp.borderStyle())
- + QLatin1String(" #000000")); //!! HARD-CODING color black
+ + borderStyleName(tableFormatTmp.borderStyle()) + QLatin1String(" ")
+ + tableFormatTmp.borderBrush().color().name(QColor::HexRgb));
}
- qreal padding = format.topPadding();
- if (padding > 0 && padding == format.bottomPadding()
- && padding == format.leftPadding() && padding == format.rightPadding()) {
+ qreal topPadding = format.topPadding();
+ qreal padding = topPadding + tableFormatTmp.cellPadding();
+ if (padding > 0 && topPadding == format.bottomPadding()
+ && topPadding == format.leftPadding() && topPadding == format.rightPadding()) {
writer.writeAttribute(foNS, QString::fromLatin1("padding"), pixelToPoint(padding));
}
else {
if (padding > 0)
writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(padding));
- if (format.bottomPadding() > 0)
+ padding = format.bottomPadding() + tableFormatTmp.cellPadding();
+ if (padding > 0)
writer.writeAttribute(foNS, QString::fromLatin1("padding-bottom"),
- pixelToPoint(format.bottomPadding()));
- if (format.leftPadding() > 0)
+ pixelToPoint(padding));
+ padding = format.leftPadding() + tableFormatTmp.cellPadding();
+ if (padding > 0)
writer.writeAttribute(foNS, QString::fromLatin1("padding-left"),
- pixelToPoint(format.leftPadding()));
- if (format.rightPadding() > 0)
+ pixelToPoint(padding));
+ padding = format.rightPadding() + tableFormatTmp.cellPadding();
+ if (padding > 0)
writer.writeAttribute(foNS, QString::fromLatin1("padding-right"),
- pixelToPoint(format.rightPadding()));
+ pixelToPoint(padding));
}
if (format.hasProperty(QTextFormat::TextVerticalAlignment)) {
@@ -957,7 +963,7 @@ bool QTextOdfWriter::writeAll()
m_strategy = new QXmlStreamStrategy(m_device);
if (!m_device->isWritable() && ! m_device->open(QIODevice::WriteOnly)) {
- qWarning("QTextOdfWriter::writeAll: the device can not be opened for writing");
+ qWarning("QTextOdfWriter::writeAll: the device cannot be opened for writing");
return false;
}
QXmlStreamWriter writer(m_strategy->contentStream);
diff --git a/src/gui/text/qzipreader_p.h b/src/gui/text/qzipreader_p.h
index eed6ee6a62..378072b366 100644
--- a/src/gui/text/qzipreader_p.h
+++ b/src/gui/text/qzipreader_p.h
@@ -116,7 +116,7 @@ public:
private:
QZipReaderPrivate *d;
- Q_DISABLE_COPY(QZipReader)
+ Q_DISABLE_COPY_MOVE(QZipReader)
};
Q_DECLARE_TYPEINFO(QZipReader::FileInfo, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QZipReader::Status, Q_PRIMITIVE_TYPE);
diff --git a/src/gui/text/qzipwriter_p.h b/src/gui/text/qzipwriter_p.h
index 433bbab31e..b3bb5929cf 100644
--- a/src/gui/text/qzipwriter_p.h
+++ b/src/gui/text/qzipwriter_p.h
@@ -108,7 +108,7 @@ public:
void close();
private:
QZipWriterPrivate *d;
- Q_DISABLE_COPY(QZipWriter)
+ Q_DISABLE_COPY_MOVE(QZipWriter)
};
QT_END_NAMESPACE
diff --git a/src/gui/util/qastchandler.cpp b/src/gui/util/qastchandler.cpp
new file mode 100644
index 0000000000..6d163c6701
--- /dev/null
+++ b/src/gui/util/qastchandler.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qastchandler_p.h"
+#include "qtexturefiledata_p.h"
+
+#include <private/qnumeric_p.h>
+
+#include <QFile>
+#include <QDebug>
+#include <QSize>
+
+QT_BEGIN_NAMESPACE
+
+struct AstcHeader
+{
+ quint8 magic[4];
+ quint8 blockDimX;
+ quint8 blockDimY;
+ quint8 blockDimZ;
+ quint8 xSize[3];
+ quint8 ySize[3];
+ quint8 zSize[3];
+};
+
+bool QAstcHandler::canRead(const QByteArray &suffix, const QByteArray &block)
+{
+ Q_UNUSED(suffix)
+
+ return block.startsWith("\x13\xAB\xA1\x5C");
+}
+
+quint32 QAstcHandler::astcGLFormat(quint8 xBlockDim, quint8 yBlockDim) const
+{
+ static const quint32 glFormatRGBABase = 0x93B0; // GL_COMPRESSED_RGBA_ASTC_4x4_KHR
+ static const quint32 glFormatSRGBBase = 0x93D0; // GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
+
+ static QSize dims[14] = {
+ { 4, 4 }, // GL_COMPRESSED_xxx_ASTC_4x4_KHR
+ { 5, 4 }, // GL_COMPRESSED_xxx_ASTC_5x4_KHR
+ { 5, 5 }, // GL_COMPRESSED_xxx_ASTC_5x5_KHR
+ { 6, 5 }, // GL_COMPRESSED_xxx_ASTC_6x5_KHR
+ { 6, 6 }, // GL_COMPRESSED_xxx_ASTC_6x6_KHR
+ { 8, 5 }, // GL_COMPRESSED_xxx_ASTC_8x5_KHR
+ { 8, 6 }, // GL_COMPRESSED_xxx_ASTC_8x6_KHR
+ { 8, 8 }, // GL_COMPRESSED_xxx_ASTC_8x8_KHR
+ { 10, 5 }, // GL_COMPRESSED_xxx_ASTC_10x5_KHR
+ { 10, 6 }, // GL_COMPRESSED_xxx_ASTC_10x6_KHR
+ { 10, 8 }, // GL_COMPRESSED_xxx_ASTC_10x8_KHR
+ { 10, 10 }, // GL_COMPRESSED_xxx_ASTC_10x10_KHR
+ { 12, 10 }, // GL_COMPRESSED_xxx_ASTC_12x10_KHR
+ { 12, 12 } // GL_COMPRESSED_xxx_ASTC_12x12_KHR
+ };
+
+ const QSize dim(xBlockDim, yBlockDim);
+ int index = -1;
+ for (int i = 0; i < 14; i++) {
+ if (dim == dims[i]) {
+ index = i;
+ break;
+ }
+ }
+ if (index < 0)
+ return 0;
+
+ bool useSrgb = qEnvironmentVariableIsSet("QT_ASTCHANDLER_USE_SRGB")
+ || logName().toLower().contains("srgb");
+
+ return useSrgb ? (glFormatSRGBBase + index) : (glFormatRGBABase + index);
+}
+
+QTextureFileData QAstcHandler::read()
+{
+ QTextureFileData nullData;
+ QTextureFileData res;
+
+ if (!device())
+ return nullData;
+
+ QByteArray fileData = device()->readAll();
+ if (fileData.size() < int(sizeof(AstcHeader)) || !canRead(QByteArray(), fileData)) {
+ qCDebug(lcQtGuiTextureIO, "Not an ASTC file: %s", logName().constData());
+ return nullData;
+ }
+ res.setData(fileData);
+
+ const AstcHeader *header = reinterpret_cast<const AstcHeader *>(fileData.constData());
+
+ int xSz = int(header->xSize[0]) | int(header->xSize[1]) << 8 | int(header->xSize[2]) << 16;
+ int ySz = int(header->ySize[0]) | int(header->ySize[1]) << 8 | int(header->ySize[2]) << 16;
+ int zSz = int(header->zSize[0]) | int(header->zSize[1]) << 8 | int(header->zSize[2]) << 16;
+
+ quint32 glFmt = astcGLFormat(header->blockDimX, header->blockDimY);
+
+ if (!xSz || !ySz || !zSz || !glFmt || header->blockDimZ != 1) {
+ qCDebug(lcQtGuiTextureIO, "Invalid ASTC header data in file %s", logName().constData());
+ return nullData;
+ }
+
+ res.setSize(QSize(xSz, ySz));
+ res.setGLFormat(0); // 0 for compressed textures
+ res.setGLInternalFormat(glFmt);
+ //? BaseInternalFormat
+
+ int xBlocks = (xSz + header->blockDimX - 1) / header->blockDimX;
+ int yBlocks = (ySz + header->blockDimY - 1) / header->blockDimY;
+ int zBlocks = (zSz + header->blockDimZ - 1) / header->blockDimZ;
+
+ int byteCount = 0;
+ bool oob = mul_overflow(xBlocks, yBlocks, &byteCount)
+ || mul_overflow(byteCount, zBlocks, &byteCount)
+ || mul_overflow(byteCount, 16, &byteCount);
+
+
+ res.setDataOffset(sizeof(AstcHeader));
+ res.setNumLevels(1);
+ res.setDataLength(byteCount);
+
+ if (oob || !res.isValid()) {
+ qCDebug(lcQtGuiTextureIO, "Invalid ASTC file %s", logName().constData());
+ return nullData;
+ }
+
+ res.setLogName(logName());
+
+#if 0
+ qDebug() << "ASTC file handler read" << res << res.dataOffset() << res.dataLength();
+#endif
+ return res;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qastchandler_p.h b/src/gui/util/qastchandler_p.h
new file mode 100644
index 0000000000..398f1833b6
--- /dev/null
+++ b/src/gui/util/qastchandler_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QASTCHANDLER_H
+#define QASTCHANDLER_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 "qtexturefilehandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAstcHandler : public QTextureFileHandler
+{
+public:
+ using QTextureFileHandler::QTextureFileHandler;
+
+ static bool canRead(const QByteArray &suffix, const QByteArray &block);
+
+ QTextureFileData read() override;
+
+private:
+ quint32 astcGLFormat(quint8 xBlockDim, quint8 yBlockDim) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QASTCHANDLER_H
diff --git a/src/gui/util/qlayoutpolicy_p.h b/src/gui/util/qlayoutpolicy_p.h
index d92896e6e3..6457aeb653 100644
--- a/src/gui/util/qlayoutpolicy_p.h
+++ b/src/gui/util/qlayoutpolicy_p.h
@@ -66,6 +66,7 @@ class QVariant;
class Q_GUI_EXPORT QLayoutPolicy
{
+ Q_GADGET
Q_ENUMS(Policy)
public:
diff --git a/src/gui/util/qtexturefilereader.cpp b/src/gui/util/qtexturefilereader.cpp
index 5d4bd600e0..fefb957323 100644
--- a/src/gui/util/qtexturefilereader.cpp
+++ b/src/gui/util/qtexturefilereader.cpp
@@ -41,6 +41,7 @@
#include "qpkmhandler_p.h"
#include "qktxhandler_p.h"
+#include "qastchandler_p.h"
#include <QFileInfo>
@@ -80,6 +81,8 @@ bool QTextureFileReader::canRead()
m_handler = new QPkmHandler(m_device, logName);
} else if (QKtxHandler::canRead(suffix, headerBlock)) {
m_handler = new QKtxHandler(m_device, logName);
+ } else if (QAstcHandler::canRead(suffix, headerBlock)) {
+ m_handler = new QAstcHandler(m_device, logName);
}
// else if OtherHandler::canRead() ...etc.
}
@@ -89,7 +92,7 @@ bool QTextureFileReader::canRead()
QList<QByteArray> QTextureFileReader::supportedFileFormats()
{
// Hardcoded for now
- return {QByteArrayLiteral("pkm"), QByteArrayLiteral("ktx")};
+ return {QByteArrayLiteral("pkm"), QByteArrayLiteral("ktx"), QByteArrayLiteral("astc")};
}
bool QTextureFileReader::init()
diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri
index 6324642505..e5e711b1a0 100644
--- a/src/gui/util/util.pri
+++ b/src/gui/util/util.pri
@@ -19,7 +19,8 @@ HEADERS += \
util/qtexturefilereader_p.h \
util/qtexturefilehandler_p.h \
util/qpkmhandler_p.h \
- util/qktxhandler_p.h
+ util/qktxhandler_p.h \
+ util/qastchandler_p.h
SOURCES += \
util/qdesktopservices.cpp \
@@ -38,4 +39,5 @@ SOURCES += \
util/qtexturefiledata.cpp \
util/qtexturefilereader.cpp \
util/qpkmhandler.cpp \
- util/qktxhandler.cpp
+ util/qktxhandler.cpp \
+ util/qastchandler.cpp
diff --git a/src/gui/vulkan/qvulkaninstance.cpp b/src/gui/vulkan/qvulkaninstance.cpp
index 000c2b8caa..9895fec2ca 100644
--- a/src/gui/vulkan/qvulkaninstance.cpp
+++ b/src/gui/vulkan/qvulkaninstance.cpp
@@ -306,7 +306,7 @@ QVulkanInstance::QVulkanInstance()
/*!
Destructor.
- \note current() will return \c nullptr once the instance is destroyed.
+ \note current() will return \nullptr once the instance is destroyed.
*/
QVulkanInstance::~QVulkanInstance()
{
diff --git a/src/network/access/http2/bitstreams_p.h b/src/network/access/http2/bitstreams_p.h
index 9eba319dc2..ca272062a6 100644
--- a/src/network/access/http2/bitstreams_p.h
+++ b/src/network/access/http2/bitstreams_p.h
@@ -89,7 +89,7 @@ public:
void clear();
private:
- Q_DISABLE_COPY(BitOStream);
+ Q_DISABLE_COPY_MOVE(BitOStream);
std::vector<uchar> &buffer;
quint64 bitsSet;
diff --git a/src/network/access/http2/hpacktable_p.h b/src/network/access/http2/hpacktable_p.h
index 960e6a3d70..587d86f09c 100644
--- a/src/network/access/http2/hpacktable_p.h
+++ b/src/network/access/http2/hpacktable_p.h
@@ -236,7 +236,7 @@ private:
mutable QByteArray dummyDst;
- Q_DISABLE_COPY(FieldLookupTable)
+ Q_DISABLE_COPY_MOVE(FieldLookupTable)
};
}
diff --git a/src/network/access/qabstractnetworkcache.cpp b/src/network/access/qabstractnetworkcache.cpp
index 9afb99f23f..4e217294c4 100644
--- a/src/network/access/qabstractnetworkcache.cpp
+++ b/src/network/access/qabstractnetworkcache.cpp
@@ -331,11 +331,11 @@ QDataStream &operator<<(QDataStream &out, const QNetworkCacheMetaData &metaData)
static inline QDataStream &operator<<(QDataStream &out, const QNetworkCacheMetaData::AttributesMap &hash)
{
out << quint32(hash.size());
- QNetworkCacheMetaData::AttributesMap::ConstIterator it = hash.end();
- QNetworkCacheMetaData::AttributesMap::ConstIterator begin = hash.begin();
- while (it != begin) {
- --it;
+ QNetworkCacheMetaData::AttributesMap::ConstIterator it = hash.begin();
+ QNetworkCacheMetaData::AttributesMap::ConstIterator end = hash.end();
+ while (it != end) {
out << int(it.key()) << it.value();
+ ++it;
}
return out;
}
@@ -383,7 +383,7 @@ static inline QDataStream &operator>>(QDataStream &in, QNetworkCacheMetaData::At
int k;
QVariant t;
in >> k >> t;
- hash.insertMulti(QNetworkRequest::Attribute(k), t);
+ hash.insert(QNetworkRequest::Attribute(k), t);
}
if (in.status() != QDataStream::Ok)
@@ -475,7 +475,7 @@ QAbstractNetworkCache::~QAbstractNetworkCache()
the QIODevice when done with it.
If there is no cache for \a url, the url is invalid, or if there
- is an internal cache error 0 is returned.
+ is an internal cache error \nullptr is returned.
In the base class this is a pure virtual function.
@@ -496,7 +496,7 @@ QAbstractNetworkCache::~QAbstractNetworkCache()
Returns the device that should be populated with the data for
the cache item \a metaData. When all of the data has been written
insert() should be called. If metaData is invalid or the url in
- the metadata is invalid 0 is returned.
+ the metadata is invalid \nullptr is returned.
The cache owns the device and will take care of deleting it when
it is inserted or removed.
diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp
index d33355c470..4e399f018f 100644
--- a/src/network/access/qftp.cpp
+++ b/src/network/access/qftp.cpp
@@ -1826,8 +1826,8 @@ int QFtp::cd(const QString &dir)
is data available to read. You can then read the data with the
read() or readAll() functions.
- If \a dev is not 0, the data is written directly to the device \a
- dev. Make sure that the \a dev pointer is valid for the duration
+ If \a dev is not \nullptr, the data is written directly to the device
+ \a dev. Make sure that the \a dev pointer is valid for the duration
of the operation (it is safe to delete it when the
commandFinished() signal is emitted). In this case the readyRead()
signal is \e not emitted and you cannot read data with the
diff --git a/src/network/access/qftp_p.h b/src/network/access/qftp_p.h
index bba1f9b09d..0516c3d1f9 100644
--- a/src/network/access/qftp_p.h
+++ b/src/network/access/qftp_p.h
@@ -158,7 +158,7 @@ Q_SIGNALS:
void done(bool);
private:
- Q_DISABLE_COPY(QFtp)
+ Q_DISABLE_COPY_MOVE(QFtp)
Q_DECLARE_PRIVATE(QFtp)
Q_PRIVATE_SLOT(d_func(), void _q_startNextCommand())
diff --git a/src/network/access/qhstsstore_p.h b/src/network/access/qhstsstore_p.h
index e82596b250..5338d15592 100644
--- a/src/network/access/qhstsstore_p.h
+++ b/src/network/access/qhstsstore_p.h
@@ -87,7 +87,7 @@ private:
QVector<QHstsPolicy> observedPolicies;
QSettings store;
- Q_DISABLE_COPY(QHstsStore)
+ Q_DISABLE_COPY_MOVE(QHstsStore)
};
QT_END_NAMESPACE
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index c58fd24a44..681d84fee8 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -641,7 +641,7 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor
else { // SPDY, HTTP/2 ('h2' mode)
if (!pair.second->d_func()->requestIsPrepared)
prepareRequest(pair);
- channels[0].spdyRequestsToSend.insertMulti(request.priority(), pair);
+ channels[0].spdyRequestsToSend.insert(request.priority(), pair);
}
#ifndef Q_OS_WINRT
@@ -677,7 +677,7 @@ void QHttpNetworkConnectionPrivate::fillHttp2Queue()
for (auto &pair : highPriorityQueue) {
if (!pair.second->d_func()->requestIsPrepared)
prepareRequest(pair);
- channels[0].spdyRequestsToSend.insertMulti(QHttpNetworkRequest::HighPriority, pair);
+ channels[0].spdyRequestsToSend.insert(QHttpNetworkRequest::HighPriority, pair);
}
highPriorityQueue.clear();
@@ -685,7 +685,7 @@ void QHttpNetworkConnectionPrivate::fillHttp2Queue()
for (auto &pair : lowPriorityQueue) {
if (!pair.second->d_func()->requestIsPrepared)
prepareRequest(pair);
- channels[0].spdyRequestsToSend.insertMulti(pair.first.priority(), pair);
+ channels[0].spdyRequestsToSend.insert(pair.first.priority(), pair);
}
lowPriorityQueue.clear();
@@ -1518,6 +1518,18 @@ void QHttpNetworkConnection::preConnectFinished()
d_func()->preConnectRequests--;
}
+QString QHttpNetworkConnection::peerVerifyName() const
+{
+ Q_D(const QHttpNetworkConnection);
+ return d->peerVerifyName;
+}
+
+void QHttpNetworkConnection::setPeerVerifyName(const QString &peerName)
+{
+ Q_D(QHttpNetworkConnection);
+ d->peerVerifyName = peerName;
+}
+
#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 91827a6eb1..2bd727e0af 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -154,9 +154,11 @@ public:
void preConnectFinished();
+ QString peerVerifyName() const;
+ void setPeerVerifyName(const QString &peerName);
private:
Q_DECLARE_PRIVATE(QHttpNetworkConnection)
- Q_DISABLE_COPY(QHttpNetworkConnection)
+ Q_DISABLE_COPY_MOVE(QHttpNetworkConnection)
friend class QHttpThreadDelegate;
friend class QHttpNetworkReply;
friend class QHttpNetworkReplyPrivate;
@@ -289,6 +291,8 @@ public:
Http2::ProtocolParameters http2Parameters;
+ QString peerVerifyName;
+
friend class QHttpNetworkConnectionChannel;
};
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index d5f63af745..f79a4d1dc6 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -392,6 +392,7 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
if (!connection->sslContext().isNull())
QSslSocketPrivate::checkSettingSslContext(sslSocket, connection->sslContext());
+ sslSocket->setPeerVerifyName(connection->d_func()->peerVerifyName);
sslSocket->connectToHostEncrypted(connectHost, connectPort, QIODevice::ReadWrite, networkLayerPreference);
if (ignoreAllSslErrors)
sslSocket->ignoreSslErrors();
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index 8de9760710..a3f71b8d2f 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -66,7 +66,8 @@ QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequest
ssl(other.ssl),
preConnect(other.preConnect),
redirectCount(other.redirectCount),
- redirectPolicy(other.redirectPolicy)
+ redirectPolicy(other.redirectPolicy),
+ peerVerifyName(other.peerVerifyName)
{
}
@@ -90,7 +91,8 @@ bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &ot
&& (withCredentials == other.withCredentials)
&& (ssl == other.ssl)
&& (preConnect == other.preConnect)
- && (redirectPolicy == other.redirectPolicy);
+ && (redirectPolicy == other.redirectPolicy)
+ && (peerVerifyName == other.peerVerifyName);
}
QByteArray QHttpNetworkRequest::methodName() const
@@ -397,6 +399,15 @@ int QHttpNetworkRequest::minorVersion() const
return 1;
}
+QString QHttpNetworkRequest::peerVerifyName() const
+{
+ return d->peerVerifyName;
+}
+
+void QHttpNetworkRequest::setPeerVerifyName(const QString &peerName)
+{
+ d->peerVerifyName = peerName;
+}
QT_END_NAMESPACE
diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h
index bc797537ae..fb4896195b 100644
--- a/src/network/access/qhttpnetworkrequest_p.h
+++ b/src/network/access/qhttpnetworkrequest_p.h
@@ -147,6 +147,8 @@ public:
QByteArray methodName() const;
QByteArray uri(bool throughProxy) const;
+ QString peerVerifyName() const;
+ void setPeerVerifyName(const QString &peerName);
private:
QSharedDataPointer<QHttpNetworkRequestPrivate> d;
friend class QHttpNetworkRequestPrivate;
@@ -182,6 +184,7 @@ public:
bool preConnect;
int redirectCount;
QNetworkRequest::RedirectPolicy redirectPolicy;
+ QString peerVerifyName;
};
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 0e97acdd9d..1fdf28df9d 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -123,7 +123,7 @@ static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const
}
-static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
+static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy, const QString &peerVerifyName)
{
QString result;
QUrl copy = url;
@@ -170,7 +170,8 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
#else
Q_UNUSED(proxy)
#endif
-
+ if (!peerVerifyName.isEmpty())
+ result += QLatin1Char(':') + peerVerifyName;
return "http-connection:" + std::move(result).toLatin1();
}
@@ -317,12 +318,12 @@ void QHttpThreadDelegate::startRequest()
#ifndef QT_NO_NETWORKPROXY
if (transparentProxy.type() != QNetworkProxy::NoProxy)
- cacheKey = makeCacheKey(urlCopy, &transparentProxy);
+ cacheKey = makeCacheKey(urlCopy, &transparentProxy, httpRequest.peerVerifyName());
else if (cacheProxy.type() != QNetworkProxy::NoProxy)
- cacheKey = makeCacheKey(urlCopy, &cacheProxy);
+ cacheKey = makeCacheKey(urlCopy, &cacheProxy, httpRequest.peerVerifyName());
else
#endif
- cacheKey = makeCacheKey(urlCopy, 0);
+ cacheKey = makeCacheKey(urlCopy, 0, httpRequest.peerVerifyName());
// the http object is actually a QHttpNetworkConnection
@@ -352,7 +353,7 @@ void QHttpThreadDelegate::startRequest()
httpConnection->setTransparentProxy(transparentProxy);
httpConnection->setCacheProxy(cacheProxy);
#endif
-
+ httpConnection->setPeerVerifyName(httpRequest.peerVerifyName());
// cache the QHttpNetworkConnection corresponding to this cache key
connections.localData()->addEntry(cacheKey, httpConnection);
} else {
diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index fd6589b396..5ad820eba0 100644
--- a/src/network/access/qnetworkaccessftpbackend.cpp
+++ b/src/network/access/qnetworkaccessftpbackend.cpp
@@ -351,7 +351,7 @@ void QNetworkAccessFtpBackend::ftpDone()
}
} else if (state == Statting) {
// statted successfully, send the actual request
- emit metaDataChanged();
+ metaDataChanged();
state = Transferring;
QFtp::TransferType type = QFtp::Binary;
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 85e2c492e4..50b9488594 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1181,9 +1181,37 @@ QSharedPointer<QNetworkSession> QNetworkAccessManagerPrivate::getNetworkSession(
\sa connectToHost(), get(), post(), put(), deleteResource()
*/
+
void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quint16 port,
const QSslConfiguration &sslConfiguration)
{
+ connectToHostEncrypted(hostName, port, sslConfiguration, QString());
+}
+
+/*!
+ \since 5.13
+ \overload
+
+ Initiates a connection to the host given by \a hostName at port \a port, using
+ \a sslConfiguration with \a peerName set to be the hostName used for certificate
+ validation. 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 Preconnecting a SPDY connection can be done by calling setAllowedNextProtocols()
+ on \a sslConfiguration with QSslConfiguration::NextProtocolSpdy3_0 contained in
+ the list of allowed protocols. When using SPDY, one single connection per host is
+ enough, i.e. calling this method multiple times per host will not result in faster
+ network transactions.
+
+ \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,
+ const QString &peerName)
+{
QUrl url;
url.setHost(hostName);
url.setPort(port);
@@ -1198,6 +1226,7 @@ void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quin
QSslConfiguration::NextProtocolSpdy3_0))
request.setAttribute(QNetworkRequest::SpdyAllowedAttribute, true);
+ request.setPeerVerifyName(peerName);
get(request);
}
#endif
@@ -1361,7 +1390,8 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
QString scheme = req.url().scheme();
#ifdef Q_OS_WASM
- if (scheme == QLatin1String("http") || scheme == QLatin1String("https")) {
+ // Support http, https, and relateive urls
+ if (scheme == QLatin1String("http") || scheme == QLatin1String("https") || scheme.isEmpty()) {
QNetworkReplyWasmImpl *reply = new QNetworkReplyWasmImpl(this);
QNetworkReplyWasmImplPrivate *priv = reply->d_func();
priv->manager = this;
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 67b3a8b71b..7e2f7683d0 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -158,6 +158,9 @@ public:
#ifndef QT_NO_SSL
void connectToHostEncrypted(const QString &hostName, quint16 port = 443,
const QSslConfiguration &sslConfiguration = QSslConfiguration::defaultConfiguration());
+ void connectToHostEncrypted(const QString &hostName, quint16 port,
+ const QSslConfiguration &sslConfiguration,
+ const QString &peerName);
#endif
void connectToHost(const QString &hostName, quint16 port = 80);
diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp
index 072a7f249d..af5b126953 100644
--- a/src/network/access/qnetworkcookiejar.cpp
+++ b/src/network/access/qnetworkcookiejar.cpp
@@ -45,6 +45,14 @@
#include "QtCore/qdatetime.h"
#if QT_CONFIG(topleveldomain)
#include "private/qtldurl_p.h"
+#else
+QT_BEGIN_NAMESPACE
+static bool qIsEffectiveTLD(QString domain)
+{
+ // provide minimal checking by not accepting cookies on real TLDs
+ return !domain.contains(QLatin1Char('.'));
+}
+QT_END_NAMESPACE
#endif
QT_BEGIN_NAMESPACE
@@ -356,19 +364,12 @@ bool QNetworkCookieJar::validateCookie(const QNetworkCookie &cookie, const QUrl
// https://tools.ietf.org/html/rfc6265#section-5.3 step 5
if (host == domain)
return true;
-#if QT_CONFIG(topleveldomain)
// the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2
// redundant; the "leading dot" rule has been relaxed anyway, see QNetworkCookie::normalize()
// we remove the leading dot for this check if it's present
- if (qIsEffectiveTLD(domain))
- return false; // not accepted
-#else
- // provide minimal checking by not accepting cookies on real TLDs
- if (!domain.contains(QLatin1Char('.')))
- return false;
-#endif
-
- return true;
+ // Normally defined in qtldurl_p.h, but uses fall-back in this file when topleveldomain isn't
+ // configured:
+ return !qIsEffectiveTLD(domain);
}
QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkfile.cpp b/src/network/access/qnetworkfile.cpp
index 374dd26e2e..b7c91f28d8 100644
--- a/src/network/access/qnetworkfile.cpp
+++ b/src/network/access/qnetworkfile.cpp
@@ -65,21 +65,21 @@ void QNetworkFile::open()
if (fi.isDir()) {
QString msg = QCoreApplication::translate("QNetworkAccessFileBackend",
"Cannot open %1: Path is a directory").arg(fileName());
- error(QNetworkReply::ContentOperationNotPermittedError, msg);
+ emit error(QNetworkReply::ContentOperationNotPermittedError, msg);
} else {
- headerRead(QNetworkRequest::LastModifiedHeader, QVariant::fromValue(fi.lastModified()));
- headerRead(QNetworkRequest::ContentLengthHeader, QVariant::fromValue(fi.size()));
+ emit headerRead(QNetworkRequest::LastModifiedHeader, QVariant::fromValue(fi.lastModified()));
+ emit headerRead(QNetworkRequest::ContentLengthHeader, QVariant::fromValue(fi.size()));
opened = QFile::open(QIODevice::ReadOnly | QIODevice::Unbuffered);
if (!opened) {
QString msg = QCoreApplication::translate("QNetworkAccessFileBackend",
"Error opening %1: %2").arg(fileName(), errorString());
if (exists())
- error(QNetworkReply::ContentAccessDenied, msg);
+ emit error(QNetworkReply::ContentAccessDenied, msg);
else
- error(QNetworkReply::ContentNotFoundError, msg);
+ emit error(QNetworkReply::ContentNotFoundError, msg);
}
}
- finished(opened);
+ emit finished(opened);
}
void QNetworkFile::close()
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 2d7649fa61..f801ef0c88 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -787,6 +787,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
if (request.attribute(QNetworkRequest::EmitAllUploadProgressSignalsAttribute).toBool())
emitAllUploadProgressSignals = true;
+ httpRequest.setPeerVerifyName(newHttpRequest.peerVerifyName());
// Create the HTTP thread delegate
QHttpThreadDelegate *delegate = new QHttpThreadDelegate;
@@ -1563,7 +1564,7 @@ bool QNetworkReplyHttpImplPrivate::sendCacheContents(const QNetworkCacheMetaData
QIODevice *contents = nc->data(url);
if (!contents) {
#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
- qDebug() << "Can not send cache, the contents are 0" << url;
+ qDebug() << "Cannot send cache, the contents are 0" << url;
#endif
return false;
}
diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp
index b1e9853a50..bb6ef07741 100644
--- a/src/network/access/qnetworkreplywasmimpl.cpp
+++ b/src/network/access/qnetworkreplywasmimpl.cpp
@@ -117,7 +117,7 @@ static void q_loadCallback(val event)
val blob = xhr["response"];
val reader = val::global("FileReader").new_();
- reader.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_readBinary"));
+ reader.set("onload", val::module_property("qt_QNetworkReplyWasmImplPrivate_readBinary"));
reader.set("data-handler", xhr["data-handler"]);
reader.call<void>("readAsArrayBuffer", blob);
@@ -174,12 +174,12 @@ static void q_readBinary(val event)
QCoreApplication::processEvents();
}
-EMSCRIPTEN_BINDINGS(network_module) {
- function("QNetworkReplyWasmImplPrivate_requestErrorCallback", q_requestErrorCallback);
- function("QNetworkReplyWasmImplPrivate_progressCallback", q_progressCallback);
- function("QNetworkReplyWasmImplPrivate_loadCallback", q_loadCallback);
- function("QNetworkReplyWasmImplPrivate_responseHeadersCallback", q_responseHeadersCallback);
- function("QNetworkReplyWasmImplPrivate_readBinary", q_readBinary);
+EMSCRIPTEN_BINDINGS(qtNetworkModule) {
+ function("qt_QNetworkReplyWasmImplPrivate_requestErrorCallback", q_requestErrorCallback);
+ function("qt_QNetworkReplyWasmImplPrivate_progressCallback", q_progressCallback);
+ function("qt_QNetworkReplyWasmImplPrivate_loadCallback", q_loadCallback);
+ function("qt_QNetworkReplyWasmImplPrivate_responseHeadersCallback", q_responseHeadersCallback);
+ function("qt_QNetworkReplyWasmImplPrivate_readBinary", q_readBinary);
}
QNetworkReplyWasmImplPrivate::QNetworkReplyWasmImplPrivate()
@@ -235,6 +235,7 @@ void QNetworkReplyWasmImpl::close()
void QNetworkReplyWasmImpl::abort()
{
Q_D(const QNetworkReplyWasmImpl);
+ setError( QNetworkReply::OperationCanceledError, "Operation canceled" );
d->doAbort();
close();
@@ -331,10 +332,10 @@ void QNetworkReplyWasmImplPrivate::doSendRequest()
m_xhr.call<void>("open", verb, request.url().toString().toStdString());
- m_xhr.set("onerror", val::module_property("QNetworkReplyWasmImplPrivate_requestErrorCallback"));
- m_xhr.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_loadCallback"));
- m_xhr.set("onprogress", val::module_property("QNetworkReplyWasmImplPrivate_progressCallback"));
- m_xhr.set("onreadystatechange", val::module_property("QNetworkReplyWasmImplPrivate_responseHeadersCallback"));
+ m_xhr.set("onerror", val::module_property("qt_QNetworkReplyWasmImplPrivate_requestErrorCallback"));
+ m_xhr.set("onload", val::module_property("qt_QNetworkReplyWasmImplPrivate_loadCallback"));
+ m_xhr.set("onprogress", val::module_property("qt_QNetworkReplyWasmImplPrivate_progressCallback"));
+ m_xhr.set("onreadystatechange", val::module_property("qt_QNetworkReplyWasmImplPrivate_responseHeadersCallback"));
m_xhr.set("data-handler", val(quintptr(reinterpret_cast<void *>(this))));
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index e4c46c3183..f15c43cdd8 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -438,6 +438,7 @@ public:
if (other.sslConfiguration)
sslConfiguration = new QSslConfiguration(*other.sslConfiguration);
#endif
+ peerVerifyName = other.peerVerifyName;
}
inline bool operator==(const QNetworkRequestPrivate &other) const
@@ -446,7 +447,8 @@ public:
priority == other.priority &&
rawHeaders == other.rawHeaders &&
attributes == other.attributes &&
- maxRedirectsAllowed == other.maxRedirectsAllowed;
+ maxRedirectsAllowed == other.maxRedirectsAllowed &&
+ peerVerifyName == other.peerVerifyName;
// don't compare cookedHeaders
}
@@ -456,6 +458,7 @@ public:
mutable QSslConfiguration *sslConfiguration;
#endif
int maxRedirectsAllowed;
+ QString peerVerifyName;
};
/*!
@@ -789,6 +792,32 @@ void QNetworkRequest::setMaximumRedirectsAllowed(int maxRedirectsAllowed)
d->maxRedirectsAllowed = maxRedirectsAllowed;
}
+/*!
+ \since 5.13
+
+ Returns the host name set for the certificate validation, as set by
+ setPeerVerifyName. By default this returns a null string.
+
+ \sa setPeerVerifyName
+*/
+QString QNetworkRequest::peerVerifyName() const
+{
+ return d->peerVerifyName;
+}
+
+/*!
+ \since 5.13
+
+ Sets \a peerName as host name for the certificate validation, instead of the one used for the
+ TCP connection.
+
+ \sa peerVerifyName
+*/
+void QNetworkRequest::setPeerVerifyName(const QString &peerName)
+{
+ d->peerVerifyName = peerName;
+}
+
static QByteArray headerName(QNetworkRequest::KnownHeaders header)
{
switch (header) {
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index 8462eae8c8..efb9cbecba 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -173,6 +173,8 @@ public:
int maximumRedirectsAllowed() const;
void setMaximumRedirectsAllowed(int maximumRedirectsAllowed);
+ QString peerVerifyName() const;
+ void setPeerVerifyName(const QString &peerName);
private:
QSharedDataPointer<QNetworkRequestPrivate> d;
friend class QNetworkRequestPrivate;
diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp
index e36903fc94..f5ced0693a 100644
--- a/src/network/bearer/qnetworkconfiguration.cpp
+++ b/src/network/bearer/qnetworkconfiguration.cpp
@@ -518,7 +518,7 @@ QNetworkConfiguration::BearerType QNetworkConfiguration::bearerTypeFamily() cons
/*!
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
+ The string is not translated and therefore cannot be shown to the user. The subsequent table
shows the fixed mappings between BearerType and the bearer type name for known types. If the
BearerType is unknown this function may return additional information if it is available;
otherwise an empty string will be returned.
diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h
index 2fdb490ea0..1b1ece39b7 100644
--- a/src/network/bearer/qnetworkconfiguration_p.h
+++ b/src/network/bearer/qnetworkconfiguration_p.h
@@ -97,7 +97,7 @@ public:
static Q_CONSTEXPR int DefaultTimeout = 30000;
private:
- Q_DISABLE_COPY(QNetworkConfigurationPrivate)
+ Q_DISABLE_COPY_MOVE(QNetworkConfigurationPrivate)
};
QT_END_NAMESPACE
diff --git a/src/network/configure.json b/src/network/configure.json
index 2c005f0efb..07d46b790e 100644
--- a/src/network/configure.json
+++ b/src/network/configure.json
@@ -15,8 +15,10 @@
"openssl-linked": { "type": "void", "name": "openssl", "value": "linked" },
"openssl-runtime": { "type": "void", "name": "openssl", "value": "runtime" },
"dtls": "boolean",
+ "ocsp": "boolean",
"sctp": "boolean",
"securetransport": "boolean",
+ "schannel": "boolean",
"ssl": "boolean",
"system-proxies": "boolean"
}
@@ -184,6 +186,19 @@
]
},
"use": "openssl"
+ },
+ "ocsp": {
+ "label": "OCSP stapling support in OpenSSL",
+ "type": "compile",
+ "test": {
+ "include": ["openssl/ssl.h", "openssl/ocsp.h"],
+ "tail": [
+ "#if defined(OPENSSL_NO_OCSP) || defined(OPENSSL_NO_TLSEXT)",
+ "# error OpenSSL without OCSP stapling",
+ "#endif"
+ ]
+ },
+ "use": "openssl"
}
},
@@ -229,13 +244,13 @@
"autoDetect": "!config.winrt && !config.wasm",
"enable": "input.openssl == 'yes' || input.openssl == 'runtime'",
"disable": "input.openssl == 'no' || input.openssl == 'linked' || input.ssl == 'no'",
- "condition": "!features.securetransport && libs.openssl_headers"
+ "condition": "!features.securetransport && !features.schannel && libs.openssl_headers"
},
"openssl-linked": {
"label": " Qt directly linked to OpenSSL",
"autoDetect": false,
"enable": "input.openssl == 'linked'",
- "condition": "!features.securetransport && libs.openssl",
+ "condition": "!features.securetransport && !features.schannel && libs.openssl",
"output": [
"privateFeature",
{ "type": "define", "name": "QT_LINKED_OPENSSL" }
@@ -250,9 +265,18 @@
{ "type": "define", "name": "QT_SECURETRANSPORT" }
]
},
+ "schannel": {
+ "label": "Schannel",
+ "disable": "input.schannel == 'no' || input.ssl == 'no'",
+ "condition": "input.schannel == 'yes' && config.win32 && !config.winrt && (input.openssl == '' || input.openssl == 'no')",
+ "output": [
+ "publicFeature",
+ { "type": "define", "name": "QT_SCHANNEL" }
+ ]
+ },
"ssl": {
"label": "SSL",
- "condition": "config.winrt || features.securetransport || features.openssl",
+ "condition": "config.winrt || features.securetransport || features.openssl || features.schannel",
"output": [ "publicFeature", "feature" ]
},
"dtls": {
@@ -262,6 +286,13 @@
"condition": "features.openssl && tests.dtls",
"output": [ "publicFeature" ]
},
+ "ocsp": {
+ "label": "OCSP-stapling",
+ "purpose": "Provides OCSP stapling support",
+ "section": "Networking",
+ "condition": "features.opensslv11 && tests.ocsp",
+ "output": [ "publicFeature" ]
+ },
"opensslv11": {
"label": "OpenSSL 1.1",
"condition": "features.openssl && tests.openssl11",
@@ -391,10 +422,16 @@ For example:
"args": "securetransport",
"condition": "config.darwin"
},
+ {
+ "type": "feature",
+ "args": "schannel",
+ "condition": "config.win32 && !config.winrt"
+ },
"openssl",
"openssl-linked",
"opensslv11",
"dtls",
+ "ocsp",
"sctp",
"system-proxies"
]
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index 34db5b4b31..47ce9ab0c6 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -465,27 +465,12 @@ QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMet
methodString = "";
phase = Done;
break;
- case QAuthenticatorPrivate::Plain:
- response = '\0' + user.toUtf8() + '\0' + password.toUtf8();
- phase = Done;
- break;
case QAuthenticatorPrivate::Basic:
methodString = "Basic ";
response = user.toLatin1() + ':' + password.toLatin1();
response = response.toBase64();
phase = Done;
break;
- case QAuthenticatorPrivate::Login:
- if (challenge.contains("VXNlciBOYW1lAA==")) {
- response = user.toUtf8().toBase64();
- phase = Phase2;
- } else if (challenge.contains("UGFzc3dvcmQA")) {
- response = password.toUtf8().toBase64();
- phase = Done;
- }
- break;
- case QAuthenticatorPrivate::CramMd5:
- break;
case QAuthenticatorPrivate::DigestMd5:
methodString = "Digest ";
response = digestMd5Response(challenge, requestMethod, path);
diff --git a/src/network/kernel/qauthenticator_p.h b/src/network/kernel/qauthenticator_p.h
index 8a1ee0ebe6..265cb7afe2 100644
--- a/src/network/kernel/qauthenticator_p.h
+++ b/src/network/kernel/qauthenticator_p.h
@@ -68,7 +68,7 @@ class QNtlmWindowsHandles;
class Q_AUTOTEST_EXPORT QAuthenticatorPrivate
{
public:
- enum Method { None, Basic, Plain, Login, Ntlm, CramMd5, DigestMd5 };
+ enum Method { None, Basic, Ntlm, DigestMd5 };
QAuthenticatorPrivate();
~QAuthenticatorPrivate();
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index 0973d0dd52..1c7a8da06d 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -300,25 +300,6 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
*/
/*!
- \fn template<typename PointerToMemberFunction> int QHostInfo::lookupHost(const QString &name, const QObject *receiver, PointerToMemberFunction function)
-
- \since 5.9
-
- \overload
-
- Looks up the IP address(es) associated with host name \a name, and
- returns an ID for the lookup. When the result of the lookup is
- ready, the slot or signal \a function in \a receiver is called with
- a QHostInfo argument. The QHostInfo object can then be inspected
- to get the results of the lookup.
-
- \note There is no guarantee on the order the signals will be emitted
- if you start multiple requests with lookupHost().
-
- \sa abortHostLookup(), addresses(), error(), fromName()
-*/
-
-/*!
\fn template<typename Functor> int QHostInfo::lookupHost(const QString &name, Functor functor)
\since 5.9
@@ -354,6 +335,16 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
thread of \a context. The context's thread must have a running Qt
event loop.
+ Here is an alternative signature for the function:
+ \code
+ lookupHost(const QString &name, const QObject *receiver, PointerToMemberFunction function)
+ \endcode
+
+ In this case, when the result of the lookup is ready, the slot or
+ signal \c{function} in \c{receiver} is called with a QHostInfo
+ argument. The QHostInfo object can then be inspected to get the
+ results of the lookup.
+
\note There is no guarantee on the order the signals will be emitted
if you start multiple requests with lookupHost().
diff --git a/src/network/kernel/qhostinfo.h b/src/network/kernel/qhostinfo.h
index 75917a02a3..49871ad470 100644
--- a/src/network/kernel/qhostinfo.h
+++ b/src/network/kernel/qhostinfo.h
@@ -91,13 +91,10 @@ public:
static QString localDomainName();
#ifdef Q_CLANG_QDOC
- template<typename PointerToMemberFunction>
- static int QHostInfo::lookupHost(const QString &name, const QObject *receiver,
- PointerToMemberFunction function);
template<typename Functor>
- static int QHostInfo::lookupHost(const QString &name, Functor functor);
+ static int lookupHost(const QString &name, Functor functor);
template<typename Functor>
- static int QHostInfo::lookupHost(const QString &name, const QObject *context, Functor functor);
+ static int lookupHost(const QString &name, const QObject *context, Functor functor);
#else
// lookupHost to a QObject slot
template <typename Func>
diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp
index db51732bd3..56397814b0 100644
--- a/src/network/kernel/qnetworkproxy_win.cpp
+++ b/src/network/kernel/qnetworkproxy_win.cpp
@@ -370,7 +370,7 @@ static QList<QNetworkProxy> parseServerList(const QNetworkProxyQuery &query, con
#if !defined(Q_OS_WINRT)
namespace {
class QRegistryWatcher {
- Q_DISABLE_COPY(QRegistryWatcher)
+ Q_DISABLE_COPY_MOVE(QRegistryWatcher)
public:
QRegistryWatcher() = default;
@@ -425,7 +425,7 @@ private:
class QWindowsSystemProxy
{
- Q_DISABLE_COPY(QWindowsSystemProxy)
+ Q_DISABLE_COPY_MOVE(QWindowsSystemProxy)
public:
QWindowsSystemProxy();
~QWindowsSystemProxy();
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index e86793cb21..9c8f29e18a 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -914,7 +914,7 @@ void QAbstractSocketPrivate::resolveProxy(const QString &hostname, quint16 port)
proxies << proxy;
} else {
// try the application settings instead
- QNetworkProxyQuery query(hostname, port, QString(),
+ QNetworkProxyQuery query(hostname, port, protocolTag,
socketType == QAbstractSocket::TcpSocket ?
QNetworkProxyQuery::TcpSocket :
socketType == QAbstractSocket::SctpSocket ?
@@ -2959,6 +2959,38 @@ QNetworkProxy QAbstractSocket::proxy() const
Q_D(const QAbstractSocket);
return d->proxy;
}
+
+/*!
+ \since 5.13
+
+ Returns the protocol tag for this socket.
+ If the protocol tag is set then this is passed to QNetworkProxyQuery
+ when this is created internally to indicate the protocol tag to be
+ used.
+
+ \sa setProtocolTag(), QNetworkProxyQuery
+*/
+
+QString QAbstractSocket::protocolTag() const
+{
+ Q_D(const QAbstractSocket);
+ return d->protocolTag;
+}
+
+/*!
+ \since 5.13
+
+ Sets the protocol tag for this socket to \a tag.
+
+ \sa protocolTag()
+*/
+
+void QAbstractSocket::setProtocolTag(const QString &tag)
+{
+ Q_D(QAbstractSocket);
+ d->protocolTag = tag;
+}
+
#endif // QT_NO_NETWORKPROXY
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index 6d5e57ac52..de09195eeb 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -197,6 +197,8 @@ public:
#ifndef QT_NO_NETWORKPROXY
void setProxy(const QNetworkProxy &networkProxy);
QNetworkProxy proxy() const;
+ QString protocolTag() const;
+ void setProtocolTag(const QString &tag);
#endif
Q_SIGNALS:
diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h
index 066a35ff85..5aa69d747e 100644
--- a/src/network/socket/qabstractsocket_p.h
+++ b/src/network/socket/qabstractsocket_p.h
@@ -83,7 +83,7 @@ public:
#ifndef QT_NO_NETWORKPROXY
inline void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator) override {
Q_Q(QAbstractSocket);
- q->proxyAuthenticationRequired(proxy, authenticator);
+ emit q->proxyAuthenticationRequired(proxy, authenticator);
}
#endif
@@ -124,6 +124,7 @@ public:
#ifndef QT_NO_NETWORKPROXY
QNetworkProxy proxy;
QNetworkProxy proxyInUse;
+ QString protocolTag;
void resolveProxy(const QString &hostName, quint16 port);
#else
inline void resolveProxy(const QString &, quint16) { }
diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h
index b15dd73c96..8eebb06a4d 100644
--- a/src/network/socket/qabstractsocketengine_p.h
+++ b/src/network/socket/qabstractsocketengine_p.h
@@ -215,7 +215,7 @@ protected:
private:
Q_DECLARE_PRIVATE(QAbstractSocketEngine)
- Q_DISABLE_COPY(QAbstractSocketEngine)
+ Q_DISABLE_COPY_MOVE(QAbstractSocketEngine)
};
class QAbstractSocketEnginePrivate : public QObjectPrivate
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index 9427c3b00d..49ea17f9f8 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -649,7 +649,7 @@ void QHttpSocketEngine::slotSocketReadNotification()
}
if (priv->phase == QAuthenticatorPrivate::Done)
- emit proxyAuthenticationRequired(d->proxy, &d->authenticator);
+ proxyAuthenticationRequired(d->proxy, &d->authenticator);
// priv->phase will get reset to QAuthenticatorPrivate::Start if the authenticator got modified in the signal above.
if (priv->phase == QAuthenticatorPrivate::Done) {
setError(QAbstractSocket::ProxyAuthenticationRequiredError, tr("Authentication required"));
@@ -771,7 +771,7 @@ void QHttpSocketEngine::emitPendingReadNotification()
Q_D(QHttpSocketEngine);
d->readNotificationPending = false;
if (d->readNotificationEnabled)
- emit readNotification();
+ readNotification();
}
void QHttpSocketEngine::emitPendingWriteNotification()
@@ -779,14 +779,14 @@ void QHttpSocketEngine::emitPendingWriteNotification()
Q_D(QHttpSocketEngine);
d->writeNotificationPending = false;
if (d->writeNotificationEnabled)
- emit writeNotification();
+ writeNotification();
}
void QHttpSocketEngine::emitPendingConnectionNotification()
{
Q_D(QHttpSocketEngine);
d->connectionNotificationPending = false;
- emit connectionNotification();
+ connectionNotification();
}
void QHttpSocketEngine::emitReadNotification()
diff --git a/src/network/socket/qhttpsocketengine_p.h b/src/network/socket/qhttpsocketengine_p.h
index cb7798694a..bbcc09eee9 100644
--- a/src/network/socket/qhttpsocketengine_p.h
+++ b/src/network/socket/qhttpsocketengine_p.h
@@ -160,7 +160,7 @@ private:
bool readHttpHeader();
Q_DECLARE_PRIVATE(QHttpSocketEngine)
- Q_DISABLE_COPY(QHttpSocketEngine)
+ Q_DISABLE_COPY_MOVE(QHttpSocketEngine)
};
diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp
index a9789b7d04..c5bd599a51 100644
--- a/src/network/socket/qlocalserver.cpp
+++ b/src/network/socket/qlocalserver.cpp
@@ -506,8 +506,8 @@ void QLocalServer::setMaxPendingConnections(int numConnections)
/*!
Waits for at most \a msec milliseconds or until an incoming connection
is available. Returns \c true if a connection is available; otherwise
- returns \c false. If the operation timed out and \a timedOut is not 0,
- *timedOut will be set to true.
+ returns \c false. If the operation timed out and \a timedOut is not
+ \nullptr, *timedOut will be set to true.
This is a blocking function call. Its use is ill-advised in a
single-threaded GUI application, since the whole application will stop
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index d6ee76043f..4decbd5ded 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -87,9 +87,9 @@ void QLocalSocketPrivate::_q_winError(ulong windowsError, const QString &functio
}
if (currentState != state) {
- q->emit stateChanged(state);
+ emit q->stateChanged(state);
if (state == QLocalSocket::UnconnectedState && currentState != QLocalSocket::ConnectingState)
- q->emit disconnected();
+ emit q->disconnected();
}
emit q->error(error);
}
diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp
index 8947a7ee8a..5126a5330f 100644
--- a/src/network/socket/qnativesocketengine.cpp
+++ b/src/network/socket/qnativesocketengine.cpp
@@ -999,8 +999,8 @@ void QNativeSocketEngine::close()
/*!
Waits for \a msecs milliseconds or until the socket is ready for
- reading. If \a timedOut is not 0 and \a msecs milliseconds have
- passed, the value of \a timedOut is set to true.
+ reading. If \a timedOut is not \nullptr and \a msecs milliseconds
+ have passed, the value of \a timedOut is set to true.
Returns \c true if data is available for reading; otherwise returns
false.
@@ -1039,8 +1039,8 @@ bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut)
/*!
Waits for \a msecs milliseconds or until the socket is ready for
- writing. If \a timedOut is not 0 and \a msecs milliseconds have
- passed, the value of \a timedOut is set to true.
+ writing. If \a timedOut is not \nullptr and \a msecs milliseconds
+ have passed, the value of \a timedOut is set to true.
Returns \c true if data is available for writing; otherwise returns
false.
diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h
index aa61b74823..2292566265 100644
--- a/src/network/socket/qnativesocketengine_p.h
+++ b/src/network/socket/qnativesocketengine_p.h
@@ -196,7 +196,7 @@ public Q_SLOTS:
private:
Q_DECLARE_PRIVATE(QNativeSocketEngine)
- Q_DISABLE_COPY(QNativeSocketEngine)
+ Q_DISABLE_COPY_MOVE(QNativeSocketEngine)
};
class QSocketNotifier;
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index c999bd2088..24e8eabb6e 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -1146,22 +1146,17 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
qint64 ret = -1;
int recvResult = 0;
DWORD flags;
- DWORD bufferCount = 5;
- WSABUF * buf = 0;
+ // We start at 1500 bytes (the MTU for Ethernet V2), which should catch
+ // almost all uses (effective MTU for UDP under IPv4 is 1468), except
+ // for localhost datagrams and those reassembled by the IP layer.
+ char udpMessagePeekBuffer[1500];
+ std::vector<WSABUF> buf;
for (;;) {
- // We start at 1500 bytes (the MTU for Ethernet V2), which should catch
- // almost all uses (effective MTU for UDP under IPv4 is 1468), except
- // for localhost datagrams and those reassembled by the IP layer.
- char udpMessagePeekBuffer[1500];
-
- buf = new WSABUF[bufferCount];
- for (DWORD i=0; i<bufferCount; i++) {
- buf[i].buf = udpMessagePeekBuffer;
- buf[i].len = sizeof(udpMessagePeekBuffer);
- }
+ buf.resize(buf.size() + 5, {sizeof(udpMessagePeekBuffer), udpMessagePeekBuffer});
+
flags = MSG_PEEK;
DWORD bytesRead = 0;
- recvResult = ::WSARecv(socketDescriptor, buf, bufferCount, &bytesRead, &flags, 0,0);
+ recvResult = ::WSARecv(socketDescriptor, buf.data(), DWORD(buf.size()), &bytesRead, &flags, nullptr, nullptr);
int err = WSAGetLastError();
if (recvResult != SOCKET_ERROR) {
ret = qint64(bytesRead);
@@ -1169,8 +1164,6 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
} else {
switch (err) {
case WSAEMSGSIZE:
- bufferCount += 5;
- delete[] buf;
continue;
case WSAECONNRESET:
case WSAENETRESET:
@@ -1185,9 +1178,6 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
}
}
- if (buf)
- delete[] buf;
-
#if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %lli", ret);
#endif
diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h
index 6688bfe35c..e1fe58bb97 100644
--- a/src/network/socket/qnativesocketengine_winrt_p.h
+++ b/src/network/socket/qnativesocketengine_winrt_p.h
@@ -188,7 +188,7 @@ private slots:
private:
Q_DECLARE_PRIVATE(QNativeSocketEngine)
- Q_DISABLE_COPY(QNativeSocketEngine)
+ Q_DISABLE_COPY_MOVE(QNativeSocketEngine)
};
class QNativeSocketEnginePrivate : public QAbstractSocketEnginePrivate
diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp
index dd2bc90855..23aec12390 100644
--- a/src/network/socket/qsocks5socketengine.cpp
+++ b/src/network/socket/qsocks5socketengine.cpp
@@ -372,7 +372,7 @@ QSocks5BindData *QSocks5BindStore::retrieve(qintptr socketDescriptor)
store.erase(it);
if (bindData) {
if (bindData->controlSocket->thread() != QThread::currentThread()) {
- qWarning("Can not access socks5 bind data from different thread");
+ qWarning("Cannot access socks5 bind data from different thread");
return 0;
}
} else {
@@ -706,7 +706,7 @@ void QSocks5SocketEnginePrivate::reauthenticate()
// we require authentication
QAuthenticator auth;
- emit q->proxyAuthenticationRequired(proxyInfo, &auth);
+ q->proxyAuthenticationRequired(proxyInfo, &auth);
if (!auth.user().isEmpty() || !auth.password().isEmpty()) {
// we have new credentials, let's try again
@@ -915,7 +915,7 @@ void QSocks5SocketEnginePrivate::_q_emitPendingReadNotification()
if (readNotificationEnabled) {
QSOCKS5_D_DEBUG << "emitting readNotification";
QPointer<QSocks5SocketEngine> qq = q;
- emit q->readNotification();
+ q->readNotification();
if (!qq)
return;
// check if there needs to be a new zero read notification
@@ -944,7 +944,7 @@ void QSocks5SocketEnginePrivate::_q_emitPendingWriteNotification()
Q_Q(QSocks5SocketEngine);
if (writeNotificationEnabled) {
QSOCKS5_D_DEBUG << "emitting writeNotification";
- emit q->writeNotification();
+ q->writeNotification();
}
}
@@ -964,7 +964,7 @@ void QSocks5SocketEnginePrivate::_q_emitPendingConnectionNotification()
connectionNotificationPending = false;
Q_Q(QSocks5SocketEngine);
QSOCKS5_D_DEBUG << "emitting connectionNotification";
- emit q->connectionNotification();
+ q->connectionNotification();
}
void QSocks5SocketEnginePrivate::emitConnectionNotification()
diff --git a/src/network/socket/qsocks5socketengine_p.h b/src/network/socket/qsocks5socketengine_p.h
index 1942eff4ca..ef9d771753 100644
--- a/src/network/socket/qsocks5socketengine_p.h
+++ b/src/network/socket/qsocks5socketengine_p.h
@@ -127,7 +127,7 @@ public:
private:
Q_DECLARE_PRIVATE(QSocks5SocketEngine)
- Q_DISABLE_COPY(QSocks5SocketEngine)
+ Q_DISABLE_COPY_MOVE(QSocks5SocketEngine)
Q_PRIVATE_SLOT(d_func(), void _q_controlSocketConnected())
Q_PRIVATE_SLOT(d_func(), void _q_controlSocketReadNotification())
Q_PRIVATE_SLOT(d_func(), void _q_controlSocketError(QAbstractSocket::SocketError))
diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp
index eddf789921..56c700ca8f 100644
--- a/src/network/socket/qtcpserver.cpp
+++ b/src/network/socket/qtcpserver.cpp
@@ -493,7 +493,7 @@ QHostAddress QTcpServer::serverAddress() const
Waits for at most \a msec milliseconds or until an incoming
connection is available. Returns \c true if a connection is
available; otherwise returns \c false. If the operation timed out
- and \a timedOut is not 0, *\a timedOut will be set to true.
+ and \a timedOut is not \nullptr, *\a timedOut will be set to true.
This is a blocking function call. Its use is disadvised in a
single-threaded GUI application, since the whole application will
diff --git a/src/network/ssl/qasn1element_p.h b/src/network/ssl/qasn1element_p.h
index 2068254a95..22948e3ca5 100644
--- a/src/network/ssl/qasn1element_p.h
+++ b/src/network/ssl/qasn1element_p.h
@@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE
#define RSA_ENCRYPTION_OID QByteArrayLiteral(RSADSI_OID "1.1.1")
#define DSA_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10040.4.1")
#define EC_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10045.2.1")
+#define DH_ENCRYPTION_OID QByteArrayLiteral(RSADSI_OID "1.3.1")
// These are mostly from the RFC for PKCS#5
// PKCS#5: https://tools.ietf.org/html/rfc8018#appendix-B
@@ -137,6 +138,7 @@ public:
Rfc822NameType = 0x81,
DnsNameType = 0x82,
UniformResourceIdentifierType = 0x86,
+ IpAddressType = 0x87,
// context specific
Context0Type = 0xA0,
diff --git a/src/network/ssl/qdtls.h b/src/network/ssl/qdtls.h
index 8505b00d5e..d057eadf19 100644
--- a/src/network/ssl/qdtls.h
+++ b/src/network/ssl/qdtls.h
@@ -48,7 +48,9 @@
#include <QtCore/qcryptographichash.h>
#include <QtCore/qobject.h>
+#ifndef Q_CLANG_QDOC
QT_REQUIRE_CONFIG(dtls);
+#endif
QT_BEGIN_NAMESPACE
diff --git a/src/network/ssl/qocsp_p.h b/src/network/ssl/qocsp_p.h
new file mode 100644
index 0000000000..71f59da0b4
--- /dev/null
+++ b/src/network/ssl/qocsp_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOCSP_P_H
+#define QOCSP_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.
+//
+
+// Note, this file is a workaround: on 64-bit Windows one of OpenSSL
+// includes combined with openssl/ocsp.h results in macros from
+// wincrypt.h exposed. OpenSSL's own very "unique" and "inventive"
+// names like OCSP_RESPONSE or X509_NAME were asking to clash with
+// other entities (presumably macros) with the same names. Normally,
+// ossl_typ.h un-defines them, but due to a bug in OpenSSL, fails
+// to do this on Win 64. Thus we have to do it here. We only undef
+// 3 names, ossl_typ.h has more, but apparently we don't need them
+// (no name clash so far).
+
+QT_REQUIRE_CONFIG(ocsp);
+
+#ifdef Q_OS_WIN
+#undef X509_NAME
+#undef OCSP_REQUEST
+#undef OCSP_RESPONSE
+#endif // Q_OS_WIN
+
+#include <openssl/ocsp.h>
+
+#endif // QOCSP_P_H
diff --git a/src/network/ssl/qocspresponse.cpp b/src/network/ssl/qocspresponse.cpp
new file mode 100644
index 0000000000..d564e817ca
--- /dev/null
+++ b/src/network/ssl/qocspresponse.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+** Copyright (C) 2011 Richard J. Moore <rich@kde.org>
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qocspresponse_p.h"
+#include "qocspresponse.h"
+
+#include "qhashfunctions.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QOcspResponse
+ \brief This class represents Online Certificate Status Protocol response.
+ \since 5.13
+
+ \ingroup network
+ \ingroup ssl
+ \inmodule QtNetwork
+
+ The QOcspResponse class represents the revocation status of a server's certficate,
+ received by the client-side socket during the TLS handshake. QSslSocket must be
+ configured with OCSP stapling enabled.
+
+ \sa QSslSocket, QSslSocket::ocspResponses(), certificateStatus(),
+ revocationReason(), responder(), subject(), QOcspCertificateStatus, QOcspRevocationReason,
+ QSslConfiguration::setOcspStaplingEnabled(), QSslConfiguration::ocspStaplingEnabled(),
+ QSslConfiguration::peerCertificate()
+*/
+
+/*!
+ \enum QOcspCertificateStatus
+ \brief Describes the Online Certificate Status
+ \relates QOcspResponse
+ \since 5.13
+
+ \ingroup network
+ \ingroup ssl
+ \inmodule QtNetwork
+
+ \value Good The certificate is not revoked, but this does not necessarily
+ mean that the certificate was ever issued or that the time at which
+ the response was produced is within the certificate's validity interval.
+ \value Revoked This state indicates that the certificate has been revoked
+ (either permanently or temporarily - on hold).
+ \value Unknown This state indicates that the responder doesn't know about
+ the certificate being requested.
+
+ \sa QOcspRevocationReason
+*/
+
+/*!
+ \enum QOcspRevocationReason
+ \brief Describes the reason for revocation
+ \relates QOcspResponse
+ \since 5.13
+
+ \ingroup network
+ \ingroup ssl
+ \inmodule QtNetwork
+
+
+ This enumeration describes revocation reasons, defined in \l{https://tools.ietf.org/html/rfc5280#section-5.3.1}{RFC 5280, section 5.3.1}
+
+ \value None
+ \value Unspecified
+ \value KeyCompromise
+ \value CACompromise
+ \value AffiliationChanged
+ \value Superseded
+ \value CessationOfOperation
+ \value CertificateHold
+ \value RemoveFromCRL
+*/
+
+/*!
+ \since 5.13
+
+ Creates a new response with status QOcspCertificateStatus::Unknown
+ and revocation reason QOcspRevocationReason::None.
+
+ \sa QOcspCertificateStatus
+*/
+QOcspResponse::QOcspResponse()
+ : d(new QOcspResponsePrivate)
+{
+}
+
+/*!
+ \since 5.13
+
+ Copy-constructs a QOcspResponse instance.
+*/
+QOcspResponse::QOcspResponse(const QOcspResponse &) = default;
+
+/*!
+ \since 5.13
+
+ Move-constructs a QOcspResponse instance.
+*/
+QOcspResponse::QOcspResponse(QOcspResponse &&) Q_DECL_NOTHROW = default;
+
+/*!
+ \since 5.13
+
+ Destroys the response.
+*/
+QOcspResponse::~QOcspResponse() = default;
+
+/*!
+ \since 5.13
+
+ Copy-assigns and returns a reference to this response.
+*/
+QOcspResponse &QOcspResponse::operator=(const QOcspResponse &) = default;
+
+/*!
+ \since 5.13
+
+ Move-assigns to this QOcspResponse instance.
+*/
+QOcspResponse &QOcspResponse::operator=(QOcspResponse &&) Q_DECL_NOTHROW = default;
+
+/*!
+ \fn void QOcspResponse::swap(QOcspResponse &other)
+ \since 5.13
+
+ Swaps this response with \a other.
+*/
+
+/*!
+ \since 5.13
+
+ Returns the certificate status.
+
+ \sa QOcspCertificateStatus
+*/
+QOcspCertificateStatus QOcspResponse::certificateStatus() const
+{
+ return d->certificateStatus;
+}
+
+/*!
+ \since 5.13
+
+ Returns the reason for revocation.
+*/
+QOcspRevocationReason QOcspResponse::revocationReason() const
+{
+ return d->revocationReason;
+}
+
+/*!
+ \since 5.13
+
+ This function returns a certificate used to sign OCSP response.
+*/
+QSslCertificate QOcspResponse::responder() const
+{
+ return d->signerCert;
+}
+
+/*!
+ \since 5.13
+
+ This function returns a certificate, for which this response was issued.
+*/
+QSslCertificate QOcspResponse::subject() const
+{
+ return d->subjectCert;
+}
+
+/*!
+ \fn bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs)
+
+ Returns \c true if \a lhs and \a rhs are the responses for the same
+ certificate, signed by the same responder, have the same
+ revocation reason and the same certificate status.
+
+ \since 5.13
+ \relates QOcspResponse
+ */
+Q_NETWORK_EXPORT bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs)
+{
+ return lhs.d == rhs.d || *lhs.d == *rhs.d;
+}
+
+/*!
+ \fn bool operator != (const QOcspResponse &lhs, const QOcspResponse &rhs)
+
+ Returns \c true if \a lhs and \a rhs are responses for different certificates,
+ or signed by different responders, or have different revocation reasons, or different
+ certificate statuses.
+
+ \since 5.13
+ \relates QOcspResponse
+*/
+
+/*!
+ \fn uint qHash(const QOcspResponse &response, uint seed)
+
+ Returns the hash value for the \a response, using \a seed to seed the calculation.
+
+ \since 5.13
+ \relates QHash
+*/
+uint qHash(const QOcspResponse &response, uint seed)
+{
+ const QOcspResponsePrivate *d = response.d.data();
+ Q_ASSERT(d);
+
+ QtPrivate::QHashCombine hasher;
+ uint hash = hasher(seed, int(d->certificateStatus));
+ hash = hasher(hash, int(d->revocationReason));
+ if (!d->signerCert.isNull())
+ hash = hasher(hash, d->signerCert);
+ if (!d->subjectCert.isNull())
+ hash = hasher(hash, d->subjectCert);
+
+ return hash;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qocspresponse.h b/src/network/ssl/qocspresponse.h
new file mode 100644
index 0000000000..552a088ba5
--- /dev/null
+++ b/src/network/ssl/qocspresponse.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+** Copyright (C) 2011 Richard J. Moore <rich@kde.org>
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOCSPRESPONSE_H
+#define QOCSPRESPONSE_H
+
+#include <QtNetwork/qtnetworkglobal.h>
+
+#include <QtCore/qshareddata.h>
+#include <QtCore/qmetatype.h>
+#include <QtCore/qobject.h>
+
+#ifndef Q_CLANG_QDOC
+QT_REQUIRE_CONFIG(ssl);
+#endif
+
+QT_BEGIN_NAMESPACE
+
+enum class QOcspCertificateStatus
+{
+ Good,
+ Revoked,
+ Unknown
+};
+
+enum class QOcspRevocationReason
+{
+ None = -1,
+ Unspecified,
+ KeyCompromise,
+ CACompromise,
+ AffiliationChanged,
+ Superseded,
+ CessationOfOperation,
+ CertificateHold,
+ RemoveFromCRL
+};
+
+class QOcspResponse;
+Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed = 0);
+
+class QOcspResponsePrivate;
+class Q_NETWORK_EXPORT QOcspResponse
+{
+public:
+
+ QOcspResponse();
+ QOcspResponse(const QOcspResponse &other);
+ QOcspResponse(QOcspResponse && other) Q_DECL_NOEXCEPT;
+ ~QOcspResponse();
+
+ QOcspResponse &operator = (const QOcspResponse &other);
+ QOcspResponse &operator = (QOcspResponse &&other) Q_DECL_NOTHROW;
+
+ QOcspCertificateStatus certificateStatus() const;
+ QOcspRevocationReason revocationReason() const;
+
+ class QSslCertificate responder() const;
+ QSslCertificate subject() const;
+
+ void swap(QOcspResponse &other) Q_DECL_NOTHROW { d.swap(other.d); }
+
+private:
+
+ friend class QSslSocketBackendPrivate;
+ friend Q_NETWORK_EXPORT bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs);
+ friend Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed);
+
+ QSharedDataPointer<QOcspResponsePrivate> d;
+};
+
+inline bool operator!=(const QOcspResponse &lhs, const QOcspResponse &rhs) { return !(lhs == rhs); }
+
+Q_DECLARE_SHARED(QOcspResponse)
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QOcspResponse)
+
+#endif // QOCSPRESPONSE_H
diff --git a/src/network/ssl/qocspresponse_p.h b/src/network/ssl/qocspresponse_p.h
new file mode 100644
index 0000000000..e421b76899
--- /dev/null
+++ b/src/network/ssl/qocspresponse_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+** Copyright (C) 2011 Richard J. Moore <rich@kde.org>
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOCSPRESPONSE_P_H
+#define QOCSPRESPONSE_P_H
+
+#include <private/qtnetworkglobal_p.h>
+
+#include <qsslcertificate.h>
+#include <qocspresponse.h>
+
+#include <qshareddata.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.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QOcspResponsePrivate : public QSharedData
+{
+public:
+
+ QOcspCertificateStatus certificateStatus = QOcspCertificateStatus::Unknown;
+ QOcspRevocationReason revocationReason = QOcspRevocationReason::None;
+
+ QSslCertificate signerCert;
+ QSslCertificate subjectCert;
+};
+
+inline bool operator==(const QOcspResponsePrivate &lhs, const QOcspResponsePrivate &rhs)
+{
+ return lhs.certificateStatus == rhs.certificateStatus
+ && lhs.revocationReason == rhs.revocationReason
+ && lhs.signerCert == rhs.signerCert
+ && lhs.subjectCert == rhs.subjectCert;
+}
+
+QT_END_NAMESPACE
+
+#endif // QOCSPRESPONSE_P_H
diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp
index 19d99bc489..c9fa7f85d9 100644
--- a/src/network/ssl/qssl.cpp
+++ b/src/network/ssl/qssl.cpp
@@ -71,7 +71,8 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl");
\value Rsa The RSA algorithm.
\value Dsa The DSA algorithm.
- \value Ec The Elliptic Curve algorithm
+ \value Ec The Elliptic Curve algorithm.
+ \value Dh The Diffie-Hellman algorithm.
\value Opaque A key that should be treated as a 'black box' by QSslKey.
The opaque key facility allows applications to add support for facilities
@@ -98,6 +99,9 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl");
\value DnsEntry A DNS host name entry; the entry contains a host name
entry that the certificate is valid for. The entry may contain wildcards.
+ \value IpAddressEntry An IP address entry; the entry contains an IP address
+ entry that the certificate is valid for, introduced in Qt 5.13.
+
\note In Qt 4, this enum was called \c {AlternateNameEntryType}. That name
is deprecated in Qt 5.
@@ -116,8 +120,8 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl");
Describes the protocol of the cipher.
- \value SslV3 SSLv3. When using the WinRT backend this option will also enable TLSv1.0
- \value SslV2 SSLv2. Note, SSLv2 support was removed in OpenSSL 1.1.
+ \value SslV3 SSLv3; not supported by QSslSocket.
+ \value SslV2 SSLv2; not supported by QSslSocket.
\value TlsV1_0 TLSv1.0
\value TlsV1_0OrLater TLSv1.0 and later versions. This option is not available when using the WinRT backend due to platform limitations.
\value TlsV1 Obsolete, means the same as TlsV1_0
@@ -132,19 +136,9 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl");
\value TlsV1_3 TLSv1.3. (Since Qt 5.12)
\value TlsV1_3OrLater TLSv1.3 and later versions. (Since Qt 5.12)
\value UnknownProtocol The cipher's protocol cannot be determined.
- \value AnyProtocol The socket understands SSLv2, SSLv3, TLSv1.0 and all
- supported later versions of TLS. This value is used by QSslSocket only.
- \value TlsV1SslV3 On the client side, this will send
- a TLS 1.0 Client Hello, enabling TLSv1_0 and SSLv3 connections.
- On the server side, this will enable both SSLv3 and TLSv1_0 connections.
- \value SecureProtocols The default option, using protocols known to be secure;
- currently behaves similar to TlsV1Ssl3 except denying SSLv3 connections that does
- not upgrade to TLS.
-
- \note most servers understand both SSL and TLS, but it is recommended to use
- TLS only for security reasons. However, SSL and TLS are not compatible with
- each other: if you get unexpected handshake failures, verify that you chose
- the correct setting for your protocol.
+ \value AnyProtocol Any supported protocol. This value is used by QSslSocket only.
+ \value TlsV1SslV3 Same as TlsV1_0.
+ \value SecureProtocols The default option, using protocols known to be secure.
*/
/*!
diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h
index 60362cb410..42c7b5c56d 100644
--- a/src/network/ssl/qssl.h
+++ b/src/network/ssl/qssl.h
@@ -62,12 +62,14 @@ namespace QSsl {
Opaque,
Rsa,
Dsa,
- Ec
+ Ec,
+ Dh,
};
enum AlternativeNameEntryType {
EmailEntry,
- DnsEntry
+ DnsEntry,
+ IpAddressEntry
};
#if QT_DEPRECATED_SINCE(5,0)
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp
index d153e0b929..0156b5bf96 100644
--- a/src/network/ssl/qsslcertificate.cpp
+++ b/src/network/ssl/qsslcertificate.cpp
@@ -121,6 +121,9 @@
#ifdef QT_SECURETRANSPORT
#include "qsslsocket_mac_p.h"
#endif
+#if QT_CONFIG(schannel)
+#include "qsslsocket_schannel_p.h"
+#endif
#include "qssl_p.h"
#include "qsslcertificate.h"
diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp
index fa87cfeaaf..899c8a0d2d 100644
--- a/src/network/ssl/qsslcertificate_openssl.cpp
+++ b/src/network/ssl/qsslcertificate_openssl.cpp
@@ -44,13 +44,15 @@
#include "qsslkey_p.h"
#include "qsslcertificateextension_p.h"
+#include <QtCore/qendian.h>
+
#if QT_CONFIG(thread)
#include <QtCore/private/qmutexpool_p.h>
#endif
QT_BEGIN_NAMESPACE
// forward declaration
-static QMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name);
+static QMultiMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name);
bool QSslCertificate::operator==(const QSslCertificate &other) const
{
@@ -207,10 +209,14 @@ QMultiMap<QSsl::AlternativeNameEntryType, QString> QSslCertificate::subjectAlter
STACK_OF(GENERAL_NAME) *altNames = (STACK_OF(GENERAL_NAME) *)q_X509_get_ext_d2i(
d->x509, NID_subject_alt_name, nullptr, nullptr);
+ auto altName = [](ASN1_IA5STRING *ia5, int len) {
+ const char *altNameStr = reinterpret_cast<const char *>(q_ASN1_STRING_get0_data(ia5));
+ return QString::fromLatin1(altNameStr, len);
+ };
if (altNames) {
for (int i = 0; i < q_sk_GENERAL_NAME_num(altNames); ++i) {
const GENERAL_NAME *genName = q_sk_GENERAL_NAME_value(altNames, i);
- if (genName->type != GEN_DNS && genName->type != GEN_EMAIL)
+ if (genName->type != GEN_DNS && genName->type != GEN_EMAIL && genName->type != GEN_IPADD)
continue;
int len = q_ASN1_STRING_length(genName->d.ia5);
@@ -219,12 +225,32 @@ QMultiMap<QSsl::AlternativeNameEntryType, QString> QSslCertificate::subjectAlter
continue;
}
- const char *altNameStr = reinterpret_cast<const char *>(q_ASN1_STRING_get0_data(genName->d.ia5));
- const QString altName = QString::fromLatin1(altNameStr, len);
- if (genName->type == GEN_DNS)
- result.insert(QSsl::DnsEntry, altName);
- else if (genName->type == GEN_EMAIL)
- result.insert(QSsl::EmailEntry, altName);
+ switch (genName->type) {
+ case GEN_DNS:
+ result.insert(QSsl::DnsEntry, altName(genName->d.ia5, len));
+ break;
+ case GEN_EMAIL:
+ result.insert(QSsl::EmailEntry, altName(genName->d.ia5, len));
+ break;
+ case GEN_IPADD: {
+ QHostAddress ipAddress;
+ switch (len) {
+ case 4: // IPv4
+ ipAddress = QHostAddress(qFromBigEndian(*reinterpret_cast<quint32 *>(genName->d.iPAddress->data)));
+ break;
+ case 16: // IPv6
+ ipAddress = QHostAddress(reinterpret_cast<quint8 *>(genName->d.iPAddress->data));
+ break;
+ default: // Unknown IP address format
+ break;
+ }
+ if (!ipAddress.isNull())
+ result.insert(QSsl::IpAddressEntry, ipAddress.toString());
+ break;
+ }
+ default:
+ break;
+ }
}
q_OPENSSL_sk_pop_free((OPENSSL_STACK*)altNames, reinterpret_cast<void(*)(void*)>(q_GENERAL_NAME_free));
@@ -615,16 +641,16 @@ QByteArray QSslCertificatePrivate::asn1ObjectName(ASN1_OBJECT *object)
return asn1ObjectId(object);
}
-static QMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name)
+static QMultiMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name)
{
- QMap<QByteArray, QString> info;
+ QMultiMap<QByteArray, QString> info;
for (int i = 0; i < q_X509_NAME_entry_count(name); ++i) {
X509_NAME_ENTRY *e = q_X509_NAME_get_entry(name, i);
QByteArray name = QSslCertificatePrivate::asn1ObjectName(q_X509_NAME_ENTRY_get_object(e));
unsigned char *data = nullptr;
int size = q_ASN1_STRING_to_UTF8(&data, q_X509_NAME_ENTRY_get_data(e));
- info.insertMulti(name, QString::fromUtf8((char*)data, size));
+ info.insert(name, QString::fromUtf8((char*)data, size));
#if QT_CONFIG(opensslv11)
q_CRYPTO_free(data, nullptr, 0);
#else
diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h
index dfdceab502..4b331d4c4e 100644
--- a/src/network/ssl/qsslcertificate_p.h
+++ b/src/network/ssl/qsslcertificate_p.h
@@ -75,6 +75,10 @@ struct ASN1_OBJECT;
#include <windows.security.cryptography.certificates.h>
#endif
+#if QT_CONFIG(schannel)
+#include <wincrypt.h>
+#endif
+
QT_BEGIN_NAMESPACE
// forward declaration
@@ -96,14 +100,18 @@ public:
if (x509)
q_X509_free(x509);
#endif
+#if QT_CONFIG(schannel)
+ if (certificateContext)
+ CertFreeCertificateContext(certificateContext);
+#endif
}
bool null;
QByteArray versionString;
QByteArray serialNumberString;
- QMap<QByteArray, QString> issuerInfo;
- QMap<QByteArray, QString> subjectInfo;
+ QMultiMap<QByteArray, QString> issuerInfo;
+ QMultiMap<QByteArray, QString> subjectInfo;
QDateTime notValidAfter;
QDateTime notValidBefore;
@@ -143,6 +151,12 @@ public:
static QSslCertificate QSslCertificate_from_Certificate(ABI::Windows::Security::Cryptography::Certificates::ICertificate *iCertificate);
#endif
+
+#if QT_CONFIG(schannel)
+ const CERT_CONTEXT *certificateContext = nullptr;
+
+ static QSslCertificate QSslCertificate_from_CERT_CONTEXT(const CERT_CONTEXT *certificateContext);
+#endif
};
QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslcertificate_qt.cpp b/src/network/ssl/qsslcertificate_qt.cpp
index dfdfd529e5..cce59b5ef3 100644
--- a/src/network/ssl/qsslcertificate_qt.cpp
+++ b/src/network/ssl/qsslcertificate_qt.cpp
@@ -50,6 +50,8 @@
#include "qasn1element_p.h"
#include <QtCore/qdatastream.h>
+#include <QtCore/qendian.h>
+#include <QtNetwork/qhostaddress.h>
QT_BEGIN_NAMESPACE
@@ -139,7 +141,7 @@ QDateTime QSslCertificate::expiryDate() const
return d->notValidAfter;
}
-#ifndef Q_OS_WINRT // implemented in qsslcertificate_winrt.cpp
+#if !defined(Q_OS_WINRT) && !QT_CONFIG(schannel) // implemented in qsslcertificate_{winrt,schannel}.cpp
Qt::HANDLE QSslCertificate::handle() const
{
Q_UNIMPLEMENTED();
@@ -206,6 +208,10 @@ void QSslCertificatePrivate::init(const QByteArray &data, QSsl::EncodingFormat f
: certificatesFromDer(data, 1);
if (!certs.isEmpty()) {
*this = *certs.first().d;
+#if QT_CONFIG(schannel)
+ if (certificateContext)
+ certificateContext = CertDuplicateCertificateContext(certificateContext);
+#endif
}
}
}
@@ -399,10 +405,32 @@ bool QSslCertificatePrivate::parse(const QByteArray &data)
QDataStream nameStream(sanElem.value());
QAsn1Element nameElem;
while (nameElem.read(nameStream)) {
- if (nameElem.type() == QAsn1Element::Rfc822NameType) {
+ switch (nameElem.type()) {
+ case QAsn1Element::Rfc822NameType:
subjectAlternativeNames.insert(QSsl::EmailEntry, nameElem.toString());
- } else if (nameElem.type() == QAsn1Element::DnsNameType) {
+ break;
+ case QAsn1Element::DnsNameType:
subjectAlternativeNames.insert(QSsl::DnsEntry, nameElem.toString());
+ break;
+ case QAsn1Element::IpAddressType: {
+ QHostAddress ipAddress;
+ QByteArray ipAddrValue = nameElem.value();
+ switch (ipAddrValue.length()) {
+ case 4: // IPv4
+ ipAddress = QHostAddress(qFromBigEndian(*reinterpret_cast<quint32 *>(ipAddrValue.data())));
+ break;
+ case 16: // IPv6
+ ipAddress = QHostAddress(reinterpret_cast<quint8 *>(ipAddrValue.data()));
+ break;
+ default: // Unknown IP address format
+ break;
+ }
+ if (!ipAddress.isNull())
+ subjectAlternativeNames.insert(QSsl::IpAddressEntry, ipAddress.toString());
+ break;
+ }
+ default:
+ break;
}
}
}
diff --git a/src/network/ssl/qsslcertificate_schannel.cpp b/src/network/ssl/qsslcertificate_schannel.cpp
new file mode 100644
index 0000000000..5ea713612a
--- /dev/null
+++ b/src/network/ssl/qsslcertificate_schannel.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsslcertificate.h"
+#include "qsslcertificate_p.h"
+
+#include <wincrypt.h>
+
+QT_BEGIN_NAMESPACE
+
+QSslCertificate QSslCertificatePrivate::QSslCertificate_from_CERT_CONTEXT(const CERT_CONTEXT *certificateContext)
+{
+ QByteArray derData = QByteArray((const char *)certificateContext->pbCertEncoded,
+ certificateContext->cbCertEncoded);
+
+ QSslCertificate certificate(derData, QSsl::Der);
+ certificate.d->certificateContext = CertDuplicateCertificateContext(certificateContext);
+ return certificate;
+}
+
+Qt::HANDLE QSslCertificate::handle() const
+{
+ return Qt::HANDLE(d->certificateContext);
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index 3f732b4646..7e92d3a526 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -228,7 +228,8 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
d->nextAllowedProtocols == other.d->nextAllowedProtocols &&
d->nextNegotiatedProtocol == other.d->nextNegotiatedProtocol &&
d->nextProtocolNegotiationStatus == other.d->nextProtocolNegotiationStatus &&
- d->dtlsCookieEnabled == other.d->dtlsCookieEnabled;
+ d->dtlsCookieEnabled == other.d->dtlsCookieEnabled &&
+ d->ocspStaplingEnabled == other.d->ocspStaplingEnabled;
}
/*!
@@ -272,7 +273,8 @@ bool QSslConfiguration::isNull() const
d->preSharedKeyIdentityHint.isNull() &&
d->nextAllowedProtocols.isEmpty() &&
d->nextNegotiatedProtocol.isNull() &&
- d->nextProtocolNegotiationStatus == QSslConfiguration::NextProtocolNegotiationNone);
+ d->nextProtocolNegotiationStatus == QSslConfiguration::NextProtocolNegotiationNone &&
+ d->ocspStaplingEnabled == false);
}
/*!
@@ -585,6 +587,8 @@ void QSslConfiguration::setPrivateKey(const QSslKey &key)
ciphers. You can revert to using the entire set by calling
setCiphers() with the list returned by QSslSocket::supportedCiphers().
+ \note This is not currently supported in the Schannel backend.
+
\sa setCiphers(), QSslSocket::supportedCiphers()
*/
QList<QSslCipher> QSslConfiguration::ciphers() const
@@ -600,6 +604,8 @@ QList<QSslCipher> QSslConfiguration::ciphers() const
Restricting the cipher suite must be done before the handshake
phase, where the session cipher is chosen.
+ \note This is not currently supported in the Schannel backend.
+
\sa ciphers(), QSslSocket::supportedCiphers()
*/
void QSslConfiguration::setCiphers(const QList<QSslCipher> &ciphers)
@@ -1094,6 +1100,37 @@ void QSslConfiguration::setDefaultDtlsConfiguration(const QSslConfiguration &con
#endif // dtls
+/*!
+ \since 5.13
+ If \a enabled is true, client QSslSocket will send a certificate status request
+ to its peer when initiating a handshake. During the handshake QSslSocket will
+ verify the server's response. This value must be set before the handshake
+ starts.
+
+ \sa ocspStaplingEnabled()
+*/
+void QSslConfiguration::setOcspStaplingEnabled(bool enabled)
+{
+#if QT_CONFIG(ocsp)
+ d->ocspStaplingEnabled = enabled;
+#else
+ if (enabled)
+ qCWarning(lcSsl, "Enabling OCSP-stapling requires the feature 'ocsp'");
+#endif // ocsp
+}
+
+/*!
+ \since 5.13
+ Returns true if OCSP stapling was enabled by setOCSPStaplingEnabled(),
+ otherwise false (which is the default value).
+
+ \sa setOcspStaplingEnabled()
+*/
+bool QSslConfiguration::ocspStaplingEnabled() const
+{
+ return d->ocspStaplingEnabled;
+}
+
/*! \internal
*/
bool QSslConfigurationPrivate::peerSessionWasShared(const QSslConfiguration &configuration) {
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index 454ac0cee3..8f53e25a53 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -170,6 +170,9 @@ public:
static void setDefaultDtlsConfiguration(const QSslConfiguration &configuration);
#endif // dtls
+ void setOcspStaplingEnabled(bool enable);
+ bool ocspStaplingEnabled() const;
+
enum NextProtocolNegotiationStatus {
NextProtocolNegotiationNone,
NextProtocolNegotiationNegotiated,
diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h
index 6c23165c6a..83126bb9a0 100644
--- a/src/network/ssl/qsslconfiguration_p.h
+++ b/src/network/ssl/qsslconfiguration_p.h
@@ -143,6 +143,12 @@ public:
const bool dtlsCookieEnabled = false;
#endif // dtls
+#if QT_CONFIG(ocsp)
+ bool ocspStaplingEnabled = false;
+#else
+ const bool ocspStaplingEnabled = false;
+#endif
+
// in qsslsocket.cpp:
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp
index 35cca9f01a..e81e5582f4 100644
--- a/src/network/ssl/qsslcontext_openssl.cpp
+++ b/src/network/ssl/qsslcontext_openssl.cpp
@@ -243,12 +243,28 @@ QString QSslContext::errorString() const
return errorStr;
}
+#if QT_CONFIG(ocsp)
+extern "C" int qt_OCSP_status_server_callback(SSL *ssl, void *); // Defined in qsslsocket_openssl.cpp.
+#endif // ocsp
// static
void QSslContext::applyBackendConfig(QSslContext *sslContext)
{
- if (sslContext->sslConfiguration.backendConfiguration().isEmpty())
+ const QMap<QByteArray, QVariant> &conf = sslContext->sslConfiguration.backendConfiguration();
+ if (conf.isEmpty())
return;
+#if QT_CONFIG(ocsp)
+ auto ocspResponsePos = conf.find("Qt-OCSP-response");
+ if (ocspResponsePos != conf.end()) {
+ // This is our private, undocumented configuration option, existing only for
+ // the purpose of testing OCSP status responses. We don't even check this
+ // callback was set. If no - the test must fail.
+ q_SSL_CTX_set_tlsext_status_cb(sslContext->ctx, qt_OCSP_status_server_callback);
+ if (conf.size() == 1)
+ return;
+ }
+#endif // ocsp
+
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) {
QSharedPointer<SSL_CONF_CTX> cctx(q_SSL_CONF_CTX_new(), &q_SSL_CONF_CTX_free);
@@ -256,8 +272,10 @@ void QSslContext::applyBackendConfig(QSslContext *sslContext)
q_SSL_CONF_CTX_set_ssl_ctx(cctx.data(), sslContext->ctx);
q_SSL_CONF_CTX_set_flags(cctx.data(), SSL_CONF_FLAG_FILE);
- const auto &backendConfig = sslContext->sslConfiguration.backendConfiguration();
- for (auto i = backendConfig.constBegin(); i != backendConfig.constEnd(); ++i) {
+ for (auto i = conf.constBegin(); i != conf.constEnd(); ++i) {
+ if (i.key() == "Qt-OCSP-response") // This never goes to SSL_CONF_cmd().
+ continue;
+
if (!i.value().canConvert(QMetaType::QByteArray)) {
sslContext->errorCode = QSslError::UnspecifiedError;
sslContext->errorStr = msgErrorSettingBackendConfig(
diff --git a/src/network/ssl/qsslcontext_openssl11.cpp b/src/network/ssl/qsslcontext_openssl11.cpp
index c96a48dac1..21a5c779f7 100644
--- a/src/network/ssl/qsslcontext_openssl11.cpp
+++ b/src/network/ssl/qsslcontext_openssl11.cpp
@@ -95,6 +95,10 @@ init_context:
// SSL 2 is no longer supported, but chosen deliberately -> error
sslContext->ctx = nullptr;
unsupportedProtocol = true;
+ } else if (sslContext->sslConfiguration.protocol() == QSsl::SslV3) {
+ // SSL 3 is no longer supported, but chosen deliberately -> error
+ sslContext->ctx = nullptr;
+ unsupportedProtocol = true;
} else {
switch (sslContext->sslConfiguration.protocol()) {
case QSsl::DtlsV1_0:
@@ -151,11 +155,6 @@ init_context:
long maxVersion = anyVersion;
switch (sslContext->sslConfiguration.protocol()) {
- // The single-protocol versions first:
- case QSsl::SslV3:
- minVersion = SSL3_VERSION;
- maxVersion = SSL3_VERSION;
- break;
case QSsl::TlsV1_0:
minVersion = TLS1_VERSION;
maxVersion = TLS1_VERSION;
@@ -181,9 +180,6 @@ init_context:
// Ranges:
case QSsl::TlsV1SslV3:
case QSsl::AnyProtocol:
- minVersion = SSL3_VERSION;
- maxVersion = 0;
- break;
case QSsl::SecureProtocols:
case QSsl::TlsV1_0OrLater:
minVersion = TLS1_VERSION;
@@ -227,8 +223,9 @@ init_context:
break;
#endif // TLS1_3_VERSION
case QSsl::SslV2:
- // This protocol is not supported by OpenSSL 1.1 and we handle
- // it as an error (see the code above).
+ case QSsl::SslV3:
+ // These protocols are not supported, and we handle
+ // them as an error (see the code above).
Q_UNREACHABLE();
break;
case QSsl::UnknownProtocol:
diff --git a/src/network/ssl/qsslcontext_opensslpre11.cpp b/src/network/ssl/qsslcontext_opensslpre11.cpp
index 34537d1da4..956c5c32ec 100644
--- a/src/network/ssl/qsslcontext_opensslpre11.cpp
+++ b/src/network/ssl/qsslcontext_opensslpre11.cpp
@@ -115,32 +115,19 @@ init_context:
break;
#endif // dtls
case QSsl::SslV2:
-#ifndef OPENSSL_NO_SSL2
- sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method());
-#else
- // SSL 2 not supported by the system, but chosen deliberately -> error
- sslContext->ctx = 0;
- unsupportedProtocol = true;
-#endif
- break;
case QSsl::SslV3:
-#ifndef OPENSSL_NO_SSL3_METHOD
- sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method());
-#else
- // SSL 3 not supported by the system, but chosen deliberately -> error
+ // We don't support SSLv2 / SSLv3.
sslContext->ctx = 0;
unsupportedProtocol = true;
-#endif
break;
case QSsl::SecureProtocols:
// SSLv2 and SSLv3 will be disabled by SSL options
// But we need q_SSLv23_server_method() otherwise AnyProtocol will be unable to connect on Win32.
- case QSsl::TlsV1SslV3:
- // SSLv2 will will be disabled by SSL options
case QSsl::AnyProtocol:
default:
sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
break;
+ case QSsl::TlsV1SslV3:
case QSsl::TlsV1_0:
sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method());
break;
@@ -212,12 +199,9 @@ init_context:
long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
q_SSL_CTX_set_options(sslContext->ctx, options);
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
// Tell OpenSSL to release memory early
// http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html
- if (q_SSLeay() >= 0x10000000L)
- q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS);
-#endif
+ q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS);
// Initialize ciphers
QByteArray cipherString;
diff --git a/src/network/ssl/qssldiffiehellmanparameters.cpp b/src/network/ssl/qssldiffiehellmanparameters.cpp
index 7fbcff2861..65041d4456 100644
--- a/src/network/ssl/qssldiffiehellmanparameters.cpp
+++ b/src/network/ssl/qssldiffiehellmanparameters.cpp
@@ -136,7 +136,7 @@ QSslDiffieHellmanParameters QSslDiffieHellmanParameters::fromEncoded(const QByte
to check whether the Diffie-Hellman parameters were valid
and loaded correctly.
- In particular, if \a device is \c nullptr or not open for reading, an invalid
+ In particular, if \a device is \nullptr or not open for reading, an invalid
object will be returned.
\sa isValid()
diff --git a/src/network/ssl/qsslellipticcurve.cpp b/src/network/ssl/qsslellipticcurve.cpp
index 88baa1ff6c..5608d32fa7 100644
--- a/src/network/ssl/qsslellipticcurve.cpp
+++ b/src/network/ssl/qsslellipticcurve.cpp
@@ -64,6 +64,8 @@ QT_BEGIN_NAMESPACE
QSslEllipticCurve instances can be compared for equality and can be used as keys
in QHash and QSet. They cannot be used as key in a QMap.
+
+ \note This class is currently only supported in OpenSSL.
*/
/*!
diff --git a/src/network/ssl/qsslerror.cpp b/src/network/ssl/qsslerror.cpp
index 3f79d1a037..02dd16a58d 100644
--- a/src/network/ssl/qsslerror.cpp
+++ b/src/network/ssl/qsslerror.cpp
@@ -86,6 +86,18 @@
\value UnspecifiedError
\value NoSslSupport
\value CertificateBlacklisted
+ \value OcspNoResponseFound
+ \value OcspMalformedRequest
+ \value OcspMalformedResponse
+ \value OcspInternalError
+ \value OcspTryLater
+ \value OcspSigRequred
+ \value OcspUnauthorized
+ \value OcspResponseCannotBeTrusted
+ \value OcspResponseCertIdUnknown
+ \value OcspResponseExpired
+ \value OcspStatusUnknown
+
\sa QSslError::errorString()
*/
@@ -292,6 +304,39 @@ QString QSslError::errorString() const
case CertificateBlacklisted:
errStr = QSslSocket::tr("The peer certificate is blacklisted");
break;
+ case OcspNoResponseFound:
+ errStr = QSslSocket::tr("No OCSP status response found");
+ break;
+ case OcspMalformedRequest:
+ errStr = QSslSocket::tr("The OCSP status request had invalid syntax");
+ break;
+ case OcspMalformedResponse:
+ errStr = QSslSocket::tr("OCSP response contains an unexpected number of SingleResponse structures");
+ break;
+ case OcspInternalError:
+ errStr = QSslSocket::tr("OCSP responder reached an inconsistent internal state");
+ break;
+ case OcspTryLater:
+ errStr = QSslSocket::tr("OCSP responder was unable to return a status for the requested certificate");
+ break;
+ case OcspSigRequred:
+ errStr = QSslSocket::tr("The server requires the client to sign the OCSP request in order to construct a response");
+ break;
+ case OcspUnauthorized:
+ errStr = QSslSocket::tr("The client is not authorized to request OCSP status from this server");
+ break;
+ case OcspResponseCannotBeTrusted:
+ errStr = QSslSocket::tr("OCSP responder's identity cannot be verified");
+ break;
+ case OcspResponseCertIdUnknown:
+ errStr = QSslSocket::tr("The identity of a certificate in an OCSP response cannot be established");
+ break;
+ case OcspResponseExpired:
+ errStr = QSslSocket::tr("The certificate status response has expired");
+ break;
+ case OcspStatusUnknown:
+ errStr = QSslSocket::tr("The certificate's status is unknown");
+ break;
default:
errStr = QSslSocket::tr("Unknown error");
break;
diff --git a/src/network/ssl/qsslerror.h b/src/network/ssl/qsslerror.h
index d7c959423d..513b8afd7f 100644
--- a/src/network/ssl/qsslerror.h
+++ b/src/network/ssl/qsslerror.h
@@ -80,6 +80,18 @@ public:
HostNameMismatch,
NoSslSupport,
CertificateBlacklisted,
+ CertificateStatusUnknown,
+ OcspNoResponseFound,
+ OcspMalformedRequest,
+ OcspMalformedResponse,
+ OcspInternalError,
+ OcspTryLater,
+ OcspSigRequred,
+ OcspUnauthorized,
+ OcspResponseCannotBeTrusted,
+ OcspResponseCertIdUnknown,
+ OcspResponseExpired,
+ OcspStatusUnknown,
UnspecifiedError = -1
};
diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp
index 9a43e67772..99c1a39c73 100644
--- a/src/network/ssl/qsslkey_openssl.cpp
+++ b/src/network/ssl/qsslkey_openssl.cpp
@@ -69,6 +69,11 @@ void QSslKeyPrivate::clear(bool deep)
q_DSA_free(dsa);
dsa = nullptr;
}
+ if (algorithm == QSsl::Dh && dh) {
+ if (deep)
+ q_DH_free(dh);
+ dh = nullptr;
+ }
#ifndef OPENSSL_NO_EC
if (algorithm == QSsl::Ec && ec) {
if (deep)
@@ -105,6 +110,12 @@ bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey)
type = QSsl::PrivateKey;
dsa = q_EVP_PKEY_get1_DSA(pkey);
return true;
+ } else if (keyType == EVP_PKEY_DH) {
+ isNull = false;
+ algorithm = QSsl::Dh;
+ type = QSsl::PrivateKey;
+ dh = q_EVP_PKEY_get1_DH(pkey);
+ return true;
}
#ifndef OPENSSL_NO_EC
else if (keyType == EVP_PKEY_EC) {
@@ -160,6 +171,15 @@ void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhra
: q_PEM_read_bio_DSAPrivateKey(bio, &dsa, nullptr, phrase);
if (dsa && dsa == result)
isNull = false;
+ } else if (algorithm == QSsl::Dh) {
+ EVP_PKEY *result = (type == QSsl::PublicKey)
+ ? q_PEM_read_bio_PUBKEY(bio, nullptr, nullptr, phrase)
+ : q_PEM_read_bio_PrivateKey(bio, nullptr, nullptr, phrase);
+ if (result)
+ dh = q_EVP_PKEY_get1_DH(result);
+ if (dh)
+ isNull = false;
+ q_EVP_PKEY_free(result);
#ifndef OPENSSL_NO_EC
} else if (algorithm == QSsl::Ec) {
EC_KEY *result = (type == QSsl::PublicKey)
@@ -181,6 +201,7 @@ int QSslKeyPrivate::length() const
switch (algorithm) {
case QSsl::Rsa: return q_RSA_bits(rsa);
case QSsl::Dsa: return q_DSA_bits(dsa);
+ case QSsl::Dh: return q_DH_bits(dh);
#ifndef OPENSSL_NO_EC
case QSsl::Ec: return q_EC_GROUP_get_degree(q_EC_KEY_get0_group(ec));
#endif
@@ -215,7 +236,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const
fail = true;
} else {
if (!q_PEM_write_bio_RSAPrivateKey(
- bio, rsa, cipher, const_cast<uchar *>((const uchar *)passPhrase.data()),
+ bio, rsa, cipher, (uchar *)passPhrase.data(),
passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
@@ -226,20 +247,33 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const
fail = true;
} else {
if (!q_PEM_write_bio_DSAPrivateKey(
- bio, dsa, cipher, const_cast<uchar *>((const uchar *)passPhrase.data()),
+ bio, dsa, cipher, (uchar *)passPhrase.data(),
passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
}
+ } else if (algorithm == QSsl::Dh) {
+ EVP_PKEY *result = q_EVP_PKEY_new();
+ if (!result || !q_EVP_PKEY_set1_DH(result, dh)) {
+ fail = true;
+ } else if (type == QSsl::PublicKey) {
+ if (!q_PEM_write_bio_PUBKEY(bio, result))
+ fail = true;
+ } else if (!q_PEM_write_bio_PrivateKey(
+ bio, result, cipher, (uchar *)passPhrase.data(),
+ passPhrase.size(), nullptr, nullptr)) {
+ fail = true;
+ }
+ q_EVP_PKEY_free(result);
#ifndef OPENSSL_NO_EC
} else if (algorithm == QSsl::Ec) {
if (type == QSsl::PublicKey) {
if (!q_PEM_write_bio_EC_PUBKEY(bio, ec))
fail = true;
} else {
- if (!q_PEM_write_bio_ECPrivateKey(bio, ec, cipher,
- const_cast<uchar *>((const uchar *)passPhrase.data()),
- passPhrase.size(), nullptr, nullptr)) {
+ if (!q_PEM_write_bio_ECPrivateKey(
+ bio, ec, cipher, (uchar *)passPhrase.data(),
+ passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
}
@@ -267,6 +301,8 @@ Qt::HANDLE QSslKeyPrivate::handle() const
return Qt::HANDLE(rsa);
case QSsl::Dsa:
return Qt::HANDLE(dsa);
+ case QSsl::Dh:
+ return Qt::HANDLE(dh);
#ifndef OPENSSL_NO_EC
case QSsl::Ec:
return Qt::HANDLE(ec);
diff --git a/src/network/ssl/qsslkey_p.cpp b/src/network/ssl/qsslkey_p.cpp
index 28e3e2efd8..b29b38beab 100644
--- a/src/network/ssl/qsslkey_p.cpp
+++ b/src/network/ssl/qsslkey_p.cpp
@@ -116,6 +116,8 @@ QByteArray QSslKeyPrivate::pemHeader() const
return QByteArrayLiteral("-----BEGIN DSA PRIVATE KEY-----");
else if (algorithm == QSsl::Ec)
return QByteArrayLiteral("-----BEGIN EC PRIVATE KEY-----");
+ else if (algorithm == QSsl::Dh)
+ return QByteArrayLiteral("-----BEGIN PRIVATE KEY-----");
Q_UNREACHABLE();
return QByteArray();
@@ -141,6 +143,8 @@ QByteArray QSslKeyPrivate::pemFooter() const
return QByteArrayLiteral("-----END DSA PRIVATE KEY-----");
else if (algorithm == QSsl::Ec)
return QByteArrayLiteral("-----END EC PRIVATE KEY-----");
+ else if (algorithm == QSsl::Dh)
+ return QByteArrayLiteral("-----END PRIVATE KEY-----");
Q_UNREACHABLE();
return QByteArray();
@@ -535,7 +539,9 @@ QDebug operator<<(QDebug debug, const QSslKey &key)
debug << "QSslKey("
<< (key.type() == QSsl::PublicKey ? "PublicKey" : "PrivateKey")
<< ", " << (key.algorithm() == QSsl::Opaque ? "OPAQUE" :
- (key.algorithm() == QSsl::Rsa ? "RSA" : ((key.algorithm() == QSsl::Dsa) ? "DSA" : "EC")))
+ (key.algorithm() == QSsl::Rsa ? "RSA" :
+ (key.algorithm() == QSsl::Dsa ? "DSA" :
+ (key.algorithm() == QSsl::Dh ? "DH" : "EC"))))
<< ", " << key.length()
<< ')';
return debug;
diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h
index 7ae2cc740b..06403b5479 100644
--- a/src/network/ssl/qsslkey_p.h
+++ b/src/network/ssl/qsslkey_p.h
@@ -116,6 +116,7 @@ public:
EVP_PKEY *opaque;
RSA *rsa;
DSA *dsa;
+ DH *dh;
#ifndef OPENSSL_NO_EC
EC_KEY *ec;
#endif
@@ -129,7 +130,7 @@ public:
QAtomicInt ref;
private:
- Q_DISABLE_COPY(QSslKeyPrivate)
+ Q_DISABLE_COPY_MOVE(QSslKeyPrivate)
};
QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp
index a13275f3bb..5ebd8ac3bd 100644
--- a/src/network/ssl/qsslkey_qt.cpp
+++ b/src/network/ssl/qsslkey_qt.cpp
@@ -165,6 +165,7 @@ static int extractPkcs8KeyLength(const QVector<QAsn1Element> &items, QSslKeyPriv
switch (algorithm){
case QSsl::Rsa: return "RSA";
case QSsl::Dsa: return "DSA";
+ case QSsl::Dh: return "DH";
case QSsl::Ec: return "EC";
case QSsl::Opaque: return "Opaque";
}
@@ -217,6 +218,21 @@ static int extractPkcs8KeyLength(const QVector<QAsn1Element> &items, QSslKeyPriv
if (dsaInfo.size() != 3 || dsaInfo[0].type() != QAsn1Element::IntegerType)
return -1;
keyLength = numberOfBits(dsaInfo[0].value());
+ } else if (value == DH_ENCRYPTION_OID) {
+ if (Q_UNLIKELY(that->algorithm != QSsl::Dh)) {
+ // As above for RSA.
+ qWarning() << "QSslKey: Found DH when asked to use" << getName(that->algorithm)
+ << "\nLoading will fail.";
+ return -1;
+ }
+ // DH's structure is documented here:
+ // https://www.cryptsoft.com/pkcs11doc/STANDARD/v201-95.pdf in section 11.9.
+ if (pkcs8Info[1].type() != QAsn1Element::SequenceType)
+ return -1;
+ const QVector<QAsn1Element> dhInfo = pkcs8Info[1].toVector();
+ if (dhInfo.size() < 2 || dhInfo.size() > 3 || dhInfo[0].type() != QAsn1Element::IntegerType)
+ return -1;
+ keyLength = numberOfBits(dhInfo[0].value());
} else {
// in case of unexpected formats:
qWarning() << "QSslKey: Unsupported PKCS#8 key algorithm:" << value
@@ -268,6 +284,16 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhra
if (params.isEmpty() || params[0].type() != QAsn1Element::IntegerType)
return;
keyLength = numberOfBits(params[0].value());
+ } else if (algorithm == QSsl::Dh) {
+ if (infoItems[0].toObjectId() != DH_ENCRYPTION_OID)
+ return;
+ if (infoItems[1].type() != QAsn1Element::SequenceType)
+ return;
+ // key params
+ const QVector<QAsn1Element> params = infoItems[1].toVector();
+ if (params.isEmpty() || params[0].type() != QAsn1Element::IntegerType)
+ return;
+ keyLength = numberOfBits(params[0].value());
} else if (algorithm == QSsl::Ec) {
if (infoItems[0].toObjectId() != EC_ENCRYPTION_OID)
return;
@@ -307,6 +333,12 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhra
if (items.size() != 6 || items[1].type() != QAsn1Element::IntegerType)
return;
keyLength = numberOfBits(items[1].value());
+ } else if (algorithm == QSsl::Dh) {
+ if (versionHex != "00")
+ return;
+ if (items.size() < 5 || items.size() > 6 || items[1].type() != QAsn1Element::IntegerType)
+ return;
+ keyLength = numberOfBits(items[1].value());
} else if (algorithm == QSsl::Ec) {
if (versionHex != "01")
return;
diff --git a/src/network/ssl/qsslkey_schannel.cpp b/src/network/ssl/qsslkey_schannel.cpp
new file mode 100644
index 0000000000..5694068860
--- /dev/null
+++ b/src/network/ssl/qsslkey_schannel.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qssl_p.h"
+#include "qsslkey.h"
+#include "qsslkey_p.h"
+#include "qsslcertificate_p.h"
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qscopeguard.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+const wchar_t *getName(QSslKeyPrivate::Cipher cipher)
+{
+ switch (cipher) {
+ case QSslKeyPrivate::Cipher::DesCbc:
+ return BCRYPT_DES_ALGORITHM;
+ case QSslKeyPrivate::Cipher::DesEde3Cbc:
+ return BCRYPT_3DES_ALGORITHM;
+ case QSslKeyPrivate::Cipher::Rc2Cbc:
+ return BCRYPT_RC2_ALGORITHM;
+ }
+ Q_UNREACHABLE();
+}
+
+BCRYPT_ALG_HANDLE getHandle(QSslKeyPrivate::Cipher cipher)
+{
+ BCRYPT_ALG_HANDLE handle;
+ NTSTATUS status = BCryptOpenAlgorithmProvider(
+ &handle, // phAlgorithm
+ getName(cipher), // pszAlgId
+ nullptr, // pszImplementation
+ 0 // dwFlags
+ );
+ if (status < 0) {
+ qCWarning(lcSsl, "Failed to open algorithm handle (%ld)!", status);
+ return nullptr;
+ }
+
+ return handle;
+}
+
+BCRYPT_KEY_HANDLE generateSymmetricKey(BCRYPT_ALG_HANDLE handle,
+ const QByteArray &key)
+{
+ BCRYPT_KEY_HANDLE keyHandle;
+ NTSTATUS status = BCryptGenerateSymmetricKey(
+ handle, // hAlgorithm
+ &keyHandle, // phKey
+ nullptr, // pbKeyObject (can ignore)
+ 0, // cbKeyObject (also ignoring)
+ reinterpret_cast<unsigned char *>(const_cast<char *>(key.data())), // pbSecret
+ ULONG(key.length()), // cbSecret
+ 0 // dwFlags
+ );
+ if (status < 0) {
+ qCWarning(lcSsl, "Failed to generate symmetric key (%ld)!", status);
+ return nullptr;
+ }
+
+ status = BCryptSetProperty(
+ keyHandle, // hObject
+ BCRYPT_CHAINING_MODE, // pszProperty
+ reinterpret_cast<UCHAR *>(const_cast<wchar_t *>(BCRYPT_CHAIN_MODE_CBC)), // pbInput
+ ARRAYSIZE(BCRYPT_CHAIN_MODE_CBC), // cbInput
+ 0 // dwFlags
+ );
+ if (status < 0) {
+ BCryptDestroyKey(keyHandle);
+ qCWarning(lcSsl, "Failed to change the symmetric key's chaining mode (%ld)!", status);
+ return nullptr;
+ }
+ return keyHandle;
+}
+
+QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data, const QByteArray &key,
+ const QByteArray &iv, bool encrypt)
+{
+ BCRYPT_ALG_HANDLE handle = getHandle(cipher);
+ if (!handle)
+ return {};
+ auto handleDealloc = qScopeGuard([&handle]() {
+ BCryptCloseAlgorithmProvider(handle, 0);
+ });
+
+ BCRYPT_KEY_HANDLE keyHandle = generateSymmetricKey(handle, key);
+ if (!keyHandle)
+ return {};
+ auto keyHandleDealloc = qScopeGuard([&keyHandle]() {
+ BCryptDestroyKey(keyHandle);
+ });
+
+ QByteArray ivCopy = iv; // This gets modified, so we take a copy
+
+ ULONG sizeNeeded = 0;
+ QVarLengthArray<unsigned char> output;
+ auto cryptFunction = encrypt ? BCryptEncrypt : BCryptDecrypt;
+ for (int i = 0; i < 2; i++) {
+ output.resize(int(sizeNeeded));
+ auto input = reinterpret_cast<unsigned char *>(const_cast<char *>(data.data()));
+ // Need to call it twice because the first iteration lets us know the size needed.
+ NTSTATUS status = cryptFunction(
+ keyHandle, // hKey
+ input, // pbInput
+ ULONG(data.length()), // cbInput
+ nullptr, // pPaddingInfo
+ reinterpret_cast<unsigned char *>(ivCopy.data()), // pbIV
+ ULONG(ivCopy.length()), // cbIV
+ sizeNeeded ? output.data() : nullptr, // pbOutput
+ ULONG(output.length()), // cbOutput
+ &sizeNeeded, // pcbResult
+ BCRYPT_BLOCK_PADDING // dwFlags
+ );
+ if (status < 0) {
+ qCWarning(lcSsl, "%s failed (%ld)!", encrypt ? "Encrypt" : "Decrypt", status);
+ return {};
+ }
+ }
+
+ return QByteArray(reinterpret_cast<const char *>(output.constData()), int(sizeNeeded));
+}
+} // anonymous namespace
+
+QByteArray QSslKeyPrivate::decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key,
+ const QByteArray &iv)
+{
+ return doCrypt(cipher, data, key, iv, false);
+}
+
+QByteArray QSslKeyPrivate::encrypt(Cipher cipher, const QByteArray &data, const QByteArray &key,
+ const QByteArray &iv)
+{
+ return doCrypt(cipher, data, key, iv, true);
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslpresharedkeyauthenticator.cpp b/src/network/ssl/qsslpresharedkeyauthenticator.cpp
index 3bb2719026..01e1501763 100644
--- a/src/network/ssl/qsslpresharedkeyauthenticator.cpp
+++ b/src/network/ssl/qsslpresharedkeyauthenticator.cpp
@@ -94,6 +94,8 @@ QSslPreSharedKeyAuthenticatorPrivate::QSslPreSharedKeyAuthenticatorPrivate()
\note PSK ciphersuites are supported only when using OpenSSL 1.0.1 (or
greater) as the SSL backend.
+ \note PSK is currently only supported in OpenSSL.
+
\sa QSslSocket
*/
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 4f49a71e8a..e164217e4e 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -133,7 +133,8 @@
\list
\li The socket's cryptographic cipher suite can be customized before
- the handshake phase with setCiphers() and setDefaultCiphers().
+ the handshake phase with QSslConfiguration::setCiphers()
+ and QSslConfiguration::setDefaultCiphers().
\li The socket's local certificate and private key can be customized
before the handshake phase with setLocalCertificate() and
setPrivateKey().
@@ -202,6 +203,7 @@
does not require this certificate to be valid. This is useful when you
want to display peer certificate details to the user without affecting the
actual SSL handshake. This mode is the default for servers.
+ Note: In Schannel this value acts the same as VerifyNone.
\value VerifyPeer QSslSocket will request a certificate from the peer
during the SSL handshake phase, and requires that this certificate is
@@ -312,6 +314,7 @@
#include "qssl_p.h"
#include "qsslsocket.h"
#include "qsslcipher.h"
+#include "qocspresponse.h"
#ifndef QT_NO_OPENSSL
#include "qsslsocket_openssl_p.h"
#endif
@@ -321,6 +324,9 @@
#ifdef QT_SECURETRANSPORT
#include "qsslsocket_mac_p.h"
#endif
+#if QT_CONFIG(schannel)
+#include "qsslsocket_schannel_p.h"
+#endif
#include "qsslconfiguration_p.h"
#include <QtCore/qdebug.h>
@@ -459,6 +465,9 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, O
return;
}
+ if (!d->verifyProtocolSupported("QSslSocket::connectToHostEncrypted:"))
+ return;
+
d->init();
d->autoStartHandshake = true;
d->initialized = true;
@@ -906,7 +915,8 @@ void QSslSocket::abort()
time without notice.
\sa localCertificate(), peerCertificate(), peerCertificateChain(),
- sessionCipher(), privateKey(), ciphers(), caCertificates()
+ sessionCipher(), privateKey(), QSslConfiguration::ciphers(),
+ QSslConfiguration::caCertificates()
*/
QSslConfiguration QSslSocket::sslConfiguration() const
{
@@ -930,7 +940,8 @@ QSslConfiguration QSslSocket::sslConfiguration() const
It is not possible to set the SSL-state related fields.
- \sa setLocalCertificate(), setPrivateKey(), setCaCertificates(), setCiphers()
+ \sa setLocalCertificate(), setPrivateKey(), QSslConfiguration::setCaCertificates(),
+ QSslConfiguration::setCiphers()
*/
void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
{
@@ -952,6 +963,9 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
d->configuration.nextAllowedProtocols = configuration.allowedNextProtocols();
d->configuration.nextNegotiatedProtocol = configuration.nextNegotiatedProtocol();
d->configuration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus();
+#if QT_CONFIG(ocsp)
+ d->configuration.ocspStaplingEnabled = configuration.ocspStaplingEnabled();
+#endif
// if the CA certificates were set explicitly (either via
// QSslConfiguration::setCaCertificates() or QSslSocket::setCaCertificates(),
@@ -1113,8 +1127,10 @@ QList<QSslCertificate> QSslSocket::peerCertificateChain() const
session cipher. This ordered list must be in place before the
handshake phase begins.
- \sa ciphers(), setCiphers(), setDefaultCiphers(), defaultCiphers(),
- supportedCiphers()
+ \sa QSslConfiguration::ciphers(), QSslConfiguration::setCiphers(),
+ QSslConfiguration::setCiphers(),
+ QSslConfiguration::ciphers(),
+ QSslConfiguration::supportedCiphers()
*/
QSslCipher QSslSocket::sessionCipher() const
{
@@ -1136,6 +1152,20 @@ QSsl::SslProtocol QSslSocket::sessionProtocol() const
return d->sessionProtocol();
}
+/*!
+ \since 5.13
+
+ This function returns Online Certificate Status Protocol responses that
+ a server may send during a TLS handshake using OCSP stapling. The vector
+ is empty if no definitive response or no response at all was received.
+
+ \sa QSslConfiguration::setOcspStaplingEnabled()
+*/
+QVector<QOcspResponse> QSslSocket::ocspResponses() const
+{
+ Q_D(const QSslSocket);
+ return d->ocspResponses;
+}
/*!
Sets the socket's private \l {QSslKey} {key} to \a key. The
@@ -1198,6 +1228,7 @@ QSslKey QSslSocket::privateKey() const
return d->configuration.privateKey;
}
+#if QT_DEPRECATED_SINCE(5, 5)
/*!
\deprecated
@@ -1341,6 +1372,7 @@ QList<QSslCipher> QSslSocket::supportedCiphers()
{
return QSslSocketPrivate::supportedCiphers();
}
+#endif // #if QT_DEPRECATED_SINCE(5, 5)
/*!
Searches all files in the \a path for certificates encoded in the
@@ -1376,7 +1408,8 @@ bool QSslSocket::addCaCertificates(const QString &path, QSsl::EncodingFormat for
To add multiple certificates, use addCaCertificates().
- \sa caCertificates(), setCaCertificates()
+ \sa QSslConfiguration::caCertificates(),
+ QSslConfiguration::setCaCertificates()
*/
void QSslSocket::addCaCertificate(const QSslCertificate &certificate)
{
@@ -1391,7 +1424,7 @@ void QSslSocket::addCaCertificate(const QSslCertificate &certificate)
For more precise control, use addCaCertificate().
- \sa caCertificates(), addDefaultCaCertificate()
+ \sa QSslConfiguration::caCertificates(), addDefaultCaCertificate()
*/
void QSslSocket::addCaCertificates(const QList<QSslCertificate> &certificates)
{
@@ -1399,6 +1432,7 @@ void QSslSocket::addCaCertificates(const QList<QSslCertificate> &certificates)
d->configuration.caCertificates += certificates;
}
+#if QT_DEPRECATED_SINCE(5, 5)
/*!
\deprecated
@@ -1443,6 +1477,7 @@ QList<QSslCertificate> QSslSocket::caCertificates() const
Q_D(const QSslSocket);
return d->configuration.caCertificates;
}
+#endif // #if QT_DEPRECATED_SINCE(5, 5)
/*!
Searches all files in the \a path for certificates with the
@@ -1454,7 +1489,8 @@ QList<QSslCertificate> QSslSocket::caCertificates() const
Each SSL socket's CA certificate database is initialized to the
default CA certificate database.
- \sa defaultCaCertificates(), addCaCertificates(), addDefaultCaCertificate()
+ \sa QSslConfiguration::caCertificates(), addCaCertificates(),
+ addDefaultCaCertificate()
*/
bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat encoding,
QRegExp::PatternSyntax syntax)
@@ -1467,7 +1503,7 @@ bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFor
SSL socket's CA certificate database is initialized to the default
CA certificate database.
- \sa defaultCaCertificates(), addCaCertificates()
+ \sa QSslConfiguration::defaultCaCertificates(), addCaCertificates()
*/
void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate)
{
@@ -1479,13 +1515,14 @@ void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate)
SSL socket's CA certificate database is initialized to the default
CA certificate database.
- \sa defaultCaCertificates(), addCaCertificates()
+ \sa QSslConfiguration::caCertificates(), addCaCertificates()
*/
void QSslSocket::addDefaultCaCertificates(const QList<QSslCertificate> &certificates)
{
QSslSocketPrivate::addDefaultCaCertificates(certificates);
}
+#if QT_DEPRECATED_SINCE(5, 5)
/*!
\deprecated
@@ -1553,6 +1590,7 @@ QList<QSslCertificate> QSslSocket::systemCaCertificates()
// we are calling ensureInitialized() in the method below
return QSslSocketPrivate::systemCaCertificates();
}
+#endif // #if QT_DEPRECATED_SINCE(5, 5)
/*!
Waits until the socket is connected, or \a msecs milliseconds,
@@ -1597,6 +1635,8 @@ bool QSslSocket::waitForEncrypted(int msecs)
return false;
if (d->mode == UnencryptedMode && !d->autoStartHandshake)
return false;
+ if (!d->verifyProtocolSupported("QSslSocket::waitForEncrypted:"))
+ return false;
QElapsedTimer stopWatch;
stopWatch.start();
@@ -1846,6 +1886,10 @@ void QSslSocket::startClientEncryption()
d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed"));
return;
}
+
+ if (!d->verifyProtocolSupported("QSslSocket::startClientEncryption:"))
+ return;
+
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << "QSslSocket::startClientEncryption()";
#endif
@@ -1889,6 +1933,9 @@ void QSslSocket::startServerEncryption()
d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed"));
return;
}
+ if (!d->verifyProtocolSupported("QSslSocket::startServerEncryption"))
+ return;
+
d->mode = SslServerMode;
emit modeChanged(d->mode);
d->startServerEncryption();
@@ -1974,6 +2021,7 @@ void QSslSocket::connectToHost(const QString &hostName, quint16 port, OpenMode o
d->createPlainSocket(openMode);
}
#ifndef QT_NO_NETWORKPROXY
+ d->plainSocket->setProtocolTag(d->protocolTag);
d->plainSocket->setProxy(proxy());
#endif
QIODevice::open(openMode);
@@ -2108,6 +2156,7 @@ void QSslSocketPrivate::init()
shutdown = false;
pendingClose = false;
flushTriggered = false;
+ ocspResponses.clear();
// we don't want to clear the ignoreErrorsList, so
// that it is possible setting it before connecting
@@ -2122,6 +2171,20 @@ void QSslSocketPrivate::init()
/*!
\internal
*/
+bool QSslSocketPrivate::verifyProtocolSupported(const char *where)
+{
+ if (configuration.protocol == QSsl::SslV2 || configuration.protocol == QSsl::SslV3) {
+ qCWarning(lcSsl) << where << "Attempted to use an unsupported protocol.";
+ setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
+ QSslSocket::tr("Attempted to use an unsupported protocol."));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \internal
+*/
QList<QSslCipher> QSslSocketPrivate::defaultCiphers()
{
QSslSocketPrivate::ensureInitialized();
@@ -2324,6 +2387,9 @@ void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPri
#if QT_CONFIG(dtls)
ptr->dtlsCookieEnabled = global->dtlsCookieEnabled;
#endif
+#if QT_CONFIG(ocsp)
+ ptr->ocspStaplingEnabled = global->ocspStaplingEnabled;
+#endif
}
/*!
@@ -2822,6 +2888,17 @@ QSharedPointer<QSslContext> QSslSocketPrivate::sslContext(QSslSocket *socket)
bool QSslSocketPrivate::isMatchingHostname(const QSslCertificate &cert, const QString &peerName)
{
+ QHostAddress hostAddress(peerName);
+ if (!hostAddress.isNull()) {
+ const auto subjectAlternativeNames = cert.subjectAlternativeNames();
+ const auto ipAddresses = subjectAlternativeNames.equal_range(QSsl::AlternativeNameEntryType::IpAddressEntry);
+
+ for (auto it = ipAddresses.first; it != ipAddresses.second; it++) {
+ if (QHostAddress(*it).isEqual(hostAddress, QHostAddress::StrictConversion))
+ return true;
+ }
+ }
+
const QString lowerPeerName = QString::fromLatin1(QUrl::toAce(peerName));
const QStringList commonNames = cert.subjectInfo(QSslCertificate::CommonName);
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index c66ebdde54..35943c7d7e 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -44,6 +44,7 @@
#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/qlist.h>
#include <QtCore/qregexp.h>
+#include <QtCore/qvector.h>
#ifndef QT_NO_SSL
# include <QtNetwork/qtcpsocket.h>
# include <QtNetwork/qsslerror.h>
@@ -60,6 +61,7 @@ class QSslCertificate;
class QSslConfiguration;
class QSslEllipticCurve;
class QSslPreSharedKeyAuthenticator;
+class QOcspResponse;
class QSslSocketPrivate;
class Q_NETWORK_EXPORT QSslSocket : public QTcpSocket
@@ -142,6 +144,7 @@ public:
QList<QSslCertificate> peerCertificateChain() const;
QSslCipher sessionCipher() const;
QSsl::SslProtocol sessionProtocol() const;
+ QVector<QOcspResponse> ocspResponses() const;
// Private keys, for server sockets.
void setPrivateKey(const QSslKey &key);
@@ -228,7 +231,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_flushWriteBuffer())
Q_PRIVATE_SLOT(d_func(), void _q_flushReadBuffer())
Q_PRIVATE_SLOT(d_func(), void _q_resumeImplementation())
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !QT_CONFIG(schannel)
Q_PRIVATE_SLOT(d_func(), void _q_caRootLoaded(QSslCertificate,QSslCertificate))
#endif
friend class QSslSocketBackendPrivate;
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index 7c5f4310f8..487e975db6 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -89,7 +89,7 @@ struct EphemeralSecKeychain
~EphemeralSecKeychain();
SecKeychainRef keychain = nullptr;
- Q_DISABLE_COPY(EphemeralSecKeychain)
+ Q_DISABLE_COPY_MOVE(EphemeralSecKeychain)
};
EphemeralSecKeychain::EphemeralSecKeychain()
@@ -995,9 +995,6 @@ void QSslSocketBackendPrivate::destroySslContext()
context.reset(nullptr);
}
-static QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase);
-
-
bool QSslSocketBackendPrivate::setSessionCertificate(QString &errorDescription, QAbstractSocket::SocketError &errorCode)
{
Q_ASSERT_X(context, Q_FUNC_INFO, "invalid SSL context (null)");
@@ -1112,6 +1109,12 @@ bool QSslSocketBackendPrivate::setSessionProtocol()
return false;
}
+ // SslV3 is unsupported.
+ if (configuration.protocol == QSsl::SslV3) {
+ qCDebug(lcSsl) << "protocol QSsl::SslV3 is disabled";
+ return false;
+ }
+
// SecureTransport has kTLSProtocol13 constant and also, kTLSProtocolMaxSupported.
// Calling SSLSetProtocolVersionMax/Min with any of these two constants results
// in errInvalidParam and a failure to set the protocol version. This means
@@ -1126,14 +1129,7 @@ bool QSslSocketBackendPrivate::setSessionProtocol()
OSStatus err = errSecSuccess;
- if (configuration.protocol == QSsl::SslV3) {
- #ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : SSLv3";
- #endif
- err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
- if (err == errSecSuccess)
- err = SSLSetProtocolVersionMax(context, kSSLProtocol3);
- } else if (configuration.protocol == QSsl::TlsV1_0) {
+ if (configuration.protocol == QSsl::TlsV1_0) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.0";
#endif
@@ -1158,13 +1154,14 @@ bool QSslSocketBackendPrivate::setSessionProtocol()
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : any";
#endif
- // kSSLProtocol3, since kSSLProtocol2 is disabled:
- err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
+ err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
} else if (configuration.protocol == QSsl::TlsV1SslV3) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : SSLv3 - TLSv1.2";
#endif
- err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
+ err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
+ if (err == errSecSuccess)
+ err = SSLSetProtocolVersionMax(context, kTLSProtocol1);
} else if (configuration.protocol == QSsl::SecureProtocols) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2";
@@ -1210,7 +1207,7 @@ bool QSslSocketBackendPrivate::verifySessionProtocol() const
if (configuration.protocol == QSsl::AnyProtocol)
protocolOk = true;
else if (configuration.protocol == QSsl::TlsV1SslV3)
- protocolOk = (sessionProtocol() >= QSsl::SslV3);
+ protocolOk = (sessionProtocol() == QSsl::TlsV1_0);
else if (configuration.protocol == QSsl::SecureProtocols)
protocolOk = (sessionProtocol() >= QSsl::TlsV1_0);
else if (configuration.protocol == QSsl::TlsV1_0OrLater)
@@ -1503,264 +1500,4 @@ bool QSslSocketBackendPrivate::startHandshake()
}
}
-/*
- PKCS12 helpers.
-*/
-
-static QAsn1Element wrap(quint8 type, const QAsn1Element &child)
-{
- QByteArray value;
- QDataStream stream(&value, QIODevice::WriteOnly);
- child.write(stream);
- return QAsn1Element(type, value);
-}
-
-static QAsn1Element _q_PKCS7_data(const QByteArray &data)
-{
- QVector<QAsn1Element> items;
- items << QAsn1Element::fromObjectId("1.2.840.113549.1.7.1");
- items << wrap(QAsn1Element::Context0Type,
- QAsn1Element(QAsn1Element::OctetStringType, data));
- return QAsn1Element::fromVector(items);
-}
-
-/*!
- PKCS #12 key derivation.
-
- Some test vectors:
- http://www.drh-consultancy.demon.co.uk/test.txt
-*/
-static QByteArray _q_PKCS12_keygen(char id, const QByteArray &salt, const QString &passPhrase, int n, int r)
-{
- const int u = 20;
- const int v = 64;
-
- // password formatting
- QByteArray passUnicode(passPhrase.size() * 2 + 2, '\0');
- char *p = passUnicode.data();
- for (int i = 0; i < passPhrase.size(); ++i) {
- quint16 ch = passPhrase[i].unicode();
- *(p++) = (ch & 0xff00) >> 8;
- *(p++) = (ch & 0xff);
- }
-
- // prepare I
- QByteArray D(64, id);
- QByteArray S, P;
- const int sSize = v * ((salt.size() + v - 1) / v);
- S.resize(sSize);
- for (int i = 0; i < sSize; ++i) {
- S[i] = salt[i % salt.size()];
- }
- const int pSize = v * ((passUnicode.size() + v - 1) / v);
- P.resize(pSize);
- for (int i = 0; i < pSize; ++i) {
- P[i] = passUnicode[i % passUnicode.size()];
- }
- QByteArray I = S + P;
-
- // apply hashing
- const int c = (n + u - 1) / u;
- QByteArray A;
- QByteArray B;
- B.resize(v);
- QCryptographicHash hash(QCryptographicHash::Sha1);
- for (int i = 0; i < c; ++i) {
- // hash r iterations
- QByteArray Ai = D + I;
- for (int j = 0; j < r; ++j) {
- hash.reset();
- hash.addData(Ai);
- Ai = hash.result();
- }
-
- for (int j = 0; j < v; ++j) {
- B[j] = Ai[j % u];
- }
-
- // modify I as Ij = (Ij + B + 1) modulo 2^v
- for (int p = 0; p < I.size(); p += v) {
- quint8 carry = 1;
- for (int j = v - 1; j >= 0; --j) {
- quint16 v = quint8(I[p+j]) + quint8(B[j]) + carry;
- I[p+j] = v & 0xff;
- carry = (v & 0xff00) >> 8;
- }
- }
- A += Ai;
- }
- return A.left(n);
-}
-
-static QByteArray _q_PKCS12_salt()
-{
- QByteArray salt;
- salt.resize(8);
- for (int i = 0; i < salt.size(); ++i) {
- salt[i] = (qrand() & 0xff);
- }
- return salt;
-}
-
-static QByteArray _q_PKCS12_certBag(const QSslCertificate &cert)
-{
- QVector<QAsn1Element> items;
- items << QAsn1Element::fromObjectId("1.2.840.113549.1.12.10.1.3");
-
- // certificate
- QVector<QAsn1Element> certItems;
- certItems << QAsn1Element::fromObjectId("1.2.840.113549.1.9.22.1");
- certItems << wrap(QAsn1Element::Context0Type,
- QAsn1Element(QAsn1Element::OctetStringType, cert.toDer()));
- items << wrap(QAsn1Element::Context0Type,
- QAsn1Element::fromVector(certItems));
-
- // local key id
- const QByteArray localKeyId = cert.digest(QCryptographicHash::Sha1);
- QVector<QAsn1Element> idItems;
- idItems << QAsn1Element::fromObjectId("1.2.840.113549.1.9.21");
- idItems << wrap(QAsn1Element::SetType,
- QAsn1Element(QAsn1Element::OctetStringType, localKeyId));
- items << wrap(QAsn1Element::SetType, QAsn1Element::fromVector(idItems));
-
- // dump
- QAsn1Element root = wrap(QAsn1Element::SequenceType, QAsn1Element::fromVector(items));
- QByteArray ba;
- QDataStream stream(&ba, QIODevice::WriteOnly);
- root.write(stream);
- return ba;
-}
-
-static QAsn1Element _q_PKCS12_key(const QSslKey &key)
-{
- Q_ASSERT(key.algorithm() == QSsl::Rsa || key.algorithm() == QSsl::Dsa);
-
- QVector<QAsn1Element> keyItems;
- keyItems << QAsn1Element::fromInteger(0);
- QVector<QAsn1Element> algoItems;
- if (key.algorithm() == QSsl::Rsa)
- algoItems << QAsn1Element::fromObjectId(RSA_ENCRYPTION_OID);
- else if (key.algorithm() == QSsl::Dsa)
- algoItems << QAsn1Element::fromObjectId(DSA_ENCRYPTION_OID);
- algoItems << QAsn1Element(QAsn1Element::NullType);
- keyItems << QAsn1Element::fromVector(algoItems);
- keyItems << QAsn1Element(QAsn1Element::OctetStringType, key.toDer());
- return QAsn1Element::fromVector(keyItems);
-}
-
-static QByteArray _q_PKCS12_shroudedKeyBag(const QSslKey &key, const QString &passPhrase, const QByteArray &localKeyId)
-{
- const int iterations = 2048;
- QByteArray salt = _q_PKCS12_salt();
- QByteArray cKey = _q_PKCS12_keygen(1, salt, passPhrase, 24, iterations);
- QByteArray cIv = _q_PKCS12_keygen(2, salt, passPhrase, 8, iterations);
-
- // prepare and encrypt data
- QByteArray plain;
- QDataStream plainStream(&plain, QIODevice::WriteOnly);
- _q_PKCS12_key(key).write(plainStream);
- QByteArray crypted = QSslKeyPrivate::encrypt(QSslKeyPrivate::DesEde3Cbc,
- plain, cKey, cIv);
-
- QVector<QAsn1Element> items;
- items << QAsn1Element::fromObjectId("1.2.840.113549.1.12.10.1.2");
-
- // key
- QVector<QAsn1Element> keyItems;
- QVector<QAsn1Element> algoItems;
- algoItems << QAsn1Element::fromObjectId("1.2.840.113549.1.12.1.3");
- QVector<QAsn1Element> paramItems;
- paramItems << QAsn1Element(QAsn1Element::OctetStringType, salt);
- paramItems << QAsn1Element::fromInteger(iterations);
- algoItems << QAsn1Element::fromVector(paramItems);
- keyItems << QAsn1Element::fromVector(algoItems);
- keyItems << QAsn1Element(QAsn1Element::OctetStringType, crypted);
- items << wrap(QAsn1Element::Context0Type,
- QAsn1Element::fromVector(keyItems));
-
- // local key id
- QVector<QAsn1Element> idItems;
- idItems << QAsn1Element::fromObjectId("1.2.840.113549.1.9.21");
- idItems << wrap(QAsn1Element::SetType,
- QAsn1Element(QAsn1Element::OctetStringType, localKeyId));
- items << wrap(QAsn1Element::SetType,
- QAsn1Element::fromVector(idItems));
-
- // dump
- QAsn1Element root = wrap(QAsn1Element::SequenceType, QAsn1Element::fromVector(items));
- QByteArray ba;
- QDataStream stream(&ba, QIODevice::WriteOnly);
- root.write(stream);
- return ba;
-}
-
-static QByteArray _q_PKCS12_bag(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase)
-{
- QVector<QAsn1Element> items;
-
- // certs
- for (int i = 0; i < certs.size(); ++i)
- items << _q_PKCS7_data(_q_PKCS12_certBag(certs[i]));
-
- // key
- const QByteArray localKeyId = certs.first().digest(QCryptographicHash::Sha1);
- items << _q_PKCS7_data(_q_PKCS12_shroudedKeyBag(key, passPhrase, localKeyId));
-
- // dump
- QAsn1Element root = QAsn1Element::fromVector(items);
- QByteArray ba;
- QDataStream stream(&ba, QIODevice::WriteOnly);
- root.write(stream);
- return ba;
-}
-
-static QAsn1Element _q_PKCS12_mac(const QByteArray &data, const QString &passPhrase)
-{
- const int iterations = 2048;
-
- // salt generation
- QByteArray macSalt = _q_PKCS12_salt();
- QByteArray key = _q_PKCS12_keygen(3, macSalt, passPhrase, 20, iterations);
-
- // HMAC calculation
- QMessageAuthenticationCode hmac(QCryptographicHash::Sha1, key);
- hmac.addData(data);
-
- QVector<QAsn1Element> algoItems;
- algoItems << QAsn1Element::fromObjectId("1.3.14.3.2.26");
- algoItems << QAsn1Element(QAsn1Element::NullType);
-
- QVector<QAsn1Element> digestItems;
- digestItems << QAsn1Element::fromVector(algoItems);
- digestItems << QAsn1Element(QAsn1Element::OctetStringType, hmac.result());
-
- QVector<QAsn1Element> macItems;
- macItems << QAsn1Element::fromVector(digestItems);
- macItems << QAsn1Element(QAsn1Element::OctetStringType, macSalt);
- macItems << QAsn1Element::fromInteger(iterations);
- return QAsn1Element::fromVector(macItems);
-}
-
-QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase)
-{
- QVector<QAsn1Element> items;
-
- // version
- items << QAsn1Element::fromInteger(3);
-
- // auth safe
- const QByteArray data = _q_PKCS12_bag(certs, key, passPhrase);
- items << _q_PKCS7_data(data);
-
- // HMAC
- items << _q_PKCS12_mac(data, passPhrase);
-
- // dump
- QAsn1Element root = QAsn1Element::fromVector(items);
- QByteArray ba;
- QDataStream stream(&ba, QIODevice::WriteOnly);
- root.write(stream);
- return ba;
-}
-
QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslsocket_mac_p.h b/src/network/ssl/qsslsocket_mac_p.h
index e37171e56a..48aca964a1 100644
--- a/src/network/ssl/qsslsocket_mac_p.h
+++ b/src/network/ssl/qsslsocket_mac_p.h
@@ -75,7 +75,7 @@ public:
private:
SSLContextRef context;
- Q_DISABLE_COPY(QSecureTransportContext)
+ Q_DISABLE_COPY_MOVE(QSecureTransportContext)
};
class QSslSocketBackendPrivate : public QSslSocketPrivate
@@ -129,7 +129,7 @@ private:
QSecureTransportContext context;
bool renegotiating = false;
- Q_DISABLE_COPY(QSslSocketBackendPrivate)
+ Q_DISABLE_COPY_MOVE(QSslSocketBackendPrivate)
};
QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index b5b098502d..c48cd42360 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -65,6 +65,7 @@
#include "qsslellipticcurve.h"
#include "qsslpresharedkeyauthenticator.h"
#include "qsslpresharedkeyauthenticator_p.h"
+#include "qocspresponse_p.h"
#ifdef Q_OS_WIN
#include "qwindowscarootfetcher_p.h"
@@ -83,16 +84,16 @@
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qscopedvaluerollback.h>
+#if QT_CONFIG(ocsp)
+#include "qocsp_p.h"
+#endif
+
+#include <algorithm>
+
#include <string.h>
QT_BEGIN_NAMESPACE
-#if defined(Q_OS_WIN)
- PtrCertOpenSystemStoreW QSslSocketPrivate::ptrCertOpenSystemStoreW = nullptr;
- PtrCertFindCertificateInStore QSslSocketPrivate::ptrCertFindCertificateInStore = nullptr;
- PtrCertCloseStore QSslSocketPrivate::ptrCertCloseStore = nullptr;
-#endif
-
bool QSslSocketPrivate::s_libraryLoaded = false;
bool QSslSocketPrivate::s_loadedCiphersAndCerts = false;
bool QSslSocketPrivate::s_loadRootCertsOnDemand = false;
@@ -137,6 +138,37 @@ static unsigned int q_ssl_psk_server_callback(SSL *ssl,
return d->tlsPskServerCallback(identity, psk, max_psk_len);
}
#endif
+
+#if QT_CONFIG(ocsp)
+
+int qt_OCSP_status_server_callback(SSL *ssl, void *ocspRequest)
+{
+ Q_UNUSED(ocspRequest)
+ if (!ssl)
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ auto d = static_cast<QSslSocketBackendPrivate *>(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData));
+ if (!d)
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ Q_ASSERT(d->mode == QSslSocket::SslServerMode);
+ const QByteArray &response = d->ocspResponseDer;
+ Q_ASSERT(response.size());
+
+ unsigned char *derCopy = static_cast<unsigned char *>(q_OPENSSL_malloc(size_t(response.size())));
+ if (!derCopy)
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ std::copy(response.data(), response.data() + response.size(), derCopy);
+ // We don't check the return value: internally OpenSSL simply assignes the
+ // pointer (it assumes it now owns this memory btw!) and the length.
+ q_SSL_set_tlsext_status_ocsp_resp(ssl, derCopy, response.size());
+
+ return SSL_TLSEXT_ERR_OK;
+}
+
+#endif // ocsp
+
} // extern "C"
QSslSocketBackendPrivate::QSslSocketBackendPrivate()
@@ -204,8 +236,120 @@ QSslErrorEntry QSslErrorEntry::fromStoreContext(X509_STORE_CTX *ctx)
};
}
+#if QT_CONFIG(ocsp)
+
+QSslError qt_OCSP_response_status_to_QSslError(long code)
+{
+ switch (code) {
+ case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST:
+ return QSslError::OcspMalformedRequest;
+ case OCSP_RESPONSE_STATUS_INTERNALERROR:
+ return QSslError::OcspInternalError;
+ case OCSP_RESPONSE_STATUS_TRYLATER:
+ return QSslError::OcspTryLater;
+ case OCSP_RESPONSE_STATUS_SIGREQUIRED:
+ return QSslError::OcspSigRequred;
+ case OCSP_RESPONSE_STATUS_UNAUTHORIZED:
+ return QSslError::OcspUnauthorized;
+ case OCSP_RESPONSE_STATUS_SUCCESSFUL:
+ default:
+ return {};
+ }
+ Q_UNREACHABLE();
+}
+
+QOcspRevocationReason qt_OCSP_revocation_reason(int reason)
+{
+ switch (reason) {
+ case OCSP_REVOKED_STATUS_NOSTATUS:
+ return QOcspRevocationReason::None;
+ case OCSP_REVOKED_STATUS_UNSPECIFIED:
+ return QOcspRevocationReason::Unspecified;
+ case OCSP_REVOKED_STATUS_KEYCOMPROMISE:
+ return QOcspRevocationReason::KeyCompromise;
+ case OCSP_REVOKED_STATUS_CACOMPROMISE:
+ return QOcspRevocationReason::CACompromise;
+ case OCSP_REVOKED_STATUS_AFFILIATIONCHANGED:
+ return QOcspRevocationReason::AffiliationChanged;
+ case OCSP_REVOKED_STATUS_SUPERSEDED:
+ return QOcspRevocationReason::Superseded;
+ case OCSP_REVOKED_STATUS_CESSATIONOFOPERATION:
+ return QOcspRevocationReason::CessationOfOperation;
+ case OCSP_REVOKED_STATUS_CERTIFICATEHOLD:
+ return QOcspRevocationReason::CertificateHold;
+ case OCSP_REVOKED_STATUS_REMOVEFROMCRL:
+ return QOcspRevocationReason::RemoveFromCRL;
+ default:
+ return QOcspRevocationReason::None;
+ }
+
+ Q_UNREACHABLE();
+}
+
+bool qt_OCSP_certificate_match(OCSP_SINGLERESP *singleResponse, X509 *peerCert, X509 *issuer)
+{
+ // OCSP_basic_verify does verify that the responder is legit, the response is
+ // correctly signed, CertID is correct. But it does not know which certificate
+ // we were presented with by our peer, so it does not check if it's a response
+ // for our peer's certificate.
+ Q_ASSERT(singleResponse && peerCert && issuer);
+
+ const OCSP_CERTID *certId = q_OCSP_SINGLERESP_get0_id(singleResponse); // Does not increment refcount.
+ if (!certId) {
+ qCWarning(lcSsl, "A SingleResponse without CertID");
+ return false;
+ }
+
+ ASN1_OBJECT *md = nullptr;
+ ASN1_INTEGER *reportedSerialNumber = nullptr;
+ const int result = q_OCSP_id_get0_info(nullptr, &md, nullptr, &reportedSerialNumber, const_cast<OCSP_CERTID *>(certId));
+ if (result != 1 || !md || !reportedSerialNumber) {
+ qCWarning(lcSsl, "Failed to extract a hash and serial number from CertID structure");
+ return false;
+ }
+
+ if (!q_X509_get_serialNumber(peerCert)) {
+ // Is this possible at all? But we have to check this,
+ // ASN1_INTEGER_cmp (called from OCSP_id_cmp) dereferences
+ // without any checks at all.
+ qCWarning(lcSsl, "No serial number in peer's ceritificate");
+ return false;
+ }
+
+ const int nid = q_OBJ_obj2nid(md);
+ if (nid == NID_undef) {
+ qCWarning(lcSsl, "Unknown hash algorithm in CertID");
+ return false;
+ }
+
+ const EVP_MD *digest = q_EVP_get_digestbynid(nid); // Does not increment refcount.
+ if (!digest) {
+ qCWarning(lcSsl) << "No digest for nid" << nid;
+ return false;
+ }
+
+ OCSP_CERTID *recreatedId = q_OCSP_cert_to_id(digest, peerCert, issuer);
+ if (!recreatedId) {
+ qCWarning(lcSsl, "Failed to re-create CertID");
+ return false;
+ }
+ const QSharedPointer<OCSP_CERTID> guard(recreatedId, q_OCSP_CERTID_free);
+
+ if (q_OCSP_id_cmp(const_cast<OCSP_CERTID *>(certId), recreatedId)) {
+ qDebug(lcSsl, "Certificate ID mismatch");
+ return false;
+ }
+ // Bingo!
+ return true;
+}
+
+#endif // ocsp
+
// ### This list is shared between all threads, and protected by a
-// mutex. Investigate using thread local storage instead.
+// mutex. Investigate using thread local storage instead. Or better properly
+// use OpenSSL's ability to attach application data to an SSL/SSL_CTX
+// and extract it in a callback. See how it's done, for example, in PSK
+// callback or in DTLS verification callback.
struct QSslErrorList
{
QMutex mutex;
@@ -280,7 +424,7 @@ long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, Q
{
long options;
if (protocol == QSsl::TlsV1SslV3)
- options = SSL_OP_ALL|SSL_OP_NO_SSLv2;
+ options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
else if (protocol == QSsl::SecureProtocols)
options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
else if (protocol == QSsl::TlsV1_0OrLater)
@@ -357,7 +501,7 @@ bool QSslSocketBackendPrivate::initSslContext()
if (configuration.protocol != QSsl::SslV2 &&
configuration.protocol != QSsl::SslV3 &&
configuration.protocol != QSsl::UnknownProtocol &&
- mode == QSslSocket::SslClientMode && QSslSocket::sslLibraryVersionNumber() >= 0x00090806fL) {
+ mode == QSslSocket::SslClientMode) {
// Set server hostname on TLS extension. RFC4366 section 3.1 requires it in ACE format.
QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName;
if (tlsHostName.isEmpty())
@@ -412,6 +556,40 @@ bool QSslSocketBackendPrivate::initSslContext()
}
#endif
+#if QT_CONFIG(ocsp)
+ if (configuration.ocspStaplingEnabled) {
+ if (mode == QSslSocket::SslServerMode) {
+ setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
+ QSslSocket::tr("Server-side QSslSocket does not support OCSP stapling"));
+ return false;
+ }
+ if (q_SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp) != 1) {
+ setErrorAndEmit(QAbstractSocket::SslInternalError,
+ QSslSocket::tr("Failed to enable OCSP stapling"));
+ return false;
+ }
+ }
+
+ ocspResponseDer.clear();
+ auto responsePos = configuration.backendConfig.find("Qt-OCSP-response");
+ if (responsePos != configuration.backendConfig.end()) {
+ // This is our private, undocumented 'API' we use for the auto-testing of
+ // OCSP-stapling. It must be a der-encoded OCSP response, presumably set
+ // by tst_QOcsp.
+ const QVariant data(responsePos.value());
+ if (data.canConvert<QByteArray>())
+ ocspResponseDer = data.toByteArray();
+ }
+
+ if (ocspResponseDer.size()) {
+ if (mode != QSslSocket::SslServerMode) {
+ setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
+ QSslSocket::tr("Client-side sockets do not send OCSP responses"));
+ return false;
+ }
+ }
+#endif // ocsp
+
return true;
}
@@ -552,22 +730,20 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
#endif
QList<QSslCertificate> systemCerts;
#if defined(Q_OS_WIN)
- if (ptrCertOpenSystemStoreW && ptrCertFindCertificateInStore && ptrCertCloseStore) {
- HCERTSTORE hSystemStore;
- hSystemStore = ptrCertOpenSystemStoreW(0, L"ROOT");
- if (hSystemStore) {
- PCCERT_CONTEXT pc = nullptr;
- while (1) {
- pc = ptrCertFindCertificateInStore(hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, nullptr, pc);
- if (!pc)
- break;
- QByteArray der(reinterpret_cast<const char *>(pc->pbCertEncoded),
- static_cast<int>(pc->cbCertEncoded));
- QSslCertificate cert(der, QSsl::Der);
- systemCerts.append(cert);
- }
- ptrCertCloseStore(hSystemStore, 0);
+ HCERTSTORE hSystemStore;
+ hSystemStore = CertOpenSystemStoreW(0, L"ROOT");
+ if (hSystemStore) {
+ PCCERT_CONTEXT pc = nullptr;
+ while (1) {
+ pc = CertFindCertificateInStore(hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, nullptr, pc);
+ if (!pc)
+ break;
+ QByteArray der(reinterpret_cast<const char *>(pc->pbCertEncoded),
+ static_cast<int>(pc->cbCertEncoded));
+ QSslCertificate cert(der, QSsl::Der);
+ systemCerts.append(cert);
}
+ CertCloseStore(hSystemStore, 0);
}
#elif defined(Q_OS_UNIX)
QSet<QString> certFiles;
@@ -1005,9 +1181,33 @@ bool QSslSocketBackendPrivate::startHandshake()
}
}
- bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer
- || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer
- && mode == QSslSocket::SslClientMode);
+ const bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer
+ || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer
+ && mode == QSslSocket::SslClientMode);
+
+#if QT_CONFIG(ocsp)
+ // For now it's always QSslSocket::SslClientMode - initSslContext() will bail out early,
+ // if it's enabled in QSslSocket::SslServerMode. This can change.
+ if (!configuration.peerCertificate.isNull() && configuration.ocspStaplingEnabled && doVerifyPeer) {
+ if (!checkOcspStatus()) {
+ if (ocspErrors.isEmpty()) {
+ {
+ const ScopedBool bg(inSetAndEmitError, true);
+ setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, ocspErrorDescription);
+ }
+ q->abort();
+ return false;
+ }
+
+ for (const QSslError &error : ocspErrors) {
+ errors << error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+ }
+ }
+#endif // ocsp
// Check the peer certificate itself. First try the subject's common name
// (CN) as a wildcard, then try all alternate subject name DNS entries the
@@ -1254,6 +1454,193 @@ void QSslSocketBackendPrivate::_q_caRootLoaded(QSslCertificate cert, QSslCertifi
#endif
+#if QT_CONFIG(ocsp)
+
+bool QSslSocketBackendPrivate::checkOcspStatus()
+{
+ Q_ASSERT(ssl);
+ Q_ASSERT(mode == QSslSocket::SslClientMode); // See initSslContext() for SslServerMode
+ Q_ASSERT(configuration.peerVerifyMode != QSslSocket::VerifyNone);
+
+ ocspResponses.clear();
+ ocspErrorDescription.clear();
+ ocspErrors.clear();
+
+ const unsigned char *responseData = nullptr;
+ const long responseLength = q_SSL_get_tlsext_status_ocsp_resp(ssl, &responseData);
+ if (responseLength <= 0 || !responseData) {
+ ocspErrors.push_back(QSslError::OcspNoResponseFound);
+ return false;
+ }
+
+ OCSP_RESPONSE *response = q_d2i_OCSP_RESPONSE(nullptr, &responseData, responseLength);
+ if (!response) {
+ // Treat this as a fatal SslHandshakeError.
+ ocspErrorDescription = QSslSocket::tr("Failed to decode OCSP response");
+ return false;
+ }
+ const QSharedPointer<OCSP_RESPONSE> responseGuard(response, q_OCSP_RESPONSE_free);
+
+ const int ocspStatus = q_OCSP_response_status(response);
+ if (ocspStatus != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+ // It's not a definitive response, it's an error message (not signed by the responder).
+ ocspErrors.push_back(qt_OCSP_response_status_to_QSslError(ocspStatus));
+ return false;
+ }
+
+ OCSP_BASICRESP *basicResponse = q_OCSP_response_get1_basic(response);
+ if (!basicResponse) {
+ // SslHandshakeError.
+ ocspErrorDescription = QSslSocket::tr("Failed to extract basic OCSP response");
+ return false;
+ }
+ const QSharedPointer<OCSP_BASICRESP> basicResponseGuard(basicResponse, q_OCSP_BASICRESP_free);
+
+ SSL_CTX *ctx = q_SSL_get_SSL_CTX(ssl); // Does not increment refcount.
+ Q_ASSERT(ctx);
+ X509_STORE *store = q_SSL_CTX_get_cert_store(ctx); // Does not increment refcount.
+ if (!store) {
+ // SslHandshakeError.
+ ocspErrorDescription = QSslSocket::tr("No certificate verification store, cannot verify OCSP response");
+ return false;
+ }
+
+ STACK_OF(X509) *peerChain = q_SSL_get_peer_cert_chain(ssl); // Does not increment refcount.
+ X509 *peerX509 = q_SSL_get_peer_certificate(ssl);
+ Q_ASSERT(peerChain || peerX509);
+ const QSharedPointer<X509> peerX509Guard(peerX509, q_X509_free);
+ // OCSP_basic_verify with 0 as verificationFlags:
+ //
+ // 0) Tries to find the OCSP responder's certificate in either peerChain
+ // or basicResponse->certs. If not found, verification fails.
+ // 1) It checks the signature using the responder's public key.
+ // 2) Then it tries to validate the responder's cert (building a chain
+ // etc.)
+ // 3) It checks CertID in response.
+ // 4) Ensures the responder is authorized to sign the status respond.
+ //
+ // Here it's important to notice that it calls X509_cert_verify and
+ // as a result, possibly, our verification callback. Given this callback
+ // at the moment uses a global variable, we have to lock. This will change
+ // as soon as we fix our verification procedure.
+ // Also note, OpenSSL prior to 1.0.2b would only use bs->certs to
+ // verify the responder's chain (see their commit 4ba9a4265bd).
+ // Working this around - is too much fuss for ancient versions we
+ // are dropping quite soon anyway.
+ {
+ const unsigned long verificationFlags = 0;
+ const QMutexLocker locker(&_q_sslErrorList()->mutex);
+ // Before unlocking the mutex, startHandshake() stores errors (found in SSL_connect()
+ // or SSL_accept()) into the local variable, so it's safe to clear it here - as soon
+ // as we managed to lock, whoever had the lock before, already stored their own copy
+ // of errors.
+ _q_sslErrorList()->errors.clear();
+ const int success = q_OCSP_basic_verify(basicResponse, peerChain, store, verificationFlags);
+ if (success <= 0 || _q_sslErrorList()->errors.size()) {
+ _q_sslErrorList()->errors.clear();
+ ocspErrors.push_back(QSslError::OcspResponseCannotBeTrusted);
+ }
+ }
+
+ if (q_OCSP_resp_count(basicResponse) != 1) {
+ ocspErrors.push_back(QSslError::OcspMalformedResponse);
+ return false;
+ }
+
+ OCSP_SINGLERESP *singleResponse = q_OCSP_resp_get0(basicResponse, 0);
+ if (!singleResponse) {
+ ocspErrors.clear();
+ // A fatal problem -> SslHandshakeError.
+ ocspErrorDescription = QSslSocket::tr("Failed to decode a SingleResponse from OCSP status response");
+ return false;
+ }
+
+ // Let's make sure the response is for the correct certificate - we
+ // can re-create this CertID using our peer's certificate and its
+ // issuer's public key.
+ ocspResponses.push_back(QOcspResponse());
+ QOcspResponsePrivate *dResponse = ocspResponses.back().d.data();
+ dResponse->subjectCert = configuration.peerCertificate;
+ bool matchFound = false;
+ if (configuration.peerCertificate.isSelfSigned()) {
+ dResponse->signerCert = configuration.peerCertificate;
+ matchFound = qt_OCSP_certificate_match(singleResponse, peerX509, peerX509);
+ } else {
+ const STACK_OF(X509) *certs = q_SSL_get_peer_cert_chain(ssl);
+ if (!certs) // Oh, what a cataclysm! Last try:
+ certs = q_OCSP_resp_get0_certs(basicResponse);
+ if (certs) {
+ // It could be the first certificate in 'certs' is our peer's
+ // certificate. Since it was not captured by the 'self-signed' branch
+ // above, the CertID will not match and we'll just iterate on to the
+ // next certificate. So we start from 0, not 1.
+ for (int i = 0, e = q_sk_X509_num(certs); i < e; ++i) {
+ X509 *issuer = q_sk_X509_value(certs, i);
+ matchFound = qt_OCSP_certificate_match(singleResponse, peerX509, issuer);
+ if (matchFound) {
+ if (q_X509_check_issued(issuer, peerX509) == X509_V_OK) {
+ dResponse->signerCert = QSslCertificatePrivate::QSslCertificate_from_X509(issuer);
+ break;
+ }
+ matchFound = false;
+ }
+ }
+ }
+ }
+
+ if (!matchFound) {
+ dResponse->signerCert.clear();
+ ocspErrors.push_back({QSslError::OcspResponseCertIdUnknown, configuration.peerCertificate});
+ }
+
+ // Check if the response is valid time-wise:
+ ASN1_GENERALIZEDTIME *revTime = nullptr;
+ ASN1_GENERALIZEDTIME *thisUpdate = nullptr;
+ ASN1_GENERALIZEDTIME *nextUpdate = nullptr;
+ int reason;
+ const int certStatus = q_OCSP_single_get0_status(singleResponse, &reason, &revTime, &thisUpdate, &nextUpdate);
+ if (!thisUpdate) {
+ // This is unexpected, treat as SslHandshakeError, OCSP_check_validity assumes this pointer
+ // to be != nullptr.
+ ocspErrors.clear();
+ ocspResponses.clear();
+ ocspErrorDescription = QSslSocket::tr("Failed to extract 'this update time' from the SingleResponse");
+ return false;
+ }
+
+ // OCSP_check_validity(this, next, nsec, maxsec) does this check:
+ // this <= now <= next. They allow some freedom to account
+ // for delays/time inaccuracy.
+ // this > now + nsec ? -> NOT_YET_VALID
+ // if maxsec >= 0:
+ // now - maxsec > this ? -> TOO_OLD
+ // now - nsec > next ? -> EXPIRED
+ // next < this ? -> NEXT_BEFORE_THIS
+ // OK.
+ if (!q_OCSP_check_validity(thisUpdate, nextUpdate, 60, -1))
+ ocspErrors.push_back({QSslError::OcspResponseExpired, configuration.peerCertificate});
+
+ // And finally, the status:
+ switch (certStatus) {
+ case V_OCSP_CERTSTATUS_GOOD:
+ // This certificate was not found among the revoked ones.
+ dResponse->certificateStatus = QOcspCertificateStatus::Good;
+ break;
+ case V_OCSP_CERTSTATUS_REVOKED:
+ dResponse->certificateStatus = QOcspCertificateStatus::Revoked;
+ dResponse->revocationReason = qt_OCSP_revocation_reason(reason);
+ ocspErrors.push_back({QSslError::CertificateRevoked, configuration.peerCertificate});
+ break;
+ case V_OCSP_CERTSTATUS_UNKNOWN:
+ dResponse->certificateStatus = QOcspCertificateStatus::Unknown;
+ ocspErrors.push_back({QSslError::OcspStatusUnknown, configuration.peerCertificate});
+ }
+
+ return !ocspErrors.size();
+}
+
+#endif // ocsp
+
void QSslSocketBackendPrivate::disconnectFromHost()
{
if (ssl) {
diff --git a/src/network/ssl/qsslsocket_openssl11.cpp b/src/network/ssl/qsslsocket_openssl11.cpp
index 2a2667bd48..b60b8be41f 100644
--- a/src/network/ssl/qsslsocket_openssl11.cpp
+++ b/src/network/ssl/qsslsocket_openssl11.cpp
@@ -122,21 +122,7 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
#if QT_CONFIG(library)
//load symbols needed to receive certificates from system store
-#if defined(Q_OS_WIN)
- HINSTANCE hLib = LoadLibraryW(L"Crypt32");
- if (hLib) {
- ptrCertOpenSystemStoreW = reinterpret_cast<PtrCertOpenSystemStoreW>(
- reinterpret_cast<QFunctionPointer>(GetProcAddress(hLib, "CertOpenSystemStoreW")));
- ptrCertFindCertificateInStore = reinterpret_cast<PtrCertFindCertificateInStore>(
- reinterpret_cast<QFunctionPointer>(GetProcAddress(hLib, "CertFindCertificateInStore")));
- ptrCertCloseStore = reinterpret_cast<PtrCertCloseStore>(
- reinterpret_cast<QFunctionPointer>(GetProcAddress(hLib, "CertCloseStore")));
- if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore)
- qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen
- } else {
- qCWarning(lcSsl, "could not load crypt32 library"); // should never happen
- }
-#elif defined(Q_OS_QNX)
+#if defined(Q_OS_QNX)
s_loadRootCertsOnDemand = true;
#elif defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
// check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
index fae007e12d..a44d00a830 100644
--- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
@@ -84,12 +84,12 @@ int q_DSA_bits(DSA *a);
int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c);
int q_EVP_PKEY_base_id(EVP_PKEY *a);
int q_RSA_bits(RSA *a);
-int q_OPENSSL_sk_num(OPENSSL_STACK *a);
-void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
-OPENSSL_STACK *q_OPENSSL_sk_new_null();
-void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
-void q_OPENSSL_sk_free(OPENSSL_STACK *a);
-void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
+Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
+Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
+Q_AUTOTEST_EXPORT OPENSSL_STACK *q_OPENSSL_sk_new_null();
+Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
+Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
+Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
int q_SSL_session_reused(SSL *a);
unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
@@ -102,6 +102,7 @@ const SSL_METHOD *q_TLS_server_method();
ASN1_TIME *q_X509_getm_notBefore(X509 *a);
ASN1_TIME *q_X509_getm_notAfter(X509 *a);
+Q_AUTOTEST_EXPORT void q_X509_up_ref(X509 *a);
long q_X509_get_version(X509 *a);
EVP_PKEY *q_X509_get_pubkey(X509 *a);
void q_X509_STORE_set_verify_cb(X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb);
@@ -172,6 +173,10 @@ void q_BIO_set_init(BIO *a, int init);
int q_BIO_get_shutdown(BIO *a);
void q_BIO_set_shutdown(BIO *a, int shut);
+#if QT_CONFIG(ocsp)
+const OCSP_CERTID *q_OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x);
+#endif // ocsp
+
#define q_SSL_CTX_set_min_proto_version(ctx, version) \
q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, nullptr)
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index c16b9d5f76..c23234e291 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -69,6 +69,9 @@
#include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qsslsocket_p.h"
+#include <QtCore/qvector.h>
+#include <QtCore/qstring.h>
+
#ifdef Q_OS_WIN
#include <qt_windows.h>
#if defined(OCSP_RESPONSE)
@@ -152,6 +155,16 @@ public:
void _q_caRootLoaded(QSslCertificate,QSslCertificate) override;
#endif
+#if QT_CONFIG(ocsp)
+ bool checkOcspStatus();
+#endif
+
+ // This decription will go to setErrorAndEmit(SslHandshakeError, ocspErrorDescription)
+ QString ocspErrorDescription;
+ // These will go to sslErrors()
+ QVector<QSslError> ocspErrors;
+ QByteArray ocspResponseDer;
+
Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher);
static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 299df6b685..aa1dc681e0 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -172,6 +172,7 @@ DEFINEFUNC2(unsigned long, SSL_set_options, SSL *ssl, ssl, unsigned long op, op,
DEFINEFUNC(const SSL_METHOD *, TLS_method, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(const SSL_METHOD *, TLS_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(const SSL_METHOD *, TLS_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(void, X509_up_ref, X509 *a, a, return, DUMMYARG)
DEFINEFUNC(ASN1_TIME *, X509_getm_notBefore, X509 *a, a, return nullptr, return)
DEFINEFUNC(ASN1_TIME *, X509_getm_notAfter, X509 *a, a, return nullptr, return)
DEFINEFUNC(long, X509_get_version, X509 *a, a, return -1, return)
@@ -199,6 +200,35 @@ DEFINEFUNC2(int, BIO_meth_set_create, BIO_METHOD *biom, biom, DgramCreateCallbac
DEFINEFUNC2(int, BIO_meth_set_destroy, BIO_METHOD *biom, biom, DgramDestroyCallback dtr, dtr, return 0, return)
#endif // dtls
+#if QT_CONFIG(ocsp)
+DEFINEFUNC(const OCSP_CERTID *, OCSP_SINGLERESP_get0_id, const OCSP_SINGLERESP *x, x, return nullptr, return)
+DEFINEFUNC3(OCSP_RESPONSE *, d2i_OCSP_RESPONSE, OCSP_RESPONSE **a, a, const unsigned char **in, in, long len, len, return nullptr, return)
+DEFINEFUNC(void, OCSP_RESPONSE_free, OCSP_RESPONSE *rs, rs, return, DUMMYARG)
+DEFINEFUNC(OCSP_BASICRESP *, OCSP_response_get1_basic, OCSP_RESPONSE *resp, resp, return nullptr, return)
+DEFINEFUNC(void, OCSP_BASICRESP_free, OCSP_BASICRESP *bs, bs, return, DUMMYARG)
+DEFINEFUNC(int, OCSP_response_status, OCSP_RESPONSE *resp, resp, return OCSP_RESPONSE_STATUS_INTERNALERROR, return)
+DEFINEFUNC4(int, OCSP_basic_verify, OCSP_BASICRESP *bs, bs, STACK_OF(X509) *certs, certs, X509_STORE *st, st, unsigned long flags, flags, return -1, return)
+DEFINEFUNC(int, OCSP_resp_count, OCSP_BASICRESP *bs, bs, return 0, return)
+DEFINEFUNC2(OCSP_SINGLERESP *, OCSP_resp_get0, OCSP_BASICRESP *bs, bs, int idx, idx, return nullptr, return)
+DEFINEFUNC5(int, OCSP_single_get0_status, OCSP_SINGLERESP *single, single, int *reason, reason, ASN1_GENERALIZEDTIME **revtime, revtime,
+ ASN1_GENERALIZEDTIME **thisupd, thisupd, ASN1_GENERALIZEDTIME **nextupd, nextupd, return -1, return)
+DEFINEFUNC4(int, OCSP_check_validity, ASN1_GENERALIZEDTIME *thisupd, thisupd, ASN1_GENERALIZEDTIME *nextupd, nextupd, long nsec, nsec, long maxsec, maxsec, return 0, return)
+DEFINEFUNC3(OCSP_CERTID *, OCSP_cert_to_id, const EVP_MD *dgst, dgst, X509 *subject, subject, X509 *issuer, issuer, return nullptr, return)
+DEFINEFUNC(void, OCSP_CERTID_free, OCSP_CERTID *cid, cid, return, DUMMYARG)
+DEFINEFUNC5(int, OCSP_id_get0_info, ASN1_OCTET_STRING **piNameHash, piNameHash, ASN1_OBJECT **pmd, pmd,
+ ASN1_OCTET_STRING **piKeyHash, piKeyHash, ASN1_INTEGER **pserial, pserial, OCSP_CERTID *cid, cid,
+ return 0, return)
+DEFINEFUNC2(OCSP_RESPONSE *, OCSP_response_create, int status, status, OCSP_BASICRESP *bs, bs, return nullptr, return)
+DEFINEFUNC(const STACK_OF(X509) *, OCSP_resp_get0_certs, const OCSP_BASICRESP *bs, bs, return nullptr, return)
+DEFINEFUNC2(int, OCSP_id_cmp, OCSP_CERTID *a, a, OCSP_CERTID *b, b, return -1, return)
+DEFINEFUNC7(OCSP_SINGLERESP *, OCSP_basic_add1_status, OCSP_BASICRESP *r, r, OCSP_CERTID *c, c, int s, s,
+ int re, re, ASN1_TIME *rt, rt, ASN1_TIME *t, t, ASN1_TIME *n, n, return nullptr, return)
+DEFINEFUNC(OCSP_BASICRESP *, OCSP_BASICRESP_new, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC2(int, i2d_OCSP_RESPONSE, OCSP_RESPONSE *r, r, unsigned char **ppout, ppout, return 0, return)
+DEFINEFUNC6(int, OCSP_basic_sign, OCSP_BASICRESP *br, br, X509 *signer, signer, EVP_PKEY *key, key,
+ const EVP_MD *dg, dg, STACK_OF(X509) *cs, cs, unsigned long flags, flags, return 0, return)
+#endif // ocsp
+
DEFINEFUNC2(void, BIO_set_data, BIO *a, a, void *ptr, ptr, return, DUMMYARG)
DEFINEFUNC(void *, BIO_get_data, BIO *a, a, return nullptr, return)
DEFINEFUNC2(void, BIO_set_init, BIO *a, a, int init, init, return, DUMMYARG)
@@ -235,17 +265,10 @@ DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO
DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)
DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(void, sk_push, _STACK *a, a, void *b, b, return, DUMMYARG)
DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG)
DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return nullptr, return)
-#else
-DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return)
-DEFINEFUNC2(void, sk_push, STACK *a, a, char *b, b, return, DUMMYARG)
-DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG)
-DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return nullptr, return)
-#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return)
DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG)
@@ -254,49 +277,18 @@ DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC5(int, SSL_get_ex_new_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return)
#endif // OPENSSL_VERSION_NUMBER >= 0x10001000L
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#endif
DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#endif
DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-#else
-#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#endif
-DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
-DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#endif
-DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
-DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
-#endif
DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get_chain, X509_STORE_CTX *a, a, return nullptr, return)
@@ -329,6 +321,7 @@ DEFINEFUNC(const char *, SSLeay_version, int a, a, return nullptr, return)
#endif // QT_CONFIG(opensslv11)
DEFINEFUNC(long, ASN1_INTEGER_get, ASN1_INTEGER *a, a, return 0, return)
+DEFINEFUNC2(int, ASN1_INTEGER_cmp, const ASN1_INTEGER *a, a, const ASN1_INTEGER *b, b, return 1, return)
DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return)
DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return)
DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return)
@@ -357,6 +350,7 @@ DEFINEFUNC5(int, EVP_CipherInit, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *typ
DEFINEFUNC6(int, EVP_CipherInit_ex, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *cipher, cipher, ENGINE *impl, impl, const unsigned char *key, key, const unsigned char *iv, iv, int enc, enc, return 0, return)
DEFINEFUNC5(int, EVP_CipherUpdate, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, const unsigned char *in, in, int inl, inl, return 0, return)
DEFINEFUNC3(int, EVP_CipherFinal, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, return 0, return)
+DEFINEFUNC(const EVP_MD *, EVP_get_digestbyname, const char *name, name, return nullptr, return)
#ifndef OPENSSL_NO_DES
DEFINEFUNC(const EVP_CIPHER *, EVP_des_cbc, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return nullptr, return)
@@ -368,12 +362,14 @@ DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return)
+DEFINEFUNC2(int, EVP_PKEY_set1_DH, EVP_PKEY *a, a, DH *b, b, return -1, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC2(int, EVP_PKEY_set1_EC_KEY, EVP_PKEY *a, a, EC_KEY *b, b, return -1, return)
#endif
DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG)
DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return nullptr, return)
DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return nullptr, return)
+DEFINEFUNC(DH *, EVP_PKEY_get1_DH, EVP_PKEY *a, a, return nullptr, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC(EC_KEY *, EVP_PKEY_get1_EC_KEY, EVP_PKEY *a, a, return nullptr, return)
#endif
@@ -399,6 +395,7 @@ DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_p
DEFINEFUNC4(DH *, PEM_read_bio_DHparams, BIO *a, a, DH **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC7(int, PEM_write_bio_DSAPrivateKey, BIO *a, a, DSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
+DEFINEFUNC7(int, PEM_write_bio_PrivateKey, BIO *a, a, EVP_PKEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
#endif
@@ -411,6 +408,7 @@ DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_pass
#endif
DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return)
DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return)
+DEFINEFUNC2(int, PEM_write_bio_PUBKEY, BIO *a, a, EVP_PKEY *b, b, return 0, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC2(int, PEM_write_bio_EC_PUBKEY, BIO *a, a, EC_KEY *b, b, return 0, return)
#endif
@@ -428,12 +426,9 @@ DEFINEFUNC(int, SSL_connect, SSL *a, a, return -1, return)
DEFINEFUNC(int, SSL_CTX_check_private_key, const SSL_CTX *a, a, return -1, return)
DEFINEFUNC4(long, SSL_CTX_ctrl, SSL_CTX *a, a, int b, b, long c, c, void *d, d, return -1, return)
DEFINEFUNC(void, SSL_CTX_free, SSL_CTX *a, a, return, DUMMYARG)
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
DEFINEFUNC(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a, a, return nullptr, return)
-#else
-DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return nullptr, return)
-#endif
DEFINEFUNC2(int, SSL_CTX_set_cipher_list, SSL_CTX *a, a, const char *b, b, return -1, return)
+DEFINEFUNC3(long, SSL_CTX_callback_ctrl, SSL_CTX *ctx, ctx, int dst, dst, GenericCallbackType cb, cb, return 0, return)
DEFINEFUNC(int, SSL_CTX_set_default_verify_paths, SSL_CTX *a, a, return -1, return)
DEFINEFUNC3(void, SSL_CTX_set_verify, SSL_CTX *a, a, int b, b, int (*c)(int, X509_STORE_CTX *), c, return, DUMMYARG)
DEFINEFUNC2(void, SSL_CTX_set_verify_depth, SSL_CTX *a, a, int b, b, return, DUMMYARG)
@@ -453,22 +448,14 @@ DEFINEFUNC3(int, SSL_CONF_cmd, SSL_CONF_CTX *a, a, const char *b, b, const char
#endif
DEFINEFUNC(void, SSL_free, SSL *a, a, return, DUMMYARG)
DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, const SSL *a, a, return nullptr, return)
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr, return)
-#else
-DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr, return)
-#endif
DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return)
DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
-#if OPENSSL_VERSION_NUMBER >= 0x00908000L
-// 0.9.8 broke SC and BC by changing this function's signature.
DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
-#else
-DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return)
-#endif
DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return)
+DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return)
DEFINEFUNC4(long, SSL_ctrl, SSL *a, a, int cmd, cmd, long larg, larg, void *parg, parg, return -1, return)
DEFINEFUNC3(int, SSL_read, SSL *a, a, void *b, b, int c, c, return -1, return)
DEFINEFUNC3(void, SSL_set_bio, SSL *a, a, BIO *b, b, BIO *c, c, return, DUMMYARG)
@@ -498,6 +485,9 @@ DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return nullptr, return)
DEFINEFUNC2(void, X509_print, BIO *a, a, X509 *b, b, return, DUMMYARG);
DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return nullptr, return)
DEFINEFUNC(void, X509_free, X509 *a, a, return, DUMMYARG)
+//Q_AUTOTEST_EXPORT ASN1_TIME *q_X509_gmtime_adj(ASN1_TIME *s, long adj);
+DEFINEFUNC2(ASN1_TIME *, X509_gmtime_adj, ASN1_TIME *s, s, long adj, adj, return nullptr, return)
+DEFINEFUNC(void, ASN1_TIME_free, ASN1_TIME *t, t, return, DUMMYARG)
DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return nullptr, return)
DEFINEFUNC(int, X509_get_ext_count, X509 *a, a, return 0, return)
DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d, return nullptr, return)
@@ -508,11 +498,7 @@ DEFINEFUNC(ASN1_OCTET_STRING *, X509_EXTENSION_get_data, X509_EXTENSION *a, a, r
DEFINEFUNC(void, BASIC_CONSTRAINTS_free, BASIC_CONSTRAINTS *a, a, return, DUMMYARG)
DEFINEFUNC(void, AUTHORITY_KEYID_free, AUTHORITY_KEYID *a, a, return, DUMMYARG)
DEFINEFUNC(void, GENERAL_NAME_free, GENERAL_NAME *a, a, return, DUMMYARG)
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, const ASN1_STRING *b, b, return 0, return)
-#else
-DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, ASN1_STRING *b, b, return 0, return)
-#endif
DEFINEFUNC2(int, X509_check_issued, X509 *a, a, X509 *b, b, return -1, return)
DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return nullptr, return)
DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return nullptr, return)
@@ -577,6 +563,7 @@ DEFINEFUNC2(void, BIO_clear_flags, BIO *b, b, int flags, flags, return, DUMMYARG
DEFINEFUNC2(void *, BIO_get_ex_data, BIO *b, b, int idx, idx, return nullptr, return)
DEFINEFUNC3(int, BIO_set_ex_data, BIO *b, b, int idx, idx, void *data, data, return -1, return)
+DEFINEFUNC3(void *, CRYPTO_malloc, size_t num, num, const char *file, file, int line, line, return nullptr, return)
DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
@@ -990,6 +977,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(TLS_method)
RESOLVEFUNC(TLS_client_method)
RESOLVEFUNC(TLS_server_method)
+ RESOLVEFUNC(X509_up_ref)
RESOLVEFUNC(X509_STORE_CTX_get0_chain)
RESOLVEFUNC(X509_getm_notBefore)
RESOLVEFUNC(X509_getm_notAfter)
@@ -1025,7 +1013,30 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(BIO_meth_set_create)
RESOLVEFUNC(BIO_meth_set_destroy)
#endif // dtls
-
+#if QT_CONFIG(ocsp)
+ RESOLVEFUNC(OCSP_SINGLERESP_get0_id)
+ RESOLVEFUNC(d2i_OCSP_RESPONSE)
+ RESOLVEFUNC(OCSP_RESPONSE_free)
+ RESOLVEFUNC(OCSP_response_status)
+ RESOLVEFUNC(OCSP_response_get1_basic)
+ RESOLVEFUNC(OCSP_BASICRESP_free)
+ RESOLVEFUNC(OCSP_basic_verify)
+ RESOLVEFUNC(OCSP_resp_count)
+ RESOLVEFUNC(OCSP_resp_get0)
+ RESOLVEFUNC(OCSP_single_get0_status)
+ RESOLVEFUNC(OCSP_check_validity)
+ RESOLVEFUNC(OCSP_cert_to_id)
+ RESOLVEFUNC(OCSP_id_get0_info)
+ RESOLVEFUNC(OCSP_resp_get0_certs)
+ RESOLVEFUNC(OCSP_basic_sign)
+ RESOLVEFUNC(OCSP_response_create)
+ RESOLVEFUNC(i2d_OCSP_RESPONSE)
+ RESOLVEFUNC(OCSP_basic_add1_status)
+ RESOLVEFUNC(OCSP_BASICRESP_new)
+ RESOLVEFUNC(OCSP_CERTID_free)
+ RESOLVEFUNC(OCSP_cert_to_id)
+ RESOLVEFUNC(OCSP_id_cmp)
+#endif // ocsp
RESOLVEFUNC(BIO_set_data)
RESOLVEFUNC(BIO_get_data)
RESOLVEFUNC(BIO_set_init)
@@ -1064,24 +1075,12 @@ bool q_resolveOpenSslSymbols()
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
RESOLVEFUNC(SSL_get_ex_new_index)
#endif
-#ifndef OPENSSL_NO_SSL2
- RESOLVEFUNC(SSLv2_client_method)
-#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
- RESOLVEFUNC(SSLv3_client_method)
-#endif
RESOLVEFUNC(SSLv23_client_method)
RESOLVEFUNC(TLSv1_client_method)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
RESOLVEFUNC(TLSv1_1_client_method)
RESOLVEFUNC(TLSv1_2_client_method)
#endif
-#ifndef OPENSSL_NO_SSL2
- RESOLVEFUNC(SSLv2_server_method)
-#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
- RESOLVEFUNC(SSLv3_server_method)
-#endif
RESOLVEFUNC(SSLv23_server_method)
RESOLVEFUNC(TLSv1_server_method)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
@@ -1132,6 +1131,7 @@ bool q_resolveOpenSslSymbols()
#endif // !opensslv11
RESOLVEFUNC(ASN1_INTEGER_get)
+ RESOLVEFUNC(ASN1_INTEGER_cmp)
RESOLVEFUNC(ASN1_STRING_length)
RESOLVEFUNC(ASN1_STRING_to_UTF8)
RESOLVEFUNC(BIO_ctrl)
@@ -1168,6 +1168,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EVP_CipherInit_ex)
RESOLVEFUNC(EVP_CipherUpdate)
RESOLVEFUNC(EVP_CipherFinal)
+ RESOLVEFUNC(EVP_get_digestbyname)
#ifndef OPENSSL_NO_DES
RESOLVEFUNC(EVP_des_cbc)
RESOLVEFUNC(EVP_des_ede3_cbc)
@@ -1179,12 +1180,14 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EVP_PKEY_assign)
RESOLVEFUNC(EVP_PKEY_set1_RSA)
RESOLVEFUNC(EVP_PKEY_set1_DSA)
+ RESOLVEFUNC(EVP_PKEY_set1_DH)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EVP_PKEY_set1_EC_KEY)
#endif
RESOLVEFUNC(EVP_PKEY_free)
RESOLVEFUNC(EVP_PKEY_get1_DSA)
RESOLVEFUNC(EVP_PKEY_get1_RSA)
+ RESOLVEFUNC(EVP_PKEY_get1_DH)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EVP_PKEY_get1_EC_KEY)
#endif
@@ -1208,6 +1211,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(PEM_read_bio_DHparams)
RESOLVEFUNC(PEM_write_bio_DSAPrivateKey)
RESOLVEFUNC(PEM_write_bio_RSAPrivateKey)
+ RESOLVEFUNC(PEM_write_bio_PrivateKey)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(PEM_write_bio_ECPrivateKey)
#endif
@@ -1221,6 +1225,7 @@ bool q_resolveOpenSslSymbols()
#endif
RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY)
RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY)
+ RESOLVEFUNC(PEM_write_bio_PUBKEY)
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(PEM_write_bio_EC_PUBKEY)
#endif
@@ -1237,6 +1242,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_CTX_free)
RESOLVEFUNC(SSL_CTX_new)
RESOLVEFUNC(SSL_CTX_set_cipher_list)
+ RESOLVEFUNC(SSL_CTX_callback_ctrl)
RESOLVEFUNC(SSL_CTX_set_default_verify_paths)
RESOLVEFUNC(SSL_CTX_set_verify)
RESOLVEFUNC(SSL_CTX_set_verify_depth)
@@ -1266,6 +1272,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_get_peer_certificate)
RESOLVEFUNC(SSL_get_verify_result)
RESOLVEFUNC(SSL_new)
+ RESOLVEFUNC(SSL_get_SSL_CTX)
RESOLVEFUNC(SSL_ctrl)
RESOLVEFUNC(SSL_read)
RESOLVEFUNC(SSL_set_accept_state)
@@ -1313,6 +1320,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(X509_digest)
RESOLVEFUNC(X509_EXTENSION_get_object)
RESOLVEFUNC(X509_free)
+ RESOLVEFUNC(X509_gmtime_adj)
+ RESOLVEFUNC(ASN1_TIME_free)
RESOLVEFUNC(X509_get_ext)
RESOLVEFUNC(X509_get_ext_count)
RESOLVEFUNC(X509_get_ext_d2i)
@@ -1350,6 +1359,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(DTLS_server_method)
RESOLVEFUNC(DTLS_client_method)
#endif // dtls
+ RESOLVEFUNC(CRYPTO_malloc)
RESOLVEFUNC(DH_new)
RESOLVEFUNC(DH_free)
RESOLVEFUNC(d2i_DHparams)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index bfdfbf0efc..e09820b2f2 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -72,6 +72,10 @@
#include "qsslsocket_openssl_p.h"
#include <QtCore/qglobal.h>
+#if QT_CONFIG(ocsp)
+#include "qocsp_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
#define DUMMYARG
@@ -224,6 +228,7 @@ QT_BEGIN_NAMESPACE
bool q_resolveOpenSslSymbols();
long q_ASN1_INTEGER_get(ASN1_INTEGER *a);
+int q_ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
int q_ASN1_STRING_length(ASN1_STRING *a);
int q_ASN1_STRING_to_UTF8(unsigned char **a, ASN1_STRING *b);
long q_BIO_ctrl(BIO *a, int b, long c, void *d);
@@ -267,6 +272,8 @@ int q_EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, const unsigned
int q_EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc);
int q_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl);
int q_EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+const EVP_MD *q_EVP_get_digestbyname(const char *name);
+
#ifndef OPENSSL_NO_DES
const EVP_CIPHER *q_EVP_des_cbc();
const EVP_CIPHER *q_EVP_des_ede3_cbc();
@@ -274,16 +281,18 @@ const EVP_CIPHER *q_EVP_des_ede3_cbc();
#ifndef OPENSSL_NO_RC2
const EVP_CIPHER *q_EVP_rc2_cbc();
#endif
-const EVP_MD *q_EVP_sha1();
+Q_AUTOTEST_EXPORT const EVP_MD *q_EVP_sha1();
int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c);
Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b);
int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
+int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b);
#ifndef OPENSSL_NO_EC
int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b);
#endif
-void q_EVP_PKEY_free(EVP_PKEY *a);
+Q_AUTOTEST_EXPORT void q_EVP_PKEY_free(EVP_PKEY *a);
RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a);
DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a);
+DH *q_EVP_PKEY_get1_DH(EVP_PKEY *a);
#ifndef OPENSSL_NO_EC
EC_KEY *q_EVP_PKEY_get1_EC_KEY(EVP_PKEY *a);
#endif
@@ -297,6 +306,7 @@ int q_OBJ_ln2nid(const char *s);
int q_i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *obj);
int q_OBJ_obj2txt(char *buf, int buf_len, ASN1_OBJECT *obj, int no_name);
int q_OBJ_obj2nid(const ASN1_OBJECT *a);
+#define q_EVP_get_digestbynid(a) q_EVP_get_digestbyname(q_OBJ_nid2sn(a))
#ifdef SSLEAY_MACROS
// ### verify
void *q_PEM_ASN1_read_bio(d2i_of_void *a, const char *b, BIO *c, void **d, pem_password_cb *e,
@@ -314,6 +324,8 @@ int q_PEM_write_bio_DSAPrivateKey(BIO *a, DSA *b, const EVP_CIPHER *c, unsigned
int e, pem_password_cb *f, void *g);
int q_PEM_write_bio_RSAPrivateKey(BIO *a, RSA *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
+int q_PEM_write_bio_PrivateKey(BIO *a, EVP_PKEY *b, const EVP_CIPHER *c, unsigned char *d,
+ int e, pem_password_cb *f, void *g);
#ifndef OPENSSL_NO_EC
int q_PEM_write_bio_ECPrivateKey(BIO *a, EC_KEY *b, const EVP_CIPHER *c, unsigned char *d,
int e, pem_password_cb *f, void *g);
@@ -327,6 +339,7 @@ EC_KEY *q_PEM_read_bio_EC_PUBKEY(BIO *a, EC_KEY **b, pem_password_cb *c, void *d
#endif
int q_PEM_write_bio_DSA_PUBKEY(BIO *a, DSA *b);
int q_PEM_write_bio_RSA_PUBKEY(BIO *a, RSA *b);
+int q_PEM_write_bio_PUBKEY(BIO *a, EVP_PKEY *b);
#ifndef OPENSSL_NO_EC
int q_PEM_write_bio_EC_PUBKEY(BIO *a, EC_KEY *b);
#endif
@@ -344,15 +357,15 @@ int q_SSL_connect(SSL *a);
int q_SSL_CTX_check_private_key(const SSL_CTX *a);
long q_SSL_CTX_ctrl(SSL_CTX *a, int b, long c, void *d);
void q_SSL_CTX_free(SSL_CTX *a);
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
SSL_CTX *q_SSL_CTX_new(const SSL_METHOD *a);
-#else
-SSL_CTX *q_SSL_CTX_new(SSL_METHOD *a);
-#endif
int q_SSL_CTX_set_cipher_list(SSL_CTX *a, const char *b);
int q_SSL_CTX_set_default_verify_paths(SSL_CTX *a);
void q_SSL_CTX_set_verify(SSL_CTX *a, int b, int (*c)(int, X509_STORE_CTX *));
void q_SSL_CTX_set_verify_depth(SSL_CTX *a, int b);
+extern "C" {
+typedef void (*GenericCallbackType)();
+}
+long q_SSL_CTX_callback_ctrl(SSL_CTX *, int, GenericCallbackType);
int q_SSL_CTX_use_certificate(SSL_CTX *a, X509 *b);
int q_SSL_CTX_use_certificate_file(SSL_CTX *a, const char *b, int c);
int q_SSL_CTX_use_PrivateKey(SSL_CTX *a, EVP_PKEY *b);
@@ -369,17 +382,14 @@ int q_SSL_CONF_cmd(SSL_CONF_CTX *a, const char *b, const char *c);
#endif
void q_SSL_free(SSL *a);
STACK_OF(SSL_CIPHER) *q_SSL_get_ciphers(const SSL *a);
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
-#else
-SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
-#endif
int q_SSL_version(const SSL *a);
int q_SSL_get_error(SSL *a, int b);
STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a);
X509 *q_SSL_get_peer_certificate(SSL *a);
long q_SSL_get_verify_result(const SSL *a);
SSL *q_SSL_new(SSL_CTX *a);
+SSL_CTX *q_SSL_get_SSL_CTX(SSL *a);
long q_SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg);
int q_SSL_read(SSL *a, void *b, int c);
void q_SSL_set_bio(SSL *a, BIO *b, BIO *c);
@@ -414,7 +424,9 @@ X509 *q_X509_dup(X509 *a);
void q_X509_print(BIO *a, X509*b);
int q_X509_digest(const X509 *x509, const EVP_MD *type, unsigned char *md, unsigned int *len);
ASN1_OBJECT *q_X509_EXTENSION_get_object(X509_EXTENSION *a);
-void q_X509_free(X509 *a);
+Q_AUTOTEST_EXPORT void q_X509_free(X509 *a);
+Q_AUTOTEST_EXPORT ASN1_TIME *q_X509_gmtime_adj(ASN1_TIME *s, long adj);
+Q_AUTOTEST_EXPORT void q_ASN1_TIME_free(ASN1_TIME *t);
X509_EXTENSION *q_X509_get_ext(X509 *a, int b);
int q_X509_get_ext_count(X509 *a);
void *q_X509_get_ext_d2i(X509 *a, int b, int *c, int *d);
@@ -424,11 +436,7 @@ int q_X509_EXTENSION_get_critical(X509_EXTENSION *a);
ASN1_OCTET_STRING *q_X509_EXTENSION_get_data(X509_EXTENSION *a);
void q_BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a);
void q_AUTHORITY_KEYID_free(AUTHORITY_KEYID *a);
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
int q_ASN1_STRING_print(BIO *a, const ASN1_STRING *b);
-#else
-int q_ASN1_STRING_print(BIO *a, ASN1_STRING *b);
-#endif
int q_X509_check_issued(X509 *a, X509 *b);
X509_NAME *q_X509_get_issuer_name(X509 *a);
X509_NAME *q_X509_get_subject_name(X509 *a);
@@ -571,6 +579,57 @@ int q_BIO_set_ex_data(BIO *b, int idx, void *data);
class QDateTime;
QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime);
+#ifndef OPENSSL_NO_TLSEXT
+
+#define q_SSL_set_tlsext_status_type(ssl, type) \
+ q_SSL_ctrl((ssl), SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE, (type), nullptr)
+
+#endif // OPENSSL_NO_TLSEXT
+
+#if QT_CONFIG(ocsp)
+
+OCSP_RESPONSE *q_d2i_OCSP_RESPONSE(OCSP_RESPONSE **a, const unsigned char **in, long len);
+Q_AUTOTEST_EXPORT int q_i2d_OCSP_RESPONSE(OCSP_RESPONSE *r, unsigned char **ppout);
+Q_AUTOTEST_EXPORT OCSP_RESPONSE *q_OCSP_response_create(int status, OCSP_BASICRESP *bs);
+Q_AUTOTEST_EXPORT void q_OCSP_RESPONSE_free(OCSP_RESPONSE *rs);
+int q_OCSP_response_status(OCSP_RESPONSE *resp);
+OCSP_BASICRESP *q_OCSP_response_get1_basic(OCSP_RESPONSE *resp);
+Q_AUTOTEST_EXPORT OCSP_SINGLERESP *q_OCSP_basic_add1_status(OCSP_BASICRESP *rsp, OCSP_CERTID *cid,
+ int status, int reason, ASN1_TIME *revtime,
+ ASN1_TIME *thisupd, ASN1_TIME *nextupd);
+Q_AUTOTEST_EXPORT int q_OCSP_basic_sign(OCSP_BASICRESP *brsp, X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
+ STACK_OF(X509) *certs, unsigned long flags);
+Q_AUTOTEST_EXPORT OCSP_BASICRESP *q_OCSP_BASICRESP_new();
+Q_AUTOTEST_EXPORT void q_OCSP_BASICRESP_free(OCSP_BASICRESP *bs);
+int q_OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags);
+int q_OCSP_resp_count(OCSP_BASICRESP *bs);
+OCSP_SINGLERESP *q_OCSP_resp_get0(OCSP_BASICRESP *bs, int idx);
+int q_OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, ASN1_GENERALIZEDTIME **revtime,
+ ASN1_GENERALIZEDTIME **thisupd, ASN1_GENERALIZEDTIME **nextupd);
+int q_OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec);
+int q_OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, ASN1_OCTET_STRING **pikeyHash,
+ ASN1_INTEGER **pserial, OCSP_CERTID *cid);
+
+const STACK_OF(X509) *q_OCSP_resp_get0_certs(const OCSP_BASICRESP *bs);
+Q_AUTOTEST_EXPORT OCSP_CERTID *q_OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
+Q_AUTOTEST_EXPORT void q_OCSP_CERTID_free(OCSP_CERTID *cid);
+int q_OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+
+#define q_SSL_get_tlsext_status_ocsp_resp(ssl, arg) \
+ q_SSL_ctrl(ssl, SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP, 0, arg)
+
+#define q_SSL_CTX_set_tlsext_status_cb(ssl, cb) \
+ q_SSL_CTX_callback_ctrl(ssl, SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB, GenericCallbackType(cb))
+
+# define q_SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \
+ q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP, arglen, arg)
+
+#endif // ocsp
+
+
+void *q_CRYPTO_malloc(size_t num, const char *file, int line);
+#define q_OPENSSL_malloc(num) q_CRYPTO_malloc(num, "", 0)
+
QT_END_NAMESPACE
#endif
diff --git a/src/network/ssl/qsslsocket_opensslpre11.cpp b/src/network/ssl/qsslsocket_opensslpre11.cpp
index bc4fd9dc85..f5aab821ea 100644
--- a/src/network/ssl/qsslsocket_opensslpre11.cpp
+++ b/src/network/ssl/qsslsocket_opensslpre11.cpp
@@ -251,21 +251,7 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
#if QT_CONFIG(library)
//load symbols needed to receive certificates from system store
-#if defined(Q_OS_WIN)
- HINSTANCE hLib = LoadLibraryW(L"Crypt32");
- if (hLib) {
- ptrCertOpenSystemStoreW = reinterpret_cast<PtrCertOpenSystemStoreW>(
- reinterpret_cast<QFunctionPointer>(GetProcAddress(hLib, "CertOpenSystemStoreW")));
- ptrCertFindCertificateInStore = reinterpret_cast<PtrCertFindCertificateInStore>(
- reinterpret_cast<QFunctionPointer>(GetProcAddress(hLib, "CertFindCertificateInStore")));
- ptrCertCloseStore = reinterpret_cast<PtrCertCloseStore>(
- reinterpret_cast<QFunctionPointer>(GetProcAddress(hLib, "CertCloseStore")));
- if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore)
- qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen
- } else {
- qCWarning(lcSsl, "could not load crypt32 library"); // should never happen
- }
-#elif defined(Q_OS_QNX)
+#if defined(Q_OS_QNX)
s_loadRootCertsOnDemand = true;
#elif defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
// check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
index b7bac5d2a2..46b6505346 100644
--- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
@@ -89,9 +89,7 @@ void q_ERR_free_strings();
void q_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
void q_EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
typedef _STACK STACK;
-#endif
// The typedef we use to make our pre 1.1 code look more like 1.1 (less ifdefs).
typedef STACK OPENSSL_STACK;
@@ -111,22 +109,13 @@ void q_sk_free(STACK *a);
// address of this:
#define q_OPENSSL_sk_free q_sk_free
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
void *q_sk_value(STACK *a, int b);
void q_sk_push(STACK *st, void *data);
-#else
-char *q_sk_value(STACK *a, int b);
-void q_sk_push(STACK *st, char *data);
-#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
#define q_OPENSSL_sk_value(a, b) q_sk_value(a, b)
#define q_OPENSSL_sk_push(st, data) q_sk_push(st, data)
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
SSL_CTX *q_SSL_CTX_new(const SSL_METHOD *a);
-#else
-SSL_CTX *q_SSL_CTX_new(SSL_METHOD *a);
-#endif
int q_SSL_library_init();
void q_SSL_load_error_strings();
@@ -135,49 +124,14 @@ void q_SSL_load_error_strings();
int q_SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
#endif
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-#ifndef OPENSSL_NO_SSL2
-const SSL_METHOD *q_SSLv2_client_method();
-#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
-const SSL_METHOD *q_SSLv3_client_method();
-#endif
const SSL_METHOD *q_SSLv23_client_method();
const SSL_METHOD *q_TLSv1_client_method();
const SSL_METHOD *q_TLSv1_1_client_method();
const SSL_METHOD *q_TLSv1_2_client_method();
-#ifndef OPENSSL_NO_SSL2
-const SSL_METHOD *q_SSLv2_server_method();
-#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
-const SSL_METHOD *q_SSLv3_server_method();
-#endif
const SSL_METHOD *q_SSLv23_server_method();
const SSL_METHOD *q_TLSv1_server_method();
const SSL_METHOD *q_TLSv1_1_server_method();
const SSL_METHOD *q_TLSv1_2_server_method();
-#else
-#ifndef OPENSSL_NO_SSL2
-SSL_METHOD *q_SSLv2_client_method();
-#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
-SSL_METHOD *q_SSLv3_client_method();
-#endif
-SSL_METHOD *q_SSLv23_client_method();
-SSL_METHOD *q_TLSv1_client_method();
-SSL_METHOD *q_TLSv1_1_client_method();
-SSL_METHOD *q_TLSv1_2_client_method();
-#ifndef OPENSSL_NO_SSL2
-SSL_METHOD *q_SSLv2_server_method();
-#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
-SSL_METHOD *q_SSLv3_server_method();
-#endif
-SSL_METHOD *q_SSLv23_server_method();
-SSL_METHOD *q_TLSv1_server_method();
-SSL_METHOD *q_TLSv1_1_server_method();
-SSL_METHOD *q_TLSv1_2_server_method();
-#endif
STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
@@ -218,6 +172,7 @@ DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
#define q_SSL_SESSION_get_ticket_lifetime_hint(s) ((s)->tlsext_tick_lifetime_hint)
#define q_RSA_bits(rsa) q_BN_num_bits((rsa)->n)
#define q_DSA_bits(dsa) q_BN_num_bits((dsa)->p)
+#define q_DH_bits(dsa) q_BN_num_bits((dh)->p)
#define q_X509_STORE_set_verify_cb(s,c) X509_STORE_set_verify_cb_func((s),(c))
char *q_CONF_get1_default_config_file();
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 6f34c6c888..daa9be23f4 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -58,6 +58,7 @@
#include <private/qtcpsocket_p.h>
#include "qsslkey.h"
#include "qsslconfiguration_p.h"
+#include "qocspresponse.h"
#ifndef QT_NO_OPENSSL
#include <private/qsslcontext_openssl_p.h>
#else
@@ -65,7 +66,7 @@ class QSslContext;
#endif
#include <QtCore/qstringlist.h>
-
+#include <QtCore/qvector.h>
#include <private/qringbuffer_p.h>
#if defined(Q_OS_MAC)
@@ -89,14 +90,6 @@ QT_BEGIN_NAMESPACE
typedef OSStatus (*PtrSecTrustCopyAnchorCertificates)(CFArrayRef*);
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- typedef HCERTSTORE (WINAPI *PtrCertOpenSystemStoreW)(HCRYPTPROV_LEGACY, LPCWSTR);
- typedef PCCERT_CONTEXT (WINAPI *PtrCertFindCertificateInStore)(HCERTSTORE, DWORD, DWORD, DWORD, const void*, PCCERT_CONTEXT);
- typedef BOOL (WINAPI *PtrCertCloseStore)(HCERTSTORE, DWORD);
-#endif // Q_OS_WIN && !Q_OS_WINRT
-
-
-
class QSslSocketPrivate : public QTcpSocketPrivate
{
Q_DECLARE_PUBLIC(QSslSocket)
@@ -105,6 +98,7 @@ public:
virtual ~QSslSocketPrivate();
void init();
+ bool verifyProtocolSupported(const char *where);
bool initialized;
QSslSocket::SslMode mode;
@@ -155,12 +149,6 @@ public:
const QString &peerName);
Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname);
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- static PtrCertOpenSystemStoreW ptrCertOpenSystemStoreW;
- static PtrCertFindCertificateInStore ptrCertFindCertificateInStore;
- static PtrCertCloseStore ptrCertCloseStore;
-#endif // Q_OS_WIN && !Q_OS_WINRT
-
// The socket itself, including private slots.
QTcpSocket *plainSocket;
void createPlainSocket(QIODevice::OpenMode openMode);
@@ -184,7 +172,7 @@ public:
void _q_flushWriteBuffer();
void _q_flushReadBuffer();
void _q_resumeImplementation();
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !QT_CONFIG(schannel)
virtual void _q_caRootLoaded(QSslCertificate,QSslCertificate) = 0;
#endif
@@ -220,8 +208,14 @@ protected:
bool verifyErrorsHaveBeenIgnored();
bool paused;
bool flushTriggered;
+ QVector<QOcspResponse> ocspResponses;
};
+#if QT_CONFIG(securetransport) || QT_CONFIG(schannel)
+// Implemented in qsslsocket_qt.cpp
+QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase);
+#endif
+
QT_END_NAMESPACE
#endif
diff --git a/src/network/ssl/qsslsocket_qt.cpp b/src/network/ssl/qsslsocket_qt.cpp
new file mode 100644
index 0000000000..b0fb60ea76
--- /dev/null
+++ b/src/network/ssl/qsslsocket_qt.cpp
@@ -0,0 +1,307 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jeremy Lainé <jeremy.laine@m4x.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtCore/qbytearray.h>
+#include <QtCore/qdatastream.h>
+#include <QtCore/qmessageauthenticationcode.h>
+
+#include "qsslsocket_p.h"
+#include "qasn1element_p.h"
+#include "qsslkey_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*
+ PKCS12 helpers.
+*/
+
+static QAsn1Element wrap(quint8 type, const QAsn1Element &child)
+{
+ QByteArray value;
+ QDataStream stream(&value, QIODevice::WriteOnly);
+ child.write(stream);
+ return QAsn1Element(type, value);
+}
+
+static QAsn1Element _q_PKCS7_data(const QByteArray &data)
+{
+ QVector<QAsn1Element> items;
+ items << QAsn1Element::fromObjectId("1.2.840.113549.1.7.1");
+ items << wrap(QAsn1Element::Context0Type,
+ QAsn1Element(QAsn1Element::OctetStringType, data));
+ return QAsn1Element::fromVector(items);
+}
+
+/*!
+ PKCS #12 key derivation.
+
+ Some test vectors:
+ http://www.drh-consultancy.demon.co.uk/test.txt
+*/
+static QByteArray _q_PKCS12_keygen(char id, const QByteArray &salt, const QString &passPhrase, int n, int r)
+{
+ const int u = 20;
+ const int v = 64;
+
+ // password formatting
+ QByteArray passUnicode(passPhrase.size() * 2 + 2, '\0');
+ char *p = passUnicode.data();
+ for (int i = 0; i < passPhrase.size(); ++i) {
+ quint16 ch = passPhrase[i].unicode();
+ *(p++) = (ch & 0xff00) >> 8;
+ *(p++) = (ch & 0xff);
+ }
+
+ // prepare I
+ QByteArray D(64, id);
+ QByteArray S, P;
+ const int sSize = v * ((salt.size() + v - 1) / v);
+ S.resize(sSize);
+ for (int i = 0; i < sSize; ++i)
+ S[i] = salt[i % salt.size()];
+ const int pSize = v * ((passUnicode.size() + v - 1) / v);
+ P.resize(pSize);
+ for (int i = 0; i < pSize; ++i)
+ P[i] = passUnicode[i % passUnicode.size()];
+ QByteArray I = S + P;
+
+ // apply hashing
+ const int c = (n + u - 1) / u;
+ QByteArray A;
+ QByteArray B;
+ B.resize(v);
+ QCryptographicHash hash(QCryptographicHash::Sha1);
+ for (int i = 0; i < c; ++i) {
+ // hash r iterations
+ QByteArray Ai = D + I;
+ for (int j = 0; j < r; ++j) {
+ hash.reset();
+ hash.addData(Ai);
+ Ai = hash.result();
+ }
+
+ for (int j = 0; j < v; ++j)
+ B[j] = Ai[j % u];
+
+ // modify I as Ij = (Ij + B + 1) modulo 2^v
+ for (int p = 0; p < I.size(); p += v) {
+ quint8 carry = 1;
+ for (int j = v - 1; j >= 0; --j) {
+ quint16 v = quint8(I[p + j]) + quint8(B[j]) + carry;
+ I[p + j] = v & 0xff;
+ carry = (v & 0xff00) >> 8;
+ }
+ }
+ A += Ai;
+ }
+ return A.left(n);
+}
+
+static QByteArray _q_PKCS12_salt()
+{
+ QByteArray salt;
+ salt.resize(8);
+ for (int i = 0; i < salt.size(); ++i)
+ salt[i] = (qrand() & 0xff);
+ return salt;
+}
+
+static QByteArray _q_PKCS12_certBag(const QSslCertificate &cert)
+{
+ QVector<QAsn1Element> items;
+ items << QAsn1Element::fromObjectId("1.2.840.113549.1.12.10.1.3");
+
+ // certificate
+ QVector<QAsn1Element> certItems;
+ certItems << QAsn1Element::fromObjectId("1.2.840.113549.1.9.22.1");
+ certItems << wrap(QAsn1Element::Context0Type,
+ QAsn1Element(QAsn1Element::OctetStringType, cert.toDer()));
+ items << wrap(QAsn1Element::Context0Type,
+ QAsn1Element::fromVector(certItems));
+
+ // local key id
+ const QByteArray localKeyId = cert.digest(QCryptographicHash::Sha1);
+ QVector<QAsn1Element> idItems;
+ idItems << QAsn1Element::fromObjectId("1.2.840.113549.1.9.21");
+ idItems << wrap(QAsn1Element::SetType,
+ QAsn1Element(QAsn1Element::OctetStringType, localKeyId));
+ items << wrap(QAsn1Element::SetType, QAsn1Element::fromVector(idItems));
+
+ // dump
+ QAsn1Element root = wrap(QAsn1Element::SequenceType, QAsn1Element::fromVector(items));
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ root.write(stream);
+ return ba;
+}
+
+static QAsn1Element _q_PKCS12_key(const QSslKey &key)
+{
+ Q_ASSERT(key.algorithm() == QSsl::Rsa || key.algorithm() == QSsl::Dsa);
+
+ QVector<QAsn1Element> keyItems;
+ keyItems << QAsn1Element::fromInteger(0);
+ QVector<QAsn1Element> algoItems;
+ if (key.algorithm() == QSsl::Rsa)
+ algoItems << QAsn1Element::fromObjectId(RSA_ENCRYPTION_OID);
+ else if (key.algorithm() == QSsl::Dsa)
+ algoItems << QAsn1Element::fromObjectId(DSA_ENCRYPTION_OID);
+ algoItems << QAsn1Element(QAsn1Element::NullType);
+ keyItems << QAsn1Element::fromVector(algoItems);
+ keyItems << QAsn1Element(QAsn1Element::OctetStringType, key.toDer());
+ return QAsn1Element::fromVector(keyItems);
+}
+
+static QByteArray _q_PKCS12_shroudedKeyBag(const QSslKey &key, const QString &passPhrase, const QByteArray &localKeyId)
+{
+ const int iterations = 2048;
+ QByteArray salt = _q_PKCS12_salt();
+ QByteArray cKey = _q_PKCS12_keygen(1, salt, passPhrase, 24, iterations);
+ QByteArray cIv = _q_PKCS12_keygen(2, salt, passPhrase, 8, iterations);
+
+ // prepare and encrypt data
+ QByteArray plain;
+ QDataStream plainStream(&plain, QIODevice::WriteOnly);
+ _q_PKCS12_key(key).write(plainStream);
+ QByteArray crypted = QSslKeyPrivate::encrypt(QSslKeyPrivate::DesEde3Cbc,
+ plain, cKey, cIv);
+
+ QVector<QAsn1Element> items;
+ items << QAsn1Element::fromObjectId("1.2.840.113549.1.12.10.1.2");
+
+ // key
+ QVector<QAsn1Element> keyItems;
+ QVector<QAsn1Element> algoItems;
+ algoItems << QAsn1Element::fromObjectId("1.2.840.113549.1.12.1.3");
+ QVector<QAsn1Element> paramItems;
+ paramItems << QAsn1Element(QAsn1Element::OctetStringType, salt);
+ paramItems << QAsn1Element::fromInteger(iterations);
+ algoItems << QAsn1Element::fromVector(paramItems);
+ keyItems << QAsn1Element::fromVector(algoItems);
+ keyItems << QAsn1Element(QAsn1Element::OctetStringType, crypted);
+ items << wrap(QAsn1Element::Context0Type,
+ QAsn1Element::fromVector(keyItems));
+
+ // local key id
+ QVector<QAsn1Element> idItems;
+ idItems << QAsn1Element::fromObjectId("1.2.840.113549.1.9.21");
+ idItems << wrap(QAsn1Element::SetType,
+ QAsn1Element(QAsn1Element::OctetStringType, localKeyId));
+ items << wrap(QAsn1Element::SetType,
+ QAsn1Element::fromVector(idItems));
+
+ // dump
+ QAsn1Element root = wrap(QAsn1Element::SequenceType, QAsn1Element::fromVector(items));
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ root.write(stream);
+ return ba;
+}
+
+static QByteArray _q_PKCS12_bag(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase)
+{
+ QVector<QAsn1Element> items;
+
+ // certs
+ for (int i = 0; i < certs.size(); ++i)
+ items << _q_PKCS7_data(_q_PKCS12_certBag(certs[i]));
+
+ // key
+ if (!key.isNull()) {
+ const QByteArray localKeyId = certs.first().digest(QCryptographicHash::Sha1);
+ items << _q_PKCS7_data(_q_PKCS12_shroudedKeyBag(key, passPhrase, localKeyId));
+ }
+
+ // dump
+ QAsn1Element root = QAsn1Element::fromVector(items);
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ root.write(stream);
+ return ba;
+}
+
+static QAsn1Element _q_PKCS12_mac(const QByteArray &data, const QString &passPhrase)
+{
+ const int iterations = 2048;
+
+ // salt generation
+ QByteArray macSalt = _q_PKCS12_salt();
+ QByteArray key = _q_PKCS12_keygen(3, macSalt, passPhrase, 20, iterations);
+
+ // HMAC calculation
+ QMessageAuthenticationCode hmac(QCryptographicHash::Sha1, key);
+ hmac.addData(data);
+
+ QVector<QAsn1Element> algoItems;
+ algoItems << QAsn1Element::fromObjectId("1.3.14.3.2.26");
+ algoItems << QAsn1Element(QAsn1Element::NullType);
+
+ QVector<QAsn1Element> digestItems;
+ digestItems << QAsn1Element::fromVector(algoItems);
+ digestItems << QAsn1Element(QAsn1Element::OctetStringType, hmac.result());
+
+ QVector<QAsn1Element> macItems;
+ macItems << QAsn1Element::fromVector(digestItems);
+ macItems << QAsn1Element(QAsn1Element::OctetStringType, macSalt);
+ macItems << QAsn1Element::fromInteger(iterations);
+ return QAsn1Element::fromVector(macItems);
+}
+
+QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase)
+{
+ QVector<QAsn1Element> items;
+
+ // version
+ items << QAsn1Element::fromInteger(3);
+
+ // auth safe
+ const QByteArray data = _q_PKCS12_bag(certs, key, passPhrase);
+ items << _q_PKCS7_data(data);
+
+ // HMAC
+ items << _q_PKCS12_mac(data, passPhrase);
+
+ // dump
+ QAsn1Element root = QAsn1Element::fromVector(items);
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ root.write(stream);
+ return ba;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp
new file mode 100644
index 0000000000..1314b432a4
--- /dev/null
+++ b/src/network/ssl/qsslsocket_schannel.cpp
@@ -0,0 +1,1994 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// #define QSSLSOCKET_DEBUG
+
+#include "qssl_p.h"
+#include "qsslsocket.h"
+#include "qsslsocket_schannel_p.h"
+#include "qsslcertificate.h"
+#include "qsslcertificateextension.h"
+#include "qsslcertificate_p.h"
+#include "qsslcipher_p.h"
+
+#include <QtCore/qscopeguard.h>
+#include <QtCore/qoperatingsystemversion.h>
+#include <QtCore/qregularexpression.h>
+#include <QtCore/qdatastream.h>
+#include <QtCore/qmutex.h>
+
+#define SECURITY_WIN32
+#include <security.h>
+#include <schnlsp.h>
+
+#if NTDDI_VERSION >= NTDDI_WINBLUE && !defined(Q_CC_MINGW)
+// ALPN = Application Layer Protocol Negotiation
+#define SUPPORTS_ALPN 1
+#endif
+
+// Not defined in MinGW
+#ifndef SECBUFFER_ALERT
+#define SECBUFFER_ALERT 17
+#endif
+#ifndef SECPKG_ATTR_APPLICATION_PROTOCOL
+#define SECPKG_ATTR_APPLICATION_PROTOCOL 35
+#endif
+
+// Another missing MinGW define
+#ifndef SEC_E_APPLICATION_PROTOCOL_MISMATCH
+#define SEC_E_APPLICATION_PROTOCOL_MISMATCH _HRESULT_TYPEDEF_(0x80090367L)
+#endif
+
+// Also not defined in MinGW.......
+#ifndef SP_PROT_TLS1_SERVER
+#define SP_PROT_TLS1_SERVER 0x00000040
+#endif
+#ifndef SP_PROT_TLS1_CLIENT
+#define SP_PROT_TLS1_CLIENT 0x00000080
+#endif
+#ifndef SP_PROT_TLS1_0_SERVER
+#define SP_PROT_TLS1_0_SERVER SP_PROT_TLS1_SERVER
+#endif
+#ifndef SP_PROT_TLS1_0_CLIENT
+#define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT
+#endif
+#ifndef SP_PROT_TLS1_0
+#define SP_PROT_TLS1_0 (SP_PROT_TLS1_0_CLIENT | SP_PROT_TLS1_0_SERVER)
+#endif
+#ifndef SP_PROT_TLS1_1_SERVER
+#define SP_PROT_TLS1_1_SERVER 0x00000100
+#endif
+#ifndef SP_PROT_TLS1_1_CLIENT
+#define SP_PROT_TLS1_1_CLIENT 0x00000200
+#endif
+#ifndef SP_PROT_TLS1_1
+#define SP_PROT_TLS1_1 (SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_1_SERVER)
+#endif
+#ifndef SP_PROT_TLS1_2_SERVER
+#define SP_PROT_TLS1_2_SERVER 0x00000400
+#endif
+#ifndef SP_PROT_TLS1_2_CLIENT
+#define SP_PROT_TLS1_2_CLIENT 0x00000800
+#endif
+#ifndef SP_PROT_TLS1_2
+#define SP_PROT_TLS1_2 (SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_2_SERVER)
+#endif
+#ifndef SP_PROT_TLS1_3_SERVER
+#define SP_PROT_TLS1_3_SERVER 0x00001000
+#endif
+#ifndef SP_PROT_TLS1_3_CLIENT
+#define SP_PROT_TLS1_3_CLIENT 0x00002000
+#endif
+#ifndef SP_PROT_TLS1_3
+#define SP_PROT_TLS1_3 (SP_PROT_TLS1_3_CLIENT | SP_PROT_TLS1_3_SERVER)
+#endif
+
+/*
+ @future!:
+
+ - Transmitting intermediate certificates
+ - Look for a way to avoid putting intermediate certificates in the certificate store
+ - No documentation on how to send the chain
+ - A stackoverflow question on this from 3 years ago implies schannel only sends intermediate
+ certificates if it's "in the system or user certificate store".
+ - https://stackoverflow.com/q/30156584/2493610
+ - This can be done by users, but we shouldn't add any and all local intermediate
+ certs to the stores automatically.
+ - PSK support
+ - Was added in Windows 10 (it seems), documentation at time of writing is sparse/non-existent.
+ - Specifically about how to supply credentials when they're requested.
+ - Or how to recognize that they're requested in the first place.
+ - Skip certificate verification.
+ - Check if "PSK-only" is still required to do PSK _at all_ (all-around bad solution).
+ - Check if SEC_I_INCOMPLETE_CREDENTIALS is still returned for both "missing certificate" and
+ "missing PSK" when calling InitializeSecurityContext in "performHandshake".
+
+ Medium priority:
+ - Setting cipher-suites (or ALG_ID)
+ - People have survived without it in WinRT
+
+ Low priority:
+ - Possibly make RAII wrappers for SecBuffer (which I commonly create QScopeGuards for)
+
+*/
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+SecBuffer createSecBuffer(void *ptr, unsigned long length, unsigned long bufferType)
+{
+ return SecBuffer{ length, bufferType, ptr };
+}
+
+SecBuffer createSecBuffer(QByteArray &buffer, unsigned long bufferType)
+{
+ return createSecBuffer(buffer.data(), static_cast<unsigned long>(buffer.length()), bufferType);
+}
+
+QString schannelErrorToString(qint32 status)
+{
+ switch (status) {
+ case SEC_E_INSUFFICIENT_MEMORY:
+ return QSslSocket::tr("Insufficient memory");
+ case SEC_E_INTERNAL_ERROR:
+ return QSslSocket::tr("Internal error");
+ case SEC_E_INVALID_HANDLE:
+ return QSslSocket::tr("An internal handle was invalid");
+ case SEC_E_INVALID_TOKEN:
+ return QSslSocket::tr("An internal token was invalid");
+ case SEC_E_LOGON_DENIED:
+ // According to the link below we get this error when Schannel receives TLS1_ALERT_ACCESS_DENIED
+ // https://docs.microsoft.com/en-us/windows/desktop/secauthn/schannel-error-codes-for-tls-and-ssl-alerts
+ return QSslSocket::tr("Access denied");
+ case SEC_E_NO_AUTHENTICATING_AUTHORITY:
+ return QSslSocket::tr("No authority could be contacted for authorization");
+ case SEC_E_NO_CREDENTIALS:
+ return QSslSocket::tr("No credentials");
+ case SEC_E_TARGET_UNKNOWN:
+ return QSslSocket::tr("The target is unknown or unreachable");
+ case SEC_E_UNSUPPORTED_FUNCTION:
+ return QSslSocket::tr("An unsupported function was requested");
+ case SEC_E_WRONG_PRINCIPAL:
+ // SNI error
+ return QSslSocket::tr("The hostname provided does not match the one received from the peer");
+ case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
+ return QSslSocket::tr("No common protocol exists between the client and the server");
+ case SEC_E_ILLEGAL_MESSAGE:
+ return QSslSocket::tr("Unexpected or badly-formatted message received");
+ case SEC_E_ENCRYPT_FAILURE:
+ return QSslSocket::tr("The data could not be encrypted");
+ case SEC_E_ALGORITHM_MISMATCH:
+ return QSslSocket::tr("No cipher suites in common");
+ case SEC_E_UNKNOWN_CREDENTIALS:
+ // This can mean "invalid argument" in some cases...
+ return QSslSocket::tr("The credentials were not recognized / Invalid argument");
+ case SEC_E_MESSAGE_ALTERED:
+ // According to the Internet it also triggers for messages that are out of order.
+ // https://microsoft.public.platformsdk.security.narkive.com/4JAvlMvD/help-please-schannel-security-contexts-and-decryptmessage
+ return QSslSocket::tr("The message was tampered with, damaged or out of sequence.");
+ case SEC_E_OUT_OF_SEQUENCE:
+ return QSslSocket::tr("A message was received out of sequence.");
+ case SEC_E_CONTEXT_EXPIRED:
+ return QSslSocket::tr("The TLS/SSL connection has been closed");
+ default:
+ return QSslSocket::tr("Unknown error occurred: %1").arg(status);
+ }
+}
+
+DWORD toSchannelProtocol(QSsl::SslProtocol protocol)
+{
+ DWORD protocols = SP_PROT_NONE;
+ switch (protocol) {
+ case QSsl::UnknownProtocol:
+ return DWORD(-1);
+ case QSsl::DtlsV1_0:
+ case QSsl::DtlsV1_2:
+ case QSsl::DtlsV1_0OrLater:
+ case QSsl::DtlsV1_2OrLater:
+ return DWORD(-1); // Not supported at the moment (@future)
+ case QSsl::AnyProtocol:
+ protocols = SP_PROT_TLS1_0 | SP_PROT_TLS1_1 | SP_PROT_TLS1_2;
+ // @future Add TLS 1.3 when supported by Windows!
+ break;
+ case QSsl::SslV2:
+ case QSsl::SslV3:
+ return DWORD(-1); // Not supported
+ case QSsl::TlsV1SslV3:
+ protocols = SP_PROT_TLS1_0;
+ break;
+ case QSsl::TlsV1_0:
+ protocols = SP_PROT_TLS1_0;
+ break;
+ case QSsl::TlsV1_1:
+ protocols = SP_PROT_TLS1_1;
+ break;
+ case QSsl::TlsV1_2:
+ protocols = SP_PROT_TLS1_2;
+ break;
+ case QSsl::TlsV1_3:
+ if ((false)) // @future[0/1] Replace with version check once it's supported in Windows
+ protocols = SP_PROT_TLS1_3;
+ else
+ protocols = DWORD(-1);
+ break;
+ case QSsl::SecureProtocols: // TLS v1.0 and later is currently considered secure
+ case QSsl::TlsV1_0OrLater:
+ // For the "OrLater" protocols we fall through from one to the next, adding all of them
+ // in ascending order
+ protocols = SP_PROT_TLS1_0;
+ Q_FALLTHROUGH();
+ case QSsl::TlsV1_1OrLater:
+ protocols |= SP_PROT_TLS1_1;
+ Q_FALLTHROUGH();
+ case QSsl::TlsV1_2OrLater:
+ protocols |= SP_PROT_TLS1_2;
+ Q_FALLTHROUGH();
+ case QSsl::TlsV1_3OrLater:
+ if ((false)) // @future[1/1] Also replace this with a version check
+ protocols |= SP_PROT_TLS1_3;
+ else if (protocol == QSsl::TlsV1_3OrLater)
+ protocols = DWORD(-1); // if TlsV1_3OrLater was specifically chosen we should fail
+ break;
+ }
+ return protocols;
+}
+
+/*!
+ \internal
+ Used when converting the established session's \a protocol back to
+ Qt's own SslProtocol type.
+
+ Only one protocol should be passed in at a time.
+*/
+QSsl::SslProtocol toQtSslProtocol(DWORD protocol)
+{
+#define MAP_PROTOCOL(sp_protocol, q_protocol) \
+ if (protocol & sp_protocol) { \
+ Q_ASSERT(!(protocol & ~sp_protocol)); \
+ return q_protocol; \
+ }
+
+ MAP_PROTOCOL(SP_PROT_TLS1_0, QSsl::TlsV1_0)
+ MAP_PROTOCOL(SP_PROT_TLS1_1, QSsl::TlsV1_1)
+ MAP_PROTOCOL(SP_PROT_TLS1_2, QSsl::TlsV1_2)
+ MAP_PROTOCOL(SP_PROT_TLS1_3, QSsl::TlsV1_3)
+#undef MAP_PROTOCOL
+ Q_UNREACHABLE();
+ return QSsl::UnknownProtocol;
+}
+
+/*!
+ \internal
+ Used by verifyCertContext to check if a client cert is used by a server or vice versa.
+*/
+bool netscapeWrongCertType(const QList<QSslCertificateExtension> &extensions, bool isClient)
+{
+ const auto netscapeIt = std::find_if(
+ extensions.cbegin(), extensions.cend(),
+ [](const QSslCertificateExtension &extension) {
+ const auto netscapeCertType = QStringLiteral("2.16.840.1.113730.1.1");
+ return extension.oid() == netscapeCertType;
+ });
+ if (netscapeIt != extensions.cend()) {
+ const QByteArray netscapeCertTypeByte = netscapeIt->value().toByteArray();
+ int netscapeCertType = 0;
+ QDataStream dataStream(netscapeCertTypeByte);
+ dataStream >> netscapeCertType;
+ if (dataStream.status() != QDataStream::Status::Ok)
+ return true;
+ const int expectedPeerCertType = isClient ? NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE
+ : NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE;
+ if ((netscapeCertType & expectedPeerCertType) == 0)
+ return true;
+ }
+ return false;
+}
+
+/*!
+ \internal
+ Used by verifyCertContext to check the basicConstraints certificate
+ extension to see if the certificate is a certificate authority.
+ Returns false if the certificate does not have the basicConstraints
+ extension or if it is not a certificate authority.
+*/
+bool isCertificateAuthority(const QList<QSslCertificateExtension> &extensions)
+{
+ auto it = std::find_if(extensions.cbegin(), extensions.cend(),
+ [](const QSslCertificateExtension &extension) {
+ return extension.name() == QLatin1String("basicConstraints");
+ });
+ if (it != extensions.cend()) {
+ QVariantMap basicConstraints = it->value().toMap();
+ return basicConstraints.value(QLatin1String("ca"), false).toBool();
+ }
+ return false;
+}
+
+/*!
+ \internal
+ Returns true if the attributes we requested from the context/handshake have
+ been given.
+*/
+bool matchesContextRequirements(DWORD attributes, DWORD requirements,
+ QSslSocket::PeerVerifyMode verifyMode,
+ bool isClient)
+{
+#ifdef QSSLSOCKET_DEBUG
+#define DEBUG_WARN(message) qCWarning(lcSsl, message)
+#else
+#define DEBUG_WARN(message)
+#endif
+
+#define CHECK_ATTRIBUTE(attributeName) \
+ do { \
+ const DWORD req##attributeName = isClient ? ISC_REQ_##attributeName : ASC_REQ_##attributeName; \
+ const DWORD ret##attributeName = isClient ? ISC_RET_##attributeName : ASC_RET_##attributeName; \
+ if (!(requirements & req##attributeName) != !(attributes & ret##attributeName)) { \
+ DEBUG_WARN("Missing attribute \"" #attributeName "\""); \
+ return false; \
+ } \
+ } while (false)
+
+ CHECK_ATTRIBUTE(CONFIDENTIALITY);
+ CHECK_ATTRIBUTE(REPLAY_DETECT);
+ CHECK_ATTRIBUTE(SEQUENCE_DETECT);
+ CHECK_ATTRIBUTE(STREAM);
+ if (verifyMode == QSslSocket::PeerVerifyMode::VerifyPeer)
+ CHECK_ATTRIBUTE(MUTUAL_AUTH);
+
+ // This one is manual because there is no server / ASC_ version
+ if (isClient) {
+ const auto reqManualCredValidation = ISC_REQ_MANUAL_CRED_VALIDATION;
+ const auto retManualCredValidation = ISC_RET_MANUAL_CRED_VALIDATION;
+ if (!(requirements & reqManualCredValidation) != !(attributes & retManualCredValidation)) {
+ DEBUG_WARN("Missing attribute \"MANUAL_CRED_VALIDATION\"");
+ return false;
+ }
+ }
+
+ return true;
+#undef CHECK_ATTRIBUTE
+#undef DEBUG_WARN
+}
+
+template<typename Required, typename Actual>
+Required const_reinterpret_cast(Actual *p)
+{
+ return Required(p);
+}
+
+#ifdef SUPPORTS_ALPN
+bool supportsAlpn()
+{
+ return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8_1;
+}
+
+QByteArray createAlpnString(const QByteArrayList &nextAllowedProtocols)
+{
+ QByteArray alpnString;
+ if (!nextAllowedProtocols.isEmpty() && supportsAlpn()) {
+ const QByteArray names = [&nextAllowedProtocols]() {
+ QByteArray protocolString;
+ for (QByteArray proto : nextAllowedProtocols) {
+ if (proto.size() > 255) {
+ qCWarning(lcSsl) << "TLS ALPN extension" << proto
+ << "is too long and will be truncated to 255 characters.";
+ proto = proto.left(255);
+ }
+ protocolString += char(proto.length()) + proto;
+ }
+ return protocolString;
+ }();
+
+ const quint16 namesSize = names.size();
+ const quint32 alpnId = SecApplicationProtocolNegotiationExt_ALPN;
+ const quint32 totalSize = sizeof(alpnId) + sizeof(namesSize) + namesSize;
+ alpnString = QByteArray::fromRawData(reinterpret_cast<const char *>(&totalSize), sizeof(totalSize))
+ + QByteArray::fromRawData(reinterpret_cast<const char *>(&alpnId), sizeof(alpnId))
+ + QByteArray::fromRawData(reinterpret_cast<const char *>(&namesSize), sizeof(namesSize))
+ + names;
+ }
+ return alpnString;
+}
+#endif // SUPPORTS_ALPN
+} // anonymous namespace
+
+bool QSslSocketPrivate::s_loadRootCertsOnDemand = true;
+bool QSslSocketPrivate::s_loadedCiphersAndCerts = false;
+Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_schannel_mutex, (QMutex::Recursive))
+
+void QSslSocketPrivate::ensureInitialized()
+{
+ const QMutexLocker locker(qt_schannel_mutex);
+ if (s_loadedCiphersAndCerts)
+ return;
+ s_loadedCiphersAndCerts = true;
+
+ setDefaultCaCertificates(systemCaCertificates());
+ s_loadRootCertsOnDemand = true; // setDefaultCaCertificates sets it to false, re-enable it.
+
+ resetDefaultCiphers();
+}
+
+void QSslSocketPrivate::resetDefaultCiphers()
+{
+ setDefaultSupportedCiphers(QSslSocketBackendPrivate::defaultCiphers());
+ setDefaultCiphers(QSslSocketBackendPrivate::defaultCiphers());
+}
+
+void QSslSocketPrivate::resetDefaultEllipticCurves()
+{
+ Q_UNIMPLEMENTED();
+}
+
+bool QSslSocketPrivate::supportsSsl()
+{
+ return true;
+}
+
+QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
+{
+ // Copied from qsslsocket_openssl.cpp's systemCaCertificates function.
+ QList<QSslCertificate> systemCerts;
+ auto hSystemStore = QHCertStorePointer(CertOpenSystemStore(0, L"ROOT"));
+ if (hSystemStore) {
+ PCCERT_CONTEXT pc = nullptr;
+ while ((pc = CertFindCertificateInStore(hSystemStore.get(), X509_ASN_ENCODING, 0,
+ CERT_FIND_ANY, nullptr, pc))) {
+ systemCerts.append(QSslCertificatePrivate::QSslCertificate_from_CERT_CONTEXT(pc));
+ }
+ }
+ return systemCerts;
+}
+
+long QSslSocketPrivate::sslLibraryVersionNumber()
+{
+ const auto os = QOperatingSystemVersion::current();
+ return (os.majorVersion() << 24) | ((os.minorVersion() & 0xFF) << 16) | (os.microVersion() & 0xFFFF);
+}
+
+QString QSslSocketPrivate::sslLibraryVersionString()
+{
+ const auto os = QOperatingSystemVersion::current();
+ return QString::fromLatin1("Secure Channel, %1 %2.%3.%4")
+ .arg(os.name(),
+ QString::number(os.majorVersion()),
+ QString::number(os.minorVersion()),
+ QString::number(os.microVersion()));
+}
+
+long QSslSocketPrivate::sslLibraryBuildVersionNumber()
+{
+ // There is no separate build version
+ return sslLibraryVersionNumber();
+}
+
+QString QSslSocketPrivate::sslLibraryBuildVersionString()
+{
+ const auto os = QOperatingSystemVersion::current();
+ return QString::fromLatin1("%1.%2.%3")
+ .arg(QString::number(os.majorVersion()),
+ QString::number(os.minorVersion()),
+ QString::number(os.microVersion()));
+}
+
+QSslSocketBackendPrivate::QSslSocketBackendPrivate()
+{
+ SecInvalidateHandle(&credentialHandle);
+ SecInvalidateHandle(&contextHandle);
+ ensureInitialized();
+}
+
+QSslSocketBackendPrivate::~QSslSocketBackendPrivate()
+{
+ closeCertificateStores();
+ deallocateContext();
+ freeCredentialsHandle();
+ CertFreeCertificateContext(localCertContext);
+}
+
+bool QSslSocketBackendPrivate::sendToken(void *token, unsigned long tokenLength, bool emitError)
+{
+ if (tokenLength == 0)
+ return true;
+ const qint64 written = plainSocket->write(static_cast<const char *>(token), tokenLength);
+ if (written != qint64(tokenLength)) {
+ // Failed to write/buffer everything or an error occurred
+ if (emitError)
+ setErrorAndEmit(plainSocket->error(), plainSocket->errorString());
+ return false;
+ }
+ return true;
+}
+
+QString QSslSocketBackendPrivate::targetName() const
+{
+ // Used for SNI extension
+ return verificationPeerName.isEmpty() ? q_func()->peerName() : verificationPeerName;
+}
+
+ULONG QSslSocketBackendPrivate::getContextRequirements()
+{
+ const bool isClient = mode == QSslSocket::SslClientMode;
+ ULONG req = 0;
+
+ req |= ISC_REQ_ALLOCATE_MEMORY; // Allocate memory for buffers automatically
+ req |= ISC_REQ_CONFIDENTIALITY; // Encrypt messages
+ req |= ISC_REQ_REPLAY_DETECT; // Detect replayed messages
+ req |= ISC_REQ_SEQUENCE_DETECT; // Detect out of sequence messages
+ req |= ISC_REQ_STREAM; // Support a stream-oriented connection
+
+ if (isClient) {
+ req |= ISC_REQ_MANUAL_CRED_VALIDATION; // Manually validate certificate
+ } else {
+ switch (configuration.peerVerifyMode) {
+ case QSslSocket::PeerVerifyMode::VerifyNone:
+ // There doesn't seem to be a way to ask for an optional client cert :-(
+ case QSslSocket::PeerVerifyMode::AutoVerifyPeer:
+ case QSslSocket::PeerVerifyMode::QueryPeer:
+ break;
+ case QSslSocket::PeerVerifyMode::VerifyPeer:
+ req |= ISC_REQ_MUTUAL_AUTH;
+ break;
+ }
+ }
+
+ return req;
+}
+
+bool QSslSocketBackendPrivate::acquireCredentialsHandle()
+{
+ Q_ASSERT(schannelState == SchannelState::InitializeHandshake);
+
+ const bool isClient = mode == QSslSocket::SslClientMode;
+ const DWORD protocols = toSchannelProtocol(configuration.protocol);
+ if (protocols == DWORD(-1)) {
+ setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
+ QSslSocket::tr("Invalid protocol chosen"));
+ return false;
+ }
+
+ const CERT_CHAIN_CONTEXT *chainContext = nullptr;
+ auto freeCertChain = qScopeGuard([&chainContext]() {
+ if (chainContext)
+ CertFreeCertificateChain(chainContext);
+ });
+
+ DWORD certsCount = 0;
+ // Set up our certificate stores before trying to use one...
+ initializeCertificateStores();
+
+ // Check if user has specified a certificate chain but it could not be loaded.
+ // This happens if there was something wrong with the certificate chain or there was no private
+ // key.
+ if (!configuration.localCertificateChain.isEmpty() && !localCertificateStore)
+ return true; // 'true' because "tst_QSslSocket::setEmptyKey" expects us to not disconnect
+
+ if (localCertificateStore != nullptr) {
+ CERT_CHAIN_FIND_BY_ISSUER_PARA findParam;
+ ZeroMemory(&findParam, sizeof(findParam));
+ findParam.cbSize = sizeof(findParam);
+ findParam.pszUsageIdentifier = isClient ? szOID_PKIX_KP_CLIENT_AUTH : szOID_PKIX_KP_SERVER_AUTH;
+
+ // There should only be one chain in our store, so.. we grab that one.
+ chainContext = CertFindChainInStore(localCertificateStore.get(),
+ X509_ASN_ENCODING,
+ 0,
+ CERT_CHAIN_FIND_BY_ISSUER,
+ &findParam,
+ nullptr);
+ if (!chainContext) {
+ const QString message = isClient
+ ? QSslSocket::tr("The certificate provided cannot be used for a client.")
+ : QSslSocket::tr("The certificate provided cannot be used for a server.");
+ setErrorAndEmit(QAbstractSocket::SocketError::SslInvalidUserDataError, message);
+ return false;
+ }
+ Q_ASSERT(chainContext->cChain == 1);
+ Q_ASSERT(chainContext->rgpChain[0]);
+ Q_ASSERT(chainContext->rgpChain[0]->cbSize >= 1);
+ Q_ASSERT(chainContext->rgpChain[0]->rgpElement[0]);
+ Q_ASSERT(!localCertContext);
+ localCertContext = CertDuplicateCertificateContext(chainContext->rgpChain[0]
+ ->rgpElement[0]
+ ->pCertContext);
+ certsCount = 1;
+ Q_ASSERT(localCertContext);
+ }
+
+ SCHANNEL_CRED cred{
+ SCHANNEL_CRED_VERSION, // dwVersion
+ certsCount, // cCreds
+ &localCertContext, // paCred (certificate(s) containing a private key for authentication)
+ nullptr, // hRootStore
+
+ 0, // cMappers (reserved)
+ nullptr, // aphMappers (reserved)
+
+ 0, // cSupportedAlgs
+ nullptr, // palgSupportedAlgs (nullptr = system default) @future: QSslCipher-related
+
+ protocols, // grbitEnabledProtocols
+ 0, // dwMinimumCipherStrength (0 = system default)
+ 0, // dwMaximumCipherStrength (0 = system default)
+ 0, // dwSessionLifespan (0 = schannel default, 10 hours)
+ SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
+ | SCH_CRED_NO_DEFAULT_CREDS, // dwFlags
+ 0 // dwCredFormat (must be 0)
+ };
+
+ TimeStamp expiration{};
+ auto status = AcquireCredentialsHandle(nullptr, // pszPrincipal (unused)
+ const_cast<wchar_t *>(UNISP_NAME), // pszPackage
+ isClient ? SECPKG_CRED_OUTBOUND : SECPKG_CRED_INBOUND, // fCredentialUse
+ nullptr, // pvLogonID (unused)
+ &cred, // pAuthData
+ nullptr, // pGetKeyFn (unused)
+ nullptr, // pvGetKeyArgument (unused)
+ &credentialHandle, // phCredential
+ &expiration // ptsExpir
+ );
+
+ if (status != SEC_E_OK) {
+ setErrorAndEmit(QAbstractSocket::SslInternalError, schannelErrorToString(status));
+ return false;
+ }
+ return true;
+}
+
+void QSslSocketBackendPrivate::deallocateContext()
+{
+ if (SecIsValidHandle(&contextHandle)) {
+ DeleteSecurityContext(&contextHandle);
+ SecInvalidateHandle(&contextHandle);
+ }
+}
+
+void QSslSocketBackendPrivate::freeCredentialsHandle()
+{
+ if (SecIsValidHandle(&credentialHandle)) {
+ FreeCredentialsHandle(&credentialHandle);
+ SecInvalidateHandle(&credentialHandle);
+ }
+}
+
+void QSslSocketBackendPrivate::closeCertificateStores()
+{
+ localCertificateStore.reset();
+ peerCertificateStore.reset();
+ caCertificateStore.reset();
+}
+
+bool QSslSocketBackendPrivate::createContext()
+{
+ Q_ASSERT(SecIsValidHandle(&credentialHandle));
+ Q_ASSERT(schannelState == SchannelState::InitializeHandshake);
+ Q_ASSERT(mode == QSslSocket::SslClientMode);
+ ULONG contextReq = getContextRequirements();
+
+ SecBuffer outBuffers[3];
+ outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN);
+ outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT);
+ outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
+ auto freeBuffers = qScopeGuard([&outBuffers]() {
+ for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) {
+ if (outBuffers[i].pvBuffer)
+ FreeContextBuffer(outBuffers[i].pvBuffer);
+ }
+ });
+ SecBufferDesc outputBufferDesc{
+ SECBUFFER_VERSION,
+ ARRAYSIZE(outBuffers),
+ outBuffers
+ };
+
+ TimeStamp expiry;
+
+ SecBufferDesc alpnBufferDesc;
+ bool useAlpn = false;
+#ifdef SUPPORTS_ALPN
+ configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNone;
+ QByteArray alpnString = createAlpnString(configuration.nextAllowedProtocols);
+ useAlpn = !alpnString.isEmpty();
+ SecBuffer alpnBuffers[1];
+ alpnBuffers[0] = createSecBuffer(alpnString, SECBUFFER_APPLICATION_PROTOCOLS);
+ alpnBufferDesc = {
+ SECBUFFER_VERSION,
+ ARRAYSIZE(alpnBuffers),
+ alpnBuffers
+ };
+#endif
+
+ auto status = InitializeSecurityContext(&credentialHandle, // phCredential
+ nullptr, // phContext
+ const_reinterpret_cast<SEC_WCHAR *>(targetName().utf16()), // pszTargetName
+ contextReq, // fContextReq
+ 0, // Reserved1
+ 0, // TargetDataRep (unused)
+ useAlpn ? &alpnBufferDesc : nullptr, // pInput
+ 0, // Reserved2
+ &contextHandle, // phNewContext
+ &outputBufferDesc, // pOutput
+ &contextAttributes, // pfContextAttr
+ &expiry // ptsExpiry
+ );
+
+ // This is the first call to InitializeSecurityContext, so theoretically "CONTINUE_NEEDED"
+ // should be the only non-error return-code here.
+ if (status != SEC_I_CONTINUE_NEEDED) {
+ setErrorAndEmit(QAbstractSocket::SslInternalError,
+ QSslSocket::tr("Error creating SSL context (%1)").arg(schannelErrorToString(status)));
+ return false;
+ }
+
+ if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer))
+ return false;
+ schannelState = SchannelState::PerformHandshake;
+ return true;
+}
+
+bool QSslSocketBackendPrivate::acceptContext()
+{
+ Q_ASSERT(SecIsValidHandle(&credentialHandle));
+ Q_ASSERT(schannelState == SchannelState::InitializeHandshake);
+ Q_ASSERT(mode == QSslSocket::SslServerMode);
+ ULONG contextReq = getContextRequirements();
+
+ intermediateBuffer += plainSocket->read(16384);
+ if (intermediateBuffer.isEmpty())
+ return true; // definitely need more data..
+
+ SecBuffer inBuffers[2];
+ inBuffers[0] = createSecBuffer(intermediateBuffer, SECBUFFER_TOKEN);
+
+#ifdef SUPPORTS_ALPN
+ configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNone;
+ // The string must be alive when we call AcceptSecurityContext
+ QByteArray alpnString = createAlpnString(configuration.nextAllowedProtocols);
+ if (!alpnString.isEmpty()) {
+ inBuffers[1] = createSecBuffer(alpnString, SECBUFFER_APPLICATION_PROTOCOLS);
+ } else
+#endif
+ {
+ inBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
+ }
+
+ SecBufferDesc inputBufferDesc{
+ SECBUFFER_VERSION,
+ ARRAYSIZE(inBuffers),
+ inBuffers
+ };
+
+ SecBuffer outBuffers[3];
+ outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN);
+ outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT);
+ outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
+ auto freeBuffers = qScopeGuard([&outBuffers]() {
+ for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) {
+ if (outBuffers[i].pvBuffer)
+ FreeContextBuffer(outBuffers[i].pvBuffer);
+ }
+ });
+ SecBufferDesc outputBufferDesc{
+ SECBUFFER_VERSION,
+ ARRAYSIZE(outBuffers),
+ outBuffers
+ };
+
+ TimeStamp expiry;
+ auto status = AcceptSecurityContext(
+ &credentialHandle, // phCredential
+ nullptr, // phContext
+ &inputBufferDesc, // pInput
+ contextReq, // fContextReq
+ 0, // TargetDataRep (unused)
+ &contextHandle, // phNewContext
+ &outputBufferDesc, // pOutput
+ &contextAttributes, // pfContextAttr
+ &expiry // ptsTimeStamp
+ );
+
+ if (inBuffers[1].BufferType == SECBUFFER_EXTRA) {
+ // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
+ // inBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to
+ // be stored.
+ intermediateBuffer = intermediateBuffer.right(int(inBuffers[1].cbBuffer));
+ } else if (status != SEC_E_INCOMPLETE_MESSAGE) {
+ intermediateBuffer.clear();
+ }
+
+ if (status != SEC_I_CONTINUE_NEEDED) {
+ setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
+ QSslSocket::tr("Error creating SSL context (%1)").arg(schannelErrorToString(status)));
+ return false;
+ }
+ if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer))
+ return false;
+ schannelState = SchannelState::PerformHandshake;
+ return true;
+}
+
+bool QSslSocketBackendPrivate::performHandshake()
+{
+ if (plainSocket->state() == QAbstractSocket::UnconnectedState) {
+ setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
+ QSslSocket::tr("The TLS/SSL connection has been closed"));
+ return false;
+ }
+ Q_ASSERT(SecIsValidHandle(&credentialHandle));
+ Q_ASSERT(SecIsValidHandle(&contextHandle));
+ Q_ASSERT(schannelState == SchannelState::PerformHandshake);
+
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "Bytes available from socket:" << plainSocket->bytesAvailable();
+ qCDebug(lcSsl) << "intermediateBuffer size:" << intermediateBuffer.size();
+#endif
+
+ intermediateBuffer += plainSocket->read(16384);
+ if (intermediateBuffer.isEmpty())
+ return true; // no data, will fail
+
+ SecBuffer inputBuffers[2];
+ inputBuffers[0] = createSecBuffer(intermediateBuffer, SECBUFFER_TOKEN);
+ inputBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
+ SecBufferDesc inputBufferDesc{
+ SECBUFFER_VERSION,
+ ARRAYSIZE(inputBuffers),
+ inputBuffers
+ };
+
+ SecBuffer outBuffers[3];
+ outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN);
+ outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT);
+ outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
+ auto freeBuffers = qScopeGuard([&outBuffers]() {
+ for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) {
+ if (outBuffers[i].pvBuffer)
+ FreeContextBuffer(outBuffers[i].pvBuffer);
+ }
+ });
+ SecBufferDesc outputBufferDesc{
+ SECBUFFER_VERSION,
+ ARRAYSIZE(outBuffers),
+ outBuffers
+ };
+
+ ULONG contextReq = getContextRequirements();
+ TimeStamp expiry;
+ auto status = InitializeSecurityContext(&credentialHandle, // phCredential
+ &contextHandle, // phContext
+ const_reinterpret_cast<SEC_WCHAR *>(targetName().utf16()), // pszTargetName
+ contextReq, // fContextReq
+ 0, // Reserved1
+ 0, // TargetDataRep (unused)
+ &inputBufferDesc, // pInput
+ 0, // Reserved2
+ nullptr, // phNewContext (we already have one)
+ &outputBufferDesc, // pOutput
+ &contextAttributes, // pfContextAttr
+ &expiry // ptsExpiry
+ );
+
+ if (inputBuffers[1].BufferType == SECBUFFER_EXTRA) {
+ // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
+ // inputBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to
+ // be stored.
+ intermediateBuffer = intermediateBuffer.right(int(inputBuffers[1].cbBuffer));
+ } else {
+ // Clear the buffer if we weren't asked for more data
+ if (status != SEC_E_INCOMPLETE_MESSAGE)
+ intermediateBuffer.clear();
+ }
+ switch (status) {
+ case SEC_E_OK:
+ // Need to transmit a final token in the handshake if 'cbBuffer' is non-zero.
+ if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer))
+ return false;
+ schannelState = SchannelState::VerifyHandshake;
+ return true;
+ case SEC_I_CONTINUE_NEEDED:
+ if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer))
+ return false;
+ // Must call InitializeSecurityContext again later (done through continueHandshake)
+ return true;
+ case SEC_I_INCOMPLETE_CREDENTIALS:
+ // Schannel takes care of picking certificate to send (other than the one we can specify),
+ // so if we get here then that means we don't have a certificate the server accepts.
+ setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
+ QSslSocket::tr("Server did not accept any certificate we could present."));
+ return false;
+ case SEC_I_CONTEXT_EXPIRED:
+ // "The message sender has finished using the connection and has initiated a shutdown."
+ if (outBuffers[0].BufferType == SECBUFFER_TOKEN) {
+ if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer))
+ return false;
+ }
+ if (!shutdown) { // we did not initiate this
+ setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
+ QSslSocket::tr("The TLS/SSL connection has been closed"));
+ }
+ return true;
+ case SEC_E_INCOMPLETE_MESSAGE:
+ // Simply incomplete, wait for more data
+ return true;
+ case SEC_E_ALGORITHM_MISMATCH:
+ setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
+ QSslSocket::tr("Algorithm mismatch"));
+ shutdown = true; // skip sending the "Shutdown" alert
+ return false;
+ }
+
+ // Note: We can get here if the connection is using TLS 1.2 and the server certificate uses
+ // MD5, which is not allowed in Schannel. This causes an "invalid token" error during handshake.
+ // (If you came here investigating an error: md5 is insecure, update your certificate)
+ setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
+ QSslSocket::tr("Handshake failed: %1").arg(schannelErrorToString(status)));
+ return false;
+}
+
+bool QSslSocketBackendPrivate::verifyHandshake()
+{
+ Q_Q(QSslSocket);
+
+ const bool isClient = mode == QSslSocket::SslClientMode;
+#define CHECK_STATUS(status) \
+ if (status != SEC_E_OK) { \
+ setErrorAndEmit(QAbstractSocket::SslInternalError, \
+ QSslSocket::tr("Failed to query the TLS context: %1") \
+ .arg(schannelErrorToString(status))); \
+ return false; \
+ }
+
+ // Everything is set up, now make sure there's nothing wrong and query some attributes...
+ if (!matchesContextRequirements(contextAttributes, getContextRequirements(),
+ configuration.peerVerifyMode, isClient)) {
+ setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
+ QSslSocket::tr("Did not get the required attributes for the connection."));
+ return false;
+ }
+
+ // Get stream sizes (to know the max size of a message and the size of the header and trailer)
+ auto status = QueryContextAttributes(&contextHandle,
+ SECPKG_ATTR_STREAM_SIZES,
+ &streamSizes);
+ CHECK_STATUS(status);
+
+ // Get session cipher info
+ status = QueryContextAttributes(&contextHandle,
+ SECPKG_ATTR_CONNECTION_INFO,
+ &connectionInfo);
+ CHECK_STATUS(status);
+
+#ifdef SUPPORTS_ALPN
+ if (!configuration.nextAllowedProtocols.isEmpty() && supportsAlpn()) {
+ SecPkgContext_ApplicationProtocol alpn;
+ status = QueryContextAttributes(&contextHandle,
+ SECPKG_ATTR_APPLICATION_PROTOCOL,
+ &alpn);
+ CHECK_STATUS(status);
+ if (alpn.ProtoNegoStatus == SecApplicationProtocolNegotiationStatus_Success) {
+ QByteArray negotiatedProto = QByteArray((const char *)alpn.ProtocolId,
+ alpn.ProtocolIdSize);
+ if (!configuration.nextAllowedProtocols.contains(negotiatedProto)) {
+ setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
+ QSslSocket::tr("Unwanted protocol was negotiated"));
+ return false;
+ }
+ configuration.nextNegotiatedProtocol = negotiatedProto;
+ configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated;
+ } else {
+ configuration.nextNegotiatedProtocol = "";
+ configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationUnsupported;
+ }
+ }
+#endif // supports ALPN
+
+#undef CHECK_STATUS
+
+ // Verify certificate
+ CERT_CONTEXT *certificateContext = nullptr;
+ auto freeCertificate = qScopeGuard([&certificateContext]() {
+ if (certificateContext)
+ CertFreeCertificateContext(certificateContext);
+ });
+ status = QueryContextAttributes(&contextHandle,
+ SECPKG_ATTR_REMOTE_CERT_CONTEXT,
+ &certificateContext);
+
+ // QueryPeer can (currently) not work in Schannel since Schannel itself doesn't have a way to
+ // ask for a certificate and then still be OK if it's not received.
+ // To work around this we don't request a certificate at all for QueryPeer.
+ // For servers AutoVerifyPeer is supposed to be treated the same as QueryPeer.
+ // This means that servers using Schannel will only request client certificate for "VerifyPeer".
+ if ((!isClient && configuration.peerVerifyMode == QSslSocket::PeerVerifyMode::VerifyPeer)
+ || (isClient && configuration.peerVerifyMode != QSslSocket::PeerVerifyMode::VerifyNone
+ && configuration.peerVerifyMode != QSslSocket::PeerVerifyMode::QueryPeer)) {
+ if (status != SEC_E_OK) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "Couldn't retrieve peer certificate, status:"
+ << schannelErrorToString(status);
+#endif
+ const QSslError error{ QSslError::NoPeerCertificate };
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+ }
+
+ // verifyCertContext returns false if the user disconnected while it was checking errors.
+ if (certificateContext && sslErrors.isEmpty() && !verifyCertContext(certificateContext))
+ return false;
+
+ if (!checkSslErrors() || state != QAbstractSocket::ConnectedState) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << __func__ << "was unsuccessful. Paused:" << paused;
+#endif
+ // If we're paused then checkSslErrors returned false, but it's not an error
+ return paused && state == QAbstractSocket::ConnectedState;
+ }
+
+ schannelState = SchannelState::Done;
+ peerCertVerified = true;
+ return true;
+}
+
+bool QSslSocketBackendPrivate::renegotiate()
+{
+ SecBuffer outBuffers[3];
+ outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN);
+ outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT);
+ outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
+ auto freeBuffers = qScopeGuard([&outBuffers]() {
+ for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) {
+ if (outBuffers[i].pvBuffer)
+ FreeContextBuffer(outBuffers[i].pvBuffer);
+ }
+ });
+ SecBufferDesc outputBufferDesc{
+ SECBUFFER_VERSION,
+ ARRAYSIZE(outBuffers),
+ outBuffers
+ };
+
+ ULONG contextReq = getContextRequirements();
+ TimeStamp expiry;
+ SECURITY_STATUS status;
+ if (mode == QSslSocket::SslClientMode) {
+ status = InitializeSecurityContext(&credentialHandle, // phCredential
+ &contextHandle, // phContext
+ const_reinterpret_cast<SEC_WCHAR *>(targetName().utf16()), // pszTargetName
+ contextReq, // fContextReq
+ 0, // Reserved1
+ 0, // TargetDataRep (unused)
+ nullptr, // pInput (nullptr for renegotiate)
+ 0, // Reserved2
+ nullptr, // phNewContext (we already have one)
+ &outputBufferDesc, // pOutput
+ &contextAttributes, // pfContextAttr
+ &expiry // ptsExpiry
+ );
+ } else {
+ status = AcceptSecurityContext(
+ &credentialHandle, // phCredential
+ &contextHandle, // phContext
+ nullptr, // pInput
+ contextReq, // fContextReq
+ 0, // TargetDataRep (unused)
+ nullptr, // phNewContext
+ &outputBufferDesc, // pOutput
+ &contextAttributes, // pfContextAttr,
+ &expiry // ptsTimeStamp
+ );
+ }
+ if (status == SEC_I_CONTINUE_NEEDED) {
+ schannelState = SchannelState::PerformHandshake;
+ return sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer);
+ }
+ setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
+ QSslSocket::tr("Renegotiation was unsuccessful: %1").arg(schannelErrorToString(status)));
+ return false;
+}
+
+/*!
+ \internal
+ reset the state in preparation for reuse of socket
+*/
+void QSslSocketBackendPrivate::reset()
+{
+ closeCertificateStores(); // certificate stores could've changed
+ deallocateContext();
+ freeCredentialsHandle(); // in case we already had one (@future: session resumption requires re-use)
+
+ connectionInfo = {};
+ streamSizes = {};
+
+ CertFreeCertificateContext(localCertContext);
+ localCertContext = nullptr;
+
+ contextAttributes = 0;
+ intermediateBuffer.clear();
+ schannelState = SchannelState::InitializeHandshake;
+
+ connectionEncrypted = false;
+ shutdown = false;
+ peerCertVerified = false;
+ renegotiating = false;
+}
+
+void QSslSocketBackendPrivate::startClientEncryption()
+{
+ if (connectionEncrypted)
+ return; // let's not mess up the connection...
+ reset();
+ continueHandshake();
+}
+
+void QSslSocketBackendPrivate::startServerEncryption()
+{
+ if (connectionEncrypted)
+ return; // let's not mess up the connection...
+ reset();
+ continueHandshake();
+}
+
+void QSslSocketBackendPrivate::transmit()
+{
+ Q_Q(QSslSocket);
+
+ // Can happen if called through QSslSocket::abort->QSslSocket::close->QSslSocket::flush->here
+ if (plainSocket->state() == QAbstractSocket::SocketState::UnconnectedState)
+ return;
+
+ if (schannelState != SchannelState::Done) {
+ continueHandshake();
+ return;
+ }
+
+ if (connectionEncrypted) { // encrypt data in writeBuffer and write it to plainSocket
+ qint64 totalBytesWritten = 0;
+ qint64 writeBufferSize;
+ while ((writeBufferSize = writeBuffer.size()) > 0) {
+ const int headerSize = int(streamSizes.cbHeader);
+ const int trailerSize = int(streamSizes.cbTrailer);
+ // Try to read 'cbMaximumMessage' bytes from buffer before encrypting.
+ const int size = int(std::min(writeBufferSize, qint64(streamSizes.cbMaximumMessage)));
+ QByteArray fullMessage(headerSize + trailerSize + size, Qt::Uninitialized);
+ {
+ // Use peek() here instead of read() so we don't lose data if encryption fails.
+ qint64 copied = writeBuffer.peek(fullMessage.data() + headerSize, size);
+ Q_ASSERT(copied == size);
+ }
+
+ SecBuffer inputBuffers[4]{
+ createSecBuffer(fullMessage.data(), headerSize, SECBUFFER_STREAM_HEADER),
+ createSecBuffer(fullMessage.data() + headerSize, size, SECBUFFER_DATA),
+ createSecBuffer(fullMessage.data() + headerSize + size, trailerSize, SECBUFFER_STREAM_TRAILER),
+ createSecBuffer(nullptr, 0, SECBUFFER_EMPTY)
+ };
+ SecBufferDesc message{
+ SECBUFFER_VERSION,
+ ARRAYSIZE(inputBuffers),
+ inputBuffers
+ };
+ auto status = EncryptMessage(&contextHandle, 0, &message, 0);
+ if (status != SEC_E_OK) {
+ setErrorAndEmit(QAbstractSocket::SslInternalError,
+ QSslSocket::tr("Schannel failed to encrypt data: %1")
+ .arg(schannelErrorToString(status)));
+ return;
+ }
+ // Data was encrypted successfully, so we free() what we peek()ed earlier
+ writeBuffer.free(size);
+
+ // The trailer's size is not final, so resize fullMessage to not send trailing junk
+ fullMessage.resize(inputBuffers[0].cbBuffer + inputBuffers[1].cbBuffer + inputBuffers[2].cbBuffer);
+ const qint64 bytesWritten = plainSocket->write(fullMessage);
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "Wrote" << bytesWritten << "of total"
+ << fullMessage.length() << "bytes";
+#endif
+ if (bytesWritten >= 0) {
+ totalBytesWritten += bytesWritten;
+ } else {
+ setErrorAndEmit(plainSocket->error(), plainSocket->errorString());
+ return;
+ }
+ }
+
+ if (totalBytesWritten > 0) {
+ // Don't emit bytesWritten() recursively.
+ if (!emittedBytesWritten) {
+ emittedBytesWritten = true;
+ emit q->bytesWritten(totalBytesWritten);
+ emittedBytesWritten = false;
+ }
+ emit q->channelBytesWritten(0, totalBytesWritten);
+ }
+ }
+
+ if (connectionEncrypted) { // Decrypt data from remote
+ int totalRead = 0;
+ bool hadIncompleteData = false;
+ while (!readBufferMaxSize || buffer.size() < readBufferMaxSize) {
+ QByteArray ciphertext;
+ if (intermediateBuffer.length()) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "Restoring data from intermediateBuffer:"
+ << intermediateBuffer.length() << "bytes";
+#endif
+ ciphertext.swap(intermediateBuffer);
+ }
+ int initialLength = ciphertext.length();
+ ciphertext += plainSocket->read(16384);
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "Read" << ciphertext.length() - initialLength
+ << "encrypted bytes from the socket";
+#endif
+ if (ciphertext.length() == 0 || (hadIncompleteData && initialLength == ciphertext.length())) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << (hadIncompleteData ? "No new data received, leaving loop!"
+ : "Nothing to decrypt, leaving loop!");
+#endif
+ if (ciphertext.length()) // We have data, it came from intermediateBuffer, swap back
+ intermediateBuffer.swap(ciphertext);
+ break;
+ }
+ hadIncompleteData = false;
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "Total amount of bytes to decrypt:" << ciphertext.length();
+#endif
+
+ SecBuffer dataBuffer[4]{
+ createSecBuffer(ciphertext, SECBUFFER_DATA),
+ createSecBuffer(nullptr, 0, SECBUFFER_EMPTY),
+ createSecBuffer(nullptr, 0, SECBUFFER_EMPTY),
+ createSecBuffer(nullptr, 0, SECBUFFER_EMPTY)
+ };
+ SecBufferDesc message{
+ SECBUFFER_VERSION,
+ ARRAYSIZE(dataBuffer),
+ dataBuffer
+ };
+ auto status = DecryptMessage(&contextHandle, &message, 0, nullptr);
+ if (status == SEC_E_OK || status == SEC_I_RENEGOTIATE || status == SEC_I_CONTEXT_EXPIRED) {
+ // There can still be 0 output even if it succeeds, this is fine
+ if (dataBuffer[1].cbBuffer > 0) {
+ // It is always decrypted in-place.
+ // But [0] is the STREAM_HEADER, [1] is the DATA and [2] is the STREAM_TRAILER.
+ // The pointers in all of those still point into the 'ciphertext' byte array.
+ buffer.append(static_cast<char *>(dataBuffer[1].pvBuffer),
+ dataBuffer[1].cbBuffer);
+ totalRead += dataBuffer[1].cbBuffer;
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "Decrypted" << dataBuffer[1].cbBuffer
+ << "bytes. New read buffer size:" << buffer.size();
+#endif
+ }
+ if (dataBuffer[3].BufferType == SECBUFFER_EXTRA) {
+ // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
+ // dataBuffer[3].cbBuffer indicates the amount of bytes _NOT_ processed,
+ // the rest need to be stored.
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "We've got excess data, moving it to the intermediate buffer:"
+ << dataBuffer[3].cbBuffer << "bytes";
+#endif
+ intermediateBuffer = ciphertext.right(int(dataBuffer[3].cbBuffer));
+ }
+ } else if (status == SEC_E_INCOMPLETE_MESSAGE) {
+ // Need more data before we can decrypt.. to the buffer it goes!
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl, "We didn't have enough data to decrypt anything, will try again!");
+#endif
+ Q_ASSERT(intermediateBuffer.isEmpty());
+ intermediateBuffer.swap(ciphertext);
+ // We try again, but if we don't get any more data then we leave
+ hadIncompleteData = true;
+ } else if (status == SEC_E_INVALID_HANDLE) {
+ // I don't think this should happen, if it does we're done...
+ qCWarning(lcSsl, "The internal SSPI handle is invalid!");
+ Q_UNREACHABLE();
+ } else if (status == SEC_E_INVALID_TOKEN) {
+ qCWarning(lcSsl, "Got SEC_E_INVALID_TOKEN!");
+ Q_UNREACHABLE(); // Happened once due to a bug, but shouldn't generally happen(?)
+ } else if (status == SEC_E_MESSAGE_ALTERED) {
+ // The message has been altered, disconnect now.
+ shutdown = true; // skips sending the shutdown alert
+ disconnectFromHost();
+ setErrorAndEmit(QAbstractSocket::SslInternalError,
+ schannelErrorToString(status));
+ break;
+ } else if (status == SEC_E_OUT_OF_SEQUENCE) {
+ // @todo: I don't know if this one is actually "fatal"..
+ // This path might never be hit as it seems this is for connection-oriented connections,
+ // while SEC_E_MESSAGE_ALTERED is for stream-oriented ones (what we use).
+ shutdown = true; // skips sending the shutdown alert
+ disconnectFromHost();
+ setErrorAndEmit(QAbstractSocket::SslInternalError,
+ schannelErrorToString(status));
+ break;
+ } else if (status == SEC_I_CONTEXT_EXPIRED) {
+ // 'remote' has initiated a shutdown
+ disconnectFromHost();
+ setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
+ schannelErrorToString(status));
+ break;
+ } else if (status == SEC_I_RENEGOTIATE) {
+ // 'remote' wants to renegotiate
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl, "The peer wants to renegotiate.");
+#endif
+ schannelState = SchannelState::Renegotiate;
+ renegotiating = true;
+ // We need to call 'continueHandshake' or else there's no guarantee it ever gets called
+ continueHandshake();
+ break;
+ }
+ }
+
+ if (totalRead) {
+ if (readyReadEmittedPointer)
+ *readyReadEmittedPointer = true;
+ emit q->readyRead();
+ emit q->channelReadyRead(0);
+ }
+ }
+}
+
+void QSslSocketBackendPrivate::sendShutdown()
+{
+ const bool isClient = mode == QSslSocket::SslClientMode;
+ DWORD shutdownToken = SCHANNEL_SHUTDOWN;
+ SecBuffer buffer = createSecBuffer(&shutdownToken, sizeof(SCHANNEL_SHUTDOWN), SECBUFFER_TOKEN);
+ SecBufferDesc token{
+ SECBUFFER_VERSION,
+ 1,
+ &buffer
+ };
+ auto status = ApplyControlToken(&contextHandle, &token);
+
+ if (status != SEC_E_OK) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "Failed to apply shutdown control token:" << schannelErrorToString(status);
+#endif
+ return;
+ }
+
+ SecBuffer outBuffers[3];
+ outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN);
+ outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT);
+ outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
+ auto freeBuffers = qScopeGuard([&outBuffers]() {
+ for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) {
+ if (outBuffers[i].pvBuffer)
+ FreeContextBuffer(outBuffers[i].pvBuffer);
+ }
+ });
+ SecBufferDesc outputBufferDesc{
+ SECBUFFER_VERSION,
+ ARRAYSIZE(outBuffers),
+ outBuffers
+ };
+
+ ULONG contextReq = getContextRequirements();
+ TimeStamp expiry;
+ if (isClient) {
+ status = InitializeSecurityContext(&credentialHandle, // phCredential
+ &contextHandle, // phContext
+ const_reinterpret_cast<SEC_WCHAR *>(targetName().utf16()), // pszTargetName
+ contextReq, // fContextReq
+ 0, // Reserved1
+ 0, // TargetDataRep (unused)
+ nullptr, // pInput
+ 0, // Reserved2
+ nullptr, // phNewContext (we already have one)
+ &outputBufferDesc, // pOutput
+ &contextAttributes, // pfContextAttr
+ &expiry // ptsExpiry
+ );
+ } else {
+ status = AcceptSecurityContext(
+ &credentialHandle, // phCredential
+ &contextHandle, // phContext
+ nullptr, // pInput
+ contextReq, // fContextReq
+ 0, // TargetDataRep (unused)
+ nullptr, // phNewContext
+ &outputBufferDesc, // pOutput
+ &contextAttributes, // pfContextAttr,
+ &expiry // ptsTimeStamp
+ );
+ }
+ if (status == SEC_E_OK || status == SEC_I_CONTEXT_EXPIRED) {
+ if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, false)) {
+ // We failed to send the shutdown message, but it's not that important since we're
+ // shutting down anyway.
+ return;
+ }
+ } else {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "Failed to initialize shutdown:" << schannelErrorToString(status);
+#endif
+ }
+}
+
+void QSslSocketBackendPrivate::disconnectFromHost()
+{
+ if (SecIsValidHandle(&contextHandle)) {
+ if (!shutdown) {
+ shutdown = true;
+ if (plainSocket->state() != QAbstractSocket::UnconnectedState) {
+ if (connectionEncrypted) {
+ // Read as much as possible because this is likely our last chance
+ qint64 tempMax = readBufferMaxSize;
+ readBufferMaxSize = 0;
+ transmit();
+ readBufferMaxSize = tempMax;
+ sendShutdown();
+ }
+ }
+ }
+ }
+ if (plainSocket->state() != QAbstractSocket::UnconnectedState)
+ plainSocket->disconnectFromHost();
+}
+
+void QSslSocketBackendPrivate::disconnected()
+{
+ shutdown = true;
+ connectionEncrypted = false;
+ deallocateContext();
+ freeCredentialsHandle();
+}
+
+QSslCipher QSslSocketBackendPrivate::sessionCipher() const
+{
+ if (!connectionEncrypted)
+ return QSslCipher();
+ return QSslCipher(QStringLiteral("Schannel"), sessionProtocol());
+}
+
+QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const
+{
+ if (!connectionEncrypted)
+ return QSsl::SslProtocol::UnknownProtocol;
+ return toQtSslProtocol(connectionInfo.dwProtocol);
+}
+
+void QSslSocketBackendPrivate::continueHandshake()
+{
+ Q_Q(QSslSocket);
+ const bool isServer = mode == QSslSocket::SslServerMode;
+ switch (schannelState) {
+ case SchannelState::InitializeHandshake:
+ if (!SecIsValidHandle(&credentialHandle) && !acquireCredentialsHandle()) {
+ disconnectFromHost();
+ return;
+ }
+ if (!SecIsValidHandle(&credentialHandle)) // Needed to support tst_QSslSocket::setEmptyKey
+ return;
+ if (!SecIsValidHandle(&contextHandle) && !(isServer ? acceptContext() : createContext())) {
+ disconnectFromHost();
+ return;
+ }
+ if (schannelState != SchannelState::PerformHandshake)
+ break;
+ Q_FALLTHROUGH();
+ case SchannelState::PerformHandshake:
+ if (!performHandshake()) {
+ disconnectFromHost();
+ return;
+ }
+ if (schannelState != SchannelState::VerifyHandshake)
+ break;
+ Q_FALLTHROUGH();
+ case SchannelState::VerifyHandshake:
+ // if we're in shutdown or renegotiating then we might not need to verify
+ // (since we already did)
+ if (!peerCertVerified && !verifyHandshake()) {
+ shutdown = true; // Skip sending shutdown alert
+ q->abort(); // We don't want to send buffered data
+ disconnectFromHost();
+ return;
+ }
+ if (schannelState != SchannelState::Done)
+ break;
+ Q_FALLTHROUGH();
+ case SchannelState::Done:
+ // connectionEncrypted is already true if we come here from a renegotiation
+ if (!connectionEncrypted) {
+ connectionEncrypted = true; // all is done
+ emit q->encrypted();
+ }
+ renegotiating = false;
+ if (pendingClose) {
+ pendingClose = false;
+ disconnectFromHost();
+ } else {
+ transmit();
+ }
+ break;
+ case SchannelState::Renegotiate:
+ if (!renegotiate()) {
+ disconnectFromHost();
+ return;
+ }
+ break;
+ }
+}
+
+QList<QSslCipher> QSslSocketBackendPrivate::defaultCiphers()
+{
+ QList<QSslCipher> ciphers;
+ // @temp (I hope), stolen from qsslsocket_winrt.cpp
+ const QString protocolStrings[] = { QStringLiteral("TLSv1"), QStringLiteral("TLSv1.1"),
+ QStringLiteral("TLSv1.2"), QStringLiteral("TLSv1.3") };
+ const QSsl::SslProtocol protocols[] = { QSsl::TlsV1_0, QSsl::TlsV1_1,
+ QSsl::TlsV1_2, QSsl::TlsV1_3 };
+ const int size = ARRAYSIZE(protocols);
+ Q_STATIC_ASSERT(size == ARRAYSIZE(protocolStrings));
+ ciphers.reserve(size);
+ for (int i = 0; i < size; ++i) {
+ QSslCipher cipher;
+ cipher.d->isNull = false;
+ cipher.d->name = QStringLiteral("Schannel");
+ cipher.d->protocol = protocols[i];
+ cipher.d->protocolString = protocolStrings[i];
+ ciphers.append(cipher);
+ }
+
+ return ciphers;
+}
+
+QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &certificateChain,
+ const QString &hostName)
+{
+ Q_UNUSED(certificateChain);
+ Q_UNUSED(hostName);
+
+ Q_UNIMPLEMENTED();
+ return {}; // @future implement(?)
+}
+
+bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, QSslKey *key, QSslCertificate *cert,
+ QList<QSslCertificate> *caCertificates,
+ const QByteArray &passPhrase)
+{
+ Q_UNUSED(device);
+ Q_UNUSED(key);
+ Q_UNUSED(cert);
+ Q_UNUSED(caCertificates);
+ Q_UNUSED(passPhrase);
+ // @future: can load into its own certificate store (encountered problems extracting key).
+ Q_UNIMPLEMENTED();
+ return false;
+}
+
+/*
+ Copied from qsslsocket_mac.cpp, which was copied from qsslsocket_openssl.cpp
+*/
+bool QSslSocketBackendPrivate::checkSslErrors()
+{
+ if (sslErrors.isEmpty())
+ return true;
+ Q_Q(QSslSocket);
+
+ emit q->sslErrors(sslErrors);
+
+ const bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer
+ || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer
+ && mode == QSslSocket::SslClientMode);
+ const bool doEmitSslError = !verifyErrorsHaveBeenIgnored();
+ // check whether we need to emit an SSL handshake error
+ if (doVerifyPeer && doEmitSslError) {
+ if (q->pauseMode() & QAbstractSocket::PauseOnSslErrors) {
+ pauseSocketNotifiers(q);
+ paused = true;
+ } else {
+ setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
+ sslErrors.constFirst().errorString());
+ plainSocket->disconnectFromHost();
+ }
+ return false;
+ }
+
+ return true;
+}
+
+void QSslSocketBackendPrivate::initializeCertificateStores()
+{
+ //// helper function which turns a chain into a certificate store
+ auto createStoreFromCertificateChain = [](const QList<QSslCertificate> certChain, const QSslKey &privateKey) {
+ const wchar_t *passphrase = L"";
+ // Need to embed the private key in the certificate
+ QByteArray pkcs12 = _q_makePkcs12(certChain,
+ privateKey,
+ QString::fromWCharArray(passphrase, 0));
+ CRYPT_DATA_BLOB pfxBlob;
+ pfxBlob.cbData = DWORD(pkcs12.length());
+ pfxBlob.pbData = reinterpret_cast<unsigned char *>(pkcs12.data());
+ return QHCertStorePointer(PFXImportCertStore(&pfxBlob, passphrase, 0));
+ };
+
+ if (!configuration.localCertificateChain.isEmpty()) {
+ if (configuration.privateKey.isNull()) {
+ setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
+ QSslSocket::tr("Cannot provide a certificate with no key"));
+ return;
+ }
+ if (localCertificateStore == nullptr) {
+ localCertificateStore = createStoreFromCertificateChain(configuration.localCertificateChain,
+ configuration.privateKey);
+ if (localCertificateStore == nullptr)
+ qCWarning(lcSsl, "Failed to load certificate chain!");
+ }
+ }
+
+ if (!configuration.caCertificates.isEmpty() && !caCertificateStore) {
+ caCertificateStore = createStoreFromCertificateChain(configuration.caCertificates,
+ {}); // No private key for the CA certs
+ }
+}
+
+bool QSslSocketBackendPrivate::verifyCertContext(CERT_CONTEXT *certContext)
+{
+ Q_ASSERT(certContext);
+ Q_Q(QSslSocket);
+
+ const bool isClient = mode == QSslSocket::SslClientMode;
+
+ // Create a collection of stores so we can pass in multiple stores as additional locations to
+ // search for the certificate chain
+ auto tempCertCollection = QHCertStorePointer(CertOpenStore(CERT_STORE_PROV_COLLECTION,
+ X509_ASN_ENCODING,
+ 0,
+ CERT_STORE_CREATE_NEW_FLAG,
+ nullptr));
+ if (!tempCertCollection) {
+#ifdef QSSLSOCKET_DEBUG
+ qCWarning(lcSsl, "Failed to create certificate store collection!");
+#endif
+ return false;
+ }
+
+ if (rootCertOnDemandLoadingAllowed()) {
+ // @future(maybe): following the OpenSSL backend these certificates should be added into
+ // the Ca list, not just included during verification.
+ // That being said, it's not trivial to add the root certificates (if and only if they
+ // came from the system root store). And I don't see this mentioned in our documentation.
+ auto rootStore = QHCertStorePointer(CertOpenSystemStore(0, L"ROOT"));
+ if (!rootStore) {
+#ifdef QSSLSOCKET_DEBUG
+ qCWarning(lcSsl, "Failed to open the system root CA certificate store!");
+#endif
+ return false;
+ } else if (!CertAddStoreToCollection(tempCertCollection.get(), rootStore.get(), 0, 1)) {
+#ifdef QSSLSOCKET_DEBUG
+ qCWarning(lcSsl, "Failed to add the system root CA certificate store to the certificate store collection!");
+#endif
+ return false;
+ }
+ }
+ if (caCertificateStore) {
+ if (!CertAddStoreToCollection(tempCertCollection.get(), caCertificateStore.get(), 0, 1)) {
+#ifdef QSSLSOCKET_DEBUG
+ qCWarning(lcSsl, "Failed to add the user's CA certificate store to the certificate store collection!");
+#endif
+ return false;
+ }
+ }
+
+ if (!CertAddStoreToCollection(tempCertCollection.get(), certContext->hCertStore, 0, 0)) {
+#ifdef QSSLSOCKET_DEBUG
+ qCWarning(lcSsl, "Failed to add certificate's origin store to the certificate store collection!");
+#endif
+ return false;
+ }
+
+ CERT_CHAIN_PARA parameters;
+ ZeroMemory(&parameters, sizeof(parameters));
+ parameters.cbSize = sizeof(CERT_CHAIN_PARA);
+ parameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
+ parameters.RequestedUsage.Usage.cUsageIdentifier = 1;
+ LPSTR oid = LPSTR(isClient ? szOID_PKIX_KP_SERVER_AUTH
+ : szOID_PKIX_KP_CLIENT_AUTH);
+ parameters.RequestedUsage.Usage.rgpszUsageIdentifier = &oid;
+
+ configuration.peerCertificate.clear();
+ configuration.peerCertificateChain.clear();
+ const CERT_CHAIN_CONTEXT *chainContext = nullptr;
+ auto freeCertChain = qScopeGuard([&chainContext]() {
+ if (chainContext)
+ CertFreeCertificateChain(chainContext);
+ });
+ BOOL status = CertGetCertificateChain(nullptr, // hChainEngine, default
+ certContext, // pCertContext
+ nullptr, // pTime, 'now'
+ tempCertCollection.get(), // hAdditionalStore, additional cert store
+ &parameters, // pChainPara
+ CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, // dwFlags
+ nullptr, // reserved
+ &chainContext // ppChainContext
+ );
+ if (status == FALSE || !chainContext || chainContext->cChain == 0) {
+ QSslError error(QSslError::UnableToVerifyFirstCertificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ return q->state() == QAbstractSocket::ConnectedState;
+ }
+
+ // Helper-function to get a QSslCertificate given a CERT_CHAIN_ELEMENT
+ static auto getCertificateFromChainElement = [](CERT_CHAIN_ELEMENT *element) {
+ if (!element)
+ return QSslCertificate();
+
+ const CERT_CONTEXT *certContext = element->pCertContext;
+ return QSslCertificatePrivate::QSslCertificate_from_CERT_CONTEXT(certContext);
+ };
+
+ // Pick a chain to use as the certificate chain, if multiple are available:
+ // According to https://docs.microsoft.com/en-gb/windows/desktop/api/wincrypt/ns-wincrypt-_cert_chain_context
+ // this seems to be the best way to get a trusted chain.
+ CERT_SIMPLE_CHAIN *chain = chainContext->rgpChain[chainContext->cChain - 1];
+
+ if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_PARTIAL_CHAIN) {
+ auto error = QSslError(QSslError::SslError::UnableToGetIssuerCertificate,
+ getCertificateFromChainElement(chain->rgpElement[chain->cElement - 1]));
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+ if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS) {
+ // @Note: This is actually one of two errors:
+ // "either the certificate cannot be used to issue other certificates, or the chain path length has been exceeded."
+ // But here we are checking the chain's status, so we assume the "issuing" error cannot occur here.
+ auto error = QSslError(QSslError::PathLengthExceeded);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+ static const DWORD leftoverCertChainErrorMask = CERT_TRUST_IS_CYCLIC | CERT_TRUST_INVALID_EXTENSION
+ | CERT_TRUST_INVALID_POLICY_CONSTRAINTS | CERT_TRUST_INVALID_NAME_CONSTRAINTS
+ | CERT_TRUST_CTL_IS_NOT_TIME_VALID | CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID
+ | CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE;
+ if (chain->TrustStatus.dwErrorStatus & leftoverCertChainErrorMask) {
+ auto error = QSslError(QSslError::SslError::UnspecifiedError);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+
+ DWORD verifyDepth = chain->cElement;
+ if (configuration.peerVerifyDepth > 0 && DWORD(configuration.peerVerifyDepth) < verifyDepth)
+ verifyDepth = DWORD(configuration.peerVerifyDepth);
+
+ for (DWORD i = 0; i < verifyDepth; i++) {
+ CERT_CHAIN_ELEMENT *element = chain->rgpElement[i];
+ QSslCertificate certificate = getCertificateFromChainElement(element);
+ const QList<QSslCertificateExtension> extensions = certificate.extensions();
+
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "issuer:" << certificate.issuerDisplayName()
+ << "\nsubject:" << certificate.subjectDisplayName()
+ << "\nQSslCertificate info:" << certificate
+ << "\nextended error info:" << element->pwszExtendedErrorInfo
+ << "\nerror status:" << element->TrustStatus.dwErrorStatus;
+#endif
+
+ configuration.peerCertificateChain.append(certificate);
+
+ if (certificate.isBlacklisted()) {
+ const auto error = QSslError(QSslError::CertificateBlacklisted, certificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+
+ LONG result = CertVerifyTimeValidity(nullptr /*== now */, element->pCertContext->pCertInfo);
+ if (result != 0) {
+ auto error = QSslError(result == -1 ? QSslError::CertificateNotYetValid
+ : QSslError::CertificateExpired,
+ certificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+
+ //// Errors
+ if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_TIME_VALID) {
+ // handled right above
+ Q_ASSERT(!sslErrors.isEmpty());
+ }
+ if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_REVOKED) {
+ auto error = QSslError(QSslError::CertificateRevoked, certificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+ if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID) {
+ auto error = QSslError(QSslError::CertificateSignatureFailed, certificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+
+ // While netscape shouldn't be relevant now it defined an extension which is
+ // still in use. Schannel does not check this automatically, so we do it here.
+ // It is used to differentiate between client and server certificates.
+ if (netscapeWrongCertType(extensions, isClient))
+ element->TrustStatus.dwErrorStatus |= CERT_TRUST_IS_NOT_VALID_FOR_USAGE;
+
+ if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) {
+ auto error = QSslError(QSslError::InvalidPurpose, certificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+ if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_UNTRUSTED_ROOT) {
+ // Override this error if we have the certificate inside our trusted CAs list.
+ const bool isTrustedRoot = configuration.caCertificates.contains(certificate);
+ if (!isTrustedRoot) {
+ auto error = QSslError(QSslError::CertificateUntrusted, certificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+ }
+ static const DWORD certRevocationCheckUnavailableError = CERT_TRUST_IS_OFFLINE_REVOCATION
+ | CERT_TRUST_REVOCATION_STATUS_UNKNOWN;
+ if (element->TrustStatus.dwErrorStatus & certRevocationCheckUnavailableError) {
+ // @future(maybe): Do something with this
+ }
+
+ // Dumping ground of errors that don't fit our specific errors
+ static const DWORD leftoverCertErrorMask = CERT_TRUST_IS_CYCLIC
+ | CERT_TRUST_INVALID_EXTENSION | CERT_TRUST_INVALID_NAME_CONSTRAINTS
+ | CERT_TRUST_INVALID_POLICY_CONSTRAINTS
+ | CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT
+ | CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT
+ | CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT
+ | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT
+ | CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT;
+ if (element->TrustStatus.dwErrorStatus & leftoverCertErrorMask) {
+ auto error = QSslError(QSslError::UnspecifiedError, certificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+ if (element->TrustStatus.dwErrorStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS) {
+ auto it = std::find_if(extensions.cbegin(), extensions.cend(),
+ [](const QSslCertificateExtension &extension) {
+ return extension.name() == QLatin1String("basicConstraints");
+ });
+ if (it != extensions.cend()) {
+ // @Note: This is actually one of two errors:
+ // "either the certificate cannot be used to issue other certificates,
+ // or the chain path length has been exceeded."
+ QVariantMap basicConstraints = it->value().toMap();
+ QSslError error;
+ if (i > 0 && !basicConstraints.value(QLatin1String("ca"), false).toBool())
+ error = QSslError(QSslError::InvalidPurpose, certificate);
+ else
+ error = QSslError(QSslError::PathLengthExceeded, certificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+ }
+ if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_EXPLICIT_DISTRUST) {
+ auto error = QSslError(QSslError::CertificateBlacklisted, certificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+
+ if (element->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED) {
+ // If it's self-signed *and* a CA then we can assume it's a root CA certificate
+ // and we can ignore the "self-signed" note:
+ // We check the basicConstraints certificate extension when possible, but this didn't
+ // exist for version 1, so we can only guess in that case
+ const bool isRootCertificateAuthority = isCertificateAuthority(extensions)
+ || certificate.version() == "1";
+
+ // Root certificate tends to be signed by themselves, so ignore self-signed status.
+ if (!isRootCertificateAuthority) {
+ auto error = QSslError(QSslError::SelfSignedCertificate, certificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+ }
+ }
+
+ if (!configuration.peerCertificateChain.isEmpty())
+ configuration.peerCertificate = configuration.peerCertificateChain.first();
+
+ // @Note: Somewhat copied from qsslsocket_mac.cpp
+ const bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer
+ || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer
+ && mode == QSslSocket::SslClientMode);
+ // Check the peer certificate itself. First try the subject's common name
+ // (CN) as a wildcard, then try all alternate subject name DNS entries the
+ // same way.
+ if (!configuration.peerCertificate.isNull()) {
+ // but only if we're a client connecting to a server
+ // if we're the server, don't check CN
+ if (mode == QSslSocket::SslClientMode) {
+ const QString peerName(verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName);
+ if (!isMatchingHostname(configuration.peerCertificate, peerName)) {
+ // No matches in common names or alternate names.
+ const QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+ }
+ } else if (doVerifyPeer) {
+ // No peer certificate presented. Report as error if the socket
+ // expected one.
+ const QSslError error(QSslError::NoPeerCertificate);
+ sslErrors += error;
+ emit q->peerVerifyError(error);
+ if (q->state() != QAbstractSocket::ConnectedState)
+ return false;
+ }
+
+ return true;
+}
+
+bool QSslSocketBackendPrivate::rootCertOnDemandLoadingAllowed()
+{
+ return allowRootCertOnDemandLoading && s_loadRootCertsOnDemand;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslsocket_schannel_p.h b/src/network/ssl/qsslsocket_schannel_p.h
new file mode 100644
index 0000000000..9879e2fc60
--- /dev/null
+++ b/src/network/ssl/qsslsocket_schannel_p.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSSLSOCKET_SCHANNEL_P_H
+#define QSSLSOCKET_SCHANNEL_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.
+//
+
+QT_REQUIRE_CONFIG(schannel);
+
+#include <QtNetwork/private/qtnetworkglobal_p.h>
+
+#include "qsslsocket_p.h"
+
+#define SECURITY_WIN32
+#include <security.h>
+#include <schnlsp.h>
+#undef SECURITY_WIN32
+
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+
+struct QHCertStoreDeleter {
+ void operator()(HCERTSTORE store)
+ {
+ CertCloseStore(store, 0);
+ }
+};
+typedef std::unique_ptr<void, QHCertStoreDeleter> QHCertStorePointer;
+
+class QSslSocketBackendPrivate final : public QSslSocketPrivate
+{
+ Q_DISABLE_COPY_MOVE(QSslSocketBackendPrivate)
+ Q_DECLARE_PUBLIC(QSslSocket)
+public:
+ QSslSocketBackendPrivate();
+ ~QSslSocketBackendPrivate();
+
+ // Platform specific functions
+ void startClientEncryption() override;
+ void startServerEncryption() override;
+ void transmit() override;
+ void disconnectFromHost() override;
+ void disconnected() override;
+ QSslCipher sessionCipher() const override;
+ QSsl::SslProtocol sessionProtocol() const override;
+ void continueHandshake() override;
+
+ static QList<QSslCipher> defaultCiphers();
+ static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain,
+ const QString &hostName);
+ static bool importPkcs12(QIODevice *device, QSslKey *key, QSslCertificate *cert,
+ QList<QSslCertificate> *caCertificates, const QByteArray &passPhrase);
+
+private:
+ enum class SchannelState {
+ InitializeHandshake, // create and transmit context (client)/accept context (server)
+ PerformHandshake, // get token back, process it
+ VerifyHandshake, // Verify that things are OK
+ Done, // Connection encrypted!
+ Renegotiate // Renegotiating!
+ } schannelState = SchannelState::InitializeHandshake;
+
+ void reset();
+ bool acquireCredentialsHandle();
+ ULONG getContextRequirements();
+ bool createContext(); // for clients
+ bool acceptContext(); // for server
+ bool performHandshake();
+ bool verifyHandshake();
+ bool renegotiate();
+
+ bool sendToken(void *token, unsigned long tokenLength, bool emitError = true);
+ QString targetName() const;
+
+ bool checkSslErrors();
+ void deallocateContext();
+ void freeCredentialsHandle();
+ void closeCertificateStores();
+ void sendShutdown();
+
+ void initializeCertificateStores();
+ bool verifyCertContext(CERT_CONTEXT *certContext);
+
+ bool rootCertOnDemandLoadingAllowed();
+
+ SecPkgContext_ConnectionInfo connectionInfo = {};
+ SecPkgContext_StreamSizes streamSizes = {};
+
+ CredHandle credentialHandle; // Initialized in ctor
+ CtxtHandle contextHandle; // Initialized in ctor
+
+ QByteArray intermediateBuffer; // data which is left-over or incomplete
+
+ QHCertStorePointer localCertificateStore = nullptr;
+ QHCertStorePointer peerCertificateStore = nullptr;
+ QHCertStorePointer caCertificateStore = nullptr;
+
+ const CERT_CONTEXT *localCertContext = nullptr;
+
+ ULONG contextAttributes = 0;
+
+ bool renegotiating = false;
+ bool peerCertVerified = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSSLSOCKET_SCHANNEL_P_H
diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp
index cc69b9ac96..d54ac2ad73 100644
--- a/src/network/ssl/qsslsocket_winrt.cpp
+++ b/src/network/ssl/qsslsocket_winrt.cpp
@@ -207,9 +207,9 @@ void QSslSocketPrivate::resetDefaultCiphers()
QList<QSslCipher> QSslSocketBackendPrivate::defaultCiphers()
{
QList<QSslCipher> ciphers;
- const QString protocolStrings[] = { QStringLiteral("SSLv3"), QStringLiteral("TLSv1"),
+ const QString protocolStrings[] = { QStringLiteral("TLSv1"),
QStringLiteral("TLSv1.1"), QStringLiteral("TLSv1.2") };
- const QSsl::SslProtocol protocols[] = { QSsl::SslV3, QSsl::TlsV1_0, QSsl::TlsV1_1, QSsl::TlsV1_2 };
+ const QSsl::SslProtocol protocols[] = { QSsl::TlsV1_0, QSsl::TlsV1_1, QSsl::TlsV1_2 };
const int size = static_cast<int>(ARRAYSIZE(protocols));
ciphers.reserve(size);
for (int i = 0; i < size; ++i) {
@@ -234,10 +234,14 @@ void QSslSocketBackendPrivate::startClientEncryption()
QSsl::SslProtocol protocol = q->protocol();
switch (q->protocol()) {
- case QSsl::AnyProtocol:
+ case QSsl::SslV2:
case QSsl::SslV3:
+ setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
+ QStringLiteral("unsupported protocol"));
+ return;
+ case QSsl::AnyProtocol:
case QSsl::TlsV1SslV3:
- protectionLevel = SocketProtectionLevel_Ssl; // Only use this value if weak cipher support is required
+ protectionLevel = SocketProtectionLevel_Tls10;
break;
case QSsl::TlsV1_0:
protectionLevel = SocketProtectionLevel_Tls10;
diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri
index 6975264038..8bb70a2aed 100644
--- a/src/network/ssl/ssl.pri
+++ b/src/network/ssl/ssl.pri
@@ -29,7 +29,9 @@ qtConfig(ssl) {
ssl/qsslsocket.h \
ssl/qsslsocket_p.h \
ssl/qsslpresharedkeyauthenticator.h \
- ssl/qsslpresharedkeyauthenticator_p.h
+ ssl/qsslpresharedkeyauthenticator_p.h \
+ ssl/qocspresponse.h \
+ ssl/qocspresponse_p.h
SOURCES += ssl/qsslconfiguration.cpp \
ssl/qsslcipher.cpp \
ssl/qssldiffiehellmanparameters.cpp \
@@ -37,7 +39,8 @@ qtConfig(ssl) {
ssl/qsslkey_p.cpp \
ssl/qsslerror.cpp \
ssl/qsslsocket.cpp \
- ssl/qsslpresharedkeyauthenticator.cpp
+ ssl/qsslpresharedkeyauthenticator.cpp \
+ ssl/qocspresponse.cpp
winrt {
HEADERS += ssl/qsslsocket_winrt_p.h
@@ -49,6 +52,19 @@ qtConfig(ssl) {
ssl/qsslellipticcurve_dummy.cpp
}
+ qtConfig(schannel) {
+ HEADERS += ssl/qsslsocket_schannel_p.h
+ SOURCES += ssl/qsslsocket_schannel.cpp \
+ ssl/qsslcertificate_schannel.cpp \
+ ssl/qsslkey_schannel.cpp \
+ ssl/qsslkey_qt.cpp \
+ ssl/qssldiffiehellmanparameters_dummy.cpp \
+ ssl/qsslellipticcurve_dummy.cpp \
+ ssl/qsslsocket_qt.cpp
+
+ LIBS_PRIVATE += "-lSecur32" "-lCrypt32" "-lbcrypt" "-lncrypt"
+ }
+
qtConfig(securetransport) {
HEADERS += ssl/qsslsocket_mac_p.h
SOURCES += ssl/qssldiffiehellmanparameters_dummy.cpp \
@@ -56,6 +72,7 @@ qtConfig(ssl) {
ssl/qsslkey_mac.cpp \
ssl/qsslsocket_mac_shared.cpp \
ssl/qsslsocket_mac.cpp \
+ ssl/qsslsocket_qt.cpp \
ssl/qsslellipticcurve_dummy.cpp
}
@@ -83,6 +100,8 @@ qtConfig(ssl) {
SOURCES += ssl/qdtls_openssl.cpp
}
+ qtConfig(ocsp): HEADERS += ssl/qocsp_p.h
+
qtConfig(opensslv11) {
HEADERS += ssl/qsslsocket_openssl11_symbols_p.h
SOURCES += ssl/qsslsocket_openssl11.cpp \
diff --git a/src/opengl/doc/qtopengl.qdocconf b/src/opengl/doc/qtopengl.qdocconf
index 6ff6cae2cb..2d38a5d2af 100644
--- a/src/opengl/doc/qtopengl.qdocconf
+++ b/src/opengl/doc/qtopengl.qdocconf
@@ -23,6 +23,8 @@ depends += qtdoc qtcore qtgui qtwidgets qmake
examplesinstallpath = opengl
+tagfile = qtopengl.tags
+
# 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
# Qt Assistant and/or Qt Creator.
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index d1ed621790..abf5b8ea48 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -160,7 +160,7 @@ public:
void setTranslateZ(GLfloat z);
private:
- Q_DISABLE_COPY(QGL2PaintEngineEx)
+ Q_DISABLE_COPY_MOVE(QGL2PaintEngineEx)
};
class QGL2PaintEngineExPrivate : public QPaintEngineExPrivate, protected QOpenGLExtensions
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index ba4a1dcaa1..8ef53afaea 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -3880,12 +3880,9 @@ void QGLContext::doneCurrent()
*/
QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFlags f)
- : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
+ : QWidget(*(new QGLWidgetPrivate), parent, f)
{
Q_D(QGLWidget);
- setAttribute(Qt::WA_PaintOnScreen);
- setAttribute(Qt::WA_NoSystemBackground);
- setAutoFillBackground(true); // for compatibility
d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget);
}
@@ -3893,12 +3890,9 @@ QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFl
\internal
*/
QGLWidget::QGLWidget(QGLWidgetPrivate &dd, const QGLFormat &format, QWidget *parent, const QGLWidget *shareWidget, Qt::WindowFlags f)
- : QWidget(dd, parent, f | Qt::MSWindowsOwnDC)
+ : QWidget(dd, parent, f)
{
Q_D(QGLWidget);
- setAttribute(Qt::WA_PaintOnScreen);
- setAttribute(Qt::WA_NoSystemBackground);
- setAutoFillBackground(true); // for compatibility
d->init(new QGLContext(format, this), shareWidget);
}
@@ -3935,12 +3929,9 @@ QGLWidget::QGLWidget(QGLWidgetPrivate &dd, const QGLFormat &format, QWidget *par
QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget* shareWidget,
Qt::WindowFlags f)
- : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
+ : QWidget(*(new QGLWidgetPrivate), parent, f)
{
Q_D(QGLWidget);
- setAttribute(Qt::WA_PaintOnScreen);
- setAttribute(Qt::WA_NoSystemBackground);
- setAutoFillBackground(true); // for compatibility
d->init(new QGLContext(format, this), shareWidget);
}
@@ -3971,12 +3962,9 @@ QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget*
*/
QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, const QGLWidget *shareWidget,
Qt::WindowFlags f)
- : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
+ : QWidget(*(new QGLWidgetPrivate), parent, f)
{
Q_D(QGLWidget);
- setAttribute(Qt::WA_PaintOnScreen);
- setAttribute(Qt::WA_NoSystemBackground);
- setAutoFillBackground(true); // for compatibility
d->init(context, shareWidget);
}
@@ -4131,14 +4119,14 @@ void QGLWidget::swapBuffers()
/*!
\fn const QGLContext* QGLWidget::overlayContext() const
- Returns the overlay context of this widget, or 0 if this widget
- has no overlay.
+ Returns the overlay context of this widget, or \nullptr if this
+ widget has no overlay.
\sa context()
*/
const QGLContext* QGLWidget::overlayContext() const
{
- return 0;
+ return nullptr;
}
/*!
@@ -5169,6 +5157,15 @@ QPaintEngine *QGLWidget::paintEngine() const
void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget)
{
+ Q_Q(QGLWidget);
+ q->setAttribute(Qt::WA_PaintOnScreen);
+ q->setAttribute(Qt::WA_NoSystemBackground);
+ q->setAutoFillBackground(true); // for compatibility
+
+ mustHaveWindowHandle = 1;
+ q->setAttribute(Qt::WA_NativeWindow);
+ q->setWindowFlag(Qt::MSWindowsOwnDC);
+
initContext(context, shareWidget);
}
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index a1ba0485e0..f5accbeb3c 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -51,22 +51,6 @@
#include <QtGui/QSurfaceFormat>
-#if defined(Q_CLANG_QDOC)
-#undef GLint
-typedef int GLint;
-#undef GLuint
-typedef unsigned int GLuint;
-#undef GLenum
-typedef unsigned int GLenum;
-#undef GLclampf
-typedef float GLclampf;
-#undef GLsizei
-typedef int GLsizei;
-#undef GLboolean
-typedef bool GLboolean;
-#endif
-
-
QT_BEGIN_NAMESPACE
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 0b2ddf97fe..b2158ebfaa 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -211,7 +211,7 @@ QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat()
If the desired amount of samples per pixel is not supported by the hardware
then the maximum number of samples per pixel will be used. Note that
- multisample framebuffer objects can not be bound as textures. Also, the
+ multisample framebuffer objects cannot be bound as textures. Also, the
\c{GL_EXT_framebuffer_multisample} extension is required to create a
framebuffer with more than one sample per pixel.
diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp
index 7fe7102510..f22f9f470b 100644
--- a/src/opengl/qglfunctions.cpp
+++ b/src/opengl/qglfunctions.cpp
@@ -170,7 +170,8 @@ QGLFunctions::QGLFunctions()
/*!
Constructs a function resolver for \a context. If \a context
- is null, then the resolver will be created for the current QGLContext.
+ is \nullptr, then the resolver will be created for the current
+ QGLContext.
An object constructed in this way can only be used with \a context
and other contexts that share with it. Use initializeGLFunctions()
@@ -305,7 +306,7 @@ bool QGLFunctions::hasOpenGLFeature(QGLFunctions::OpenGLFeature feature) const
/*!
Initializes GL function resolution for \a context. If \a context
- is null, then the current QGLContext will be used.
+ is \nullptr, then the current QGLContext will be used.
After calling this function, the QGLFunctions object can only be
used with \a context and other contexts that share with it.
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index 545df8fa44..35f60318be 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -3169,7 +3169,8 @@ GLenum QGLShaderProgram::geometryOutputType() const
Language (GLSL) are supported on this system; false otherwise.
The \a context is used to resolve the GLSL extensions.
- If \a context is null, then QGLContext::currentContext() is used.
+ If \a context is \nullptr, then QGLContext::currentContext() is
+ used.
*/
bool QGLShaderProgram::hasOpenGLShaderPrograms(const QGLContext *context)
{
@@ -3207,7 +3208,8 @@ void QGLShaderProgram::shaderDestroyed()
this system; false otherwise.
The \a context is used to resolve the GLSL extensions.
- If \a context is null, then QGLContext::currentContext() is used.
+ If \a context is \nullptr, then QGLContext::currentContext() is
+ used.
\since 4.7
*/
diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h
index dfdef44b54..3ce88197d2 100644
--- a/src/opengl/qglshaderprogram.h
+++ b/src/opengl/qglshaderprogram.h
@@ -46,17 +46,6 @@
#include <QtGui/qvector4d.h>
#include <QtGui/qmatrix4x4.h>
-#if defined(Q_CLANG_QDOC)
-#undef GLfloat
-typedef double GLfloat;
-#undef GLint
-typedef int GLint;
-#undef GLuint
-typedef unsigned int GLuint;
-#undef GLenum
-typedef unsigned int GLenum;
-#endif
-
QT_BEGIN_NAMESPACE
diff --git a/src/opengl/qgraphicsshadereffect_p.h b/src/opengl/qgraphicsshadereffect_p.h
index 9efcecd25f..1a32f24d70 100644
--- a/src/opengl/qgraphicsshadereffect_p.h
+++ b/src/opengl/qgraphicsshadereffect_p.h
@@ -80,7 +80,7 @@ protected:
private:
Q_DECLARE_PRIVATE(QGraphicsShaderEffect)
- Q_DISABLE_COPY(QGraphicsShaderEffect)
+ Q_DISABLE_COPY_MOVE(QGraphicsShaderEffect)
friend class QGLCustomShaderEffectStage;
};
diff --git a/src/platformheaders/doc/qtplatformheaders.qdocconf b/src/platformheaders/doc/qtplatformheaders.qdocconf
index 1ff6fe7a21..9a034e7671 100644
--- a/src/platformheaders/doc/qtplatformheaders.qdocconf
+++ b/src/platformheaders/doc/qtplatformheaders.qdocconf
@@ -35,5 +35,7 @@ sourcedirs += ..
exampledirs += snippets
imagedirs += images
+tagfile = qtplatformheaders.tags
+
navigation.landingpage = "Qt Platform Headers"
navigation.cppclassespage = "Qt Platform Headers C++ Classes"
diff --git a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h
index e51c2fde67..032dcafa6e 100644
--- a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h
+++ b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h
@@ -81,6 +81,15 @@ public:
func(window, border);
}
+ typedef void (*SetHasBorderInFullScreenDefault)(bool border);
+ static const QByteArray setHasBorderInFullScreenDefaultIdentifier() { return QByteArrayLiteral("WindowsSetHasBorderInFullScreenDefault"); }
+ static void setHasBorderInFullScreenDefault(bool border)
+ {
+ auto func = reinterpret_cast<SetHasBorderInFullScreenDefault>(QGuiApplication::platformFunction(setHasBorderInFullScreenDefaultIdentifier()));
+ if (func)
+ func(border);
+ }
+
typedef void (*SetWindowActivationBehaviorType)(WindowActivationBehavior);
static const QByteArray setWindowActivationBehaviorIdentifier() { return QByteArrayLiteral("WindowsSetWindowActivationBehavior"); }
diff --git a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc
index a52bbe061b..0c52cde753 100644
--- a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc
+++ b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc
@@ -93,7 +93,40 @@
is true then it will enable the WS_BORDER flag in full screen mode to enable other top level windows
inside the application to appear on top when required.
+ \note The setting must be applied before showing the window or switching it
+ to full screen. For QML, setHasBorderInFullScreenDefault() can be used to
+ set a default value.
+
+ See also \l [QtDoc] {Fullscreen OpenGL Based Windows}
+*/
+
+/*!
+ \typedef QWindowsWindowFunctions::SetHasBorderInFullScreenDefault
+ \since 5.13
+
+ This is the typedef for the function returned by QGuiApplication::platformFunction
+ when passed setHasBorderInFullScreenDefaultIdentifier.
+*/
+
+/*!
+ \fn QByteArray QWindowsWindowFunctions::setHasBorderInFullScreenDefaultIdentifier()
+ \since 5.13
+
+ This function returns the bytearray that can be used to query
+ QGuiApplication::platformFunction to retrieve the SetHasBorderInFullScreen function.
+*/
+
+/*!
+ \fn void QWindowsWindowFunctions::setHasBorderInFullScreenDefault(bool border)
+ \since 5.13
+
+ This is a convenience function that can be used directly instead of resolving
+ the function pointer. \a border will be relayed to the function retrieved by
+ QGuiApplication. When \a border is true, the WS_BORDER flag will be set
+ in full screen mode for all windows by default.
+
See also \l [QtDoc] {Fullscreen OpenGL Based Windows}
+ \sa setHasBorderInFullScreen()
*/
/*!
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_p.h
index e3c22b0b37..b1ce14b5c3 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_p.h
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_p.h
@@ -96,7 +96,7 @@ signals:
protected:
QDeviceDiscovery(QDeviceTypes types, QObject *parent) : QObject(parent), m_types(types) { }
- Q_DISABLE_COPY(QDeviceDiscovery)
+ Q_DISABLE_COPY_MOVE(QDeviceDiscovery)
QDeviceTypes m_types;
};
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
index 9d8bf07af8..c0e528f922 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -332,14 +332,6 @@ void QEGLPlatformContext::updateFormatFromGL()
QByteArray version = QByteArray(reinterpret_cast<const char *>(s));
int major, minor;
if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor)) {
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- // Some Android 4.2.2 devices report OpenGL ES 3.0 without the functions being available.
- static int apiLevel = QtAndroidPrivate::androidSdkVersion();
- if (apiLevel <= 17 && major >= 3) {
- major = 2;
- minor = 0;
- }
-#endif
m_format.setMajorVersion(major);
m_format.setMinorVersion(minor);
}
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index 04a5026395..381db1ed12 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -1556,7 +1556,7 @@ QFontEngineFT::QGlyphSet *QFontEngineFT::loadGlyphSet(const QTransform &matrix)
gs = &transformedGlyphSets[0];
gs->clear();
gs->transformationMatrix = m;
- gs->outline_drawing = fontDef.pixelSize * fontDef.pixelSize * qAbs(matrix.det()) >= QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE;
+ gs->outline_drawing = fontDef.pixelSize * fontDef.pixelSize * qAbs(matrix.determinant()) > QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE;
}
Q_ASSERT(gs != 0);
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
index bd4338feb8..10df85f68e 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
@@ -1952,13 +1952,13 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, const Q
} else {
HGDIOBJ oldFont = SelectObject(data->hdc, hfont);
+ const QFont::HintingPreference hintingPreference =
+ static_cast<QFont::HintingPreference>(request.hintingPreference);
+ bool useDw = useDirectWrite(hintingPreference, fam);
+
IDWriteFontFace *directWriteFontFace = NULL;
HRESULT hr = data->directWriteGdiInterop->CreateFontFaceFromHdc(data->hdc, &directWriteFontFace);
- if (FAILED(hr)) {
- const QString errorString = qt_error_string(int(hr));
- qWarning().noquote().nospace() << "DirectWrite: CreateFontFaceFromHDC() failed ("
- << errorString << ") for " << request << ' ' << lf << " dpi=" << dpi;
- } else {
+ if (SUCCEEDED(hr)) {
bool isColorFont = false;
#if defined(QT_USE_DIRECTWRITE2)
IDWriteFontFace2 *directWriteFontFace2 = nullptr;
@@ -1968,9 +1968,7 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, const Q
isColorFont = directWriteFontFace2->GetPaletteEntryCount() > 0;
}
#endif
- const QFont::HintingPreference hintingPreference =
- static_cast<QFont::HintingPreference>(request.hintingPreference);
- const bool useDw = useDirectWrite(hintingPreference, fam, isColorFont);
+ useDw = useDw || useDirectWrite(hintingPreference, fam, isColorFont);
qCDebug(lcQpaFonts) << __FUNCTION__ << request.family << request.pointSize
<< "pt" << "hintingPreference=" << hintingPreference << "color=" << isColorFont
<< dpi << "dpi" << "useDirectWrite=" << useDw;
@@ -1992,6 +1990,10 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, const Q
} else {
directWriteFontFace->Release();
}
+ } else if (useDw) {
+ const QString errorString = qt_error_string(int(hr));
+ qWarning().noquote().nospace() << "DirectWrite: CreateFontFaceFromHDC() failed ("
+ << errorString << ") for " << request << ' ' << lf << " dpi=" << dpi;
}
SelectObject(data->hdc, oldFont);
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
index afba86bbe1..b85a2dceee 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
@@ -67,7 +67,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts)
class QWindowsFontEngineData
{
- Q_DISABLE_COPY(QWindowsFontEngineData)
+ Q_DISABLE_COPY_MOVE(QWindowsFontEngineData)
public:
QWindowsFontEngineData();
~QWindowsFontEngineData();
@@ -85,7 +85,7 @@ public:
class QWindowsFontDatabase : public QPlatformFontDatabase
{
- Q_DISABLE_COPY(QWindowsFontDatabase)
+ Q_DISABLE_COPY_MOVE(QWindowsFontDatabase)
public:
enum FontOptions {
// Relevant bits from QWindowsIntegration::Options
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h
index 2b575a9b45..b1b9d828ac 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h
@@ -66,7 +66,7 @@ class QWindowsFontEngineData;
class QWindowsFontEngine : public QFontEngine
{
- Q_DISABLE_COPY(QWindowsFontEngine)
+ Q_DISABLE_COPY_MOVE(QWindowsFontEngine)
public:
QWindowsFontEngine(const QString &name, LOGFONT lf,
const QSharedPointer<QWindowsFontEngineData> &fontEngineData);
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
index 57c41938bc..60a5896e7b 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
@@ -69,7 +69,7 @@ namespace {
class GeometrySink: public IDWriteGeometrySink
{
- Q_DISABLE_COPY(GeometrySink)
+ Q_DISABLE_COPY_MOVE(GeometrySink)
public:
GeometrySink(QPainterPath *path)
: m_refCount(0), m_path(path)
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h
index 9326f5aece..3eaf8cf3d8 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h
@@ -72,7 +72,7 @@ class QWindowsFontEngineData;
class QWindowsFontEngineDirectWrite : public QFontEngine
{
- Q_DISABLE_COPY(QWindowsFontEngineDirectWrite)
+ Q_DISABLE_COPY_MOVE(QWindowsFontEngineDirectWrite)
public:
explicit QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace,
qreal pixelSize,
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h b/src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h
index 6c47a527d2..ed68ac2644 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h
+++ b/src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
class QWindowsNativeImage
{
- Q_DISABLE_COPY(QWindowsNativeImage)
+ Q_DISABLE_COPY_MOVE(QWindowsNativeImage)
public:
QWindowsNativeImage(int width, int height,
QImage::Format format);
diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp
index 6bd73de8f3..6458454336 100644
--- a/src/platformsupport/glxconvenience/qglxconvenience.cpp
+++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp
@@ -224,13 +224,16 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format
}
QXlibPointer<XVisualInfo> visual(glXGetVisualFromFBConfig(display, candidate));
- if (visual.isNull())
- continue;
-
- const int actualRed = qPopulationCount(visual->red_mask);
- const int actualGreen = qPopulationCount(visual->green_mask);
- const int actualBlue = qPopulationCount(visual->blue_mask);
- const int actualAlpha = visual->depth - actualRed - actualGreen - actualBlue;
+ int actualRed;
+ int actualGreen;
+ int actualBlue;
+ int actualAlpha;
+ glXGetFBConfigAttrib(display, candidate, GLX_RED_SIZE, &actualRed);
+ glXGetFBConfigAttrib(display, candidate, GLX_GREEN_SIZE, &actualGreen);
+ glXGetFBConfigAttrib(display, candidate, GLX_BLUE_SIZE, &actualBlue);
+ glXGetFBConfigAttrib(display, candidate, GLX_ALPHA_SIZE, &actualAlpha);
+ // Sometimes the visuals don't have a depth that includes the alpha channel.
+ actualAlpha = qMin(actualAlpha, visual->depth - actualRed - actualGreen - actualBlue);
if (requestedRed && actualRed < requestedRed)
continue;
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
index ad134a825f..666613f09d 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
@@ -557,7 +557,7 @@ bool QEvdevKeyboardHandler::loadKeymap(const QString &file)
delete [] qmap_keymap;
delete [] qmap_keycompose;
- qWarning("Keymap file '%s' can not be loaded.", qPrintable(file));
+ qWarning("Keymap file '%s' cannot be loaded.", qPrintable(file));
return false;
}
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h
index 5498a3e4f0..21e6d055a0 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h
@@ -132,7 +132,7 @@ inline QDataStream &operator<<(QDataStream &ds, const QEvdevKeyboardMap::Composi
class QFdContainer
{
int m_fd;
- Q_DISABLE_COPY(QFdContainer);
+ Q_DISABLE_COPY_MOVE(QFdContainer);
public:
explicit QFdContainer(int fd = -1) Q_DECL_NOTHROW : m_fd(fd) {}
~QFdContainer() { reset(); }
diff --git a/src/platformsupport/input/input-support.pro b/src/platformsupport/input/input-support.pro
new file mode 100644
index 0000000000..3d39210b9e
--- /dev/null
+++ b/src/platformsupport/input/input-support.pro
@@ -0,0 +1,35 @@
+TARGET = QtInputSupport
+MODULE = input_support
+
+QT = core-private gui-private devicediscovery_support-private
+CONFIG += static internal_module
+
+DEFINES += QT_NO_CAST_FROM_ASCII
+PRECOMPILED_HEADER = ../../corelib/global/qt_pch.h
+
+qtConfig(evdev) {
+ include($$PWD/evdevmouse/evdevmouse.pri)
+ include($$PWD/evdevkeyboard/evdevkeyboard.pri)
+ include($$PWD/evdevtouch/evdevtouch.pri)
+ qtConfig(tabletevent) {
+ include($$PWD/evdevtablet/evdevtablet.pri)
+ }
+}
+
+qtConfig(tslib) {
+ include($$PWD/tslib/tslib.pri)
+}
+
+qtConfig(libinput) {
+ include($$PWD/libinput/libinput.pri)
+}
+
+qtConfig(evdev)|qtConfig(libinput) {
+ include($$PWD/shared/shared.pri)
+}
+
+qtConfig(integrityhid) {
+ include($$PWD/integrityhid/integrityhid.pri)
+}
+
+load(qt_module)
diff --git a/src/platformsupport/input/input.pro b/src/platformsupport/input/input.pro
index 3d39210b9e..138c04dea3 100644
--- a/src/platformsupport/input/input.pro
+++ b/src/platformsupport/input/input.pro
@@ -1,35 +1,8 @@
-TARGET = QtInputSupport
-MODULE = input_support
+TEMPLATE = subdirs
+QT_FOR_CONFIG += gui-private
-QT = core-private gui-private devicediscovery_support-private
-CONFIG += static internal_module
+qtConfig(xkbcommon): SUBDIRS += xkbcommon
-DEFINES += QT_NO_CAST_FROM_ASCII
-PRECOMPILED_HEADER = ../../corelib/global/qt_pch.h
+SUBDIRS += input-support.pro ### FIXME - QTBUG-52657
-qtConfig(evdev) {
- include($$PWD/evdevmouse/evdevmouse.pri)
- include($$PWD/evdevkeyboard/evdevkeyboard.pri)
- include($$PWD/evdevtouch/evdevtouch.pri)
- qtConfig(tabletevent) {
- include($$PWD/evdevtablet/evdevtablet.pri)
- }
-}
-
-qtConfig(tslib) {
- include($$PWD/tslib/tslib.pri)
-}
-
-qtConfig(libinput) {
- include($$PWD/libinput/libinput.pri)
-}
-
-qtConfig(evdev)|qtConfig(libinput) {
- include($$PWD/shared/shared.pri)
-}
-
-qtConfig(integrityhid) {
- include($$PWD/integrityhid/integrityhid.pri)
-}
-
-load(qt_module)
+CONFIG += ordered
diff --git a/src/platformsupport/input/libinput/libinput.pri b/src/platformsupport/input/libinput/libinput.pri
index 476f20c1b8..f80b5f41d9 100644
--- a/src/platformsupport/input/libinput/libinput.pri
+++ b/src/platformsupport/input/libinput/libinput.pri
@@ -14,4 +14,7 @@ QMAKE_USE_PRIVATE += libudev libinput
INCLUDEPATH += $$PWD/../shared
-qtConfig(xkbcommon): QMAKE_USE_PRIVATE += xkbcommon
+qtConfig(xkbcommon): {
+ QMAKE_USE_PRIVATE += xkbcommon
+ QT += xkbcommon_support-private
+}
diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
index baef769bc9..6586b084f1 100644
--- a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
+++ b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
@@ -47,6 +47,7 @@
#if QT_CONFIG(xkbcommon)
#include <xkbcommon/xkbcommon-keysyms.h>
#include <xkbcommon/xkbcommon-names.h>
+#include <QtXkbCommonSupport/private/qxkbcommon_p.h>
#endif
QT_BEGIN_NAMESPACE
@@ -56,88 +57,7 @@ Q_DECLARE_LOGGING_CATEGORY(qLcLibInput)
const int REPEAT_DELAY = 500;
const int REPEAT_RATE = 100;
-#if QT_CONFIG(xkbcommon)
-struct KeyTabEntry {
- int xkbkey;
- int qtkey;
-};
-
-static inline bool operator==(const KeyTabEntry &a, const KeyTabEntry &b)
-{
- return a.xkbkey == b.xkbkey;
-}
-
-static const KeyTabEntry keyTab[] = {
- { XKB_KEY_Escape, Qt::Key_Escape },
- { XKB_KEY_Tab, Qt::Key_Tab },
- { XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab },
- { XKB_KEY_BackSpace, Qt::Key_Backspace },
- { XKB_KEY_Return, Qt::Key_Return },
- { XKB_KEY_Insert, Qt::Key_Insert },
- { XKB_KEY_Delete, Qt::Key_Delete },
- { XKB_KEY_Clear, Qt::Key_Delete },
- { XKB_KEY_Pause, Qt::Key_Pause },
- { XKB_KEY_Print, Qt::Key_Print },
-
- { XKB_KEY_Home, Qt::Key_Home },
- { XKB_KEY_End, Qt::Key_End },
- { XKB_KEY_Left, Qt::Key_Left },
- { XKB_KEY_Up, Qt::Key_Up },
- { XKB_KEY_Right, Qt::Key_Right },
- { XKB_KEY_Down, Qt::Key_Down },
- { XKB_KEY_Prior, Qt::Key_PageUp },
- { XKB_KEY_Next, Qt::Key_PageDown },
-
- { XKB_KEY_Shift_L, Qt::Key_Shift },
- { XKB_KEY_Shift_R, Qt::Key_Shift },
- { XKB_KEY_Shift_Lock, Qt::Key_Shift },
- { XKB_KEY_Control_L, Qt::Key_Control },
- { XKB_KEY_Control_R, Qt::Key_Control },
- { XKB_KEY_Meta_L, Qt::Key_Meta },
- { XKB_KEY_Meta_R, Qt::Key_Meta },
- { XKB_KEY_Alt_L, Qt::Key_Alt },
- { XKB_KEY_Alt_R, Qt::Key_Alt },
- { XKB_KEY_Caps_Lock, Qt::Key_CapsLock },
- { XKB_KEY_Num_Lock, Qt::Key_NumLock },
- { XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock },
- { XKB_KEY_Super_L, Qt::Key_Super_L },
- { XKB_KEY_Super_R, Qt::Key_Super_R },
- { XKB_KEY_Menu, Qt::Key_Menu },
- { XKB_KEY_Hyper_L, Qt::Key_Hyper_L },
- { XKB_KEY_Hyper_R, Qt::Key_Hyper_R },
- { XKB_KEY_Help, Qt::Key_Help },
-
- { XKB_KEY_KP_Space, Qt::Key_Space },
- { XKB_KEY_KP_Tab, Qt::Key_Tab },
- { XKB_KEY_KP_Enter, Qt::Key_Enter },
- { XKB_KEY_KP_Home, Qt::Key_Home },
- { XKB_KEY_KP_Left, Qt::Key_Left },
- { XKB_KEY_KP_Up, Qt::Key_Up },
- { XKB_KEY_KP_Right, Qt::Key_Right },
- { XKB_KEY_KP_Down, Qt::Key_Down },
- { XKB_KEY_KP_Prior, Qt::Key_PageUp },
- { XKB_KEY_KP_Next, Qt::Key_PageDown },
- { XKB_KEY_KP_End, Qt::Key_End },
- { XKB_KEY_KP_Begin, Qt::Key_Clear },
- { XKB_KEY_KP_Insert, Qt::Key_Insert },
- { XKB_KEY_KP_Delete, Qt::Key_Delete },
- { XKB_KEY_KP_Equal, Qt::Key_Equal },
- { XKB_KEY_KP_Multiply, Qt::Key_Asterisk },
- { XKB_KEY_KP_Add, Qt::Key_Plus },
- { XKB_KEY_KP_Separator, Qt::Key_Comma },
- { XKB_KEY_KP_Subtract, Qt::Key_Minus },
- { XKB_KEY_KP_Decimal, Qt::Key_Period },
- { XKB_KEY_KP_Divide, Qt::Key_Slash },
-};
-#endif
-
QLibInputKeyboard::QLibInputKeyboard()
-#if QT_CONFIG(xkbcommon)
- : m_ctx(0),
- m_keymap(0),
- m_state(0),
- m_mods(Qt::NoModifier)
-#endif
{
#if QT_CONFIG(xkbcommon)
qCDebug(qLcLibInput) << "Using xkbcommon for key mapping";
@@ -148,18 +68,14 @@ QLibInputKeyboard::QLibInputKeyboard()
}
m_keymap = xkb_keymap_new_from_names(m_ctx, nullptr, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (!m_keymap) {
- qWarning("Failed to compile keymap");
+ qCWarning(qLcLibInput, "Failed to compile keymap");
return;
}
m_state = xkb_state_new(m_keymap);
if (!m_state) {
- qWarning("Failed to create xkb state");
+ qCWarning(qLcLibInput, "Failed to create xkb state");
return;
}
- m_modindex[0] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_CTRL);
- m_modindex[1] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_ALT);
- m_modindex[2] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_SHIFT);
- m_modindex[3] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_LOGO);
m_repeatTimer.setSingleShot(true);
connect(&m_repeatTimer, &QTimer::timeout, this, &QLibInputKeyboard::handleRepeat);
@@ -186,52 +102,33 @@ void QLibInputKeyboard::processKey(libinput_event_keyboard *e)
if (!m_ctx || !m_keymap || !m_state)
return;
- const uint32_t k = libinput_event_keyboard_get_key(e) + 8;
+ const uint32_t keycode = libinput_event_keyboard_get_key(e) + 8;
+ const xkb_keysym_t sym = xkb_state_key_get_one_sym(m_state, keycode);
const bool pressed = libinput_event_keyboard_get_key_state(e) == LIBINPUT_KEY_STATE_PRESSED;
- QVarLengthArray<char, 32> chars(32);
- const int size = xkb_state_key_get_utf8(m_state, k, chars.data(), chars.size());
- if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL
- chars.resize(size + 1);
- xkb_state_key_get_utf8(m_state, k, chars.data(), chars.size());
- }
- const QString text = QString::fromUtf8(chars.constData(), size);
-
- const xkb_keysym_t sym = xkb_state_key_get_one_sym(m_state, k);
+ // Modifiers here is the modifier state before the event, i.e. not
+ // including the current key in case it is a modifier. See the XOR
+ // logic in QKeyEvent::modifiers(). ### QTBUG-73826
+ Qt::KeyboardModifiers modifiers = QXkbCommon::modifiers(m_state);
- // mods here is the modifier state before the event, i.e. not
- // including the current key in case it is a modifier.
- Qt::KeyboardModifiers mods = Qt::NoModifier;
- const int qtkey = keysymToQtKey(sym, &mods, text);
+ const QString text = QXkbCommon::lookupString(m_state, keycode);
+ const int qtkey = QXkbCommon::keysymToQtKey(sym, modifiers, m_state, keycode);
- if (qtkey == Qt::Key_Control)
- mods |= Qt::ControlModifier;
- if (qtkey == Qt::Key_Alt)
- mods |= Qt::AltModifier;
- if (qtkey == Qt::Key_Shift)
- mods |= Qt::ShiftModifier;
- if (qtkey == Qt::Key_Meta)
- mods |= Qt::MetaModifier;
- xkb_state_update_key(m_state, k, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
+ xkb_state_update_key(m_state, keycode, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
- if (mods != Qt::NoModifier) {
- if (pressed)
- m_mods |= mods;
- else
- m_mods &= ~mods;
+ Qt::KeyboardModifiers modifiersAfterStateChange = QXkbCommon::modifiers(m_state);
+ QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(modifiersAfterStateChange);
- QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(m_mods);
- }
QWindowSystemInterface::handleExtendedKeyEvent(nullptr,
pressed ? QEvent::KeyPress : QEvent::KeyRelease,
- qtkey, m_mods, k, sym, m_mods, text);
+ qtkey, modifiers, keycode, sym, modifiers, text);
- if (pressed && xkb_keymap_key_repeats(m_keymap, k)) {
+ if (pressed && xkb_keymap_key_repeats(m_keymap, keycode)) {
m_repeatData.qtkey = qtkey;
- m_repeatData.mods = mods;
- m_repeatData.nativeScanCode = k;
+ m_repeatData.mods = modifiers;
+ m_repeatData.nativeScanCode = keycode;
m_repeatData.virtualKey = sym;
- m_repeatData.nativeMods = mods;
+ m_repeatData.nativeMods = modifiers;
m_repeatData.unicodeText = text;
m_repeatData.repeatCount = 1;
m_repeatTimer.setInterval(REPEAT_DELAY);
@@ -256,50 +153,6 @@ void QLibInputKeyboard::handleRepeat()
m_repeatTimer.setInterval(REPEAT_RATE);
m_repeatTimer.start();
}
-
-int QLibInputKeyboard::keysymToQtKey(xkb_keysym_t key) const
-{
- const size_t elemCount = sizeof(keyTab) / sizeof(KeyTabEntry);
- KeyTabEntry e;
- e.xkbkey = key;
- const KeyTabEntry *result = std::find(keyTab, keyTab + elemCount, e);
- return result != keyTab + elemCount ? result->qtkey : 0;
-}
-
-int QLibInputKeyboard::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers *modifiers, const QString &text) const
-{
- int code = 0;
-#if QT_CONFIG(textcodec)
- QTextCodec *systemCodec = QTextCodec::codecForLocale();
-#endif
- if (keysym < 128 || (keysym < 256
-#if QT_CONFIG(textcodec)
- && systemCodec->mibEnum() == 4
-#endif
- )) {
- // upper-case key, if known
- code = isprint((int)keysym) ? toupper((int)keysym) : 0;
- } else if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) {
- // function keys
- code = Qt::Key_F1 + ((int)keysym - XKB_KEY_F1);
- } else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) {
- if (keysym >= XKB_KEY_KP_0) {
- // numeric keypad keys
- code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0);
- } else {
- code = keysymToQtKey(keysym);
- }
- *modifiers |= Qt::KeypadModifier;
- } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f
- && text.unicode()->unicode() != 0x7f
- && !(keysym >= XKB_KEY_dead_grave && keysym <= XKB_KEY_dead_longsolidusoverlay)) {
- code = text.unicode()->toUpper().unicode();
- } else {
- // any other keys
- code = keysymToQtKey(keysym);
- }
- return code;
-}
#endif
QT_END_NAMESPACE
diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard_p.h b/src/platformsupport/input/libinput/qlibinputkeyboard_p.h
index 14ae71b545..7521902e02 100644
--- a/src/platformsupport/input/libinput/qlibinputkeyboard_p.h
+++ b/src/platformsupport/input/libinput/qlibinputkeyboard_p.h
@@ -79,10 +79,9 @@ private:
int keysymToQtKey(xkb_keysym_t key) const;
int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers *modifiers, const QString &text) const;
- xkb_context *m_ctx;
- xkb_keymap *m_keymap;
- xkb_state *m_state;
- xkb_mod_index_t m_modindex[4];
+ xkb_context *m_ctx = nullptr;
+ xkb_keymap *m_keymap = nullptr;
+ xkb_state *m_state = nullptr;
QTimer m_repeatTimer;
@@ -95,7 +94,6 @@ private:
QString unicodeText;
int repeatCount;
} m_repeatData;
- Qt::KeyboardModifiers m_mods;
#endif
};
diff --git a/src/platformsupport/input/xkbcommon/qxkbcommon.cpp b/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
new file mode 100644
index 0000000000..877c5d848f
--- /dev/null
+++ b/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
@@ -0,0 +1,828 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxkbcommon_p.h"
+
+#include <private/qmakearray_p.h>
+
+#include <QtCore/QMetaMethod>
+#include <QtGui/QKeyEvent>
+#include <QtGui/private/qguiapplication_p.h>
+
+#include <qpa/qplatforminputcontext.h>
+#include <qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcXkbcommon, "qt.xkbcommon")
+
+static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
+ xkb_state *state, xkb_keycode_t code,
+ bool superAsMeta, bool hyperAsMeta);
+
+typedef struct xkb2qt
+{
+ unsigned int xkb;
+ unsigned int qt;
+
+ constexpr bool operator <=(const xkb2qt &that) const noexcept
+ {
+ return xkb <= that.xkb;
+ }
+
+ constexpr bool operator <(const xkb2qt &that) const noexcept
+ {
+ return xkb < that.xkb;
+ }
+} xkb2qt_t;
+
+template<std::size_t Xkb, std::size_t Qt>
+struct Xkb2Qt
+{
+ using Type = xkb2qt_t;
+ static constexpr Type data() noexcept { return Type{Xkb, Qt}; }
+};
+
+static constexpr const auto KeyTbl = qMakeArray(
+ QSortedData<
+ // misc keys
+
+ Xkb2Qt<XKB_KEY_Escape, Qt::Key_Escape>,
+ Xkb2Qt<XKB_KEY_Tab, Qt::Key_Tab>,
+ Xkb2Qt<XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab>,
+ Xkb2Qt<XKB_KEY_BackSpace, Qt::Key_Backspace>,
+ Xkb2Qt<XKB_KEY_Return, Qt::Key_Return>,
+ Xkb2Qt<XKB_KEY_Insert, Qt::Key_Insert>,
+ Xkb2Qt<XKB_KEY_Delete, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
+ Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
+ Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
+ Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
+
+ // cursor movement
+
+ Xkb2Qt<XKB_KEY_Home, Qt::Key_Home>,
+ Xkb2Qt<XKB_KEY_End, Qt::Key_End>,
+ Xkb2Qt<XKB_KEY_Left, Qt::Key_Left>,
+ Xkb2Qt<XKB_KEY_Up, Qt::Key_Up>,
+ Xkb2Qt<XKB_KEY_Right, Qt::Key_Right>,
+ Xkb2Qt<XKB_KEY_Down, Qt::Key_Down>,
+ Xkb2Qt<XKB_KEY_Prior, Qt::Key_PageUp>,
+ Xkb2Qt<XKB_KEY_Next, Qt::Key_PageDown>,
+
+ // modifiers
+
+ Xkb2Qt<XKB_KEY_Shift_L, Qt::Key_Shift>,
+ Xkb2Qt<XKB_KEY_Shift_R, Qt::Key_Shift>,
+ Xkb2Qt<XKB_KEY_Shift_Lock, Qt::Key_Shift>,
+ Xkb2Qt<XKB_KEY_Control_L, Qt::Key_Control>,
+ Xkb2Qt<XKB_KEY_Control_R, Qt::Key_Control>,
+ Xkb2Qt<XKB_KEY_Meta_L, Qt::Key_Meta>,
+ Xkb2Qt<XKB_KEY_Meta_R, Qt::Key_Meta>,
+ Xkb2Qt<XKB_KEY_Alt_L, Qt::Key_Alt>,
+ Xkb2Qt<XKB_KEY_Alt_R, Qt::Key_Alt>,
+ Xkb2Qt<XKB_KEY_Caps_Lock, Qt::Key_CapsLock>,
+ Xkb2Qt<XKB_KEY_Num_Lock, Qt::Key_NumLock>,
+ Xkb2Qt<XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock>,
+ Xkb2Qt<XKB_KEY_Super_L, Qt::Key_Super_L>,
+ Xkb2Qt<XKB_KEY_Super_R, Qt::Key_Super_R>,
+ Xkb2Qt<XKB_KEY_Menu, Qt::Key_Menu>,
+ Xkb2Qt<XKB_KEY_Hyper_L, Qt::Key_Hyper_L>,
+ Xkb2Qt<XKB_KEY_Hyper_R, Qt::Key_Hyper_R>,
+ Xkb2Qt<XKB_KEY_Help, Qt::Key_Help>,
+ Xkb2Qt<0x1000FF74, Qt::Key_Backtab>, // hardcoded HP backtab
+ Xkb2Qt<0x1005FF10, Qt::Key_F11>, // hardcoded Sun F36 (labeled F11)
+ Xkb2Qt<0x1005FF11, Qt::Key_F12>, // hardcoded Sun F37 (labeled F12)
+
+ // numeric and function keypad keys
+
+ Xkb2Qt<XKB_KEY_KP_Space, Qt::Key_Space>,
+ Xkb2Qt<XKB_KEY_KP_Tab, Qt::Key_Tab>,
+ Xkb2Qt<XKB_KEY_KP_Enter, Qt::Key_Enter>,
+ Xkb2Qt<XKB_KEY_KP_Home, Qt::Key_Home>,
+ Xkb2Qt<XKB_KEY_KP_Left, Qt::Key_Left>,
+ Xkb2Qt<XKB_KEY_KP_Up, Qt::Key_Up>,
+ Xkb2Qt<XKB_KEY_KP_Right, Qt::Key_Right>,
+ Xkb2Qt<XKB_KEY_KP_Down, Qt::Key_Down>,
+ Xkb2Qt<XKB_KEY_KP_Prior, Qt::Key_PageUp>,
+ Xkb2Qt<XKB_KEY_KP_Next, Qt::Key_PageDown>,
+ Xkb2Qt<XKB_KEY_KP_End, Qt::Key_End>,
+ Xkb2Qt<XKB_KEY_KP_Begin, Qt::Key_Clear>,
+ Xkb2Qt<XKB_KEY_KP_Insert, Qt::Key_Insert>,
+ Xkb2Qt<XKB_KEY_KP_Delete, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_KP_Equal, Qt::Key_Equal>,
+ Xkb2Qt<XKB_KEY_KP_Multiply, Qt::Key_Asterisk>,
+ Xkb2Qt<XKB_KEY_KP_Add, Qt::Key_Plus>,
+ Xkb2Qt<XKB_KEY_KP_Separator, Qt::Key_Comma>,
+ Xkb2Qt<XKB_KEY_KP_Subtract, Qt::Key_Minus>,
+ Xkb2Qt<XKB_KEY_KP_Decimal, Qt::Key_Period>,
+ Xkb2Qt<XKB_KEY_KP_Divide, Qt::Key_Slash>,
+
+ // special non-XF86 function keys
+
+ Xkb2Qt<XKB_KEY_Undo, Qt::Key_Undo>,
+ Xkb2Qt<XKB_KEY_Redo, Qt::Key_Redo>,
+ Xkb2Qt<XKB_KEY_Find, Qt::Key_Find>,
+ Xkb2Qt<XKB_KEY_Cancel, Qt::Key_Cancel>,
+
+ // International input method support keys
+
+ // International & multi-key character composition
+ Xkb2Qt<XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr>,
+ Xkb2Qt<XKB_KEY_Multi_key, Qt::Key_Multi_key>,
+ Xkb2Qt<XKB_KEY_Codeinput, Qt::Key_Codeinput>,
+ Xkb2Qt<XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate>,
+ Xkb2Qt<XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate>,
+ Xkb2Qt<XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate>,
+
+ // Misc Functions
+ Xkb2Qt<XKB_KEY_Mode_switch, Qt::Key_Mode_switch>,
+ Xkb2Qt<XKB_KEY_script_switch, Qt::Key_Mode_switch>,
+
+ // Japanese keyboard support
+ Xkb2Qt<XKB_KEY_Kanji, Qt::Key_Kanji>,
+ Xkb2Qt<XKB_KEY_Muhenkan, Qt::Key_Muhenkan>,
+ //Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan_Mode>,
+ Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan>,
+ Xkb2Qt<XKB_KEY_Henkan, Qt::Key_Henkan>,
+ Xkb2Qt<XKB_KEY_Romaji, Qt::Key_Romaji>,
+ Xkb2Qt<XKB_KEY_Hiragana, Qt::Key_Hiragana>,
+ Xkb2Qt<XKB_KEY_Katakana, Qt::Key_Katakana>,
+ Xkb2Qt<XKB_KEY_Hiragana_Katakana, Qt::Key_Hiragana_Katakana>,
+ Xkb2Qt<XKB_KEY_Zenkaku, Qt::Key_Zenkaku>,
+ Xkb2Qt<XKB_KEY_Hankaku, Qt::Key_Hankaku>,
+ Xkb2Qt<XKB_KEY_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku>,
+ Xkb2Qt<XKB_KEY_Touroku, Qt::Key_Touroku>,
+ Xkb2Qt<XKB_KEY_Massyo, Qt::Key_Massyo>,
+ Xkb2Qt<XKB_KEY_Kana_Lock, Qt::Key_Kana_Lock>,
+ Xkb2Qt<XKB_KEY_Kana_Shift, Qt::Key_Kana_Shift>,
+ Xkb2Qt<XKB_KEY_Eisu_Shift, Qt::Key_Eisu_Shift>,
+ Xkb2Qt<XKB_KEY_Eisu_toggle, Qt::Key_Eisu_toggle>,
+ //Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Kanji_Bangou>,
+ //Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_Zen_Koho>,
+ //Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_Mae_Koho>,
+ Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Codeinput>,
+ Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_MultipleCandidate>,
+ Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_PreviousCandidate>,
+
+ // Korean keyboard support
+ Xkb2Qt<XKB_KEY_Hangul, Qt::Key_Hangul>,
+ Xkb2Qt<XKB_KEY_Hangul_Start, Qt::Key_Hangul_Start>,
+ Xkb2Qt<XKB_KEY_Hangul_End, Qt::Key_Hangul_End>,
+ Xkb2Qt<XKB_KEY_Hangul_Hanja, Qt::Key_Hangul_Hanja>,
+ Xkb2Qt<XKB_KEY_Hangul_Jamo, Qt::Key_Hangul_Jamo>,
+ Xkb2Qt<XKB_KEY_Hangul_Romaja, Qt::Key_Hangul_Romaja>,
+ //Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Hangul_Codeinput>,
+ Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Codeinput>,
+ Xkb2Qt<XKB_KEY_Hangul_Jeonja, Qt::Key_Hangul_Jeonja>,
+ Xkb2Qt<XKB_KEY_Hangul_Banja, Qt::Key_Hangul_Banja>,
+ Xkb2Qt<XKB_KEY_Hangul_PreHanja, Qt::Key_Hangul_PreHanja>,
+ Xkb2Qt<XKB_KEY_Hangul_PostHanja, Qt::Key_Hangul_PostHanja>,
+ //Xkb2Qt<XKB_KEY_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate>,
+ //Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate>,
+ //Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate>,
+ Xkb2Qt<XKB_KEY_Hangul_SingleCandidate, Qt::Key_SingleCandidate>,
+ Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate>,
+ Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate>,
+ Xkb2Qt<XKB_KEY_Hangul_Special, Qt::Key_Hangul_Special>,
+ //Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Hangul_switch>,
+ Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Mode_switch>,
+
+ // dead keys
+ Xkb2Qt<XKB_KEY_dead_grave, Qt::Key_Dead_Grave>,
+ Xkb2Qt<XKB_KEY_dead_acute, Qt::Key_Dead_Acute>,
+ Xkb2Qt<XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex>,
+ Xkb2Qt<XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde>,
+ Xkb2Qt<XKB_KEY_dead_macron, Qt::Key_Dead_Macron>,
+ Xkb2Qt<XKB_KEY_dead_breve, Qt::Key_Dead_Breve>,
+ Xkb2Qt<XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot>,
+ Xkb2Qt<XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis>,
+ Xkb2Qt<XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering>,
+ Xkb2Qt<XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute>,
+ Xkb2Qt<XKB_KEY_dead_caron, Qt::Key_Dead_Caron>,
+ Xkb2Qt<XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla>,
+ Xkb2Qt<XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek>,
+ Xkb2Qt<XKB_KEY_dead_iota, Qt::Key_Dead_Iota>,
+ Xkb2Qt<XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound>,
+ Xkb2Qt<XKB_KEY_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound>,
+ Xkb2Qt<XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot>,
+ Xkb2Qt<XKB_KEY_dead_hook, Qt::Key_Dead_Hook>,
+ Xkb2Qt<XKB_KEY_dead_horn, Qt::Key_Dead_Horn>,
+ Xkb2Qt<XKB_KEY_dead_stroke, Qt::Key_Dead_Stroke>,
+ Xkb2Qt<XKB_KEY_dead_abovecomma, Qt::Key_Dead_Abovecomma>,
+ Xkb2Qt<XKB_KEY_dead_abovereversedcomma, Qt::Key_Dead_Abovereversedcomma>,
+ Xkb2Qt<XKB_KEY_dead_doublegrave, Qt::Key_Dead_Doublegrave>,
+ Xkb2Qt<XKB_KEY_dead_belowring, Qt::Key_Dead_Belowring>,
+ Xkb2Qt<XKB_KEY_dead_belowmacron, Qt::Key_Dead_Belowmacron>,
+ Xkb2Qt<XKB_KEY_dead_belowcircumflex, Qt::Key_Dead_Belowcircumflex>,
+ Xkb2Qt<XKB_KEY_dead_belowtilde, Qt::Key_Dead_Belowtilde>,
+ Xkb2Qt<XKB_KEY_dead_belowbreve, Qt::Key_Dead_Belowbreve>,
+ Xkb2Qt<XKB_KEY_dead_belowdiaeresis, Qt::Key_Dead_Belowdiaeresis>,
+ Xkb2Qt<XKB_KEY_dead_invertedbreve, Qt::Key_Dead_Invertedbreve>,
+ Xkb2Qt<XKB_KEY_dead_belowcomma, Qt::Key_Dead_Belowcomma>,
+ Xkb2Qt<XKB_KEY_dead_currency, Qt::Key_Dead_Currency>,
+ Xkb2Qt<XKB_KEY_dead_a, Qt::Key_Dead_a>,
+ Xkb2Qt<XKB_KEY_dead_A, Qt::Key_Dead_A>,
+ Xkb2Qt<XKB_KEY_dead_e, Qt::Key_Dead_e>,
+ Xkb2Qt<XKB_KEY_dead_E, Qt::Key_Dead_E>,
+ Xkb2Qt<XKB_KEY_dead_i, Qt::Key_Dead_i>,
+ Xkb2Qt<XKB_KEY_dead_I, Qt::Key_Dead_I>,
+ Xkb2Qt<XKB_KEY_dead_o, Qt::Key_Dead_o>,
+ Xkb2Qt<XKB_KEY_dead_O, Qt::Key_Dead_O>,
+ Xkb2Qt<XKB_KEY_dead_u, Qt::Key_Dead_u>,
+ Xkb2Qt<XKB_KEY_dead_U, Qt::Key_Dead_U>,
+ Xkb2Qt<XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa>,
+ Xkb2Qt<XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa>,
+ Xkb2Qt<XKB_KEY_dead_greek, Qt::Key_Dead_Greek>,
+ Xkb2Qt<XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline>,
+ Xkb2Qt<XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline>,
+ Xkb2Qt<XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline>,
+ Xkb2Qt<XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay>,
+
+ // Special keys from X.org - This include multimedia keys,
+ // wireless/bluetooth/uwb keys, special launcher keys, etc.
+ Xkb2Qt<XKB_KEY_XF86Back, Qt::Key_Back>,
+ Xkb2Qt<XKB_KEY_XF86Forward, Qt::Key_Forward>,
+ Xkb2Qt<XKB_KEY_XF86Stop, Qt::Key_Stop>,
+ Xkb2Qt<XKB_KEY_XF86Refresh, Qt::Key_Refresh>,
+ Xkb2Qt<XKB_KEY_XF86Favorites, Qt::Key_Favorites>,
+ Xkb2Qt<XKB_KEY_XF86AudioMedia, Qt::Key_LaunchMedia>,
+ Xkb2Qt<XKB_KEY_XF86OpenURL, Qt::Key_OpenUrl>,
+ Xkb2Qt<XKB_KEY_XF86HomePage, Qt::Key_HomePage>,
+ Xkb2Qt<XKB_KEY_XF86Search, Qt::Key_Search>,
+ Xkb2Qt<XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown>,
+ Xkb2Qt<XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute>,
+ Xkb2Qt<XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp>,
+ Xkb2Qt<XKB_KEY_XF86AudioPlay, Qt::Key_MediaPlay>,
+ Xkb2Qt<XKB_KEY_XF86AudioStop, Qt::Key_MediaStop>,
+ Xkb2Qt<XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious>,
+ Xkb2Qt<XKB_KEY_XF86AudioNext, Qt::Key_MediaNext>,
+ Xkb2Qt<XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord>,
+ Xkb2Qt<XKB_KEY_XF86AudioPause, Qt::Key_MediaPause>,
+ Xkb2Qt<XKB_KEY_XF86Mail, Qt::Key_LaunchMail>,
+ Xkb2Qt<XKB_KEY_XF86MyComputer, Qt::Key_Launch0>, // ### Qt 6: remap properly
+ Xkb2Qt<XKB_KEY_XF86Calculator, Qt::Key_Launch1>,
+ Xkb2Qt<XKB_KEY_XF86Memo, Qt::Key_Memo>,
+ Xkb2Qt<XKB_KEY_XF86ToDoList, Qt::Key_ToDoList>,
+ Xkb2Qt<XKB_KEY_XF86Calendar, Qt::Key_Calendar>,
+ Xkb2Qt<XKB_KEY_XF86PowerDown, Qt::Key_PowerDown>,
+ Xkb2Qt<XKB_KEY_XF86ContrastAdjust, Qt::Key_ContrastAdjust>,
+ Xkb2Qt<XKB_KEY_XF86Standby, Qt::Key_Standby>,
+ Xkb2Qt<XKB_KEY_XF86MonBrightnessUp, Qt::Key_MonBrightnessUp>,
+ Xkb2Qt<XKB_KEY_XF86MonBrightnessDown, Qt::Key_MonBrightnessDown>,
+ Xkb2Qt<XKB_KEY_XF86KbdLightOnOff, Qt::Key_KeyboardLightOnOff>,
+ Xkb2Qt<XKB_KEY_XF86KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp>,
+ Xkb2Qt<XKB_KEY_XF86KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown>,
+ Xkb2Qt<XKB_KEY_XF86PowerOff, Qt::Key_PowerOff>,
+ Xkb2Qt<XKB_KEY_XF86WakeUp, Qt::Key_WakeUp>,
+ Xkb2Qt<XKB_KEY_XF86Eject, Qt::Key_Eject>,
+ Xkb2Qt<XKB_KEY_XF86ScreenSaver, Qt::Key_ScreenSaver>,
+ Xkb2Qt<XKB_KEY_XF86WWW, Qt::Key_WWW>,
+ Xkb2Qt<XKB_KEY_XF86Sleep, Qt::Key_Sleep>,
+ Xkb2Qt<XKB_KEY_XF86LightBulb, Qt::Key_LightBulb>,
+ Xkb2Qt<XKB_KEY_XF86Shop, Qt::Key_Shop>,
+ Xkb2Qt<XKB_KEY_XF86History, Qt::Key_History>,
+ Xkb2Qt<XKB_KEY_XF86AddFavorite, Qt::Key_AddFavorite>,
+ Xkb2Qt<XKB_KEY_XF86HotLinks, Qt::Key_HotLinks>,
+ Xkb2Qt<XKB_KEY_XF86BrightnessAdjust, Qt::Key_BrightnessAdjust>,
+ Xkb2Qt<XKB_KEY_XF86Finance, Qt::Key_Finance>,
+ Xkb2Qt<XKB_KEY_XF86Community, Qt::Key_Community>,
+ Xkb2Qt<XKB_KEY_XF86AudioRewind, Qt::Key_AudioRewind>,
+ Xkb2Qt<XKB_KEY_XF86BackForward, Qt::Key_BackForward>,
+ Xkb2Qt<XKB_KEY_XF86ApplicationLeft, Qt::Key_ApplicationLeft>,
+ Xkb2Qt<XKB_KEY_XF86ApplicationRight, Qt::Key_ApplicationRight>,
+ Xkb2Qt<XKB_KEY_XF86Book, Qt::Key_Book>,
+ Xkb2Qt<XKB_KEY_XF86CD, Qt::Key_CD>,
+ Xkb2Qt<XKB_KEY_XF86Calculater, Qt::Key_Calculator>,
+ Xkb2Qt<XKB_KEY_XF86Clear, Qt::Key_Clear>,
+ Xkb2Qt<XKB_KEY_XF86ClearGrab, Qt::Key_ClearGrab>,
+ Xkb2Qt<XKB_KEY_XF86Close, Qt::Key_Close>,
+ Xkb2Qt<XKB_KEY_XF86Copy, Qt::Key_Copy>,
+ Xkb2Qt<XKB_KEY_XF86Cut, Qt::Key_Cut>,
+ Xkb2Qt<XKB_KEY_XF86Display, Qt::Key_Display>,
+ Xkb2Qt<XKB_KEY_XF86DOS, Qt::Key_DOS>,
+ Xkb2Qt<XKB_KEY_XF86Documents, Qt::Key_Documents>,
+ Xkb2Qt<XKB_KEY_XF86Excel, Qt::Key_Excel>,
+ Xkb2Qt<XKB_KEY_XF86Explorer, Qt::Key_Explorer>,
+ Xkb2Qt<XKB_KEY_XF86Game, Qt::Key_Game>,
+ Xkb2Qt<XKB_KEY_XF86Go, Qt::Key_Go>,
+ Xkb2Qt<XKB_KEY_XF86iTouch, Qt::Key_iTouch>,
+ Xkb2Qt<XKB_KEY_XF86LogOff, Qt::Key_LogOff>,
+ Xkb2Qt<XKB_KEY_XF86Market, Qt::Key_Market>,
+ Xkb2Qt<XKB_KEY_XF86Meeting, Qt::Key_Meeting>,
+ Xkb2Qt<XKB_KEY_XF86MenuKB, Qt::Key_MenuKB>,
+ Xkb2Qt<XKB_KEY_XF86MenuPB, Qt::Key_MenuPB>,
+ Xkb2Qt<XKB_KEY_XF86MySites, Qt::Key_MySites>,
+ Xkb2Qt<XKB_KEY_XF86New, Qt::Key_New>,
+ Xkb2Qt<XKB_KEY_XF86News, Qt::Key_News>,
+ Xkb2Qt<XKB_KEY_XF86OfficeHome, Qt::Key_OfficeHome>,
+ Xkb2Qt<XKB_KEY_XF86Open, Qt::Key_Open>,
+ Xkb2Qt<XKB_KEY_XF86Option, Qt::Key_Option>,
+ Xkb2Qt<XKB_KEY_XF86Paste, Qt::Key_Paste>,
+ Xkb2Qt<XKB_KEY_XF86Phone, Qt::Key_Phone>,
+ Xkb2Qt<XKB_KEY_XF86Reply, Qt::Key_Reply>,
+ Xkb2Qt<XKB_KEY_XF86Reload, Qt::Key_Reload>,
+ Xkb2Qt<XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows>,
+ Xkb2Qt<XKB_KEY_XF86RotationPB, Qt::Key_RotationPB>,
+ Xkb2Qt<XKB_KEY_XF86RotationKB, Qt::Key_RotationKB>,
+ Xkb2Qt<XKB_KEY_XF86Save, Qt::Key_Save>,
+ Xkb2Qt<XKB_KEY_XF86Send, Qt::Key_Send>,
+ Xkb2Qt<XKB_KEY_XF86Spell, Qt::Key_Spell>,
+ Xkb2Qt<XKB_KEY_XF86SplitScreen, Qt::Key_SplitScreen>,
+ Xkb2Qt<XKB_KEY_XF86Support, Qt::Key_Support>,
+ Xkb2Qt<XKB_KEY_XF86TaskPane, Qt::Key_TaskPane>,
+ Xkb2Qt<XKB_KEY_XF86Terminal, Qt::Key_Terminal>,
+ Xkb2Qt<XKB_KEY_XF86Tools, Qt::Key_Tools>,
+ Xkb2Qt<XKB_KEY_XF86Travel, Qt::Key_Travel>,
+ Xkb2Qt<XKB_KEY_XF86Video, Qt::Key_Video>,
+ Xkb2Qt<XKB_KEY_XF86Word, Qt::Key_Word>,
+ Xkb2Qt<XKB_KEY_XF86Xfer, Qt::Key_Xfer>,
+ Xkb2Qt<XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn>,
+ Xkb2Qt<XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut>,
+ Xkb2Qt<XKB_KEY_XF86Away, Qt::Key_Away>,
+ Xkb2Qt<XKB_KEY_XF86Messenger, Qt::Key_Messenger>,
+ Xkb2Qt<XKB_KEY_XF86WebCam, Qt::Key_WebCam>,
+ Xkb2Qt<XKB_KEY_XF86MailForward, Qt::Key_MailForward>,
+ Xkb2Qt<XKB_KEY_XF86Pictures, Qt::Key_Pictures>,
+ Xkb2Qt<XKB_KEY_XF86Music, Qt::Key_Music>,
+ Xkb2Qt<XKB_KEY_XF86Battery, Qt::Key_Battery>,
+ Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
+ Xkb2Qt<XKB_KEY_XF86WLAN, Qt::Key_WLAN>,
+ Xkb2Qt<XKB_KEY_XF86UWB, Qt::Key_UWB>,
+ Xkb2Qt<XKB_KEY_XF86AudioForward, Qt::Key_AudioForward>,
+ Xkb2Qt<XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat>,
+ Xkb2Qt<XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay>,
+ Xkb2Qt<XKB_KEY_XF86Subtitle, Qt::Key_Subtitle>,
+ Xkb2Qt<XKB_KEY_XF86AudioCycleTrack, Qt::Key_AudioCycleTrack>,
+ Xkb2Qt<XKB_KEY_XF86Time, Qt::Key_Time>,
+ Xkb2Qt<XKB_KEY_XF86Select, Qt::Key_Select>,
+ Xkb2Qt<XKB_KEY_XF86View, Qt::Key_View>,
+ Xkb2Qt<XKB_KEY_XF86TopMenu, Qt::Key_TopMenu>,
+ Xkb2Qt<XKB_KEY_XF86Red, Qt::Key_Red>,
+ Xkb2Qt<XKB_KEY_XF86Green, Qt::Key_Green>,
+ Xkb2Qt<XKB_KEY_XF86Yellow, Qt::Key_Yellow>,
+ Xkb2Qt<XKB_KEY_XF86Blue, Qt::Key_Blue>,
+ Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
+ Xkb2Qt<XKB_KEY_XF86Suspend, Qt::Key_Suspend>,
+ Xkb2Qt<XKB_KEY_XF86Hibernate, Qt::Key_Hibernate>,
+ Xkb2Qt<XKB_KEY_XF86TouchpadToggle, Qt::Key_TouchpadToggle>,
+ Xkb2Qt<XKB_KEY_XF86TouchpadOn, Qt::Key_TouchpadOn>,
+ Xkb2Qt<XKB_KEY_XF86TouchpadOff, Qt::Key_TouchpadOff>,
+ Xkb2Qt<XKB_KEY_XF86AudioMicMute, Qt::Key_MicMute>,
+ Xkb2Qt<XKB_KEY_XF86Launch0, Qt::Key_Launch2>, // ### Qt 6: remap properly
+ Xkb2Qt<XKB_KEY_XF86Launch1, Qt::Key_Launch3>,
+ Xkb2Qt<XKB_KEY_XF86Launch2, Qt::Key_Launch4>,
+ Xkb2Qt<XKB_KEY_XF86Launch3, Qt::Key_Launch5>,
+ Xkb2Qt<XKB_KEY_XF86Launch4, Qt::Key_Launch6>,
+ Xkb2Qt<XKB_KEY_XF86Launch5, Qt::Key_Launch7>,
+ Xkb2Qt<XKB_KEY_XF86Launch6, Qt::Key_Launch8>,
+ Xkb2Qt<XKB_KEY_XF86Launch7, Qt::Key_Launch9>,
+ Xkb2Qt<XKB_KEY_XF86Launch8, Qt::Key_LaunchA>,
+ Xkb2Qt<XKB_KEY_XF86Launch9, Qt::Key_LaunchB>,
+ Xkb2Qt<XKB_KEY_XF86LaunchA, Qt::Key_LaunchC>,
+ Xkb2Qt<XKB_KEY_XF86LaunchB, Qt::Key_LaunchD>,
+ Xkb2Qt<XKB_KEY_XF86LaunchC, Qt::Key_LaunchE>,
+ Xkb2Qt<XKB_KEY_XF86LaunchD, Qt::Key_LaunchF>,
+ Xkb2Qt<XKB_KEY_XF86LaunchE, Qt::Key_LaunchG>,
+ Xkb2Qt<XKB_KEY_XF86LaunchF, Qt::Key_LaunchH>
+ >::Data{}
+);
+
+xkb_keysym_t QXkbCommon::qxkbcommon_xkb_keysym_to_upper(xkb_keysym_t ks)
+{
+ xkb_keysym_t lower, upper;
+
+ xkbcommon_XConvertCase(ks, &lower, &upper);
+
+ return upper;
+}
+
+QString QXkbCommon::lookupString(struct xkb_state *state, xkb_keycode_t code)
+{
+ QVarLengthArray<char, 32> chars(32);
+ const int size = xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
+ if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL
+ chars.resize(size + 1);
+ xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
+ }
+ return QString::fromUtf8(chars.constData(), size);
+}
+
+QString QXkbCommon::lookupStringNoKeysymTransformations(xkb_keysym_t keysym)
+{
+ QVarLengthArray<char, 32> chars(32);
+ const int size = xkb_keysym_to_utf8(keysym, chars.data(), chars.size());
+ if (size == 0)
+ return QString(); // the keysym does not have a Unicode representation
+
+ if (Q_UNLIKELY(size > chars.size())) {
+ chars.resize(size);
+ xkb_keysym_to_utf8(keysym, chars.data(), chars.size());
+ }
+ return QString::fromUtf8(chars.constData(), size - 1);
+}
+
+QVector<xkb_keysym_t> QXkbCommon::toKeysym(QKeyEvent *event)
+{
+ QVector<xkb_keysym_t> keysyms;
+ int qtKey = event->key();
+
+ if (qtKey >= Qt::Key_F1 && qtKey <= Qt::Key_F35) {
+ keysyms.append(XKB_KEY_F1 + (qtKey - Qt::Key_F1));
+ } else if (event->modifiers() & Qt::KeypadModifier) {
+ if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9)
+ keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0));
+ } else if (isLatin(qtKey) && event->text().isUpper()) {
+ keysyms.append(qtKey);
+ }
+
+ if (!keysyms.isEmpty())
+ return keysyms;
+
+ // check if we have a direct mapping
+ auto it = std::find_if(KeyTbl.cbegin(), KeyTbl.cend(), [&qtKey](xkb2qt_t elem) {
+ return elem.qt == static_cast<uint>(qtKey);
+ });
+ if (it != KeyTbl.end()) {
+ keysyms.append(it->xkb);
+ return keysyms;
+ }
+
+ QVector<uint> ucs4;
+ if (event->text().isEmpty())
+ ucs4.append(qtKey);
+ else
+ ucs4 = event->text().toUcs4();
+
+ // From libxkbcommon keysym-utf.c:
+ // "We allow to represent any UCS character in the range U-00000000 to
+ // U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff."
+ for (uint utf32 : qAsConst(ucs4))
+ keysyms.append(utf32 | 0x01000000);
+
+ return keysyms;
+}
+
+int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers)
+{
+ return keysymToQtKey(keysym, modifiers, nullptr, 0);
+}
+
+int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
+ xkb_state *state, xkb_keycode_t code,
+ bool superAsMeta, bool hyperAsMeta)
+{
+ // Note 1: All standard key sequences on linux (as defined in platform theme)
+ // that use a latin character also contain a control modifier, which is why
+ // checking for Qt::ControlModifier is sufficient here. It is possible to
+ // override QPlatformTheme::keyBindings() and provide custom sequences for
+ // QKeySequence::StandardKey. Custom sequences probably should respect this
+ // convention (alternatively, we could test against other modifiers here).
+ // Note 2: The possibleKeys() shorcut mechanism is not affected by this value
+ // adjustment and does its own thing.
+ if (modifiers & Qt::ControlModifier) {
+ // With standard shortcuts we should prefer a latin character, this is
+ // for checks like "some qkeyevent == QKeySequence::Copy" to work even
+ // when using for example 'russian' keyboard layout.
+ if (!QXkbCommon::isLatin(keysym)) {
+ xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code);
+ if (latinKeysym != XKB_KEY_NoSymbol)
+ keysym = latinKeysym;
+ }
+ }
+
+ return keysymToQtKey_internal(keysym, modifiers, state, code, superAsMeta, hyperAsMeta);
+}
+
+static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
+ xkb_state *state, xkb_keycode_t code,
+ bool superAsMeta, bool hyperAsMeta)
+{
+ int qtKey = 0;
+
+ // lookup from direct mapping
+ if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) {
+ // function keys
+ qtKey = Qt::Key_F1 + (keysym - XKB_KEY_F1);
+ } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
+ // numeric keypad keys
+ qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
+ } else if (QXkbCommon::isLatin(keysym)) {
+ qtKey = QXkbCommon::qxkbcommon_xkb_keysym_to_upper(keysym);
+ } else {
+ // check if we have a direct mapping
+ xkb2qt_t searchKey{keysym, 0};
+ auto it = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey);
+ if (it != KeyTbl.end() && !(searchKey < *it))
+ qtKey = it->qt;
+ }
+
+ if (qtKey)
+ return qtKey;
+
+ // lookup from unicode
+ QString text;
+ if (!state || modifiers & Qt::ControlModifier) {
+ // Control modifier changes the text to ASCII control character, therefore we
+ // can't use this text to map keysym to a qt key. We can use the same keysym
+ // (it is not affectd by transformation) to obtain untransformed text. For details
+ // see "Appendix A. Default Symbol Transformations" in the XKB specification.
+ text = QXkbCommon::lookupStringNoKeysymTransformations(keysym);
+ } else {
+ text = QXkbCommon::lookupString(state, code);
+ }
+ if (!text.isEmpty()) {
+ if (text.unicode()->isDigit()) {
+ // Ensures that also non-latin digits are mapped to corresponding qt keys,
+ // e.g CTRL + ۲ (arabic two), is mapped to CTRL + Qt::Key_2.
+ qtKey = Qt::Key_0 + text.unicode()->digitValue();
+ } else {
+ qtKey = text.unicode()->toUpper().unicode();
+ }
+ }
+
+ // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
+ if (superAsMeta && (qtKey == Qt::Key_Super_L || qtKey == Qt::Key_Super_R))
+ qtKey = Qt::Key_Meta;
+ if (hyperAsMeta && (qtKey == Qt::Key_Hyper_L || qtKey == Qt::Key_Hyper_R))
+ qtKey = Qt::Key_Meta;
+
+ return qtKey;
+}
+
+Qt::KeyboardModifiers QXkbCommon::modifiers(struct xkb_state *state)
+{
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE) > 0)
+ modifiers |= Qt::ControlModifier;
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE) > 0)
+ modifiers |= Qt::AltModifier;
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_EFFECTIVE) > 0)
+ modifiers |= Qt::ShiftModifier;
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_LOGO, XKB_STATE_MODS_EFFECTIVE) > 0)
+ modifiers |= Qt::MetaModifier;
+
+ return modifiers;
+}
+
+// Possible modifier states.
+static const Qt::KeyboardModifiers ModsTbl[] = {
+ Qt::NoModifier, // 0
+ Qt::ShiftModifier, // 1
+ Qt::ControlModifier, // 2
+ Qt::ControlModifier | Qt::ShiftModifier, // 3
+ Qt::AltModifier, // 4
+ Qt::AltModifier | Qt::ShiftModifier, // 5
+ Qt::AltModifier | Qt::ControlModifier, // 6
+ Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7
+ Qt::NoModifier // Fall-back to raw Key_*, for non-latin1 kb layouts
+};
+
+QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
+ bool superAsMeta, bool hyperAsMeta)
+{
+ QList<int> result;
+ quint32 keycode = event->nativeScanCode();
+ Qt::KeyboardModifiers modifiers = event->modifiers();
+ xkb_keymap *keymap = xkb_state_get_keymap(state);
+ // turn off the modifier bits which doesn't participate in shortcuts
+ Qt::KeyboardModifiers notNeeded = Qt::KeypadModifier | Qt::GroupSwitchModifier;
+ modifiers &= ~notNeeded;
+ // create a fresh kb state and test against the relevant modifier combinations
+ ScopedXKBState scopedXkbQueryState(xkb_state_new(keymap));
+ xkb_state *queryState = scopedXkbQueryState.get();
+ if (!queryState) {
+ qCWarning(lcXkbcommon) << Q_FUNC_INFO << "failed to compile xkb keymap";
+ return result;
+ }
+ // get kb state from the master state and update the temporary state
+ xkb_layout_index_t lockedLayout = xkb_state_serialize_layout(state, XKB_STATE_LAYOUT_LOCKED);
+ xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LATCHED);
+ xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LOCKED);
+ xkb_mod_mask_t depressedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_DEPRESSED);
+ xkb_state_update_mask(queryState, depressedMods, latchedMods, lockedMods, 0, 0, lockedLayout);
+ // handle shortcuts for level three and above
+ xkb_layout_index_t layoutIndex = xkb_state_key_get_layout(queryState, keycode);
+ xkb_level_index_t levelIndex = 0;
+ if (layoutIndex != XKB_LAYOUT_INVALID) {
+ levelIndex = xkb_state_key_get_level(queryState, keycode, layoutIndex);
+ if (levelIndex == XKB_LEVEL_INVALID)
+ levelIndex = 0;
+ }
+ if (levelIndex <= 1)
+ xkb_state_update_mask(queryState, 0, latchedMods, lockedMods, 0, 0, lockedLayout);
+
+ xkb_keysym_t sym = xkb_state_key_get_one_sym(queryState, keycode);
+ if (sym == XKB_KEY_NoSymbol)
+ return result;
+
+ int baseQtKey = keysymToQtKey_internal(sym, modifiers, queryState, keycode, superAsMeta, hyperAsMeta);
+ if (baseQtKey)
+ result += (baseQtKey + modifiers);
+
+ xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(keymap, "Shift");
+ xkb_mod_index_t altMod = xkb_keymap_mod_get_index(keymap, "Alt");
+ xkb_mod_index_t controlMod = xkb_keymap_mod_get_index(keymap, "Control");
+ xkb_mod_index_t metaMod = xkb_keymap_mod_get_index(keymap, "Meta");
+
+ Q_ASSERT(shiftMod < 32);
+ Q_ASSERT(altMod < 32);
+ Q_ASSERT(controlMod < 32);
+
+ xkb_mod_mask_t depressed;
+ int qtKey = 0;
+ // obtain a list of possible shortcuts for the given key event
+ for (uint i = 1; i < sizeof(ModsTbl) / sizeof(*ModsTbl) ; ++i) {
+ Qt::KeyboardModifiers neededMods = ModsTbl[i];
+ if ((modifiers & neededMods) == neededMods) {
+ if (i == 8) {
+ if (isLatin(baseQtKey))
+ continue;
+ // add a latin key as a fall back key
+ sym = lookupLatinKeysym(state, keycode);
+ } else {
+ depressed = 0;
+ if (neededMods & Qt::AltModifier)
+ depressed |= (1 << altMod);
+ if (neededMods & Qt::ShiftModifier)
+ depressed |= (1 << shiftMod);
+ if (neededMods & Qt::ControlModifier)
+ depressed |= (1 << controlMod);
+ if (metaMod < 32 && neededMods & Qt::MetaModifier)
+ depressed |= (1 << metaMod);
+ xkb_state_update_mask(queryState, depressed, latchedMods, lockedMods, 0, 0, lockedLayout);
+ sym = xkb_state_key_get_one_sym(queryState, keycode);
+ }
+ if (sym == XKB_KEY_NoSymbol)
+ continue;
+
+ Qt::KeyboardModifiers mods = modifiers & ~neededMods;
+ qtKey = keysymToQtKey_internal(sym, mods, queryState, keycode, superAsMeta, hyperAsMeta);
+ if (!qtKey || qtKey == baseQtKey)
+ continue;
+
+ // catch only more specific shortcuts, i.e. Ctrl+Shift+= also generates Ctrl++ and +,
+ // but Ctrl++ is more specific than +, so we should skip the last one
+ bool ambiguous = false;
+ for (int shortcut : qAsConst(result)) {
+ if (int(shortcut & ~Qt::KeyboardModifierMask) == qtKey && (shortcut & mods) == mods) {
+ ambiguous = true;
+ break;
+ }
+ }
+ if (ambiguous)
+ continue;
+
+ result += (qtKey + mods);
+ }
+ }
+
+ return result;
+}
+
+void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap)
+{
+ const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts(keymap);
+ const xkb_keycode_t minKeycode = xkb_keymap_min_keycode(keymap);
+ const xkb_keycode_t maxKeycode = xkb_keymap_max_keycode(keymap);
+
+ const xkb_keysym_t *keysyms = nullptr;
+ int nrLatinKeys = 0;
+ for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
+ for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
+ xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms);
+ if (keysyms && isLatin(keysyms[0]))
+ nrLatinKeys++;
+ if (nrLatinKeys > 10) // arbitrarily chosen threshold
+ return;
+ }
+ }
+ // This means that lookupLatinKeysym() will not find anything and latin
+ // key shortcuts might not work. This is a bug in the affected desktop
+ // environment. Usually can be solved via system settings by adding e.g. 'us'
+ // layout to the list of seleced layouts, or by using command line, "setxkbmap
+ // -layout rus,en". The position of latin key based layout in the list of the
+ // selected layouts is irrelevant. Properly functioning desktop environments
+ // handle this behind the scenes, even if no latin key based layout has been
+ // explicitly listed in the selected layouts.
+ qCDebug(lcXkbcommon, "no keyboard layouts with latin keys present");
+}
+
+xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode)
+{
+ xkb_layout_index_t layout;
+ xkb_keysym_t sym = XKB_KEY_NoSymbol;
+ xkb_keymap *keymap = xkb_state_get_keymap(state);
+ const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts_for_key(keymap, keycode);
+ const xkb_layout_index_t currentLayout = xkb_state_key_get_layout(state, keycode);
+ // Look at user layouts in the order in which they are defined in system
+ // settings to find a latin keysym.
+ for (layout = 0; layout < layoutCount; ++layout) {
+ if (layout == currentLayout)
+ continue;
+ const xkb_keysym_t *syms = nullptr;
+ xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout);
+ if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1)
+ continue;
+ if (isLatin(syms[0])) {
+ sym = syms[0];
+ break;
+ }
+ }
+
+ if (sym == XKB_KEY_NoSymbol)
+ return sym;
+
+ xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LATCHED);
+ xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LOCKED);
+
+ // Check for uniqueness, consider the following setup:
+ // setxkbmap -layout us,ru,us -variant dvorak,, -option 'grp:ctrl_alt_toggle' (set 'ru' as active).
+ // In this setup, the user would expect to trigger a ctrl+q shortcut by pressing ctrl+<physical x key>,
+ // because "US dvorak" is higher up in the layout settings list. This check verifies that an obtained
+ // 'sym' can not be acquired by any other layout higher up in the user's layout list. If it can be acquired
+ // then the obtained key is not unique. This prevents ctrl+<physical q key> from generating a ctrl+q
+ // shortcut in the above described setup. We don't want ctrl+<physical x key> and ctrl+<physical q key> to
+ // generate the same shortcut event in this case.
+ const xkb_keycode_t minKeycode = xkb_keymap_min_keycode(keymap);
+ const xkb_keycode_t maxKeycode = xkb_keymap_max_keycode(keymap);
+ ScopedXKBState queryState(xkb_state_new(keymap));
+ for (xkb_layout_index_t prevLayout = 0; prevLayout < layout; ++prevLayout) {
+ xkb_state_update_mask(queryState.get(), 0, latchedMods, lockedMods, 0, 0, prevLayout);
+ for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
+ xkb_keysym_t prevSym = xkb_state_key_get_one_sym(queryState.get(), code);
+ if (prevSym == sym) {
+ sym = XKB_KEY_NoSymbol;
+ break;
+ }
+ }
+ }
+
+ return sym;
+}
+
+void QXkbCommon::setXkbContext(QPlatformInputContext *inputContext, struct xkb_context *context)
+{
+ if (!inputContext || !context)
+ return;
+
+ const char *const inputContextClassName = "QComposeInputContext";
+ const char *const normalizedSignature = "setXkbContext(xkb_context*)";
+
+ if (inputContext->objectName() != QLatin1String(inputContextClassName))
+ return;
+
+ static const QMetaMethod setXkbContext = [&]() {
+ int methodIndex = inputContext->metaObject()->indexOfMethod(normalizedSignature);
+ QMetaMethod method = inputContext->metaObject()->method(methodIndex);
+ Q_ASSERT(method.isValid());
+ if (!method.isValid())
+ qCWarning(lcXkbcommon) << normalizedSignature << "not found on" << inputContextClassName;
+ return method;
+ }();
+
+ if (!setXkbContext.isValid())
+ return;
+
+ setXkbContext.invoke(inputContext, Qt::DirectConnection, Q_ARG(struct xkb_context*, context));
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbxkbcommon.h b/src/platformsupport/input/xkbcommon/qxkbcommon_3rdparty.cpp
index 422c0c0f12..08f43b3b72 100644
--- a/src/plugins/platforms/xcb/qxcbxkbcommon.h
+++ b/src/platformsupport/input/xkbcommon/qxkbcommon_3rdparty.cpp
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -37,10 +37,7 @@
**
****************************************************************************/
-/* XConvertCase was copied from src/3rdparty/xkbcommon/src/keysym.c,
- which contains the following license information:
-
- Copyright 1985, 1987, 1990, 1998 The Open Group
+/* Copyright 1985, 1987, 1990, 1998 The Open Group
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -89,6 +86,7 @@
*/
/*
+ XConvertCase was copied from src/3rdparty/xkbcommon/src/keysym.c
The following code modifications were applied:
XConvertCase() was renamed to xkbcommon_XConvertCase(), to not confuse it
@@ -99,10 +97,9 @@
results instead of using the less complete version from keysym.c
*/
-#include <xkbcommon/xkbcommon.h>
-#include <QtCore/QChar>
+#include "qxkbcommon_p.h"
-QT_BEGIN_NAMESPACE
+#include <QtCore/QChar>
static void qt_UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *upper)
{
@@ -110,7 +107,7 @@ static void qt_UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *
*upper = QChar::toUpper(code);
}
-void xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper)
+void QXkbCommon::xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper)
{
/* Latin 1 keysym */
if (sym < 0x100) {
@@ -220,14 +217,3 @@ void xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t
break;
}
}
-
-xkb_keysym_t xkbcommon_xkb_keysym_to_upper(xkb_keysym_t ks)
-{
- xkb_keysym_t lower, upper;
-
- xkbcommon_XConvertCase(ks, &lower, &upper);
-
- return upper;
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/input/xkbcommon/qxkbcommon_p.h b/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
new file mode 100644
index 0000000000..561eae03db
--- /dev/null
+++ b/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXKBCOMMON_P_H
+#define QXKBCOMMON_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QString>
+#include <QtCore/QVector>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QList>
+
+#include <xkbcommon/xkbcommon.h>
+
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcXkbcommon)
+
+class QEvent;
+class QKeyEvent;
+class QPlatformInputContext;
+
+class QXkbCommon
+{
+public:
+ static QString lookupString(struct xkb_state *state, xkb_keycode_t code);
+ static QString lookupStringNoKeysymTransformations(xkb_keysym_t keysym);
+
+ static QVector<xkb_keysym_t> toKeysym(QKeyEvent *event);
+
+ static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers);
+ static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
+ xkb_state *state, xkb_keycode_t code,
+ bool superAsMeta = false, bool hyperAsMeta = false);
+
+ // xkbcommon_* API is part of libxkbcommon internals, with modifications as
+ // desribed in the header of the implementation file.
+ static void xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper);
+ static xkb_keysym_t qxkbcommon_xkb_keysym_to_upper(xkb_keysym_t ks);
+
+ static Qt::KeyboardModifiers modifiers(struct xkb_state *state);
+
+ static QList<int> possibleKeys(xkb_state *state, const QKeyEvent *event,
+ bool superAsMeta = false, bool hyperAsMeta = false);
+
+ static void verifyHasLatinLayout(xkb_keymap *keymap);
+ static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode);
+
+ static bool isLatin(xkb_keysym_t sym) {
+ return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
+ }
+ static bool isKeypad(xkb_keysym_t sym) {
+ return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9;
+ }
+
+ static void setXkbContext(QPlatformInputContext *inputContext, struct xkb_context *context);
+
+ struct XKBStateDeleter {
+ void operator()(struct xkb_state *state) const { return xkb_state_unref(state); }
+ };
+ struct XKBKeymapDeleter {
+ void operator()(struct xkb_keymap *keymap) const { return xkb_keymap_unref(keymap); }
+ };
+ struct XKBContextDeleter {
+ void operator()(struct xkb_context *context) const { return xkb_context_unref(context); }
+ };
+ using ScopedXKBState = std::unique_ptr<struct xkb_state, XKBStateDeleter>;
+ using ScopedXKBKeymap = std::unique_ptr<struct xkb_keymap, XKBKeymapDeleter>;
+ using ScopedXKBContext = std::unique_ptr<struct xkb_context, XKBContextDeleter>;
+};
+
+QT_END_NAMESPACE
+
+#endif // QXKBCOMMON_P_H
diff --git a/src/platformsupport/input/xkbcommon/xkbcommon.pro b/src/platformsupport/input/xkbcommon/xkbcommon.pro
new file mode 100644
index 0000000000..22b16ae44a
--- /dev/null
+++ b/src/platformsupport/input/xkbcommon/xkbcommon.pro
@@ -0,0 +1,23 @@
+TARGET = QtXkbCommonSupport
+MODULE = xkbcommon_support
+
+QT = core-private gui-private
+CONFIG += static internal_module
+
+DEFINES += QT_NO_CAST_FROM_ASCII
+PRECOMPILED_HEADER = ../../../corelib/global/qt_pch.h
+
+QMAKE_USE += xkbcommon
+
+HEADERS += \
+ qxkbcommon_p.h
+
+SOURCES += \
+ qxkbcommon.cpp \
+ qxkbcommon_3rdparty.cpp
+
+# qxkbcommon.cpp::KeyTbl has more than 256 levels of expansion and older
+# Clang uses that as a limit (it's 1024 in current versions).
+clang:!intel_icc: QMAKE_CXXFLAGS += -ftemplate-depth=1024
+
+load(qt_module)
diff --git a/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
index e81d272d4f..ca740f967e 100644
--- a/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+++ b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
@@ -52,6 +52,9 @@
#include <qdebug.h>
#include <qrect.h>
#include <qloggingcategory.h>
+#include <qstandardpaths.h>
+#include <qdir.h>
+#include <qmetaobject.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformservices.h>
#include <qdbusconnectioninterface.h>
diff --git a/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor.cpp b/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor.cpp
index d3c5454f01..ef2d330959 100644
--- a/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor.cpp
+++ b/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor.cpp
@@ -52,6 +52,9 @@
#ifndef QT_NO_SYSTEMTRAYICON
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QCoreApplication>
+
#include "qdbustrayicon_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy_p.h b/src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy_p.h
index 03899723ab..352b4aa5d6 100644
--- a/src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy_p.h
+++ b/src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy_p.h
@@ -65,6 +65,7 @@
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
+#include <QtCore/QLoggingCategory>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
diff --git a/src/platformsupport/themes/qabstractfileiconengine.cpp b/src/platformsupport/themes/qabstractfileiconengine.cpp
index 192ed00510..c5800d9119 100644
--- a/src/platformsupport/themes/qabstractfileiconengine.cpp
+++ b/src/platformsupport/themes/qabstractfileiconengine.cpp
@@ -76,7 +76,7 @@ QPixmap QAbstractFileIconEngine::pixmap(const QSize &size, QIcon::Mode mode,
key += QLatin1Char('_') + QString::number(size.width());
QPixmap result;
- if (!QPixmapCache::find(key, result)) {
+ if (!QPixmapCache::find(key, &result)) {
result = filePixmap(size, mode, state);
if (!result.isNull())
QPixmapCache::insert(key, result);
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
index 543e66491d..e74b1cf744 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
@@ -465,7 +465,7 @@ void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path,
cpPriv->state |= QNetworkConfiguration::Active;
if (deviceType == DEVICE_TYPE_ETHERNET) {
- for (const auto *interfaceDevice : interfaceDevices) {
+ for (auto interfaceDevice : qAsConst(interfaceDevices)) {
if (interfaceDevice->deviceType() == deviceType) {
auto *wiredDevice = wiredDevices.value(interfaceDevice->path());
if (wiredDevice && wiredDevice->carrier()) {
@@ -716,7 +716,7 @@ QNetworkSession::State QNetworkManagerEngine::sessionStateForId(const QString &i
if (!ptr->isValid)
return QNetworkSession::Invalid;
- for (QNetworkManagerConnectionActive *activeConnection : activeConnectionsList) {
+ for (QNetworkManagerConnectionActive *activeConnection : qAsConst(activeConnectionsList)) {
const QString identifier = activeConnection->connection().path();
if (id == identifier) {
diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp
index 847479047f..a09ae72cb5 100644
--- a/src/plugins/bearer/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/qnetworksession_impl.cpp
@@ -82,8 +82,6 @@ Q_SIGNALS:
void forcedSessionClose(const QNetworkConfiguration &config);
};
-#include "qnetworksession_impl.moc"
-
Q_GLOBAL_STATIC(QNetworkSessionManagerPrivate, sessionManager);
void QNetworkSessionPrivateImpl::syncStateWithInterface()
@@ -432,3 +430,5 @@ void QNetworkSessionPrivateImpl::decrementTimeout()
}
QT_END_NAMESPACE
+
+#include "qnetworksession_impl.moc"
diff --git a/src/plugins/generic/tuiotouch/qtuiohandler.cpp b/src/plugins/generic/tuiotouch/qtuiohandler.cpp
index bb18ba5085..cb82672acd 100644
--- a/src/plugins/generic/tuiotouch/qtuiohandler.cpp
+++ b/src/plugins/generic/tuiotouch/qtuiohandler.cpp
@@ -169,7 +169,7 @@ void QTuioHandler::processPackets()
messages.push_back(msg);
}
- for (const QOscMessage &message : messages) {
+ for (const QOscMessage &message : qAsConst(messages)) {
if (message.addressPattern() == "/tuio/2Dcur") {
QList<QVariant> arguments = message.arguments();
if (arguments.count() == 0) {
@@ -368,12 +368,12 @@ void QTuioHandler::process2DCurFseq(const QOscMessage &message)
QList<QWindowSystemInterface::TouchPoint> tpl;
tpl.reserve(m_activeCursors.size() + m_deadCursors.size());
- for (const QTuioCursor &tc : m_activeCursors) {
+ for (const QTuioCursor &tc : qAsConst(m_activeCursors)) {
QWindowSystemInterface::TouchPoint tp = cursorToTouchPoint(tc, win);
tpl.append(tp);
}
- for (const QTuioCursor &tc : m_deadCursors) {
+ for (const QTuioCursor &tc : qAsConst(m_deadCursors)) {
QWindowSystemInterface::TouchPoint tp = cursorToTouchPoint(tc, win);
tp.state = Qt::TouchPointReleased;
tpl.append(tp);
@@ -542,12 +542,12 @@ void QTuioHandler::process2DObjFseq(const QOscMessage &message)
QList<QWindowSystemInterface::TouchPoint> tpl;
tpl.reserve(m_activeTokens.size() + m_deadTokens.size());
- for (const QTuioToken & t : m_activeTokens) {
+ for (const QTuioToken & t : qAsConst(m_activeTokens)) {
QWindowSystemInterface::TouchPoint tp = tokenToTouchPoint(t, win);
tpl.append(tp);
}
- for (const QTuioToken & t : m_deadTokens) {
+ for (const QTuioToken & t : qAsConst(m_deadTokens)) {
QWindowSystemInterface::TouchPoint tp = tokenToTouchPoint(t, win);
tp.state = Qt::TouchPointReleased;
tp.velocity = QVector2D();
diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro
index 68bc2c3466..2e2f8600c3 100644
--- a/src/plugins/platforminputcontexts/compose/compose.pro
+++ b/src/plugins/platforminputcontexts/compose/compose.pro
@@ -3,18 +3,14 @@ TARGET = composeplatforminputcontextplugin
QT += core-private gui-private
SOURCES += $$PWD/qcomposeplatforminputcontextmain.cpp \
- $$PWD/qcomposeplatforminputcontext.cpp \
- $$PWD/generator/qtablegenerator.cpp \
+ $$PWD/qcomposeplatforminputcontext.cpp
-HEADERS += $$PWD/qcomposeplatforminputcontext.h \
- $$PWD/generator/qtablegenerator.h \
+HEADERS += $$PWD/qcomposeplatforminputcontext.h
QMAKE_USE_PRIVATE += xkbcommon
include($$OUT_PWD/../../../gui/qtgui-config.pri)
-DEFINES += X11_PREFIX='\\"$$QMAKE_X11_PREFIX\\"'
-
OTHER_FILES += $$PWD/compose.json
PLUGIN_TYPE = platforminputcontexts
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
deleted file mode 100644
index b5a0a5bbeb..0000000000
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ /dev/null
@@ -1,658 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtablegenerator.h"
-
-#include <QtCore/QByteArray>
-#include <QtCore/QTextCodec>
-#include <QtCore/QDebug>
-#include <QtCore/QDir>
-#include <QtCore/QStringList>
-#include <QtCore/QString>
-#include <QtCore/QSaveFile>
-#include <QtCore/QStandardPaths>
-#include <private/qcore_unix_p.h>
-
-#include <algorithm>
-
-#include <xkbcommon/xkbcommon.h>
-
-#include <locale.h> // LC_CTYPE
-#include <string.h> // strchr, strncmp, etc.
-#include <strings.h> // strncasecmp
-#include <clocale> // LC_CTYPE
-
-static const quint32 SupportedCacheVersion = 1;
-
-/*
- In short on how and why the "Compose" file is cached:
-
- The "Compose" file is large, for en_US it's likely located at:
- /usr/share/X11/locale/en_US.UTF-8/Compose
- and it has about 6000 string lines.
- Q(Gui)Applications parse this file each time they're created. On modern CPUs
- it incurs a 4-10 ms startup penalty of each Qt gui app, on older CPUs -
- tens of ms or more.
- Since the "Compose" file (almost) never changes using a pre-parsed
- cache file instead of the "Compose" file is a good idea to improve Qt5
- application startup time by about 5+ ms (or tens of ms on older CPUs).
-
- The cache file contains the contents of the QComposeCacheFileHeader struct at the
- beginning followed by the pre-parsed contents of the "Compose" file.
-
- struct QComposeCacheFileHeader stores
- (a) The cache version - in the unlikely event that some day one might need
- to break compatibility.
- (b) The (cache) file size.
- (c) The lastModified field tracks if anything changed since the last time
- the cache file was saved.
- If anything did change then we read the compose file and save (cache) it
- in binary/pre-parsed format, which should happen extremely rarely if at all.
-*/
-
-struct QComposeCacheFileHeader
-{
- quint32 cacheVersion;
- // The compiler will add 4 padding bytes anyway.
- // Reserve them explicitly to possibly use in the future.
- quint32 reserved;
- quint64 fileSize;
- qint64 lastModified;
-};
-
-// localHostName() copied from qtbase/src/corelib/io/qlockfile_unix.cpp
-static QByteArray localHostName()
-{
- QByteArray hostName(512, Qt::Uninitialized);
- if (gethostname(hostName.data(), hostName.size()) == -1)
- return QByteArray();
- hostName.truncate(strlen(hostName.data()));
- return hostName;
-}
-
-/*
- Reads metadata about the Compose file. Later used to determine if the
- compose cache should be updated. The fileSize field will be zero on failure.
-*/
-static QComposeCacheFileHeader readFileMetadata(const QString &path)
-{
- quint64 fileSize = 0;
- qint64 lastModified = 0;
- const QByteArray pathBytes = QFile::encodeName(path);
- QT_STATBUF st;
- if (QT_STAT(pathBytes.data(), &st) == 0) {
- lastModified = st.st_mtime;
- fileSize = st.st_size;
- }
- QComposeCacheFileHeader info = { 0, 0, fileSize, lastModified };
- return info;
-}
-
-static const QString getCacheFilePath()
-{
- QFile machineIdFile("/var/lib/dbus/machine-id");
- QString machineId;
- if (machineIdFile.exists()) {
- if (machineIdFile.open(QIODevice::ReadOnly))
- machineId = QString::fromLatin1(machineIdFile.readAll().trimmed());
- }
- if (machineId.isEmpty())
- machineId = localHostName();
- const QString dirPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
-
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- return dirPath + QLatin1String("/qt_compose_cache_big_endian_") + machineId;
- return dirPath + QLatin1String("/qt_compose_cache_little_endian_") + machineId;
-}
-
-// Returns empty vector on failure
-static QVector<QComposeTableElement> loadCache(const QComposeCacheFileHeader &composeInfo)
-{
- QVector<QComposeTableElement> vec;
- const QString cacheFilePath = getCacheFilePath();
- QFile inputFile(cacheFilePath);
-
- if (!inputFile.open(QIODevice::ReadOnly))
- return vec;
- QComposeCacheFileHeader cacheInfo;
- // use a "buffer" variable to make the line after this one more readable.
- char *buffer = reinterpret_cast<char*>(&cacheInfo);
-
- if (inputFile.read(buffer, sizeof cacheInfo) != sizeof cacheInfo)
- return vec;
- if (cacheInfo.fileSize == 0)
- return vec;
- // using "!=" just in case someone replaced with a backup that existed before
- if (cacheInfo.lastModified != composeInfo.lastModified)
- return vec;
- if (cacheInfo.cacheVersion != SupportedCacheVersion)
- return vec;
- const QByteArray pathBytes = QFile::encodeName(cacheFilePath);
- QT_STATBUF st;
- if (QT_STAT(pathBytes.data(), &st) != 0)
- return vec;
- const off_t fileSize = st.st_size;
- if (fileSize > 1024 * 1024 * 5) {
- // The cache file size is usually about 150KB, so if its size is over
- // say 5MB then somebody inflated the file, abort.
- return vec;
- }
- const off_t bufferSize = fileSize - (sizeof cacheInfo);
- const size_t elemSize = sizeof (struct QComposeTableElement);
- const int elemCount = bufferSize / elemSize;
- const QByteArray ba = inputFile.read(bufferSize);
- const char *data = ba.data();
- // Since we know the number of the (many) elements and their size in
- // advance calling vector.reserve(..) seems reasonable.
- vec.reserve(elemCount);
-
- for (int i = 0; i < elemCount; i++) {
- const QComposeTableElement *elem =
- reinterpret_cast<const QComposeTableElement*>(data + (i * elemSize));
- vec.push_back(*elem);
- }
- return vec;
-}
-
-// Returns true on success, false otherwise.
-static bool saveCache(const QComposeCacheFileHeader &info, const QVector<QComposeTableElement> &vec)
-{
- const QString filePath = getCacheFilePath();
-#if QT_CONFIG(temporaryfile)
- QSaveFile outputFile(filePath);
-#else
- QFile outputFile(filePath);
-#endif
- if (!outputFile.open(QIODevice::WriteOnly))
- return false;
- const char *data = reinterpret_cast<const char*>(&info);
-
- if (outputFile.write(data, sizeof info) != sizeof info)
- return false;
- data = reinterpret_cast<const char*>(vec.constData());
- const qint64 size = vec.size() * (sizeof (struct QComposeTableElement));
-
- if (outputFile.write(data, size) != size)
- return false;
-#if QT_CONFIG(temporaryfile)
- return outputFile.commit();
-#else
- return true;
-#endif
-}
-
-TableGenerator::TableGenerator() : m_state(NoErrors),
- m_systemComposeDir(QString())
-{
- initPossibleLocations();
- QString composeFilePath = findComposeFile();
-#ifdef DEBUG_GENERATOR
-// don't use cache when in debug mode.
- if (!composeFilePath.isEmpty())
- qDebug() << "Using Compose file from: " << composeFilePath;
-#else
- QComposeCacheFileHeader fileInfo = readFileMetadata(composeFilePath);
- if (fileInfo.fileSize != 0)
- m_composeTable = loadCache(fileInfo);
-#endif
- if (m_composeTable.isEmpty() && cleanState()) {
- if (composeFilePath.isEmpty()) {
- m_state = MissingComposeFile;
- } else {
- QFile composeFile(composeFilePath);
- composeFile.open(QIODevice::ReadOnly);
- parseComposeFile(&composeFile);
- orderComposeTable();
- if (m_composeTable.isEmpty()) {
- m_state = EmptyTable;
-#ifndef DEBUG_GENERATOR
-// don't save cache when in debug mode
- } else {
- fileInfo.cacheVersion = SupportedCacheVersion;
- saveCache(fileInfo, m_composeTable);
-#endif
- }
- }
- }
-#ifdef DEBUG_GENERATOR
- printComposeTable();
-#endif
-}
-
-void TableGenerator::initPossibleLocations()
-{
- // Compose files come as a part of Xlib library. Xlib doesn't provide
- // a mechanism how to retrieve the location of these files reliably, since it was
- // never meant for external software to parse compose tables directly. Best we
- // can do is to hardcode search paths. To add an extra system path use
- // the QTCOMPOSE environment variable
- m_possibleLocations.reserve(7);
- if (qEnvironmentVariableIsSet("QTCOMPOSE"))
- m_possibleLocations.append(QString::fromLocal8Bit(qgetenv("QTCOMPOSE")));
- m_possibleLocations.append(QStringLiteral("/usr/share/X11/locale"));
- m_possibleLocations.append(QStringLiteral("/usr/local/share/X11/locale"));
- m_possibleLocations.append(QStringLiteral("/usr/lib/X11/locale"));
- m_possibleLocations.append(QStringLiteral("/usr/local/lib/X11/locale"));
- m_possibleLocations.append(QStringLiteral(X11_PREFIX "/share/X11/locale"));
- m_possibleLocations.append(QStringLiteral(X11_PREFIX "/lib/X11/locale"));
-}
-
-QString TableGenerator::findComposeFile()
-{
- // check if XCOMPOSEFILE points to a Compose file
- if (qEnvironmentVariableIsSet("XCOMPOSEFILE")) {
- const QString path = QFile::decodeName(qgetenv("XCOMPOSEFILE"));
- if (QFile::exists(path))
- return path;
- else
- qWarning("$XCOMPOSEFILE doesn't point to an existing file");
- }
-
- // check if user’s home directory has a file named .XCompose
- if (cleanState()) {
- QString path = qgetenv("HOME") + QLatin1String("/.XCompose");
- if (QFile::exists(path))
- return path;
- }
-
- // check for the system provided compose files
- if (cleanState()) {
- QString table = composeTableForLocale();
- if (cleanState()) {
- if (table.isEmpty())
- // no table mappings for the system's locale in the compose.dir
- m_state = UnsupportedLocale;
- else {
- QString path = QDir(systemComposeDir()).filePath(table);
- if (QFile::exists(path))
- return path;
- }
- }
- }
- return QString();
-}
-
-QString TableGenerator::composeTableForLocale()
-{
- QByteArray loc = locale().toUpper().toUtf8();
- QString table = readLocaleMappings(loc);
- if (table.isEmpty())
- table = readLocaleMappings(readLocaleAliases(loc));
- return table;
-}
-
-bool TableGenerator::findSystemComposeDir()
-{
- bool found = false;
- for (int i = 0; i < m_possibleLocations.size(); ++i) {
- QString path = m_possibleLocations.at(i);
- if (QFile::exists(path + QLatin1String("/compose.dir"))) {
- m_systemComposeDir = path;
- found = true;
- break;
- }
- }
-
- if (!found) {
- // should we ask to report this in the qt bug tracker?
- m_state = UnknownSystemComposeDir;
- qWarning("Qt Warning: Could not find a location of the system's Compose files. "
- "Consider setting the QTCOMPOSE environment variable.");
- }
-
- return found;
-}
-
-QString TableGenerator::systemComposeDir()
-{
- if (m_systemComposeDir.isNull()
- && !findSystemComposeDir()) {
- return QLatin1String("$QTCOMPOSE");
- }
-
- return m_systemComposeDir;
-}
-
-QString TableGenerator::locale() const
-{
- char *name = setlocale(LC_CTYPE, (char *)0);
- return QLatin1String(name);
-}
-
-QString TableGenerator::readLocaleMappings(const QByteArray &locale)
-{
- QString file;
- if (locale.isEmpty())
- return file;
-
- QFile mappings(systemComposeDir() + QLatin1String("/compose.dir"));
- if (mappings.open(QIODevice::ReadOnly)) {
- const int localeNameLength = locale.size();
- const char * const localeData = locale.constData();
-
- char l[1024];
- // formating of compose.dir has some inconsistencies
- while (!mappings.atEnd()) {
- int read = mappings.readLine(l, sizeof(l));
- if (read <= 0)
- break;
-
- char *line = l;
- if (*line >= 'a' && *line <= 'z') {
- // file name
- while (*line && *line != ':' && *line != ' ' && *line != '\t')
- ++line;
- if (!*line)
- continue;
- const char * const composeFileNameEnd = line;
- *line = '\0';
- ++line;
-
- // locale name
- while (*line && (*line == ' ' || *line == '\t'))
- ++line;
- const char * const lc = line;
- while (*line && *line != ' ' && *line != '\t' && *line != '\n')
- ++line;
- *line = '\0';
- if (localeNameLength == (line - lc) && !strncasecmp(lc, localeData, line - lc)) {
- file = QString::fromLocal8Bit(l, composeFileNameEnd - l);
- break;
- }
- }
- }
- mappings.close();
- }
- return file;
-}
-
-QByteArray TableGenerator::readLocaleAliases(const QByteArray &locale)
-{
- QFile aliases(systemComposeDir() + QLatin1String("/locale.alias"));
- QByteArray fullLocaleName;
- if (aliases.open(QIODevice::ReadOnly)) {
- while (!aliases.atEnd()) {
- char l[1024];
- int read = aliases.readLine(l, sizeof(l));
- char *line = l;
- if (read && ((*line >= 'a' && *line <= 'z') ||
- (*line >= 'A' && *line <= 'Z'))) {
- const char *alias = line;
- while (*line && *line != ':' && *line != ' ' && *line != '\t')
- ++line;
- if (!*line)
- continue;
- *line = 0;
- if (locale.size() == (line - alias)
- && !strncasecmp(alias, locale.constData(), line - alias)) {
- // found a match for alias, read the real locale name
- ++line;
- while (*line && (*line == ' ' || *line == '\t'))
- ++line;
- const char *fullName = line;
- while (*line && *line != ' ' && *line != '\t' && *line != '\n')
- ++line;
- *line = 0;
- fullLocaleName = fullName;
-#ifdef DEBUG_GENERATOR
- qDebug() << "Alias for: " << alias << "is: " << fullLocaleName;
- break;
-#endif
- }
- }
- }
- aliases.close();
- }
- return fullLocaleName;
-}
-
-bool TableGenerator::processFile(const QString &composeFileName)
-{
- QFile composeFile(composeFileName);
- if (composeFile.open(QIODevice::ReadOnly)) {
- parseComposeFile(&composeFile);
- return true;
- }
- qWarning() << QString(QLatin1String("Qt Warning: Compose file: \"%1\" can't be found"))
- .arg(composeFile.fileName());
- return false;
-}
-
-TableGenerator::~TableGenerator()
-{
-}
-
-QVector<QComposeTableElement> TableGenerator::composeTable() const
-{
- return m_composeTable;
-}
-
-void TableGenerator::parseComposeFile(QFile *composeFile)
-{
-#ifdef DEBUG_GENERATOR
- qDebug() << "TableGenerator::parseComposeFile: " << composeFile->fileName();
-#endif
-
- char line[1024];
- while (!composeFile->atEnd()) {
- composeFile->readLine(line, sizeof(line));
- if (*line == '<')
- parseKeySequence(line);
- else if (!strncmp(line, "include", 7))
- parseIncludeInstruction(QString::fromLocal8Bit(line));
- }
-
- composeFile->close();
-}
-
-void TableGenerator::parseIncludeInstruction(QString line)
-{
- // Parse something that looks like:
- // include "/usr/share/X11/locale/en_US.UTF-8/Compose"
- QString quote = QStringLiteral("\"");
- line.remove(0, line.indexOf(quote) + 1);
- line.chop(line.length() - line.indexOf(quote));
-
- // expand substitutions if present
- line.replace(QLatin1String("%H"), QString(qgetenv("HOME")));
- line.replace(QLatin1String("%L"), systemComposeDir() + QLatin1Char('/') + composeTableForLocale());
- line.replace(QLatin1String("%S"), systemComposeDir());
-
- processFile(line);
-}
-
-ushort TableGenerator::keysymToUtf8(quint32 sym)
-{
- QByteArray chars;
- int bytes;
- chars.resize(8);
- bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size());
- if (bytes == -1)
- qWarning("TableGenerator::keysymToUtf8 - buffer too small");
-
- chars.resize(bytes-1);
-
-#ifdef DEBUG_GENERATOR
- QTextCodec *codec = QTextCodec::codecForLocale();
- qDebug() << QString("keysym - 0x%1 : utf8 - %2").arg(QString::number(sym, 16))
- .arg(codec->toUnicode(chars));
-#endif
- return QString::fromUtf8(chars).at(0).unicode();
-}
-
-static inline int fromBase8(const char *s, const char *end)
-{
- int result = 0;
- while (*s && s != end) {
- if (*s < '0' || *s > '7')
- return 0;
- result *= 8;
- result += *s - '0';
- ++s;
- }
- return result;
-}
-
-static inline int fromBase16(const char *s, const char *end)
-{
- int result = 0;
- while (*s && s != end) {
- result *= 16;
- if (*s >= '0' && *s <= '9')
- result += *s - '0';
- else if (*s >= 'a' && *s <= 'f')
- result += *s - 'a' + 10;
- else if (*s >= 'A' && *s <= 'F')
- result += *s - 'A' + 10;
- else
- return 0;
- ++s;
- }
- return result;
-}
-
-void TableGenerator::parseKeySequence(char *line)
-{
- // we are interested in the lines with the following format:
- // <Multi_key> <numbersign> <S> : "♬" U266c # BEAMED SIXTEENTH NOTE
- char *keysEnd = strchr(line, ':');
- if (!keysEnd)
- return;
-
- QComposeTableElement elem;
- // find the composed value - strings may be direct text encoded in the locale
- // for which the compose file is to be used, or an escaped octal or hexadecimal
- // character code. Octal codes are specified as "\123" and hexadecimal codes as "\0x123a".
- char *composeValue = strchr(keysEnd, '"');
- if (!composeValue)
- return;
- ++composeValue;
-
- char *composeValueEnd = strchr(composeValue, '"');
- if (!composeValueEnd)
- return;
-
- // if composed value is a quotation mark adjust the end pointer
- if (composeValueEnd[1] == '"')
- ++composeValueEnd;
-
- if (*composeValue == '\\' && composeValue[1] >= '0' && composeValue[1] <= '9') {
- // handle octal and hex code values
- char detectBase = composeValue[2];
- if (detectBase == 'x') {
- // hexadecimal character code
- elem.value = keysymToUtf8(fromBase16(composeValue + 3, composeValueEnd));
- } else {
- // octal character code
- elem.value = keysymToUtf8(fromBase8(composeValue + 1, composeValueEnd));
- }
- } else {
- // handle direct text encoded in the locale
- if (*composeValue == '\\')
- ++composeValue;
- elem.value = QString::fromLocal8Bit(composeValue, composeValueEnd - composeValue).at(0).unicode();
- ++composeValue;
- }
-
-#ifdef DEBUG_GENERATOR
- // find the comment
- elem.comment = QString::fromLocal8Bit(composeValueEnd + 1).trimmed();
-#endif
-
- // find the key sequence and convert to X11 keysym
- char *k = line;
- const char *kend = keysEnd;
-
- for (int i = 0; i < QT_KEYSEQUENCE_MAX_LEN; i++) {
- // find the next pair of angle brackets and get the contents within
- while (k < kend && *k != '<')
- ++k;
- char *sym = ++k;
- while (k < kend && *k != '>')
- ++k;
- *k = '\0';
- if (k < kend) {
- elem.keys[i] = xkb_keysym_from_name(sym, (xkb_keysym_flags)0);
- if (elem.keys[i] == XKB_KEY_NoSymbol) {
- if (!strcmp(sym, "dead_inverted_breve"))
- elem.keys[i] = XKB_KEY_dead_invertedbreve;
- else if (!strcmp(sym, "dead_double_grave"))
- elem.keys[i] = XKB_KEY_dead_doublegrave;
-#ifdef DEBUG_GENERATOR
- else
- qWarning() << QString("Qt Warning - invalid keysym: %1").arg(sym);
-#endif
- }
- } else {
- elem.keys[i] = 0;
- }
- }
- m_composeTable.append(elem);
-}
-
-void TableGenerator::printComposeTable() const
-{
-#ifdef DEBUG_GENERATOR
-# ifndef QT_NO_DEBUG_STREAM
- if (m_composeTable.isEmpty())
- return;
-
- QDebug ds = qDebug() << "output:\n";
- ds.nospace();
- const int tableSize = m_composeTable.size();
- for (int i = 0; i < tableSize; ++i) {
- const QComposeTableElement &elem = m_composeTable.at(i);
- ds << "{ {";
- for (int j = 0; j < QT_KEYSEQUENCE_MAX_LEN; j++) {
- ds << hex << showbase << elem.keys[j] << ", ";
- }
- ds << "}, " << hex << showbase << elem.value << ", \"\" }, // " << elem.comment << " \n";
- }
-# endif
-#endif
-}
-
-void TableGenerator::orderComposeTable()
-{
- // Stable-sorting to ensure that the item that appeared before the other in the
- // original container will still appear first after the sort. This property is
- // needed to handle the cases when user re-defines already defined key sequence
- std::stable_sort(m_composeTable.begin(), m_composeTable.end(), ByKeys());
-}
-
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
deleted file mode 100644
index 4f58358f4e..0000000000
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTABLEGENERATOR_H
-#define QTABLEGENERATOR_H
-
-#include <QtCore/QVector>
-#include <QtCore/QFile>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-
-#include <algorithm>
-
-static Q_CONSTEXPR int QT_KEYSEQUENCE_MAX_LEN = 6;
-
-//#define DEBUG_GENERATOR
-
-/* Whenever QComposeTableElement gets modified supportedCacheVersion
- from qtablegenerator.cpp must be bumped. */
-struct QComposeTableElement {
- uint keys[QT_KEYSEQUENCE_MAX_LEN];
- uint value;
-#ifdef DEBUG_GENERATOR
- QString comment;
-#endif
-};
-
-#ifndef DEBUG_GENERATOR
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(QComposeTableElement, Q_PRIMITIVE_TYPE);
-QT_END_NAMESPACE
-#endif
-
-struct ByKeys
-{
- using uint_array = uint[QT_KEYSEQUENCE_MAX_LEN];
- using result_type = bool;
-
- bool operator()(const uint_array &lhs, const uint_array &rhs) const Q_DECL_NOTHROW
- {
- return std::lexicographical_compare(lhs, lhs + QT_KEYSEQUENCE_MAX_LEN,
- rhs, rhs + QT_KEYSEQUENCE_MAX_LEN);
- }
-
- bool operator()(const uint_array &lhs, const QComposeTableElement &rhs) const Q_DECL_NOTHROW
- {
- return operator()(lhs, rhs.keys);
- }
-
- bool operator()(const QComposeTableElement &lhs, const uint_array &rhs) const Q_DECL_NOTHROW
- {
- return operator()(lhs.keys, rhs);
- }
-
- bool operator()(const QComposeTableElement &lhs, const QComposeTableElement &rhs) const Q_DECL_NOTHROW
- {
- return operator()(lhs.keys, rhs.keys);
- }
-};
-
-class TableGenerator
-{
-
-public:
- enum TableState
- {
- UnsupportedLocale,
- EmptyTable,
- UnknownSystemComposeDir,
- MissingComposeFile,
- NoErrors
- };
-
- TableGenerator();
- ~TableGenerator();
-
- void parseComposeFile(QFile *composeFile);
- void printComposeTable() const;
- void orderComposeTable();
-
- QVector<QComposeTableElement> composeTable() const;
- TableState tableState() const { return m_state; }
-
-protected:
- bool processFile(const QString &composeFileName);
- void parseKeySequence(char *line);
- void parseIncludeInstruction(QString line);
-
- QString findComposeFile();
- bool findSystemComposeDir();
- QString systemComposeDir();
- QString composeTableForLocale();
-
- ushort keysymToUtf8(quint32 sym);
-
- QString readLocaleMappings(const QByteArray &locale);
- QByteArray readLocaleAliases(const QByteArray &locale);
- void initPossibleLocations();
- bool cleanState() const { return m_state == NoErrors; }
- QString locale() const;
-
-private:
- QVector<QComposeTableElement> m_composeTable;
- TableState m_state;
- QString m_systemComposeDir;
- QList<QString> m_possibleLocations;
-};
-
-#endif // QTABLEGENERATOR_H
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
index 81a730232c..57fe7c2fa2 100644
--- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -36,131 +36,102 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
#include "qcomposeplatforminputcontext.h"
#include <QtCore/QCoreApplication>
#include <QtGui/QKeyEvent>
-#include <QtCore/QDebug>
-#include <algorithm>
+#include <locale.h>
QT_BEGIN_NAMESPACE
-//#define DEBUG_COMPOSING
+Q_LOGGING_CATEGORY(lcXkbCompose, "qt.xkb.compose")
-static const int ignoreKeys[] = {
- Qt::Key_Shift,
- Qt::Key_Control,
- Qt::Key_Meta,
- Qt::Key_Alt,
- Qt::Key_CapsLock,
- Qt::Key_Super_L,
- Qt::Key_Super_R,
- Qt::Key_Hyper_L,
- Qt::Key_Hyper_R,
- Qt::Key_Mode_switch
-};
+QComposeInputContext::QComposeInputContext()
+{
+ setObjectName(QStringLiteral("QComposeInputContext"));
+ qCDebug(lcXkbCompose, "using xkb compose input context");
+}
-static const int composingKeys[] = {
- Qt::Key_Multi_key,
- Qt::Key_Dead_Grave,
- Qt::Key_Dead_Acute,
- Qt::Key_Dead_Circumflex,
- Qt::Key_Dead_Tilde,
- Qt::Key_Dead_Macron,
- Qt::Key_Dead_Breve,
- Qt::Key_Dead_Abovedot,
- Qt::Key_Dead_Diaeresis,
- Qt::Key_Dead_Abovering,
- Qt::Key_Dead_Doubleacute,
- Qt::Key_Dead_Caron,
- Qt::Key_Dead_Cedilla,
- Qt::Key_Dead_Ogonek,
- Qt::Key_Dead_Iota,
- Qt::Key_Dead_Voiced_Sound,
- Qt::Key_Dead_Semivoiced_Sound,
- Qt::Key_Dead_Belowdot,
- Qt::Key_Dead_Hook,
- Qt::Key_Dead_Horn,
- Qt::Key_Dead_Stroke,
- Qt::Key_Dead_Abovecomma,
- Qt::Key_Dead_Abovereversedcomma,
- Qt::Key_Dead_Doublegrave,
- Qt::Key_Dead_Belowring,
- Qt::Key_Dead_Belowmacron,
- Qt::Key_Dead_Belowcircumflex,
- Qt::Key_Dead_Belowtilde,
- Qt::Key_Dead_Belowbreve,
- Qt::Key_Dead_Belowdiaeresis,
- Qt::Key_Dead_Invertedbreve,
- Qt::Key_Dead_Belowcomma,
- Qt::Key_Dead_Currency,
- Qt::Key_Dead_a,
- Qt::Key_Dead_A,
- Qt::Key_Dead_e,
- Qt::Key_Dead_E,
- Qt::Key_Dead_i,
- Qt::Key_Dead_I,
- Qt::Key_Dead_o,
- Qt::Key_Dead_O,
- Qt::Key_Dead_u,
- Qt::Key_Dead_U,
- Qt::Key_Dead_Small_Schwa,
- Qt::Key_Dead_Capital_Schwa,
- Qt::Key_Dead_Greek,
- Qt::Key_Dead_Lowline,
- Qt::Key_Dead_Aboveverticalline,
- Qt::Key_Dead_Belowverticalline,
- Qt::Key_Dead_Longsolidusoverlay
-};
+QComposeInputContext::~QComposeInputContext()
+{
+ xkb_compose_state_unref(m_composeState);
+ xkb_compose_table_unref(m_composeTable);
+}
-QComposeInputContext::QComposeInputContext()
- : m_tableState(TableGenerator::EmptyTable)
- , m_compositionTableInitialized(false)
+void QComposeInputContext::ensureInitialized()
{
- clearComposeBuffer();
+ if (m_initialized)
+ return;
+
+ if (!m_XkbContext) {
+ qCWarning(lcXkbCompose) << "error: xkb context has not been set on" << metaObject()->className();
+ return;
+ }
+
+ m_initialized = true;
+ const char *locale = setlocale(LC_CTYPE, "");
+ if (!locale)
+ locale = setlocale(LC_CTYPE, nullptr);
+ qCDebug(lcXkbCompose) << "detected locale (LC_CTYPE):" << locale;
+
+ m_composeTable = xkb_compose_table_new_from_locale(m_XkbContext, locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
+ if (m_composeTable)
+ m_composeState = xkb_compose_state_new(m_composeTable, XKB_COMPOSE_STATE_NO_FLAGS);
+
+ if (!m_composeTable) {
+ qCWarning(lcXkbCompose, "failed to create compose table");
+ return;
+ }
+ if (!m_composeState) {
+ qCWarning(lcXkbCompose, "failed to create compose state");
+ return;
+ }
}
bool QComposeInputContext::filterEvent(const QEvent *event)
{
- const QKeyEvent *keyEvent = (const QKeyEvent *)event;
- // should pass only the key presses
- if (keyEvent->type() != QEvent::KeyPress) {
+ auto keyEvent = static_cast<const QKeyEvent *>(event);
+ if (keyEvent->type() != QEvent::KeyPress)
return false;
- }
- // if there were errors when generating the compose table input
- // context should not try to filter anything, simply return false
- if (m_compositionTableInitialized && (m_tableState & TableGenerator::NoErrors) != TableGenerator::NoErrors)
+ if (!inputMethodAccepted())
return false;
- int keyval = keyEvent->key();
- int keysym = 0;
+ // lazy initialization - we don't want to do this on an app startup
+ ensureInitialized();
- if (ignoreKey(keyval))
+ if (!m_composeTable || !m_composeState)
return false;
- if (!composeKey(keyval) && keyEvent->text().isEmpty())
- return false;
+ xkb_compose_state_feed(m_composeState, keyEvent->nativeVirtualKey());
- keysym = keyEvent->nativeVirtualKey();
+ switch (xkb_compose_state_get_status(m_composeState)) {
+ case XKB_COMPOSE_COMPOSING:
+ return true;
+ case XKB_COMPOSE_CANCELLED:
+ reset();
+ return false;
+ case XKB_COMPOSE_COMPOSED:
+ {
+ const int size = xkb_compose_state_get_utf8(m_composeState, nullptr, 0);
+ QVarLengthArray<char, 32> buffer(size + 1);
+ xkb_compose_state_get_utf8(m_composeState, buffer.data(), buffer.size());
+ QString composedText = QString::fromUtf8(buffer.constData());
- int nCompose = 0;
- while (nCompose < QT_KEYSEQUENCE_MAX_LEN && m_composeBuffer[nCompose] != 0)
- nCompose++;
+ QInputMethodEvent event;
+ event.setCommitString(composedText);
+ QCoreApplication::sendEvent(m_focusObject, &event);
- if (nCompose == QT_KEYSEQUENCE_MAX_LEN) {
reset();
- nCompose = 0;
- }
-
- m_composeBuffer[nCompose] = keysym;
- // check sequence
- if (checkComposeTable())
return true;
-
- return false;
+ }
+ case XKB_COMPOSE_NOTHING:
+ return false;
+ default:
+ Q_UNREACHABLE();
+ return false;
+ }
}
bool QComposeInputContext::isValid() const
@@ -175,7 +146,8 @@ void QComposeInputContext::setFocusObject(QObject *object)
void QComposeInputContext::reset()
{
- clearComposeBuffer();
+ if (m_composeState)
+ xkb_compose_state_reset(m_composeState);
}
void QComposeInputContext::update(Qt::InputMethodQueries q)
@@ -183,125 +155,4 @@ void QComposeInputContext::update(Qt::InputMethodQueries q)
QPlatformInputContext::update(q);
}
-static bool isDuplicate(const QComposeTableElement &lhs, const QComposeTableElement &rhs)
-{
- return std::equal(lhs.keys, lhs.keys + QT_KEYSEQUENCE_MAX_LEN,
- QT_MAKE_CHECKED_ARRAY_ITERATOR(rhs.keys, QT_KEYSEQUENCE_MAX_LEN));
-}
-
-bool QComposeInputContext::checkComposeTable()
-{
- if (!m_compositionTableInitialized) {
- TableGenerator reader;
- m_tableState = reader.tableState();
-
- m_compositionTableInitialized = true;
- if ((m_tableState & TableGenerator::NoErrors) == TableGenerator::NoErrors) {
- m_composeTable = reader.composeTable();
- } else {
-#ifdef DEBUG_COMPOSING
- qDebug( "### FAILED_PARSING ###" );
-#endif
- // if we have errors, don' try to look things up anyways.
- reset();
- return false;
- }
- }
- Q_ASSERT(!m_composeTable.isEmpty());
- QVector<QComposeTableElement>::const_iterator it =
- std::lower_bound(m_composeTable.constBegin(), m_composeTable.constEnd(), m_composeBuffer, ByKeys());
-
- // prevent dereferencing an 'end' iterator, which would result in a crash
- if (it == m_composeTable.constEnd())
- it -= 1;
-
- QComposeTableElement elem = *it;
- // would be nicer if qLowerBound had API that tells if the item was actually found
- if (m_composeBuffer[0] != elem.keys[0]) {
-#ifdef DEBUG_COMPOSING
- qDebug( "### no match ###" );
-#endif
- reset();
- return false;
- }
- // check if compose buffer is matched
- for (int i=0; i < QT_KEYSEQUENCE_MAX_LEN; i++) {
-
- // check if partial match
- if (m_composeBuffer[i] == 0 && elem.keys[i]) {
-#ifdef DEBUG_COMPOSING
- qDebug("### partial match ###");
-#endif
- return true;
- }
-
- if (m_composeBuffer[i] != elem.keys[i]) {
-#ifdef DEBUG_COMPOSING
- qDebug("### different entry ###");
-#endif
- reset();
- return i != 0;
- }
- }
-#ifdef DEBUG_COMPOSING
- qDebug("### match exactly ###");
-#endif
-
- // check if the key sequence is overwriten - see the comment in
- // TableGenerator::orderComposeTable()
- int next = 1;
- do {
- // if we are at the end of the table, then we have nothing to do here
- if (it + next != m_composeTable.constEnd()) {
- QComposeTableElement nextElem = *(it + next);
- if (isDuplicate(elem, nextElem)) {
- elem = nextElem;
- next++;
- continue;
- } else {
- break;
- }
- }
- break;
- } while (true);
-
- commitText(elem.value);
- reset();
-
- return true;
-}
-
-void QComposeInputContext::commitText(uint character) const
-{
- QInputMethodEvent event;
- event.setCommitString(QChar(character));
- QCoreApplication::sendEvent(m_focusObject, &event);
-}
-
-bool QComposeInputContext::ignoreKey(int keyval) const
-{
- for (uint i = 0; i < (sizeof(ignoreKeys) / sizeof(ignoreKeys[0])); i++)
- if (keyval == ignoreKeys[i])
- return true;
-
- return false;
-}
-
-bool QComposeInputContext::composeKey(int keyval) const
-{
- for (uint i = 0; i < (sizeof(composingKeys) / sizeof(composingKeys[0])); i++)
- if (keyval == composingKeys[i])
- return true;
-
- return false;
-}
-
-void QComposeInputContext::clearComposeBuffer()
-{
- for (uint i=0; i < (sizeof(m_composeBuffer) / sizeof(int)); i++)
- m_composeBuffer[i] = 0;
-}
-
-QComposeInputContext::~QComposeInputContext() {}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h
index 4830959665..b1de1b1094 100644
--- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -36,24 +36,24 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
#ifndef QCOMPOSEPLATFORMINPUTCONTEXT_H
#define QCOMPOSEPLATFORMINPUTCONTEXT_H
-#include <qpa/qplatforminputcontext.h>
+#include <QtCore/QLoggingCategory>
-#include <QtCore/QList>
+#include <qpa/qplatforminputcontext.h>
-#include "generator/qtablegenerator.h"
+#include <xkbcommon/xkbcommon-compose.h>
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcXkbCompose)
+
class QEvent;
class QComposeInputContext : public QPlatformInputContext
{
Q_OBJECT
-
public:
QComposeInputContext();
~QComposeInputContext();
@@ -62,21 +62,22 @@ public:
void setFocusObject(QObject *object) override;
void reset() override;
void update(Qt::InputMethodQueries) override;
+
bool filterEvent(const QEvent *event) override;
+ // This invokable is called from QXkbCommon::setXkbContext().
+ Q_INVOKABLE void setXkbContext(struct xkb_context *context) { m_XkbContext = context; }
+
protected:
- void clearComposeBuffer();
- bool ignoreKey(int keyval) const;
- bool composeKey(int keyval) const;
- bool checkComposeTable();
- void commitText(uint character) const;
+ void ensureInitialized();
private:
- QObject *m_focusObject;
- QVector<QComposeTableElement> m_composeTable;
- uint m_composeBuffer[QT_KEYSEQUENCE_MAX_LEN];
- TableGenerator::TableState m_tableState;
- bool m_compositionTableInitialized;
+ bool m_initialized = false;
+ xkb_context *m_context = nullptr;
+ xkb_compose_table *m_composeTable = nullptr;
+ xkb_compose_state *m_composeState = nullptr;
+ QObject *m_focusObject = nullptr;
+ struct xkb_context *m_XkbContext = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp
index 6b33df65b9..d062d4fd6a 100644
--- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -61,7 +61,7 @@ QComposeInputContext *QComposePlatformInputContextPlugin::create(const QString &
if (system.compare(system, QLatin1String("compose"), Qt::CaseInsensitive) == 0
|| system.compare(system, QLatin1String("xim"), Qt::CaseInsensitive) == 0)
return new QComposeInputContext;
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforminputcontexts/ibus/ibus.pro b/src/plugins/platforminputcontexts/ibus/ibus.pro
index 52836bb8b6..9ba2297e38 100644
--- a/src/plugins/platforminputcontexts/ibus/ibus.pro
+++ b/src/plugins/platforminputcontexts/ibus/ibus.pro
@@ -1,6 +1,6 @@
TARGET = ibusplatforminputcontextplugin
-QT += dbus gui-private
+QT += dbus gui-private xkbcommon_support-private
SOURCES += $$PWD/qibusplatforminputcontext.cpp \
$$PWD/qibusproxy.cpp \
$$PWD/qibusproxyportal.cpp \
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
index ca315840e2..f2429f24ff 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
@@ -47,7 +47,11 @@
#include <qpa/qplatformcursor.h>
#include <qpa/qplatformscreen.h>
-#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qwindowsysteminterface_p.h>
+
+#include <QtGui/private/qguiapplication_p.h>
+
+#include <QtXkbCommonSupport/private/qxkbcommon_p.h>
#include "qibusproxy.h"
#include "qibusproxyportal.h"
@@ -217,17 +221,14 @@ void QIBusPlatformInputContext::update(Qt::InputMethodQueries q)
&& (q.testFlag(Qt::ImSurroundingText)
|| q.testFlag(Qt::ImCursorPosition)
|| q.testFlag(Qt::ImAnchorPosition))) {
- QInputMethodQueryEvent srrndTextQuery(Qt::ImSurroundingText);
- QInputMethodQueryEvent cursorPosQuery(Qt::ImCursorPosition);
- QInputMethodQueryEvent anchorPosQuery(Qt::ImAnchorPosition);
- QCoreApplication::sendEvent(input, &srrndTextQuery);
- QCoreApplication::sendEvent(input, &cursorPosQuery);
- QCoreApplication::sendEvent(input, &anchorPosQuery);
+ QInputMethodQueryEvent query(Qt::ImSurroundingText | Qt::ImCursorPosition | Qt::ImAnchorPosition);
+
+ QCoreApplication::sendEvent(input, &query);
- QString surroundingText = srrndTextQuery.value(Qt::ImSurroundingText).toString();
- uint cursorPosition = cursorPosQuery.value(Qt::ImCursorPosition).toUInt();
- uint anchorPosition = anchorPosQuery.value(Qt::ImAnchorPosition).toUInt();
+ QString surroundingText = query.value(Qt::ImSurroundingText).toString();
+ uint cursorPosition = query.value(Qt::ImCursorPosition).toUInt();
+ uint anchorPosition = query.value(Qt::ImAnchorPosition).toUInt();
QIBusText text;
text.text = surroundingText;
@@ -336,14 +337,12 @@ void QIBusPlatformInputContext::forwardKeyEvent(uint keyval, uint keycode, uint
if (!input)
return;
- if (debug)
- qDebug() << "forwardKeyEvent" << keyval << keycode << state;
-
QEvent::Type type = QEvent::KeyPress;
if (state & IBUS_RELEASE_MASK)
type = QEvent::KeyRelease;
state &= ~IBUS_RELEASE_MASK;
+ keycode += 8;
Qt::KeyboardModifiers modifiers = Qt::NoModifier;
if (state & IBUS_SHIFT_MASK)
@@ -355,7 +354,13 @@ void QIBusPlatformInputContext::forwardKeyEvent(uint keyval, uint keycode, uint
if (state & IBUS_META_MASK)
modifiers |= Qt::MetaModifier;
- QKeyEvent event(type, keyval, modifiers, QString(keyval));
+ int qtcode = QXkbCommon::keysymToQtKey(keyval, modifiers);
+ QString text = QXkbCommon::lookupStringNoKeysymTransformations(keyval);
+
+ if (debug)
+ qDebug() << "forwardKeyEvent" << keyval << keycode << state << modifiers << qtcode << text;
+
+ QKeyEvent event(type, qtcode, modifiers, keycode, keyval, state, text);
QCoreApplication::sendEvent(input, &event);
}
@@ -422,9 +427,9 @@ bool QIBusPlatformInputContext::filterEvent(const QEvent *event)
QDBusPendingReply<bool> reply = d->context->ProcessKeyEvent(sym, code - 8, ibusState);
if (m_eventFilterUseSynchronousMode || reply.isFinished()) {
- bool retval = reply.value();
- qCDebug(qtQpaInputMethods) << "filterEvent return" << code << sym << state << retval;
- return retval;
+ bool filtered = reply.value();
+ qCDebug(qtQpaInputMethods) << "filterEvent return" << code << sym << state << filtered;
+ return filtered;
}
Qt::KeyboardModifiers modifiers = keyEvent->modifiers();
@@ -494,23 +499,22 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal
const bool isAutoRepeat = args.at(7).toBool();
// copied from QXcbKeyboard::handleKeyEvent()
- bool retval = reply.value();
- qCDebug(qtQpaInputMethods) << "filterEventFinished return" << code << sym << state << retval;
- if (!retval) {
+ bool filtered = reply.value();
+ qCDebug(qtQpaInputMethods) << "filterEventFinished return" << code << sym << state << filtered;
+ if (!filtered) {
#ifndef QT_NO_CONTEXTMENU
if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu
&& window != NULL) {
const QPoint globalPos = window->screen()->handle()->cursor()->pos();
const QPoint pos = window->mapFromGlobal(globalPos);
-#ifndef QT_NO_CONTEXTMENU
- QWindowSystemInterface::handleContextMenuEvent(window, false, pos,
- globalPos, modifiers);
-#endif
+ QWindowSystemInterfacePrivate::ContextMenuEvent contextMenuEvent(window, false, pos,
+ globalPos, modifiers);
+ QGuiApplicationPrivate::processWindowSystemEvent(&contextMenuEvent);
}
-#endif // QT_NO_CONTEXTMENU
- QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
- code, sym, state, string, isAutoRepeat);
-
+#endif
+ QWindowSystemInterfacePrivate::KeyEvent keyEvent(window, time, type, qtcode, modifiers,
+ code, sym, state, string, isAutoRepeat);
+ QGuiApplicationPrivate::processWindowSystemEvent(&keyEvent);
}
call->deleteLater();
}
diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro
index ed6b1b8702..56a39a49e7 100644
--- a/src/plugins/platforminputcontexts/platforminputcontexts.pro
+++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro
@@ -1,10 +1,11 @@
TEMPLATE = subdirs
QT_FOR_CONFIG += gui-private
-qtHaveModule(dbus) {
-!mac:!win32:SUBDIRS += ibus
-}
-
-qtConfig(xcb): SUBDIRS += compose
+qtConfig(xkbcommon) {
+ SUBDIRS += compose
+ qtHaveModule(dbus) {
+ !macos:!win32:SUBDIRS += ibus
+ }
+}
diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro
index 73db9e93a3..78632a9bea 100644
--- a/src/plugins/platforms/android/android.pro
+++ b/src/plugins/platforms/android/android.pro
@@ -20,6 +20,7 @@ INCLUDEPATH += \
$$QT_SOURCE_TREE/src/3rdparty/android
SOURCES += $$PWD/androidplatformplugin.cpp \
+ $$PWD/androidcontentfileengine.cpp \
$$PWD/androiddeadlockprotector.cpp \
$$PWD/androidjnimain.cpp \
$$PWD/androidjniaccessibility.cpp \
@@ -46,9 +47,11 @@ SOURCES += $$PWD/androidplatformplugin.cpp \
$$PWD/qandroidplatformopenglcontext.cpp \
$$PWD/qandroidplatformforeignwindow.cpp \
$$PWD/qandroideventdispatcher.cpp \
- $$PWD/qandroidplatformoffscreensurface.cpp
+ $$PWD/qandroidplatformoffscreensurface.cpp \
+ $$PWD/qandroidplatformfiledialoghelper.cpp
HEADERS += $$PWD/qandroidplatformintegration.h \
+ $$PWD/androidcontentfileengine.h \
$$PWD/androiddeadlockprotector.h \
$$PWD/androidjnimain.h \
$$PWD/androidjniaccessibility.h \
@@ -75,7 +78,8 @@ HEADERS += $$PWD/qandroidplatformintegration.h \
$$PWD/qandroidplatformopenglcontext.h \
$$PWD/qandroidplatformforeignwindow.h \
$$PWD/qandroideventdispatcher.h \
- $$PWD/qandroidplatformoffscreensurface.h
+ $$PWD/qandroidplatformoffscreensurface.h \
+ $$PWD/qandroidplatformfiledialoghelper.h
qtConfig(android-style-assets): SOURCES += $$PWD/extract.cpp
else: SOURCES += $$PWD/extract-dummy.cpp
diff --git a/src/plugins/platforms/android/androidcontentfileengine.cpp b/src/plugins/platforms/android/androidcontentfileengine.cpp
new file mode 100644
index 0000000000..1444407195
--- /dev/null
+++ b/src/plugins/platforms/android/androidcontentfileengine.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Volker Krause <vkrause@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "androidcontentfileengine.h"
+
+#include <private/qjni_p.h>
+#include <private/qjnihelpers_p.h>
+
+#include <QDebug>
+
+AndroidContentFileEngine::AndroidContentFileEngine(const QString &fileName)
+ : QFSFileEngine(fileName)
+{
+}
+
+bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
+{
+ QString openModeStr;
+ if (openMode & QFileDevice::ReadOnly) {
+ openModeStr += QLatin1Char('r');
+ }
+ if (openMode & QFileDevice::WriteOnly) {
+ openModeStr += QLatin1Char('w');
+ }
+ if (openMode & QFileDevice::Truncate) {
+ openModeStr += QLatin1Char('t');
+ } else if (openMode & QFileDevice::Append) {
+ openModeStr += QLatin1Char('a');
+ }
+
+ const auto fd = QJNIObjectPrivate::callStaticMethod<jint>("org/qtproject/qt5/android/QtNative",
+ "openFdForContentUrl",
+ "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I",
+ QtAndroidPrivate::context(),
+ QJNIObjectPrivate::fromString(fileName(DefaultName)).object(),
+ QJNIObjectPrivate::fromString(openModeStr).object());
+
+ if (fd < 0) {
+ return false;
+ }
+
+ return QFSFileEngine::open(openMode, fd, QFile::AutoCloseHandle);
+}
+
+
+AndroidContentFileEngineHandler::AndroidContentFileEngineHandler() = default;
+AndroidContentFileEngineHandler::~AndroidContentFileEngineHandler() = default;
+
+QAbstractFileEngine* AndroidContentFileEngineHandler::create(const QString &fileName) const
+{
+ if (!fileName.startsWith(QLatin1String("content"))) {
+ return nullptr;
+ }
+
+ return new AndroidContentFileEngine(fileName);
+}
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_dummy.cpp b/src/plugins/platforms/android/androidcontentfileengine.h
index 78b289ea49..db3def03d6 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration_dummy.cpp
+++ b/src/plugins/platforms/android/androidcontentfileengine.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 Volker Krause <vkrause@kde.org>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -37,9 +37,24 @@
**
****************************************************************************/
-#include "qoffscreenintegration.h"
+#ifndef ANDROIDCONTENTFILEENGINE_H
+#define ANDROIDCONTENTFILEENGINE_H
-QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration()
+#include <private/qfsfileengine_p.h>
+
+class AndroidContentFileEngine : public QFSFileEngine
+{
+public:
+ AndroidContentFileEngine(const QString &fileName);
+ bool open(QIODevice::OpenMode openMode) override;
+};
+
+class AndroidContentFileEngineHandler : public QAbstractFileEngineHandler
{
- return new QOffscreenIntegration;
-}
+public:
+ AndroidContentFileEngineHandler();
+ ~AndroidContentFileEngineHandler();
+ QAbstractFileEngine *create(const QString &fileName) const override;
+};
+
+#endif // ANDROIDCONTENTFILEENGINE_H
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index 309e41bfd6..d4b7f38bf6 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -329,10 +329,7 @@ if (!clazz) { \
GET_AND_CHECK_STATIC_METHOD(m_setFocusedMethodID, nodeInfoClass, "setFocused", "(Z)V");
GET_AND_CHECK_STATIC_METHOD(m_setScrollableMethodID, nodeInfoClass, "setScrollable", "(Z)V");
GET_AND_CHECK_STATIC_METHOD(m_setVisibleToUserMethodID, nodeInfoClass, "setVisibleToUser", "(Z)V");
-
- if (QtAndroidPrivate::androidSdkVersion() >= 18) {
- GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V");
- }
+ GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V");
return true;
}
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 74edfd8356..6ae429b24e 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -49,6 +49,7 @@
#include "androidjniinput.h"
#include "androidjniclipboard.h"
#include "androidjnimenu.h"
+#include "androidcontentfileengine.h"
#include "androiddeadlockprotector.h"
#include "qandroidplatformdialoghelpers.h"
#include "qandroidplatformintegration.h"
@@ -116,6 +117,7 @@ static double m_scaledDensity = 0;
static double m_density = 1.0;
static AndroidAssetsFileEngineHandler *m_androidAssetsFileEngineHandler = nullptr;
+static AndroidContentFileEngineHandler *m_androidContentFileEngineHandler = nullptr;
@@ -445,6 +447,7 @@ static jboolean startQtAndroidPlugin(JNIEnv *env, jobject /*object*/, jstring pa
{
m_androidPlatformIntegration = nullptr;
m_androidAssetsFileEngineHandler = new AndroidAssetsFileEngineHandler();
+ m_androidContentFileEngineHandler = new AndroidContentFileEngineHandler();
m_mainLibraryHnd = nullptr;
{ // Set env. vars
const char *nativeString = env->GetStringUTFChars(environmentString, 0);
@@ -555,6 +558,8 @@ static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/)
m_androidPlatformIntegration = nullptr;
delete m_androidAssetsFileEngineHandler;
m_androidAssetsFileEngineHandler = nullptr;
+ delete m_androidContentFileEngineHandler;
+ m_androidContentFileEngineHandler = nullptr;
}
static void terminateQt(JNIEnv *env, jclass /*clazz*/)
diff --git a/src/plugins/platforms/android/extract-dummy.cpp b/src/plugins/platforms/android/extract-dummy.cpp
index d07fbe1ba7..fdce8ec64c 100644
--- a/src/plugins/platforms/android/extract-dummy.cpp
+++ b/src/plugins/platforms/android/extract-dummy.cpp
@@ -40,16 +40,6 @@
#include <jni.h>
#include <extract.h>
-extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo(JNIEnv *, jobject, Res_png_9patch*)
-{
- return 0;
-}
-
-extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractChunkInfo(JNIEnv *, jobject, jbyteArray)
-{
- return 0;
-}
-
extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo20(JNIEnv *, jobject, long)
{
return 0;
diff --git a/src/plugins/platforms/android/extract.cpp b/src/plugins/platforms/android/extract.cpp
index 2f2ffa7126..acffa353f1 100644
--- a/src/plugins/platforms/android/extract.cpp
+++ b/src/plugins/platforms/android/extract.cpp
@@ -48,46 +48,6 @@
#define LOG_TAG "extractSyleInfo"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
-extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo(JNIEnv * env, jobject, Res_png_9patch* chunk)
-{
- Res_png_9patch::deserialize(chunk);
- //printChunkInformation(chunk);
- jintArray result;
- size_t size = 3+chunk->numXDivs+chunk->numYDivs+chunk->numColors;
- result = env->NewIntArray(size);
- if (!result)
- return 0;
-
- jint *data = (jint*)malloc(sizeof(jint)*size);
- size_t pos = 0;
- data[pos++]=chunk->numXDivs;
- data[pos++]=chunk->numYDivs;
- data[pos++]=chunk->numColors;
- for (int x = 0; x <chunk->numXDivs; x ++)
- data[pos++]=chunk->xDivs[x];
- for (int y = 0; y <chunk->numYDivs; y ++)
- data[pos++]=chunk->yDivs[y];
- for (int c = 0; c <chunk->numColors; c ++)
- data[pos++]=chunk->colors[c];
- env->SetIntArrayRegion(result, 0, size, data);
- free(data);
- return result;
-}
-
-extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractChunkInfo(JNIEnv * env, jobject obj, jbyteArray chunkObj)
-{
- size_t chunkSize = env->GetArrayLength(chunkObj);
- void* storage = alloca(chunkSize);
- env->GetByteArrayRegion(chunkObj, 0, chunkSize,
- reinterpret_cast<jbyte*>(storage));
-
- if (!env->ExceptionCheck())
- return Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo(env, obj, static_cast<Res_png_9patch*>(storage));
- else
- env->ExceptionClear();
- return 0;
-}
-
// The following part was shamelessly stolen from ResourceTypes.cpp from Android's sources
/*
* Copyright (C) 2005 The Android Open Source Project
diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp
new file mode 100644
index 0000000000..4fb271a75c
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB)
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformfiledialoghelper.h"
+
+#include <androidjnimain.h>
+#include <private/qjni_p.h>
+#include <jni.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtAndroidFileDialogHelper {
+
+#define RESULT_OK -1
+#define REQUEST_CODE 1305 // Arbitrary
+
+QAndroidPlatformFileDialogHelper::QAndroidPlatformFileDialogHelper()
+ : QPlatformFileDialogHelper()
+ , m_selectedFile()
+{
+}
+
+bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, jint resultCode, jobject data)
+{
+ if (requestCode != REQUEST_CODE)
+ return false;
+
+ if (resultCode == RESULT_OK) {
+ const QJNIObjectPrivate intent = QJNIObjectPrivate::fromLocalRef(data);
+ const QJNIObjectPrivate uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;");
+ const QString uriStr = uri.callObjectMethod("toString", "()Ljava/lang/String;").toString();
+ m_selectedFile = QUrl(uriStr);
+ Q_EMIT fileSelected(m_selectedFile);
+ Q_EMIT accept();
+ } else {
+ Q_EMIT reject();
+ }
+
+ return true;
+}
+
+bool QAndroidPlatformFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+{
+ Q_UNUSED(windowFlags)
+ Q_UNUSED(windowModality)
+ Q_UNUSED(parent)
+
+ if (options()->fileMode() != QFileDialogOptions::FileMode::ExistingFile)
+ return false;
+
+ QtAndroidPrivate::registerActivityResultListener(this);
+
+ const QJNIObjectPrivate ACTION_OPEN_DOCUMENT = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "ACTION_OPEN_DOCUMENT", "Ljava/lang/String;");
+ QJNIObjectPrivate intent("android/content/Intent", "(Ljava/lang/String;)V", ACTION_OPEN_DOCUMENT.object());
+ const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "CATEGORY_OPENABLE", "Ljava/lang/String;");
+ intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;", CATEGORY_OPENABLE.object());
+ intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QJNIObjectPrivate::fromString(QStringLiteral("*/*")).object());
+
+ const QJNIObjectPrivate activity(QtAndroid::activity());
+ activity.callMethod<void>("startActivityForResult", "(Landroid/content/Intent;I)V", intent.object(), REQUEST_CODE);
+
+ return true;
+}
+
+void QAndroidPlatformFileDialogHelper::exec()
+{
+}
+
+void QAndroidPlatformFileDialogHelper::hide()
+{
+}
+
+QString QAndroidPlatformFileDialogHelper::selectedNameFilter() const
+{
+ return QString();
+}
+
+void QAndroidPlatformFileDialogHelper::selectNameFilter(const QString &filter)
+{
+ Q_UNUSED(filter)
+}
+
+void QAndroidPlatformFileDialogHelper::setFilter()
+{
+}
+
+QList<QUrl> QAndroidPlatformFileDialogHelper::selectedFiles() const
+{
+ return {m_selectedFile};
+}
+
+void QAndroidPlatformFileDialogHelper::selectFile(const QUrl &file)
+{
+ Q_UNUSED(file)
+}
+
+QUrl QAndroidPlatformFileDialogHelper::directory() const
+{
+ return QUrl();
+}
+
+void QAndroidPlatformFileDialogHelper::setDirectory(const QUrl &directory)
+{
+ Q_UNUSED(directory)
+}
+
+bool QAndroidPlatformFileDialogHelper::defaultNameFilterDisables() const
+{
+ return false;
+}
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h
new file mode 100644
index 0000000000..e445aa2fef
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB)
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMFILEDIALOGHELPER_H
+#define QANDROIDPLATFORMFILEDIALOGHELPER_H
+
+#include <jni.h>
+#include <qpa/qplatformdialoghelper.h>
+#include <QtCore/private/qjnihelpers_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtAndroidFileDialogHelper {
+
+class QAndroidPlatformFileDialogHelper: public QPlatformFileDialogHelper, public QtAndroidPrivate::ActivityResultListener
+{
+ Q_OBJECT
+
+public:
+ QAndroidPlatformFileDialogHelper();
+ void exec() override;
+
+ bool show(Qt::WindowFlags windowFlags,
+ Qt::WindowModality windowModality,
+ QWindow *parent) override;
+ void hide() override;
+
+ QString selectedNameFilter() const override;
+ void selectNameFilter(const QString &filter) override;
+ void setFilter() override;
+ QList<QUrl> selectedFiles() const override;
+ void selectFile(const QUrl &file) override;
+ QUrl directory() const override;
+ void setDirectory(const QUrl &directory) override;
+ bool defaultNameFilterDisables() const override;
+ bool handleActivityResult(jint requestCode, jint resultCode, jobject data) override;
+
+private:
+ QUrl m_selectedFile;
+};
+
+}
+QT_END_NAMESPACE
+
+#endif // QANDROIDPLATFORMFILEDIALOGHELPER_H
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index b891407c44..a78a62337f 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -44,6 +44,7 @@
#include "qandroidplatformmenu.h"
#include "qandroidplatformmenuitem.h"
#include "qandroidplatformdialoghelpers.h"
+#include "qandroidplatformfiledialoghelper.h"
#include <QCoreApplication>
#include <QDebug>
@@ -512,6 +513,8 @@ bool QAndroidPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType t
{
if (type == MessageDialog)
return qEnvironmentVariableIntValue("QT_USE_ANDROID_NATIVE_DIALOGS") == 1;
+ if (type == FileDialog)
+ return true;
return false;
}
@@ -520,6 +523,8 @@ QPlatformDialogHelper *QAndroidPlatformTheme::createPlatformDialogHelper(QPlatfo
switch (type) {
case MessageDialog:
return new QtAndroidDialogHelpers::QAndroidPlatformMessageDialogHelper;
+ case FileDialog:
+ return new QtAndroidFileDialogHelper::QAndroidPlatformFileDialogHelper;
default:
return 0;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index f26263261c..f0ef70e3a3 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -51,6 +51,19 @@ QT_USE_NAMESPACE
#ifndef QT_NO_ACCESSIBILITY
+/**
+ * Converts between absolute character offsets and line numbers of a
+ * QAccessibleTextInterface. Works in exactly one of two modes:
+ *
+ * - Pass *line == -1 in order to get a line containing character at the given
+ * *offset
+ * - Pass *offset == -1 in order to get the offset of first character of the
+ * given *line
+ *
+ * You can optionally also pass non-NULL `start` and `end`, which will in both
+ * modes be filled with the offset of the first and last characters of the
+ * relevant line.
+ */
static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *offset, NSUInteger *start = 0, NSUInteger *end = 0)
{
Q_ASSERT(*line == -1 || *offset == -1);
@@ -224,7 +237,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
return [attributes autorelease];
}
-- (id)parentElement {
+- (id)accessibilityParent {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface || !iface->isValid())
return nil;
@@ -237,7 +250,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
if (QAccessibleInterface *parent = iface->parent()) {
if (parent->role() != QAccessible::Application) {
QAccessible::Id parentId = QAccessible::uniqueId(parent);
- return [QMacAccessibilityElement elementWithId: parentId];
+ return NSAccessibilityUnignoredAncestor([QMacAccessibilityElement elementWithId: parentId]);
}
}
@@ -245,12 +258,18 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
QPlatformWindow *platformWindow = window->handle();
if (platformWindow) {
QCocoaWindow *win = static_cast<QCocoaWindow*>(platformWindow);
- return qnsview_cast(win->view());
+ return NSAccessibilityUnignoredAncestor(qnsview_cast(win->view()));
}
}
return nil;
}
+- (NSRect)accessibilityFrame {
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
+ if (!iface || !iface->isValid())
+ return NSZeroRect;
+ return QCocoaScreen::mapToNative(iface->rect());
+}
- (id) minValueAttribute:(QAccessibleInterface*)iface {
if (QAccessibleValueInterface *val = iface->valueInterface())
@@ -285,13 +304,13 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute];
return @([focusedElement isEqual:self]);
} else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) {
- return NSAccessibilityUnignoredAncestor([self parentElement]);
+ return self.accessibilityParent;
} else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) {
// We're in the same window as our parent.
- return [[self parentElement] accessibilityAttributeValue:NSAccessibilityWindowAttribute];
+ return [[self accessibilityParent] accessibilityAttributeValue:NSAccessibilityWindowAttribute];
} else if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) {
// We're in the same top level element as our parent.
- return [[self parentElement] accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
+ return [[self accessibilityParent] accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
} else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) {
// The position in points of the element's lower-left corner in screen-relative coordinates
QPointF qtPosition = QRectF(iface->rect()).bottomLeft();
@@ -347,12 +366,8 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
return [NSValue valueWithRange: NSMakeRange(0, iface->text(QAccessible::Name).length())];
} else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) {
if (QAccessibleTextInterface *text = iface->textInterface()) {
- int line = 0; // true for all single line edits
- if (iface->state().multiLine) {
- int position = text->cursorPosition();
- convertLineOffset(text, &line, &position);
- }
- return @(line);
+ int position = text->cursorPosition();
+ return [self accessibilityAttributeValue:NSAccessibilityLineForIndexParameterizedAttribute forParameter:@(position)];
}
return nil;
} else if ([attribute isEqualToString:NSAccessibilityMinValueAttribute]) {
@@ -408,8 +423,11 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
int index = [parameter intValue];
if (index < 0 || index > iface->textInterface()->characterCount())
return nil;
- int line = -1;
- convertLineOffset(iface->textInterface(), &line, &index);
+ int line = 0; // true for all single line edits
+ if (iface->state().multiLine) {
+ line = -1;
+ convertLineOffset(iface->textInterface(), &line, &index);
+ }
return @(line);
}
if ([attribute isEqualToString: NSAccessibilityRangeForLineParameterizedAttribute]) {
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 93d95b38ea..fe1fc31553 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -86,7 +86,7 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context)
}
m_context = nativeHandle.value<QCocoaNativeContext>().context();
if (!m_context) {
- qCWarning(lcQpaOpenGLContext, "QCocoaNativeContext's NSOpenGLContext can not be null");
+ qCWarning(lcQpaOpenGLContext, "QCocoaNativeContext's NSOpenGLContext cannot be null");
return;
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 50adbad518..298d11fe08 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -217,6 +217,7 @@ QCocoaWindow::~QCocoaWindow()
}
[m_view release];
+ [m_nsWindow close];
[m_nsWindow release];
}
@@ -618,7 +619,7 @@ void QCocoaWindow::applyWindowState(Qt::WindowStates requestedState)
if (nsWindow.styleMask & NSWindowStyleMaskUtilityWindow
&& newState & (Qt::WindowMinimized | Qt::WindowFullScreen)) {
- qWarning() << window()->type() << "windows can not be made" << newState;
+ qWarning() << window()->type() << "windows cannot be made" << newState;
handleWindowStateChanged(HandleUnconditionally);
return;
}
diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm
index 490dbe8c4c..cb1799b039 100644
--- a/src/plugins/platforms/cocoa/qnsview_drawing.mm
+++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm
@@ -106,7 +106,7 @@
"_q_mac_wantsLayer", "QT_MAC_WANTS_LAYER");
if (wantsLayer != -1 && [self layerEnabledByMacOS]) {
- qCWarning(lcQpaDrawing) << "Layer-backing can not be explicitly controlled on 10.14 when built against the 10.14 SDK";
+ qCWarning(lcQpaDrawing) << "Layer-backing cannot be explicitly controlled on 10.14 when built against the 10.14 SDK";
return true;
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
index 24f82e7843..24051c352e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
@@ -423,7 +423,7 @@ void QEglFSKmsGbmScreen::updateFlipStatus()
if (m_flipPending)
return;
- for (const CloneDestination &d : m_cloneDests) {
+ for (const CloneDestination &d : qAsConst(m_cloneDests)) {
if (d.cloneFlipPending)
return;
}
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
index 7a871b3812..af6bd1d630 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
@@ -72,7 +72,7 @@ public:
QList<QPlatformScreen *> screens() const;
- QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE;
+ QFunctionPointer platformFunction(const QByteArray &function) const override;
private:
void createInputHandlers();
diff --git a/src/plugins/platforms/offscreen/offscreen.pro b/src/plugins/platforms/offscreen/offscreen.pro
index 392ee8bed1..f226132592 100644
--- a/src/plugins/platforms/offscreen/offscreen.pro
+++ b/src/plugins/platforms/offscreen/offscreen.pro
@@ -17,13 +17,10 @@ HEADERS = qoffscreenintegration.h \
OTHER_FILES += offscreen.json
-qtConfig(system-xcb):qtConfig(xlib):qtConfig(opengl):!qtConfig(opengles2) {
+qtConfig(xlib):qtConfig(opengl):!qtConfig(opengles2) {
SOURCES += qoffscreenintegration_x11.cpp
HEADERS += qoffscreenintegration_x11.h
QT += glx_support-private
- system(echo "Using X11 offscreen integration with GLX")
-} else {
- SOURCES += qoffscreenintegration_dummy.cpp
}
PLUGIN_TYPE = platforms
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
index ef3b0dd3ff..869e9228cd 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
@@ -67,6 +67,10 @@
#include <qpa/qplatformservices.h>
+#if QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2)
+#include "qoffscreenintegration_x11.h"
+#endif
+
QT_BEGIN_NAMESPACE
class QCoreTextFontEngine;
@@ -220,4 +224,14 @@ QPlatformServices *QOffscreenIntegration::services() const
return m_services.data();
}
+QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration()
+{
+#if QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2)
+ QByteArray glx = qgetenv("QT_QPA_OFFSCREEN_NO_GLX");
+ if (glx.isEmpty())
+ return new QOffscreenX11Integration;
+#endif
+ return new QOffscreenIntegration;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.h b/src/plugins/platforms/offscreen/qoffscreenintegration.h
index fc988126bb..098e726550 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration.h
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration.h
@@ -41,6 +41,7 @@
#define QOFFSCREENINTEGRATION_H
#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformnativeinterface.h>
#include <qscopedpointer.h>
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp
index 93566220e8..92fc8aa57a 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp
@@ -41,6 +41,7 @@
#include <QByteArray>
#include <QOpenGLContext>
+#include <QtPlatformHeaders/QGLXNativeContext>
#include <X11/Xlib.h>
#include <GL/glx.h>
@@ -52,16 +53,36 @@
QT_BEGIN_NAMESPACE
-QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration()
+class QOffscreenX11Info
{
- return new QOffscreenX11Integration;
-}
+public:
+ QOffscreenX11Info(QOffscreenX11Connection *connection)
+ : m_connection(connection)
+ {
+ }
+
+ Display *display() const {
+ return (Display *)m_connection->display();
+ }
+
+ Window root() const {
+ return DefaultRootWindow(display());
+ }
+
+ int screenNumber() const {
+ return m_connection->screenNumber();
+ }
+
+private:
+ QOffscreenX11Connection *m_connection;
+};
bool QOffscreenX11Integration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
case OpenGL: return true;
case ThreadedOpenGL: return true;
+ case RasterGLSurface: return true;
default: return QOffscreenIntegration::hasCapability(cap);
}
}
@@ -77,6 +98,40 @@ QPlatformOpenGLContext *QOffscreenX11Integration::createPlatformOpenGLContext(QO
return new QOffscreenX11GLXContext(m_connection->x11Info(), context);
}
+QPlatformNativeInterface *QOffscreenX11Integration::nativeInterface() const
+{
+ return const_cast<QOffscreenX11Integration *>(this);
+}
+
+void *QOffscreenX11Integration::nativeResourceForScreen(const QByteArray &resource, QScreen *screen)
+{
+ Q_UNUSED(screen)
+ if (resource.toLower() == QByteArrayLiteral("display") ) {
+ if (!m_connection)
+ m_connection.reset(new QOffscreenX11Connection);
+ return m_connection->display();
+ }
+ return nullptr;
+}
+
+#ifndef QT_NO_OPENGL
+void *QOffscreenX11Integration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) {
+ if (resource.toLower() == QByteArrayLiteral("glxconfig") ) {
+ if (context) {
+ QOffscreenX11GLXContext *glxPlatformContext = static_cast<QOffscreenX11GLXContext *>(context->handle());
+ return glxPlatformContext->glxConfig();
+ }
+ }
+ if (resource.toLower() == QByteArrayLiteral("glxcontext") ) {
+ if (context) {
+ QOffscreenX11GLXContext *glxPlatformContext = static_cast<QOffscreenX11GLXContext *>(context->handle());
+ return glxPlatformContext->glxContext();
+ }
+ }
+ return nullptr;
+}
+#endif
+
QOffscreenX11Connection::QOffscreenX11Connection()
{
XInitThreads();
@@ -93,30 +148,6 @@ QOffscreenX11Connection::~QOffscreenX11Connection()
XCloseDisplay((Display *)m_display);
}
-class QOffscreenX11Info
-{
-public:
- QOffscreenX11Info(QOffscreenX11Connection *connection)
- : m_connection(connection)
- {
- }
-
- Display *display() const {
- return (Display *)m_connection->display();
- }
-
- Window root() const {
- return DefaultRootWindow(display());
- }
-
- int screenNumber() const {
- return m_connection->screenNumber();
- }
-
-private:
- QOffscreenX11Connection *m_connection;
-};
-
QOffscreenX11Info *QOffscreenX11Connection::x11Info()
{
if (!m_x11Info)
@@ -127,11 +158,12 @@ QOffscreenX11Info *QOffscreenX11Connection::x11Info()
class QOffscreenX11GLXContextData
{
public:
- QOffscreenX11Info *x11;
+ QOffscreenX11Info *x11 = nullptr;
QSurfaceFormat format;
- GLXContext context;
- GLXContext shareContext;
- Window window;
+ GLXContext context = nullptr;
+ GLXContext shareContext = nullptr;
+ GLXFBConfig config = nullptr;
+ Window window = 0;
};
static Window createDummyWindow(QOffscreenX11Info *x11, XVisualInfo *visualInfo)
@@ -142,6 +174,7 @@ static Window createDummyWindow(QOffscreenX11Info *x11, XVisualInfo *visualInfo)
a.border_pixel = BlackPixel(x11->display(), x11->screenNumber());
a.colormap = cmap;
+
Window window = XCreateWindow(x11->display(), x11->root(),
0, 0, 100, 100,
0, visualInfo->depth, InputOutput, visualInfo->visual,
@@ -163,14 +196,23 @@ static Window createDummyWindow(QOffscreenX11Info *x11, GLXFBConfig config)
QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGLContext *context)
: d(new QOffscreenX11GLXContextData)
{
+
d->x11 = x11;
d->format = context->format();
+ if (d->format.renderableType() == QSurfaceFormat::DefaultRenderableType)
+ d->format.setRenderableType(QSurfaceFormat::OpenGL);
+
+ if (d->format.renderableType() != QSurfaceFormat::OpenGL)
+ return;
+
d->shareContext = 0;
if (context->shareHandle())
d->shareContext = static_cast<QOffscreenX11GLXContext *>(context->shareHandle())->d->context;
GLXFBConfig config = qglx_findConfig(x11->display(), x11->screenNumber(), d->format);
+ d->config = config;
+
if (config) {
d->context = glXCreateNewContext(x11->display(), config, GLX_RGBA_TYPE, d->shareContext, true);
if (!d->context && d->shareContext) {
@@ -199,6 +241,9 @@ QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGL
d->window = createDummyWindow(x11, visualInfo);
XFree(visualInfo);
}
+ if (d->context)
+ context->setNativeHandle(QVariant::fromValue<QGLXNativeContext>(QGLXNativeContext(d->context)));
+
}
QOffscreenX11GLXContext::~QOffscreenX11GLXContext()
@@ -251,4 +296,14 @@ bool QOffscreenX11GLXContext::isValid() const
return d->context && d->window;
}
+void *QOffscreenX11GLXContext::glxContext() const
+{
+ return d->context;
+}
+
+void *QOffscreenX11GLXContext::glxConfig() const
+{
+ return d->config;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h
index 5e1c6b799b..5ef51a15a8 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h
@@ -52,12 +52,19 @@ QT_BEGIN_NAMESPACE
class QOffscreenX11Connection;
class QOffscreenX11Info;
-class QOffscreenX11Integration : public QOffscreenIntegration
+class QOffscreenX11Integration : public QOffscreenIntegration, public QPlatformNativeInterface
{
public:
bool hasCapability(QPlatformIntegration::Capability cap) const override;
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
+ QPlatformNativeInterface *nativeInterface()const override;
+
+ // QPlatformNativeInterface
+ void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) override;
+#ifndef QT_NO_OPENGL
+ void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override;
+#endif
private:
mutable QScopedPointer<QOffscreenX11Connection> m_connection;
@@ -97,6 +104,9 @@ public:
bool isSharing() const override;
bool isValid() const override;
+ void *glxConfig() const;
+ void *glxContext() const;
+
private:
QScopedPointer<QOffscreenX11GLXContextData> d;
};
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index e4843cb438..f29e11489b 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -381,6 +381,8 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
if (m_lastGlobalMousePoint != globalPoint ||
m_lastLocalMousePoint != localPoint ||
m_lastButtonState != buttons) {
+ if (m_lastButtonState != 0 && buttons == 0)
+ (static_cast<QQnxWindow *>(w->handle()))->handleActivationEvent();
QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons);
qScreenEventDebug() << "Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << static_cast<int>(buttons);
}
@@ -457,6 +459,9 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
m_lastMouseWindow = qnxWindow;
if (w) {
+ if (qnxType == SCREEN_EVENT_MTOUCH_RELEASE)
+ (static_cast<QQnxWindow *>(w->handle()))->handleActivationEvent();
+
// get size of screen which contains window
QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(w);
QSizeF screenSize = platformScreen->geometry().size();
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 2096bc789e..7644e28b44 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -156,7 +156,8 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
m_visible(false),
m_exposed(true),
m_windowState(Qt::WindowNoState),
- m_mmRendererWindow(0)
+ m_mmRendererWindow(0),
+ m_firstActivateHandled(false)
{
qWindowDebug() << "window =" << window << ", size =" << window->size();
@@ -341,6 +342,14 @@ void QQnxWindow::setVisible(bool visible)
if (visible) {
applyWindowState();
} else {
+ if (showWithoutActivating() && focusable() && m_firstActivateHandled) {
+ m_firstActivateHandled = false;
+ int val = SCREEN_SENSITIVITY_NO_FOCUS;
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
+ "Failed to set window sensitivity");
+ }
+
// Flush the context, otherwise it won't disappear immediately
screen_flush_context(m_screenContext, 0);
}
@@ -618,13 +627,56 @@ void QQnxWindow::requestActivateWindow()
void QQnxWindow::setFocus(screen_window_t newFocusWindow)
{
+ screen_window_t temporaryFocusWindow = nullptr;
+
screen_group_t screenGroup = 0;
- screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_GROUP,
- reinterpret_cast<void**>(&screenGroup));
- if (screenGroup) {
- screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS,
- reinterpret_cast<void**>(&newFocusWindow));
+ Q_SCREEN_CHECKERROR(screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_GROUP,
+ reinterpret_cast<void **>(&screenGroup)),
+ "Failed to retrieve window group");
+
+ if (showWithoutActivating() && focusable() && !m_firstActivateHandled) {
+ m_firstActivateHandled = true;
+ int val = SCREEN_SENSITIVITY_TEST;
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
+ "Failed to set window sensitivity");
+
+#if _SCREEN_VERSION < _SCREEN_MAKE_VERSION(1, 0, 0)
+ // For older versions of screen, the window may still have group
+ // focus even though it was marked NO_FOCUS when it was hidden.
+ // In that situation, focus has to be given to another window
+ // so that this window can take focus back from it.
+ screen_window_t oldFocusWindow = nullptr;
+ Q_SCREEN_CHECKERROR(
+ screen_get_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS,
+ reinterpret_cast<void **>(&oldFocusWindow)),
+ "Failed to retrieve group focus");
+ if (newFocusWindow == oldFocusWindow) {
+ char groupName[256];
+ memset(groupName, 0, sizeof(groupName));
+ Q_SCREEN_CHECKERROR(screen_get_group_property_cv(screenGroup, SCREEN_PROPERTY_NAME,
+ sizeof(groupName) - 1, groupName),
+ "Failed to retrieve group name");
+
+ Q_SCREEN_CHECKERROR(screen_create_window_type(&temporaryFocusWindow,
+ m_screenContext, SCREEN_CHILD_WINDOW),
+ "Failed to create temporary focus window");
+ Q_SCREEN_CHECKERROR(screen_join_window_group(temporaryFocusWindow, groupName),
+ "Temporary focus window failed to join window group");
+ Q_SCREEN_CHECKERROR(
+ screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS,
+ reinterpret_cast<void **>(&temporaryFocusWindow)),
+ "Temporary focus window failed to take focus");
+ screen_flush_context(m_screenContext, 0);
+ }
+#endif
}
+
+ Q_SCREEN_CHECKERROR(screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS,
+ reinterpret_cast<void **>(&newFocusWindow)),
+ "Failed to set group focus");
+
+ screen_destroy_window(temporaryFocusWindow);
}
void QQnxWindow::setWindowState(Qt::WindowStates state)
@@ -711,7 +763,11 @@ void QQnxWindow::initWindow()
screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val),
"Failed to set swap interval");
- if (window()->flags() & Qt::WindowDoesNotAcceptFocus) {
+ if (showWithoutActivating() || !focusable()) {
+ // NO_FOCUS is temporary for showWithoutActivating (and pop-up) windows.
+ // Using NO_FOCUS ensures that screen doesn't activate the window because
+ // it was just created. Sensitivity will be changed to TEST when the
+ // window is clicked or touched.
val = SCREEN_SENSITIVITY_NO_FOCUS;
Q_SCREEN_CHECKERROR(
screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
@@ -825,4 +881,22 @@ bool QQnxWindow::shouldMakeFullScreen() const
&& (QQnxIntegration::instance()->options() & QQnxIntegration::FullScreenApplication));
}
+
+void QQnxWindow::handleActivationEvent()
+{
+ if (showWithoutActivating() && focusable() && !m_firstActivateHandled)
+ requestActivateWindow();
+}
+
+bool QQnxWindow::showWithoutActivating() const
+{
+ return (window()->flags() & Qt::Popup) == Qt::Popup
+ || window()->property("_q_showWithoutActivating").toBool();
+}
+
+bool QQnxWindow::focusable() const
+{
+ return (window()->flags() & Qt::WindowDoesNotAcceptFocus) != Qt::WindowDoesNotAcceptFocus;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index 2895a547b1..20c38cb4b7 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -113,6 +113,7 @@ public:
bool shouldMakeFullScreen() const;
void windowPosted();
+ void handleActivationEvent();
protected:
virtual int pixelFormat() const = 0;
@@ -131,6 +132,8 @@ private:
void updateZorder(screen_window_t window, int &zOrder);
void applyWindowState();
void setFocus(screen_window_t newFocusWindow);
+ bool showWithoutActivating() const;
+ bool focusable() const;
screen_window_t m_window;
QSize m_bufferSize;
@@ -152,6 +155,7 @@ private:
QByteArray m_parentGroupName;
bool m_isTopLevel;
+ bool m_firstActivateHandled;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/vnc/qvnc.cpp b/src/plugins/platforms/vnc/qvnc.cpp
index ffe00de2b1..32114c6443 100644
--- a/src/plugins/platforms/vnc/qvnc.cpp
+++ b/src/plugins/platforms/vnc/qvnc.cpp
@@ -600,7 +600,7 @@ void QVncClientCursor::changeCursor(QCursor *widgetCursor, QWindow *window)
cursor = *platformImage.image();
hotspot = platformImage.hotspot();
}
- for (auto client : clients)
+ for (auto client : qAsConst(clients))
client->setDirtyCursor();
}
@@ -638,16 +638,14 @@ void QVncServer::init()
QVncServer::~QVncServer()
{
- for (auto client : clients) {
- delete client;
- }
+ qDeleteAll(clients);
}
void QVncServer::setDirty()
{
- for (auto client : clients) {
+ for (auto client : qAsConst(clients))
client->setDirty(qvnc_screen->dirtyRegion);
- }
+
qvnc_screen->clearDirty();
}
diff --git a/src/plugins/platforms/vnc/qvncscreen.cpp b/src/plugins/platforms/vnc/qvncscreen.cpp
index 67d33de2f0..2eca18fb4d 100644
--- a/src/plugins/platforms/vnc/qvncscreen.cpp
+++ b/src/plugins/platforms/vnc/qvncscreen.cpp
@@ -75,7 +75,7 @@ bool QVncScreen::initialize()
mDepth = 32;
mPhysicalSize = QSizeF(mGeometry.width()/96.*25.4, mGeometry.height()/96.*25.4);
- for (const QString &arg : mArgs) {
+ for (const QString &arg : qAsConst(mArgs)) {
QRegularExpressionMatch match;
if (arg.contains(mmSizeRx, &match)) {
mPhysicalSize = QSizeF(match.captured("width").toDouble(), match.captured("height").toDouble());
diff --git a/src/plugins/platforms/wasm/qtloader.js b/src/plugins/platforms/wasm/qtloader.js
index 37a5308034..3cbb1c8aa8 100644
--- a/src/plugins/platforms/wasm/qtloader.js
+++ b/src/plugins/platforms/wasm/qtloader.js
@@ -50,6 +50,7 @@
// External mode.usage:
//
// var config = {
+// canvasElements : [$("canvas-id")],
// showLoader: function() {
// loader.style.display = 'block'
// canvas.style.display = 'hidden'
@@ -69,6 +70,8 @@
// One or more HTML elements. QtLoader will display loader elements
// on these while loading the applicaton, and replace the loader with a
// canvas on load complete.
+// canvasElements : [canvas-element, ...]
+// One or more canvas elements.
// showLoader : function(status, containerElement)
// Optional loading element constructor function. Implement to create
// a custom loading screen. This function may be called multiple times,
@@ -115,6 +118,12 @@
// "Exited", iff crashed is false.
// exitText
// Abort/exit message.
+// addCanvasElement
+// Add canvas at run-time. Adds a corresponding QScreen,
+// removeCanvasElement
+// Remove canvas at run-time. Removes the corresponding QScreen.
+// resizeCanvasElement
+// Signals to the application that a canvas has been resized.
var Module = {}
@@ -146,8 +155,25 @@ function QtLoader(config)
while (element.firstChild) element.removeChild(element.firstChild);
}
- // Set default state handler functions if needed
+ function createCanvas() {
+ var canvas = document.createElement("canvas");
+ canvas.className = "QtCanvas";
+ canvas.style.height = "100%";
+ canvas.style.width = "100%";
+
+ // Set contentEditable in order to enable clipboard events; hide the resulting focus frame.
+ canvas.contentEditable = true;
+ canvas.style.outline = "0px solid transparent";
+ canvas.style.cursor = "default";
+
+ return canvas;
+ }
+
+ // Set default state handler functions and create canvases if needed
if (config.containerElements !== undefined) {
+
+ config.canvasElements = config.containerElements.map(createCanvas);
+
config.showError = config.showError || function(errorText, container) {
removeChildren(container);
var errorTextElement = document.createElement("text");
@@ -164,12 +190,8 @@ function QtLoader(config)
return loadingText;
};
- config.showCanvas = config.showCanvas || function(container) {
+ config.showCanvas = config.showCanvas || function(canvas, container) {
removeChildren(container);
- var canvas = document.createElement("canvas");
- canvas.className = "QtCanvas"
- canvas.style = "height: 100%; width: 100%;"
- return canvas;
}
config.showExit = config.showExit || function(crashed, exitCode, container) {
@@ -211,6 +233,9 @@ function QtLoader(config)
publicAPI.canLoadApplication = canLoadQt();
publicAPI.status = undefined;
publicAPI.loadEmscriptenModule = loadEmscriptenModule;
+ publicAPI.addCanvasElement = addCanvasElement;
+ publicAPI.removeCanvasElement = removeCanvasElement;
+ publicAPI.resizeCanvasElement = resizeCanvasElement;
restartCount = 0;
@@ -312,13 +337,13 @@ function QtLoader(config)
// and is ready to be instantiated. Define the instantiateWasm callback which
// emscripten will call to create the instance.
Module.instantiateWasm = function(imports, successCallback) {
- return WebAssembly.instantiate(wasmModule, imports).then(function(instance) {
- successCallback(instance);
- return instance;
+ WebAssembly.instantiate(wasmModule, imports).then(function(instance) {
+ successCallback(instance, wasmModule);
}, function(error) {
self.error = error;
setStatus("Error");
});
+ return {};
};
Module.locateFile = Module.locateFile || function(filename) {
@@ -382,6 +407,10 @@ function QtLoader(config)
}
});
+ Module.mainScriptUrlOrBlob = new Blob([emscriptenModuleSource], {type: 'text/javascript'});
+
+ Module.qtCanvasElements = config.canvasElements;
+
config.restart = function() {
// Restart by reloading the page. This will wipe all state which means
@@ -436,19 +465,17 @@ function QtLoader(config)
}
function setCanvasContent() {
- var firstCanvas;
if (config.containerElements === undefined) {
- firstCanvas = config.showCanvas();
- } else {
- for (container of config.containerElements) {
- var canvasElement = config.showCanvas(container);
- container.appendChild(canvasElement);
- }
- firstCanvas = config.containerElements[0].firstChild;
+ if (config.showCanvas !== undefined)
+ config.showCanvas();
+ return;
}
- if (Module.canvas === undefined) {
- Module.canvas = firstCanvas;
+ for (var i = 0; i < config.containerElements.length; ++i) {
+ var container = config.containerElements[i];
+ var canvas = config.canvasElements[i];
+ config.showCanvas(canvas, container);
+ container.appendChild(canvas);
}
}
@@ -510,6 +537,25 @@ function QtLoader(config)
window.setTimeout(function() { handleStatusChange(); }, 0);
}
+ function addCanvasElement(element) {
+ if (publicAPI.status == "Running")
+ Module.qtAddCanvasElement(element);
+ else
+ console.log("Error: addCanvasElement can only be called in the Running state");
+ }
+
+ function removeCanvasElement(element) {
+ if (publicAPI.status == "Running")
+ Module.qtRemoveCanvasElement(element);
+ else
+ console.log("Error: removeCanvasElement can only be called in the Running state");
+ }
+
+ function resizeCanvasElement(element) {
+ if (publicAPI.status == "Running")
+ Module.qtResizeCanvasElement(element);
+ }
+
setStatus("Created");
return publicAPI;
diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp
new file mode 100644
index 0000000000..d4a1e4dd50
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp
@@ -0,0 +1,229 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmclipboard.h"
+#include "qwasmwindow.h"
+
+#include <emscripten.h>
+#include <emscripten/html5.h>
+#include <emscripten/bind.h>
+
+#include <QCoreApplication>
+#include <qpa/qwindowsysteminterface.h>
+
+using namespace emscripten;
+
+// there has got to be a better way...
+static QByteArray g_clipboardArray;
+static QByteArray g_clipboardFormat;
+
+static val getClipboardData()
+{
+ return val(g_clipboardArray.constData());
+}
+
+static val getClipboardFormat()
+{
+ return val(g_clipboardFormat.constData());
+}
+
+static void pasteClipboardData(emscripten::val format, emscripten::val dataPtr)
+{
+ QString formatString = QString::fromStdString(format.as<std::string>());
+ QByteArray dataArray = QByteArray::fromStdString(dataPtr.as<std::string>());
+ QMimeData *mMimeData = new QMimeData;
+ mMimeData->setData(formatString, dataArray);
+ QWasmClipboard::qWasmClipboardPaste(mMimeData);
+}
+
+static void qClipboardPromiseResolve(emscripten::val something)
+{
+ pasteClipboardData(emscripten::val("text/plain"), something);
+}
+
+static void qClipboardCutTo(val event)
+{
+ if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) {
+ // Send synthetic Ctrl+X to make the app cut data to Qt's clipboard
+ QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(
+ 0, QEvent::KeyPress, Qt::Key_X, Qt::ControlModifier, "X");
+ }
+
+ val module = val::global("Module");
+ val clipdata = module.call<val>("qtGetClipboardData");
+ val clipFormat = module.call<val>("qtGetClipboardFormat");
+ event["clipboardData"].call<void>("setData", clipFormat, clipdata);
+ event.call<void>("preventDefault");
+}
+
+static void qClipboardCopyTo(val event)
+{
+ if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) {
+ // Send synthetic Ctrl+C to make the app copy data to Qt's clipboard
+ QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(
+ 0, QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier, "C");
+ }
+
+ val module = val::global("Module");
+ val clipdata = module.call<val>("qtGetClipboardData");
+ val clipFormat = module.call<val>("qtGetClipboardFormat");
+ event["clipboardData"].call<void>("setData", clipFormat, clipdata);
+ event.call<void>("preventDefault");
+}
+
+static void qClipboardPasteTo(val event)
+{
+ bool hasClipboardApi = QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi;
+ val clipdata = hasClipboardApi ?
+ val::global("Module").call<val>("qtGetClipboardData") :
+ event["clipboardData"].call<val>("getData", std::string("text"));
+
+ const std::string data = clipdata.as<std::string>();
+ if (data.length() > 0) {
+ QString qstr = QString::fromStdString(data);
+ QMimeData *mMimeData = new QMimeData;
+ mMimeData->setText(qstr);
+ QWasmClipboard::qWasmClipboardPaste(mMimeData);
+ }
+}
+
+EMSCRIPTEN_BINDINGS(qtClipboardModule) {
+ function("qtGetClipboardData", &getClipboardData);
+ function("qtGetClipboardFormat", &getClipboardFormat);
+ function("qtPasteClipboardData", &pasteClipboardData);
+ function("qtClipboardPromiseResolve", &qClipboardPromiseResolve);
+ function("qtClipboardCutTo", &qClipboardCutTo);
+ function("qtClipboardCopyTo", &qClipboardCopyTo);
+ function("qtClipboardPasteTo", &qClipboardPasteTo);
+}
+
+QWasmClipboard::QWasmClipboard()
+{
+ val clipboard = val::global("navigator")["clipboard"];
+ hasClipboardApi = (!clipboard.isUndefined() && !clipboard["readText"].isUndefined());
+
+ initClipboardEvents();
+}
+
+QWasmClipboard::~QWasmClipboard()
+{
+ g_clipboardArray.clear();
+ g_clipboardFormat.clear();
+}
+
+QMimeData* QWasmClipboard::mimeData(QClipboard::Mode mode)
+{
+ if (mode != QClipboard::Clipboard)
+ return nullptr;
+
+ return QPlatformClipboard::mimeData(mode);
+}
+
+void QWasmClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode)
+{
+ if (mimeData->hasText()) {
+ g_clipboardFormat = mimeData->formats().at(0).toUtf8();
+ g_clipboardArray = mimeData->text().toUtf8();
+ } else if (mimeData->hasHtml()) {
+ g_clipboardFormat =mimeData->formats().at(0).toUtf8();
+ g_clipboardArray = mimeData->html().toUtf8();
+ }
+
+ QPlatformClipboard::setMimeData(mimeData, mode);
+}
+
+bool QWasmClipboard::supportsMode(QClipboard::Mode mode) const
+{
+ return mode == QClipboard::Clipboard;
+}
+
+bool QWasmClipboard::ownsMode(QClipboard::Mode mode) const
+{
+ Q_UNUSED(mode);
+ return false;
+}
+
+void QWasmClipboard::qWasmClipboardPaste(QMimeData *mData)
+{
+ QWasmIntegration::get()->clipboard()->setMimeData(mData, QClipboard::Clipboard);
+
+ QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(
+ 0, QEvent::KeyPress, Qt::Key_V, Qt::ControlModifier, "V");
+}
+
+void QWasmClipboard::initClipboardEvents()
+{
+ if (!hasClipboardApi)
+ return;
+
+ val permissions = val::global("navigator")["permissions"];
+ val readPermissionsMap = val::object();
+ readPermissionsMap.set("name", val("clipboard-read"));
+ permissions.call<val>("query", readPermissionsMap);
+
+ val writePermissionsMap = val::object();
+ writePermissionsMap.set("name", val("clipboard-write"));
+ permissions.call<val>("query", writePermissionsMap);
+}
+
+void QWasmClipboard::installEventHandlers(const QString &canvasId)
+{
+ if (hasClipboardApi)
+ return;
+
+ // Fallback path for browsers which do not support direct clipboard access
+ val canvas = val::global(canvasId.toUtf8().constData());
+ canvas.call<void>("addEventListener", std::string("cut"),
+ val::module_property("qtClipboardCutTo"));
+ canvas.call<void>("addEventListener", std::string("copy"),
+ val::module_property("qtClipboardCopyTo"));
+ canvas.call<void>("addEventListener", std::string("paste"),
+ val::module_property("qtClipboardPasteTo"));
+}
+
+void QWasmClipboard::readTextFromClipboard()
+{
+ if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) {
+ val navigator = val::global("navigator");
+ val textPromise = navigator["clipboard"].call<val>("readText");
+ val readTextResolve = val::global("Module")["qtClipboardPromiseResolve"];
+ textPromise.call<val>("then", readTextResolve);
+ }
+}
+
+void QWasmClipboard::writeTextToClipboard()
+{
+ if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) {
+ val module = val::global("Module");
+ val txt = module.call<val>("qtGetClipboardData");
+ val format = module.call<val>("qtGetClipboardFormat");
+ val navigator = val::global("navigator");
+ navigator["clipboard"].call<void>("writeText", txt.as<std::string>());
+ }
+}
diff --git a/src/plugins/platforms/wasm/qwasmclipboard.h b/src/plugins/platforms/wasm/qwasmclipboard.h
new file mode 100644
index 0000000000..00aae8fead
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmclipboard.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWasmClipboard_H
+#define QWasmClipboard_H
+
+#include <QObject>
+
+#include <qpa/qplatformclipboard.h>
+#include <QMimeData>
+
+#include <emscripten/bind.h>
+
+class QWasmClipboard : public QObject, public QPlatformClipboard
+{
+public:
+ QWasmClipboard();
+ virtual ~QWasmClipboard();
+
+ // QPlatformClipboard methods.
+ QMimeData* mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override;
+ void setMimeData(QMimeData* data, QClipboard::Mode mode = QClipboard::Clipboard) override;
+ bool supportsMode(QClipboard::Mode mode) const override;
+ bool ownsMode(QClipboard::Mode mode) const override;
+
+ static void qWasmClipboardPaste(QMimeData *mData);
+ void initClipboardEvents();
+ void installEventHandlers(const QString &canvasId);
+ bool hasClipboardApi;
+ void readTextFromClipboard();
+ void writeTextToClipboard();
+};
+
+#endif // QWASMCLIPBOARD_H
diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp
index 3dc6b7d2f3..90cc20789d 100644
--- a/src/plugins/platforms/wasm/qwasmcompositor.cpp
+++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp
@@ -56,8 +56,9 @@ QWasmCompositedWindow::QWasmCompositedWindow()
{
}
-QWasmCompositor::QWasmCompositor()
- : m_frameBuffer(nullptr)
+QWasmCompositor::QWasmCompositor(QWasmScreen *screen)
+ :QObject(screen)
+ , m_frameBuffer(nullptr)
, m_blitter(new QOpenGLTextureBlitter)
, m_needComposit(false)
, m_inFlush(false)
@@ -107,11 +108,6 @@ void QWasmCompositor::removeWindow(QWasmWindow *window)
notifyTopWindowChanged(window);
}
-void QWasmCompositor::setScreen(QWasmScreen *screen)
-{
- m_screen = screen;
-}
-
void QWasmCompositor::setVisible(QWasmWindow *window, bool visible)
{
QWasmCompositedWindow &compositedWindow = m_compositedWindows[window];
@@ -654,7 +650,7 @@ void QWasmCompositor::frame()
m_needComposit = false;
- if (m_windowStack.empty() || !m_screen)
+ if (m_windowStack.empty() || !screen())
return;
QWasmWindow *someWindow = nullptr;
@@ -673,7 +669,7 @@ void QWasmCompositor::frame()
if (m_context.isNull()) {
m_context.reset(new QOpenGLContext());
//mContext->setFormat(mScreen->format());
- m_context->setScreen(m_screen->screen());
+ m_context->setScreen(screen()->screen());
m_context->create();
}
@@ -682,8 +678,8 @@ void QWasmCompositor::frame()
if (!m_blitter->isCreated())
m_blitter->create();
- qreal dpr = m_screen->devicePixelRatio();
- glViewport(0, 0, m_screen->geometry().width() * dpr, m_screen->geometry().height() * dpr);
+ qreal dpr = screen()->devicePixelRatio();
+ glViewport(0, 0, screen()->geometry().width() * dpr, screen()->geometry().height() * dpr);
m_context->functions()->glClearColor(0.2, 0.2, 0.2, 1.0);
m_context->functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
@@ -697,7 +693,7 @@ void QWasmCompositor::frame()
if (!compositedWindow.visible)
continue;
- drawWindow(m_blitter.data(), m_screen, window);
+ drawWindow(m_blitter.data(), screen(), window);
}
m_blitter->release();
@@ -719,3 +715,8 @@ void QWasmCompositor::notifyTopWindowChanged(QWasmWindow *window)
requestRedraw();
QWindowSystemInterface::handleWindowActivated(window->window());
}
+
+QWasmScreen *QWasmCompositor::screen()
+{
+ return static_cast<QWasmScreen *>(parent());
+}
diff --git a/src/plugins/platforms/wasm/qwasmcompositor.h b/src/plugins/platforms/wasm/qwasmcompositor.h
index 4e5ed46cec..ed6facdcc3 100644
--- a/src/plugins/platforms/wasm/qwasmcompositor.h
+++ b/src/plugins/platforms/wasm/qwasmcompositor.h
@@ -62,7 +62,7 @@ class QWasmCompositor : public QObject
{
Q_OBJECT
public:
- QWasmCompositor();
+ QWasmCompositor(QWasmScreen *screen);
~QWasmCompositor();
enum QWasmSubControl {
@@ -103,7 +103,6 @@ public:
void addWindow(QWasmWindow *window, QWasmWindow *parentWindow = nullptr);
void removeWindow(QWasmWindow *window);
- void setScreen(QWasmScreen *screen);
void setVisible(QWasmWindow *window, bool visible);
void raise(QWasmWindow *window);
@@ -129,8 +128,7 @@ private slots:
void frame();
private:
- void createFrameBuffer();
- void flushCompletedCallback(int32_t);
+ QWasmScreen *screen();
void notifyTopWindowChanged(QWasmWindow *window);
void drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
void drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
@@ -142,7 +140,6 @@ private:
QImage *m_frameBuffer;
QScopedPointer<QOpenGLContext> m_context;
QScopedPointer<QOpenGLTextureBlitter> m_blitter;
- QWasmScreen *m_screen;
QHash<QWasmWindow *, QWasmCompositedWindow> m_compositedWindows;
QList<QWasmWindow *> m_windowStack;
diff --git a/src/plugins/platforms/wasm/qwasmcursor.cpp b/src/plugins/platforms/wasm/qwasmcursor.cpp
index 54804a55b3..2b3f37300d 100644
--- a/src/plugins/platforms/wasm/qwasmcursor.cpp
+++ b/src/plugins/platforms/wasm/qwasmcursor.cpp
@@ -28,19 +28,21 @@
****************************************************************************/
#include "qwasmcursor.h"
+#include "qwasmscreen.h"
#include <QtCore/qdebug.h>
+#include <QtGui/qwindow.h>
#include <emscripten/emscripten.h>
+#include <emscripten/bind.h>
void QWasmCursor::changeCursor(QCursor *windowCursor, QWindow *window)
{
- if (windowCursor == nullptr)
+ if (!windowCursor || !window)
+ return;
+ QScreen *screen = window->screen();
+ if (!screen)
return;
-
- // FIXME: The HTML5 plugin sets the cursor on the native canvas; when using multiple windows
- // multiple cursors need to be managed taking mouse postion and stacking into account.
- Q_UNUSED(window);
// Bitmap and custom cursors are not implemented (will fall back to "auto")
if (windowCursor->shape() == Qt::BitmapCursor || windowCursor->shape() >= Qt::CustomCursor)
@@ -51,12 +53,10 @@ void QWasmCursor::changeCursor(QCursor *windowCursor, QWindow *window)
if (htmlCursorName.isEmpty())
htmlCursorName = "auto";
- // Set cursor on the main canvas
- EM_ASM_ARGS({
- if (Module['canvas']) {
- Module['canvas'].style['cursor'] = Pointer_stringify($0);
- }
- }, htmlCursorName.constData());
+ // Set cursor on the canvas
+ QString canvasId = QWasmScreen::get(screen)->canvasId();
+ emscripten::val canvasStyle = emscripten::val::global(canvasId.toUtf8().constData())["style"];
+ canvasStyle.set("cursor", emscripten::val(htmlCursorName.constData()));
}
QByteArray QWasmCursor::cursorShapeToHtml(Qt::CursorShape shape)
diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
index 8ab109f03c..1c4c8cb7e8 100644
--- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
+++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
@@ -31,6 +31,7 @@
#include "qwasmeventdispatcher.h"
#include "qwasmcompositor.h"
#include "qwasmintegration.h"
+#include "qwasmclipboard.h"
#include <QtGui/qevent.h>
#include <qpa/qwindowsysteminterface.h>
@@ -39,6 +40,9 @@
#include <QtCore/qobject.h>
#include <QtCore/qdeadlinetimer.h>
+#include <private/qmakearray_p.h>
+#include <QtCore/qnamespace.h>
+
#include <emscripten/bind.h>
#include <iostream>
@@ -46,71 +50,336 @@
QT_BEGIN_NAMESPACE
using namespace emscripten;
+typedef struct emkb2qt {
+ const char *em;
+ unsigned int qt;
+
+ constexpr bool operator <=(const emkb2qt &that) const noexcept
+ {
+ return !(strcmp(that) > 0);
+ }
+
+ bool operator <(const emkb2qt &that) const noexcept
+ {
+ return ::strcmp(em, that.em) < 0;
+ }
+ constexpr int strcmp(const emkb2qt &that, const int i = 0) const
+ {
+ return em[i] == 0 && that.em[i] == 0 ? 0
+ : em[i] == 0 ? -1
+ : that.em[i] == 0 ? 1
+ : em[i] < that.em[i] ? -1
+ : em[i] > that.em[i] ? 1
+ : strcmp(that, i + 1);
+ }
+} emkb2qt_t;
+
+template<unsigned int Qt, char ... EmChar>
+struct Emkb2Qt
+{
+ static constexpr const char storage[sizeof ... (EmChar) + 1] = {EmChar..., '\0'};
+ using Type = emkb2qt_t;
+ static constexpr Type data() noexcept { return Type{storage, Qt}; }
+};
+
+template<unsigned int Qt, char ... EmChar> constexpr char Emkb2Qt<Qt, EmChar...>::storage[];
+
+static constexpr const auto KeyTbl = qMakeArray(
+ QSortedData<
+ Emkb2Qt< Qt::Key_Escape, 'E','s','c','a','p','e' >,
+ Emkb2Qt< Qt::Key_Tab, 'T','a','b' >,
+ Emkb2Qt< Qt::Key_Backspace, 'B','a','c','k','s','p','a','c','e' >,
+ Emkb2Qt< Qt::Key_Return, 'E','n','t','e','r' >,
+ Emkb2Qt< Qt::Key_Insert, 'I','n','s','e','r','t' >,
+ Emkb2Qt< Qt::Key_Delete, 'D','e','l','e','t','e' >,
+ Emkb2Qt< Qt::Key_Pause, 'P','a','u','s','e' >,
+ Emkb2Qt< Qt::Key_Pause, 'C','l','e','a','r' >,
+ Emkb2Qt< Qt::Key_Home, 'H','o','m','e' >,
+ Emkb2Qt< Qt::Key_End, 'E','n','d' >,
+ Emkb2Qt< Qt::Key_Left, 'A','r','r','o','w','L','e','f','t' >,
+ Emkb2Qt< Qt::Key_Up, 'A','r','r','o','w','U','p' >,
+ Emkb2Qt< Qt::Key_Right, 'A','r','r','o','w','R','i','g','h','t' >,
+ Emkb2Qt< Qt::Key_Down, 'A','r','r','o','w','D','o','w','n' >,
+ Emkb2Qt< Qt::Key_PageUp, 'P','a','g','e','U','p' >,
+ Emkb2Qt< Qt::Key_PageDown, 'P','a','g','e','D','o','w','n' >,
+ Emkb2Qt< Qt::Key_Shift, 'S','h','i','f','t' >,
+ Emkb2Qt< Qt::Key_Control, 'C','o','n','t','r','o','l' >,
+ Emkb2Qt< Qt::Key_Meta, 'O','S'>,
+ Emkb2Qt< Qt::Key_Alt, 'A','l','t','L','e','f','t' >,
+ Emkb2Qt< Qt::Key_Alt, 'A','l','t' >,
+ Emkb2Qt< Qt::Key_CapsLock, 'C','a','p','s','L','o','c','k' >,
+ Emkb2Qt< Qt::Key_NumLock, 'N','u','m','L','o','c','k' >,
+ Emkb2Qt< Qt::Key_ScrollLock, 'S','c','r','o','l','l','L','o','c','k' >,
+ Emkb2Qt< Qt::Key_F1, 'F','1' >,
+ Emkb2Qt< Qt::Key_F2, 'F','2' >,
+ Emkb2Qt< Qt::Key_F3, 'F','3' >,
+ Emkb2Qt< Qt::Key_F4, 'F','4' >,
+ Emkb2Qt< Qt::Key_F5, 'F','5' >,
+ Emkb2Qt< Qt::Key_F6, 'F','6' >,
+ Emkb2Qt< Qt::Key_F7, 'F','7' >,
+ Emkb2Qt< Qt::Key_F8, 'F','8' >,
+ Emkb2Qt< Qt::Key_F9, 'F','9' >,
+ Emkb2Qt< Qt::Key_F10, 'F','1','0' >,
+ Emkb2Qt< Qt::Key_F11, 'F','1','1' >,
+ Emkb2Qt< Qt::Key_F12, 'F','1','2' >,
+ Emkb2Qt< Qt::Key_F13, 'F','1','3' >,
+ Emkb2Qt< Qt::Key_F14, 'F','1','4' >,
+ Emkb2Qt< Qt::Key_F15, 'F','1','5' >,
+ Emkb2Qt< Qt::Key_F16, 'F','1','6' >,
+ Emkb2Qt< Qt::Key_F17, 'F','1','7' >,
+ Emkb2Qt< Qt::Key_F18, 'F','1','8' >,
+ Emkb2Qt< Qt::Key_F19, 'F','1','9' >,
+ Emkb2Qt< Qt::Key_F20, 'F','2','0' >,
+ Emkb2Qt< Qt::Key_F21, 'F','2','1' >,
+ Emkb2Qt< Qt::Key_F22, 'F','2','2' >,
+ Emkb2Qt< Qt::Key_F23, 'F','2','3' >,
+ Emkb2Qt< Qt::Key_Space, ' ' >,
+ Emkb2Qt< Qt::Key_Comma, ',' >,
+ Emkb2Qt< Qt::Key_Minus, '-' >,
+ Emkb2Qt< Qt::Key_Period, '.' >,
+ Emkb2Qt< Qt::Key_Slash, '/' >,
+ Emkb2Qt< Qt::Key_0, '0' >,
+ Emkb2Qt< Qt::Key_1, '1' >,
+ Emkb2Qt< Qt::Key_2, '2' >,
+ Emkb2Qt< Qt::Key_3, '3' >,
+ Emkb2Qt< Qt::Key_4, '4' >,
+ Emkb2Qt< Qt::Key_5, '5' >,
+ Emkb2Qt< Qt::Key_6, '6' >,
+ Emkb2Qt< Qt::Key_7, '7' >,
+ Emkb2Qt< Qt::Key_8, '8' >,
+ Emkb2Qt< Qt::Key_9, '9' >,
+ Emkb2Qt< Qt::Key_Semicolon, ';' >,
+ Emkb2Qt< Qt::Key_Equal, '=' >,
+ Emkb2Qt< Qt::Key_A, 'K','e','y','A' >,
+ Emkb2Qt< Qt::Key_B, 'K','e','y','B' >,
+ Emkb2Qt< Qt::Key_C, 'K','e','y','C' >,
+ Emkb2Qt< Qt::Key_D, 'K','e','y','D' >,
+ Emkb2Qt< Qt::Key_E, 'K','e','y','E' >,
+ Emkb2Qt< Qt::Key_F, 'K','e','y','F' >,
+ Emkb2Qt< Qt::Key_G, 'K','e','y','G' >,
+ Emkb2Qt< Qt::Key_H, 'K','e','y','H' >,
+ Emkb2Qt< Qt::Key_I, 'K','e','y','I' >,
+ Emkb2Qt< Qt::Key_J, 'K','e','y','J' >,
+ Emkb2Qt< Qt::Key_K, 'K','e','y','K' >,
+ Emkb2Qt< Qt::Key_L, 'K','e','y','L' >,
+ Emkb2Qt< Qt::Key_M, 'K','e','y','M' >,
+ Emkb2Qt< Qt::Key_N, 'K','e','y','N' >,
+ Emkb2Qt< Qt::Key_O, 'K','e','y','O' >,
+ Emkb2Qt< Qt::Key_P, 'K','e','y','P' >,
+ Emkb2Qt< Qt::Key_Q, 'K','e','y','Q' >,
+ Emkb2Qt< Qt::Key_R, 'K','e','y','R' >,
+ Emkb2Qt< Qt::Key_S, 'K','e','y','S' >,
+ Emkb2Qt< Qt::Key_T, 'K','e','y','T' >,
+ Emkb2Qt< Qt::Key_U, 'K','e','y','U' >,
+ Emkb2Qt< Qt::Key_V, 'K','e','y','V' >,
+ Emkb2Qt< Qt::Key_W, 'K','e','y','W' >,
+ Emkb2Qt< Qt::Key_X, 'K','e','y','X' >,
+ Emkb2Qt< Qt::Key_Y, 'K','e','y','Y' >,
+ Emkb2Qt< Qt::Key_Z, 'K','e','y','Z' >,
+ Emkb2Qt< Qt::Key_BracketLeft, '[' >,
+ Emkb2Qt< Qt::Key_Backslash, '\\' >,
+ Emkb2Qt< Qt::Key_BracketRight, ']' >,
+ Emkb2Qt< Qt::Key_Apostrophe, '\'' >,
+ Emkb2Qt< Qt::Key_QuoteLeft, 'B','a','c','k','q','u','o','t','e' >,
+ Emkb2Qt< Qt::Key_multiply, 'N','u','m','p','a','d','M','u','l','t','i','p','l','y' >,
+ Emkb2Qt< Qt::Key_Minus, 'N','u','m','p','a','d','S','u','b','t','r','a','c','t' >,
+ Emkb2Qt< Qt::Key_Period, 'N','u','m','p','a','d','D','e','c','i','m','a','l' >,
+ Emkb2Qt< Qt::Key_Plus, 'N','u','m','p','a','d','A','d','d' >,
+ Emkb2Qt< Qt::Key_division, 'N','u','m','p','a','d','D','i','v','i','d','e' >,
+ Emkb2Qt< Qt::Key_Equal, 'N','u','m','p','a','d','E','q','u','a','l' >,
+ Emkb2Qt< Qt::Key_0, 'N','u','m','p','a','d','0' >,
+ Emkb2Qt< Qt::Key_1, 'N','u','m','p','a','d','1' >,
+ Emkb2Qt< Qt::Key_2, 'N','u','m','p','a','d','2' >,
+ Emkb2Qt< Qt::Key_3, 'N','u','m','p','a','d','3' >,
+ Emkb2Qt< Qt::Key_4, 'N','u','m','p','a','d','4' >,
+ Emkb2Qt< Qt::Key_5, 'N','u','m','p','a','d','5' >,
+ Emkb2Qt< Qt::Key_6, 'N','u','m','p','a','d','6' >,
+ Emkb2Qt< Qt::Key_7, 'N','u','m','p','a','d','7' >,
+ Emkb2Qt< Qt::Key_8, 'N','u','m','p','a','d','8' >,
+ Emkb2Qt< Qt::Key_9, 'N','u','m','p','a','d','9' >,
+ Emkb2Qt< Qt::Key_Comma, 'N','u','m','p','a','d','C','o','m','m','a' >,
+ Emkb2Qt< Qt::Key_Enter, 'N','u','m','p','a','d','E','n','t','e','r' >,
+ Emkb2Qt< Qt::Key_Paste, 'P','a','s','t','e' >,
+ Emkb2Qt< Qt::Key_AltGr, 'A','l','t','R','i','g','h','t' >,
+ Emkb2Qt< Qt::Key_Help, 'H','e','l','p' >,
+ Emkb2Qt< Qt::Key_Equal, '=' >,
+ Emkb2Qt< Qt::Key_yen, 'I','n','t','l','Y','e','n' >,
+
+ Emkb2Qt< Qt::Key_Exclam, '\x21' >,
+ Emkb2Qt< Qt::Key_QuoteDbl, '\x22' >,
+ Emkb2Qt< Qt::Key_NumberSign, '\x23' >,
+ Emkb2Qt< Qt::Key_Dollar, '\x24' >,
+ Emkb2Qt< Qt::Key_Percent, '\x25' >,
+ Emkb2Qt< Qt::Key_Ampersand, '\x26' >,
+ Emkb2Qt< Qt::Key_ParenLeft, '\x28' >,
+ Emkb2Qt< Qt::Key_ParenRight, '\x29' >,
+ Emkb2Qt< Qt::Key_Asterisk, '\x2a' >,
+ Emkb2Qt< Qt::Key_Plus, '\x2b' >,
+ Emkb2Qt< Qt::Key_Colon, '\x3a' >,
+ Emkb2Qt< Qt::Key_Semicolon, '\x3b' >,
+ Emkb2Qt< Qt::Key_Less, '\x3c' >,
+ Emkb2Qt< Qt::Key_Equal, '\x3d' >,
+ Emkb2Qt< Qt::Key_Greater, '\x3e' >,
+ Emkb2Qt< Qt::Key_Question, '\x3f' >,
+ Emkb2Qt< Qt::Key_At, '\x40' >,
+ Emkb2Qt< Qt::Key_BracketLeft, '\x5b' >,
+ Emkb2Qt< Qt::Key_Backslash, '\x5c' >,
+ Emkb2Qt< Qt::Key_BracketRight, '\x5d' >,
+ Emkb2Qt< Qt::Key_AsciiCircum, '\x5e' >,
+ Emkb2Qt< Qt::Key_Underscore, '\x5f' >,
+ Emkb2Qt< Qt::Key_QuoteLeft, '\x60'>,
+ Emkb2Qt< Qt::Key_BraceLeft, '\x7b'>,
+ Emkb2Qt< Qt::Key_Bar, '\x7c'>,
+ Emkb2Qt< Qt::Key_BraceRight, '\x7d'>,
+ Emkb2Qt< Qt::Key_AsciiTilde, '\x7e'>,
+ Emkb2Qt< Qt::Key_Space, '\x20' >,
+ Emkb2Qt< Qt::Key_Comma, '\x2c' >,
+ Emkb2Qt< Qt::Key_Minus, '\x2d' >,
+ Emkb2Qt< Qt::Key_Period, '\x2e' >,
+ Emkb2Qt< Qt::Key_Slash, '\x2f' >,
+ Emkb2Qt< Qt::Key_Apostrophe, '\x27' >,
+ Emkb2Qt< Qt::Key_Menu, 'C','o','n','t','e','x','t','M','e','n','u' >,
+
+ Emkb2Qt< Qt::Key_Agrave, '\xc3','\xa0' >,
+ Emkb2Qt< Qt::Key_Aacute, '\xc3','\xa1' >,
+ Emkb2Qt< Qt::Key_Acircumflex, '\xc3','\xa2' >,
+ Emkb2Qt< Qt::Key_Adiaeresis, '\xc3','\xa4' >,
+ Emkb2Qt< Qt::Key_AE, '\xc3','\xa6' >,
+ Emkb2Qt< Qt::Key_Atilde, '\xc3','\xa3' >,
+ Emkb2Qt< Qt::Key_Aring, '\xc3','\xa5' >,
+ Emkb2Qt< Qt::Key_Ccedilla, '\xc3','\xa7' >,
+ Emkb2Qt< Qt::Key_Egrave, '\xc3','\xa8' >,
+ Emkb2Qt< Qt::Key_Eacute, '\xc3','\xa9' >,
+ Emkb2Qt< Qt::Key_Ecircumflex, '\xc3','\xaa' >,
+ Emkb2Qt< Qt::Key_Ediaeresis, '\xc3','\xab' >,
+ Emkb2Qt< Qt::Key_Icircumflex, '\xc3','\xae' >,
+ Emkb2Qt< Qt::Key_Idiaeresis, '\xc3','\xaf' >,
+ Emkb2Qt< Qt::Key_Ocircumflex, '\xc3','\xb4' >,
+ Emkb2Qt< Qt::Key_Odiaeresis, '\xc3','\xb6' >,
+ Emkb2Qt< Qt::Key_Ograve, '\xc3','\xb2' >,
+ Emkb2Qt< Qt::Key_Oacute, '\xc3','\xb3' >,
+ Emkb2Qt< Qt::Key_Ooblique, '\xc3','\xb8' >,
+ Emkb2Qt< Qt::Key_Otilde, '\xc3','\xb5' >,
+ Emkb2Qt< Qt::Key_Ucircumflex, '\xc3','\xbb' >,
+ Emkb2Qt< Qt::Key_Udiaeresis, '\xc3','\xbc' >,
+ Emkb2Qt< Qt::Key_Ugrave, '\xc3','\xb9' >,
+ Emkb2Qt< Qt::Key_Uacute, '\xc3','\xba' >,
+ Emkb2Qt< Qt::Key_Ntilde, '\xc3','\xb1' >,
+ Emkb2Qt< Qt::Key_ydiaeresis, '\xc3','\xbf' >
+ >::Data{}
+ );
+
+static constexpr const auto DeadKeyShiftTbl = qMakeArray(
+ QSortedData<
+ // shifted
+ Emkb2Qt< Qt::Key_Agrave, '\xc3','\x80' >,
+ Emkb2Qt< Qt::Key_Aacute, '\xc3','\x81' >,
+ Emkb2Qt< Qt::Key_Acircumflex, '\xc3','\x82' >,
+ Emkb2Qt< Qt::Key_Adiaeresis, '\xc3','\x84' >,
+ Emkb2Qt< Qt::Key_AE, '\xc3','\x86' >,
+ Emkb2Qt< Qt::Key_Atilde, '\xc3','\x83' >,
+ Emkb2Qt< Qt::Key_Aring, '\xc3','\x85' >,
+ Emkb2Qt< Qt::Key_Egrave, '\xc3','\x88' >,
+ Emkb2Qt< Qt::Key_Eacute, '\xc3','\x89' >,
+ Emkb2Qt< Qt::Key_Ecircumflex, '\xc3','\x8a' >,
+ Emkb2Qt< Qt::Key_Ediaeresis, '\xc3','\x8b' >,
+ Emkb2Qt< Qt::Key_Icircumflex, '\xc3','\x8e' >,
+ Emkb2Qt< Qt::Key_Idiaeresis, '\xc3','\x8f' >,
+ Emkb2Qt< Qt::Key_Ocircumflex, '\xc3','\x94' >,
+ Emkb2Qt< Qt::Key_Odiaeresis, '\xc3','\x96' >,
+ Emkb2Qt< Qt::Key_Ograve, '\xc3','\x92' >,
+ Emkb2Qt< Qt::Key_Oacute, '\xc3','\x93' >,
+ Emkb2Qt< Qt::Key_Ooblique, '\xc3','\x98' >,
+ Emkb2Qt< Qt::Key_Otilde, '\xc3','\x95' >,
+ Emkb2Qt< Qt::Key_Ucircumflex, '\xc3','\x9b' >,
+ Emkb2Qt< Qt::Key_Udiaeresis, '\xc3','\x9c' >,
+ Emkb2Qt< Qt::Key_Ugrave, '\xc3','\x99' >,
+ Emkb2Qt< Qt::Key_Uacute, '\xc3','\x9a' >,
+ Emkb2Qt< Qt::Key_Ntilde, '\xc3','\x91' >,
+ Emkb2Qt< Qt::Key_Ccedilla, '\xc3','\x87' >,
+ Emkb2Qt< Qt::Key_ydiaeresis, '\xc3','\x8f' >
+ >::Data{}
+);
+
// macOS CTRL <-> META switching. We most likely want to enable
// the existing switching code in QtGui, but for now do it here.
static bool g_usePlatformMacCtrlMetaSwitching = false;
bool g_useNaturalScrolling = true; // natural scrolling is default on linux/windows
-void setNaturalScrolling(bool use) {
- g_useNaturalScrolling = use;
+static void mouseWheelEvent(emscripten::val event) {
+
+ emscripten::val wheelInterted = event["webkitDirectionInvertedFromDevice"];
+
+ if (wheelInterted.as<bool>()) {
+ g_useNaturalScrolling = true;
+ }
}
-EMSCRIPTEN_BINDINGS(mouse_module) {
- function("setNaturalScrolling", &setNaturalScrolling);
+EMSCRIPTEN_BINDINGS(qtMouseModule) {
+ function("qtMouseWheelEvent", &mouseWheelEvent);
}
-QWasmEventTranslator::QWasmEventTranslator(QObject *parent)
- : QObject(parent)
+QWasmEventTranslator::QWasmEventTranslator(QWasmScreen *screen)
+ : QObject(screen)
, draggedWindow(nullptr)
, lastWindow(nullptr)
, pressedButtons(Qt::NoButton)
, resizeMode(QWasmWindow::ResizeNone)
{
- emscripten_set_keydown_callback(0, (void *)this, 1, &keyboard_cb);
- emscripten_set_keyup_callback(0, (void *)this, 1, &keyboard_cb);
-
- emscripten_set_mousedown_callback(0, (void *)this, 1, &mouse_cb);
- emscripten_set_mouseup_callback(0, (void *)this, 1, &mouse_cb);
- emscripten_set_mousemove_callback(0, (void *)this, 1, &mouse_cb);
-
- emscripten_set_focus_callback(0, (void *)this, 1, &focus_cb);
-
- emscripten_set_wheel_callback(0, (void *)this, 1, &wheel_cb);
-
touchDevice = new QTouchDevice;
touchDevice->setType(QTouchDevice::TouchScreen);
touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition);
QWindowSystemInterface::registerTouchDevice(touchDevice);
- emscripten_set_touchstart_callback("#canvas", (void *)this, 1, &touchCallback);
- emscripten_set_touchend_callback("#canvas", (void *)this, 1, &touchCallback);
- emscripten_set_touchmove_callback("#canvas", (void *)this, 1, &touchCallback);
- emscripten_set_touchcancel_callback("#canvas", (void *)this, 1, &touchCallback);
+ initEventHandlers();
+}
+
+void QWasmEventTranslator::initEventHandlers()
+{
+ qDebug() << "QWasmEventTranslator::initEventHandlers";
+
+ QByteArray _canvasId = screen()->canvasId().toUtf8();
+ const char *canvasId = _canvasId.constData();
// The Platform Detect: expand coverage and move as needed
enum Platform {
GenericPlatform,
MacOSPlatform
};
- Platform platform =
- Platform(EM_ASM_INT("if (navigator.platform.includes(\"Mac\")) return 1; return 0;"));
-
+ Platform platform = Platform(emscripten::val::global("navigator")["platform"]
+ .call<bool>("includes", emscripten::val("Mac")));
g_usePlatformMacCtrlMetaSwitching = (platform == MacOSPlatform);
if (platform == MacOSPlatform) {
g_useNaturalScrolling = false; // make this !default on macOS
- EM_ASM(
- if (window.safari !== undefined) {//this only works on safari
- Module["canvas"].addEventListener('wheel', mouseWheelEvent);
- function mouseWheelEvent(e) {
- if (event.webkitDirectionInvertedFromDevice) {
- Module.setNaturalScrolling(event.webkitDirectionInvertedFromDevice);
- }
- }
- }
- );
+
+ if (emscripten::val::global("window")["safari"].isUndefined()) {
+
+ emscripten::val::global(canvasId).call<void>("addEventListener",
+ std::string("wheel"),
+ val::module_property("qtMouseWheelEvent"));
+ }
}
+
+ emscripten_set_keydown_callback(canvasId, (void *)this, 1, &keyboard_cb);
+ emscripten_set_keyup_callback(canvasId, (void *)this, 1, &keyboard_cb);
+
+ emscripten_set_mousedown_callback(canvasId, (void *)this, 1, &mouse_cb);
+ emscripten_set_mouseup_callback(canvasId, (void *)this, 1, &mouse_cb);
+ emscripten_set_mousemove_callback(canvasId, (void *)this, 1, &mouse_cb);
+
+ emscripten_set_focus_callback(canvasId, (void *)this, 1, &focus_cb);
+
+ emscripten_set_wheel_callback(canvasId, (void *)this, 1, &wheel_cb);
+
+ emscripten_set_touchstart_callback(canvasId, (void *)this, 1, &touchCallback);
+ emscripten_set_touchend_callback(canvasId, (void *)this, 1, &touchCallback);
+ emscripten_set_touchmove_callback(canvasId, (void *)this, 1, &touchCallback);
+ emscripten_set_touchcancel_callback(canvasId, (void *)this, 1, &touchCallback);
+
+ emscripten_set_resize_callback(nullptr, (void *)this, 1, uiEvent_cb); // Note: handles browser window resize
+
}
template <typename Event>
@@ -153,132 +422,49 @@ QFlags<Qt::KeyboardModifier> QWasmEventTranslator::translateMouseEventModifier(c
int QWasmEventTranslator::keyboard_cb(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
{
- Q_UNUSED(userData)
-
- bool alphanumeric;
- Qt::Key qtKey = translateEmscriptKey(keyEvent, &alphanumeric);
-
- QEvent::Type keyType = QEvent::None;
- switch (eventType) {
- case EMSCRIPTEN_EVENT_KEYPRESS:
- case EMSCRIPTEN_EVENT_KEYDOWN: //down
- keyType = QEvent::KeyPress;
- break;
- case EMSCRIPTEN_EVENT_KEYUP: //up
- keyType = QEvent::KeyRelease;
- break;
- default:
- break;
- };
+ QWasmEventTranslator *wasmTranslator = reinterpret_cast<QWasmEventTranslator *>(userData);
+ bool accepted = wasmTranslator->processKeyboard(eventType, keyEvent);
- if (keyType == QEvent::None)
- return 0;
-
- QString keyText = alphanumeric ? QString(keyEvent->key) : QString();
- bool accepted = QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(
- 0, keyType, qtKey, translateKeyboardEventModifier(keyEvent), keyText);
- QWasmEventDispatcher::maintainTimers();
return accepted ? 1 : 0;
}
-Qt::Key QWasmEventTranslator::translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey, bool *outAlphanumeric)
+QWasmScreen *QWasmEventTranslator::screen()
{
- Qt::Key qtKey;
- if (outAlphanumeric)
- *outAlphanumeric = false;
-
- switch (emscriptKey->keyCode) {
- case KeyMultiply: qtKey = Qt::Key_Asterisk; *outAlphanumeric = true; break;
- case KeyAdd: qtKey = Qt::Key_Plus; *outAlphanumeric = true; break;
- case KeyMinus: qtKey = Qt::Key_Minus; *outAlphanumeric = true; break;
- case KeySubtract: qtKey = Qt::Key_Minus; *outAlphanumeric = true; break;
- case KeyDecimal: qtKey = Qt::Key_Period; *outAlphanumeric = true; break;
- case KeyDivide: qtKey = Qt::Key_Slash; *outAlphanumeric = true; break;
- case KeyNumPad0: qtKey = Qt::Key_0; *outAlphanumeric = true; break;
- case KeyNumPad1: qtKey = Qt::Key_1; *outAlphanumeric = true; break;
- case KeyNumPad2: qtKey = Qt::Key_2; *outAlphanumeric = true; break;
- case KeyNumPad3: qtKey = Qt::Key_3; *outAlphanumeric = true; break;
- case KeyNumPad4: qtKey = Qt::Key_4; *outAlphanumeric = true; break;
- case KeyNumPad5: qtKey = Qt::Key_5; *outAlphanumeric = true; break;
- case KeyNumPad6: qtKey = Qt::Key_6; *outAlphanumeric = true; break;
- case KeyNumPad7: qtKey = Qt::Key_7; *outAlphanumeric = true; break;
- case KeyNumPad8: qtKey = Qt::Key_8; *outAlphanumeric = true; break;
- case KeyNumPad9: qtKey = Qt::Key_9; *outAlphanumeric = true; break;
- case KeyComma: qtKey = Qt::Key_Comma; *outAlphanumeric = true; break;
- case KeyPeriod: qtKey = Qt::Key_Period; *outAlphanumeric = true; break;
- case KeySlash: qtKey = Qt::Key_Slash; *outAlphanumeric = true; break;
- case KeySemiColon: qtKey = Qt::Key_Semicolon; *outAlphanumeric = true; break;
- case KeyEquals: qtKey = Qt::Key_Equal; *outAlphanumeric = true; break;
- case KeyOpenBracket: qtKey = Qt::Key_BracketLeft; *outAlphanumeric = true; break;
- case KeyCloseBracket: qtKey = Qt::Key_BracketRight; *outAlphanumeric = true; break;
- case KeyBackSlash: qtKey = Qt::Key_Backslash; *outAlphanumeric = true; break;
- case KeyMeta:
- Q_FALLTHROUGH();
- case KeyMetaRight:
- qtKey = Qt::Key_Meta;
- break;
- case KeyTab: qtKey = Qt::Key_Tab; break;
- case KeyClear: qtKey = Qt::Key_Clear; break;
- case KeyBackSpace: qtKey = Qt::Key_Backspace; break;
- case KeyEnter: qtKey = Qt::Key_Return; break;
- case KeyShift: qtKey = Qt::Key_Shift; break;
- case KeyControl: qtKey = Qt::Key_Control; break;
- case KeyAlt: qtKey = Qt::Key_Alt; break;
- case KeyCapsLock: qtKey = Qt::Key_CapsLock; break;
- case KeyEscape: qtKey = Qt::Key_Escape; break;
- case KeyPageUp: qtKey = Qt::Key_PageUp; break;
- case KeyPageDown: qtKey = Qt::Key_PageDown; break;
- case KeyEnd: qtKey = Qt::Key_End; break;
- case KeyHome: qtKey = Qt::Key_Home; break;
- case KeyLeft: qtKey = Qt::Key_Left; break;
- case KeyUp: qtKey = Qt::Key_Up; break;
- case KeyRight: qtKey = Qt::Key_Right; break;
- case KeyDown: qtKey = Qt::Key_Down; break;
- case KeyBrightnessDown: qtKey = Qt::Key_MonBrightnessDown; break;
- case KeyBrightnessUp: qtKey = Qt::Key_MonBrightnessUp; break;
- case KeyMediaTrackPrevious: qtKey = Qt::Key_MediaPrevious; break;
- case KeyMediaPlayPause: qtKey = Qt::Key_MediaTogglePlayPause; break;
- case KeyMediaTrackNext: qtKey = Qt::Key_MediaNext; break;
- case KeyAudioVolumeMute: qtKey = Qt::Key_VolumeMute; break;
- case KeyAudioVolumeDown: qtKey = Qt::Key_VolumeDown; break;
- case KeyAudioVolumeUp: qtKey = Qt::Key_VolumeUp; break;
- case KeyDelete: qtKey = Qt::Key_Delete; break;
-
- case KeyF1: qtKey = Qt::Key_F1; break;
- case KeyF2: qtKey = Qt::Key_F2; break;
- case KeyF3: qtKey = Qt::Key_F3; break;
- case KeyF4: qtKey = Qt::Key_F4; break;
- case KeyF5: qtKey = Qt::Key_F5; break;
- case KeyF6: qtKey = Qt::Key_F6; break;
- case KeyF7: qtKey = Qt::Key_F7; break;
- case KeyF8: qtKey = Qt::Key_F8; break;
- case KeyF9: qtKey = Qt::Key_F9; break;
- case KeyF10: qtKey = Qt::Key_F10; break;
- case KeyF11: qtKey = Qt::Key_F11; break;
- case KeyF12: qtKey = Qt::Key_F12; break;
- case 124: qtKey = Qt::Key_F13; break;
- case 125: qtKey = Qt::Key_F14; break;
-
- case KeySpace:
- default:
- if (outAlphanumeric)
- *outAlphanumeric = true;
- qtKey = static_cast<Qt::Key>(emscriptKey->keyCode);
- break;
- }
+ return static_cast<QWasmScreen *>(parent());
+}
- // Handle Mac command key. Using event->keyCode as above is
- // no reliable since the codes differ between browsers.
- if (qstrncmp(emscriptKey->key, "Meta", 4) == 0) {
- qtKey = Qt::Key_Meta;
- *outAlphanumeric = false;
+Qt::Key QWasmEventTranslator::translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey)
+{
+ Qt::Key qtKey = Qt::Key_unknown;
+
+ if (qstrncmp(emscriptKey->code, "Key", 3) == 0 || qstrncmp(emscriptKey->code, "Numpad", 6) == 0) {
+
+ emkb2qt_t searchKey{emscriptKey->code, 0}; // search emcsripten code
+ auto it1 = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey);
+ if (it1 != KeyTbl.end() && !(searchKey < *it1)) {
+ qtKey = static_cast<Qt::Key>(it1->qt);
+ }
+ } else if (qstrncmp(emscriptKey->key, "Dead", 4) == 0 ) {
+ emkb2qt_t searchKey1{emscriptKey->code, 0};
+ for (auto it1 = KeyTbl.cbegin(); it1 != KeyTbl.end(); ++it1)
+ if (it1 != KeyTbl.end() && (qstrcmp(searchKey1.em, it1->em) == 0)) {
+ qtKey = static_cast<Qt::Key>(it1->qt);
+ }
}
- if (g_usePlatformMacCtrlMetaSwitching) {
- if (qtKey == Qt::Key_Meta)
- qtKey = Qt::Key_Control;
- else if (qtKey == Qt::Key_Control)
- qtKey = Qt::Key_Meta;
+ if (qtKey == Qt::Key_unknown) {
+ emkb2qt_t searchKey{emscriptKey->key, 0}; // search unicode key
+ auto it1 = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey);
+ if (it1 != KeyTbl.end() && !(searchKey < *it1)) {
+ qtKey = static_cast<Qt::Key>(it1->qt);
+ }
+ }
+ if (qtKey == Qt::Key_unknown) {//try harder with shifted number keys
+ emkb2qt_t searchKey1{emscriptKey->key, 0};
+ for (auto it1 = KeyTbl.cbegin(); it1 != KeyTbl.end(); ++it1)
+ if (it1 != KeyTbl.end() && (qstrcmp(searchKey1.em, it1->em) == 0)) {
+ qtKey = static_cast<Qt::Key>(it1->qt);
+ }
}
return qtKey;
@@ -363,14 +549,14 @@ void resizeWindow(QWindow *window, QWasmWindow::ResizeMode mode,
void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEvent *mouseEvent)
{
auto timestamp = mouseEvent->timestamp;
- QPoint point(mouseEvent->canvasX, mouseEvent->canvasY);
+ QPoint point(mouseEvent->targetX, mouseEvent->targetY);
QEvent::Type buttonEventType = QEvent::None;
Qt::MouseButton button = translateMouseButton(mouseEvent->button);
Qt::KeyboardModifiers modifiers = translateMouseEventModifier(mouseEvent);
- QWindow *window2 = QWasmIntegration::get()->compositor()->windowAt(point, 5);
+ QWindow *window2 = screen()->compositor()->windowAt(point, 5);
if (window2 != nullptr)
lastWindow = window2;
@@ -382,8 +568,11 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven
switch (eventType) {
case EMSCRIPTEN_EVENT_MOUSEDOWN:
{
- if (window2)
+ if (window2) {
window2->raise();
+ if (!window2->isActive())
+ window2->requestActivate();
+ }
pressedButtons.setFlag(button);
@@ -463,8 +652,8 @@ int QWasmEventTranslator::focus_cb(int /*eventType*/, const EmscriptenFocusEvent
int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData)
{
Q_UNUSED(eventType)
- Q_UNUSED(userData)
+ QWasmEventTranslator *eventTranslator = static_cast<QWasmEventTranslator *>(userData);
EmscriptenMouseEvent mouseEvent = wheelEvent->mouse;
int scrollFactor = 0;
@@ -483,11 +672,12 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh
if (g_useNaturalScrolling) //macOS platform has document oriented scrolling
scrollFactor = -scrollFactor;
- Qt::KeyboardModifiers modifiers = translateMouseEventModifier(&mouseEvent);
+ QWasmEventTranslator *translator = (QWasmEventTranslator*)userData;
+ Qt::KeyboardModifiers modifiers = translator->translateMouseEventModifier(&mouseEvent);
auto timestamp = mouseEvent.timestamp;
QPoint globalPoint(mouseEvent.canvasX, mouseEvent.canvasY);
- QWindow *window2 = QWasmIntegration::get()->compositor()->windowAt(globalPoint, 5);
+ QWindow *window2 = eventTranslator->screen()->compositor()->windowAt(globalPoint, 5);
QPoint localPoint(globalPoint.x() - window2->geometry().x(), globalPoint.y() - window2->geometry().y());
@@ -496,8 +686,8 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh
if (wheelEvent->deltaY != 0) pixelDelta.setY(wheelEvent->deltaY * scrollFactor);
if (wheelEvent->deltaX != 0) pixelDelta.setX(wheelEvent->deltaX * scrollFactor);
- QWindowSystemInterface::handleWheelEvent(window2, timestamp, localPoint, globalPoint, QPoint(), pixelDelta, modifiers);
-
+ QWindowSystemInterface::handleWheelEvent(window2, timestamp, localPoint,
+ globalPoint, QPoint(), pixelDelta, modifiers);
QWasmEventDispatcher::maintainTimers();
return 1;
@@ -505,6 +695,12 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh
int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
{
+ auto translator = reinterpret_cast<QWasmEventTranslator*>(userData);
+ return translator->handleTouch(eventType, touchEvent);
+}
+
+int QWasmEventTranslator::handleTouch(int eventType, const EmscriptenTouchEvent *touchEvent)
+{
QList<QWindowSystemInterface::TouchPoint> touchPointList;
touchPointList.reserve(touchEvent->numTouches);
QWindow *window2;
@@ -513,46 +709,68 @@ int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEven
const EmscriptenTouchPoint *touches = &touchEvent->touches[i];
- QPoint point(touches->canvasX, touches->canvasY);
- window2 = QWasmIntegration::get()->compositor()->windowAt(point, 5);
-
+ QPoint point(touches->targetX, touches->targetY);
+ window2 = this->screen()->compositor()->windowAt(point, 5);
QWindowSystemInterface::TouchPoint touchPoint;
- auto cX = point.x();
- auto cY = point.y();
touchPoint.area = QRect(0, 0, 8, 8);
- touchPoint.area.moveCenter(QPointF(cX,cY)); // simulate area
-
touchPoint.id = touches->identifier;
- touchPoint.normalPosition = QPointF(cX / window2->width(), cY / window2->height());
+ touchPoint.pressure = 1.0;
+
+ const QPointF screenPos(point);
+
+ touchPoint.area.moveCenter(screenPos);
+
+ const auto tp = pressedTouchIds.constFind(touchPoint.id);
+ if (tp != pressedTouchIds.constEnd())
+ touchPoint.normalPosition = tp.value();
+
+ QPointF normalPosition(screenPos.x() / window2->width(),
+ screenPos.y() / window2->height());
+
+ const bool stationaryTouchPoint = (normalPosition == touchPoint.normalPosition);
+ touchPoint.normalPosition = normalPosition;
switch (eventType) {
case EMSCRIPTEN_EVENT_TOUCHSTART:
- touchPoint.state = Qt::TouchPointPressed;
+ if (tp != pressedTouchIds.constEnd()) {
+ touchPoint.state = (stationaryTouchPoint
+ ? Qt::TouchPointStationary
+ : Qt::TouchPointMoved);
+ } else {
+ touchPoint.state = Qt::TouchPointPressed;
+ }
+ pressedTouchIds.insert(touchPoint.id, touchPoint.normalPosition);
+
break;
case EMSCRIPTEN_EVENT_TOUCHEND:
touchPoint.state = Qt::TouchPointReleased;
+ pressedTouchIds.remove(touchPoint.id);
break;
case EMSCRIPTEN_EVENT_TOUCHMOVE:
- touchPoint.state = Qt::TouchPointMoved;
+ touchPoint.state = (stationaryTouchPoint
+ ? Qt::TouchPointStationary
+ : Qt::TouchPointMoved);
+
+ pressedTouchIds.insert(touchPoint.id, touchPoint.normalPosition);
break;
default:
- Q_UNREACHABLE();
+ break;
}
touchPointList.append(touchPoint);
}
- QWasmEventTranslator *wasmEventTranslator = (QWasmEventTranslator*)userData;
QFlags<Qt::KeyboardModifier> keyModifier = translatKeyModifier(touchEvent);
- if (eventType != EMSCRIPTEN_EVENT_TOUCHCANCEL)
- QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(window2, wasmEventTranslator->getTimestamp(), wasmEventTranslator->touchDevice, touchPointList, keyModifier);
- else
- QWindowSystemInterface::handleTouchCancelEvent(window2, wasmEventTranslator->getTimestamp(), wasmEventTranslator->touchDevice, keyModifier);
+ QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(
+ window2, getTimestamp(), touchDevice, touchPointList, keyModifier);
+
+ if (eventType == EMSCRIPTEN_EVENT_TOUCHCANCEL)
+ QWindowSystemInterface::handleTouchCancelEvent(window2, getTimestamp(), touchDevice, keyModifier);
QWasmEventDispatcher::maintainTimers();
- return 1;
+ return 0;
}
quint64 QWasmEventTranslator::getTimestamp()
@@ -560,4 +778,149 @@ quint64 QWasmEventTranslator::getTimestamp()
return QDeadlineTimer::current().deadlineNSecs() / 1000;
}
+Qt::Key QWasmEventTranslator::translateDeadKey(Qt::Key deadKey, Qt::Key accentBaseKey)
+{
+ Qt::Key wasmKey = Qt::Key_unknown;
+ switch (deadKey) {
+#ifdef Q_OS_MACOS
+ case Qt::Key_QuoteLeft: // ` macOS: Key_Dead_Grave
+#else
+ case Qt::Key_O: // ´ Key_Dead_Grave
+#endif
+ wasmKey = graveKeyTable.value(accentBaseKey);
+ break;
+ case Qt::Key_E: // ´ Key_Dead_Acute
+ wasmKey = acuteKeyTable.value(accentBaseKey);
+ break;
+ case Qt::Key_AsciiTilde:
+ case Qt::Key_N:// Key_Dead_Tilde
+ wasmKey = tildeKeyTable.value(accentBaseKey);
+ break;
+#ifndef Q_OS_MACOS
+ case Qt::Key_QuoteLeft:
+#endif
+ case Qt::Key_U:// ¨ Key_Dead_Diaeresis
+ wasmKey = diaeresisKeyTable.value(accentBaseKey);
+ break;
+ case Qt::Key_I:// macOS Key_Dead_Circumflex
+ case Qt::Key_6:// linux
+ case Qt::Key_Apostrophe:// linux
+ wasmKey = circumflexKeyTable.value(accentBaseKey);
+ break;
+ break;
+ default:
+ break;
+ };
+
+ return wasmKey;
+}
+
+bool QWasmEventTranslator::processKeyboard(int eventType, const EmscriptenKeyboardEvent *keyEvent)
+{
+ Qt::Key qtKey = translateEmscriptKey(keyEvent);
+
+ Qt::KeyboardModifiers modifiers = translateKeyboardEventModifier(keyEvent);
+
+ QString keyText;
+ QEvent::Type keyType = QEvent::None;
+ switch (eventType) {
+ case EMSCRIPTEN_EVENT_KEYPRESS:
+ case EMSCRIPTEN_EVENT_KEYDOWN: // down
+ keyType = QEvent::KeyPress;
+
+ if (m_emDeadKey != Qt::Key_unknown) {
+
+ Qt::Key transformedKey = translateDeadKey(m_emDeadKey, qtKey);
+
+ if (transformedKey != Qt::Key_unknown)
+ qtKey = transformedKey;
+
+ if (keyEvent->shiftKey == 0) {
+ for (auto it = KeyTbl.cbegin(); it != KeyTbl.end(); ++it) {
+ if (it != KeyTbl.end() && (qtKey == static_cast<Qt::Key>(it->qt))) {
+ keyText = it->em;
+ m_emDeadKey = Qt::Key_unknown;
+ break;
+ }
+ }
+ } else {
+ for (auto it = DeadKeyShiftTbl.cbegin(); it != DeadKeyShiftTbl.end(); ++it) {
+ if (it != DeadKeyShiftTbl.end() && (qtKey == static_cast<Qt::Key>(it->qt))) {
+ keyText = it->em;
+ m_emDeadKey = Qt::Key_unknown;
+ break;
+ }
+ }
+ }
+ }
+ if (qstrncmp(keyEvent->key, "Dead", 4) == 0 || qtKey == Qt::Key_AltGr) {
+ qtKey = translateEmscriptKey(keyEvent);
+ m_emStickyDeadKey = true;
+ if (keyEvent->shiftKey == 1 && qtKey == Qt::Key_QuoteLeft)
+ qtKey = Qt::Key_AsciiTilde;
+ m_emDeadKey = qtKey;
+ }
+ break;
+ case EMSCRIPTEN_EVENT_KEYUP: // up
+ keyType = QEvent::KeyRelease;
+ if (m_emStickyDeadKey && qtKey != Qt::Key_Alt) {
+ m_emStickyDeadKey = false;
+ }
+ break;
+ default:
+ break;
+ };
+
+ if (keyType == QEvent::None)
+ return 0;
+
+ QFlags<Qt::KeyboardModifier> mods = translateKeyboardEventModifier(keyEvent);
+
+ // Clipboard fallback path: cut/copy/paste are handled by clipboard event
+ // handlers if direct clipboard access is not available.
+ if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi && modifiers & Qt::ControlModifier &&
+ (qtKey == Qt::Key_X || qtKey == Qt::Key_C || qtKey == Qt::Key_V)) {
+ return 0;
+ }
+
+ bool accepted = false;
+
+ if (keyType == QEvent::KeyPress &&
+ mods.testFlag(Qt::ControlModifier)
+ && qtKey == Qt::Key_V) {
+ QWasmIntegration::get()->getWasmClipboard()->readTextFromClipboard();
+ } else {
+ if (keyText.isEmpty())
+ keyText = QString(keyEvent->key);
+ if (keyText.size() > 1)
+ keyText.clear();
+ accepted = QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(
+ 0, keyType, qtKey, modifiers, keyText);
+ }
+ if (keyType == QEvent::KeyPress &&
+ mods.testFlag(Qt::ControlModifier)
+ && qtKey == Qt::Key_C) {
+ QWasmIntegration::get()->getWasmClipboard()->writeTextToClipboard();
+ }
+
+ QWasmEventDispatcher::maintainTimers();
+
+ return accepted;
+}
+
+int QWasmEventTranslator::uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData)
+{
+ Q_UNUSED(e)
+ QWasmEventTranslator *eventTranslator = static_cast<QWasmEventTranslator *>(userData);
+
+ if (eventType == EMSCRIPTEN_EVENT_RESIZE) {
+ // This resize event is called when the HTML window is resized. Depending
+ // on the page layout the the canvas might also have been resized, so we
+ // update the Qt screen size (and canvas render size).
+ eventTranslator->screen()->updateQScreenAndCanvasRenderSize();
+ }
+
+ return 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.h b/src/plugins/platforms/wasm/qwasmeventtranslator.h
index f3dff8e48c..d6043072ba 100644
--- a/src/plugins/platforms/wasm/qwasmeventtranslator.h
+++ b/src/plugins/platforms/wasm/qwasmeventtranslator.h
@@ -36,6 +36,7 @@
#include <emscripten/html5.h>
#include "qwasmwindow.h"
#include <QtGui/qtouchdevice.h>
+#include <QHash>
QT_BEGIN_NAMESPACE
@@ -45,133 +46,9 @@ class QWasmEventTranslator : public QObject
{
Q_OBJECT
- enum KeyCode {
- // numpad
- KeyNumPad0 = 0x60,
- KeyNumPad1 = 0x61,
- KeyNumPad2 = 0x62,
- KeyNumPad3 = 0x63,
- KeyNumPad4 = 0x64,
- KeyNumPad5 = 0x65,
- KeyNumPad6 = 0x66,
- KeyNumPad7 = 0x67,
- KeyNumPad8 = 0x68,
- KeyNumPad9 = 0x69,
- KeyMultiply = 0x6A,
- KeyAdd = 0x6B,
- KeySeparator = 0x6C,
- KeySubtract = 0x6D,
- KeyDecimal = 0x6E,
- KeyDivide = 0x6F,
- KeyMeta = 0x5B,
- KeyMetaRight = 0x5C,
- ////////
- KeyClear = 0x90,
- KeyEnter = 0xD,
- KeyBackSpace = 0x08,
- KeyCancel = 0x03,
- KeyTab = 0x09,
- KeyShift = 0x10,
- KeyControl = 0x11,
- KeyAlt = 0x12,
- KeyPause = 0x13,
- KeyCapsLock = 0x14,
- KeyEscape = 0x1B,
- KeySpace = 0x20,
- KeyPageUp = 0x21,
- KeyPageDown = 0x22,
- KeyEnd = 0x23,
- KeyHome = 0x24,
- KeyLeft = 0x25,
- KeyUp = 0x26,
- KeyRight = 0x27,
- KeyDown = 0x28,
- KeyComma = 0xBC,
- KeyPeriod = 0xBE,
- KeySlash = 0xBF,
- KeyZero = 0x30,
- KeyOne = 0x31,
- KeyTwo = 0x32,
- KeyThree = 0x33,
- KeyFour = 0x34,
- KeyFive = 0x35,
- KeySix = 0x36,
- KeySeven = 0x37,
- KeyEight = 0x38,
- KeyNine = 0x39,
- KeyBrightnessDown = 0xD8,
- KeyBrightnessUp = 0xD9,
- KeyMediaTrackPrevious = 0xB1,
- KeyMediaPlayPause = 0xB3,
- KeyMediaTrackNext = 0xB0,
- KeyAudioVolumeMute = 0xAD,
- KeyAudioVolumeDown = 0xAE,
- KeyAudioVolumeUp = 0xAF,
- KeySemiColon = 0xBA,
- KeyEquals = 0xBB,
- KeyMinus = 0xBD,
- KeyA = 0x41,
- KeyB = 0x42,
- KeyC = 0x43,
- KeyD = 0x44,
- KeyE = 0x45,
- KeyF = 0x46,
- KeyG = 0x47,
- KeyH = 0x48,
- KeyI = 0x49,
- KeyJ = 0x4A,
- KeyK = 0x4B,
- KeyL = 0x4C,
- KeyM = 0x4D,
- KeyN = 0x4E,
- KeyO = 0x4F,
- KeyP = 0x50,
- KeyQ = 0x51,
- KeyR = 0x52,
- KeyS = 0x53,
- KeyT = 0x54,
- KeyU = 0x55,
- KeyV = 0x56,
- KeyW = 0x57,
- KeyX = 0x58,
- KeyY = 0x59,
- KeyZ = 0x5A,
- KeyOpenBracket = 0xDB,
- KeyBackSlash = 0xDC,
- KeyCloseBracket = 0xDD,
- KeyF1 = 0x70,
- KeyF2 = 0x71,
- KeyF3 = 0x72,
- KeyF4 = 0x73,
- KeyF5 = 0x74,
- KeyF6 = 0x75,
- KeyF7 = 0x76,
- KeyF8 = 0x77,
- KeyF9 = 0x78,
- KeyF10 = 0x79,
- KeyF11 = 0x7A,
- KeyF12 = 0x7B,
- KeyDelete = 0x2E,
- KeyNumLock = 0x90,
- KeyScrollLock = 0x91,
- KeyPrintScreen = 0x9A,
- KeyInsert = 0x9B,
- KeyHelp = 0x9C,
- KeyBackQuote = 0xC0,
- KeyQuote = 0xDE,
- KeyFinal = 0x18,
- KeyConvert = 0x1C,
- KeyNonConvert = 0x1D,
- KeyAccept = 0x1E,
- KeyModeChange = 0x1F,
- KeyKana = 0x15,
- KeyKanji = 0x19,
- KeyUndefined = 0x0
- };
-
public:
- explicit QWasmEventTranslator(QObject *parent = 0);
+ explicit QWasmEventTranslator(QWasmScreen *screen);
static int keyboard_cb(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData);
static int mouse_cb(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
@@ -180,19 +57,65 @@ public:
static int touchCallback(int eventType, const EmscriptenTouchEvent *ev, void *userData);
+ static int uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData);
+
void processEvents();
+ void initEventHandlers();
+ int handleTouch(int eventType, const EmscriptenTouchEvent *touchEvent);
Q_SIGNALS:
void getWindowAt(const QPoint &point, QWindow **window);
private:
- static Qt::Key translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey, bool *outAlphanumretic);
+ QWasmScreen *screen();
+ Qt::Key translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey);
template <typename Event>
- static QFlags<Qt::KeyboardModifier> translatKeyModifier(const Event *event);
- static QFlags<Qt::KeyboardModifier> translateKeyboardEventModifier(const EmscriptenKeyboardEvent *keyEvent);
- static QFlags<Qt::KeyboardModifier> translateMouseEventModifier(const EmscriptenMouseEvent *mouseEvent);
- static Qt::MouseButton translateMouseButton(unsigned short button);
+ QFlags<Qt::KeyboardModifier> translatKeyModifier(const Event *event);
+ QFlags<Qt::KeyboardModifier> translateKeyboardEventModifier(const EmscriptenKeyboardEvent *keyEvent);
+ QFlags<Qt::KeyboardModifier> translateMouseEventModifier(const EmscriptenMouseEvent *mouseEvent);
+ Qt::MouseButton translateMouseButton(unsigned short button);
void processMouse(int eventType, const EmscriptenMouseEvent *mouseEvent);
+ bool processKeyboard(int eventType, const EmscriptenKeyboardEvent *keyEvent);
+
+ Qt::Key translateDeadKey(Qt::Key deadKey, Qt::Key accentBaseKey);
+
+ QHash<Qt::Key , Qt::Key> tildeKeyTable { // ~
+ { Qt::Key_A, Qt::Key_Atilde},
+ { Qt::Key_N, Qt::Key_Ntilde},
+ { Qt::Key_O, Qt::Key_Otilde}
+ };
+ QHash<Qt::Key , Qt::Key> graveKeyTable { // `
+ { Qt::Key_A, Qt::Key_Agrave},
+ { Qt::Key_E, Qt::Key_Egrave},
+ { Qt::Key_I, Qt::Key_Igrave},
+ { Qt::Key_O, Qt::Key_Ograve},
+ { Qt::Key_U, Qt::Key_Ugrave}
+ };
+ QHash<Qt::Key , Qt::Key> acuteKeyTable { // '
+ { Qt::Key_A, Qt::Key_Aacute},
+ { Qt::Key_E, Qt::Key_Eacute},
+ { Qt::Key_I, Qt::Key_Iacute},
+ { Qt::Key_O, Qt::Key_Oacute},
+ { Qt::Key_U, Qt::Key_Uacute},
+ { Qt::Key_Y, Qt::Key_Yacute}
+ };
+ QHash<Qt::Key , Qt::Key> diaeresisKeyTable { // umlaut ¨
+ { Qt::Key_A, Qt::Key_Adiaeresis},
+ { Qt::Key_E, Qt::Key_Ediaeresis},
+ { Qt::Key_I, Qt::Key_Idiaeresis},
+ { Qt::Key_O, Qt::Key_Odiaeresis},
+ { Qt::Key_U, Qt::Key_Udiaeresis},
+ { Qt::Key_Y, Qt::Key_ydiaeresis}
+ };
+ QHash<Qt::Key , Qt::Key> circumflexKeyTable { // ^
+ { Qt::Key_A, Qt::Key_Acircumflex},
+ { Qt::Key_E, Qt::Key_Ecircumflex},
+ { Qt::Key_I, Qt::Key_Icircumflex},
+ { Qt::Key_O, Qt::Key_Ocircumflex},
+ { Qt::Key_U, Qt::Key_Ucircumflex}
+ };
+
+ QMap <int, QPointF> pressedTouchIds;
private:
QWindow *draggedWindow;
@@ -205,6 +128,9 @@ private:
QRect resizeStartRect;
QTouchDevice *touchDevice;
quint64 getTimestamp();
+
+ Qt::Key m_emDeadKey = Qt::Key_unknown;
+ bool m_emStickyDeadKey = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp
index 3829043d07..e601d553f2 100644
--- a/src/plugins/platforms/wasm/qwasmintegration.cpp
+++ b/src/plugins/platforms/wasm/qwasmintegration.cpp
@@ -33,6 +33,8 @@
#include "qwasmcompositor.h"
#include "qwasmopenglcontext.h"
#include "qwasmtheme.h"
+#include "qwasmclipboard.h"
+#include "qwasmservices.h"
#include "qwasmwindow.h"
#ifndef QT_NO_OPENGL
@@ -55,47 +57,76 @@
using namespace emscripten;
QT_BEGIN_NAMESPACE
-void browserBeforeUnload()
+static void browserBeforeUnload(emscripten::val)
{
QWasmIntegration::QWasmBrowserExit();
}
-EMSCRIPTEN_BINDINGS(my_module)
+static void addCanvasElement(emscripten::val canvas)
{
- function("browserBeforeUnload", &browserBeforeUnload);
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ QWasmIntegration::get()->addScreen(canvasId);
}
-static QWasmIntegration *globalHtml5Integration;
-QWasmIntegration *QWasmIntegration::get() { return globalHtml5Integration; }
+static void removeCanvasElement(emscripten::val canvas)
+{
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ QWasmIntegration::get()->removeScreen(canvasId);
+}
-QWasmIntegration::QWasmIntegration()
- : m_fontDb(nullptr),
- m_compositor(new QWasmCompositor),
- m_screen(new QWasmScreen(m_compositor)),
- m_eventDispatcher(nullptr)
+static void resizeCanvasElement(emscripten::val canvas)
{
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ QWasmIntegration::get()->resizeScreen(canvasId);
+}
- globalHtml5Integration = this;
+EMSCRIPTEN_BINDINGS(qtQWasmIntegraton)
+{
+ function("qtBrowserBeforeUnload", &browserBeforeUnload);
+ function("qtAddCanvasElement", &addCanvasElement);
+ function("qtRemoveCanvasElement", &removeCanvasElement);
+ function("qtResizeCanvasElement", &resizeCanvasElement);
+}
- updateQScreenAndCanvasRenderSize();
- QWindowSystemInterface::handleScreenAdded(m_screen);
- emscripten_set_resize_callback(0, (void *)this, 1, uiEvent_cb);
+QWasmIntegration *QWasmIntegration::s_instance;
- m_eventTranslator = new QWasmEventTranslator;
+QWasmIntegration::QWasmIntegration()
+ : m_fontDb(nullptr),
+ m_desktopServices(nullptr),
+ m_clipboard(new QWasmClipboard)
+{
+ s_instance = this;
+
+ // We expect that qtloader.js has populated Module.qtCanvasElements with one or more canvases.
+ // Also check Module.canvas, which may be set if the emscripen or a custom loader is used.
+ emscripten::val qtCanvaseElements = val::module_property("qtCanvasElements");
+ emscripten::val canvas = val::module_property("canvas");
+
+ if (!qtCanvaseElements.isUndefined()) {
+ int screenCount = qtCanvaseElements["length"].as<int>();
+ for (int i = 0; i < screenCount; ++i) {
+ emscripten::val canvas = qtCanvaseElements[i].as<emscripten::val>();
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ addScreen(canvasId);
+ }
+ } else if (!canvas.isUndefined()){
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ addScreen(canvasId);
+ }
- EM_ASM(// exit app if browser closes
- window.onbeforeunload = function () {
- Module.browserBeforeUnload();
- };
- );
+ emscripten::val::global("window").set("onbeforeunload", val::module_property("qtBrowserBeforeUnload"));
}
QWasmIntegration::~QWasmIntegration()
{
- delete m_compositor;
- QWindowSystemInterface::handleScreenRemoved(m_screen);
delete m_fontDb;
- delete m_eventTranslator;
+ delete m_desktopServices;
+
+ for (auto it = m_screens.constBegin(); it != m_screens.constEnd(); ++it)
+ QWindowSystemInterface::handleScreenRemoved(*it);
+ m_screens.clear();
+
+ s_instance = nullptr;
}
void QWasmIntegration::QWasmBrowserExit()
@@ -109,7 +140,7 @@ bool QWasmIntegration::hasCapability(QPlatformIntegration::Capability cap) const
switch (cap) {
case ThreadedPixmaps: return true;
case OpenGL: return true;
- case ThreadedOpenGL: return true;
+ case ThreadedOpenGL: return false;
case RasterGLSurface: return false; // to enable this you need to fix qopenglwidget and quickwidget for wasm
case MultipleWindows: return true;
case WindowManagement: return true;
@@ -119,13 +150,15 @@ bool QWasmIntegration::hasCapability(QPlatformIntegration::Capability cap) const
QPlatformWindow *QWasmIntegration::createPlatformWindow(QWindow *window) const
{
- return new QWasmWindow(window, m_compositor, m_backingStores.value(window));
+ QWasmCompositor *compositor = QWasmScreen::get(window->screen())->compositor();
+ return new QWasmWindow(window, compositor, m_backingStores.value(window));
}
QPlatformBackingStore *QWasmIntegration::createPlatformBackingStore(QWindow *window) const
{
#ifndef QT_NO_OPENGL
- QWasmBackingStore *backingStore = new QWasmBackingStore(m_compositor, window);
+ QWasmCompositor *compositor = QWasmScreen::get(window->screen())->compositor();
+ QWasmBackingStore *backingStore = new QWasmBackingStore(compositor, window);
m_backingStores.insert(window, backingStore);
return backingStore;
#else
@@ -155,9 +188,21 @@ QAbstractEventDispatcher *QWasmIntegration::createEventDispatcher() const
QVariant QWasmIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
+ if (hint == ShowIsFullScreen)
+ return true;
+
return QPlatformIntegration::styleHint(hint);
}
+Qt::WindowState QWasmIntegration::defaultWindowState(Qt::WindowFlags flags) const
+{
+ // Don't maximize dialogs
+ if (flags & Qt::Dialog & ~Qt::Window)
+ return Qt::WindowNoState;
+
+ return QPlatformIntegration::defaultWindowState(flags);
+}
+
QStringList QWasmIntegration::themeNames() const
{
return QStringList() << QLatin1String("webassembly");
@@ -170,50 +215,34 @@ QPlatformTheme *QWasmIntegration::createPlatformTheme(const QString &name) const
return QPlatformIntegration::createPlatformTheme(name);
}
-int QWasmIntegration::uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData)
+QPlatformServices *QWasmIntegration::services() const
{
- Q_UNUSED(e)
- Q_UNUSED(userData)
-
- if (eventType == EMSCRIPTEN_EVENT_RESIZE) {
- // This resize event is called when the HTML window is resized. Depending
- // on the page layout the the canvas might also have been resized, so we
- // update the Qt screen size (and canvas render size).
- updateQScreenAndCanvasRenderSize();
- }
-
- return 0;
+ if (m_desktopServices == nullptr)
+ m_desktopServices = new QWasmServices();
+ return m_desktopServices;
}
-static void set_canvas_size(double width, double height)
+QPlatformClipboard* QWasmIntegration::clipboard() const
{
- EM_ASM_({
- var canvas = Module.canvas;
- canvas.width = $0;
- canvas.height = $1;
- }, width, height);
+ return m_clipboard;
}
-void QWasmIntegration::updateQScreenAndCanvasRenderSize()
+void QWasmIntegration::addScreen(const QString &canvasId)
{
- // The HTML canvas has two sizes: the CSS size and the canvas render size.
- // The CSS size is determined according to standard CSS rules, while the
- // render size is set using the "width" and "height" attributes. The render
- // size must be set manually and is not auto-updated on CSS size change.
- // Setting the render size to a value larger than the CSS size enables high-dpi
- // rendering.
-
- double css_width;
- double css_height;
- emscripten_get_element_css_size(0, &css_width, &css_height);
- QSizeF cssSize(css_width, css_height);
+ QWasmScreen *screen = new QWasmScreen(canvasId);
+ m_clipboard->installEventHandlers(canvasId);
+ m_screens.insert(canvasId, screen);
+ QWindowSystemInterface::handleScreenAdded(screen);
+}
- QWasmScreen *screen = QWasmIntegration::get()->m_screen;
- QSizeF canvasSize = cssSize * screen->devicePixelRatio();
+void QWasmIntegration::removeScreen(const QString &canvasId)
+{
+ QWindowSystemInterface::handleScreenRemoved(m_screens.take(canvasId));
+}
- set_canvas_size(canvasSize.width(), canvasSize.height());
- screen->setGeometry(QRect(QPoint(0, 0), cssSize.toSize()));
- QWasmIntegration::get()->m_compositor->redrawWindowContent();
+void QWasmIntegration::resizeScreen(const QString &canvasId)
+{
+ m_screens.value(canvasId)->updateQScreenAndCanvasRenderSize();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h
index ebc3d9d431..11d8d0f7f5 100644
--- a/src/plugins/platforms/wasm/qwasmintegration.h
+++ b/src/plugins/platforms/wasm/qwasmintegration.h
@@ -49,6 +49,8 @@ class QWasmEventDispatcher;
class QWasmScreen;
class QWasmCompositor;
class QWasmBackingStore;
+class QWasmClipboard;
+class QWasmServices;
class QWasmIntegration : public QObject, public QPlatformIntegration
{
@@ -66,25 +68,28 @@ public:
QPlatformFontDatabase *fontDatabase() const override;
QAbstractEventDispatcher *createEventDispatcher() const override;
QVariant styleHint(QPlatformIntegration::StyleHint hint) const override;
+ Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const override;
QStringList themeNames() const override;
QPlatformTheme *createPlatformTheme(const QString &name) const override;
+ QPlatformServices *services() const override;
+ QPlatformClipboard *clipboard() const override;
+ QWasmClipboard *getWasmClipboard() { return m_clipboard; }
- static QWasmIntegration *get();
- QWasmScreen *screen() { return m_screen; }
- QWasmCompositor *compositor() { return m_compositor; }
- QWasmEventTranslator *eventTranslator() { return m_eventTranslator; }
-
+ static QWasmIntegration *get() { return s_instance; }
static void QWasmBrowserExit();
- static void updateQScreenAndCanvasRenderSize();
+
+ void addScreen(const QString &canvasId);
+ void removeScreen(const QString &canvasId);
+ void resizeScreen(const QString &canvasId);
private:
mutable QWasmFontDatabase *m_fontDb;
- QWasmCompositor *m_compositor;
- mutable QWasmScreen *m_screen;
- mutable QWasmEventTranslator *m_eventTranslator;
- mutable QWasmEventDispatcher *m_eventDispatcher;
- static int uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData);
+ mutable QWasmServices *m_desktopServices;
mutable QHash<QWindow *, QWasmBackingStore *> m_backingStores;
+
+ QHash<QString, QWasmScreen *> m_screens;
+ mutable QWasmClipboard *m_clipboard;
+ static QWasmIntegration *s_instance;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
index 73af3d1878..ae43e2ebf0 100644
--- a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
+++ b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
@@ -28,7 +28,7 @@
****************************************************************************/
#include "qwasmopenglcontext.h"
-
+#include "qwasmintegration.h"
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
@@ -57,7 +57,7 @@ void QWasmOpenGLContext::maybeRecreateEmscriptenContext(QPlatformSurface *surfac
emscripten_webgl_destroy_context(m_context);
// Create new context
- const char *canvasId = 0; // (use default canvas) FIXME: get the actual canvas from the surface.
+ const QString canvasId = QWasmScreen::get(surface->screen())->canvasId();
m_context = createEmscriptenContext(canvasId, m_requestedFormat);
// Register context-lost callback.
@@ -73,11 +73,11 @@ void QWasmOpenGLContext::maybeRecreateEmscriptenContext(QPlatformSurface *surfac
return true;
};
bool capture = true;
- emscripten_set_webglcontextlost_callback(canvasId, this, capture, callback);
+ emscripten_set_webglcontextlost_callback(canvasId.toLocal8Bit().constData(), this, capture, callback);
}
}
-EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(const char *canvasId, QSurfaceFormat format)
+EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(const QString &canvasId, QSurfaceFormat format)
{
EmscriptenWebGLContextAttributes attributes;
emscripten_webgl_init_context_attributes(&attributes); // Populate with default attributes
@@ -96,7 +96,7 @@ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(cons
attributes.depth = format.depthBufferSize() > 0;
attributes.stencil = format.stencilBufferSize() > 0;
- EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(canvasId, &attributes);
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(canvasId.toLocal8Bit().constData(), &attributes);
return context;
}
diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.h b/src/plugins/platforms/wasm/qwasmopenglcontext.h
index 9123100479..126b596a7e 100644
--- a/src/plugins/platforms/wasm/qwasmopenglcontext.h
+++ b/src/plugins/platforms/wasm/qwasmopenglcontext.h
@@ -51,7 +51,7 @@ public:
private:
void maybeRecreateEmscriptenContext(QPlatformSurface *surface);
- static EMSCRIPTEN_WEBGL_CONTEXT_HANDLE createEmscriptenContext(const char *canvasId, QSurfaceFormat format);
+ static EMSCRIPTEN_WEBGL_CONTEXT_HANDLE createEmscriptenContext(const QString &canvasId, QSurfaceFormat format);
bool m_contextLost = false;
QSurfaceFormat m_requestedFormat;
diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
index 93e9906ffc..a26cafa900 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.cpp
+++ b/src/plugins/platforms/wasm/qwasmscreen.cpp
@@ -29,7 +29,10 @@
#include "qwasmscreen.h"
#include "qwasmwindow.h"
+#include "qwasmeventtranslator.h"
#include "qwasmcompositor.h"
+#include <emscripten/bind.h>
+#include <emscripten/val.h>
#include <QtEglSupport/private/qeglconvenience_p.h>
#ifndef QT_NO_OPENGL
@@ -43,12 +46,13 @@
QT_BEGIN_NAMESPACE
-QWasmScreen::QWasmScreen(QWasmCompositor *compositor)
- : m_compositor(compositor)
- , m_depth(32)
- , m_format(QImage::Format_RGB32)
+QWasmScreen::QWasmScreen(const QString &canvasId)
+ : m_canvasId(canvasId)
+
{
- m_compositor->setScreen(this);
+ m_compositor = new QWasmCompositor(this);
+ m_eventTranslator = new QWasmEventTranslator(this);
+ updateQScreenAndCanvasRenderSize();
}
QWasmScreen::~QWasmScreen()
@@ -56,6 +60,31 @@ QWasmScreen::~QWasmScreen()
}
+QWasmScreen *QWasmScreen::get(QPlatformScreen *screen)
+{
+ return static_cast<QWasmScreen *>(screen);
+}
+
+QWasmScreen *QWasmScreen::get(QScreen *screen)
+{
+ return get(screen->handle());
+}
+
+QWasmCompositor *QWasmScreen::compositor()
+{
+ return m_compositor;
+}
+
+QWasmEventTranslator *QWasmScreen::eventTranslator()
+{
+ return m_eventTranslator;
+}
+
+QString QWasmScreen::canvasId() const
+{
+ return m_canvasId;
+}
+
QRect QWasmScreen::geometry() const
{
return m_geometry;
@@ -77,12 +106,15 @@ qreal QWasmScreen::devicePixelRatio() const
// HTML window dpr if the OpenGL driver/GPU allocates a less than
// full resolution surface. Use emscripten_webgl_get_drawing_buffer_size()
// and compute the dpr instead.
- double htmlWindowDpr = EM_ASM_DOUBLE({
- return window.devicePixelRatio;
- });
+ double htmlWindowDpr = emscripten::val::global("window")["devicePixelRatio"].as<double>();
return qreal(htmlWindowDpr);
}
+QString QWasmScreen::name() const
+{
+ return m_canvasId;
+}
+
QPlatformCursor *QWasmScreen::cursor() const
{
return const_cast<QWasmCursor *>(&m_cursor);
@@ -115,4 +147,31 @@ void QWasmScreen::setGeometry(const QRect &rect)
resizeMaximizedWindows();
}
+void QWasmScreen::updateQScreenAndCanvasRenderSize()
+{
+ // The HTML canvas has two sizes: the CSS size and the canvas render size.
+ // The CSS size is determined according to standard CSS rules, while the
+ // render size is set using the "width" and "height" attributes. The render
+ // size must be set manually and is not auto-updated on CSS size change.
+ // Setting the render size to a value larger than the CSS size enables high-dpi
+ // rendering.
+
+ QByteArray canvasId = m_canvasId.toUtf8();
+ double css_width;
+ double css_height;
+ emscripten_get_element_css_size(canvasId.constData(), &css_width, &css_height);
+ QSizeF cssSize(css_width, css_height);
+
+ QSizeF canvasSize = cssSize * devicePixelRatio();
+ emscripten::val canvas = emscripten::val::global(canvasId.constData());
+ canvas.set("width", canvasSize.width());
+ canvas.set("height", canvasSize.height());
+
+ emscripten::val rect = canvas.call<emscripten::val>("getBoundingClientRect");
+ QPoint position(rect["left"].as<int>(), rect["top"].as<int>());
+
+ setGeometry(QRect(position, cssSize.toSize()));
+ m_compositor->redrawWindowContent();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmscreen.h b/src/plugins/platforms/wasm/qwasmscreen.h
index 3891db77bb..82d2a83edb 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.h
+++ b/src/plugins/platforms/wasm/qwasmscreen.h
@@ -43,20 +43,28 @@ class QPlatformOpenGLContext;
class QWasmWindow;
class QWasmBackingStore;
class QWasmCompositor;
+class QWasmEventTranslator;
class QOpenGLContext;
class QWasmScreen : public QObject, public QPlatformScreen
{
Q_OBJECT
public:
-
- QWasmScreen(QWasmCompositor *compositor);
+ QWasmScreen(const QString &canvasId);
~QWasmScreen();
+ static QWasmScreen *get(QPlatformScreen *screen);
+ static QWasmScreen *get(QScreen *screen);
+ QString canvasId() const;
+
+ QWasmCompositor *compositor();
+ QWasmEventTranslator *eventTranslator();
+
QRect geometry() const override;
int depth() const override;
QImage::Format format() const override;
qreal devicePixelRatio() const override;
+ QString name() const override;
QPlatformCursor *cursor() const override;
void resizeMaximizedWindows();
@@ -64,17 +72,18 @@ public:
QWindow *topLevelAt(const QPoint &p) const override;
void invalidateSize();
+ void updateQScreenAndCanvasRenderSize();
public slots:
void setGeometry(const QRect &rect);
-protected:
private:
- QWasmCompositor *m_compositor;
-
+ QString m_canvasId;
+ QWasmCompositor *m_compositor = nullptr;
+ QWasmEventTranslator *m_eventTranslator = nullptr;
QRect m_geometry = QRect(0, 0, 100, 100);
- int m_depth;
- QImage::Format m_format;
+ int m_depth = 32;
+ QImage::Format m_format = QImage::Format_RGB32;
QWasmCursor m_cursor;
};
diff --git a/src/plugins/platforms/wasm/qwasmservices.cpp b/src/plugins/platforms/wasm/qwasmservices.cpp
new file mode 100644
index 0000000000..9328b8c065
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmservices.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmservices.h"
+#include <QtCore/QUrl>
+#include <QtCore/QDebug>
+
+#include <emscripten/val.h>
+
+QT_BEGIN_NAMESPACE
+
+bool QWasmServices::openUrl(const QUrl &url)
+{
+ QByteArray utf8Url = url.toString().toUtf8();
+ emscripten::val::global("window").call<void>("open", emscripten::val(utf8Url.constData()), emscripten::val("_blank"));
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/globaldefs.h b/src/plugins/platforms/wasm/qwasmservices.h
index 5ad193c29a..3b37f21f82 100644
--- a/src/tools/uic/globaldefs.h
+++ b/src/plugins/platforms/wasm/qwasmservices.h
@@ -1,11 +1,11 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the tools applications of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
@@ -16,8 +16,9 @@
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
@@ -26,16 +27,19 @@
**
****************************************************************************/
-#ifndef GLOBALDEFS_H
-#define GLOBALDEFS_H
+#ifndef QWASMDESKTOPSERVICES_H
+#define QWASMDESKTOPSERVICES_H
-#include <qglobal.h>
+#include <qpa/qplatformservices.h>
QT_BEGIN_NAMESPACE
-enum { BOXLAYOUT_DEFAULT_MARGIN = 11 };
-enum { BOXLAYOUT_DEFAULT_SPACING = 6 };
+class QWasmServices : public QPlatformServices
+{
+public:
+ bool openUrl(const QUrl &url) override;
+};
QT_END_NAMESPACE
-#endif // GLOBALDEFS_H
+#endif // QWASMDESKTOPSERVICES_H
diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp
index 25a0190053..39797cb09d 100644
--- a/src/plugins/platforms/wasm/qwasmwindow.cpp
+++ b/src/plugins/platforms/wasm/qwasmwindow.cpp
@@ -198,8 +198,10 @@ void QWasmWindow::injectMouseReleased(const QPoint &local, const QPoint &global,
if (!hasTitleBar() || button != Qt::LeftButton)
return;
- if (closeButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarCloseButton)
+ if (closeButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarCloseButton) {
window()->close();
+ return;
+ }
if (maxButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarMaxButton) {
window()->setWindowState(Qt::WindowMaximized);
diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro
index eaaba53aa2..9b98445c68 100644
--- a/src/plugins/platforms/wasm/wasm.pro
+++ b/src/plugins/platforms/wasm/wasm.pro
@@ -18,7 +18,9 @@ SOURCES = \
qwasmcompositor.cpp \
qwasmcursor.cpp \
qwasmopenglcontext.cpp \
- qwasmtheme.cpp
+ qwasmtheme.cpp \
+ qwasmclipboard.cpp \
+ qwasmservices.cpp
HEADERS = \
qwasmintegration.h \
@@ -31,7 +33,9 @@ HEADERS = \
qwasmstylepixmaps_p.h \
qwasmcursor.h \
qwasmopenglcontext.h \
- qwasmtheme.h
+ qwasmtheme.h \
+ qwasmclipboard.h \
+ qwasmservices.h
wasmfonts.files = \
../../../3rdparty/wasm/Vera.ttf \
diff --git a/src/plugins/platforms/wasm/wasm_shell.html b/src/plugins/platforms/wasm/wasm_shell.html
index 67bfcdfbdc..6ad7886ed4 100644
--- a/src/plugins/platforms/wasm/wasm_shell.html
+++ b/src/plugins/platforms/wasm/wasm_shell.html
@@ -7,27 +7,32 @@
<style>
html, body { padding: 0; margin : 0; overflow:hidden; height: 100% }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
- canvas { border: 0px none; background-color: white; height:100%; width:100%; }
+ canvas { border: 0px none; background-color: white; height:100%; width:100%; }
+ /* The contenteditable property is set to true for the canvas in order to support
+ clipboard events. Hide the resulting focus frame and set the cursor back to
+ the default cursor. */
+ canvas { outline: 0px solid transparent; cursor:default }
</style>
</head>
<body onload="init()">
- <figure style="overflow:visible;" id="spinner">
+ <figure style="overflow:visible;" id="qtspinner">
<center style="margin-top:1.5em; line-height:150%">
<img src="qtlogo.svg"; width=320; height=200; style="display:block"> </img>
<strong>Qt for WebAssembly: APPNAME</strong>
- <div id="status"></div>
+ <div id="qtstatus"></div>
<noscript>JavaScript is disabled. Please enable JavaScript to use this application.</noscript>
</center>
</figure>
- <canvas id="canvas" oncontextmenu="event.preventDefault()"></canvas>
+ <canvas id="qtcanvas" oncontextmenu="event.preventDefault()" contenteditable="true"></canvas>
<script type='text/javascript'>
function init() {
- var spinner = document.getElementById('spinner');
- var canvas = document.getElementById('canvas');
- var status = document.getElementById('status')
+ var spinner = document.querySelector('#qtspinner');
+ var canvas = document.querySelector('#qtcanvas');
+ var status = document.querySelector('#qtstatus')
var qtLoader = QtLoader({
+ canvasElements : [canvas],
showLoader: function(loaderStatus) {
spinner.style.display = 'block';
canvas.style.display = 'none';
@@ -50,7 +55,6 @@
showCanvas: function() {
spinner.style.display = 'none';
canvas.style.display = 'block';
- return canvas;
},
});
qtLoader.loadEmscriptenModule("APPNAME");
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index 8adcf56b11..878f55e56b 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -445,7 +445,7 @@ static inline QTextFormat standardFormat(StandardFormat format)
const QPalette palette = QGuiApplication::palette();
const QColor background = palette.text().color();
result.setBackground(QBrush(background));
- result.setForeground(palette.background());
+ result.setForeground(palette.window());
break;
}
}
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
index ed945ec4b1..9003e94c56 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -277,6 +277,8 @@ QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &fun
return QFunctionPointer(QWindowsWindow::setTouchWindowTouchTypeStatic);
if (function == QWindowsWindowFunctions::setHasBorderInFullScreenIdentifier())
return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenStatic);
+ if (function == QWindowsWindowFunctions::setHasBorderInFullScreenDefaultIdentifier())
+ return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenDefault);
if (function == QWindowsWindowFunctions::setWindowActivationBehaviorIdentifier())
return QFunctionPointer(QWindowsNativeInterface::setWindowActivationBehavior);
if (function == QWindowsWindowFunctions::isTabletModeIdentifier())
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 6dd3e6ed56..a6b9781252 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -284,24 +284,24 @@ static inline QPalette systemPalette()
result.setColor(QPalette::Link, Qt::blue);
result.setColor(QPalette::LinkVisited, Qt::magenta);
result.setColor(QPalette::Inactive, QPalette::Button, result.button().color());
- result.setColor(QPalette::Inactive, QPalette::Window, result.background().color());
+ result.setColor(QPalette::Inactive, QPalette::Window, result.window().color());
result.setColor(QPalette::Inactive, QPalette::Light, result.light().color());
result.setColor(QPalette::Inactive, QPalette::Dark, result.dark().color());
if (result.midlight() == result.button())
result.setColor(QPalette::Midlight, result.button().color().lighter(110));
- if (result.background() != result.base()) {
+ if (result.window() != result.base()) {
result.setColor(QPalette::Inactive, QPalette::Highlight, result.color(QPalette::Inactive, QPalette::Window));
result.setColor(QPalette::Inactive, QPalette::HighlightedText, result.color(QPalette::Inactive, QPalette::Text));
}
const QColor disabled =
- mixColors(result.foreground().color(), result.button().color());
+ mixColors(result.windowText().color(), result.button().color());
- result.setColorGroup(QPalette::Disabled, result.foreground(), result.button(),
+ result.setColorGroup(QPalette::Disabled, result.windowText(), result.button(),
result.light(), result.dark(), result.mid(),
result.text(), result.brightText(), result.base(),
- result.background());
+ result.window());
result.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
result.setColor(QPalette::Disabled, QPalette::Text, disabled);
result.setColor(QPalette::Disabled, QPalette::ButtonText, disabled);
@@ -310,7 +310,7 @@ static inline QPalette systemPalette()
result.setColor(QPalette::Disabled, QPalette::HighlightedText,
getSysColor(COLOR_HIGHLIGHTTEXT));
result.setColor(QPalette::Disabled, QPalette::Base,
- result.background().color());
+ result.window().color());
return result;
}
@@ -333,7 +333,7 @@ static inline QPalette toolTipPalette(const QPalette &systemPalette)
result.setColor(QPalette::All, QPalette::ToolTipBase, tipBgColor);
result.setColor(QPalette::All, QPalette::ToolTipText, tipTextColor);
const QColor disabled =
- mixColors(result.foreground().color(), result.button().color());
+ mixColors(result.windowText().color(), result.button().color());
result.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
result.setColor(QPalette::Disabled, QPalette::Text, disabled);
result.setColor(QPalette::Disabled, QPalette::ToolTipText, disabled);
@@ -858,7 +858,8 @@ QPixmap QWindowsFileIconEngine::filePixmap(const QSize &size, QIcon::Mode, QIcon
int iIcon = (useDefaultFolderIcon && defaultFolderIIcon >= 0) ? defaultFolderIIcon
: **dirIconEntryCache.object(filePath);
if (iIcon) {
- QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize, requestedImageListSize), pixmap);
+ QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize, requestedImageListSize),
+ &pixmap);
if (pixmap.isNull()) // Let's keep both caches in sync
dirIconEntryCache.remove(filePath);
else
@@ -889,7 +890,7 @@ QPixmap QWindowsFileIconEngine::filePixmap(const QSize &size, QIcon::Mode, QIcon
//using the unique icon index provided by windows save us from duplicate keys
key = dirIconPixmapCacheKey(info.iIcon, iconSize, requestedImageListSize);
- QPixmapCache::find(key, pixmap);
+ QPixmapCache::find(key, &pixmap);
if (!pixmap.isNull()) {
QMutexLocker locker(&mx);
dirIconEntryCache.insert(filePath, FakePointer<int>::create(info.iIcon));
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 0376e363f3..338e594c7b 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1183,6 +1183,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
const char *QWindowsWindow::embeddedNativeParentHandleProperty = "_q_embedded_native_parent_handle";
const char *QWindowsWindow::hasBorderInFullScreenProperty = "_q_has_border_in_fullscreen";
+bool QWindowsWindow::m_borderInFullScreenDefault = false;
QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) :
QWindowsBaseWindow(aWindow),
@@ -1220,7 +1221,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
if (aWindow->isTopLevel())
setWindowIcon(aWindow->icon());
- if (aWindow->property(hasBorderInFullScreenProperty).toBool())
+ if (m_borderInFullScreenDefault || aWindow->property(hasBorderInFullScreenProperty).toBool())
setFlag(HasBorderInFullScreen);
clearFlag(WithinCreate);
}
@@ -2819,6 +2820,11 @@ void QWindowsWindow::setHasBorderInFullScreenStatic(QWindow *window, bool border
window->setProperty(hasBorderInFullScreenProperty, QVariant(border));
}
+void QWindowsWindow::setHasBorderInFullScreenDefault(bool border)
+{
+ m_borderInFullScreenDefault = border;
+}
+
void QWindowsWindow::setHasBorderInFullScreen(bool border)
{
if (testFlag(HasBorderInFullScreen) == border)
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 2675990cf1..0d8096ddfa 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -342,6 +342,7 @@ public:
static void setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes);
void registerTouchWindow(QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes = QWindowsWindowFunctions::NormalTouch);
static void setHasBorderInFullScreenStatic(QWindow *window, bool border);
+ static void setHasBorderInFullScreenDefault(bool border);
void setHasBorderInFullScreen(bool border);
static QString formatWindowTitle(const QString &title);
@@ -387,6 +388,7 @@ private:
// note: intentionally not using void * in order to avoid breaking x86
VkSurfaceKHR m_vkSurface = 0;
#endif
+ static bool m_borderInFullScreenDefault;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp
index 6ddcec0256..8d958aae94 100644
--- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp
+++ b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp
@@ -459,7 +459,7 @@ static QPixmap qt_patternForAlpha(uchar alpha, int screen)
% HexString<uchar>(alpha)
% HexString<int>(screen);
- if (!QPixmapCache::find(key, pm)) {
+ if (!QPixmapCache::find(key, &pm)) {
// #### why not use a mono image here????
QImage pattern(DITHER_SIZE, DITHER_SIZE, QImage::Format_ARGB32);
pattern.fill(0xffffffff);
diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h
index 9b01c0a3fc..bc82351283 100644
--- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h
+++ b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h
@@ -116,7 +116,7 @@ protected:
friend GC qt_x11_get_brush_gc(QPainter *);
private:
- Q_DISABLE_COPY(QX11PaintEngine)
+ Q_DISABLE_COPY_MOVE(QX11PaintEngine)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index f9240a45cc..741317d766 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -641,17 +641,17 @@ void QXcbBackingStoreImage::flushPixmap(const QRegion &region, bool fullRegion)
xcb_subimage.bit_order = m_xcb_image->bit_order;
const bool needsByteSwap = xcb_subimage.byte_order != m_xcb_image->byte_order;
+ // Ensure that we don't send more than maxPutImageRequestDataBytes per request.
+ const auto maxPutImageRequestDataBytes = connection()->maxRequestDataBytes(sizeof(xcb_put_image_request_t));
for (const QRect &rect : region) {
- // We must make sure that each request is not larger than max_req_size.
- // Each request takes req_size + m_xcb_image->stride * height bytes.
- static const uint32_t req_size = sizeof(xcb_put_image_request_t);
- const uint32_t max_req_size = xcb_get_maximum_request_length(xcb_connection());
- const int rows_per_put = (max_req_size - req_size) / m_xcb_image->stride;
+ const quint32 stride = round_up_scanline(rect.width() * m_qimage.depth(), xcb_subimage.scanline_pad) >> 3;
+ const int rows_per_put = maxPutImageRequestDataBytes / stride;
// This assert could trigger if a single row has more pixels than fit in
- // a single PutImage request. However, max_req_size is guaranteed to be
- // at least 16384 bytes. That should be enough for quite large images.
+ // a single PutImage request. In the absence of the BIG-REQUESTS extension
+ // the theoretical maximum lengths of maxPutImageRequestDataBytes can be
+ // roughly 256kB.
Q_ASSERT(rows_per_put > 0);
// If we upload the whole image in a single chunk, the result might be
@@ -666,9 +666,10 @@ void QXcbBackingStoreImage::flushPixmap(const QRegion &region, bool fullRegion)
while (height > 0) {
const int rows = std::min(height, rows_per_put);
const QRect subRect(x, y, width, rows);
- const quint32 stride = round_up_scanline(width * m_qimage.depth(), xcb_subimage.scanline_pad) >> 3;
const QImage subImage = native_sub_image(&m_flushBuffer, stride, m_qimage, subRect, needsByteSwap);
+ Q_ASSERT(static_cast<size_t>(subImage.sizeInBytes()) <= maxPutImageRequestDataBytes);
+
xcb_subimage.width = width;
xcb_subimage.height = rows;
xcb_subimage.data = const_cast<uint8_t *>(subImage.constBits());
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index ac8b029916..2cb6720d40 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -240,8 +240,8 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c)
xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD), mask);
}
- // change property protocol request is 24 bytes
- m_increment = (xcb_get_maximum_request_length(xcb_connection()) * 4) - 24;
+ // xcb_change_property_request_t and xcb_get_property_request_t are the same size
+ m_maxPropertyRequestDataBytes = connection()->maxRequestDataBytes(sizeof(xcb_change_property_request_t));
}
QXcbClipboard::~QXcbClipboard()
@@ -486,7 +486,7 @@ xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_win
if (m_clipboard_closing)
allow_incr = false;
- if (data.size() > m_increment && allow_incr) {
+ if (data.size() > m_maxPropertyRequestDataBytes && allow_incr) {
long bytes = data.size();
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property,
atom(QXcbAtom::INCR), 32, 1, (const void *)&bytes);
@@ -496,7 +496,7 @@ xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_win
}
// make sure we can perform the XChangeProperty in a single request
- if (data.size() > m_increment)
+ if (data.size() > m_maxPropertyRequestDataBytes)
return XCB_NONE; // ### perhaps use several XChangeProperty calls w/ PropModeAppend?
int dataSize = data.size() / (dataFormat / 8);
// use a single request to transfer data
@@ -678,17 +678,8 @@ void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_eve
emitChanged(mode);
}
-
-static inline int maxSelectionIncr(xcb_connection_t *c)
-{
- int l = xcb_get_maximum_request_length(c);
- return (l > 65536 ? 65536*4 : l*4) - 100;
-}
-
bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, bool deleteProperty, QByteArray *buffer, int *size, xcb_atom_t *type, int *format)
{
- int maxsize = maxSelectionIncr(xcb_connection());
- ulong bytes_left; // bytes_after
xcb_atom_t dummy_type;
int dummy_format;
@@ -705,7 +696,8 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property,
}
*type = reply->type;
*format = reply->format;
- bytes_left = reply->bytes_after;
+
+ auto bytes_left = reply->bytes_after;
int offset = 0, buffer_offset = 0;
@@ -720,7 +712,8 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property,
while (bytes_left) {
// more to read...
- reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, offset, maxsize/4);
+ reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, win, property,
+ XCB_GET_PROPERTY_TYPE_ANY, offset, m_maxPropertyRequestDataBytes / 4);
if (!reply || reply->type == XCB_NONE)
break;
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h
index 26d3b3b395..51ae0dc1ee 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.h
+++ b/src/plugins/platforms/xcb/qxcbclipboard.h
@@ -113,7 +113,7 @@ public:
xcb_window_t getSelectionOwner(xcb_atom_t atom) const;
QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t t = 0);
- int increment() const { return m_increment; }
+ int increment() const { return m_maxPropertyRequestDataBytes; }
int clipboardTimeout() const { return clipboard_timeout; }
void removeTransaction(xcb_window_t window) { m_transactions.remove(window); }
@@ -137,7 +137,7 @@ private:
static const int clipboard_timeout;
- int m_increment = 0;
+ int m_maxPropertyRequestDataBytes = 0;
bool m_clipboard_closing = false;
xcb_timestamp_t m_incr_receive_time = 0;
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 0d71a5a552..06d1000993 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -132,6 +132,12 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
if (!m_startupId.isNull())
qunsetenv("DESKTOP_STARTUP_ID");
+ m_focusInTimer.setSingleShot(true);
+ m_focusInTimer.callOnTimeout([]() {
+ // No FocusIn events for us, proceed with FocusOut normally.
+ QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason);
+ });
+
sync();
}
@@ -731,11 +737,6 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
m_glIntegration->handleXcbEvent(event, response_type);
}
-void QXcbConnection::addPeekFunc(PeekFunc f)
-{
- m_peekFuncs.append(f);
-}
-
void QXcbConnection::setFocusWindow(QWindow *w)
{
m_focusWindow = w ? static_cast<QXcbWindow *>(w->handle()) : nullptr;
@@ -1015,15 +1016,6 @@ void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags)
if (compressEvent(event))
continue;
- auto isWaitingFor = [=](PeekFunc peekFunc) {
- // These callbacks return true if the event is what they were
- // waiting for, remove them from the list in that case.
- return peekFunc(this, event);
- };
- m_peekFuncs.erase(std::remove_if(m_peekFuncs.begin(), m_peekFuncs.end(),
- isWaitingFor),
- m_peekFuncs.end());
-
handleXcbEvent(event);
// The lock-based solution used to free the lock inside this loop,
@@ -1032,12 +1024,6 @@ void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags)
m_eventQueue->flushBufferedEvents();
}
- // Indicate with a null event that the event the callbacks are waiting for
- // is not in the queue currently.
- for (PeekFunc f : qAsConst(m_peekFuncs))
- f(this, nullptr);
- m_peekFuncs.clear();
-
xcb_flush(xcb_connection());
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 15537fede4..bbfa252881 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -43,6 +43,7 @@
#include <xcb/xcb.h>
#include <xcb/randr.h>
+#include <QtCore/QTimer>
#include <QtGui/private/qtguiglobal_p.h>
#include "qxcbexport.h"
#include <QHash>
@@ -183,9 +184,6 @@ public:
QXcbWindowEventListener *windowEventListenerFromId(xcb_window_t id);
QXcbWindow *platformWindowFromId(xcb_window_t id);
- typedef bool (*PeekFunc)(QXcbConnection *, xcb_generic_event_t *);
- void addPeekFunc(PeekFunc f);
-
inline xcb_timestamp_t time() const { return m_time; }
inline void setTime(xcb_timestamp_t t) { if (timeGreaterThan(t, m_time)) m_time = t; }
@@ -247,6 +245,8 @@ public:
void flush() { xcb_flush(xcb_connection()); }
void processXcbEvents(QEventLoop::ProcessEventsFlags flags);
+ QTimer &focusInTimer() { return m_focusInTimer; }
+
protected:
bool event(QEvent *e) override;
@@ -366,8 +366,6 @@ private:
WindowMapper m_mapper;
- QVector<PeekFunc> m_peekFuncs;
-
Qt::MouseButtons m_buttonState = 0;
Qt::MouseButton m_button = Qt::NoButton;
@@ -388,6 +386,8 @@ private:
friend class QXcbEventQueue;
QByteArray m_xdgCurrentDesktop;
+ QTimer m_focusInTimer;
+
};
#if QT_CONFIG(xcb_xinput)
#if QT_CONFIG(tabletevent)
diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
index af72285135..9a028e5a7e 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
@@ -134,6 +134,7 @@ QXcbBasicConnection::QXcbBasicConnection(const char *displayName)
m_setup = xcb_get_setup(m_xcbConnection);
m_xcbAtom.initialize(m_xcbConnection);
+ m_maximumRequestLength = xcb_get_maximum_request_length(m_xcbConnection);
xcb_extension_t *extensions[] = {
&xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id,
@@ -178,6 +179,14 @@ QXcbBasicConnection::~QXcbBasicConnection()
}
}
+size_t QXcbBasicConnection::maxRequestDataBytes(size_t requestSize) const
+{
+ if (hasBigRequest())
+ requestSize += 4; // big-request encoding adds 4 bytes
+
+ return m_maximumRequestLength * 4 - requestSize;
+}
+
xcb_atom_t QXcbBasicConnection::internAtom(const char *name)
{
if (!name || *name == 0)
@@ -199,6 +208,11 @@ QByteArray QXcbBasicConnection::atomName(xcb_atom_t atom)
return QByteArray();
}
+bool QXcbBasicConnection::hasBigRequest() const
+{
+ return m_maximumRequestLength > m_setup->maximum_request_length;
+}
+
#if QT_CONFIG(xcb_xinput)
// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
// - "pad0" became "extension"
diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.h b/src/plugins/platforms/xcb/qxcbconnection_basic.h
index 6e407a5f80..b979129cba 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_basic.h
+++ b/src/plugins/platforms/xcb/qxcbconnection_basic.h
@@ -74,6 +74,8 @@ public:
}
const xcb_setup_t *setup() const { return m_setup; }
+ size_t maxRequestDataBytes(size_t requestSize) const;
+
inline xcb_atom_t atom(QXcbAtom::Atom qatom) const { return m_xcbAtom.atom(qatom); }
QXcbAtom::Atom qatom(xcb_atom_t atom) const { return m_xcbAtom.qatom(atom); }
xcb_atom_t internAtom(const char *name);
@@ -95,6 +97,7 @@ public:
bool hasShmFd() const { return m_hasShmFd; }
bool hasXSync() const { return m_hasXSync; }
bool hasXinerama() const { return m_hasXinerama; }
+ bool hasBigRequest() const;
#if QT_CONFIG(xcb_xinput)
bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; }
@@ -153,6 +156,8 @@ private:
uint32_t m_xfixesFirstEvent = 0;
uint32_t m_xrandrFirstEvent = 0;
uint32_t m_xkbFirstEvent = 0;
+
+ uint32_t m_maximumRequestLength = 0;
};
#define Q_XCB_REPLY_CONNECTION_ARG(connection, ...) connection
diff --git a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp
index 4e631beb25..9ba71ada37 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp
@@ -210,7 +210,7 @@ void QXcbConnection::updateScreen(QXcbScreen *screen, const xcb_randr_output_cha
const int idx = m_screens.indexOf(screen);
if (idx > 0) {
qAsConst(m_screens).first()->setPrimary(false);
- m_screens.swap(0, idx);
+ m_screens.swapItemsAt(0, idx);
}
screen->virtualDesktop()->setPrimaryScreen(screen);
QWindowSystemInterface::handlePrimaryScreenChanged(screen);
@@ -262,7 +262,7 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen)
newPrimary->setPrimary(true);
const int idx = m_screens.indexOf(newPrimary);
if (idx > 0)
- m_screens.swap(0, idx);
+ m_screens.swapItemsAt(0, idx);
QWindowSystemInterface::handlePrimaryScreenChanged(newPrimary);
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 91fd612cde..e4da207b00 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -637,7 +637,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
qreal nx = -1.0, ny = -1.0;
qreal w = 0.0, h = 0.0;
bool majorAxisIsY = touchPoint.area.height() > touchPoint.area.width();
- for (const TouchDeviceData::ValuatorClassInfo vci : dev->valuatorInfo) {
+ for (const TouchDeviceData::ValuatorClassInfo &vci : qAsConst(dev->valuatorInfo)) {
double value;
if (!xi2GetValuatorValueIfSet(xiDeviceEvent, vci.number, &value))
continue;
@@ -823,7 +823,7 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab)
| XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE
| XCB_INPUT_XI_EVENT_MASK_TOUCH_END;
- for (int id : m_xiMasterPointerIds) {
+ for (int id : qAsConst(m_xiMasterPointerIds)) {
xcb_generic_error_t *error = nullptr;
auto cookie = xcb_input_xi_grab_device(xcb_connection(), w, XCB_CURRENT_TIME, XCB_CURSOR_NONE, id,
XCB_INPUT_GRAB_MODE_22_ASYNC, XCB_INPUT_GRAB_MODE_22_ASYNC,
@@ -841,7 +841,7 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab)
free(reply);
}
} else { // ungrab
- for (int id : m_xiMasterPointerIds) {
+ for (int id : qAsConst(m_xiMasterPointerIds)) {
auto cookie = xcb_input_xi_ungrab_device_checked(xcb_connection(), XCB_CURRENT_TIME, id);
xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie);
if (error) {
diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp
index acec0486c2..82a36c0727 100644
--- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp
+++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp
@@ -262,7 +262,7 @@ qint32 QXcbEventQueue::generatePeekerId()
bool QXcbEventQueue::removePeekerId(qint32 peekerId)
{
- const auto it = m_peekerToNode.find(peekerId);
+ const auto it = m_peekerToNode.constFind(peekerId);
if (it == m_peekerToNode.constEnd()) {
qCWarning(lcQpaXcb, "failed to remove unknown peeker id: %d", peekerId);
return false;
@@ -281,7 +281,7 @@ bool QXcbEventQueue::peekEventQueue(PeekerCallback peeker, void *peekerData,
const bool peekerIdProvided = peekerId != -1;
auto peekerToNodeIt = m_peekerToNode.find(peekerId);
- if (peekerIdProvided && peekerToNodeIt == m_peekerToNode.constEnd()) {
+ if (peekerIdProvided && peekerToNodeIt == m_peekerToNode.end()) {
qCWarning(lcQpaXcb, "failed to find index for unknown peeker id: %d", peekerId);
return false;
}
@@ -341,7 +341,7 @@ bool QXcbEventQueue::peekEventQueue(PeekerCallback peeker, void *peekerData,
// Before updating, make sure that a peeker callback did not remove
// the peeker id.
peekerToNodeIt = m_peekerToNode.find(peekerId);
- if (peekerToNodeIt != m_peekerToNode.constEnd())
+ if (peekerToNodeIt != m_peekerToNode.end())
*peekerToNodeIt = node; // id still in the cache, update node
}
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index ed9e87a036..a70c7db923 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -357,6 +357,8 @@ void QXcbIntegration::initialize()
m_inputContext.reset(QPlatformInputContextFactory::create(icStr));
if (!m_inputContext && icStr != defaultInputContext && icStr != QLatin1String("none"))
m_inputContext.reset(QPlatformInputContextFactory::create(defaultInputContext));
+
+ defaultConnection()->keyboard()->initialize();
}
void QXcbIntegration::moveToScreen(QWindow *window, int screen)
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index c5dc7b21ad..d0e02ecdd1 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -39,7 +39,6 @@
#include "qxcbkeyboard.h"
#include "qxcbwindow.h"
#include "qxcbscreen.h"
-#include "qxcbxkbcommon.h"
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatforminputcontext.h>
@@ -49,404 +48,20 @@
#include <QtCore/QMetaEnum>
#include <private/qguiapplication_p.h>
-#include <private/qmakearray_p.h>
-#include <xkbcommon/xkbcommon-keysyms.h>
+#if QT_CONFIG(xkb)
+#include <xkbcommon/xkbcommon-x11.h>
+#endif
#if QT_CONFIG(xcb_xinput)
#include <xcb/xinput.h>
#endif
-QT_BEGIN_NAMESPACE
-
-typedef struct xkb2qt
-{
- unsigned int xkb;
- unsigned int qt;
-
- constexpr bool operator <=(const xkb2qt &that) const noexcept
- {
- return xkb <= that.xkb;
- }
-
- constexpr bool operator <(const xkb2qt &that) const noexcept
- {
- return xkb < that.xkb;
- }
-} xkb2qt_t;
-template<std::size_t Xkb, std::size_t Qt>
-struct Xkb2Qt
-{
- using Type = xkb2qt_t;
- static constexpr Type data() noexcept { return Type{Xkb, Qt}; }
-};
-
-static constexpr const auto KeyTbl = qMakeArray(
- QSortedData<
- // misc keys
-
- Xkb2Qt<XKB_KEY_Escape, Qt::Key_Escape>,
- Xkb2Qt<XKB_KEY_Tab, Qt::Key_Tab>,
- Xkb2Qt<XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab>,
- Xkb2Qt<XKB_KEY_BackSpace, Qt::Key_Backspace>,
- Xkb2Qt<XKB_KEY_Return, Qt::Key_Return>,
- Xkb2Qt<XKB_KEY_Insert, Qt::Key_Insert>,
- Xkb2Qt<XKB_KEY_Delete, Qt::Key_Delete>,
- Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
- Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
- Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
- Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
- Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
-
- // cursor movement
-
- Xkb2Qt<XKB_KEY_Home, Qt::Key_Home>,
- Xkb2Qt<XKB_KEY_End, Qt::Key_End>,
- Xkb2Qt<XKB_KEY_Left, Qt::Key_Left>,
- Xkb2Qt<XKB_KEY_Up, Qt::Key_Up>,
- Xkb2Qt<XKB_KEY_Right, Qt::Key_Right>,
- Xkb2Qt<XKB_KEY_Down, Qt::Key_Down>,
- Xkb2Qt<XKB_KEY_Prior, Qt::Key_PageUp>,
- Xkb2Qt<XKB_KEY_Next, Qt::Key_PageDown>,
-
- // modifiers
-
- Xkb2Qt<XKB_KEY_Shift_L, Qt::Key_Shift>,
- Xkb2Qt<XKB_KEY_Shift_R, Qt::Key_Shift>,
- Xkb2Qt<XKB_KEY_Shift_Lock, Qt::Key_Shift>,
- Xkb2Qt<XKB_KEY_Control_L, Qt::Key_Control>,
- Xkb2Qt<XKB_KEY_Control_R, Qt::Key_Control>,
- Xkb2Qt<XKB_KEY_Meta_L, Qt::Key_Meta>,
- Xkb2Qt<XKB_KEY_Meta_R, Qt::Key_Meta>,
- Xkb2Qt<XKB_KEY_Alt_L, Qt::Key_Alt>,
- Xkb2Qt<XKB_KEY_Alt_R, Qt::Key_Alt>,
- Xkb2Qt<XKB_KEY_Caps_Lock, Qt::Key_CapsLock>,
- Xkb2Qt<XKB_KEY_Num_Lock, Qt::Key_NumLock>,
- Xkb2Qt<XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock>,
- Xkb2Qt<XKB_KEY_Super_L, Qt::Key_Super_L>,
- Xkb2Qt<XKB_KEY_Super_R, Qt::Key_Super_R>,
- Xkb2Qt<XKB_KEY_Menu, Qt::Key_Menu>,
- Xkb2Qt<XKB_KEY_Hyper_L, Qt::Key_Hyper_L>,
- Xkb2Qt<XKB_KEY_Hyper_R, Qt::Key_Hyper_R>,
- Xkb2Qt<XKB_KEY_Help, Qt::Key_Help>,
- Xkb2Qt<0x1000FF74, Qt::Key_Backtab>, // hardcoded HP backtab
- Xkb2Qt<0x1005FF10, Qt::Key_F11>, // hardcoded Sun F36 (labeled F11)
- Xkb2Qt<0x1005FF11, Qt::Key_F12>, // hardcoded Sun F37 (labeled F12)
-
- // numeric and function keypad keys
-
- Xkb2Qt<XKB_KEY_KP_Space, Qt::Key_Space>,
- Xkb2Qt<XKB_KEY_KP_Tab, Qt::Key_Tab>,
- Xkb2Qt<XKB_KEY_KP_Enter, Qt::Key_Enter>,
- //Xkb2Qt<XKB_KEY_KP_F1, Qt::Key_F1>,
- //Xkb2Qt<XKB_KEY_KP_F2, Qt::Key_F2>,
- //Xkb2Qt<XKB_KEY_KP_F3, Qt::Key_F3>,
- //Xkb2Qt<XKB_KEY_KP_F4, Qt::Key_F4>,
- Xkb2Qt<XKB_KEY_KP_Home, Qt::Key_Home>,
- Xkb2Qt<XKB_KEY_KP_Left, Qt::Key_Left>,
- Xkb2Qt<XKB_KEY_KP_Up, Qt::Key_Up>,
- Xkb2Qt<XKB_KEY_KP_Right, Qt::Key_Right>,
- Xkb2Qt<XKB_KEY_KP_Down, Qt::Key_Down>,
- Xkb2Qt<XKB_KEY_KP_Prior, Qt::Key_PageUp>,
- Xkb2Qt<XKB_KEY_KP_Next, Qt::Key_PageDown>,
- Xkb2Qt<XKB_KEY_KP_End, Qt::Key_End>,
- Xkb2Qt<XKB_KEY_KP_Begin, Qt::Key_Clear>,
- Xkb2Qt<XKB_KEY_KP_Insert, Qt::Key_Insert>,
- Xkb2Qt<XKB_KEY_KP_Delete, Qt::Key_Delete>,
- Xkb2Qt<XKB_KEY_KP_Equal, Qt::Key_Equal>,
- Xkb2Qt<XKB_KEY_KP_Multiply, Qt::Key_Asterisk>,
- Xkb2Qt<XKB_KEY_KP_Add, Qt::Key_Plus>,
- Xkb2Qt<XKB_KEY_KP_Separator, Qt::Key_Comma>,
- Xkb2Qt<XKB_KEY_KP_Subtract, Qt::Key_Minus>,
- Xkb2Qt<XKB_KEY_KP_Decimal, Qt::Key_Period>,
- Xkb2Qt<XKB_KEY_KP_Divide, Qt::Key_Slash>,
-
- // special non-XF86 function keys
-
- Xkb2Qt<XKB_KEY_Undo, Qt::Key_Undo>,
- Xkb2Qt<XKB_KEY_Redo, Qt::Key_Redo>,
- Xkb2Qt<XKB_KEY_Find, Qt::Key_Find>,
- Xkb2Qt<XKB_KEY_Cancel, Qt::Key_Cancel>,
-
- // International input method support keys
-
- // International & multi-key character composition
- Xkb2Qt<XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr>,
- Xkb2Qt<XKB_KEY_Multi_key, Qt::Key_Multi_key>,
- Xkb2Qt<XKB_KEY_Codeinput, Qt::Key_Codeinput>,
- Xkb2Qt<XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate>,
- Xkb2Qt<XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate>,
- Xkb2Qt<XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate>,
-
- // Misc Functions
- Xkb2Qt<XKB_KEY_Mode_switch, Qt::Key_Mode_switch>,
- Xkb2Qt<XKB_KEY_script_switch, Qt::Key_Mode_switch>,
-
- // Japanese keyboard support
- Xkb2Qt<XKB_KEY_Kanji, Qt::Key_Kanji>,
- Xkb2Qt<XKB_KEY_Muhenkan, Qt::Key_Muhenkan>,
- //Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan_Mode>,
- Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan>,
- Xkb2Qt<XKB_KEY_Henkan, Qt::Key_Henkan>,
- Xkb2Qt<XKB_KEY_Romaji, Qt::Key_Romaji>,
- Xkb2Qt<XKB_KEY_Hiragana, Qt::Key_Hiragana>,
- Xkb2Qt<XKB_KEY_Katakana, Qt::Key_Katakana>,
- Xkb2Qt<XKB_KEY_Hiragana_Katakana, Qt::Key_Hiragana_Katakana>,
- Xkb2Qt<XKB_KEY_Zenkaku, Qt::Key_Zenkaku>,
- Xkb2Qt<XKB_KEY_Hankaku, Qt::Key_Hankaku>,
- Xkb2Qt<XKB_KEY_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku>,
- Xkb2Qt<XKB_KEY_Touroku, Qt::Key_Touroku>,
- Xkb2Qt<XKB_KEY_Massyo, Qt::Key_Massyo>,
- Xkb2Qt<XKB_KEY_Kana_Lock, Qt::Key_Kana_Lock>,
- Xkb2Qt<XKB_KEY_Kana_Shift, Qt::Key_Kana_Shift>,
- Xkb2Qt<XKB_KEY_Eisu_Shift, Qt::Key_Eisu_Shift>,
- Xkb2Qt<XKB_KEY_Eisu_toggle, Qt::Key_Eisu_toggle>,
- //Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Kanji_Bangou>,
- //Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_Zen_Koho>,
- //Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_Mae_Koho>,
- Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Codeinput>,
- Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_MultipleCandidate>,
- Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_PreviousCandidate>,
-
- // Korean keyboard support
- Xkb2Qt<XKB_KEY_Hangul, Qt::Key_Hangul>,
- Xkb2Qt<XKB_KEY_Hangul_Start, Qt::Key_Hangul_Start>,
- Xkb2Qt<XKB_KEY_Hangul_End, Qt::Key_Hangul_End>,
- Xkb2Qt<XKB_KEY_Hangul_Hanja, Qt::Key_Hangul_Hanja>,
- Xkb2Qt<XKB_KEY_Hangul_Jamo, Qt::Key_Hangul_Jamo>,
- Xkb2Qt<XKB_KEY_Hangul_Romaja, Qt::Key_Hangul_Romaja>,
- //Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Hangul_Codeinput>,
- Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Codeinput>,
- Xkb2Qt<XKB_KEY_Hangul_Jeonja, Qt::Key_Hangul_Jeonja>,
- Xkb2Qt<XKB_KEY_Hangul_Banja, Qt::Key_Hangul_Banja>,
- Xkb2Qt<XKB_KEY_Hangul_PreHanja, Qt::Key_Hangul_PreHanja>,
- Xkb2Qt<XKB_KEY_Hangul_PostHanja, Qt::Key_Hangul_PostHanja>,
- //Xkb2Qt<XKB_KEY_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate>,
- //Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate>,
- //Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate>,
- Xkb2Qt<XKB_KEY_Hangul_SingleCandidate, Qt::Key_SingleCandidate>,
- Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate>,
- Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate>,
- Xkb2Qt<XKB_KEY_Hangul_Special, Qt::Key_Hangul_Special>,
- //Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Hangul_switch>,
- Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Mode_switch>,
-
- // dead keys
- Xkb2Qt<XKB_KEY_dead_grave, Qt::Key_Dead_Grave>,
- Xkb2Qt<XKB_KEY_dead_acute, Qt::Key_Dead_Acute>,
- Xkb2Qt<XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex>,
- Xkb2Qt<XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde>,
- Xkb2Qt<XKB_KEY_dead_macron, Qt::Key_Dead_Macron>,
- Xkb2Qt<XKB_KEY_dead_breve, Qt::Key_Dead_Breve>,
- Xkb2Qt<XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot>,
- Xkb2Qt<XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis>,
- Xkb2Qt<XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering>,
- Xkb2Qt<XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute>,
- Xkb2Qt<XKB_KEY_dead_caron, Qt::Key_Dead_Caron>,
- Xkb2Qt<XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla>,
- Xkb2Qt<XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek>,
- Xkb2Qt<XKB_KEY_dead_iota, Qt::Key_Dead_Iota>,
- Xkb2Qt<XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound>,
- Xkb2Qt<XKB_KEY_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound>,
- Xkb2Qt<XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot>,
- Xkb2Qt<XKB_KEY_dead_hook, Qt::Key_Dead_Hook>,
- Xkb2Qt<XKB_KEY_dead_horn, Qt::Key_Dead_Horn>,
- Xkb2Qt<XKB_KEY_dead_stroke, Qt::Key_Dead_Stroke>,
- Xkb2Qt<XKB_KEY_dead_abovecomma, Qt::Key_Dead_Abovecomma>,
- Xkb2Qt<XKB_KEY_dead_abovereversedcomma, Qt::Key_Dead_Abovereversedcomma>,
- Xkb2Qt<XKB_KEY_dead_doublegrave, Qt::Key_Dead_Doublegrave>,
- Xkb2Qt<XKB_KEY_dead_belowring, Qt::Key_Dead_Belowring>,
- Xkb2Qt<XKB_KEY_dead_belowmacron, Qt::Key_Dead_Belowmacron>,
- Xkb2Qt<XKB_KEY_dead_belowcircumflex, Qt::Key_Dead_Belowcircumflex>,
- Xkb2Qt<XKB_KEY_dead_belowtilde, Qt::Key_Dead_Belowtilde>,
- Xkb2Qt<XKB_KEY_dead_belowbreve, Qt::Key_Dead_Belowbreve>,
- Xkb2Qt<XKB_KEY_dead_belowdiaeresis, Qt::Key_Dead_Belowdiaeresis>,
- Xkb2Qt<XKB_KEY_dead_invertedbreve, Qt::Key_Dead_Invertedbreve>,
- Xkb2Qt<XKB_KEY_dead_belowcomma, Qt::Key_Dead_Belowcomma>,
- Xkb2Qt<XKB_KEY_dead_currency, Qt::Key_Dead_Currency>,
- Xkb2Qt<XKB_KEY_dead_a, Qt::Key_Dead_a>,
- Xkb2Qt<XKB_KEY_dead_A, Qt::Key_Dead_A>,
- Xkb2Qt<XKB_KEY_dead_e, Qt::Key_Dead_e>,
- Xkb2Qt<XKB_KEY_dead_E, Qt::Key_Dead_E>,
- Xkb2Qt<XKB_KEY_dead_i, Qt::Key_Dead_i>,
- Xkb2Qt<XKB_KEY_dead_I, Qt::Key_Dead_I>,
- Xkb2Qt<XKB_KEY_dead_o, Qt::Key_Dead_o>,
- Xkb2Qt<XKB_KEY_dead_O, Qt::Key_Dead_O>,
- Xkb2Qt<XKB_KEY_dead_u, Qt::Key_Dead_u>,
- Xkb2Qt<XKB_KEY_dead_U, Qt::Key_Dead_U>,
- Xkb2Qt<XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa>,
- Xkb2Qt<XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa>,
- Xkb2Qt<XKB_KEY_dead_greek, Qt::Key_Dead_Greek>,
- Xkb2Qt<XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline>,
- Xkb2Qt<XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline>,
- Xkb2Qt<XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline>,
- Xkb2Qt<XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay>,
-
- // Special keys from X.org - This include multimedia keys,
- // wireless/bluetooth/uwb keys, special launcher keys, etc.
- Xkb2Qt<XKB_KEY_XF86Back, Qt::Key_Back>,
- Xkb2Qt<XKB_KEY_XF86Forward, Qt::Key_Forward>,
- Xkb2Qt<XKB_KEY_XF86Stop, Qt::Key_Stop>,
- Xkb2Qt<XKB_KEY_XF86Refresh, Qt::Key_Refresh>,
- Xkb2Qt<XKB_KEY_XF86Favorites, Qt::Key_Favorites>,
- Xkb2Qt<XKB_KEY_XF86AudioMedia, Qt::Key_LaunchMedia>,
- Xkb2Qt<XKB_KEY_XF86OpenURL, Qt::Key_OpenUrl>,
- Xkb2Qt<XKB_KEY_XF86HomePage, Qt::Key_HomePage>,
- Xkb2Qt<XKB_KEY_XF86Search, Qt::Key_Search>,
- Xkb2Qt<XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown>,
- Xkb2Qt<XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute>,
- Xkb2Qt<XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp>,
- Xkb2Qt<XKB_KEY_XF86AudioPlay, Qt::Key_MediaPlay>,
- Xkb2Qt<XKB_KEY_XF86AudioStop, Qt::Key_MediaStop>,
- Xkb2Qt<XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious>,
- Xkb2Qt<XKB_KEY_XF86AudioNext, Qt::Key_MediaNext>,
- Xkb2Qt<XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord>,
- Xkb2Qt<XKB_KEY_XF86AudioPause, Qt::Key_MediaPause>,
- Xkb2Qt<XKB_KEY_XF86Mail, Qt::Key_LaunchMail>,
- Xkb2Qt<XKB_KEY_XF86MyComputer, Qt::Key_Launch0>, // ### Qt 6: remap properly
- Xkb2Qt<XKB_KEY_XF86Calculator, Qt::Key_Launch1>,
- Xkb2Qt<XKB_KEY_XF86Memo, Qt::Key_Memo>,
- Xkb2Qt<XKB_KEY_XF86ToDoList, Qt::Key_ToDoList>,
- Xkb2Qt<XKB_KEY_XF86Calendar, Qt::Key_Calendar>,
- Xkb2Qt<XKB_KEY_XF86PowerDown, Qt::Key_PowerDown>,
- Xkb2Qt<XKB_KEY_XF86ContrastAdjust, Qt::Key_ContrastAdjust>,
- Xkb2Qt<XKB_KEY_XF86Standby, Qt::Key_Standby>,
- Xkb2Qt<XKB_KEY_XF86MonBrightnessUp, Qt::Key_MonBrightnessUp>,
- Xkb2Qt<XKB_KEY_XF86MonBrightnessDown, Qt::Key_MonBrightnessDown>,
- Xkb2Qt<XKB_KEY_XF86KbdLightOnOff, Qt::Key_KeyboardLightOnOff>,
- Xkb2Qt<XKB_KEY_XF86KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp>,
- Xkb2Qt<XKB_KEY_XF86KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown>,
- Xkb2Qt<XKB_KEY_XF86PowerOff, Qt::Key_PowerOff>,
- Xkb2Qt<XKB_KEY_XF86WakeUp, Qt::Key_WakeUp>,
- Xkb2Qt<XKB_KEY_XF86Eject, Qt::Key_Eject>,
- Xkb2Qt<XKB_KEY_XF86ScreenSaver, Qt::Key_ScreenSaver>,
- Xkb2Qt<XKB_KEY_XF86WWW, Qt::Key_WWW>,
- Xkb2Qt<XKB_KEY_XF86Sleep, Qt::Key_Sleep>,
- Xkb2Qt<XKB_KEY_XF86LightBulb, Qt::Key_LightBulb>,
- Xkb2Qt<XKB_KEY_XF86Shop, Qt::Key_Shop>,
- Xkb2Qt<XKB_KEY_XF86History, Qt::Key_History>,
- Xkb2Qt<XKB_KEY_XF86AddFavorite, Qt::Key_AddFavorite>,
- Xkb2Qt<XKB_KEY_XF86HotLinks, Qt::Key_HotLinks>,
- Xkb2Qt<XKB_KEY_XF86BrightnessAdjust, Qt::Key_BrightnessAdjust>,
- Xkb2Qt<XKB_KEY_XF86Finance, Qt::Key_Finance>,
- Xkb2Qt<XKB_KEY_XF86Community, Qt::Key_Community>,
- Xkb2Qt<XKB_KEY_XF86AudioRewind, Qt::Key_AudioRewind>,
- Xkb2Qt<XKB_KEY_XF86BackForward, Qt::Key_BackForward>,
- Xkb2Qt<XKB_KEY_XF86ApplicationLeft, Qt::Key_ApplicationLeft>,
- Xkb2Qt<XKB_KEY_XF86ApplicationRight, Qt::Key_ApplicationRight>,
- Xkb2Qt<XKB_KEY_XF86Book, Qt::Key_Book>,
- Xkb2Qt<XKB_KEY_XF86CD, Qt::Key_CD>,
- Xkb2Qt<XKB_KEY_XF86Calculater, Qt::Key_Calculator>,
- Xkb2Qt<XKB_KEY_XF86Clear, Qt::Key_Clear>,
- Xkb2Qt<XKB_KEY_XF86ClearGrab, Qt::Key_ClearGrab>,
- Xkb2Qt<XKB_KEY_XF86Close, Qt::Key_Close>,
- Xkb2Qt<XKB_KEY_XF86Copy, Qt::Key_Copy>,
- Xkb2Qt<XKB_KEY_XF86Cut, Qt::Key_Cut>,
- Xkb2Qt<XKB_KEY_XF86Display, Qt::Key_Display>,
- Xkb2Qt<XKB_KEY_XF86DOS, Qt::Key_DOS>,
- Xkb2Qt<XKB_KEY_XF86Documents, Qt::Key_Documents>,
- Xkb2Qt<XKB_KEY_XF86Excel, Qt::Key_Excel>,
- Xkb2Qt<XKB_KEY_XF86Explorer, Qt::Key_Explorer>,
- Xkb2Qt<XKB_KEY_XF86Game, Qt::Key_Game>,
- Xkb2Qt<XKB_KEY_XF86Go, Qt::Key_Go>,
- Xkb2Qt<XKB_KEY_XF86iTouch, Qt::Key_iTouch>,
- Xkb2Qt<XKB_KEY_XF86LogOff, Qt::Key_LogOff>,
- Xkb2Qt<XKB_KEY_XF86Market, Qt::Key_Market>,
- Xkb2Qt<XKB_KEY_XF86Meeting, Qt::Key_Meeting>,
- Xkb2Qt<XKB_KEY_XF86MenuKB, Qt::Key_MenuKB>,
- Xkb2Qt<XKB_KEY_XF86MenuPB, Qt::Key_MenuPB>,
- Xkb2Qt<XKB_KEY_XF86MySites, Qt::Key_MySites>,
- Xkb2Qt<XKB_KEY_XF86New, Qt::Key_New>,
- Xkb2Qt<XKB_KEY_XF86News, Qt::Key_News>,
- Xkb2Qt<XKB_KEY_XF86OfficeHome, Qt::Key_OfficeHome>,
- Xkb2Qt<XKB_KEY_XF86Open, Qt::Key_Open>,
- Xkb2Qt<XKB_KEY_XF86Option, Qt::Key_Option>,
- Xkb2Qt<XKB_KEY_XF86Paste, Qt::Key_Paste>,
- Xkb2Qt<XKB_KEY_XF86Phone, Qt::Key_Phone>,
- Xkb2Qt<XKB_KEY_XF86Reply, Qt::Key_Reply>,
- Xkb2Qt<XKB_KEY_XF86Reload, Qt::Key_Reload>,
- Xkb2Qt<XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows>,
- Xkb2Qt<XKB_KEY_XF86RotationPB, Qt::Key_RotationPB>,
- Xkb2Qt<XKB_KEY_XF86RotationKB, Qt::Key_RotationKB>,
- Xkb2Qt<XKB_KEY_XF86Save, Qt::Key_Save>,
- Xkb2Qt<XKB_KEY_XF86Send, Qt::Key_Send>,
- Xkb2Qt<XKB_KEY_XF86Spell, Qt::Key_Spell>,
- Xkb2Qt<XKB_KEY_XF86SplitScreen, Qt::Key_SplitScreen>,
- Xkb2Qt<XKB_KEY_XF86Support, Qt::Key_Support>,
- Xkb2Qt<XKB_KEY_XF86TaskPane, Qt::Key_TaskPane>,
- Xkb2Qt<XKB_KEY_XF86Terminal, Qt::Key_Terminal>,
- Xkb2Qt<XKB_KEY_XF86Tools, Qt::Key_Tools>,
- Xkb2Qt<XKB_KEY_XF86Travel, Qt::Key_Travel>,
- Xkb2Qt<XKB_KEY_XF86Video, Qt::Key_Video>,
- Xkb2Qt<XKB_KEY_XF86Word, Qt::Key_Word>,
- Xkb2Qt<XKB_KEY_XF86Xfer, Qt::Key_Xfer>,
- Xkb2Qt<XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn>,
- Xkb2Qt<XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut>,
- Xkb2Qt<XKB_KEY_XF86Away, Qt::Key_Away>,
- Xkb2Qt<XKB_KEY_XF86Messenger, Qt::Key_Messenger>,
- Xkb2Qt<XKB_KEY_XF86WebCam, Qt::Key_WebCam>,
- Xkb2Qt<XKB_KEY_XF86MailForward, Qt::Key_MailForward>,
- Xkb2Qt<XKB_KEY_XF86Pictures, Qt::Key_Pictures>,
- Xkb2Qt<XKB_KEY_XF86Music, Qt::Key_Music>,
- Xkb2Qt<XKB_KEY_XF86Battery, Qt::Key_Battery>,
- Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
- Xkb2Qt<XKB_KEY_XF86WLAN, Qt::Key_WLAN>,
- Xkb2Qt<XKB_KEY_XF86UWB, Qt::Key_UWB>,
- Xkb2Qt<XKB_KEY_XF86AudioForward, Qt::Key_AudioForward>,
- Xkb2Qt<XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat>,
- Xkb2Qt<XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay>,
- Xkb2Qt<XKB_KEY_XF86Subtitle, Qt::Key_Subtitle>,
- Xkb2Qt<XKB_KEY_XF86AudioCycleTrack, Qt::Key_AudioCycleTrack>,
- Xkb2Qt<XKB_KEY_XF86Time, Qt::Key_Time>,
- Xkb2Qt<XKB_KEY_XF86Select, Qt::Key_Select>,
- Xkb2Qt<XKB_KEY_XF86View, Qt::Key_View>,
- Xkb2Qt<XKB_KEY_XF86TopMenu, Qt::Key_TopMenu>,
- Xkb2Qt<XKB_KEY_XF86Red, Qt::Key_Red>,
- Xkb2Qt<XKB_KEY_XF86Green, Qt::Key_Green>,
- Xkb2Qt<XKB_KEY_XF86Yellow, Qt::Key_Yellow>,
- Xkb2Qt<XKB_KEY_XF86Blue, Qt::Key_Blue>,
- Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
- Xkb2Qt<XKB_KEY_XF86Suspend, Qt::Key_Suspend>,
- Xkb2Qt<XKB_KEY_XF86Hibernate, Qt::Key_Hibernate>,
- Xkb2Qt<XKB_KEY_XF86TouchpadToggle, Qt::Key_TouchpadToggle>,
- Xkb2Qt<XKB_KEY_XF86TouchpadOn, Qt::Key_TouchpadOn>,
- Xkb2Qt<XKB_KEY_XF86TouchpadOff, Qt::Key_TouchpadOff>,
- Xkb2Qt<XKB_KEY_XF86AudioMicMute, Qt::Key_MicMute>,
- Xkb2Qt<XKB_KEY_XF86Launch0, Qt::Key_Launch2>, // ### Qt 6: remap properly
- Xkb2Qt<XKB_KEY_XF86Launch1, Qt::Key_Launch3>,
- Xkb2Qt<XKB_KEY_XF86Launch2, Qt::Key_Launch4>,
- Xkb2Qt<XKB_KEY_XF86Launch3, Qt::Key_Launch5>,
- Xkb2Qt<XKB_KEY_XF86Launch4, Qt::Key_Launch6>,
- Xkb2Qt<XKB_KEY_XF86Launch5, Qt::Key_Launch7>,
- Xkb2Qt<XKB_KEY_XF86Launch6, Qt::Key_Launch8>,
- Xkb2Qt<XKB_KEY_XF86Launch7, Qt::Key_Launch9>,
- Xkb2Qt<XKB_KEY_XF86Launch8, Qt::Key_LaunchA>,
- Xkb2Qt<XKB_KEY_XF86Launch9, Qt::Key_LaunchB>,
- Xkb2Qt<XKB_KEY_XF86LaunchA, Qt::Key_LaunchC>,
- Xkb2Qt<XKB_KEY_XF86LaunchB, Qt::Key_LaunchD>,
- Xkb2Qt<XKB_KEY_XF86LaunchC, Qt::Key_LaunchE>,
- Xkb2Qt<XKB_KEY_XF86LaunchD, Qt::Key_LaunchF>,
- Xkb2Qt<XKB_KEY_XF86LaunchE, Qt::Key_LaunchG>,
- Xkb2Qt<XKB_KEY_XF86LaunchF, Qt::Key_LaunchH>
- >::Data{}
-);
-
-// Possible modifier states.
-static const Qt::KeyboardModifiers ModsTbl[] = {
- Qt::NoModifier, // 0
- Qt::ShiftModifier, // 1
- Qt::ControlModifier, // 2
- Qt::ControlModifier | Qt::ShiftModifier, // 3
- Qt::AltModifier, // 4
- Qt::AltModifier | Qt::ShiftModifier, // 5
- Qt::AltModifier | Qt::ControlModifier, // 6
- Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7
- Qt::NoModifier // Fall-back to raw Key_*, for non-latin1 kb layouts
-};
+QT_BEGIN_NAMESPACE
Qt::KeyboardModifiers QXcbKeyboard::translateModifiers(int s) const
{
- Qt::KeyboardModifiers ret = 0;
+ Qt::KeyboardModifiers ret = Qt::NoModifier;
if (s & XCB_MOD_MASK_SHIFT)
ret |= Qt::ShiftModifier;
if (s & XCB_MOD_MASK_CONTROL)
@@ -473,7 +88,7 @@ static xcb_keysym_t getUnshiftedXKey(xcb_keysym_t unshifted, xcb_keysym_t shifte
xcb_keysym_t xlower;
xcb_keysym_t xupper;
- xkbcommon_XConvertCase(unshifted, &xlower, &xupper);
+ QXkbCommon::xkbcommon_XConvertCase(unshifted, &xlower, &xupper);
if (xlower != xupper // Check if symbol is cased
&& unshifted == xupper) { // Unshifted must be upper case
@@ -805,7 +420,12 @@ void QXcbKeyboard::updateKeymap()
updateXKBMods();
- checkForLatinLayout();
+ QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get());
+}
+
+QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
+{
+ return QXkbCommon::possibleKeys(m_xkbState.get(), event, m_superAsMeta, m_hyperAsMeta);
}
#if QT_CONFIG(xkb)
@@ -918,272 +538,6 @@ void QXcbKeyboard::updateXKBMods()
xkb_mods.mod5 = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Mod5");
}
-static bool isLatin(xkb_keysym_t sym)
-{
- return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
-}
-
-void QXcbKeyboard::checkForLatinLayout() const
-{
- const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts(m_xkbKeymap.get());
- const xcb_keycode_t minKeycode = xkb_keymap_min_keycode(m_xkbKeymap.get());
- const xcb_keycode_t maxKeycode = xkb_keymap_max_keycode(m_xkbKeymap.get());
-
- const xkb_keysym_t *keysyms = nullptr;
- int nrLatinKeys = 0;
- for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
- for (xcb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
- xkb_keymap_key_get_syms_by_level(m_xkbKeymap.get(), code, layout, 0, &keysyms);
- if (keysyms && isLatin(keysyms[0]))
- nrLatinKeys++;
- if (nrLatinKeys > 10) // arbitrarily chosen threshold
- return;
- }
- }
- // This means that lookupLatinKeysym() will not find anything and latin
- // key shortcuts might not work. This is a bug in the affected desktop
- // environment. Usually can be solved via system settings by adding e.g. 'us'
- // layout to the list of seleced layouts, or by using command line, "setxkbmap
- // -layout rus,en". The position of latin key based layout in the list of the
- // selected layouts is irrelevant. Properly functioning desktop environments
- // handle this behind the scenes, even if no latin key based layout has been
- // explicitly listed in the selected layouts.
- qCWarning(lcQpaKeyboard, "no keyboard layouts with latin keys present");
-}
-
-xkb_keysym_t QXcbKeyboard::lookupLatinKeysym(xkb_keycode_t keycode) const
-{
- xkb_layout_index_t layout;
- xkb_keysym_t sym = XKB_KEY_NoSymbol;
- const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts_for_key(m_xkbKeymap.get(), keycode);
- const xkb_layout_index_t currentLayout = xkb_state_key_get_layout(m_xkbState.get(), keycode);
- // Look at user layouts in the order in which they are defined in system
- // settings to find a latin keysym.
- for (layout = 0; layout < layoutCount; ++layout) {
- if (layout == currentLayout)
- continue;
- const xkb_keysym_t *syms;
- xkb_level_index_t level = xkb_state_key_get_level(m_xkbState.get(), keycode, layout);
- if (xkb_keymap_key_get_syms_by_level(m_xkbKeymap.get(), keycode, layout, level, &syms) != 1)
- continue;
- if (isLatin(syms[0])) {
- sym = syms[0];
- break;
- }
- }
-
- if (sym == XKB_KEY_NoSymbol)
- return sym;
-
- xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LATCHED);
- xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LOCKED);
-
- // Check for uniqueness, consider the following setup:
- // setxkbmap -layout us,ru,us -variant dvorak,, -option 'grp:ctrl_alt_toggle' (set 'ru' as active).
- // In this setup, the user would expect to trigger a ctrl+q shortcut by pressing ctrl+<physical x key>,
- // because "US dvorak" is higher up in the layout settings list. This check verifies that an obtained
- // 'sym' can not be acquired by any other layout higher up in the user's layout list. If it can be acquired
- // then the obtained key is not unique. This prevents ctrl+<physical q key> from generating a ctrl+q
- // shortcut in the above described setup. We don't want ctrl+<physical x key> and ctrl+<physical q key> to
- // generate the same shortcut event in this case.
- const xcb_keycode_t minKeycode = xkb_keymap_min_keycode(m_xkbKeymap.get());
- const xcb_keycode_t maxKeycode = xkb_keymap_max_keycode(m_xkbKeymap.get());
- ScopedXKBState state(xkb_state_new(m_xkbKeymap.get()));
- for (xkb_layout_index_t prevLayout = 0; prevLayout < layout; ++prevLayout) {
- xkb_state_update_mask(state.get(), 0, latchedMods, lockedMods, 0, 0, prevLayout);
- for (xcb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
- xkb_keysym_t prevSym = xkb_state_key_get_one_sym(state.get(), code);
- if (prevSym == sym) {
- sym = XKB_KEY_NoSymbol;
- break;
- }
- }
- }
-
- return sym;
-}
-
-static const char *qtKeyName(int qtKey)
-{
- int keyEnumIndex = qt_getQtMetaObject()->indexOfEnumerator("Key");
- QMetaEnum keyEnum = qt_getQtMetaObject()->enumerator(keyEnumIndex);
- return keyEnum.valueToKey(qtKey);
-}
-
-QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
-{
- // turn off the modifier bits which doesn't participate in shortcuts
- Qt::KeyboardModifiers notNeeded = Qt::KeypadModifier | Qt::GroupSwitchModifier;
- Qt::KeyboardModifiers modifiers = event->modifiers() &= ~notNeeded;
- // create a fresh kb state and test against the relevant modifier combinations
- struct xkb_state *kb_state = xkb_state_new(m_xkbKeymap.get());
- if (!kb_state) {
- qWarning("QXcbKeyboard: failed to compile xkb keymap!");
- return QList<int>();
- }
- // get kb state from the master xkb_state and update the temporary kb_state
- xkb_layout_index_t lockedLayout = xkb_state_serialize_layout(m_xkbState.get(), XKB_STATE_LAYOUT_LOCKED);
- xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LATCHED);
- xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LOCKED);
- xkb_mod_mask_t depressedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_DEPRESSED);
-
- xkb_state_update_mask(kb_state, depressedMods, latchedMods, lockedMods, 0, 0, lockedLayout);
- quint32 keycode = event->nativeScanCode();
- // handle shortcuts for level three and above
- xkb_layout_index_t layoutIndex = xkb_state_key_get_layout(kb_state, keycode);
- xkb_level_index_t levelIndex = 0;
- if (layoutIndex != XKB_LAYOUT_INVALID) {
- levelIndex = xkb_state_key_get_level(kb_state, keycode, layoutIndex);
- if (levelIndex == XKB_LEVEL_INVALID)
- levelIndex = 0;
- }
- if (levelIndex <= 1)
- xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods, 0, 0, lockedLayout);
-
- xkb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, keycode);
- if (sym == XKB_KEY_NoSymbol) {
- xkb_state_unref(kb_state);
- return QList<int>();
- }
-
- QList<int> result;
- int baseQtKey = keysymToQtKey(sym, modifiers, kb_state, keycode);
- if (baseQtKey)
- result += (baseQtKey + modifiers);
-
- xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Shift");
- xkb_mod_index_t altMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Alt");
- xkb_mod_index_t controlMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Control");
- xkb_mod_index_t metaMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Meta");
-
- Q_ASSERT(shiftMod < 32);
- Q_ASSERT(altMod < 32);
- Q_ASSERT(controlMod < 32);
-
- xkb_mod_mask_t depressed;
- int qtKey = 0;
- // obtain a list of possible shortcuts for the given key event
- for (uint i = 1; i < sizeof(ModsTbl) / sizeof(*ModsTbl) ; ++i) {
- Qt::KeyboardModifiers neededMods = ModsTbl[i];
- if ((modifiers & neededMods) == neededMods) {
- if (i == 8) {
- if (isLatin(baseQtKey))
- continue;
- // add a latin key as a fall back key
- sym = lookupLatinKeysym(keycode);
- } else {
- depressed = 0;
- if (neededMods & Qt::AltModifier)
- depressed |= (1 << altMod);
- if (neededMods & Qt::ShiftModifier)
- depressed |= (1 << shiftMod);
- if (neededMods & Qt::ControlModifier)
- depressed |= (1 << controlMod);
- if (metaMod < 32 && neededMods & Qt::MetaModifier)
- depressed |= (1 << metaMod);
- xkb_state_update_mask(kb_state, depressed, latchedMods, lockedMods, 0, 0, lockedLayout);
- sym = xkb_state_key_get_one_sym(kb_state, keycode);
- }
- if (sym == XKB_KEY_NoSymbol)
- continue;
-
- Qt::KeyboardModifiers mods = modifiers & ~neededMods;
- qtKey = keysymToQtKey(sym, mods, kb_state, keycode);
- if (!qtKey || qtKey == baseQtKey)
- continue;
-
- // catch only more specific shortcuts, i.e. Ctrl+Shift+= also generates Ctrl++ and +,
- // but Ctrl++ is more specific than +, so we should skip the last one
- bool ambiguous = false;
- for (int shortcut : qAsConst(result)) {
- if (int(shortcut & ~Qt::KeyboardModifierMask) == qtKey && (shortcut & mods) == mods) {
- ambiguous = true;
- break;
- }
- }
- if (ambiguous)
- continue;
-
- result += (qtKey + mods);
- }
- }
- xkb_state_unref(kb_state);
- return result;
-}
-
-int QXcbKeyboard::keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
- struct xkb_state *state, xcb_keycode_t code) const
-{
- int qtKey = 0;
-
- // lookup from direct mapping
- if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) {
- // function keys
- qtKey = Qt::Key_F1 + (keysym - XKB_KEY_F1);
- } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
- // numeric keypad keys
- qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
- } else if (isLatin(keysym)) {
- qtKey = xkbcommon_xkb_keysym_to_upper(keysym);
- } else {
- // check if we have a direct mapping
- xkb2qt_t searchKey{keysym, 0};
- auto it = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey);
- if (it != KeyTbl.end() && !(searchKey < *it))
- qtKey = it->qt;
- }
-
- QString text;
- bool fromUnicode = qtKey == 0;
- if (fromUnicode) { // lookup from unicode
- if (modifiers & Qt::ControlModifier) {
- // Control modifier changes the text to ASCII control character, therefore we
- // can't use this text to map keysym to a qt key. We can use the same keysym
- // (it is not affectd by transformation) to obtain untransformed text. For details
- // see "Appendix A. Default Symbol Transformations" in the XKB specification.
- text = lookupStringNoKeysymTransformations(keysym);
- } else {
- text = lookupString(state, code);
- }
- if (!text.isEmpty()) {
- if (text.unicode()->isDigit()) {
- // Ensures that also non-latin digits are mapped to corresponding qt keys,
- // e.g CTRL + ۲ (arabic two), is mapped to CTRL + Qt::Key_2.
- qtKey = Qt::Key_0 + text.unicode()->digitValue();
- } else {
- qtKey = text.unicode()->toUpper().unicode();
- }
- }
- }
-
- if (rmod_masks.meta) {
- // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
- if (rmod_masks.meta == rmod_masks.super && (qtKey == Qt::Key_Super_L
- || qtKey == Qt::Key_Super_R)) {
- qtKey = Qt::Key_Meta;
- } else if (rmod_masks.meta == rmod_masks.hyper && (qtKey == Qt::Key_Hyper_L
- || qtKey == Qt::Key_Hyper_R)) {
- qtKey = Qt::Key_Meta;
- }
- }
-
- if (Q_UNLIKELY(lcQpaKeyboard().isDebugEnabled())) {
- char keysymName[64];
- xkb_keysym_get_name(keysym, keysymName, sizeof(keysymName));
- QString keysymInHex = QString(QStringLiteral("0x%1")).arg(keysym, 0, 16);
- if (qtKeyName(qtKey)) {
- qCDebug(lcQpaKeyboard).nospace() << "keysym: " << keysymName << "("
- << keysymInHex << ") mapped to Qt::" << qtKeyName(qtKey) << " | text: " << text
- << " | qt key: " << qtKey << " mapped from unicode number: " << fromUnicode;
- } else {
- qCDebug(lcQpaKeyboard).nospace() << "no Qt::Key for keysym: " << keysymName
- << "(" << keysymInHex << ") | text: " << text << " | qt key: " << qtKey;
- }
- }
-
- return qtKey;
-}
-
QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
: QXcbObject(connection)
{
@@ -1211,6 +565,12 @@ QXcbKeyboard::~QXcbKeyboard()
xcb_key_symbols_free(m_key_symbols);
}
+void QXcbKeyboard::initialize()
+{
+ auto inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
+ QXkbCommon::setXkbContext(inputContext, m_xkbContext.get());
+}
+
void QXcbKeyboard::selectEvents()
{
#if QT_CONFIG(xkb)
@@ -1514,6 +874,12 @@ void QXcbKeyboard::resolveMaskConflicts()
rmod_masks.meta = rmod_masks.hyper;
}
}
+
+ // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
+ if (rmod_masks.meta && rmod_masks.meta == rmod_masks.super)
+ m_superAsMeta = true;
+ if (rmod_masks.meta && rmod_masks.meta == rmod_masks.hyper)
+ m_hyperAsMeta = true;
}
void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, xcb_keycode_t code,
@@ -1529,7 +895,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
if (type == QEvent::KeyPress)
targetWindow->updateNetWmUserTime(time);
- ScopedXKBState sendEventState;
+ QXkbCommon::ScopedXKBState sendEventState;
if (fromSendEvent) {
// Have a temporary keyboard state filled in from state
// this way we allow for synthetic events to have different state
@@ -1546,30 +912,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
struct xkb_state *xkbState = fromSendEvent ? sendEventState.get() : m_xkbState.get();
xcb_keysym_t sym = xkb_state_key_get_one_sym(xkbState, code);
- QString text = lookupString(xkbState, code);
+ QString text = QXkbCommon::lookupString(xkbState, code);
Qt::KeyboardModifiers modifiers = translateModifiers(state);
- if (sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9)
+ if (QXkbCommon::isKeypad(sym))
modifiers |= Qt::KeypadModifier;
- // Note 1: All standard key sequences on linux (as defined in platform theme)
- // that use a latin character also contain a control modifier, which is why
- // checking for Qt::ControlModifier is sufficient here. It is possible to
- // override QPlatformTheme::keyBindings() and provide custom sequences for
- // QKeySequence::StandardKey. Custom sequences probably should respect this
- // convention (alternatively, we could test against other modifiers here).
- // Note 2: The possibleKeys() shorcut mechanism is not affected by this value
- // adjustment and does its own thing.
- xcb_keysym_t latinKeysym = XKB_KEY_NoSymbol;
- if (modifiers & Qt::ControlModifier) {
- // With standard shortcuts we should prefer a latin character, this is
- // in checks like "event == QKeySequence::Copy".
- if (!isLatin(sym))
- latinKeysym = lookupLatinKeysym(code);
- }
-
- int qtcode = keysymToQtKey(latinKeysym != XKB_KEY_NoSymbol ? latinKeysym : sym,
- modifiers, xkbState, code);
+ int qtcode = QXkbCommon::keysymToQtKey(sym, modifiers, xkbState, code, m_superAsMeta, m_hyperAsMeta);
if (type == QEvent::KeyPress) {
if (m_isAutoRepeat && m_autoRepeatCode != code)
@@ -1611,28 +960,6 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
}
}
-QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const
-{
- QVarLengthArray<char, 32> chars(32);
- const int size = xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
- if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL
- chars.resize(size + 1);
- xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
- }
- return QString::fromUtf8(chars.constData(), size);
-}
-
-QString QXcbKeyboard::lookupStringNoKeysymTransformations(xkb_keysym_t keysym) const
-{
- QVarLengthArray<char, 32> chars(32);
- const int size = xkb_keysym_to_utf8(keysym, chars.data(), chars.size());
- if (Q_UNLIKELY(size > chars.size())) {
- chars.resize(size);
- xkb_keysym_to_utf8(keysym, chars.data(), chars.size());
- }
- return QString::fromUtf8(chars.constData(), size);
-}
-
static bool fromSendEvent(const void *event)
{
// From X11 protocol: Every event contains an 8-bit type code. The most
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index f8490592b7..e35c82ad24 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -50,16 +50,12 @@
#endif
#include <xkbcommon/xkbcommon.h>
-#if QT_CONFIG(xkb)
-#include <xkbcommon/xkbcommon-x11.h>
-#endif
+#include <QtXkbCommonSupport/private/qxkbcommon_p.h>
#include <QEvent>
QT_BEGIN_NAMESPACE
-class QWindow;
-
class QXcbKeyboard : public QXcbObject
{
public:
@@ -67,6 +63,7 @@ public:
~QXcbKeyboard();
+ void initialize();
void selectEvents();
void handleKeyPressEvent(const xcb_key_press_event_t *event);
@@ -75,7 +72,7 @@ public:
Qt::KeyboardModifiers translateModifiers(int s) const;
void updateKeymap(xcb_mapping_notify_event_t *event);
void updateKeymap();
- QList<int> possibleKeys(const QKeyEvent *e) const;
+ QList<int> possibleKeys(const QKeyEvent *event) const;
// when XKEYBOARD not present on the X server
void updateXKBMods();
@@ -96,10 +93,6 @@ protected:
quint16 state, xcb_timestamp_t time, bool fromSendEvent);
void resolveMaskConflicts();
- QString lookupString(struct xkb_state *state, xcb_keycode_t code) const;
- QString lookupStringNoKeysymTransformations(xkb_keysym_t keysym) const;
- int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
- struct xkb_state *state, xcb_keycode_t code) const;
typedef QMap<xcb_keysym_t, int> KeysymModifierMap;
struct xkb_keymap *keymapFromCore(const KeysymModifierMap &keysymMods);
@@ -111,9 +104,6 @@ protected:
void updateVModMapping();
void updateVModToRModMapping();
- xkb_keysym_t lookupLatinKeysym(xkb_keycode_t keycode) const;
- void checkForLatinLayout() const;
-
private:
bool m_config = false;
bool m_isAutoRepeat = false;
@@ -148,22 +138,12 @@ private:
int core_device_id;
#endif
- struct XKBStateDeleter {
- void operator()(struct xkb_state *state) const { return xkb_state_unref(state); }
- };
- struct XKBKeymapDeleter {
- void operator()(struct xkb_keymap *keymap) const { return xkb_keymap_unref(keymap); }
- };
- struct XKBContextDeleter {
- void operator()(struct xkb_context *context) const { return xkb_context_unref(context); }
- };
- using ScopedXKBState = std::unique_ptr<struct xkb_state, XKBStateDeleter>;
- using ScopedXKBKeymap = std::unique_ptr<struct xkb_keymap, XKBKeymapDeleter>;
- using ScopedXKBContext = std::unique_ptr<struct xkb_context, XKBContextDeleter>;
+ QXkbCommon::ScopedXKBState m_xkbState;
+ QXkbCommon::ScopedXKBKeymap m_xkbKeymap;
+ QXkbCommon::ScopedXKBContext m_xkbContext;
- ScopedXKBState m_xkbState;
- ScopedXKBKeymap m_xkbKeymap;
- ScopedXKBContext m_xkbContext;
+ bool m_superAsMeta = false;
+ bool m_hyperAsMeta = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 6f3584f509..899081e752 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -304,7 +304,7 @@ QPlatformNativeInterface::NativeResourceForWindowFunction QXcbNativeInterface::n
QPlatformNativeInterface::NativeResourceForBackingStoreFunction QXcbNativeInterface::nativeResourceFunctionForBackingStore(const QByteArray &resource)
{
const QByteArray lowerCaseResource = resource.toLower();
- NativeResourceForBackingStoreFunction func = handlerNativeResourceFunctionForBackingStore(resource);
+ NativeResourceForBackingStoreFunction func = handlerNativeResourceFunctionForBackingStore(lowerCaseResource);
return func;
}
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 57dbdc9bec..0fa0e8cd7b 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -147,7 +147,7 @@ void QXcbVirtualDesktop::setPrimaryScreen(QPlatformScreen *s)
{
const int idx = m_screens.indexOf(s);
Q_ASSERT(idx > -1);
- m_screens.swap(0, idx);
+ m_screens.swapItemsAt(0, idx);
}
QXcbXSettings *QXcbVirtualDesktop::xSettings() const
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.h b/src/plugins/platforms/xcb/qxcbsessionmanager.h
index 0ad9445361..79c587b38d 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.h
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.h
@@ -85,8 +85,6 @@ public:
private:
QEventLoop *m_eventLoop;
-
- Q_DISABLE_COPY(QXcbSessionManager)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 3bfcbf2adb..9382488b74 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -843,40 +843,12 @@ void QXcbWindow::doFocusIn()
QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason);
}
-static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event)
-{
- if (!event) {
- // FocusIn event is not in the queue, proceed with FocusOut normally.
- QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason);
- return true;
- }
- uint response_type = event->response_type & ~0x80;
- if (response_type == XCB_FOCUS_IN) {
- // Ignore focus events that are being sent only because the pointer is over
- // our window, even if the input focus is in a different window.
- xcb_focus_in_event_t *e = (xcb_focus_in_event_t *) event;
- if (e->detail != XCB_NOTIFY_DETAIL_POINTER)
- return true;
- }
-
- /* We are also interested in XEMBED_FOCUS_IN events */
- if (response_type == XCB_CLIENT_MESSAGE) {
- xcb_client_message_event_t *cme = (xcb_client_message_event_t *)event;
- if (cme->type == connection->atom(QXcbAtom::_XEMBED)
- && cme->data.data32[1] == XEMBED_FOCUS_IN)
- return true;
- }
-
- return false;
-}
-
void QXcbWindow::doFocusOut()
{
connection()->setFocusWindow(nullptr);
relayFocusToModalWindow();
// Do not set the active window to nullptr if there is a FocusIn coming.
- // The FocusIn handler will update QXcbConnection::setFocusWindow() accordingly.
- connection()->addPeekFunc(focusInPeeker);
+ connection()->focusInTimer().start(400);
}
struct QtMotifWmHints {
@@ -2264,6 +2236,8 @@ void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *event)
// our window, even if the input focus is in a different window.
if (event->detail == XCB_NOTIFY_DETAIL_POINTER)
return;
+
+ connection()->focusInTimer().stop();
doFocusIn();
}
@@ -2491,6 +2465,7 @@ void QXcbWindow::handleXEmbedMessage(const xcb_client_message_event_t *event)
xcbScreen()->windowShown(this);
break;
case XEMBED_FOCUS_IN:
+ connection()->focusInTimer().stop();
Qt::FocusReason reason;
switch (event->data.data32[2]) {
case XEMBED_FOCUS_FIRST:
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
index db3d6629b3..34c671c8c7 100644
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
@@ -6,7 +6,8 @@ QT += \
core-private gui-private \
service_support-private theme_support-private \
fontdatabase_support-private \
- edid_support-private
+ edid_support-private \
+ xkbcommon_support-private
qtHaveModule(linuxaccessibility_support-private): \
QT += linuxaccessibility_support-private
@@ -52,7 +53,6 @@ HEADERS = \
qxcbimage.h \
qxcbxsettings.h \
qxcbsystemtraytracker.h \
- qxcbxkbcommon.h \
qxcbeventqueue.h \
qxcbeventdispatcher.h \
qxcbconnection_basic.h \
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h
index 4c5f474595..3497c6a6f1 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h
@@ -84,7 +84,7 @@ public:
private:
QScopedPointer<QXdgDesktopPortalThemePrivate> d_ptr;
- Q_DISABLE_COPY(QXdgDesktopPortalTheme)
+ Q_DISABLE_COPY_MOVE(QXdgDesktopPortalTheme)
};
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h
index 2a1a83b9d7..c021b0c643 100644
--- a/src/plugins/printsupport/cups/qcupsprintengine_p.h
+++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h
@@ -77,7 +77,7 @@ public:
// end reimplementations QPdfPrintEngine
private:
- Q_DISABLE_COPY(QCupsPrintEngine)
+ Q_DISABLE_COPY_MOVE(QCupsPrintEngine)
};
class QCupsPrintEnginePrivate : public QPdfPrintEnginePrivate
@@ -91,7 +91,7 @@ public:
void closePrintDevice() override;
private:
- Q_DISABLE_COPY(QCupsPrintEnginePrivate)
+ Q_DISABLE_COPY_MOVE(QCupsPrintEnginePrivate)
void changePrinter(const QString &newPrinter);
void setPageSize(const QPageSize &pageSize);
diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.h b/src/plugins/printsupport/windows/qwindowsprintersupport.h
index 4267701145..400701628e 100644
--- a/src/plugins/printsupport/windows/qwindowsprintersupport.h
+++ b/src/plugins/printsupport/windows/qwindowsprintersupport.h
@@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE
class QWindowsPrinterSupport : public QPlatformPrinterSupport
{
- Q_DISABLE_COPY(QWindowsPrinterSupport)
+ Q_DISABLE_COPY_MOVE(QWindowsPrinterSupport)
public:
QWindowsPrinterSupport();
~QWindowsPrinterSupport() override;
diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
index f2ae3fbc47..febbe58506 100644
--- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
@@ -197,6 +197,7 @@ protected:
QSqlRecord record() const override;
void virtual_hook(int id, void *data) override;
bool nextResult() override;
+ void detachFromResultSet() override;
#if MYSQL_VERSION_ID >= 40108
bool prepare(const QString &stmt) override;
@@ -804,6 +805,15 @@ int QMYSQLResult::numRowsAffected()
return d->rowsAffected;
}
+void QMYSQLResult::detachFromResultSet()
+{
+ Q_D(QMYSQLResult);
+
+ if (d->preparedQuery) {
+ mysql_stmt_free_result(d->stmt);
+ }
+}
+
QVariant QMYSQLResult::lastInsertId() const
{
Q_D(const QMYSQLResult);
@@ -1541,7 +1551,7 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const
QSqlQuery i(createResult());
QString stmt(QLatin1String("show index from %1;"));
QSqlRecord fil = record(tablename);
- i.exec(stmt.arg(tablename));
+ i.exec(stmt.arg(escapeIdentifier(tablename, QSqlDriver::TableName)));
while (i.isActive() && i.next()) {
if (i.value(2).toString() == QLatin1String("PRIMARY")) {
idx.append(fil.field(i.value(4).toString()));
diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
index 1fbbcd0ef1..7f98efccba 100644
--- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
@@ -345,7 +345,7 @@ static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type,
{
int nativeCode = -1;
QString message = qODBCWarn(p, &nativeCode);
- return QSqlError(QLatin1String("QODBC3: ") + err, qODBCWarn(p), type,
+ return QSqlError(QLatin1String("QODBC3: ") + err, message, type,
nativeCode != -1 ? QString::number(nativeCode) : QString());
}
diff --git a/src/plugins/sqldrivers/psql/main.cpp b/src/plugins/sqldrivers/psql/main.cpp
index c5d546f6ff..a0862a238a 100644
--- a/src/plugins/sqldrivers/psql/main.cpp
+++ b/src/plugins/sqldrivers/psql/main.cpp
@@ -61,11 +61,9 @@ QPSQLDriverPlugin::QPSQLDriverPlugin()
QSqlDriver* QPSQLDriverPlugin::create(const QString &name)
{
- if (name == QLatin1String("QPSQL") || name == QLatin1String("QPSQL7")) {
- QPSQLDriver* driver = new QPSQLDriver();
- return driver;
- }
- return 0;
+ if (name == QLatin1String("QPSQL") || name == QLatin1String("QPSQL7"))
+ return new QPSQLDriver;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index 7ad9db1ea8..c1be91cb22 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -42,7 +42,7 @@
#include <qcoreapplication.h>
#include <qvariant.h>
#include <qdatetime.h>
-#include <qregexp.h>
+#include <qregularexpression.h>
#include <qsqlerror.h>
#include <qsqlfield.h>
#include <qsqlindex.h>
@@ -53,6 +53,9 @@
#include <qlocale.h>
#include <QtSql/private/qsqlresult_p.h>
#include <QtSql/private/qsqldriver_p.h>
+#include <QtCore/private/qlocale_tools_p.h>
+
+#include <queue>
#include <libpq-fe.h>
#include <pg_config.h>
@@ -133,7 +136,7 @@ protected:
bool nextResult() override;
QVariant data(int i) override;
bool isNull(int field) override;
- bool reset (const QString &query) override;
+ bool reset(const QString &query) override;
int size() override;
int numRowsAffected() override;
QSqlRecord record() const override;
@@ -147,10 +150,10 @@ class QPSQLDriverPrivate final : public QSqlDriverPrivate
Q_DECLARE_PUBLIC(QPSQLDriver)
public:
QPSQLDriverPrivate() : QSqlDriverPrivate(),
- connection(0),
+ connection(nullptr),
isUtf8(false),
pro(QPSQLDriver::Version6),
- sn(0),
+ sn(nullptr),
pendingNotifyCheck(false),
hasBackslashEscape(false),
stmtCount(0),
@@ -187,11 +190,13 @@ public:
void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type)
{
- QString query = QString::fromLatin1("select pg_class.relname, pg_namespace.nspname from pg_class "
- "left join pg_namespace on (pg_class.relnamespace = pg_namespace.oid) "
- "where (pg_class.relkind = '%1') and (pg_class.relname !~ '^Inv') "
- "and (pg_class.relname !~ '^pg_') "
- "and (pg_namespace.nspname != 'information_schema')").arg(type);
+ const QString query =
+ QStringLiteral("SELECT pg_class.relname, pg_namespace.nspname FROM pg_class "
+ "LEFT JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid) "
+ "WHERE (pg_class.relkind = '") + type +
+ QStringLiteral("') AND (pg_class.relname !~ '^Inv') "
+ "AND (pg_class.relname !~ '^pg_') "
+ "AND (pg_namespace.nspname != 'information_schema')");
t.exec(query);
while (t.next()) {
QString schema = t.value(1).toString();
@@ -294,10 +299,10 @@ public:
Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver)
QPSQLResultPrivate(QPSQLResult *q, const QPSQLDriver *drv)
: QSqlResultPrivate(q, drv),
- result(0),
+ result(nullptr),
+ stmtId(InvalidStatementId),
currentSize(-1),
canFetchMoreRows(false),
- stmtId(InvalidStatementId),
preparedQueriesEnabled(false)
{ }
@@ -305,25 +310,25 @@ public:
void deallocatePreparedStmt();
PGresult *result;
- QList<PGresult*> nextResultSets;
+ std::queue<PGresult*> nextResultSets;
+ QString preparedStmtId;
+ StatementId stmtId;
int currentSize;
bool canFetchMoreRows;
- StatementId stmtId;
bool preparedQueriesEnabled;
- QString preparedStmtId;
bool processResults();
};
-static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type,
- const QPSQLDriverPrivate *p, PGresult* result = 0)
+static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type,
+ const QPSQLDriverPrivate *p, PGresult *result = nullptr)
{
const char *s = PQerrorMessage(p->connection);
QString msg = p->isUtf8 ? QString::fromUtf8(s) : QString::fromLocal8Bit(s);
QString errorCode;
if (result) {
- errorCode = QString::fromLatin1(PQresultErrorField(result, PG_DIAG_SQLSTATE));
- msg += QString::fromLatin1("(%1)").arg(errorCode);
+ errorCode = QString::fromLatin1(PQresultErrorField(result, PG_DIAG_SQLSTATE));
+ msg += QString::fromLatin1("(%1)").arg(errorCode);
}
return QSqlError(QLatin1String("QPSQL: ") + err, msg, type, errorCode);
}
@@ -423,7 +428,7 @@ static QVariant::Type qDecodePSQLType(int t)
void QPSQLResultPrivate::deallocatePreparedStmt()
{
- const QString stmt = QLatin1String("DEALLOCATE ") + preparedStmtId;
+ const QString stmt = QStringLiteral("DEALLOCATE ") + preparedStmtId;
PGresult *result = drv_d_func()->exec(stmt);
if (PQresultStatus(result) != PGRES_COMMAND_OK)
@@ -432,7 +437,7 @@ void QPSQLResultPrivate::deallocatePreparedStmt()
preparedStmtId.clear();
}
-QPSQLResult::QPSQLResult(const QPSQLDriver* db)
+QPSQLResult::QPSQLResult(const QPSQLDriver *db)
: QSqlResult(*new QPSQLResultPrivate(this, db))
{
Q_D(QPSQLResult);
@@ -460,8 +465,10 @@ void QPSQLResult::cleanup()
if (d->result)
PQclear(d->result);
d->result = nullptr;
- while (!d->nextResultSets.isEmpty())
- PQclear(d->nextResultSets.takeFirst());
+ while (!d->nextResultSets.empty()) {
+ PQclear(d->nextResultSets.front());
+ d->nextResultSets.pop();
+ }
if (d->stmtId != InvalidStatementId) {
if (d->drv_d_func())
d->drv_d_func()->finishQuery(d->stmtId);
@@ -622,7 +629,11 @@ bool QPSQLResult::nextResult()
if (d->result)
PQclear(d->result);
- d->result = d->nextResultSets.isEmpty() ? nullptr : d->nextResultSets.takeFirst();
+ d->result = nullptr;
+ if (!d->nextResultSets.empty()) {
+ d->result = d->nextResultSets.front();
+ d->nextResultSets.pop();
+ }
return d->processResults();
}
@@ -646,34 +657,37 @@ QVariant QPSQLResult::data(int i)
return d->drv_d_func()->isUtf8 ? QString::fromUtf8(val) : QString::fromLatin1(val);
case QVariant::LongLong:
if (val[0] == '-')
- return QString::fromLatin1(val).toLongLong();
+ return QByteArray::fromRawData(val, qstrlen(val)).toLongLong();
else
- return QString::fromLatin1(val).toULongLong();
+ return QByteArray::fromRawData(val, qstrlen(val)).toULongLong();
case QVariant::Int:
return atoi(val);
case QVariant::Double: {
if (ptype == QNUMERICOID) {
- if (numericalPrecisionPolicy() != QSql::HighPrecision) {
- QVariant retval;
- bool convert;
- double dbl=QString::fromLatin1(val).toDouble(&convert);
- if (numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
- retval = (qlonglong)dbl;
- else if (numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
- retval = (int)dbl;
- else if (numericalPrecisionPolicy() == QSql::LowPrecisionDouble)
- retval = dbl;
- if (!convert)
- return QVariant();
- return retval;
- }
- return QString::fromLatin1(val);
+ if (numericalPrecisionPolicy() == QSql::HighPrecision)
+ return QString::fromLatin1(val);
+ }
+ bool ok;
+ double dbl = qstrtod(val, nullptr, &ok);
+ if (!ok) {
+ if (qstricmp(val, "NaN") == 0)
+ dbl = qQNaN();
+ else if (qstricmp(val, "Infinity") == 0)
+ dbl = qInf();
+ else if (qstricmp(val, "-Infinity") == 0)
+ dbl = -qInf();
+ else
+ return QVariant();
}
- if (qstricmp(val, "Infinity") == 0)
- return qInf();
- if (qstricmp(val, "-Infinity") == 0)
- return -qInf();
- return QString::fromLatin1(val).toDouble();
+ if (ptype == QNUMERICOID) {
+ if (numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
+ return QVariant((qlonglong)dbl);
+ else if (numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
+ return QVariant((int)dbl);
+ else if (numericalPrecisionPolicy() == QSql::LowPrecisionDouble)
+ return QVariant(dbl);
+ }
+ return dbl;
}
case QVariant::Date:
if (val[0] == '\0') {
@@ -701,7 +715,7 @@ QVariant QPSQLResult::data(int i)
#if QT_CONFIG(datestring)
if (dtval.length() < 10) {
return QVariant(QDateTime());
- } else {
+ } else {
QChar sign = dtval[dtval.size() - 3];
if (sign == QLatin1Char('-') || sign == QLatin1Char('+')) dtval += QLatin1String(":00");
return QVariant(QDateTime::fromString(dtval, Qt::ISODate).toLocalTime());
@@ -731,7 +745,7 @@ bool QPSQLResult::isNull(int field)
return PQgetisnull(d->result, currentRow, field);
}
-bool QPSQLResult::reset (const QString& query)
+bool QPSQLResult::reset(const QString &query)
{
Q_D(QPSQLResult);
cleanup();
@@ -754,7 +768,7 @@ bool QPSQLResult::reset (const QString& query)
if (!isForwardOnly()) {
// Fetch all result sets right away
while (PGresult *nextResultSet = d->drv_d_func()->getResult(d->stmtId))
- d->nextResultSets.append(nextResultSet);
+ d->nextResultSets.push(nextResultSet);
}
return d->processResults();
}
@@ -768,7 +782,8 @@ int QPSQLResult::size()
int QPSQLResult::numRowsAffected()
{
Q_D(const QPSQLResult);
- return QString::fromLatin1(PQcmdTuples(d->result)).toInt();
+ const char *tuples = PQcmdTuples(d->result);
+ return QByteArray::fromRawData(tuples, qstrlen(tuples)).toInt();
}
QVariant QPSQLResult::lastInsertId() const
@@ -777,7 +792,7 @@ QVariant QPSQLResult::lastInsertId() const
if (d->drv_d_func()->pro >= QPSQLDriver::Version8_1) {
QSqlQuery qry(driver()->createResult());
// Most recent sequence value obtained from nextval
- if (qry.exec(QLatin1String("SELECT lastval();")) && qry.next())
+ if (qry.exec(QStringLiteral("SELECT lastval();")) && qry.next())
return qry.value(0);
} else if (isActive()) {
Oid id = PQoidValue(d->result);
@@ -857,7 +872,6 @@ QSqlRecord QPSQLResult::record() const
void QPSQLResult::virtual_hook(int id, void *data)
{
Q_ASSERT(data);
-
QSqlResult::virtual_hook(id, data);
}
@@ -868,15 +882,13 @@ static QString qCreateParamString(const QVector<QVariant> &boundValues, const QS
QString params;
QSqlField f;
- for (int i = 0; i < boundValues.count(); ++i) {
- const QVariant &val = boundValues.at(i);
-
+ for (const QVariant &val : boundValues) {
f.setType(val.type());
if (val.isNull())
f.clear();
else
f.setValue(val);
- if(!params.isNull())
+ if (!params.isNull())
params.append(QLatin1String(", "));
params.append(driver->formatValue(f));
}
@@ -886,7 +898,7 @@ static QString qCreateParamString(const QVector<QVariant> &boundValues, const QS
QString qMakePreparedStmtId()
{
static QBasicAtomicInt qPreparedStmtCount = Q_BASIC_ATOMIC_INITIALIZER(0);
- QString id = QLatin1String("qpsqlpstmt_") + QString::number(qPreparedStmtCount.fetchAndAddRelaxed(1) + 1, 16);
+ QString id = QStringLiteral("qpsqlpstmt_") + QString::number(qPreparedStmtCount.fetchAndAddRelaxed(1) + 1, 16);
return id;
}
@@ -902,7 +914,7 @@ bool QPSQLResult::prepare(const QString &query)
d->deallocatePreparedStmt();
const QString stmtId = qMakePreparedStmtId();
- const QString stmt = QString::fromLatin1("PREPARE %1 AS ").arg(stmtId).append(d->positionalToNamedBinding(query));
+ const QString stmt = QStringLiteral("PREPARE %1 AS ").arg(stmtId).append(d->positionalToNamedBinding(query));
PGresult *result = d->drv_d_func()->exec(stmt);
@@ -930,9 +942,9 @@ bool QPSQLResult::exec()
QString stmt;
const QString params = qCreateParamString(boundValues(), driver());
if (params.isEmpty())
- stmt = QString::fromLatin1("EXECUTE %1").arg(d->preparedStmtId);
+ stmt = QStringLiteral("EXECUTE %1").arg(d->preparedStmtId);
else
- stmt = QString::fromLatin1("EXECUTE %1 (%2)").arg(d->preparedStmtId, params);
+ stmt = QStringLiteral("EXECUTE %1 (%2)").arg(d->preparedStmtId, params);
d->stmtId = d->drv_d_func()->sendQuery(stmt);
if (d->stmtId == InvalidStatementId) {
@@ -948,7 +960,7 @@ bool QPSQLResult::exec()
if (!isForwardOnly()) {
// Fetch all result sets right away
while (PGresult *nextResultSet = d->drv_d_func()->getResult(d->stmtId))
- d->nextResultSets.append(nextResultSet);
+ d->nextResultSets.push(nextResultSet);
}
return d->processResults();
}
@@ -957,7 +969,7 @@ bool QPSQLResult::exec()
bool QPSQLDriverPrivate::setEncodingUtf8()
{
- PGresult* result = exec("SET CLIENT_ENCODING TO 'UNICODE'");
+ PGresult *result = exec("SET CLIENT_ENCODING TO 'UNICODE'");
int status = PQresultStatus(result);
PQclear(result);
return status == PGRES_COMMAND_OK;
@@ -965,7 +977,7 @@ bool QPSQLDriverPrivate::setEncodingUtf8()
void QPSQLDriverPrivate::setDatestyle()
{
- PGresult* result = exec("SET DATESTYLE TO 'ISO'");
+ PGresult *result = exec("SET DATESTYLE TO 'ISO'");
int status = PQresultStatus(result);
if (status != PGRES_COMMAND_OK)
qWarning("%s", PQerrorMessage(connection));
@@ -994,7 +1006,7 @@ void QPSQLDriverPrivate::detectBackslashEscape()
hasBackslashEscape = true;
} else {
hasBackslashEscape = false;
- PGresult* result = exec(QLatin1String("SELECT '\\\\' x"));
+ PGresult *result = exec(QStringLiteral("SELECT '\\\\' x"));
int status = PQresultStatus(result);
if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK)
if (QString::fromLatin1(PQgetvalue(result, 0, 0)) == QLatin1String("\\"))
@@ -1072,20 +1084,21 @@ static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin)
static QPSQLDriver::Protocol qFindPSQLVersion(const QString &versionString)
{
- const QRegExp rx(QStringLiteral("(\\d+)(?:\\.(\\d+))?"));
- if (rx.indexIn(versionString) != -1) {
+ const QRegularExpression rx(QStringLiteral("(\\d+)(?:\\.(\\d+))?"));
+ const QRegularExpressionMatch match = rx.match(versionString);
+ if (match.hasMatch()) {
// Beginning with PostgreSQL version 10, a major release is indicated by
// increasing the first part of the version, e.g. 10 to 11.
// Before version 10, a major release was indicated by increasing either
// the first or second part of the version number, e.g. 9.5 to 9.6.
- int vMaj = rx.cap(1).toInt();
+ int vMaj = match.capturedRef(1).toInt();
int vMin;
if (vMaj >= 10) {
vMin = 0;
} else {
- if (rx.cap(2).isEmpty())
+ if (match.capturedRef(2).isEmpty())
return QPSQLDriver::VersionUnknown;
- vMin = rx.cap(2).toInt();
+ vMin = match.capturedRef(2).toInt();
}
return qMakePSQLVersion(vMaj, vMin);
}
@@ -1096,7 +1109,7 @@ static QPSQLDriver::Protocol qFindPSQLVersion(const QString &versionString)
QPSQLDriver::Protocol QPSQLDriverPrivate::getPSQLVersion()
{
QPSQLDriver::Protocol serverVersion = QPSQLDriver::Version6;
- PGresult* result = exec("select version()");
+ PGresult *result = exec("SELECT version()");
int status = PQresultStatus(result);
if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) {
serverVersion = qFindPSQLVersion(
@@ -1202,12 +1215,12 @@ static QString qQuote(QString s)
return s;
}
-bool QPSQLDriver::open(const QString & db,
- const QString & user,
- const QString & password,
- const QString & host,
- int port,
- const QString& connOpts)
+bool QPSQLDriver::open(const QString &db,
+ const QString &user,
+ const QString &password,
+ const QString &host,
+ int port,
+ const QString &connOpts)
{
Q_D(QPSQLDriver);
if (isOpen())
@@ -1236,7 +1249,7 @@ bool QPSQLDriver::open(const QString & db,
setLastError(qMakeError(tr("Unable to connect"), QSqlError::ConnectionError, d));
setOpenError(true);
PQfinish(d->connection);
- d->connection = 0;
+ d->connection = nullptr;
return false;
}
@@ -1260,12 +1273,12 @@ void QPSQLDriver::close()
if (d->sn) {
disconnect(d->sn, SIGNAL(activated(int)), this, SLOT(_q_handleNotification(int)));
delete d->sn;
- d->sn = 0;
+ d->sn = nullptr;
}
if (d->connection)
PQfinish(d->connection);
- d->connection = 0;
+ d->connection = nullptr;
setOpen(false);
setOpenError(false);
}
@@ -1283,7 +1296,7 @@ bool QPSQLDriver::beginTransaction()
qWarning("QPSQLDriver::beginTransaction: Database not open");
return false;
}
- PGresult* res = d->exec("BEGIN");
+ PGresult *res = d->exec("BEGIN");
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) {
setLastError(qMakeError(tr("Could not begin transaction"),
QSqlError::TransactionError, d, res));
@@ -1301,7 +1314,7 @@ bool QPSQLDriver::commitTransaction()
qWarning("QPSQLDriver::commitTransaction: Database not open");
return false;
}
- PGresult* res = d->exec("COMMIT");
+ PGresult *res = d->exec("COMMIT");
bool transaction_failed = false;
@@ -1330,7 +1343,7 @@ bool QPSQLDriver::rollbackTransaction()
qWarning("QPSQLDriver::rollbackTransaction: Database not open");
return false;
}
- PGresult* res = d->exec("ROLLBACK");
+ PGresult *res = d->exec("ROLLBACK");
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) {
setLastError(qMakeError(tr("Could not rollback transaction"),
QSqlError::TransactionError, d, res));
@@ -1355,8 +1368,8 @@ QStringList QPSQLDriver::tables(QSql::TableType type) const
if (type & QSql::Views)
const_cast<QPSQLDriverPrivate*>(d)->appendTables(tl, t, QLatin1Char('v'));
if (type & QSql::SystemTables) {
- t.exec(QLatin1String("select relname from pg_class where (relkind = 'r') "
- "and (relname like 'pg_%') "));
+ t.exec(QStringLiteral("SELECT relname FROM pg_class WHERE (relkind = 'r') "
+ "AND (relname LIKE 'pg_%') "));
while (t.next())
tl.append(t.value(0).toString());
}
@@ -1373,7 +1386,7 @@ static void qSplitTableName(QString &tablename, QString &schema)
tablename = tablename.mid(dot + 1);
}
-QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
+QSqlIndex QPSQLDriver::primaryIndex(const QString &tablename) const
{
QSqlIndex idx(tablename);
if (!isOpen())
@@ -1383,31 +1396,23 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
QString tbl = tablename;
QString schema;
qSplitTableName(tbl, schema);
-
- if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
- tbl = stripDelimiters(tbl, QSqlDriver::TableName);
- else
- tbl = std::move(tbl).toLower();
-
- if (isIdentifierEscaped(schema, QSqlDriver::TableName))
- schema = stripDelimiters(schema, QSqlDriver::TableName);
- else
- schema = std::move(schema).toLower();
-
- QString stmt = QLatin1String("SELECT pg_attribute.attname, pg_attribute.atttypid::int, "
- "pg_class.relname "
- "FROM pg_attribute, pg_class "
- "WHERE %1 pg_class.oid IN "
- "(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid IN "
- "(SELECT oid FROM pg_class WHERE relname = '%2')) "
- "AND pg_attribute.attrelid = pg_class.oid "
- "AND pg_attribute.attisdropped = false "
- "ORDER BY pg_attribute.attnum");
+ schema = stripDelimiters(schema, QSqlDriver::TableName);
+ tbl = stripDelimiters(tbl, QSqlDriver::TableName);
+
+ QString stmt = QStringLiteral("SELECT pg_attribute.attname, pg_attribute.atttypid::int, "
+ "pg_class.relname "
+ "FROM pg_attribute, pg_class "
+ "WHERE %1 pg_class.oid IN "
+ "(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid IN "
+ "(SELECT oid FROM pg_class WHERE relname = '%2')) "
+ "AND pg_attribute.attrelid = pg_class.oid "
+ "AND pg_attribute.attisdropped = false "
+ "ORDER BY pg_attribute.attnum");
if (schema.isEmpty())
- stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid) AND"));
+ stmt = stmt.arg(QStringLiteral("pg_table_is_visible(pg_class.oid) AND"));
else
- stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from "
- "pg_namespace where pg_namespace.nspname = '%1') AND").arg(schema));
+ stmt = stmt.arg(QStringLiteral("pg_class.relnamespace = (SELECT oid FROM "
+ "pg_namespace WHERE pg_namespace.nspname = '%1') AND").arg(schema));
i.exec(stmt.arg(tbl));
while (i.isActive() && i.next()) {
@@ -1418,7 +1423,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
return idx;
}
-QSqlRecord QPSQLDriver::record(const QString& tablename) const
+QSqlRecord QPSQLDriver::record(const QString &tablename) const
{
QSqlRecord info;
if (!isOpen())
@@ -1427,34 +1432,26 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
QString tbl = tablename;
QString schema;
qSplitTableName(tbl, schema);
-
- if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
- tbl = stripDelimiters(tbl, QSqlDriver::TableName);
- else
- tbl = std::move(tbl).toLower();
-
- if (isIdentifierEscaped(schema, QSqlDriver::TableName))
- schema = stripDelimiters(schema, QSqlDriver::TableName);
- else
- schema = std::move(schema).toLower();
-
- QString stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, "
- "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, "
- "pg_attrdef.adsrc "
- "from pg_class, pg_attribute "
- "left join pg_attrdef on (pg_attrdef.adrelid = "
- "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) "
- "where %1 "
- "and pg_class.relname = '%2' "
- "and pg_attribute.attnum > 0 "
- "and pg_attribute.attrelid = pg_class.oid "
- "and pg_attribute.attisdropped = false "
- "order by pg_attribute.attnum");
+ schema = stripDelimiters(schema, QSqlDriver::TableName);
+ tbl = stripDelimiters(tbl, QSqlDriver::TableName);
+
+ QString stmt = QStringLiteral("SELECT pg_attribute.attname, pg_attribute.atttypid::int, "
+ "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, "
+ "pg_attrdef.adsrc "
+ "FROM pg_class, pg_attribute "
+ "LEFT JOIN pg_attrdef ON (pg_attrdef.adrelid = "
+ "pg_attribute.attrelid AND pg_attrdef.adnum = pg_attribute.attnum) "
+ "WHERE %1 "
+ "AND pg_class.relname = '%2' "
+ "AND pg_attribute.attnum > 0 "
+ "AND pg_attribute.attrelid = pg_class.oid "
+ "AND pg_attribute.attisdropped = false "
+ "ORDER BY pg_attribute.attnum");
if (schema.isEmpty())
- stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid)"));
+ stmt = stmt.arg(QStringLiteral("pg_table_is_visible(pg_class.oid)"));
else
- stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from "
- "pg_namespace where pg_namespace.nspname = '%1')").arg(schema));
+ stmt = stmt.arg(QStringLiteral("pg_class.relnamespace = (SELECT oid FROM "
+ "pg_namespace WHERE pg_namespace.nspname = '%1')").arg(schema));
QSqlQuery query(createResult());
query.exec(stmt.arg(tbl));
@@ -1496,9 +1493,10 @@ inline void assignSpecialPsqlFloatValue(FloatType val, QString *target)
QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
{
Q_D(const QPSQLDriver);
+ const auto nullStr = [](){ return QStringLiteral("NULL"); };
QString r;
if (field.isNull()) {
- r = QLatin1String("NULL");
+ r = nullStr();
} else {
switch (int(field.type())) {
case QVariant::DateTime:
@@ -1507,14 +1505,14 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
// we force the value to be considered with a timezone information, and we force it to be UTC
// this is safe since postgresql stores only the UTC value and not the timezone offset (only used
// while parsing), so we have correct behavior in both case of with timezone and without tz
- r = QLatin1String("TIMESTAMP WITH TIME ZONE ") + QLatin1Char('\'') +
- QLocale::c().toString(field.value().toDateTime().toUTC(), QLatin1String("yyyy-MM-ddThh:mm:ss.zzz")) +
+ r = QStringLiteral("TIMESTAMP WITH TIME ZONE ") + QLatin1Char('\'') +
+ QLocale::c().toString(field.value().toDateTime().toUTC(), QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz")) +
QLatin1Char('Z') + QLatin1Char('\'');
} else {
- r = QLatin1String("NULL");
+ r = nullStr();
}
#else
- r = QLatin1String("NULL");
+ r = nullStr();
#endif // datestring
break;
case QVariant::Time:
@@ -1524,19 +1522,19 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
} else
#endif
{
- r = QLatin1String("NULL");
+ r = nullStr();
}
break;
case QVariant::String:
r = QSqlDriver::formatValue(field, trimStrings);
if (d->hasBackslashEscape)
- r.replace(QLatin1String("\\"), QLatin1String("\\\\"));
+ r.replace(QLatin1Char('\\'), QLatin1String("\\\\"));
break;
case QVariant::Bool:
if (field.value().toBool())
- r = QLatin1String("TRUE");
+ r = QStringLiteral("TRUE");
else
- r = QLatin1String("FALSE");
+ r = QStringLiteral("FALSE");
break;
case QVariant::ByteArray: {
QByteArray ba(field.value().toByteArray());
@@ -1576,7 +1574,7 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
QString QPSQLDriver::escapeIdentifier(const QString &identifier, IdentifierType) const
{
QString res = identifier;
- if(!identifier.isEmpty() && !identifier.startsWith(QLatin1Char('"')) && !identifier.endsWith(QLatin1Char('"')) ) {
+ if (!identifier.isEmpty() && !identifier.startsWith(QLatin1Char('"')) && !identifier.endsWith(QLatin1Char('"')) ) {
res.replace(QLatin1Char('"'), QLatin1String("\"\""));
res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
res.replace(QLatin1Char('.'), QLatin1String("\".\""));
@@ -1615,7 +1613,7 @@ bool QPSQLDriver::subscribeToNotification(const QString &name)
// Add the name to the list of subscriptions here so that QSQLDriverPrivate::exec knows
// to check for notifications immediately after executing the LISTEN
d->seid << name;
- QString query = QLatin1String("LISTEN ") + escapeIdentifier(name, QSqlDriver::TableName);
+ QString query = QStringLiteral("LISTEN ") + escapeIdentifier(name, QSqlDriver::TableName);
PGresult *result = d->exec(query);
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
d->seid.removeLast();
@@ -1651,7 +1649,7 @@ bool QPSQLDriver::unsubscribeFromNotification(const QString &name)
return false;
}
- QString query = QLatin1String("UNLISTEN ") + escapeIdentifier(name, QSqlDriver::TableName);
+ QString query = QStringLiteral("UNLISTEN ") + escapeIdentifier(name, QSqlDriver::TableName);
PGresult *result = d->exec(query);
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
setLastError(qMakeError(tr("Unable to unsubscribe"), QSqlError::StatementError, d, result));
@@ -1665,7 +1663,7 @@ bool QPSQLDriver::unsubscribeFromNotification(const QString &name)
if (d->seid.isEmpty()) {
disconnect(d->sn, SIGNAL(activated(int)), this, SLOT(_q_handleNotification(int)));
delete d->sn;
- d->sn = 0;
+ d->sn = nullptr;
}
return true;
@@ -1683,8 +1681,8 @@ void QPSQLDriver::_q_handleNotification(int)
d->pendingNotifyCheck = false;
PQconsumeInput(d->connection);
- PGnotify *notify = 0;
- while((notify = PQnotifies(d->connection)) != 0) {
+ PGnotify *notify = nullptr;
+ while ((notify = PQnotifies(d->connection)) != nullptr) {
QString name(QLatin1String(notify->relname));
if (d->seid.contains(name)) {
QString payload;
diff --git a/src/plugins/sqldrivers/psql/qsql_psql_p.h b/src/plugins/sqldrivers/psql/qsql_psql_p.h
index 7e1849d857..99e0b5f60f 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql_p.h
+++ b/src/plugins/sqldrivers/psql/qsql_psql_p.h
@@ -96,22 +96,22 @@ public:
UnknownLaterVersion = 100000
};
- explicit QPSQLDriver(QObject *parent=0);
- explicit QPSQLDriver(PGconn *conn, QObject *parent=0);
+ explicit QPSQLDriver(QObject *parent = nullptr);
+ explicit QPSQLDriver(PGconn *conn, QObject *parent = nullptr);
~QPSQLDriver();
bool hasFeature(DriverFeature f) const override;
- bool open(const QString & db,
- const QString & user,
- const QString & password,
- const QString & host,
+ bool open(const QString &db,
+ const QString &user,
+ const QString &password,
+ const QString &host,
int port,
- const QString& connOpts) override;
+ const QString &connOpts) override;
bool isOpen() const override;
void close() override;
QSqlResult *createResult() const override;
QStringList tables(QSql::TableType) const override;
- QSqlIndex primaryIndex(const QString& tablename) const override;
- QSqlRecord record(const QString& tablename) const override;
+ QSqlIndex primaryIndex(const QString &tablename) const override;
+ QSqlRecord record(const QString &tablename) const override;
Protocol protocol() const;
QVariant handle() const override;
diff --git a/src/plugins/styles/android/qandroidstyle_p.h b/src/plugins/styles/android/qandroidstyle_p.h
index 3faa08afb9..6cb30a2f79 100644
--- a/src/plugins/styles/android/qandroidstyle_p.h
+++ b/src/plugins/styles/android/qandroidstyle_p.h
@@ -371,7 +371,7 @@ public:
void unpolish(QWidget *widget);
private:
- Q_DISABLE_COPY(QAndroidStyle)
+ Q_DISABLE_COPY_MOVE(QAndroidStyle)
static ItemType qtControl(QStyle::ComplexControl control);
static ItemType qtControl(QStyle::ContentsType contentsType);
static ItemType qtControl(QStyle::ControlElement controlElement);
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 0745e917a2..d0e05c1e20 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -4116,7 +4116,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
titleRect.width());
const auto text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
- proxy()->drawItemText(p, titleRect, Qt::AlignCenter | Qt::TextShowMnemonic, dwOpt->palette,
+ proxy()->drawItemText(p, titleRect, Qt::AlignCenter, dwOpt->palette,
dwOpt->state & State_Enabled, text, QPalette::WindowText);
}
p->restore();
diff --git a/src/plugins/styles/mac/qmacstyle_mac_p.h b/src/plugins/styles/mac/qmacstyle_mac_p.h
index d6874001d3..88f104cccf 100644
--- a/src/plugins/styles/mac/qmacstyle_mac_p.h
+++ b/src/plugins/styles/mac/qmacstyle_mac_p.h
@@ -115,7 +115,7 @@ public:
const QWidget *widget = 0) const;
private:
- Q_DISABLE_COPY(QMacStyle)
+ Q_DISABLE_COPY_MOVE(QMacStyle)
Q_DECLARE_PRIVATE(QMacStyle)
};
diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
index 771552a121..8a3ae17b1d 100644
--- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
@@ -632,7 +632,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
{
QPen pen = painter->pen();
int margin = 3;
- painter->setPen(option->palette.background().color().darker(114));
+ painter->setPen(option->palette.window().color().darker(114));
if (option->state & State_Horizontal) {
int x1 = option->rect.center().x();
painter->drawLine(QPoint(x1, option->rect.top() + margin), QPoint(x1, option->rect.bottom() - margin));
@@ -704,7 +704,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
if (sectionSize.width() > 0 && sectionSize.height() > 0) {
QString key = QString::fromLatin1("qvdelegate-%1-%2-%3-%4-%5").arg(sectionSize.width())
.arg(sectionSize.height()).arg(selected).arg(active).arg(hover);
- if (!QPixmapCache::find(key, pixmap)) {
+ if (!QPixmapCache::find(key, &pixmap)) {
pixmap = QPixmap(sectionSize);
pixmap.fill(Qt::transparent);
@@ -1053,7 +1053,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
}
QString name = QString::fromLatin1("qiprogress-%1-%2").arg(pixmapSize.width()).arg(pixmapSize.height());
QPixmap pixmap;
- if (!QPixmapCache::find(name, pixmap)) {
+ if (!QPixmapCache::find(name, &pixmap)) {
QImage image(pixmapSize, QImage::Format_ARGB32);
image.fill(Qt::transparent);
QPainter imagePainter(&image);
@@ -1363,7 +1363,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
case CE_ToolBar:
if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
QPalette pal = option->palette;
- pal.setColor(QPalette::Dark, option->palette.background().color().darker(130));
+ pal.setColor(QPalette::Dark, option->palette.window().color().darker(130));
QStyleOptionToolBar copyOpt = *toolbar;
copyOpt.palette = pal;
QWindowsStyle::drawControl(element, &copyOpt, painter, widget);
@@ -1388,8 +1388,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
painter->translate(-rect.left() + 1, -rect.top());
}
- painter->setBrush(option->palette.background().color().darker(110));
- painter->setPen(option->palette.background().color().darker(130));
+ painter->setBrush(option->palette.window().color().darker(110));
+ painter->setPen(option->palette.window().color().darker(130));
painter->drawRect(rect.adjusted(0, 1, -1, -3));
int buttonMargin = 4;
diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h b/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h
index 0ebb0eb41a..43a2a670f8 100644
--- a/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h
+++ b/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h
@@ -99,7 +99,7 @@ public:
QPalette standardPalette() const override;
private:
- Q_DISABLE_COPY(QWindowsVistaStyle)
+ Q_DISABLE_COPY_MOVE(QWindowsVistaStyle)
Q_DECLARE_PRIVATE(QWindowsVistaStyle)
friend class QStyleFactory;
};
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
index 4b583e13d3..90026e5bf0 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
@@ -511,8 +511,8 @@ QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData)
if (numBytes == 0)
return QRegion();
- char *buf = new char[numBytes];
- if (buf == 0)
+ char *buf = new (std::nothrow) char[numBytes];
+ if (!buf)
return QRegion();
RGNDATA *rd = reinterpret_cast<RGNDATA*>(buf);
@@ -740,7 +740,8 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeDa
{
QPainter *painter = themeData.painter;
- const QPointF redirectionDelta(painter->deviceMatrix().dx(), painter->deviceMatrix().dy());
+ const auto deviceTransform = painter->deviceTransform();
+ const QPointF redirectionDelta(deviceTransform.dx(), deviceTransform.dy());
const QRect area = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio).translated(redirectionDelta).toRect();
QRegion sysRgn = painter->paintEngine()->systemClip();
@@ -835,7 +836,7 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
alphaType = data.alphaType;
potentialInvalidAlpha = data.hadInvalidAlpha;
- haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, cachedPixmap);
+ haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, &cachedPixmap);
#ifdef DEBUG_XP_STYLE
char buf[25];
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h b/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h
index 7e9f4ddda6..0f70105b0e 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h
@@ -96,7 +96,7 @@ public:
const QWidget *widget = nullptr) const override;
private:
- Q_DISABLE_COPY(QWindowsXPStyle)
+ Q_DISABLE_COPY_MOVE(QWindowsXPStyle)
Q_DECLARE_PRIVATE(QWindowsXPStyle)
friend class QStyleFactory;
};
diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp
index 5390a8b2f2..9fb9d6c55e 100644
--- a/src/printsupport/dialogs/qprintdialog_unix.cpp
+++ b/src/printsupport/dialogs/qprintdialog_unix.cpp
@@ -738,7 +738,7 @@ static std::vector<std::pair<int, int>> pageRangesFromString(const QString &page
{
std::vector<std::pair<int, int>> result;
const QStringList items = pagesString.split(',');
- for (const QString item : items) {
+ for (const QString &item : items) {
if (item.isEmpty())
return {};
diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp
index 418bc47a59..e6b665f82c 100644
--- a/src/printsupport/dialogs/qprintpreviewdialog.cpp
+++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp
@@ -331,7 +331,7 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
QVBoxLayout *topLayout = new QVBoxLayout;
topLayout->addWidget(mw);
- topLayout->setMargin(0);
+ topLayout->setContentsMargins(0, 0, 0, 0);
q->setLayout(topLayout);
QString caption = QCoreApplication::translate("QPrintPreviewDialog", "Print Preview");
diff --git a/src/printsupport/kernel/qplatformprintdevice.cpp b/src/printsupport/kernel/qplatformprintdevice.cpp
index 69d984cb0c..3d76cad688 100644
--- a/src/printsupport/kernel/qplatformprintdevice.cpp
+++ b/src/printsupport/kernel/qplatformprintdevice.cpp
@@ -40,10 +40,8 @@
#include "qplatformprintdevice.h"
#include "qprintdevice_p.h"
-#if QT_CONFIG(printdialog)
-#include "qprintdialog.h"
-#endif
+#include <QtCore/qcoreapplication.h>
#include <QtGui/qpagelayout.h>
QT_BEGIN_NAMESPACE
@@ -165,7 +163,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QPageSize &pageSize) con
// e.g. Windows defines DMPAPER_11X17 and DMPAPER_TABLOID with names "11x17" and "Tabloid", but both
// map to QPageSize::Tabloid / PPD Key "Tabloid" / ANSI B Tabloid
if (pageSize.id() != QPageSize::Custom) {
- for (const QPageSize &ps : m_pageSizes) {
+ for (const QPageSize &ps : qAsConst(m_pageSizes)) {
if (ps.id() == pageSize.id() && ps.name() == pageSize.name())
return ps;
}
@@ -173,7 +171,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QPageSize &pageSize) con
// Next try match on id only if not custom
if (pageSize.id() != QPageSize::Custom) {
- for (const QPageSize &ps : m_pageSizes) {
+ for (const QPageSize &ps : qAsConst(m_pageSizes)) {
if (ps.id() == pageSize.id())
return ps;
}
@@ -188,7 +186,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(QPageSize::PageSizeId pageSize
if (!m_havePageSizes)
loadPageSizes();
- for (const QPageSize &ps : m_pageSizes) {
+ for (const QPageSize &ps : qAsConst(m_pageSizes)) {
if (ps.id() == pageSizeId)
return ps;
}
@@ -202,7 +200,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QString &pageName) const
if (!m_havePageSizes)
loadPageSizes();
- for (const QPageSize &ps : m_pageSizes) {
+ for (const QPageSize &ps : qAsConst(m_pageSizes)) {
if (ps.name() == pageName)
return ps;
}
@@ -235,7 +233,7 @@ QPageSize QPlatformPrintDevice::supportedPageSizeMatch(const QPageSize &pageSize
return pageSize;
// Try to find a supported page size based on point size
- for (const QPageSize &ps : m_pageSizes) {
+ for (const QPageSize &ps : qAsConst(m_pageSizes)) {
if (ps.sizePoints() == pageSize.sizePoints())
return ps;
}
@@ -291,11 +289,7 @@ QPrint::InputSlot QPlatformPrintDevice::defaultInputSlot() const
{
QPrint::InputSlot input;
input.key = QByteArrayLiteral("Auto");
-#if QT_CONFIG(printdialog)
- input.name = QPrintDialog::tr("Automatic");
-#else
- input.name = QString::fromLatin1("Automatic");
-#endif
+ input.name = QCoreApplication::translate("Print Device Input Slot", "Automatic");
input.id = QPrint::Auto;
return input;
}
@@ -315,11 +309,7 @@ QPrint::OutputBin QPlatformPrintDevice::defaultOutputBin() const
{
QPrint::OutputBin output;
output.key = QByteArrayLiteral("Auto");
-#if QT_CONFIG(printdialog)
- output.name = QPrintDialog::tr("Automatic");
-#else
- output.name = QString::fromLatin1("Automatic");
-#endif
+ output.name = QCoreApplication::translate("Print Device Output Bin", "Automatic");
output.id = QPrint::AutoOutputBin;
return output;
}
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
index 829a13863b..ddcd8c4702 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -1848,7 +1848,7 @@ QList<int> QPrinter::supportedResolutions() const
= d->printEngine->property(QPrintEngine::PPK_SupportedResolutions).toList();
QList<int> intlist;
intlist.reserve(varlist.size());
- for (auto var : varlist)
+ for (const auto &var : varlist)
intlist << var.toInt();
return intlist;
}
diff --git a/src/printsupport/kernel/qprinterinfo.cpp b/src/printsupport/kernel/qprinterinfo.cpp
index 4b092dee64..167b2361ef 100644
--- a/src/printsupport/kernel/qprinterinfo.cpp
+++ b/src/printsupport/kernel/qprinterinfo.cpp
@@ -400,6 +400,35 @@ QList<QPrinter::DuplexMode> QPrinterInfo::supportedDuplexModes() const
}
/*!
+ Returns the default color mode of this printer.
+
+ \since 5.13
+*/
+
+QPrinter::ColorMode QPrinterInfo::defaultColorMode() const
+{
+ Q_D(const QPrinterInfo);
+ return QPrinter::ColorMode(d->m_printDevice.defaultColorMode());
+}
+
+/*!
+ Returns the supported color modes of this printer.
+
+ \since 5.13
+*/
+
+QList<QPrinter::ColorMode> QPrinterInfo::supportedColorModes() const
+{
+ Q_D(const QPrinterInfo);
+ QList<QPrinter::ColorMode> list;
+ const auto supportedColorModes = d->m_printDevice.supportedColorModes();
+ list.reserve(supportedColorModes.size());
+ for (QPrint::ColorMode mode : supportedColorModes)
+ list << QPrinter::ColorMode(mode);
+ return list;
+}
+
+/*!
Returns a list of all the available Printer Names on this system.
It is recommended to use this instead of availablePrinters() as
diff --git a/src/printsupport/kernel/qprinterinfo.h b/src/printsupport/kernel/qprinterinfo.h
index 8bac395ab3..7195cb76b5 100644
--- a/src/printsupport/kernel/qprinterinfo.h
+++ b/src/printsupport/kernel/qprinterinfo.h
@@ -93,6 +93,9 @@ public:
QPrinter::DuplexMode defaultDuplexMode() const;
QList<QPrinter::DuplexMode> supportedDuplexModes() const;
+ QPrinter::ColorMode defaultColorMode() const;
+ QList<QPrinter::ColorMode> supportedColorModes() const;
+
static QStringList availablePrinterNames();
static QList<QPrinterInfo> availablePrinters();
diff --git a/src/printsupport/widgets/qcupsjobwidget_p.h b/src/printsupport/widgets/qcupsjobwidget_p.h
index 4b6b047e26..42da9c7580 100644
--- a/src/printsupport/widgets/qcupsjobwidget_p.h
+++ b/src/printsupport/widgets/qcupsjobwidget_p.h
@@ -113,7 +113,7 @@ private:
int m_savedPriority;
QCUPSSupport::JobSheets m_savedJobSheets;
- Q_DISABLE_COPY(QCupsJobWidget)
+ Q_DISABLE_COPY_MOVE(QCupsJobWidget)
};
QT_END_NAMESPACE
diff --git a/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc b/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc
index d127bdf8a5..9709deeccb 100644
--- a/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc
+++ b/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc
@@ -237,3 +237,16 @@ Could not create database object
//! [38]
QPSQLDriver::getResult: Query results lost - probably discarded on executing another SQL query.
//! [38]
+
+//! [39]
+CREATE TABLE "testTable" ("id" INTEGER);
+//! [39]
+
+//! [40]
+QString tableString("testTable");
+QSqlQuery q;
+// Create table query is not quoted, therefore it is mapped to lower case
+q.exec(QString("CREATE TABLE %1 (id INTEGER)").arg(tableString));
+// Call toLower() on the string so that it can be matched
+QSqlRecord rec = database.record(tableString.toLower());
+//! [40]
diff --git a/src/sql/doc/src/sql-driver.qdoc b/src/sql/doc/src/sql-driver.qdoc
index fd95e89812..cccce48bb3 100644
--- a/src/sql/doc/src/sql-driver.qdoc
+++ b/src/sql/doc/src/sql-driver.qdoc
@@ -381,6 +381,23 @@
multibyte enabled PostgreSQL server can be found in the PostgreSQL
Administrator Guide, Chapter 5.
+ \section3 QPSQL Case Sensitivity
+
+ PostgreSQL databases will only respect case sensitivity if the table or field
+ name is quoted when the table is created. So for example, a SQL query such
+ as:
+
+ \snippet code/doc_src_sql-driver.qdoc 39
+
+ will ensure that it can be accessed with the same case that was used. If the
+ table or field name is not quoted when created, the actual table name
+ or field name will be lower-case. When QSqlDatabase::record() or
+ QSqlDatabase::primaryIndex() access a table or field that was unquoted
+ when created, the name passed to the function must be lower-case to
+ ensure it is found. For example:
+
+ \snippet code/doc_src_sql-driver.qdoc 40
+
\section3 QPSQL BLOB Support
Binary Large Objects are supported through the \c BYTEA field type in
diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp
index 2c7b4b83db..d63a9e59a8 100644
--- a/src/sql/kernel/qsqldatabase.cpp
+++ b/src/sql/kernel/qsqldatabase.cpp
@@ -1088,6 +1088,11 @@ QStringList QSqlDatabase::tables(QSql::TableType type) const
Returns the primary index for table \a tablename. If no primary
index exists, an empty QSqlIndex is returned.
+ \note Some drivers, such as the \l {QPSQL Case Sensitivity}{QPSQL}
+ driver, may may require you to pass \a tablename in lower case if
+ the table was not quoted when created. See the
+ \l{sql-driver.html}{Qt SQL driver} documentation for more information.
+
\sa tables(), record()
*/
@@ -1102,6 +1107,11 @@ QSqlIndex QSqlDatabase::primaryIndex(const QString& tablename) const
the table (or view) called \a tablename. The order in which the
fields appear in the record is undefined. If no such table (or
view) exists, an empty record is returned.
+
+ \note Some drivers, such as the \l {QPSQL Case Sensitivity}{QPSQL}
+ driver, may may require you to pass \a tablename in lower case if
+ the table was not quoted when created. See the
+ \l{sql-driver.html}{Qt SQL driver} documentation for more information.
*/
QSqlRecord QSqlDatabase::record(const QString& tablename) const
@@ -1380,6 +1390,40 @@ QSqlDatabase QSqlDatabase::cloneDatabase(const QSqlDatabase &other, const QStrin
}
/*!
+ \since 5.13
+ \overload
+
+ Clones the database connection \a other and stores it as \a
+ connectionName. All the settings from the original database, e.g.
+ databaseName(), hostName(), etc., are copied across. Does nothing
+ if \a other is an invalid database. Returns the newly created
+ database connection.
+
+ \note The new connection has not been opened. Before using the new
+ connection, you must call open().
+
+ This overload is useful when cloning the database in another thread to the
+ one that is used by the database represented by \a other.
+*/
+
+QSqlDatabase QSqlDatabase::cloneDatabase(const QString &other, const QString &connectionName)
+{
+ const QConnectionDict *dict = dbDict();
+ Q_ASSERT(dict);
+
+ dict->lock.lockForRead();
+ QSqlDatabase otherDb = dict->value(other);
+ dict->lock.unlock();
+ if (!otherDb.isValid())
+ return QSqlDatabase();
+
+ QSqlDatabase db(otherDb.driverName());
+ db.d->copy(otherDb.d);
+ QSqlDatabasePrivate::addDatabase(db, connectionName);
+ return db;
+}
+
+/*!
\since 4.4
Returns the connection name, which may be empty. \note The
diff --git a/src/sql/kernel/qsqldatabase.h b/src/sql/kernel/qsqldatabase.h
index 3aadab9b2f..f233c72c19 100644
--- a/src/sql/kernel/qsqldatabase.h
+++ b/src/sql/kernel/qsqldatabase.h
@@ -118,6 +118,7 @@ public:
static QSqlDatabase addDatabase(QSqlDriver* driver,
const QString& connectionName = QLatin1String(defaultConnection));
static QSqlDatabase cloneDatabase(const QSqlDatabase &other, const QString& connectionName);
+ static QSqlDatabase cloneDatabase(const QString &other, const QString& connectionName);
static QSqlDatabase database(const QString& connectionName = QLatin1String(defaultConnection),
bool open = true);
static void removeDatabase(const QString& connectionName);
diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp
index 8c6ae382f6..7f7b81b05b 100644
--- a/src/sql/kernel/qsqldriver.cpp
+++ b/src/sql/kernel/qsqldriver.cpp
@@ -488,6 +488,8 @@ QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType ty
QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
const QSqlRecord &rec, bool preparedStatement) const
{
+ const auto tableNameString = tableName.isEmpty() ? QString()
+ : prepareIdentifier(tableName, QSqlDriver::TableName, this);
int i;
QString s;
s.reserve(128);
@@ -500,13 +502,12 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
if (s.isEmpty())
return s;
s.chop(2);
- s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName);
+ s = QLatin1String("SELECT ") + s + QLatin1String(" FROM ") + tableNameString;
break;
case WhereStatement:
{
- const QString tableNamePrefix = tableName.isEmpty()
- ? QString()
- : prepareIdentifier(tableName, QSqlDriver::TableName, this) + QLatin1Char('.');
+ const QString tableNamePrefix = tableNameString.isEmpty()
+ ? QString() : tableNameString + QLatin1Char('.');
for (int i = 0; i < rec.count(); ++i) {
if (!rec.isGenerated(i))
continue;
@@ -523,8 +524,7 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
break;
}
case UpdateStatement:
- s.append(QLatin1String("UPDATE ")).append(tableName).append(
- QLatin1String(" SET "));
+ s = s + QLatin1String("UPDATE ") + tableNameString + QLatin1String(" SET ");
for (i = 0; i < rec.count(); ++i) {
if (!rec.isGenerated(i))
continue;
@@ -541,10 +541,10 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName,
s.clear();
break;
case DeleteStatement:
- s.append(QLatin1String("DELETE FROM ")).append(tableName);
+ s = s + QLatin1String("DELETE FROM ") + tableNameString;
break;
case InsertStatement: {
- s.append(QLatin1String("INSERT INTO ")).append(tableName).append(QLatin1String(" ("));
+ s = s + QLatin1String("INSERT INTO ") + tableNameString + QLatin1String(" (");
QString vals;
for (i = 0; i < rec.count(); ++i) {
if (!rec.isGenerated(i))
diff --git a/src/sql/models/qsqlrelationaldelegate.h b/src/sql/models/qsqlrelationaldelegate.h
index ca5c46778f..2f16a4a54b 100644
--- a/src/sql/models/qsqlrelationaldelegate.h
+++ b/src/sql/models/qsqlrelationaldelegate.h
@@ -58,7 +58,7 @@ QT_REQUIRE_CONFIG(sqlmodel);
#include <QtCore/qmetaobject.h>
QT_BEGIN_NAMESPACE
-
+// ### Qt6: QStyledItemDelegate
class QSqlRelationalDelegate: public QItemDelegate
{
static int fieldIndex(const QSqlTableModel *const model,
diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp
index 1f590c4ab2..34be010474 100644
--- a/src/sql/models/qsqlrelationaltablemodel.cpp
+++ b/src/sql/models/qsqlrelationaltablemodel.cpp
@@ -626,8 +626,8 @@ QString QSqlRelationalTableModel::selectStatement() const
/*!
Returns a QSqlTableModel object for accessing the table for which
- \a column is a foreign key, or 0 if there is no relation for the
- given \a column.
+ \a column is a foreign key, or \nullptr if there is no relation for
+ the given \a column.
The returned object is owned by the QSqlRelationalTableModel.
@@ -636,12 +636,12 @@ QString QSqlRelationalTableModel::selectStatement() const
QSqlTableModel *QSqlRelationalTableModel::relationModel(int column) const
{
Q_D(const QSqlRelationalTableModel);
- if ( column < 0 || column >= d->relations.count())
- return 0;
+ if (column < 0 || column >= d->relations.count())
+ return nullptr;
QRelation &relation = const_cast<QSqlRelationalTableModelPrivate *>(d)->relations[column];
if (!relation.isValid())
- return 0;
+ return nullptr;
if (!relation.model)
relation.populateModel();
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index a33f76838f..98d6ddf882 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -607,6 +607,16 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in
return true;
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \reimp
+ */
+bool QStringListModel::clearItemData(const QModelIndex &index)
+{
+ return setData(index, QVariant(), Qt::EditRole);
+}
+#endif
+
/*!
This function simply calls QSqlQueryModel::setQuery(\a query).
You should normally not call it on a QSqlTableModel. Instead, use
diff --git a/src/sql/models/qsqltablemodel.h b/src/sql/models/qsqltablemodel.h
index 7acc7dc94d..eba27e60ec 100644
--- a/src/sql/models/qsqltablemodel.h
+++ b/src/sql/models/qsqltablemodel.h
@@ -74,6 +74,9 @@ public:
QSqlRecord record(int row) const;
QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ bool clearItemData(const QModelIndex &index) override;
+#endif
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
diff --git a/src/testlib/configure.json b/src/testlib/configure.json
index c464037205..df6132cdc2 100644
--- a/src/testlib/configure.json
+++ b/src/testlib/configure.json
@@ -5,6 +5,12 @@
],
"features": {
+ "testlib_selfcover": {
+ "label": "Coverage testing of testlib itself",
+ "purpose": "Gauges how thoroughly testlib's selftest exercises testlib's code",
+ "autoDetect": false,
+ "output": [ "publicFeature" ]
+ },
"itemmodeltester": {
"label": "Tester for item models",
"purpose": "Provides a utility to test item models.",
diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf
index 93a5ab393c..5fdf6d9415 100644
--- a/src/testlib/doc/qttestlib.qdocconf
+++ b/src/testlib/doc/qttestlib.qdocconf
@@ -27,7 +27,7 @@ qhp.QtTestLib.subprojects.classes.sortPages = true
tagfile = ../../../doc/qttestlib/qttestlib.tags
-depends += qtcore qtdoc qtwidgets qtgui qmake qtquick
+depends += qtcore qtdoc qtwidgets qtgui qmake qtqmltest
headerdirs += ..
diff --git a/src/testlib/doc/src/qttest-index.qdoc b/src/testlib/doc/src/qttest-index.qdoc
index 6e4f954034..23be46b431 100644
--- a/src/testlib/doc/src/qttest-index.qdoc
+++ b/src/testlib/doc/src/qttest-index.qdoc
@@ -75,11 +75,15 @@
\section1 Reference
- These are links to the API reference materials.
+ \list
+ \li \l{Qt Test C++ Classes}
+ \endlist
+
+ The \l {Qt Quick Test} module enables unit testing Qt Quick applications.
\list
- \li \l{Qt Test C++ Classes}{C++ Classes}
- \li \l{Qt Quick Test QML Types}{QML Types}
+ \li \l{Qt Quick Test QML Types}
+ \li \l{Qt Quick Test C++ API}
\endlist
*/
diff --git a/src/testlib/qabstractitemmodeltester.h b/src/testlib/qabstractitemmodeltester.h
index 757074c6ae..57b8f283bc 100644
--- a/src/testlib/qabstractitemmodeltester.h
+++ b/src/testlib/qabstractitemmodeltester.h
@@ -123,11 +123,11 @@ do { \
MODELTESTER_VERIFY(variant.canConvert<QFont>());
// General Purpose roles that should return a QColor or a QBrush
- variant = model->data(model->index(0, 0), Qt::BackgroundColorRole);
+ variant = model->data(model->index(0, 0), Qt::BackgroundRole);
if (variant.isValid())
MODELTESTER_VERIFY(variant.canConvert<QColor>() || variant.canConvert<QBrush>());
- variant = model->data(model->index(0, 0), Qt::TextColorRole);
+ variant = model->data(model->index(0, 0), Qt::ForegroundRole);
if (variant.isValid())
MODELTESTER_VERIFY(variant.canConvert<QColor>() || variant.canConvert<QBrush>());
diff --git a/src/testlib/qsignalspy.qdoc b/src/testlib/qsignalspy.qdoc
index 77affc9a4b..3352307d69 100644
--- a/src/testlib/qsignalspy.qdoc
+++ b/src/testlib/qsignalspy.qdoc
@@ -63,7 +63,7 @@
Constructs a new QSignalSpy that listens for emissions of the \a signal
from the QObject \a object. If QSignalSpy is not able to listen for a
- valid signal (for example, because \a object is null or \a signal does
+ valid signal (for example, because \a object is \nullptr or \a signal does
not denote a valid signal of \a object), an explanatory warning message
will be output using qWarning() and subsequent calls to \c isValid() will
return false.
@@ -77,7 +77,7 @@
Constructs a new QSignalSpy that listens for emissions of the \a signal
from the QObject \a object. If QSignalSpy is not able to listen for a
- valid signal (for example, because \a object is null or \a signal does
+ valid signal (for example, because \a object is \nullptr or \a signal does
not denote a valid signal of \a object), an explanatory warning message
will be output using qWarning() and subsequent calls to \c isValid() will
return false.
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h
index 28b62129b6..ebd94939ce 100644
--- a/src/testlib/qtest.h
+++ b/src/testlib/qtest.h
@@ -51,6 +51,7 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qcborcommon.h>
#include <QtCore/qdatetime.h>
+#include <QtCore/qabstractitemmodel.h>
#include <QtCore/qobject.h>
#include <QtCore/qvariant.h>
#include <QtCore/qurl.h>
@@ -128,6 +129,13 @@ template<> inline char *toString(const QChar &c)
return qstrdup(qPrintable(QString::fromLatin1("QChar: '%1' (0x%2)").arg(c).arg(QString::number(static_cast<int>(c.unicode()), 16))));
}
+template<> inline char *toString(const QModelIndex &idx)
+{
+ char msg[128];
+ qsnprintf(msg, sizeof(msg), "QModelIndex(%d,%d,%p,%p)", idx.row(), idx.column(), idx.internalPointer(), idx.model());
+ return qstrdup(msg);
+}
+
template<> inline char *toString(const QPoint &p)
{
char msg[128] = {'\0'};
@@ -366,27 +374,41 @@ QT_END_NAMESPACE
# define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__);
#endif
+// Hooks for coverage-testing of QTestLib itself:
+#if QT_CONFIG(testlib_selfcover) && defined(__COVERAGESCANNER__)
+struct QtCoverageScanner
+{
+ QtCoverageScanner(const char *name)
+ {
+ __coveragescanner_clear();
+ __coveragescanner_testname(name);
+ }
+ ~QtCoverageScanner()
+ {
+ __coveragescanner_save();
+ __coveragescanner_testname("");
+ }
+};
+#define TESTLIB_SELFCOVERAGE_START(name) QtCoverageScanner _qtCoverageScanner(name);
+#else
+#define TESTLIB_SELFCOVERAGE_START(name)
+#endif
+
#define QTEST_APPLESS_MAIN(TestObject) \
int main(int argc, char *argv[]) \
{ \
+ TESTLIB_SELFCOVERAGE_START(TestObject) \
TestObject tc; \
QTEST_SET_MAIN_SOURCE_PATH \
return QTest::qExec(&tc, argc, argv); \
}
#include <QtTest/qtestsystem.h>
-#include <set>
-
-#ifndef QT_NO_OPENGL
-# define QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \
- extern Q_TESTLIB_EXPORT std::set<QByteArray> *(*qgpu_features_ptr)(const QString &); \
- extern Q_GUI_EXPORT std::set<QByteArray> *qgpu_features(const QString &);
-# define QTEST_ADD_GPU_BLACKLIST_SUPPORT \
- qgpu_features_ptr = qgpu_features;
-#else
-# define QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
-# define QTEST_ADD_GPU_BLACKLIST_SUPPORT
-#endif
+
+// Two backwards-compatibility defines for an obsolete feature:
+#define QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
+#define QTEST_ADD_GPU_BLACKLIST_SUPPORT
+// ### Qt 6: fully remove these.
#if defined(QT_NETWORK_LIB)
# include <QtTest/qtest_network.h>
@@ -403,15 +425,12 @@ int main(int argc, char *argv[]) \
#endif
#define QTEST_MAIN(TestObject) \
-QT_BEGIN_NAMESPACE \
-QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \
-QT_END_NAMESPACE \
int main(int argc, char *argv[]) \
{ \
+ TESTLIB_SELFCOVERAGE_START(#TestObject) \
QApplication app(argc, argv); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
QTEST_DISABLE_KEYPAD_NAVIGATION \
- QTEST_ADD_GPU_BLACKLIST_SUPPORT \
TestObject tc; \
QTEST_SET_MAIN_SOURCE_PATH \
return QTest::qExec(&tc, argc, argv); \
@@ -422,14 +441,11 @@ int main(int argc, char *argv[]) \
#include <QtTest/qtest_gui.h>
#define QTEST_MAIN(TestObject) \
-QT_BEGIN_NAMESPACE \
-QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \
-QT_END_NAMESPACE \
int main(int argc, char *argv[]) \
{ \
+ TESTLIB_SELFCOVERAGE_START(#TestObject) \
QGuiApplication app(argc, argv); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
- QTEST_ADD_GPU_BLACKLIST_SUPPORT \
TestObject tc; \
QTEST_SET_MAIN_SOURCE_PATH \
return QTest::qExec(&tc, argc, argv); \
@@ -440,6 +456,7 @@ int main(int argc, char *argv[]) \
#define QTEST_MAIN(TestObject) \
int main(int argc, char *argv[]) \
{ \
+ TESTLIB_SELFCOVERAGE_START(#TestObject) \
QCoreApplication app(argc, argv); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
TestObject tc; \
@@ -452,6 +469,7 @@ int main(int argc, char *argv[]) \
#define QTEST_GUILESS_MAIN(TestObject) \
int main(int argc, char *argv[]) \
{ \
+ TESTLIB_SELFCOVERAGE_START(#TestObject) \
QCoreApplication app(argc, argv); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
TestObject tc; \
diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp
index ae2913da9a..886f1f75b9 100644
--- a/src/testlib/qtestblacklist.cpp
+++ b/src/testlib/qtestblacklist.cpp
@@ -221,22 +221,6 @@ static bool checkCondition(const QByteArray &condition)
static bool ignoreAll = false;
static std::set<QByteArray> *ignoredTests = 0;
-static std::set<QByteArray> *gpuFeatures = 0;
-
-Q_TESTLIB_EXPORT std::set<QByteArray> *(*qgpu_features_ptr)(const QString &) = 0;
-
-static bool isGPUTestBlacklisted(const char *slot, const char *data = 0)
-{
- const QByteArray disableKey = QByteArrayLiteral("disable_") + QByteArray(slot);
- if (gpuFeatures->find(disableKey) != gpuFeatures->end()) {
- QByteArray msg = QByteArrayLiteral("Skipped due to GPU blacklist: ") + disableKey;
- if (data)
- msg += ':' + QByteArray(data);
- QTest::qSkip(msg.constData(), __FILE__, __LINE__);
- return true;
- }
- return false;
-}
namespace QTestPrivate {
@@ -276,17 +260,6 @@ void parseBlackList()
}
}
-void parseGpuBlackList()
-{
- if (!qgpu_features_ptr)
- return;
- QString filename = QTest::qFindTestData(QStringLiteral("GPU_BLACKLIST"));
- if (filename.isEmpty())
- return;
- if (!gpuFeatures)
- gpuFeatures = qgpu_features_ptr(filename);
-}
-
void checkBlackLists(const char *slot, const char *data)
{
bool ignore = ignoreAll;
@@ -302,21 +275,8 @@ void checkBlackLists(const char *slot, const char *data)
}
QTestResult::setBlacklistCurrentTest(ignore);
-
- // Tests blacklisted in GPU_BLACKLIST are to be skipped. Just ignoring the result is
- // not sufficient since these are expected to crash or behave in undefined ways.
- if (!ignore && gpuFeatures) {
- QByteArray s_gpu = slot;
- ignore = isGPUTestBlacklisted(s_gpu, data);
- if (!ignore && data) {
- s_gpu += ':';
- s_gpu += data;
- isGPUTestBlacklisted(s_gpu);
- }
- }
-}
-
}
+} // QTestPrivate
QT_END_NAMESPACE
diff --git a/src/testlib/qtestblacklist_p.h b/src/testlib/qtestblacklist_p.h
index 08ce052231..4522c64992 100644
--- a/src/testlib/qtestblacklist_p.h
+++ b/src/testlib/qtestblacklist_p.h
@@ -58,7 +58,6 @@ QT_BEGIN_NAMESPACE
namespace QTestPrivate {
// Export functions so they can also be used by QQuickTest
Q_TESTLIB_EXPORT void parseBlackList();
- Q_TESTLIB_EXPORT void parseGpuBlackList();
Q_TESTLIB_EXPORT void checkBlackLists(const char *slot, const char *data);
}
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 0c935a1f1c..1f69429053 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -52,6 +52,7 @@
#include <QtCore/qfileinfo.h>
#include <QtCore/qdir.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qfloat16.h>
#include <QtCore/qlibraryinfo.h>
#include <QtCore/private/qtools_p.h>
#include <QtCore/qdiriterator.h>
@@ -249,7 +250,7 @@ static void stackTrace()
static bool installCoverageTool(const char * appname, const char * testname)
{
-#ifdef __COVERAGESCANNER__
+#if defined(__COVERAGESCANNER__) && !QT_CONFIG(testlib_selfcover)
if (!qEnvironmentVariableIsEmpty("QT_TESTCOCOON_ACTIVE"))
return false;
// Set environment variable QT_TESTCOCOON_ACTIVE to prevent an eventual subtest from
@@ -286,74 +287,75 @@ namespace QTestPrivate
namespace QTest
{
- class WatchDog;
+class WatchDog;
- static QObject *currentTestObject = 0;
- static QString mainSourcePath;
+static QObject *currentTestObject = 0;
+static QString mainSourcePath;
#if defined(Q_OS_MACOS)
- bool macNeedsActivate = false;
- IOPMAssertionID powerID;
+bool macNeedsActivate = false;
+IOPMAssertionID powerID;
#endif
- class TestMethods {
- Q_DISABLE_COPY(TestMethods)
- public:
- typedef std::vector<QMetaMethod> MetaMethods;
+class TestMethods {
+public:
+ Q_DISABLE_COPY_MOVE(TestMethods)
- explicit TestMethods(const QObject *o, const MetaMethods &m = MetaMethods());
+ typedef std::vector<QMetaMethod> MetaMethods;
- void invokeTests(QObject *testObject) const;
+ explicit TestMethods(const QObject *o, const MetaMethods &m = MetaMethods());
- static QMetaMethod findMethod(const QObject *obj, const char *signature);
+ void invokeTests(QObject *testObject) const;
- private:
- bool invokeTest(int index, const char *data, WatchDog *watchDog) const;
- void invokeTestOnData(int index) const;
+ static QMetaMethod findMethod(const QObject *obj, const char *signature);
- QMetaMethod m_initTestCaseMethod; // might not exist, check isValid().
- QMetaMethod m_initTestCaseDataMethod;
- QMetaMethod m_cleanupTestCaseMethod;
- QMetaMethod m_initMethod;
- QMetaMethod m_cleanupMethod;
+private:
+ bool invokeTest(int index, const char *data, WatchDog *watchDog) const;
+ void invokeTestOnData(int index) const;
- MetaMethods m_methods;
- };
+ QMetaMethod m_initTestCaseMethod; // might not exist, check isValid().
+ QMetaMethod m_initTestCaseDataMethod;
+ QMetaMethod m_cleanupTestCaseMethod;
+ QMetaMethod m_initMethod;
+ QMetaMethod m_cleanupMethod;
- TestMethods::TestMethods(const QObject *o, const MetaMethods &m)
- : m_initTestCaseMethod(TestMethods::findMethod(o, "initTestCase()"))
- , m_initTestCaseDataMethod(TestMethods::findMethod(o, "initTestCase_data()"))
- , m_cleanupTestCaseMethod(TestMethods::findMethod(o, "cleanupTestCase()"))
- , m_initMethod(TestMethods::findMethod(o, "init()"))
- , m_cleanupMethod(TestMethods::findMethod(o, "cleanup()"))
- , m_methods(m)
- {
- if (m.empty()) {
- const QMetaObject *metaObject = o->metaObject();
- const int count = metaObject->methodCount();
- m_methods.reserve(count);
- for (int i = 0; i < count; ++i) {
- const QMetaMethod me = metaObject->method(i);
- if (isValidSlot(me))
- m_methods.push_back(me);
- }
+ MetaMethods m_methods;
+};
+
+TestMethods::TestMethods(const QObject *o, const MetaMethods &m)
+ : m_initTestCaseMethod(TestMethods::findMethod(o, "initTestCase()"))
+ , m_initTestCaseDataMethod(TestMethods::findMethod(o, "initTestCase_data()"))
+ , m_cleanupTestCaseMethod(TestMethods::findMethod(o, "cleanupTestCase()"))
+ , m_initMethod(TestMethods::findMethod(o, "init()"))
+ , m_cleanupMethod(TestMethods::findMethod(o, "cleanup()"))
+ , m_methods(m)
+{
+ if (m.empty()) {
+ const QMetaObject *metaObject = o->metaObject();
+ const int count = metaObject->methodCount();
+ m_methods.reserve(count);
+ for (int i = 0; i < count; ++i) {
+ const QMetaMethod me = metaObject->method(i);
+ if (isValidSlot(me))
+ m_methods.push_back(me);
}
}
+}
- QMetaMethod TestMethods::findMethod(const QObject *obj, const char *signature)
- {
- const QMetaObject *metaObject = obj->metaObject();
- const int funcIndex = metaObject->indexOfMethod(signature);
- return funcIndex >= 0 ? metaObject->method(funcIndex) : QMetaMethod();
- }
+QMetaMethod TestMethods::findMethod(const QObject *obj, const char *signature)
+{
+ const QMetaObject *metaObject = obj->metaObject();
+ const int funcIndex = metaObject->indexOfMethod(signature);
+ return funcIndex >= 0 ? metaObject->method(funcIndex) : QMetaMethod();
+}
- static int keyDelay = -1;
- static int mouseDelay = -1;
- static int eventDelay = -1;
+static int keyDelay = -1;
+static int mouseDelay = -1;
+static int eventDelay = -1;
#if QT_CONFIG(thread)
- static int timeout = -1;
+static int timeout = -1;
#endif
- static bool noCrashHandler = false;
+static bool noCrashHandler = false;
/*! \internal
Invoke a method of the object without generating warning if the method does not exist
@@ -500,7 +502,7 @@ static void qPrintDataTags(FILE *stream)
}
}
-static int qToInt(char *str)
+static int qToInt(const char *str)
{
char *pEnd;
int l = (int)strtol(str, &pEnd, 10);
@@ -511,7 +513,7 @@ static int qToInt(char *str)
return l;
}
-Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
+Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, const char *const argv[], bool qml)
{
int logFormat = -1; // Not set
const char *logFilename = 0;
@@ -815,9 +817,9 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
// we load the QML files. So just store the data for now.
int colon = -1;
int offset;
- for (offset = 0; *(argv[i]+offset); ++offset) {
- if (*(argv[i]+offset) == ':') {
- if (*(argv[i]+offset+1) == ':') {
+ for (offset = 0; argv[i][offset]; ++offset) {
+ if (argv[i][offset] == ':') {
+ if (argv[i][offset + 1] == ':') {
// "::" is used as a test name separator.
// e.g. "ClickTests::test_click:row1".
++offset;
@@ -864,6 +866,11 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
QTestLog::addLogger(QTestLog::Plain, logFilename);
}
+// Temporary, backwards compatibility, until qtdeclarative's use of it is converted
+Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) {
+ qtest_qParseArgs(argc, const_cast<const char *const *>(argv), qml);
+}
+
QBenchmarkResult qMedian(const QVector<QBenchmarkResult> &container)
{
const int count = container.count();
@@ -1214,7 +1221,9 @@ char *formatString(const char *prefix, const char *suffix, size_t numArguments,
Returns a pointer to a string that is the string \a ba represented
as a space-separated sequence of hex characters. If the input is
considered too long, it is truncated. A trucation is indicated in
- the returned string as an ellipsis at the end.
+ the returned string as an ellipsis at the end. The caller has
+ ownership of the returned pointer and must ensure it is later passed
+ to operator delete[].
\a length is the length of the string \a ba.
*/
@@ -1616,7 +1625,7 @@ FatalSignalHandler::~FatalSignalHandler()
// Helper class for resolving symbol names by dynamically loading "dbghelp.dll".
class DebugSymbolResolver
{
- Q_DISABLE_COPY(DebugSymbolResolver)
+ Q_DISABLE_COPY_MOVE(DebugSymbolResolver)
public:
struct Symbol {
Symbol() : name(nullptr), address(0) {}
@@ -1832,8 +1841,6 @@ void QTest::qInit(QObject *testObject, int argc, char **argv)
#endif
QTestPrivate::parseBlackList();
- QTestPrivate::parseGpuBlackList();
-
QTestResult::reset();
QTEST_ASSERT(testObject);
@@ -2183,13 +2190,12 @@ QString QTest::qFindTestData(const QString& base, const char *file, int line, co
if (found.isEmpty()) {
const char *testObjectName = QTestResult::currentTestObjectName();
if (testObjectName) {
- QString testsPath = QLibraryInfo::location(QLibraryInfo::TestsPath);
- QString candidate = QString::fromLatin1("%1/%2/%3")
+ const QString testsPath = QLibraryInfo::location(QLibraryInfo::TestsPath);
+ const QString candidate = QString::fromLatin1("%1/%2/%3")
.arg(testsPath, QFile::decodeName(testObjectName).toLower(), base);
if (QFileInfo::exists(candidate)) {
found = candidate;
- }
- else if (QTestLog::verboseLevel() >= 2) {
+ } else if (QTestLog::verboseLevel() >= 2) {
QTestLog::info(qPrintable(
QString::fromLatin1("testdata %1 not found in tests install path [%2]; "
"checking next location")
@@ -2211,11 +2217,10 @@ QString QTest::qFindTestData(const QString& base, const char *file, int line, co
}
const QString canonicalPath = srcdir.canonicalFilePath();
- QString candidate = QString::fromLatin1("%1/%2").arg(canonicalPath, base);
+ const QString candidate = QString::fromLatin1("%1/%2").arg(canonicalPath, base);
if (!canonicalPath.isEmpty() && QFileInfo::exists(candidate)) {
found = candidate;
- }
- else if (QTestLog::verboseLevel() >= 2) {
+ } else if (QTestLog::verboseLevel() >= 2) {
QTestLog::info(qPrintable(
QString::fromLatin1("testdata %1 not found relative to source path [%2]")
.arg(base, QDir::toNativeSeparators(candidate))),
@@ -2225,31 +2230,48 @@ QString QTest::qFindTestData(const QString& base, const char *file, int line, co
// 4. Try resources
if (found.isEmpty()) {
- QString candidate = QString::fromLatin1(":/%1").arg(base);
- if (QFileInfo::exists(candidate))
+ const QString candidate = QString::fromLatin1(":/%1").arg(base);
+ if (QFileInfo::exists(candidate)) {
found = candidate;
+ } else if (QTestLog::verboseLevel() >= 2) {
+ QTestLog::info(qPrintable(
+ QString::fromLatin1("testdata %1 not found in resources [%2]")
+ .arg(base, QDir::toNativeSeparators(candidate))),
+ file, line);
+ }
}
// 5. Try current directory
if (found.isEmpty()) {
const QString candidate = QDir::currentPath() + QLatin1Char('/') + base;
- if (QFileInfo::exists(candidate))
+ if (QFileInfo::exists(candidate)) {
found = candidate;
+ } else if (QTestLog::verboseLevel() >= 2) {
+ QTestLog::info(qPrintable(
+ QString::fromLatin1("testdata %1 not found in current directory [%2]")
+ .arg(base, QDir::toNativeSeparators(candidate))),
+ file, line);
+ }
}
// 6. Try main source directory
if (found.isEmpty()) {
- QString candidate = QTest::mainSourcePath % QLatin1Char('/') % base;
- if (QFileInfo::exists(candidate))
+ const QString candidate = QTest::mainSourcePath % QLatin1Char('/') % base;
+ if (QFileInfo::exists(candidate)) {
found = candidate;
+ } else if (QTestLog::verboseLevel() >= 2) {
+ QTestLog::info(qPrintable(
+ QString::fromLatin1("testdata %1 not found in main source directory [%2]")
+ .arg(base, QDir::toNativeSeparators(candidate))),
+ file, line);
+ }
}
if (found.isEmpty()) {
QTest::qWarn(qPrintable(
QString::fromLatin1("testdata %1 could not be located!").arg(base)),
file, line);
- }
- else if (QTestLog::verboseLevel() >= 1) {
+ } else if (QTestLog::verboseLevel() >= 1) {
QTestLog::info(qPrintable(
QString::fromLatin1("testdata %1 was located at %2").arg(base, QDir::toNativeSeparators(found))),
file, line);
@@ -2323,7 +2345,7 @@ void QTest::addColumnInternal(int id, const char *name)
*/
QTestData &QTest::newRow(const char *dataTag)
{
- QTEST_ASSERT_X(dataTag, "QTest::newRow()", "Data tag can not be null");
+ QTEST_ASSERT_X(dataTag, "QTest::newRow()", "Data tag cannot be null");
QTestTable *tbl = QTestTable::currentTestTable();
QTEST_ASSERT_X(tbl, "QTest::newRow()", "Cannot add testdata outside of a _data slot.");
QTEST_ASSERT_X(tbl->elementCount(), "QTest::newRow()", "Must add columns before attempting to add rows.");
@@ -2497,6 +2519,16 @@ bool QTest::compare_helper(bool success, const char *failureMsg,
return QTestResult::compare(success, failureMsg, val1, val2, actual, expected, file, line);
}
+/*! \fn bool QTest::qCompare(const qfloat16 &t1, const qfloat16 &t2, const char *actual, const char *expected, const char *file, int line)
+ \internal
+ */
+bool QTest::qCompare(qfloat16 const &t1, qfloat16 const &t2, const char *actual, const char *expected,
+ const char *file, int line)
+{
+ return compare_helper(qFuzzyCompare(t1, t2), "Compared qfloat16s are not the same (fuzzy compare)",
+ toString(t1), toString(t2), actual, expected, file, line);
+}
+
/*! \fn bool QTest::qCompare(const float &t1, const float &t2, const char *actual, const char *expected, const char *file, int line)
\internal
*/
@@ -2619,6 +2651,13 @@ template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE>(const TYPE &t) \
TO_STRING_FLOAT(float, %g)
TO_STRING_FLOAT(double, %.12lg)
+template <> Q_TESTLIB_EXPORT char *QTest::toString<qfloat16>(const qfloat16 &t)
+{
+ char *msg = new char[16];
+ qsnprintf(msg, 16, "%.3g", static_cast<float>(t));
+ return msg;
+}
+
template <> Q_TESTLIB_EXPORT char *QTest::toString<char>(const char &t)
{
unsigned char c = static_cast<unsigned char>(t);
diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h
index 5fed9d6bcc..5d566b835e 100644
--- a/src/testlib/qtestcase.h
+++ b/src/testlib/qtestcase.h
@@ -57,6 +57,7 @@
QT_BEGIN_NAMESPACE
+class qfloat16;
class QRegularExpression;
#define QVERIFY(statement) \
@@ -67,17 +68,17 @@ do {\
#define QFAIL(message) \
do {\
- QTest::qFail(message, __FILE__, __LINE__);\
+ QTest::qFail(static_cast<const char *>(message), __FILE__, __LINE__);\
return;\
} while (false)
#define QVERIFY2(statement, description) \
do {\
if (statement) {\
- if (!QTest::qVerify(true, #statement, (description), __FILE__, __LINE__))\
+ if (!QTest::qVerify(true, #statement, static_cast<const char *>(description), __FILE__, __LINE__))\
return;\
} else {\
- if (!QTest::qVerify(false, #statement, (description), __FILE__, __LINE__))\
+ if (!QTest::qVerify(false, #statement, static_cast<const char *>(description), __FILE__, __LINE__))\
return;\
}\
} while (false)
@@ -184,7 +185,7 @@ do { \
#define QSKIP_INTERNAL(statement) \
do {\
- QTest::qSkip(statement, __FILE__, __LINE__);\
+ QTest::qSkip(static_cast<const char *>(statement), __FILE__, __LINE__);\
return;\
} while (false)
@@ -200,7 +201,7 @@ do {\
#define QEXPECT_FAIL(dataIndex, comment, mode)\
do {\
- if (!QTest::qExpectFail(dataIndex, comment, QTest::mode, __FILE__, __LINE__))\
+ if (!QTest::qExpectFail(dataIndex, static_cast<const char *>(comment), QTest::mode, __FILE__, __LINE__))\
return;\
} while (false)
@@ -217,7 +218,7 @@ do {\
} while (false)
#define QWARN(msg)\
- QTest::qWarn(msg, __FILE__, __LINE__)
+ QTest::qWarn(static_cast<const char *>(msg), __FILE__, __LINE__)
#ifdef QT_TESTCASE_BUILDDIR
# define QFINDTESTDATA(basepath)\
@@ -361,6 +362,9 @@ namespace QTest
}
#endif
+ Q_TESTLIB_EXPORT bool qCompare(qfloat16 const &t1, qfloat16 const &t2,
+ const char *actual, const char *expected, const char *file, int line);
+
Q_TESTLIB_EXPORT bool qCompare(float const &t1, float const &t2,
const char *actual, const char *expected, const char *file, int line);
@@ -405,6 +409,7 @@ namespace QTest
QTEST_COMPARE_DECL(float)
QTEST_COMPARE_DECL(double)
+ QTEST_COMPARE_DECL(qfloat16)
QTEST_COMPARE_DECL(char)
QTEST_COMPARE_DECL(signed char)
QTEST_COMPARE_DECL(unsigned char)
diff --git a/src/testlib/qtestcorelist_p.h b/src/testlib/qtestcorelist_p.h
index 5943695876..4d080f6758 100644
--- a/src/testlib/qtestcorelist_p.h
+++ b/src/testlib/qtestcorelist_p.h
@@ -66,9 +66,6 @@ class QTestCoreList
void addToList(T **list);
T *nextElement();
T *previousElement();
- int count(T *list);
- int count();
-
private:
T *next;
T *prev;
@@ -121,20 +118,6 @@ T *QTestCoreList<T>::previousElement()
return prev;
}
-template <class T>
-int QTestCoreList<T>::count()
-{
- int numOfElements = 0;
- T *it = next;
-
- while (it) {
- ++numOfElements;
- it = it->nextElement();
- }
-
- return numOfElements;
-}
-
QT_END_NAMESPACE
#endif
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp
index 57bb7d95a7..faef3912c4 100644
--- a/src/testlib/qtestlog.cpp
+++ b/src/testlib/qtestlog.cpp
@@ -74,6 +74,10 @@ QT_BEGIN_NAMESPACE
static void saveCoverageTool(const char * appname, bool testfailed, bool installedTestCoverage)
{
#ifdef __COVERAGESCANNER__
+# if QT_CONFIG(testlib_selfcover)
+ __coveragescanner_teststate(QTestLog::failCount() > 0 ? "FAILED" :
+ QTestLog::passCount() > 0 ? "PASSED" : "SKIPPED");
+# else
if (!installedTestCoverage)
return;
// install again to make sure the filename is correct.
@@ -84,6 +88,7 @@ static void saveCoverageTool(const char * appname, bool testfailed, bool install
__coveragescanner_testname("");
__coveragescanner_clear();
unsetenv("QT_TESTCOCOON_ACTIVE");
+# endif // testlib_selfcover
#else
Q_UNUSED(appname);
Q_UNUSED(testfailed);
diff --git a/src/testlib/selfcover.pri b/src/testlib/selfcover.pri
new file mode 100644
index 0000000000..7de50ba6e6
--- /dev/null
+++ b/src/testlib/selfcover.pri
@@ -0,0 +1,28 @@
+# Configuration for testlib and its tests, to instrument with
+# FrogLogic's Squish CoCo (cf. testcocoon.prf, which handles similar
+# for general code; but testlib needs special handling).
+
+# Only for use when feature testlib_selfcover is enabled:
+!qtConfig(testlib_selfcover): return()
+
+# This enables verification that testlib itself is adequately tested,
+# as a grounds for trusting that testing with it is useful.
+# Exclude all non-testlib source from coverage instrumentation:
+COVERAGE_OPTIONS = --cs-exclude-file-abs-wildcard=$$QT_SOURCE_TREE/*
+COVERAGE_OPTIONS += --cs-include-file-abs-wildcard=*/src/testlib/*
+COVERAGE_OPTIONS += --cs-mcc # enable Multiple Condition Coverage
+COVERAGE_OPTIONS += --cs-mcdc # enable Multiple Condition / Decision Coverage
+# (recommended for ISO 26262 ASIL A, B and C -- highly recommended for ASIL D)
+# https://doc.froglogic.com/squish-coco/4.1/codecoverage.html#sec%3Amcdc
+
+QMAKE_CFLAGS += $$COVERAGE_OPTIONS
+QMAKE_CXXFLAGS += $$COVERAGE_OPTIONS
+QMAKE_LFLAGS += $$COVERAGE_OPTIONS
+
+# FIXME: relies on QMAKE_* being just the command-names, with no path prefix
+QMAKE_CC = cs$$QMAKE_CC
+QMAKE_CXX = cs$$QMAKE_CXX
+QMAKE_LINK = cs$$QMAKE_LINK
+QMAKE_LINK_SHLIB = cs$$QMAKE_LINK_SHLIB
+QMAKE_AR = cs$$QMAKE_AR
+QMAKE_LIB = cs$$QMAKE_LIB
diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro
index 34bb581e02..f52a913a08 100644
--- a/src/testlib/testlib.pro
+++ b/src/testlib/testlib.pro
@@ -146,4 +146,5 @@ mac {
!qtHaveModule(network): HEADERSCLEAN_EXCLUDE += qtest_network.h
+include(selfcover.pri)
load(qt_module)
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 20b1befc38..3af5237f3d 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -1400,8 +1400,8 @@ bool updateAndroidManifest(Options &options)
options.packageName = reader.attributes().value(QLatin1String("package")).toString();
} else if (reader.name() == QLatin1String("uses-sdk")) {
if (reader.attributes().hasAttribute(QLatin1String("android:minSdkVersion")))
- if (reader.attributes().value(QLatin1String("android:minSdkVersion")).toInt() < 16) {
- fprintf(stderr, "Invalid minSdkVersion version, minSdkVersion must be >= 16\n");
+ if (reader.attributes().value(QLatin1String("android:minSdkVersion")).toInt() < 21) {
+ fprintf(stderr, "Invalid minSdkVersion version, minSdkVersion must be >= 21\n");
return false;
}
} else if ((reader.name() == QLatin1String("application") ||
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index fd76646f4c..02c1fbd394 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -619,7 +619,7 @@ void Generator::generateCode()
fprintf(out, "// a) You are using a NOTIFY signal that does not exist. Fix it.\n");
fprintf(out, "// b) You are using a NOTIFY signal that does exist (in a parent class) but has a non-empty parameter list. This is a moc limitation.\n");
fprintf(out, "Q_DECL_UNUSED static void checkNotifySignalValidity_%s(%s *t) {\n", qualifiedClassNameIdentifier.constData(), cdef->qualified.constData());
- for (const QByteArray &nonClassSignal : cdef->nonClassSignalList)
+ for (const QByteArray &nonClassSignal : qAsConst(cdef->nonClassSignalList))
fprintf(out, " t->%s();\n", nonClassSignal.constData());
fprintf(out, "}\n");
}
@@ -1549,16 +1549,16 @@ void Generator::generateSignal(FunctionDef *def,int index)
fprintf(out, "nullptr");
} else {
if (def->returnTypeIsVolatile)
- fprintf(out, "const_cast<void*>(reinterpret_cast<const volatile void*>(&_t0))");
+ fprintf(out, "const_cast<void*>(reinterpret_cast<const volatile void*>(std::addressof(_t0)))");
else
- fprintf(out, "const_cast<void*>(reinterpret_cast<const void*>(&_t0))");
+ fprintf(out, "const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t0)))");
}
int i;
for (i = 1; i < offset; ++i)
if (i <= def->arguments.count() && def->arguments.at(i - 1).type.isVolatile)
- fprintf(out, ", const_cast<void*>(reinterpret_cast<const volatile void*>(&_t%d))", i);
+ fprintf(out, ", const_cast<void*>(reinterpret_cast<const volatile void*>(std::addressof(_t%d)))", i);
else
- fprintf(out, ", const_cast<void*>(reinterpret_cast<const void*>(&_t%d))", i);
+ fprintf(out, ", const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t%d)))", i);
fprintf(out, " };\n");
fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(), index);
if (def->normalizedType != "void")
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 7272df4265..5d777ece2e 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -992,7 +992,7 @@ void Moc::generate(FILE *out)
fprintf(out, "** WARNING! All changes made in this file will be lost!\n"
"*****************************************************************************/\n\n");
-
+ fprintf(out, "#include <memory>\n"); // For std::addressof
if (!noInclude) {
if (includePath.size() && !includePath.endsWith('/'))
includePath += '/';
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index d98c73e1a0..d6482f4e44 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -83,57 +83,53 @@ Q_DECLARE_TYPEINFO(ArgumentDef, Q_MOVABLE_TYPE);
struct FunctionDef
{
- FunctionDef(): returnTypeIsVolatile(false), access(Private), isConst(false), isVirtual(false), isStatic(false),
- inlineCode(false), wasCloned(false), isCompat(false), isInvokable(false),
- isScriptable(false), isSlot(false), isSignal(false), isPrivateSignal(false),
- isConstructor(false), isDestructor(false), isAbstract(false), revision(0) {}
Type type;
+ QVector<ArgumentDef> arguments;
QByteArray normalizedType;
QByteArray tag;
QByteArray name;
- bool returnTypeIsVolatile;
-
- QVector<ArgumentDef> arguments;
+ QByteArray inPrivateClass;
enum Access { Private, Protected, Public };
- Access access;
- bool isConst;
- bool isVirtual;
- bool isStatic;
- bool inlineCode;
- bool wasCloned;
-
- QByteArray inPrivateClass;
- bool isCompat;
- bool isInvokable;
- bool isScriptable;
- bool isSlot;
- bool isSignal;
- bool isPrivateSignal;
- bool isConstructor;
- bool isDestructor;
- bool isAbstract;
-
- int revision;
+ Access access = Private;
+ int revision = 0;
+
+ bool isConst = false;
+ bool isVirtual = false;
+ bool isStatic = false;
+ bool inlineCode = false;
+ bool wasCloned = false;
+
+ bool returnTypeIsVolatile = false;
+
+ bool isCompat = false;
+ bool isInvokable = false;
+ bool isScriptable = false;
+ bool isSlot = false;
+ bool isSignal = false;
+ bool isPrivateSignal = false;
+ bool isConstructor = false;
+ bool isDestructor = false;
+ bool isAbstract = false;
};
Q_DECLARE_TYPEINFO(FunctionDef, Q_MOVABLE_TYPE);
struct PropertyDef
{
- PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec), revision(0){}
- QByteArray name, type, member, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass;
- int notifyId; // -1 means no notifyId, >= 0 means signal defined in this class, < -1 means signal not defined in this class
- bool constant;
- bool final;
- enum Specification { ValueSpec, ReferenceSpec, PointerSpec };
- Specification gspec;
bool stdCppSet() const {
QByteArray s("set");
s += toupper(name[0]);
s += name.mid(1);
return (s == write);
}
- int revision;
+
+ QByteArray name, type, member, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass;
+ int notifyId = -1; // -1 means no notifyId, >= 0 means signal defined in this class, < -1 means signal not defined in this class
+ enum Specification { ValueSpec, ReferenceSpec, PointerSpec };
+ Specification gspec = ValueSpec;
+ int revision = 0;
+ bool constant = false;
+ bool final = false;
};
Q_DECLARE_TYPEINFO(PropertyDef, Q_MOVABLE_TYPE);
@@ -169,9 +165,6 @@ struct ClassDef : BaseDef {
};
QVector<QVector<Interface> >interfaceList;
- bool hasQObject = false;
- bool hasQGadget = false;
-
struct PluginData {
QByteArray iid;
QMap<QString, QJsonArray> metaArgs;
@@ -181,11 +174,14 @@ struct ClassDef : BaseDef {
QVector<FunctionDef> constructorList;
QVector<FunctionDef> signalList, slotList, methodList, publicList;
QVector<QByteArray> nonClassSignalList;
- int notifyableProperties = 0;
QVector<PropertyDef> propertyList;
+ int notifyableProperties = 0;
int revisionedMethods = 0;
int revisionedProperties = 0;
+ bool hasQObject = false;
+ bool hasQGadget = false;
+
};
Q_DECLARE_TYPEINFO(ClassDef, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(ClassDef::Interface, Q_MOVABLE_TYPE);
diff --git a/src/tools/moc/util/generate.sh b/src/tools/moc/util/generate.sh
index 3894be1309..5460d28924 100755
--- a/src/tools/moc/util/generate.sh
+++ b/src/tools/moc/util/generate.sh
@@ -27,6 +27,8 @@
##
#############################################################################
+set -ex
+
qmake
make
cat licenseheader.txt > ../keywords.cpp
diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
index ab7726a01f..ea410cd257 100644
--- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -326,7 +326,6 @@ static void writeArgList(QTextStream &ts, const QStringList &argNames,
// yes, starting from 1
for (int i = 1; i < outputArgs.count(); ++i) {
const QDBusIntrospection::Argument &arg = outputArgs.at(i);
- QString name = arg.name;
if (!first)
ts << ", ";
@@ -531,8 +530,6 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
// properties:
for (const QDBusIntrospection::Property &property : interface->properties) {
QByteArray type = qtTypeName(property.type, property.annotations);
- QString templateType = templateArg(type);
- QString constRefType = constRefArg(type);
QString getter = propertyGetter(property);
QString setter = propertySetter(property);
diff --git a/src/tools/qfloat16-tables/gen_qfloat16_tables.cpp b/src/tools/qfloat16-tables/gen_qfloat16_tables.cpp
index f5051e25fc..17fc978039 100644
--- a/src/tools/qfloat16-tables/gen_qfloat16_tables.cpp
+++ b/src/tools/qfloat16-tables/gen_qfloat16_tables.cpp
@@ -68,7 +68,7 @@ qint32 main(qint32 argc, char **argv)
return -1;
}
- QFile fid(argv[1]);
+ QFile fid(QFile::decodeName(argv[1]));
if (!fid.open(QIODevice::WriteOnly | QIODevice::Text)) {
qWarning() << "Abort: Failed to open/create file" << fid.fileName();
return -1;
@@ -79,6 +79,7 @@ qint32 main(qint32 argc, char **argv)
fid.write("#include <QtCore/qfloat16.h>\n\n");
fid.write("QT_BEGIN_NAMESPACE\n\n");
+ fid.write("#if !defined(__F16C__) && !defined(__ARM_FP16_FORMAT_IEEE)\n\n");
fid.write("const quint32 qfloat16::mantissatable[2048] = {\n");
fid.write("0,\n");
@@ -155,6 +156,7 @@ qint32 main(qint32 argc, char **argv)
fid.write("};\n\n");
+ fid.write("#endif // !__F16C__ && !__ARM_FP16_FORMAT_IEEE\n\n");
fid.write("QT_END_NAMESPACE\n");
fid.close();
return 0;
diff --git a/src/tools/qlalr/cppgenerator.cpp b/src/tools/qlalr/cppgenerator.cpp
index b14c73a8fe..508db696b1 100644
--- a/src/tools/qlalr/cppgenerator.cpp
+++ b/src/tools/qlalr/cppgenerator.cpp
@@ -460,7 +460,7 @@ void CppGenerator::generateDecl (QTextStream &out)
<< "public:" << endl
<< " enum VariousConstants {" << endl;
- for (Name t : qAsConst(grammar.terminals))
+ for (const Name &t : qAsConst(grammar.terminals))
{
QString name = *t;
int value = std::distance (grammar.names.begin (), t);
diff --git a/src/tools/qlalr/lalr.h b/src/tools/qlalr/lalr.h
index 6a2baaa462..8eadee400d 100644
--- a/src/tools/qlalr/lalr.h
+++ b/src/tools/qlalr/lalr.h
@@ -61,6 +61,8 @@ public:
public:
const_iterator () {}
+ const_iterator (const typename _Base::iterator &it):
+ _M_iterator (typename _Base::const_iterator(it)) {}
const_iterator (const typename _Base::const_iterator &it):
_M_iterator (it) {}
diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp
index 12f986b1e2..6e8c13be15 100644
--- a/src/tools/rcc/main.cpp
+++ b/src/tools/rcc/main.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -127,10 +128,25 @@ int runRcc(int argc, char *argv[])
QCommandLineOption rootOption(QStringLiteral("root"), QStringLiteral("Prefix resource access path with root path."), QStringLiteral("path"));
parser.addOption(rootOption);
+#if QT_CONFIG(zstd) && !defined(QT_NO_COMPRESS)
+# define ALGOS "[zstd], zlib, none"
+#elif QT_CONFIG(zstd)
+# define ALGOS "[zstd], none"
+#elif !defined(QT_NO_COMPRESS)
+# define ALGOS "[zlib], none"
+#else
+# define ALGOS "[none]"
+#endif
+ const QString &algoDescription =
+ QStringLiteral("Compress input files using algorithm <algo> (" ALGOS ").");
+ QCommandLineOption compressionAlgoOption(QStringLiteral("compress-algo"), algoDescription, QStringLiteral("algo"));
+ parser.addOption(compressionAlgoOption);
+#undef ALGOS
+
QCommandLineOption compressOption(QStringLiteral("compress"), QStringLiteral("Compress input files by <level>."), QStringLiteral("level"));
parser.addOption(compressOption);
- QCommandLineOption nocompressOption(QStringLiteral("no-compress"), QStringLiteral("Disable all compression."));
+ QCommandLineOption nocompressOption(QStringLiteral("no-compress"), QStringLiteral("Disable all compression. Same as --compress-algo=none."));
parser.addOption(nocompressOption);
QCommandLineOption thresholdOption(QStringLiteral("threshold"), QStringLiteral("Threshold to consider compressing files."), QStringLiteral("level"));
@@ -169,13 +185,13 @@ int runRcc(int argc, char *argv[])
QString errorMsg;
- quint8 formatVersion = 2;
+ quint8 formatVersion = 3;
if (parser.isSet(formatVersionOption)) {
bool ok = false;
formatVersion = parser.value(formatVersionOption).toUInt(&ok);
if (!ok) {
errorMsg = QLatin1String("Invalid format version specified");
- } else if (formatVersion != 1 && formatVersion != 2) {
+ } else if (formatVersion < 1 || formatVersion > 3) {
errorMsg = QLatin1String("Unsupported format version specified");
}
}
@@ -189,10 +205,17 @@ int runRcc(int argc, char *argv[])
|| library.resourceRoot().at(0) != QLatin1Char('/'))
errorMsg = QLatin1String("Root must start with a /");
}
- if (parser.isSet(compressOption))
- library.setCompressLevel(parser.value(compressOption).toInt());
+
+ if (parser.isSet(compressionAlgoOption))
+ library.setCompressionAlgorithm(RCCResourceLibrary::parseCompressionAlgorithm(parser.value(compressionAlgoOption), &errorMsg));
+ if (formatVersion < 3 && library.compressionAlgorithm() == RCCResourceLibrary::CompressionAlgorithm::Zstd)
+ errorMsg = QLatin1String("Zstandard compression requires format version 3 or higher");
if (parser.isSet(nocompressOption))
- library.setCompressLevel(-2);
+ library.setCompressionAlgorithm(RCCResourceLibrary::CompressionAlgorithm::None);
+ if (parser.isSet(compressOption) && errorMsg.isEmpty()) {
+ int level = library.parseCompressionLevel(library.compressionAlgorithm(), parser.value(compressOption), &errorMsg);
+ library.setCompressLevel(level);
+ }
if (parser.isSet(thresholdOption))
library.setCompressThreshold(parser.value(thresholdOption).toInt());
if (parser.isSet(binaryOption))
diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp
index 1a7cab01df..862e574f2d 100644
--- a/src/tools/rcc/rcc.cpp
+++ b/src/tools/rcc/rcc.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -41,6 +42,10 @@
#include <algorithm>
+#if QT_CONFIG(zstd)
+# include <zstd.h>
+#endif
+
// Note: A copy of this file is used in Qt Designer (qttools/src/designer/src/lib/shared/rcc.cpp)
QT_BEGIN_NAMESPACE
@@ -48,9 +53,18 @@ QT_BEGIN_NAMESPACE
enum {
CONSTANT_USENAMESPACE = 1,
CONSTANT_COMPRESSLEVEL_DEFAULT = -1,
+ CONSTANT_ZSTDCOMPRESSLEVEL_CHECK = 1, // Zstd level to check if compressing is a good idea
+ CONSTANT_ZSTDCOMPRESSLEVEL_STORE = 14, // Zstd level to actually store the data
CONSTANT_COMPRESSTHRESHOLD_DEFAULT = 70
};
+#if QT_CONFIG(zstd)
+# define CONSTANT_COMPRESSALGO_DEFAULT RCCResourceLibrary::CompressionAlgorithm::Zstd
+#elif !defined(QT_NO_COMPRESS)
+# define CONSTANT_COMPRESSALGO_DEFAULT RCCResourceLibrary::CompressionAlgorithm::Zlib
+#else
+# define CONSTANT_COMPRESSALGO_DEFAULT RCCResourceLibrary::CompressionAlgorithm::None
+#endif
#define writeString(s) write(s, sizeof(s))
@@ -88,15 +102,18 @@ class RCCFileInfo
public:
enum Flags
{
+ // must match qresource.cpp
NoFlags = 0x00,
Compressed = 0x01,
- Directory = 0x02
+ Directory = 0x02,
+ CompressedZstd = 0x04
};
RCCFileInfo(const QString &name = QString(), const QFileInfo &fileInfo = QFileInfo(),
QLocale::Language language = QLocale::C,
QLocale::Country country = QLocale::AnyCountry,
uint flags = NoFlags,
+ RCCResourceLibrary::CompressionAlgorithm compressAlgo = CONSTANT_COMPRESSALGO_DEFAULT,
int compressLevel = CONSTANT_COMPRESSLEVEL_DEFAULT,
int compressThreshold = CONSTANT_COMPRESSTHRESHOLD_DEFAULT);
~RCCFileInfo();
@@ -115,6 +132,7 @@ public:
QFileInfo m_fileInfo;
RCCFileInfo *m_parent;
QHash<QString, RCCFileInfo*> m_children;
+ RCCResourceLibrary::CompressionAlgorithm m_compressAlgo;
int m_compressLevel;
int m_compressThreshold;
@@ -125,7 +143,7 @@ public:
RCCFileInfo::RCCFileInfo(const QString &name, const QFileInfo &fileInfo,
QLocale::Language language, QLocale::Country country, uint flags,
- int compressLevel, int compressThreshold)
+ RCCResourceLibrary::CompressionAlgorithm compressAlgo, int compressLevel, int compressThreshold)
{
m_name = name;
m_fileInfo = fileInfo;
@@ -136,6 +154,7 @@ RCCFileInfo::RCCFileInfo(const QString &name, const QFileInfo &fileInfo,
m_nameOffset = 0;
m_dataOffset = 0;
m_childOffset = 0;
+ m_compressAlgo = compressAlgo;
m_compressLevel = compressLevel;
m_compressThreshold = compressThreshold;
}
@@ -211,6 +230,9 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
static const quint64 sourceDate = 1000 * qgetenv("QT_RCC_SOURCE_DATE_OVERRIDE").toULongLong();
if (sourceDate != 0)
lastmod = sourceDate;
+ static const quint64 sourceDate2 = 1000 * qgetenv("SOURCE_DATE_EPOCH").toULongLong();
+ if (sourceDate2 != 0)
+ lastmod = sourceDate2;
lib.writeNumber8(lastmod);
if (text || pass1)
lib.writeChar('\n');
@@ -236,19 +258,82 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
}
QByteArray data = file.readAll();
-#ifndef QT_NO_COMPRESS
// Check if compression is useful for this file
- if (m_compressLevel != 0 && data.size() != 0) {
- QByteArray compressed =
- qCompress(reinterpret_cast<uchar *>(data.data()), data.size(), m_compressLevel);
-
- int compressRatio = int(100.0 * (data.size() - compressed.size()) / data.size());
- if (compressRatio >= m_compressThreshold) {
- data = compressed;
- m_flags |= Compressed;
+ if (data.size() != 0) {
+#if QT_CONFIG(zstd)
+ if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best) {
+ m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zstd;
+ m_compressLevel = 19; // not ZSTD_maxCLevel(), as 20+ are experimental
+ }
+ if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zstd) {
+ if (lib.m_zstdCCtx == nullptr)
+ lib.m_zstdCCtx = ZSTD_createCCtx();
+ qsizetype size = data.size();
+ size = ZSTD_COMPRESSBOUND(size);
+
+ int compressLevel = m_compressLevel;
+ if (compressLevel < 0)
+ compressLevel = CONSTANT_ZSTDCOMPRESSLEVEL_CHECK;
+
+ QByteArray compressed(size, Qt::Uninitialized);
+ char *dst = const_cast<char *>(compressed.constData());
+ size_t n = ZSTD_compressCCtx(lib.m_zstdCCtx, dst, size,
+ data.constData(), data.size(),
+ compressLevel);
+ if (n * 100.0 < data.size() * 1.0 * (100 - m_compressThreshold) ) {
+ // compressing is worth it
+ if (m_compressLevel < 0) {
+ // heuristic compression, so recompress
+ n = ZSTD_compressCCtx(lib.m_zstdCCtx, dst, size,
+ data.constData(), data.size(),
+ CONSTANT_ZSTDCOMPRESSLEVEL_STORE);
+ }
+ if (ZSTD_isError(n)) {
+ QString msg = QString::fromLatin1("%1: error: compression with zstd failed: %2\n")
+ .arg(m_name, QString::fromUtf8(ZSTD_getErrorName(n)));
+ lib.m_errorDevice->write(msg.toUtf8());
+ } else if (lib.verbose()) {
+ QString msg = QString::fromLatin1("%1: note: compressed using zstd (%2 -> %3)\n")
+ .arg(m_name).arg(data.size()).arg(n);
+ lib.m_errorDevice->write(msg.toUtf8());
+ }
+
+ lib.m_overallFlags |= CompressedZstd;
+ m_flags |= CompressedZstd;
+ data = std::move(compressed);
+ data.truncate(n);
+ } else if (lib.verbose()) {
+ QString msg = QString::fromLatin1("%1: note: not compressed\n").arg(m_name);
+ lib.m_errorDevice->write(msg.toUtf8());
+ }
+ }
+#endif
+#ifndef QT_NO_COMPRESS
+ if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best) {
+ m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zlib;
+ m_compressLevel = 9;
+ }
+ if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zlib) {
+ QByteArray compressed =
+ qCompress(reinterpret_cast<uchar *>(data.data()), data.size(), m_compressLevel);
+
+ int compressRatio = int(100.0 * (data.size() - compressed.size()) / data.size());
+ if (compressRatio >= m_compressThreshold) {
+ if (lib.verbose()) {
+ QString msg = QString::fromLatin1("%1: note: compressed using zlib (%2 -> %3)\n")
+ .arg(m_name).arg(data.size()).arg(compressed.size());
+ lib.m_errorDevice->write(msg.toUtf8());
+ }
+ data = compressed;
+ lib.m_overallFlags |= Compressed;
+ m_flags |= Compressed;
+ } else if (lib.verbose()) {
+ QString msg = QString::fromLatin1("%1: note: not compressed\n").arg(m_name);
+ lib.m_errorDevice->write(msg.toUtf8());
+ }
}
- }
#endif // QT_NO_COMPRESS
+ }
// some info
if (text || pass1) {
@@ -343,7 +428,8 @@ RCCResourceLibrary::Strings::Strings() :
ATTRIBUTE_PREFIX(QLatin1String("prefix")),
ATTRIBUTE_ALIAS(QLatin1String("alias")),
ATTRIBUTE_THRESHOLD(QLatin1String("threshold")),
- ATTRIBUTE_COMPRESS(QLatin1String("compress"))
+ ATTRIBUTE_COMPRESS(QLatin1String("compress")),
+ ATTRIBUTE_COMPRESSALGO(QStringLiteral("compression-algorithm"))
{
}
@@ -351,22 +437,30 @@ RCCResourceLibrary::RCCResourceLibrary(quint8 formatVersion)
: m_root(0),
m_format(C_Code),
m_verbose(false),
+ m_compressionAlgo(CONSTANT_COMPRESSALGO_DEFAULT),
m_compressLevel(CONSTANT_COMPRESSLEVEL_DEFAULT),
m_compressThreshold(CONSTANT_COMPRESSTHRESHOLD_DEFAULT),
m_treeOffset(0),
m_namesOffset(0),
m_dataOffset(0),
+ m_overallFlags(0),
m_useNameSpace(CONSTANT_USENAMESPACE),
m_errorDevice(0),
m_outDevice(0),
m_formatVersion(formatVersion)
{
m_out.reserve(30 * 1000 * 1000);
+#if QT_CONFIG(zstd)
+ m_zstdCCtx = nullptr;
+#endif
}
RCCResourceLibrary::~RCCResourceLibrary()
{
delete m_root;
+#if QT_CONFIG(zstd)
+ ZSTD_freeCCtx(m_zstdCCtx);
+#endif
}
enum RCCXmlTag {
@@ -391,6 +485,7 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
QLocale::Language language = QLocale::c().language();
QLocale::Country country = QLocale::c().country();
QString alias;
+ auto compressAlgo = m_compressionAlgo;
int compressLevel = m_compressLevel;
int compressThreshold = m_compressThreshold;
@@ -444,17 +539,27 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
if (attributes.hasAttribute(m_strings.ATTRIBUTE_ALIAS))
alias = attributes.value(m_strings.ATTRIBUTE_ALIAS).toString();
+ compressAlgo = m_compressionAlgo;
compressLevel = m_compressLevel;
- if (attributes.hasAttribute(m_strings.ATTRIBUTE_COMPRESS))
- compressLevel = attributes.value(m_strings.ATTRIBUTE_COMPRESS).toString().toInt();
-
compressThreshold = m_compressThreshold;
+
+ QString errorString;
+ if (attributes.hasAttribute(m_strings.ATTRIBUTE_COMPRESSALGO))
+ compressAlgo = parseCompressionAlgorithm(attributes.value(m_strings.ATTRIBUTE_COMPRESSALGO), &errorString);
+ if (errorString.isEmpty() && attributes.hasAttribute(m_strings.ATTRIBUTE_COMPRESS)) {
+ QString value = attributes.value(m_strings.ATTRIBUTE_COMPRESS).toString();
+ compressLevel = parseCompressionLevel(compressAlgo, value, &errorString);
+ }
+
+ // Special case for -no-compress
+ if (m_compressLevel == -2)
+ compressAlgo = CompressionAlgorithm::None;
+
if (attributes.hasAttribute(m_strings.ATTRIBUTE_THRESHOLD))
compressThreshold = attributes.value(m_strings.ATTRIBUTE_THRESHOLD).toString().toInt();
- // Special case for -no-compress. Overrides all other settings.
- if (m_compressLevel == -2)
- compressLevel = 0;
+ if (!errorString.isEmpty())
+ reader.raiseError(errorString);
}
} else {
reader.raiseError(QString(QLatin1String("unexpected tag: %1")).arg(reader.name().toString()));
@@ -520,6 +625,7 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
language,
country,
child.isDir() ? RCCFileInfo::Directory : RCCFileInfo::NoFlags,
+ compressAlgo,
compressLevel,
compressThreshold)
);
@@ -535,6 +641,7 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
language,
country,
RCCFileInfo::NoFlags,
+ compressAlgo,
compressLevel,
compressThreshold)
);
@@ -729,6 +836,55 @@ RCCResourceLibrary::ResourceDataFileMap RCCResourceLibrary::resourceDataFileMap(
return rc;
}
+RCCResourceLibrary::CompressionAlgorithm RCCResourceLibrary::parseCompressionAlgorithm(QStringView value, QString *errorMsg)
+{
+ if (value == QLatin1String("best"))
+ return CompressionAlgorithm::Best;
+ if (value == QLatin1String("zlib")) {
+#ifdef QT_NO_COMPRESS
+ *errorMsg = QLatin1String("zlib support not compiled in");
+#else
+ return CompressionAlgorithm::Zlib;
+#endif
+ } else if (value == QLatin1String("zstd")) {
+#if QT_CONFIG(zstd)
+ return CompressionAlgorithm::Zstd;
+#else
+ *errorMsg = QLatin1String("Zstandard support not compiled in");
+#endif
+ } else if (value != QLatin1String("none")) {
+ *errorMsg = QString::fromLatin1("Unknown compression algorithm '%1'").arg(value);
+ }
+
+ return CompressionAlgorithm::None;
+}
+
+int RCCResourceLibrary::parseCompressionLevel(CompressionAlgorithm algo, const QString &level, QString *errorMsg)
+{
+ bool ok;
+ int c = level.toInt(&ok);
+ if (ok) {
+ switch (algo) {
+ case CompressionAlgorithm::None:
+ case CompressionAlgorithm::Best:
+ return 0;
+ case CompressionAlgorithm::Zlib:
+ if (c >= 1 && c <= 9)
+ return c;
+ break;
+ case CompressionAlgorithm::Zstd:
+#if QT_CONFIG(zstd)
+ if (c >= 0 && c <= ZSTD_maxCLevel())
+ return c;
+#endif
+ break;
+ }
+ }
+
+ *errorMsg = QString::fromLatin1("invalid compression level '%1'").arg(level);
+ return 0;
+}
+
bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &tempDevice, QIODevice &errorDevice)
{
m_errorDevice = &errorDevice;
@@ -795,6 +951,14 @@ bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &tempDevice, QIO
return true;
}
+void RCCResourceLibrary::writeDecimal(int value)
+{
+ Q_ASSERT(m_format != RCCResourceLibrary::Binary);
+ char buf[std::numeric_limits<int>::digits10 + 2];
+ int n = snprintf(buf, sizeof(buf), "%d", value);
+ write(buf, n + 1); // write() takes a size including terminating NUL
+}
+
void RCCResourceLibrary::writeHex(quint8 tmp)
{
const char digits[] = "0123456789abcdef";
@@ -889,6 +1053,8 @@ bool RCCResourceLibrary::writeHeader()
writeNumber4(0);
writeNumber4(0);
writeNumber4(0);
+ if (m_formatVersion >= 3)
+ writeNumber4(m_overallFlags);
}
return true;
}
@@ -1091,10 +1257,35 @@ bool RCCResourceLibrary::writeInitializer()
if (m_root) {
writeString("bool qRegisterResourceData"
"(int, const unsigned char *, "
- "const unsigned char *, const unsigned char *);\n\n");
+ "const unsigned char *, const unsigned char *);\n");
writeString("bool qUnregisterResourceData"
"(int, const unsigned char *, "
"const unsigned char *, const unsigned char *);\n\n");
+
+ if (m_overallFlags & (RCCFileInfo::Compressed | RCCFileInfo::CompressedZstd)) {
+ // use variable relocations with ELF and Mach-O
+ writeString("#if defined(__ELF__) || defined(__APPLE__)\n");
+ if (m_overallFlags & RCCFileInfo::Compressed) {
+ writeString("static inline unsigned char qResourceFeatureZlib()\n"
+ "{\n"
+ " extern const unsigned char qt_resourceFeatureZlib;\n"
+ " return qt_resourceFeatureZlib;\n"
+ "}\n");
+ }
+ if (m_overallFlags & RCCFileInfo::CompressedZstd) {
+ writeString("static inline unsigned char qResourceFeatureZstd()\n"
+ "{\n"
+ " extern const unsigned char qt_resourceFeatureZstd;\n"
+ " return qt_resourceFeatureZstd;\n"
+ "}\n");
+ }
+ writeString("#else\n");
+ if (m_overallFlags & RCCFileInfo::Compressed)
+ writeString("unsigned char qResourceFeatureZlib();\n");
+ if (m_overallFlags & RCCFileInfo::CompressedZstd)
+ writeString("unsigned char qResourceFeatureZstd();\n");
+ writeString("#endif\n\n");
+ }
}
if (m_useNameSpace)
@@ -1113,12 +1304,12 @@ bool RCCResourceLibrary::writeInitializer()
writeString("()\n{\n");
if (m_root) {
- writeString(" ");
+ writeString(" int version = ");
+ writeDecimal(m_formatVersion);
+ writeString(";\n ");
writeAddNamespaceFunction("qRegisterResourceData");
- writeString("\n (");
- writeHex(m_formatVersion);
- writeString(" qt_resource_struct, "
- "qt_resource_name, qt_resource_data);\n");
+ writeString("\n (version, qt_resource_struct, "
+ "qt_resource_name, qt_resource_data);\n");
}
writeString(" return 1;\n");
writeString("}\n\n");
@@ -1136,11 +1327,24 @@ bool RCCResourceLibrary::writeInitializer()
writeMangleNamespaceFunction(cleanResources);
writeString("()\n{\n");
if (m_root) {
- writeString(" ");
+ writeString(" int version = ");
+ writeDecimal(m_formatVersion);
+ writeString(";\n ");
+
+ // ODR-use certain symbols from QtCore if we require optional features
+ if (m_overallFlags & RCCFileInfo::Compressed) {
+ writeString("version += ");
+ writeAddNamespaceFunction("qResourceFeatureZlib()");
+ writeString(";\n ");
+ }
+ if (m_overallFlags & RCCFileInfo::CompressedZstd) {
+ writeString("version += ");
+ writeAddNamespaceFunction("qResourceFeatureZstd()");
+ writeString(";\n ");
+ }
+
writeAddNamespaceFunction("qUnregisterResourceData");
- writeString("\n (");
- writeHex(m_formatVersion);
- writeString(" qt_resource_struct, "
+ writeString("\n (version, qt_resource_struct, "
"qt_resource_name, qt_resource_data);\n");
}
writeString(" return 1;\n");
@@ -1176,6 +1380,13 @@ bool RCCResourceLibrary::writeInitializer()
p[i++] = (m_namesOffset >> 16) & 0xff;
p[i++] = (m_namesOffset >> 8) & 0xff;
p[i++] = (m_namesOffset >> 0) & 0xff;
+
+ if (m_formatVersion >= 3) {
+ p[i++] = (m_overallFlags >> 24) & 0xff;
+ p[i++] = (m_overallFlags >> 16) & 0xff;
+ p[i++] = (m_overallFlags >> 8) & 0xff;
+ p[i++] = (m_overallFlags >> 0) & 0xff;
+ }
}
return true;
}
diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h
index 36984cf38a..ad1c5cd166 100644
--- a/src/tools/rcc/rcc.h
+++ b/src/tools/rcc/rcc.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -35,6 +36,8 @@
#include <qhash.h>
#include <qstring.h>
+typedef struct ZSTD_CCtx_s ZSTD_CCtx;
+
QT_BEGIN_NAMESPACE
class RCCFileInfo;
@@ -77,6 +80,19 @@ public:
void setOutputName(const QString &name) { m_outputName = name; }
QString outputName() const { return m_outputName; }
+ enum class CompressionAlgorithm {
+ Zlib,
+ Zstd,
+
+ Best = 99,
+ None = -1
+ };
+
+ static CompressionAlgorithm parseCompressionAlgorithm(QStringView algo, QString *errorMsg);
+ void setCompressionAlgorithm(CompressionAlgorithm algo) { m_compressionAlgo = algo; }
+ CompressionAlgorithm compressionAlgorithm() const { return m_compressionAlgo; }
+
+ static int parseCompressionLevel(CompressionAlgorithm algo, const QString &level, QString *errorMsg);
void setCompressLevel(int c) { m_compressLevel = c; }
int compressLevel() const { return m_compressLevel; }
@@ -104,6 +120,7 @@ private:
const QString ATTRIBUTE_ALIAS;
const QString ATTRIBUTE_THRESHOLD;
const QString ATTRIBUTE_COMPRESS;
+ const QString ATTRIBUTE_COMPRESSALGO;
};
friend class RCCFileInfo;
void reset();
@@ -117,6 +134,7 @@ private:
bool writeInitializer();
void writeMangleNamespaceFunction(const QByteArray &name);
void writeAddNamespaceFunction(const QByteArray &name);
+ void writeDecimal(int value);
void writeHex(quint8 number);
void writeNumber2(quint16 number);
void writeNumber4(quint32 number);
@@ -125,6 +143,10 @@ private:
void writeByteArray(const QByteArray &);
void write(const char *, int len);
+#if QT_CONFIG(zstd)
+ ZSTD_CCtx *m_zstdCCtx;
+#endif
+
const Strings m_strings;
RCCFileInfo *m_root;
QStringList m_fileNames;
@@ -133,11 +155,13 @@ private:
QString m_outputName;
Format m_format;
bool m_verbose;
+ CompressionAlgorithm m_compressionAlgo;
int m_compressLevel;
int m_compressThreshold;
int m_treeOffset;
int m_namesOffset;
int m_dataOffset;
+ quint32 m_overallFlags;
bool m_useNameSpace;
QStringList m_failedResources;
QIODevice *m_errorDevice;
diff --git a/src/tools/rcc/rcc.pro b/src/tools/rcc/rcc.pro
index 208ec54a73..ae55b5d8af 100644
--- a/src/tools/rcc/rcc.pro
+++ b/src/tools/rcc/rcc.pro
@@ -8,3 +8,14 @@ SOURCES += main.cpp
QMAKE_TARGET_DESCRIPTION = "Qt Resource Compiler"
load(qt_tool)
+
+# RCC is a bootstrapped tool, so qglobal.h #includes qconfig-bootstrapped.h
+# and that has a #define saying zstd isn't present (for qresource.cpp, which is
+# part of the bootstrap lib). So we inform the presence of the feature in the
+# command-line.
+qtConfig(zstd):!cross_compile {
+ DEFINES += QT_FEATURE_zstd=1
+ QMAKE_USE_PRIVATE += zstd
+} else {
+ DEFINES += QT_FEATURE_zstd=-1
+}
diff --git a/src/tools/tracegen/helpers.cpp b/src/tools/tracegen/helpers.cpp
index f0ac7ed47f..a5526065d6 100644
--- a/src/tools/tracegen/helpers.cpp
+++ b/src/tools/tracegen/helpers.cpp
@@ -46,7 +46,7 @@ QString includeGuard(const QString &filename)
for (int i = 0; i < guard.size(); ++i) {
if (!guard.at(i).isLetterOrNumber())
- guard[i] = QChar('_');
+ guard[i] = QLatin1Char('_');
}
return guard;
diff --git a/src/tools/uic/cpp/cppwriteincludes.cpp b/src/tools/uic/cpp/cppwriteincludes.cpp
index d51fddffea..0ba49627c0 100644
--- a/src/tools/uic/cpp/cppwriteincludes.cpp
+++ b/src/tools/uic/cpp/cppwriteincludes.cpp
@@ -119,7 +119,7 @@ void WriteIncludes::acceptUI(DomUI *node)
writeHeaders(m_globalIncludes, true);
writeHeaders(m_localIncludes, false);
- m_output << QLatin1Char('\n');
+ m_output << '\n';
}
void WriteIncludes::acceptWidget(DomWidget *node)
@@ -214,14 +214,14 @@ void WriteIncludes::add(const QString &className, bool determineHeader, const QS
m_knownClasses.insert(className);
const CustomWidgetsInfo *cwi = m_uic->customWidgetsInfo();
- if (cwi->extends(className, QLatin1String("QTreeView"))
- || cwi->extends(className, QLatin1String("QTreeWidget"))
- || cwi->extends(className, QLatin1String("QTableView"))
- || cwi->extends(className, QLatin1String("QTableWidget"))) {
+ static const QStringList treeViewsWithHeaders = {
+ QLatin1String("QTreeView"), QLatin1String("QTreeWidget"),
+ QLatin1String("QTableView"), QLatin1String("QTableWidget")
+ };
+ if (cwi->extendsOneOf(className, treeViewsWithHeaders))
add(QLatin1String("QHeaderView"));
- }
- if (!m_laidOut && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox")))
+ if (!m_laidOut && cwi->extends(className, QLatin1String("QToolBox")))
add(QLatin1String("QLayout")); // spacing property of QToolBox)
if (className == QLatin1String("Line")) { // ### hmm, deprecate me!
@@ -314,7 +314,7 @@ void WriteIncludes::writeHeaders(const OrderedSet &headers, bool global)
const QString value = m_oldHeaderToNewHeader.value(header, header);
const auto trimmed = QStringRef(&value).trimmed();
if (!trimmed.isEmpty())
- m_output << "#include " << openingQuote << trimmed << closingQuote << QLatin1Char('\n');
+ m_output << "#include " << openingQuote << trimmed << closingQuote << '\n';
}
}
diff --git a/src/tools/uic/cpp/cppwriteincludes.h b/src/tools/uic/cpp/cppwriteincludes.h
index 7f03849798..e9247f4cc4 100644
--- a/src/tools/uic/cpp/cppwriteincludes.h
+++ b/src/tools/uic/cpp/cppwriteincludes.h
@@ -58,9 +58,9 @@ struct WriteIncludes : public TreeWalker
//
// actions
//
- void acceptActionGroup(DomActionGroup *node) Q_DECL_OVERRIDE;
- void acceptAction(DomAction *node) Q_DECL_OVERRIDE;
- void acceptActionRef(DomActionRef *node) Q_DECL_OVERRIDE;
+ void acceptActionGroup(DomActionGroup *node) override;
+ void acceptAction(DomAction *node) override;
+ void acceptActionRef(DomActionRef *node) override;
//
// custom widgets
diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp
index 0adc91ddb9..2fb3e502c5 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.cpp
+++ b/src/tools/uic/cpp/cppwriteinitialization.cpp
@@ -32,7 +32,8 @@
#include "utils.h"
#include "uic.h"
#include "databaseinfo.h"
-#include "globaldefs.h"
+
+#include <language.h>
#include <qtextstream.h>
#include <qversionnumber.h>
@@ -45,35 +46,26 @@
QT_BEGIN_NAMESPACE
namespace {
- // Fixup an enumeration name from class Qt.
- // They are currently stored as "BottomToolBarArea" instead of "Qt::BottomToolBarArea".
- // due to MO issues. This might be fixed in the future.
- QLatin1String qtEnumerationPrefix(const QString &name) {
- static const QLatin1String prefix("Qt::");
- if (name.indexOf(prefix) != 0)
- return prefix;
- return QLatin1String();
- }
// figure out the toolbar area of a DOM attrib list.
// By legacy, it is stored as an integer. As of 4.3.0, it is the enumeration value.
QString toolBarAreaStringFromDOMAttributes(const CPP::WriteInitialization::DomPropertyMap &attributes) {
const DomProperty *pstyle = attributes.value(QLatin1String("toolBarArea"));
+ QString result;
if (!pstyle)
- return QString();
-
+ return result;
switch (pstyle->kind()) {
- case DomProperty::Number: {
- return QLatin1String("static_cast<Qt::ToolBarArea>(")
- + QString::number(pstyle->elementNumber()) + QLatin1String("), ");
- }
- case DomProperty::Enum: {
- const QString area = pstyle->elementEnum();
- return qtEnumerationPrefix(area) + area + QLatin1String(", ");
- }
+ case DomProperty::Number:
+ result = QLatin1String(language::toolbarArea(pstyle->elementNumber()));
+ break;
+ case DomProperty::Enum:
+ result = pstyle->elementEnum();
+ break;
default:
break;
}
- return QString();
+ if (!result.startsWith(QLatin1String("Qt::")))
+ result.prepend(QLatin1String("Qt::"));
+ return result + QLatin1String(", ");
}
// Write a statement to create a spacer item.
@@ -173,17 +165,16 @@ namespace {
}
return true;
}
-
- inline void openIfndef(QTextStream &str, const QString &symbol) { if (!symbol.isEmpty()) str << QLatin1String("#ifndef ") << symbol << endl; }
- inline void closeIfndef(QTextStream &str, const QString &symbol) { if (!symbol.isEmpty()) str << QLatin1String("#endif // ") << symbol << endl; }
-
- const char *accessibilityDefineC = "QT_NO_ACCESSIBILITY";
- const char *toolTipDefineC = "QT_NO_TOOLTIP";
- const char *whatsThisDefineC = "QT_NO_WHATSTHIS";
- const char *statusTipDefineC = "QT_NO_STATUSTIP";
- const char *shortcutDefineC = "QT_NO_SHORTCUT";
}
+// QtGui
+static inline QString accessibilityConfigKey() { return QStringLiteral("accessibility"); }
+static inline QString shortcutConfigKey() { return QStringLiteral("shortcut"); }
+static inline QString whatsThisConfigKey() { return QStringLiteral("whatsthis"); }
+// QtWidgets
+static inline QString statusTipConfigKey() { return QStringLiteral("statustip"); }
+static inline QString toolTipConfigKey() { return QStringLiteral("tooltip"); }
+
namespace CPP {
FontHandle::FontHandle(const DomFont *domFont) :
@@ -521,14 +512,15 @@ void WriteInitialization::acceptUI(DomUI *node)
acceptWidget(node->elementWidget());
if (!m_buddies.empty())
- openIfndef(m_output, QLatin1String(shortcutDefineC));
+ m_output << language::openQtConfig(shortcutConfigKey());
for (const Buddy &b : qAsConst(m_buddies)) {
if (!m_registeredWidgets.contains(b.objName)) {
fprintf(stderr, "%s: Warning: Buddy assignment: '%s' is not a valid widget.\n",
qPrintable(m_option.messagePrefix()),
b.objName.toLatin1().data());
continue;
- } else if (!m_registeredWidgets.contains(b.buddy)) {
+ }
+ if (!m_registeredWidgets.contains(b.buddy)) {
fprintf(stderr, "%s: Warning: Buddy assignment: '%s' is not a valid widget.\n",
qPrintable(m_option.messagePrefix()),
b.buddy.toLatin1().data());
@@ -538,12 +530,12 @@ void WriteInitialization::acceptUI(DomUI *node)
m_output << m_indent << b.objName << "->setBuddy(" << b.buddy << ");\n";
}
if (!m_buddies.empty())
- closeIfndef(m_output, QLatin1String(shortcutDefineC));
+ m_output << language::closeQtConfig(shortcutConfigKey());
if (node->elementTabStops())
acceptTabStops(node->elementTabStops());
- if (m_delayedActionInitialization.size())
+ if (!m_delayedActionInitialization.isEmpty())
m_output << "\n" << m_delayedActionInitialization;
m_output << "\n" << m_indent << "retranslateUi(" << varName << ");\n";
@@ -616,18 +608,23 @@ void WriteInitialization::acceptWidget(DomWidget *node)
if (m_uic->isContainer(parentClass))
parentWidget.clear();
- if (m_widgetChain.size() != 1)
- m_output << m_indent << varName << " = new " << m_uic->customWidgetsInfo()->realClassName(className) << '(' << parentWidget << ");\n";
+ const auto *cwi = m_uic->customWidgetsInfo();
+
+ if (m_widgetChain.size() != 1) {
+ m_output << m_indent << varName << " = new " << cwi->realClassName(className)
+ << '(' << parentWidget << ");\n";
+ }
parentWidget = savedParentWidget;
- if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QComboBox"))) {
+
+ if (cwi->extends(className, QLatin1String("QComboBox"))) {
initializeComboBox(node);
- } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QListWidget"))) {
+ } else if (cwi->extends(className, QLatin1String("QListWidget"))) {
initializeListWidget(node);
- } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeWidget"))) {
+ } else if (cwi->extends(className, QLatin1String("QTreeWidget"))) {
initializeTreeWidget(node);
- } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableWidget"))) {
+ } else if (cwi->extends(className, QLatin1String("QTableWidget"))) {
initializeTableWidget(node);
}
@@ -636,7 +633,8 @@ void WriteInitialization::acceptWidget(DomWidget *node)
writeProperties(varName, className, node->elementProperty());
- if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QMenu")) && parentWidget.size()) {
+ if (!parentWidget.isEmpty()
+ && cwi->extends(className, QLatin1String("QMenu"))) {
initializeMenu(node, parentWidget);
}
@@ -648,7 +646,7 @@ void WriteInitialization::acceptWidget(DomWidget *node)
if (const DomWidget* parentWidget = m_widgetChain.top()) {
const QString parentClass = parentWidget->attributeClass();
if (parentClass != QLatin1String("QMainWindow")
- && !m_uic->isCustomWidgetContainer(parentClass)
+ && !m_uic->customWidgetsInfo()->isCustomWidgetContainer(parentClass)
&& !m_uic->isContainer(parentClass))
m_layoutWidget = true;
}
@@ -664,10 +662,10 @@ void WriteInitialization::acceptWidget(DomWidget *node)
const QString pageDefaultString = QLatin1String("Page");
- if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QMainWindow"))) {
- if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QMenuBar"))) {
+ if (cwi->extends(parentClass, QLatin1String("QMainWindow"))) {
+ if (cwi->extends(className, QLatin1String("QMenuBar"))) {
m_output << m_indent << parentWidget << "->setMenuBar(" << varName <<");\n";
- } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBar"))) {
+ } else if (cwi->extends(className, QLatin1String("QToolBar"))) {
m_output << m_indent << parentWidget << "->addToolBar("
<< toolBarAreaStringFromDOMAttributes(attributes) << varName << ");\n";
@@ -677,15 +675,11 @@ void WriteInitialization::acceptWidget(DomWidget *node)
}
}
- } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QDockWidget"))) {
- QString area;
- if (DomProperty *pstyle = attributes.value(QLatin1String("dockWidgetArea"))) {
- area += QLatin1String("static_cast<Qt::DockWidgetArea>(");
- area += QString::number(pstyle->elementNumber());
- area += QLatin1String("), ");
- }
-
- m_output << m_indent << parentWidget << "->addDockWidget(" << area << varName << ");\n";
+ } else if (cwi->extends(className, QLatin1String("QDockWidget"))) {
+ m_output << m_indent << parentWidget << "->addDockWidget(";
+ if (DomProperty *pstyle = attributes.value(QLatin1String("dockWidgetArea")))
+ m_output << "Qt::" << language::dockWidgetArea(pstyle->elementNumber()) << ", ";
+ m_output << varName << ");\n";
} else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStatusBar"))) {
m_output << m_indent << parentWidget << "->setStatusBar(" << varName << ");\n";
} else {
@@ -694,71 +688,62 @@ void WriteInitialization::acceptWidget(DomWidget *node)
}
// Check for addPageMethod of a custom plugin first
- const QString addPageMethod = m_uic->customWidgetsInfo()->customWidgetAddPageMethod(parentClass);
+ QString addPageMethod = cwi->customWidgetAddPageMethod(parentClass);
+ if (addPageMethod.isEmpty())
+ addPageMethod = cwi->simpleContainerAddPageMethod(parentClass);
if (!addPageMethod.isEmpty()) {
m_output << m_indent << parentWidget << "->" << addPageMethod << '(' << varName << ");\n";
- } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QStackedWidget"))) {
- m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n";
- } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QToolBar"))) {
- m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n";
- } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QDockWidget"))) {
- m_output << m_indent << parentWidget << "->setWidget(" << varName << ");\n";
- } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QScrollArea"))) {
- m_output << m_indent << parentWidget << "->setWidget(" << varName << ");\n";
- } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QSplitter"))) {
- m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n";
- } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QMdiArea"))) {
- m_output << m_indent << parentWidget << "->addSubWindow(" << varName << ");\n";
} else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QWizard"))) {
addWizardPage(varName, node, parentWidget);
} else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QToolBox"))) {
- QString icon;
- if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) {
- icon += QLatin1String(", ") ;
- icon += iconCall(picon);
- }
-
const DomProperty *plabel = attributes.value(QLatin1String("label"));
DomString *plabelString = plabel ? plabel->elementString() : 0;
+ QString icon;
+ if (const DomProperty *picon = attributes.value(QLatin1String("icon")))
+ icon = QLatin1String(", ") + iconCall(picon); // Side effect: Writes icon definition
- m_output << m_indent << parentWidget << "->addItem(" << varName << icon << ", " << noTrCall(plabelString, pageDefaultString) << ");\n";
+ m_output << m_indent << parentWidget << "->addItem(" << varName << icon
+ << ", " << noTrCall(plabelString, pageDefaultString) << ");\n";
autoTrOutput(plabelString, pageDefaultString) << m_indent << parentWidget << "->setItemText("
<< parentWidget << "->indexOf(" << varName << "), " << autoTrCall(plabelString, pageDefaultString) << ");\n";
-#ifndef QT_NO_TOOLTIP
if (DomProperty *ptoolTip = attributes.value(QLatin1String("toolTip"))) {
- autoTrOutput(ptoolTip->elementString()) << m_indent << parentWidget << "->setItemToolTip("
- << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptoolTip->elementString()) << ");\n";
+ autoTrOutput(ptoolTip->elementString())
+ << language::openQtConfig(toolTipConfigKey())
+ << m_indent << parentWidget << "->setItemToolTip(" << parentWidget
+ << "->indexOf(" << varName << "), "
+ << autoTrCall(ptoolTip->elementString()) << ");\n"
+ << language::closeQtConfig(toolTipConfigKey());
}
-#endif // QT_NO_TOOLTIP
} else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QTabWidget"))) {
- QString icon;
- if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) {
- icon += QLatin1String(", ");
- icon += iconCall(picon);
- }
-
const DomProperty *ptitle = attributes.value(QLatin1String("title"));
DomString *ptitleString = ptitle ? ptitle->elementString() : 0;
-
- m_output << m_indent << parentWidget << "->addTab(" << varName << icon << ", " << "QString());\n";
+ QString icon;
+ if (const DomProperty *picon = attributes.value(QLatin1String("icon")))
+ icon = QLatin1String(", ") + iconCall(picon); // Side effect: Writes icon definition
+ m_output << m_indent << parentWidget << "->addTab(" << varName << icon
+ << ", " << "QString());\n";
autoTrOutput(ptitleString, pageDefaultString) << m_indent << parentWidget << "->setTabText("
<< parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptitleString, pageDefaultString) << ");\n";
-#ifndef QT_NO_TOOLTIP
if (const DomProperty *ptoolTip = attributes.value(QLatin1String("toolTip"))) {
- autoTrOutput(ptoolTip->elementString()) << m_indent << parentWidget << "->setTabToolTip("
- << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptoolTip->elementString()) << ");\n";
+ autoTrOutput(ptoolTip->elementString())
+ << language::openQtConfig(toolTipConfigKey())
+ << m_indent << parentWidget << "->setTabToolTip(" << parentWidget
+ << "->indexOf(" << varName << "), "
+ << autoTrCall(ptoolTip->elementString()) << ");\n"
+ << language::closeQtConfig(toolTipConfigKey());
}
-#endif // QT_NO_TOOLTIP
-#ifndef QT_NO_WHATSTHIS
if (const DomProperty *pwhatsThis = attributes.value(QLatin1String("whatsThis"))) {
- autoTrOutput(pwhatsThis->elementString()) << m_indent << parentWidget << "->setTabWhatsThis("
- << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(pwhatsThis->elementString()) << ");\n";
+ autoTrOutput(pwhatsThis->elementString())
+ << language::openQtConfig(whatsThisConfigKey())
+ << m_indent << parentWidget << "->setTabWhatsThis(" << parentWidget
+ << "->indexOf(" << varName << "), "
+ << autoTrCall(pwhatsThis->elementString()) << ");\n"
+ << language::closeQtConfig(whatsThisConfigKey());
}
-#endif // QT_NO_WHATSTHIS
}
//
@@ -774,8 +759,14 @@ void WriteInitialization::acceptWidget(DomWidget *node)
QLatin1String("stretchLastSection"),
};
- if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeView"))
- || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeWidget"))) {
+ static const QStringList trees = {
+ QLatin1String("QTreeView"), QLatin1String("QTreeWidget")
+ };
+ static const QStringList tables = {
+ QLatin1String("QTableView"), QLatin1String("QTableWidget")
+ };
+
+ if (cwi->extendsOneOf(className, trees)) {
DomPropertyList headerProperties;
for (auto realPropertyName : realPropertyNames) {
const QString fakePropertyName = QLatin1String("header")
@@ -788,9 +779,7 @@ void WriteInitialization::acceptWidget(DomWidget *node)
writeProperties(varName + QLatin1String("->header()"), QLatin1String("QHeaderView"),
headerProperties, WritePropertyIgnoreObjectName);
- } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableView"))
- || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableWidget"))) {
-
+ } else if (cwi->extendsOneOf(className, tables)) {
static const QLatin1String headerPrefixes[] = {
QLatin1String("horizontalHeader"),
QLatin1String("verticalHeader"),
@@ -984,6 +973,24 @@ static inline QString formLayoutRole(int column, int colspan)
return column == 0 ? QLatin1String("QFormLayout::LabelRole") : QLatin1String("QFormLayout::FieldRole");
}
+static QString layoutAddMethod(DomLayoutItem::Kind kind, const QString &layoutClass)
+{
+ const QString methodPrefix = layoutClass == QLatin1String("QFormLayout")
+ ? QLatin1String("set") : QLatin1String("add");
+ switch (kind) {
+ case DomLayoutItem::Widget:
+ return methodPrefix + QLatin1String("Widget");
+ case DomLayoutItem::Layout:
+ return methodPrefix + QLatin1String("Layout");
+ case DomLayoutItem::Spacer:
+ return methodPrefix + QLatin1String("Item");
+ case DomLayoutItem::Unknown:
+ Q_ASSERT( false );
+ break;
+ }
+ Q_UNREACHABLE();
+}
+
void WriteInitialization::acceptLayoutItem(DomLayoutItem *node)
{
TreeWalker::acceptLayoutItem(node);
@@ -996,47 +1003,27 @@ void WriteInitialization::acceptLayoutItem(DomLayoutItem *node)
const QString layoutName = m_driver->findOrInsertLayout(layout);
const QString itemName = m_driver->findOrInsertLayoutItem(node);
- QString addArgs;
- QString methodPrefix = QLatin1String("add"); //Consistent API-design galore!
+ m_output << "\n" << m_indent << layoutName << "->"
+ << layoutAddMethod(node->kind(), layout->attributeClass()) << '(';
+
if (layout->attributeClass() == QLatin1String("QGridLayout")) {
const int row = node->attributeRow();
const int col = node->attributeColumn();
const int rowSpan = node->hasAttributeRowSpan() ? node->attributeRowSpan() : 1;
const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1;
-
- addArgs = QString::fromLatin1("%1, %2, %3, %4, %5").arg(itemName).arg(row).arg(col).arg(rowSpan).arg(colSpan);
+ m_output << itemName << ", " << row << ", " << col << ", " << rowSpan << ", " << colSpan;
if (!node->attributeAlignment().isEmpty())
- addArgs += QLatin1String(", ") + node->attributeAlignment();
+ m_output << ", " << node->attributeAlignment();
+ } else if (layout->attributeClass() == QLatin1String("QFormLayout")) {
+ const int row = node->attributeRow();
+ const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1;
+ const QString role = formLayoutRole(node->attributeColumn(), colSpan);
+ m_output << row << ", " << role << ", " << itemName;
} else {
- if (layout->attributeClass() == QLatin1String("QFormLayout")) {
- methodPrefix = QLatin1String("set");
- const int row = node->attributeRow();
- const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1;
- const QString role = formLayoutRole(node->attributeColumn(), colSpan);
- addArgs = QString::fromLatin1("%1, %2, %3").arg(row).arg(role, itemName);
- } else {
- addArgs = itemName;
- if (layout->attributeClass().contains(QLatin1String("Box")) && !node->attributeAlignment().isEmpty())
- addArgs += QLatin1String(", 0, ") + node->attributeAlignment();
- }
- }
-
- // figure out "add" method
- m_output << "\n" << m_indent << layoutName << "->";
- switch (node->kind()) {
- case DomLayoutItem::Widget:
- m_output << methodPrefix << "Widget(" << addArgs;
- break;
- case DomLayoutItem::Layout:
- m_output << methodPrefix << "Layout(" << addArgs;
- break;
- case DomLayoutItem::Spacer:
- m_output << methodPrefix << "Item(" << addArgs;
- break;
- case DomLayoutItem::Unknown:
- Q_ASSERT( 0 );
- break;
+ m_output << itemName;
+ if (layout->attributeClass().contains(QLatin1String("Box")) && !node->attributeAlignment().isEmpty())
+ m_output << ", 0, " << node->attributeAlignment();
}
m_output << ");\n\n";
}
@@ -1076,16 +1063,16 @@ void WriteInitialization::acceptAction(DomAction *node)
void WriteInitialization::acceptActionRef(DomActionRef *node)
{
QString actionName = node->attributeName();
+ if (actionName.isEmpty() || !m_widgetChain.top()
+ || m_driver->actionGroupByName(actionName)) {
+ return;
+ }
+
+ const QString varName = m_driver->findOrInsertWidget(m_widgetChain.top());
const bool isSeparator = actionName == QLatin1String("separator");
bool isMenu = false;
- QString varName = m_driver->findOrInsertWidget(m_widgetChain.top());
-
- if (actionName.isEmpty() || !m_widgetChain.top()) {
- return;
- } else if (m_driver->actionGroupByName(actionName)) {
- return;
- } else if (const DomWidget *w = m_driver->widgetByName(actionName)) {
+ if (const DomWidget *w = m_driver->widgetByName(actionName)) {
isMenu = m_uic->isMenu(w->attributeClass());
} else if (!(m_driver->actionByName(actionName) || isSeparator)) {
fprintf(stderr, "%s: Warning: action `%s' not declared\n",
@@ -1125,6 +1112,23 @@ QString WriteInitialization::writeStringListProperty(const DomStringList *list)
return propertyValue;
}
+static QString configKeyForProperty(const QString &propertyName)
+{
+ if (propertyName == QLatin1String("toolTip"))
+ return toolTipConfigKey();
+ if (propertyName == QLatin1String("whatsThis"))
+ return whatsThisConfigKey();
+ if (propertyName == QLatin1String("statusTip"))
+ return statusTipConfigKey();
+ if (propertyName == QLatin1String("shortcut"))
+ return shortcutConfigKey();
+ if (propertyName == QLatin1String("accessibleName")
+ || propertyName == QLatin1String("accessibleDescription")) {
+ return accessibilityConfigKey();
+ }
+ return QString();
+}
+
void WriteInitialization::writeProperties(const QString &varName,
const QString &className,
const DomPropertyList &lst,
@@ -1172,11 +1176,12 @@ void WriteInitialization::writeProperties(const QString &varName,
<< p->elementNumber() << ");\n";
continue;
}
+ static const QStringList currentIndexWidgets = {
+ QLatin1String("QComboBox"), QLatin1String("QStackedWidget"),
+ QLatin1String("QTabWidget"), QLatin1String("QToolBox")
+ };
if (propertyName == QLatin1String("currentIndex") // set currentIndex later
- && (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QComboBox"))
- || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStackedWidget"))
- || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTabWidget"))
- || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox")))) {
+ && (m_uic->customWidgetsInfo()->extendsOneOf(className, currentIndexWidgets))) {
m_delayedOut << m_indent << varName << "->setCurrentIndex("
<< p->elementNumber() << ");\n";
continue;
@@ -1461,29 +1466,19 @@ void WriteInitialization::writeProperties(const QString &varName,
break;
}
- if (propertyValue.size()) {
- const char* defineC = 0;
- if (propertyName == QLatin1String("toolTip"))
- defineC = toolTipDefineC;
- else if (propertyName == QLatin1String("whatsThis"))
- defineC = whatsThisDefineC;
- else if (propertyName == QLatin1String("statusTip"))
- defineC = statusTipDefineC;
- else if (propertyName == QLatin1String("shortcut"))
- defineC = shortcutDefineC;
- else if (propertyName == QLatin1String("accessibleName") || propertyName == QLatin1String("accessibleDescription"))
- defineC = accessibilityDefineC;
+ if (!propertyValue.isEmpty()) {
+ const QString configKey = configKeyForProperty(propertyName);
QTextStream &o = delayProperty ? m_delayedOut : autoTrOutput(p);
- if (defineC)
- openIfndef(o, QLatin1String(defineC));
+ if (!configKey.isEmpty())
+ o << language::openQtConfig(configKey);
o << m_indent << varNewName << setFunction << propertyValue;
if (!stdset)
o << ')';
o << ");\n";
- if (defineC)
- closeIfndef(o, QLatin1String(defineC));
+ if (!configKey.isEmpty())
+ o << language::closeQtConfig(configKey);
if (varName == m_mainFormVarName && &o == &m_refreshOut) {
// this is the only place (currently) where we output mainForm name to the retranslateUi().
@@ -1493,11 +1488,9 @@ void WriteInitialization::writeProperties(const QString &varName,
}
}
if (leftMargin != -1 || topMargin != -1 || rightMargin != -1 || bottomMargin != -1) {
- m_output << m_indent << varName << QLatin1String("->setContentsMargins(")
- << leftMargin << QLatin1String(", ")
- << topMargin << QLatin1String(", ")
- << rightMargin << QLatin1String(", ")
- << bottomMargin << QLatin1String(");\n");
+ m_output << m_indent << varName << "->setContentsMargins("
+ << leftMargin << ", " << topMargin << ", "
+ << rightMargin << ", " << bottomMargin << ");\n";
}
}
@@ -1519,8 +1512,8 @@ QString WriteInitialization::writeSizePolicy(const DomSizePolicy *sp)
m_output << m_indent << "QSizePolicy " << spName;
do {
if (sp->hasElementHSizeType() && sp->hasElementVSizeType()) {
- m_output << "(static_cast<QSizePolicy::Policy>(" << sp->elementHSizeType()
- << "), static_cast<QSizePolicy::Policy>(" << sp->elementVSizeType() << "));\n";
+ m_output << "(QSizePolicy::" << language::sizePolicy(sp->elementHSizeType())
+ << ", QSizePolicy::" << language::sizePolicy(sp->elementVSizeType()) << ");\n";
break;
}
if (sp->hasAttributeHSizeType() && sp->hasAttributeVSizeType()) {
@@ -1784,7 +1777,7 @@ void WriteInitialization::writeColorGroup(DomColorGroup *colorGroup, const QStri
const DomColor *color = colors.at(i);
m_output << m_indent << paletteName << ".setColor(" << group
- << ", " << "static_cast<QPalette::ColorRole>(" << QString::number(i) << ')'
+ << ", QPalette::" << language::paletteColorRole(i)
<< ", " << domColor2QString(color)
<< ");\n";
}
@@ -2059,10 +2052,15 @@ void WriteInitialization::enableSorting(DomWidget *w, const QString &varName, co
void WriteInitialization::addInitializer(Item *item,
const QString &name, int column, const QString &value, const QString &directive, bool translatable) const
{
- if (!value.isEmpty())
- item->addSetter(QLatin1String("->set") + name.at(0).toUpper() + name.midRef(1) +
- QLatin1Char('(') + (column < 0 ? QString() : QString::number(column) +
- QLatin1String(", ")) + value + QLatin1String(");"), directive, translatable);
+ if (!value.isEmpty()) {
+ QString setter;
+ QTextStream str(&setter);
+ str << "->set" << name.at(0).toUpper() << name.midRef(1) << '(';
+ if (column >= 0)
+ str << column << ", ";
+ str << value << ");";
+ item->addSetter(setter, directive, translatable);
+ }
}
/*!
@@ -2144,9 +2142,12 @@ void WriteInitialization::addCommonInitializers(Item *item,
addQtFlagsInitializer(item, properties, QLatin1String("textAlignment"), column);
addQtEnumInitializer(item, properties, QLatin1String("checkState"), column);
addStringInitializer(item, properties, QLatin1String("text"), column);
- addStringInitializer(item, properties, QLatin1String("toolTip"), column, QLatin1String(toolTipDefineC));
- addStringInitializer(item, properties, QLatin1String("whatsThis"), column, QLatin1String(whatsThisDefineC));
- addStringInitializer(item, properties, QLatin1String("statusTip"), column, QLatin1String(statusTipDefineC));
+ addStringInitializer(item, properties, QLatin1String("toolTip"), column,
+ toolTipConfigKey());
+ addStringInitializer(item, properties, QLatin1String("whatsThis"), column,
+ whatsThisConfigKey());
+ addStringInitializer(item, properties, QLatin1String("statusTip"), column,
+ statusTipConfigKey());
}
void WriteInitialization::initializeListWidget(DomWidget *w)
@@ -2286,7 +2287,7 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
item.writeRetranslateUi(varName + QLatin1String("->horizontalHeaderItem(") + QString::number(i) + QLatin1Char(')'));
- m_output << m_indent << varName << "->setHorizontalHeaderItem(" << QString::number(i) << ", " << itemName << ");\n";
+ m_output << m_indent << varName << "->setHorizontalHeaderItem(" << i << ", " << itemName << ");\n";
}
}
@@ -2308,7 +2309,7 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
item.writeRetranslateUi(varName + QLatin1String("->verticalHeaderItem(") + QString::number(i) + QLatin1Char(')'));
- m_output << m_indent << varName << "->setVerticalHeaderItem(" << QString::number(i) << ", " << itemName << ");\n";
+ m_output << m_indent << varName << "->setVerticalHeaderItem(" << i << ", " << itemName << ");\n";
}
}
@@ -2329,7 +2330,7 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
item.writeRetranslateUi(varName + QLatin1String("->item(") + QString::number(r) + QLatin1String(", ") + QString::number(c) + QLatin1Char(')'));
- m_output << m_indent << varName << "->setItem(" << QString::number(r) << ", " << QString::number(c) << ", " << itemName << ");\n";
+ m_output << m_indent << varName << "->setItem(" << r << ", " << c << ", " << itemName << ");\n";
}
}
enableSorting(w, varName, tempName);
@@ -2348,7 +2349,7 @@ QString WriteInitialization::trCall(const QString &str, const QString &commentHi
if (idBasedTranslations || m_option.idBased) {
result += QLatin1String("qtTrId(");
} else {
- result += QLatin1String("QApplication::translate(\"")
+ result += QLatin1String("QCoreApplication::translate(\"")
+ m_generatedClass
+ QLatin1String("\", ");
}
@@ -2427,19 +2428,13 @@ QTextStream &WriteInitialization::autoTrOutput(const DomString *str, const QStri
return m_output;
}
-bool WriteInitialization::isValidObject(const QString &name) const
-{
- return m_registeredWidgets.contains(name)
- || m_registeredActions.contains(name);
-}
-
QString WriteInitialization::findDeclaration(const QString &name)
{
const QString normalized = Driver::normalizedName(name);
- if (DomWidget *widget = m_driver->widgetByName(normalized))
+ if (const DomWidget *widget = m_driver->widgetByName(normalized))
return m_driver->findOrInsertWidget(widget);
- if (DomAction *action = m_driver->actionByName(normalized))
+ if (const DomAction *action = m_driver->actionByName(normalized))
return m_driver->findOrInsertAction(action);
if (const DomButtonGroup *group = m_driver->findButtonGroup(normalized))
return m_driver->findOrInsertButtonGroup(group);
@@ -2465,25 +2460,13 @@ void WriteInitialization::acceptConnection(DomConnection *connection)
<< ");\n";
}
-DomWidget *WriteInitialization::findWidget(QLatin1String widgetClass)
-{
- for (int i = m_widgetChain.count() - 1; i >= 0; --i) {
- DomWidget *widget = m_widgetChain.at(i);
-
- if (widget && m_uic->customWidgetsInfo()->extends(widget->attributeClass(), widgetClass))
- return widget;
- }
-
- return 0;
-}
-
static void generateMultiDirectiveBegin(QTextStream &outputStream, const QSet<QString> &directives)
{
if (directives.isEmpty())
return;
if (directives.size() == 1) {
- outputStream << "#ifndef " << *directives.cbegin() << endl;
+ outputStream << language::openQtConfig(*directives.cbegin());
return;
}
@@ -2491,7 +2474,10 @@ static void generateMultiDirectiveBegin(QTextStream &outputStream, const QSet<QS
// sort (always generate in the same order):
std::sort(list.begin(), list.end());
- outputStream << "#if !defined(" << list.join(QLatin1String(") || !defined(")) << ')' << endl;
+ outputStream << "#if " << language::qtConfig(list.constFirst());
+ for (int i = 1, size = list.size(); i < size; ++i)
+ outputStream << " || " << language::qtConfig(list.at(i));
+ outputStream << endl;
}
static void generateMultiDirectiveEnd(QTextStream &outputStream, const QSet<QString> &directives)
@@ -2548,9 +2534,11 @@ QString WriteInitialization::Item::writeSetupUi(const QString &parent, Item::Emp
QMultiMap<QString, QString>::ConstIterator it = m_setupUiData.setters.constBegin();
while (it != m_setupUiData.setters.constEnd()) {
- openIfndef(m_setupUiStream, it.key());
+ if (!it.key().isEmpty())
+ m_setupUiStream << language::openQtConfig(it.key());
m_setupUiStream << m_indent << uniqueName << it.value() << endl;
- closeIfndef(m_setupUiStream, it.key());
+ if (!it.key().isEmpty())
+ m_setupUiStream << language::closeQtConfig(it.key());
++it;
}
for (Item *child : qAsConst(m_children))
@@ -2577,14 +2565,17 @@ void WriteInitialization::Item::writeRetranslateUi(const QString &parentPath)
while (it != m_retranslateUiData.setters.constEnd()) {
const QString newDirective = it.key();
if (oldDirective != newDirective) {
- closeIfndef(m_retranslateUiStream, oldDirective);
- openIfndef(m_retranslateUiStream, newDirective);
+ if (!oldDirective.isEmpty())
+ m_retranslateUiStream << language::closeQtConfig(oldDirective);
+ if (!newDirective.isEmpty())
+ m_retranslateUiStream << language::openQtConfig(newDirective);
oldDirective = newDirective;
}
m_retranslateUiStream << m_indent << uniqueName << it.value() << endl;
++it;
}
- closeIfndef(m_retranslateUiStream, oldDirective);
+ if (!oldDirective.isEmpty())
+ m_retranslateUiStream << language::closeQtConfig(oldDirective);
for (int i = 0; i < m_children.size(); i++)
m_children[i]->writeRetranslateUi(uniqueName + QLatin1String("->child(") + QString::number(i) + QLatin1Char(')'));
diff --git a/src/tools/uic/cpp/cppwriteinitialization.h b/src/tools/uic/cpp/cppwriteinitialization.h
index cce83bd677..c408c44b40 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.h
+++ b/src/tools/uic/cpp/cppwriteinitialization.h
@@ -174,8 +174,6 @@ private:
void writeRetranslateUi(const QString &parentPath);
void addSetter(const QString &setter, const QString &directive = QString(), bool translatable = false); // don't call it if you already added *this as a child of another Item
void addChild(Item *child); // all setters should already been added
- int setupUiCount() const { return m_setupUiData.setters.count(); }
- int retranslateUiCount() const { return m_retranslateUiData.setters.count(); }
private:
struct ItemData
{
@@ -223,9 +221,6 @@ private:
void enableSorting(DomWidget *w, const QString &varName, const QString &tempName);
QString findDeclaration(const QString &name);
- DomWidget *findWidget(QLatin1String widgetClass);
-
- bool isValidObject(const QString &name) const;
private:
QString writeFontProperties(const DomFont *f);
diff --git a/src/tools/uic/customwidgetsinfo.cpp b/src/tools/uic/customwidgetsinfo.cpp
index 0ac0c2b6a3..d6a409152b 100644
--- a/src/tools/uic/customwidgetsinfo.cpp
+++ b/src/tools/uic/customwidgetsinfo.cpp
@@ -31,6 +31,8 @@
#include "ui4.h"
#include "utils.h"
+#include <utility>
+
QT_BEGIN_NAMESPACE
CustomWidgetsInfo::CustomWidgetsInfo() = default;
@@ -73,6 +75,24 @@ bool CustomWidgetsInfo::extends(const QString &classNameIn, QLatin1String baseCl
return false;
}
+bool CustomWidgetsInfo::extendsOneOf(const QString &classNameIn,
+ const QStringList &baseClassNames) const
+{
+ if (baseClassNames.contains(classNameIn))
+ return true;
+
+ QString className = classNameIn;
+ while (const DomCustomWidget *c = customWidget(className)) {
+ const QString extends = c->elementExtends();
+ if (className == extends) // Faulty legacy custom widget entries exist.
+ return false;
+ if (baseClassNames.contains(extends))
+ return true;
+ className = extends;
+ }
+ return false;
+}
+
bool CustomWidgetsInfo::isCustomWidgetContainer(const QString &className) const
{
if (const DomCustomWidget *dcw = m_customWidgets.value(className, 0))
@@ -96,5 +116,24 @@ QString CustomWidgetsInfo::customWidgetAddPageMethod(const QString &name) const
return QString();
}
+// add page methods for simple containers taking only the widget parameter
+QString CustomWidgetsInfo::simpleContainerAddPageMethod(const QString &name) const
+{
+ using AddPageMethod = std::pair<const char *, const char *>;
+
+ static AddPageMethod addPageMethods[] = {
+ {"QStackedWidget", "addWidget"},
+ {"QToolBar", "addWidget"},
+ {"QDockWidget", "setWidget"},
+ {"QScrollArea", "setWidget"},
+ {"QSplitter", "addWidget"},
+ {"QMdiArea", "addSubWindow"}
+ };
+ for (const auto &m : addPageMethods) {
+ if (extends(name, QLatin1String(m.first)))
+ return QLatin1String(m.second);
+ }
+ return QString();
+}
QT_END_NAMESPACE
diff --git a/src/tools/uic/customwidgetsinfo.h b/src/tools/uic/customwidgetsinfo.h
index 944ed59215..8a10999027 100644
--- a/src/tools/uic/customwidgetsinfo.h
+++ b/src/tools/uic/customwidgetsinfo.h
@@ -48,20 +48,16 @@ public:
void acceptCustomWidgets(DomCustomWidgets *node) override;
void acceptCustomWidget(DomCustomWidget *node) override;
- inline QStringList customWidgets() const
- { return m_customWidgets.keys(); }
-
- inline bool hasCustomWidget(const QString &name) const
- { return m_customWidgets.contains(name); }
-
inline DomCustomWidget *customWidget(const QString &name) const
{ return m_customWidgets.value(name); }
QString customWidgetAddPageMethod(const QString &name) const;
+ QString simpleContainerAddPageMethod(const QString &name) const;
QString realClassName(const QString &className) const;
bool extends(const QString &className, QLatin1String baseClassName) const;
+ bool extendsOneOf(const QString &className, const QStringList &baseClassNames) const;
bool isCustomWidgetContainer(const QString &className) const;
diff --git a/src/tools/uic/databaseinfo.h b/src/tools/uic/databaseinfo.h
index bebf139c5a..4015e39dbc 100644
--- a/src/tools/uic/databaseinfo.h
+++ b/src/tools/uic/databaseinfo.h
@@ -48,12 +48,6 @@ public:
inline QStringList connections() const
{ return m_connections; }
- inline QStringList cursors(const QString &connection) const
- { return m_cursors.value(connection); }
-
- inline QStringList fields(const QString &connection) const
- { return m_fields.value(connection); }
-
private:
QStringList m_connections;
QMap<QString, QStringList> m_cursors;
diff --git a/src/tools/uic/driver.cpp b/src/tools/uic/driver.cpp
index 91a48815fd..03fa1e17cf 100644
--- a/src/tools/uic/driver.cpp
+++ b/src/tools/uic/driver.cpp
@@ -33,6 +33,8 @@
#include <qfileinfo.h>
#include <qdebug.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
Driver::Driver()
@@ -43,39 +45,37 @@ Driver::Driver()
Driver::~Driver() = default;
-QString Driver::findOrInsertWidget(DomWidget *ui_widget)
-{
- if (!m_widgets.contains(ui_widget))
- m_widgets.insert(ui_widget, unique(ui_widget->attributeName(), ui_widget->attributeClass()));
+static inline QString spacerItemClass() { return QStringLiteral("QSpacerItem"); }
+static inline QString actionGroupClass() { return QStringLiteral("QActionGroup"); }
+static inline QString actionClass() { return QStringLiteral("QAction"); }
+static inline QString buttonGroupClass() { return QStringLiteral("QButtonGroup"); }
- return m_widgets.value(ui_widget);
+template <class DomClass>
+QString Driver::findOrInsert(DomObjectHash<DomClass> *domHash, const DomClass *dom,
+ const QString &className)
+{
+ auto it = domHash->find(dom);
+ if (it == domHash->end())
+ it = domHash->insert(dom, this->unique(dom->attributeName(), className));
+ return it.value();
}
-QString Driver::findOrInsertSpacer(DomSpacer *ui_spacer)
+QString Driver::findOrInsertWidget(const DomWidget *ui_widget)
{
- if (!m_spacers.contains(ui_spacer)) {
- QString name;
- if (ui_spacer->hasAttributeName())
- name = ui_spacer->attributeName();
- m_spacers.insert(ui_spacer, unique(name, QLatin1String("QSpacerItem")));
- }
-
- return m_spacers.value(ui_spacer);
+ return findOrInsert(&m_widgets, ui_widget, ui_widget->attributeClass());
}
-QString Driver::findOrInsertLayout(DomLayout *ui_layout)
+QString Driver::findOrInsertSpacer(const DomSpacer *ui_spacer)
{
- if (!m_layouts.contains(ui_layout)) {
- QString name;
- if (ui_layout->hasAttributeName())
- name = ui_layout->attributeName();
- m_layouts.insert(ui_layout, unique(name, ui_layout->attributeClass()));
- }
+ return findOrInsert(&m_spacers, ui_spacer, spacerItemClass());
+}
- return m_layouts.value(ui_layout);
+QString Driver::findOrInsertLayout(const DomLayout *ui_layout)
+{
+ return findOrInsert(&m_layouts, ui_layout, ui_layout->attributeClass());
}
-QString Driver::findOrInsertLayoutItem(DomLayoutItem *ui_layoutItem)
+QString Driver::findOrInsertLayoutItem(const DomLayoutItem *ui_layoutItem)
{
switch (ui_layoutItem->kind()) {
case DomLayoutItem::Widget:
@@ -93,38 +93,29 @@ QString Driver::findOrInsertLayoutItem(DomLayoutItem *ui_layoutItem)
return QString();
}
-QString Driver::findOrInsertActionGroup(DomActionGroup *ui_group)
+QString Driver::findOrInsertActionGroup(const DomActionGroup *ui_group)
{
- if (!m_actionGroups.contains(ui_group))
- m_actionGroups.insert(ui_group, unique(ui_group->attributeName(), QLatin1String("QActionGroup")));
-
- return m_actionGroups.value(ui_group);
+ return findOrInsert(&m_actionGroups, ui_group, actionGroupClass());
}
-QString Driver::findOrInsertAction(DomAction *ui_action)
+QString Driver::findOrInsertAction(const DomAction *ui_action)
{
- if (!m_actions.contains(ui_action))
- m_actions.insert(ui_action, unique(ui_action->attributeName(), QLatin1String("QAction")));
-
- return m_actions.value(ui_action);
+ return findOrInsert(&m_actions, ui_action, actionClass());
}
QString Driver::findOrInsertButtonGroup(const DomButtonGroup *ui_group)
{
- ButtonGroupNameHash::iterator it = m_buttonGroups.find(ui_group);
- if (it == m_buttonGroups.end())
- it = m_buttonGroups.insert(ui_group, unique(ui_group->attributeName(), QLatin1String("QButtonGroup")));
- return it.value();
+ return findOrInsert(&m_buttonGroups, ui_group, buttonGroupClass());
}
// Find a group by its non-uniqified name
const DomButtonGroup *Driver::findButtonGroup(const QString &attributeName) const
{
- const ButtonGroupNameHash::const_iterator cend = m_buttonGroups.constEnd();
- for (ButtonGroupNameHash::const_iterator it = m_buttonGroups.constBegin(); it != cend; ++it)
+ for (auto it = m_buttonGroups.cbegin(), end = m_buttonGroups.cend(); it != end; ++it) {
if (it.key()->attributeName() == attributeName)
return it.key();
- return 0;
+ }
+ return nullptr;
}
@@ -136,11 +127,9 @@ QString Driver::findOrInsertName(const QString &name)
QString Driver::normalizedName(const QString &name)
{
QString result = name;
- QChar *data = result.data();
- for (int i = name.size(); --i >= 0; ++data) {
- if (!data->isLetterOrNumber())
- *data = QLatin1Char('_');
- }
+ std::replace_if(result.begin(), result.end(),
+ [] (QChar c) { return !c.isLetterOrNumber(); },
+ QLatin1Char('_'));
return result;
}
@@ -149,23 +138,21 @@ QString Driver::unique(const QString &instanceName, const QString &className)
QString name;
bool alreadyUsed = false;
- if (instanceName.size()) {
- int id = 1;
- name = instanceName;
- name = normalizedName(name);
+ if (!instanceName.isEmpty()) {
+ name = normalizedName(instanceName);
QString base = name;
- while (m_nameRepository.contains(name)) {
+ for (int id = 1; m_nameRepository.contains(name); ++id) {
alreadyUsed = true;
- name = base + QString::number(id++);
+ name = base + QString::number(id);
}
- } else if (className.size()) {
+ } else if (!className.isEmpty()) {
name = unique(qtify(className));
} else {
name = unique(QLatin1String("var"));
}
- if (alreadyUsed && className.size()) {
+ if (alreadyUsed && !className.isEmpty()) {
fprintf(stderr, "%s: Warning: The name '%s' (%s) is already in use, defaulting to '%s'.\n",
qPrintable(m_option.messagePrefix()),
qPrintable(instanceName), qPrintable(className),
@@ -181,17 +168,10 @@ QString Driver::qtify(const QString &name)
QString qname = name;
if (qname.at(0) == QLatin1Char('Q') || qname.at(0) == QLatin1Char('K'))
- qname = qname.mid(1);
+ qname.remove(0, 1);
- int i=0;
- while (i < qname.length()) {
- if (qname.at(i).toLower() != qname.at(i))
- qname[i] = qname.at(i).toLower();
- else
- break;
-
- ++i;
- }
+ for (int i = 0, size = qname.size(); i < size && qname.at(i).isUpper(); ++i)
+ qname[i] = qname.at(i).toLower();
return qname;
}
@@ -306,56 +286,17 @@ bool Driver::uic(const QString &fileName, QTextStream *out)
return rtn;
}
-void Driver::reset()
-{
- Q_ASSERT( m_output == 0 );
-
- m_option = Option();
- m_output = 0;
- m_problems.clear();
-
- QStringList m_problems;
-
- m_widgets.clear();
- m_spacers.clear();
- m_layouts.clear();
- m_actionGroups.clear();
- m_actions.clear();
- m_nameRepository.clear();
- m_pixmaps.clear();
-}
-
-void Driver::insertPixmap(const QString &pixmap)
-{
- m_pixmaps.insert(pixmap, true);
-}
-
-bool Driver::containsPixmap(const QString &pixmap) const
-{
- return m_pixmaps.contains(pixmap);
-}
-
-DomWidget *Driver::widgetByName(const QString &name) const
+const DomWidget *Driver::widgetByName(const QString &name) const
{
return m_widgets.key(name);
}
-DomSpacer *Driver::spacerByName(const QString &name) const
-{
- return m_spacers.key(name);
-}
-
-DomLayout *Driver::layoutByName(const QString &name) const
-{
- return m_layouts.key(name);
-}
-
-DomActionGroup *Driver::actionGroupByName(const QString &name) const
+const DomActionGroup *Driver::actionGroupByName(const QString &name) const
{
return m_actionGroups.key(name);
}
-DomAction *Driver::actionByName(const QString &name) const
+const DomAction *Driver::actionByName(const QString &name) const
{
return m_actions.key(name);
}
diff --git a/src/tools/uic/driver.h b/src/tools/uic/driver.h
index 1563bdbd83..1303d0bf8a 100644
--- a/src/tools/uic/driver.h
+++ b/src/tools/uic/driver.h
@@ -49,7 +49,7 @@ class DomButtonGroup;
class Driver
{
- Q_DISABLE_COPY(Driver)
+ Q_DISABLE_COPY_MOVE(Driver)
public:
Driver();
virtual ~Driver();
@@ -63,13 +63,6 @@ public:
inline QTextStream &output() const { return *m_output; }
inline Option &option() { return m_option; }
- // initialization
- void reset();
-
- // error
- inline QStringList problems() { return m_problems; }
- inline void addProblem(const QString &problem) { m_problems.append(problem); }
-
// utils
static QString headerFileName(const QString &fileName);
QString headerFileName() const;
@@ -80,50 +73,42 @@ public:
const QString &className=QString());
// symbol table
- QString findOrInsertWidget(DomWidget *ui_widget);
- QString findOrInsertSpacer(DomSpacer *ui_spacer);
- QString findOrInsertLayout(DomLayout *ui_layout);
- QString findOrInsertLayoutItem(DomLayoutItem *ui_layoutItem);
+ QString findOrInsertWidget(const DomWidget *ui_widget);
+ QString findOrInsertSpacer(const DomSpacer *ui_spacer);
+ QString findOrInsertLayout(const DomLayout *ui_layout);
+ QString findOrInsertLayoutItem(const DomLayoutItem *ui_layoutItem);
QString findOrInsertName(const QString &name);
- QString findOrInsertActionGroup(DomActionGroup *ui_group);
- QString findOrInsertAction(DomAction *ui_action);
+ QString findOrInsertActionGroup(const DomActionGroup *ui_group);
+ QString findOrInsertAction(const DomAction *ui_action);
QString findOrInsertButtonGroup(const DomButtonGroup *ui_group);
// Find a group by its non-uniqified name
const DomButtonGroup *findButtonGroup(const QString &attributeName) const;
- inline bool hasName(const QString &name) const
- { return m_nameRepository.contains(name); }
-
- DomWidget *widgetByName(const QString &name) const;
- DomSpacer *spacerByName(const QString &name) const;
- DomLayout *layoutByName(const QString &name) const;
- DomActionGroup *actionGroupByName(const QString &name) const;
- DomAction *actionByName(const QString &name) const;
-
- // pixmap
- void insertPixmap(const QString &pixmap);
- bool containsPixmap(const QString &pixmap) const;
+ const DomWidget *widgetByName(const QString &name) const;
+ const DomActionGroup *actionGroupByName(const QString &name) const;
+ const DomAction *actionByName(const QString &name) const;
bool useIdBasedTranslations() const { return m_idBasedTranslations; }
void setUseIdBasedTranslations(bool u) { m_idBasedTranslations = u; }
private:
+ template <class DomClass> using DomObjectHash = QHash<const DomClass *, QString>;
+
+ template <class DomClass>
+ QString findOrInsert(DomObjectHash<DomClass> *domHash, const DomClass *dom, const QString &className);
+
Option m_option;
QTextStream m_stdout;
QTextStream *m_output;
- QStringList m_problems;
-
// symbol tables
- QHash<DomWidget*, QString> m_widgets;
- QHash<DomSpacer*, QString> m_spacers;
- QHash<DomLayout*, QString> m_layouts;
- QHash<DomActionGroup*, QString> m_actionGroups;
- typedef QHash<const DomButtonGroup*, QString> ButtonGroupNameHash;
- ButtonGroupNameHash m_buttonGroups;
- QHash<DomAction*, QString> m_actions;
+ DomObjectHash<DomWidget> m_widgets;
+ DomObjectHash<DomSpacer> m_spacers;
+ DomObjectHash<DomLayout> m_layouts;
+ DomObjectHash<DomActionGroup> m_actionGroups;
+ DomObjectHash<DomButtonGroup> m_buttonGroups;
+ DomObjectHash<DomAction> m_actions;
QHash<QString, bool> m_nameRepository;
- QHash<QString, bool> m_pixmaps;
bool m_idBasedTranslations = false;
};
diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp
index 41bd62bbf4..0516b854ff 100644
--- a/src/tools/uic/main.cpp
+++ b/src/tools/uic/main.cpp
@@ -131,7 +131,7 @@ int runUic(int argc, char *argv[])
QTextStream *out = 0;
QFile f;
- if (driver.option().outputFile.size()) {
+ if (!driver.option().outputFile.isEmpty()) {
f.setFileName(driver.option().outputFile);
if (!f.open(QIODevice::WriteOnly | QFile::Text)) {
fprintf(stderr, "Could not create output file\n");
diff --git a/src/tools/uic/shared/language.cpp b/src/tools/uic/shared/language.cpp
new file mode 100644
index 0000000000..730e1562bc
--- /dev/null
+++ b/src/tools/uic/shared/language.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "language.h"
+
+#include <QtCore/qtextstream.h>
+
+namespace language {
+
+QTextStream &operator<<(QTextStream &str, const qtConfig &c)
+{
+ str << "QT_CONFIG(" << c.parameter() << ')';
+ return str;
+}
+
+QTextStream &operator<<(QTextStream &str, const openQtConfig &c)
+{
+ str << "#if " << qtConfig(c.parameter()) << '\n';
+ return str;
+}
+
+QTextStream &operator<<(QTextStream &str, const closeQtConfig &c)
+{
+ str << "#endif // " << qtConfig(c.parameter()) << '\n';
+ return str;
+}
+
+struct EnumLookup
+{
+ int value;
+ const char *valueString;
+};
+
+template <int N>
+const char *lookupEnum(const EnumLookup(&array)[N], int value, int defaultIndex = 0)
+{
+ for (int i = 0; i < N; ++i) {
+ if (value == array[i].value)
+ return array[i].valueString;
+ }
+ const char *defaultValue = array[defaultIndex].valueString;
+ qWarning("uic: Warning: Invalid enumeration value %d, defaulting to %s",
+ value, defaultValue);
+ return defaultValue;
+}
+
+const char *toolbarArea(int v)
+{
+ static const EnumLookup toolBarAreas[] =
+ {
+ {0, "NoToolBarArea"},
+ {0x1, "LeftToolBarArea"},
+ {0x2, "RightToolBarArea"},
+ {0x4, "TopToolBarArea"},
+ {0x8, "BottomToolBarArea"},
+ {0xf, "AllToolBarAreas"}
+ };
+ return lookupEnum(toolBarAreas, v);
+}
+
+const char *sizePolicy(int v)
+{
+ static const EnumLookup sizePolicies[] =
+ {
+ {0, "Fixed"},
+ {0x1, "Minimum"},
+ {0x4, "Maximum"},
+ {0x5, "Preferred"},
+ {0x3, "MinimumExpanding"},
+ {0x7, "Expanding"},
+ {0xD, "Ignored"}
+ };
+ return lookupEnum(sizePolicies, v, 3);
+}
+
+const char *dockWidgetArea(int v)
+{
+ static const EnumLookup dockWidgetAreas[] =
+ {
+ {0, "NoDockWidgetArea"},
+ {0x1, "LeftDockWidgetArea"},
+ {0x2, "RightDockWidgetArea"},
+ {0x4, "TopDockWidgetArea"},
+ {0x8, "BottomDockWidgetArea"},
+ {0xf, "AllDockWidgetAreas"}
+ };
+ return lookupEnum(dockWidgetAreas, v);
+}
+
+const char *paletteColorRole(int v)
+{
+ static const EnumLookup colorRoles[] =
+ {
+ {0, "WindowText"},
+ {1, "Button"},
+ {2, "Light"},
+ {3, "Midlight"},
+ {4, "Dark"},
+ {5, "Mid"},
+ {6, "Text"},
+ {7, "BrightText"},
+ {8, "ButtonText"},
+ {9, "Base"},
+ {10, "Window"},
+ {11, "Shadow"},
+ {12, "Highlight"},
+ {13, "HighlightedText"},
+ {14, "Link"},
+ {15, "LinkVisited"},
+ {16, "AlternateBase"},
+ {17, "NoRole"},
+ {18, "ToolTipBase"},
+ {19, "ToolTipText"},
+ {20, "PlaceholderText"},
+ };
+ return lookupEnum(colorRoles, v);
+}
+
+} // namespace language
diff --git a/src/tools/uic/shared/language.h b/src/tools/uic/shared/language.h
new file mode 100644
index 0000000000..e7201b6529
--- /dev/null
+++ b/src/tools/uic/shared/language.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LANGUAGE_H
+#define LANGUAGE_H
+
+#include <QtCore/qstringview.h>
+
+QT_FORWARD_DECLARE_CLASS(QTextStream)
+
+namespace language {
+
+// Base class for streamable objects with one QStringView parameter
+class StringViewStreamable
+{
+public:
+ StringViewStreamable(QStringView parameter) : m_parameter(parameter) {}
+
+ QStringView parameter() const { return m_parameter; }
+
+private:
+ QStringView m_parameter;
+};
+
+class qtConfig : public StringViewStreamable
+{
+public:
+ qtConfig(QStringView name) : StringViewStreamable(name) {}
+};
+
+QTextStream &operator<<(QTextStream &str, const qtConfig &c);
+
+class openQtConfig : public StringViewStreamable
+{
+public:
+ openQtConfig(QStringView name) : StringViewStreamable(name) {}
+};
+
+QTextStream &operator<<(QTextStream &str, const openQtConfig &c);
+
+class closeQtConfig : public StringViewStreamable
+{
+public:
+ closeQtConfig(QStringView name) : StringViewStreamable(name) {}
+};
+
+QTextStream &operator<<(QTextStream &, const closeQtConfig &c);
+
+const char *toolbarArea(int v);
+const char *sizePolicy(int v);
+const char *dockWidgetArea(int v);
+const char *paletteColorRole(int v);
+
+} // namespace language
+
+#endif // LANGUAGE_H
diff --git a/src/tools/uic/shared/shared.pri b/src/tools/uic/shared/shared.pri
new file mode 100644
index 0000000000..dce2af8bf1
--- /dev/null
+++ b/src/tools/uic/shared/shared.pri
@@ -0,0 +1,5 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += $$PWD/language.h
+
+SOURCES += $$PWD/language.cpp
diff --git a/src/tools/uic/treewalker.h b/src/tools/uic/treewalker.h
index 43d4633d83..7e8eda57d9 100644
--- a/src/tools/uic/treewalker.h
+++ b/src/tools/uic/treewalker.h
@@ -101,7 +101,6 @@ struct TreeWalker
virtual void acceptTime(DomTime *time);
virtual void acceptDateTime(DomDateTime *dateTime);
virtual void acceptProperty(DomProperty *property);
- typedef QVector<DomScript *> DomScripts;
typedef QVector<DomWidget *> DomWidgets;
virtual void acceptIncludes(DomIncludes *includes);
virtual void acceptInclude(DomInclude *incl);
diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp
index a5b331192f..225dc6aeb2 100644
--- a/src/tools/uic/uic.cpp
+++ b/src/tools/uic/uic.cpp
@@ -106,13 +106,13 @@ bool Uic::printDependencies()
void Uic::writeCopyrightHeader(DomUI *ui)
{
QString comment = ui->elementComment();
- if (comment.size())
+ if (!comment.isEmpty())
out << "/*\n" << comment << "\n*/\n\n";
out << "/********************************************************************************\n";
out << "** Form generated from reading UI file '" << QFileInfo(opt.inputFile).fileName() << "'\n";
out << "**\n";
- out << "** Created by: Qt User Interface Compiler version " << QLatin1String(QT_VERSION_STR) << "\n";
+ out << "** Created by: Qt User Interface Compiler version " << QT_VERSION_STR << "\n";
out << "**\n";
out << "** WARNING! All changes made in this file will be lost when recompiling UI file!\n";
out << "********************************************************************************/\n\n";
@@ -243,55 +243,34 @@ void Uic::writeHeaderProtectionEnd()
out << "#endif // " << h << "\n";
}
-bool Uic::isMainWindow(const QString &className) const
-{
- return customWidgetsInfo()->extends(className, QLatin1String("QMainWindow"));
-}
-
-bool Uic::isToolBar(const QString &className) const
-{
- return customWidgetsInfo()->extends(className, QLatin1String("QToolBar"));
-}
-
bool Uic::isButton(const QString &className) const
{
- return customWidgetsInfo()->extends(className, QLatin1String("QRadioButton"))
- || customWidgetsInfo()->extends(className, QLatin1String("QToolButton"))
- || customWidgetsInfo()->extends(className, QLatin1String("QCheckBox"))
- || customWidgetsInfo()->extends(className, QLatin1String("QPushButton"))
- || customWidgetsInfo()->extends(className, QLatin1String("QCommandLinkButton"));
+ static const QStringList buttons = {
+ QLatin1String("QRadioButton"), QLatin1String("QToolButton"),
+ QLatin1String("QCheckBox"), QLatin1String("QPushButton"),
+ QLatin1String("QCommandLinkButton")
+ };
+ return customWidgetsInfo()->extendsOneOf(className, buttons);
}
bool Uic::isContainer(const QString &className) const
{
- return customWidgetsInfo()->extends(className, QLatin1String("QStackedWidget"))
- || customWidgetsInfo()->extends(className, QLatin1String("QToolBox"))
- || customWidgetsInfo()->extends(className, QLatin1String("QTabWidget"))
- || customWidgetsInfo()->extends(className, QLatin1String("QScrollArea"))
- || customWidgetsInfo()->extends(className, QLatin1String("QMdiArea"))
- || customWidgetsInfo()->extends(className, QLatin1String("QWizard"))
- || customWidgetsInfo()->extends(className, QLatin1String("QDockWidget"));
-}
-
-bool Uic::isCustomWidgetContainer(const QString &className) const
-{
- return customWidgetsInfo()->isCustomWidgetContainer(className);
-}
-
-bool Uic::isStatusBar(const QString &className) const
-{
- return customWidgetsInfo()->extends(className, QLatin1String("QStatusBar"));
-}
-
-bool Uic::isMenuBar(const QString &className) const
-{
- return customWidgetsInfo()->extends(className, QLatin1String("QMenuBar"));
+ static const QStringList containers = {
+ QLatin1String("QStackedWidget"), QLatin1String("QToolBox"),
+ QLatin1String("QTabWidget"), QLatin1String("QScrollArea"),
+ QLatin1String("QMdiArea"), QLatin1String("QWizard"),
+ QLatin1String("QDockWidget")
+ };
+
+ return customWidgetsInfo()->extendsOneOf(className, containers);
}
bool Uic::isMenu(const QString &className) const
{
- return customWidgetsInfo()->extends(className, QLatin1String("QMenu"))
- || customWidgetsInfo()->extends(className, QLatin1String("QPopupMenu"));
+ static const QStringList menus = {
+ QLatin1String("QMenu"), QLatin1String("QPopupMenu")
+ };
+ return customWidgetsInfo()->extendsOneOf(className, menus);
}
QT_END_NAMESPACE
diff --git a/src/tools/uic/uic.h b/src/tools/uic/uic.h
index 4c961aa0a5..af5f42c6db 100644
--- a/src/tools/uic/uic.h
+++ b/src/tools/uic/uic.h
@@ -53,7 +53,7 @@ struct Option;
class Uic
{
- Q_DISABLE_COPY(Uic)
+ Q_DISABLE_COPY_MOVE(Uic)
public:
Uic(Driver *driver);
~Uic();
@@ -85,13 +85,8 @@ public:
bool write(DomUI *ui);
- bool isMainWindow(const QString &className) const;
- bool isToolBar(const QString &className) const;
- bool isStatusBar(const QString &className) const;
bool isButton(const QString &className) const;
bool isContainer(const QString &className) const;
- bool isCustomWidgetContainer(const QString &className) const;
- bool isMenuBar(const QString &className) const;
bool isMenu(const QString &className) const;
private:
diff --git a/src/tools/uic/uic.pri b/src/tools/uic/uic.pri
index 3f0bab05dd..1c9098dcf9 100644
--- a/src/tools/uic/uic.pri
+++ b/src/tools/uic/uic.pri
@@ -5,7 +5,6 @@ HEADERS += \
$$PWD/customwidgetsinfo.h \
$$PWD/databaseinfo.h \
$$PWD/driver.h \
- $$PWD/globaldefs.h \
$$PWD/option.h \
$$PWD/treewalker.h \
$$PWD/utils.h \
diff --git a/src/tools/uic/uic.pro b/src/tools/uic/uic.pro
index 18511395d9..4469ce50e5 100644
--- a/src/tools/uic/uic.pro
+++ b/src/tools/uic/uic.pro
@@ -5,6 +5,7 @@ option(host_build)
DEFINES += QT_UIC QT_NO_CAST_FROM_ASCII QT_NO_FOREACH
include(uic.pri)
+include(shared/shared.pri)
include(cpp/cpp.pri)
HEADERS += uic.h
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 7132bb3297..c0bacd553d 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -646,7 +646,7 @@ void QColorWell::mouseMoveEvent(QMouseEvent *e)
drg->setMimeData(mime);
drg->setPixmap(pix);
mousePressed = false;
- drg->start();
+ drg->exec(Qt::CopyAction);
}
#endif
}
@@ -842,8 +842,8 @@ void QColorLuminancePicker::paintEvent(QPaintEvent *)
p.drawPixmap(1, coff, *pix);
const QPalette &g = palette();
qDrawShadePanel(&p, r, g, true);
- p.setPen(g.foreground().color());
- p.setBrush(g.foreground());
+ p.setPen(g.windowText().color());
+ p.setBrush(g.windowText());
QPolygon a;
int y = val2y(val);
a.setPoints(3, w, y, w+5, y+5, w+5, y-5);
@@ -1131,7 +1131,7 @@ void QColorShowLabel::mouseMoveEvent(QMouseEvent *e)
drg->setMimeData(mime);
drg->setPixmap(pix);
mousePressed = false;
- drg->start();
+ drg->exec(Qt::CopyAction);
}
#endif
}
@@ -1179,7 +1179,8 @@ QColorShower::QColorShower(QColorDialog *parent)
curQColor = Qt::white;
gl = new QGridLayout(this);
- gl->setMargin(gl->spacing());
+ const int s = gl->spacing();
+ gl->setContentsMargins(s, s, s, s);
lab = new QColorShowLabel(this);
#ifdef QT_SMALL_COLORDIALOG
@@ -1807,7 +1808,7 @@ void QColorDialogPrivate::initWidgets()
rightLay->addStretch();
cs = new QColorShower(q);
- pickLay->setMargin(cs->gl->margin());
+ pickLay->setContentsMargins(cs->gl->contentsMargins());
QObject::connect(cs, SIGNAL(newCol(QRgb)), q, SLOT(_q_newColorTypedIn(QRgb)));
QObject::connect(cs, SIGNAL(currentColorChanged(QColor)),
q, SIGNAL(currentColorChanged(QColor)));
@@ -1816,7 +1817,7 @@ void QColorDialogPrivate::initWidgets()
#else
rightLay->addWidget(cs);
if (leftLay)
- leftLay->addSpacing(cs->gl->margin());
+ leftLay->addSpacing(cs->gl->contentsMargins().right());
#endif
buttons = new QDialogButtonBox(q);
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp
index 1c10e3e786..caab6c16ba 100644
--- a/src/widgets/dialogs/qdialog.cpp
+++ b/src/widgets/dialogs/qdialog.cpp
@@ -148,7 +148,7 @@ bool QDialogPrivate::canBeNativeDialog() const
/*!
\internal
- Properly hides dialog and sets the \p resultCode
+ Properly hides dialog and sets the \a resultCode.
*/
void QDialogPrivate::hide(int resultCode)
{
@@ -164,8 +164,8 @@ void QDialogPrivate::hide(int resultCode)
/*!
\internal
- Emits finished() signal with \p resultCode. If the \p dialogCode
- is equal to 0 emits rejected(), if the \p dialogCode is equal to
+ Emits finished() signal with \a resultCode. If the \a dialogCode
+ is equal to 0 emits rejected(), if the \a dialogCode is equal to
1 emits accepted().
*/
void QDialogPrivate::finalize(int resultCode, int dialogCode)
@@ -429,7 +429,7 @@ QDialog::~QDialog()
/*!
\internal
This function is called by the push button \a pushButton when it
- becomes the default button. If \a pushButton is 0, the dialogs
+ becomes the default button. If \a pushButton is \nullptr, the dialogs
default default button becomes the default button. This is what a
push button calls when it loses focus.
*/
@@ -767,12 +767,31 @@ void QDialog::setVisible(bool visible)
if (!testAttribute(Qt::WA_DontShowOnScreen) && d->canBeNativeDialog() && d->setNativeDialogVisible(visible))
return;
+ // We should not block windows by the invisible modal dialog
+ // if a platform-specific dialog is implemented as an in-process
+ // Qt window, because in this case it will also be blocked.
+ const bool dontBlockWindows = testAttribute(Qt::WA_DontShowOnScreen)
+ && d->styleHint(QPlatformDialogHelper::DialogIsQtWindow).toBool();
+ Qt::WindowModality oldModality;
+ bool wasModalitySet;
+
+ if (dontBlockWindows) {
+ oldModality = windowModality();
+ wasModalitySet = testAttribute(Qt::WA_SetWindowModality);
+ setWindowModality(Qt::NonModal);
+ }
+
if (visible) {
if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
return;
QWidget::setVisible(visible);
+#if QT_DEPRECATED_SINCE(5, 13)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
showExtension(d->doShowExtension);
+QT_WARNING_POP
+#endif
QWidget *fw = window()->focusWidget();
if (!fw)
fw = this;
@@ -833,6 +852,11 @@ void QDialog::setVisible(bool visible)
d->eventLoop->exit();
}
+ if (dontBlockWindows) {
+ setWindowModality(oldModality);
+ setAttribute(Qt::WA_SetWindowModality, wasModalitySet);
+ }
+
#if QT_CONFIG(pushbutton)
const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
if (d->mainDef && isActiveWindow()
@@ -934,6 +958,7 @@ void QDialog::adjustPosition(QWidget* w)
move(p);
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -1002,7 +1027,7 @@ void QDialog::setExtension(QWidget* extension)
/*!
\obsolete
- Returns the dialog's extension or 0 if no extension has been
+ Returns the dialog's extension or \nullptr if no extension has been
defined.
Instead of using this functionality, we recommend that you simply call
@@ -1078,7 +1103,7 @@ void QDialog::showExtension(bool showIt)
#endif
}
}
-
+#endif
/*! \reimp */
QSize QDialog::sizeHint() const
diff --git a/src/widgets/dialogs/qdialog.h b/src/widgets/dialogs/qdialog.h
index 7f267dd939..ce2194a1de 100644
--- a/src/widgets/dialogs/qdialog.h
+++ b/src/widgets/dialogs/qdialog.h
@@ -69,11 +69,12 @@ public:
void setVisible(bool visible) override;
- void setOrientation(Qt::Orientation orientation);
- Qt::Orientation orientation() const;
-
- void setExtension(QWidget* extension);
- QWidget* extension() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use show/hide on the affected widget instead") void setOrientation(Qt::Orientation orientation);
+ QT_DEPRECATED_X("Use show/hide on the affected widget instead") Qt::Orientation orientation() const;
+ QT_DEPRECATED_X("Use show/hide on the affected widget instead") void setExtension(QWidget* extension);
+ QT_DEPRECATED_X("Use show/hide on the affected widget instead") QWidget* extension() const;
+#endif
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
@@ -96,7 +97,9 @@ public Q_SLOTS:
virtual void accept();
virtual void reject();
- void showExtension(bool);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use show/hide on the affected widget instead") void showExtension(bool);
+#endif
protected:
QDialog(QDialogPrivate &, QWidget *parent, Qt::WindowFlags f = Qt::WindowFlags());
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index eb3479b3e0..f772eb1241 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -73,6 +73,9 @@
#elif defined(Q_OS_WIN)
# include <QtCore/qt_windows.h>
#endif
+#if defined(Q_OS_WASM)
+#include <private/qwasmlocalfileaccess_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -584,10 +587,13 @@ void QFileDialogPrivate::retranslateWindowTitle()
return;
if (q->acceptMode() == QFileDialog::AcceptOpen) {
const QFileDialog::FileMode fileMode = q->fileMode();
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
if (fileMode == QFileDialog::DirectoryOnly || fileMode == QFileDialog::Directory)
q->setWindowTitle(QFileDialog::tr("Find Directory"));
else
q->setWindowTitle(QFileDialog::tr("Open"));
+QT_WARNING_POP
} else
q->setWindowTitle(QFileDialog::tr("Save As"));
@@ -611,7 +617,10 @@ void QFileDialogPrivate::updateFileNameLabel()
setLabelTextControl(QFileDialog::FileName, options->labelText(QFileDialogOptions::FileName));
} else {
switch (q_func()->fileMode()) {
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
case QFileDialog::DirectoryOnly:
+QT_WARNING_POP
case QFileDialog::Directory:
setLabelTextControl(QFileDialog::FileName, QFileDialog::tr("Directory:"));
break;
@@ -639,7 +648,10 @@ void QFileDialogPrivate::updateOkButtonText(bool saveAsOnFolder)
return;
} else {
switch (q->fileMode()) {
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
case QFileDialog::DirectoryOnly:
+QT_WARNING_POP
case QFileDialog::Directory:
setLabelTextControl(QFileDialog::Accept, QFileDialog::tr("&Choose"));
break;
@@ -1359,6 +1371,7 @@ void QFileDialog::setNameFilter(const QString &filter)
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\property QFileDialog::nameFilterDetailsVisible
\obsolete
@@ -1380,6 +1393,7 @@ bool QFileDialog::isNameFilterDetailsVisible() const
{
return !testOption(HideNameFilterDetails);
}
+#endif
/*
@@ -1704,7 +1718,10 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode)
d->options->setFileMode(static_cast<QFileDialogOptions::FileMode>(mode));
// keep ShowDirsOnly option in sync with fileMode (BTW, DirectoryOnly is obsolete)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
setOption(ShowDirsOnly, mode == DirectoryOnly);
+QT_WARNING_POP
if (!d->usingWidgets())
return;
@@ -1722,11 +1739,14 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode)
// set filter
d->model->setFilter(d->filterForMode(filter()));
// setup file type for directory
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
if (mode == DirectoryOnly || mode == Directory) {
d->qFileDialogUi->fileTypeCombo->clear();
d->qFileDialogUi->fileTypeCombo->addItem(tr("Directories"));
d->qFileDialogUi->fileTypeCombo->setEnabled(false);
}
+QT_WARNING_POP
d->updateFileNameLabel();
d->updateOkButtonText();
d->qFileDialogUi->fileTypeCombo->setEnabled(!testOption(ShowDirsOnly));
@@ -1859,6 +1879,7 @@ QFileDialog::AcceptMode QFileDialog::acceptMode() const
return static_cast<AcceptMode>(d->options->acceptMode());
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\property QFileDialog::readOnly
\obsolete
@@ -1918,6 +1939,7 @@ bool QFileDialog::confirmOverwrite() const
{
return !testOption(DontConfirmOverwrite);
}
+#endif
/*!
\property QFileDialog::defaultSuffix
@@ -2122,8 +2144,8 @@ QString QFileDialog::labelText(DialogLabel label) const
\snippet code/src_gui_dialogs_qfiledialog.cpp 8
The function creates a modal file dialog with the given \a parent widget.
- If \a parent is not 0, the dialog will be shown centered over the parent
- widget.
+ If \a parent is not \nullptr, the dialog will be shown centered over the
+ parent widget.
The file dialog's working directory will be set to \a dir. If \a dir
includes a file name, the file will be selected. Only files that match the
@@ -2145,8 +2167,8 @@ QString QFileDialog::labelText(DialogLabel label) const
native file dialog and not a QFileDialog.
On Windows the dialog will spin a blocking modal event loop that will not
- dispatch any QTimers, and if \a parent is not 0 then it will position the
- dialog just below the parent's title bar.
+ dispatch any QTimers, and if \a parent is not \nullptr then it will position
+ the dialog just below the parent's title bar.
On Unix/X11, the normal behavior of the file dialog is to resolve and
follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
@@ -2235,8 +2257,8 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent,
\snippet code/src_gui_dialogs_qfiledialog.cpp 9
This function creates a modal file dialog with the given \a parent widget.
- If \a parent is not 0, the dialog will be shown centered over the parent
- widget.
+ If \a parent is not \nullptr, the dialog will be shown centered over the
+ parent widget.
The file dialog's working directory will be set to \a dir. If \a dir
includes a file name, the file will be selected. The filter is set to
@@ -2254,8 +2276,8 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent,
native file dialog and not a QFileDialog.
On Windows the dialog will spin a blocking modal event loop that will not
- dispatch any QTimers, and if \a parent is not 0 then it will position the
- dialog just below the parent's title bar.
+ dispatch any QTimers, and if \a parent is not \nullptr then it will position
+ the dialog just below the parent's title bar.
On Unix/X11, the normal behavior of the file dialog is to resolve and
follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
@@ -2344,12 +2366,91 @@ QList<QUrl> QFileDialog::getOpenFileUrls(QWidget *parent,
}
/*!
+ This is a convenience static function that will return the content of a file
+ selected by the user.
+
+ This function is used to access local files on Qt for WebAssembly, where the web
+ sandbox places restrictions on how such access may happen. Its implementation will
+ make the browser display a native file dialog, where the user makes the file selection.
+
+ It can also be used on other platforms, where it will fall back to using QFileDialog.
+
+ The function is asynchronous and returns immediately. The \a fileOpenCompleted
+ callback will be called when a file has been selected and its contents has been
+ read into memory.
+
+ \snippet code/src_gui_dialogs_qfiledialog.cpp 14
+ \since 5.13
+*/
+void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::function<void(const QString &, const QByteArray &)> &fileOpenCompleted)
+{
+#ifdef Q_OS_WASM
+ auto openFileImpl = std::make_shared<std::function<void(void)>>();
+ QString fileName;
+ QByteArray fileContent;
+ *openFileImpl = [=]() mutable {
+ auto fileDialogClosed = [&](bool fileSelected) {
+ if (!fileSelected) {
+ fileOpenCompleted(fileName, fileContent);
+ openFileImpl.reset();
+ }
+ };
+ auto acceptFile = [&](uint64_t size, const std::string name) -> char * {
+ const uint64_t twoGB = 1ULL << 31; // QByteArray limit
+ if (size > twoGB)
+ return nullptr;
+
+ fileName = QString::fromStdString(name);
+ fileContent.resize(size);
+ return fileContent.data();
+ };
+ auto fileContentReady = [&]() mutable {
+ fileOpenCompleted(fileName, fileContent);
+ openFileImpl.reset();
+ };
+
+ auto qtFilterStringToWebAcceptString = [](const QString &qtString) {
+ // The Qt and Web name filter string formats are similar, but
+ // not identical.
+ return qtString.toStdString(); // ### TODO
+ };
+
+ QWasmLocalFileAccess::openFile(qtFilterStringToWebAcceptString(nameFilter), fileDialogClosed, acceptFile, fileContentReady);
+ };
+
+ (*openFileImpl)();
+#else
+ QFileDialog *dialog = new QFileDialog();
+ dialog->selectNameFilter(nameFilter);
+
+ auto fileSelected = [=](const QString &fileName) {
+ QByteArray fileContent;
+ if (!fileName.isNull()) {
+ QFile selectedFile(fileName);
+ selectedFile.open(QIODevice::ReadOnly);
+ fileContent = selectedFile.readAll();
+ }
+ fileOpenCompleted(fileName, fileContent);
+ };
+
+ auto dialogClosed = [=](int code) {
+ Q_UNUSED(code);
+ delete dialog;
+ };
+
+ connect(dialog, &QFileDialog::fileSelected, fileSelected);
+ connect(dialog, &QFileDialog::finished, dialogClosed);
+ dialog->show();
+#endif
+}
+
+/*!
This is a convenience static function that will return a file name selected
by the user. The file does not have to exist.
It creates a modal file dialog with the given \a parent widget. If
- \a parent is not 0, the dialog will be shown centered over the parent
- widget.
+ \a parent is not \nullptr, the dialog will be shown centered over the
+ parent widget.
\snippet code/src_gui_dialogs_qfiledialog.cpp 11
@@ -2375,9 +2476,9 @@ QList<QUrl> QFileDialog::getOpenFileUrls(QWidget *parent,
native file dialog and not a QFileDialog.
On Windows the dialog will spin a blocking modal event loop that will not
- dispatch any QTimers, and if \a parent is not 0 then it will position the
- dialog just below the parent's title bar. On \macos, with its native file
- dialog, the filter argument is ignored.
+ dispatch any QTimers, and if \a parent is not \nullptr then it will
+ position the dialog just below the parent's title bar. On \macos, with its
+ native file dialog, the filter argument is ignored.
On Unix/X11, the normal behavior of the file dialog is to resolve and
follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
@@ -2467,8 +2568,8 @@ QUrl QFileDialog::getSaveFileUrl(QWidget *parent,
\snippet code/src_gui_dialogs_qfiledialog.cpp 12
This function creates a modal file dialog with the given \a parent widget.
- If \a parent is not 0, the dialog will be shown centered over the parent
- widget.
+ If \a parent is not \nullptr, the dialog will be shown centered over the
+ parent widget.
The dialog's working directory is set to \a dir, and the caption is set to
\a caption. Either of these may be an empty string in which case the
@@ -2492,8 +2593,8 @@ QUrl QFileDialog::getSaveFileUrl(QWidget *parent,
symlinks as regular directories.
On Windows, the dialog will spin a blocking modal event loop that will not
- dispatch any QTimers, and if \a parent is not 0 then it will position the
- dialog just below the parent's title bar.
+ dispatch any QTimers, and if \a parent is not \nullptr then it will position
+ the dialog just below the parent's title bar.
\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
@@ -2548,7 +2649,10 @@ QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent,
args.parent = parent;
args.caption = caption;
args.directory = QFileDialogPrivate::workingDirectory(dir);
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
args.mode = (options & ShowDirsOnly ? DirectoryOnly : Directory);
+QT_WARNING_POP
args.options = options;
QFileDialog dialog(args);
@@ -2661,7 +2765,10 @@ void QFileDialog::accept()
}
switch (fileMode()) {
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
case DirectoryOnly:
+QT_WARNING_POP
case Directory: {
QString fn = files.first();
QFileInfo info(fn);
@@ -2697,7 +2804,7 @@ void QFileDialog::accept()
}
// check if we have to ask for permission to overwrite the file
- if (!info.exists() || !confirmOverwrite() || acceptMode() == AcceptOpen) {
+ if (!info.exists() || testOption(DontConfirmOverwrite) || acceptMode() == AcceptOpen) {
d->emitFilesSelected(QStringList(fn));
QDialog::accept();
#if QT_CONFIG(messagebox)
@@ -3565,7 +3672,10 @@ void QFileDialogPrivate::_q_updateOkButton()
isOpenDirectory = true;
} else {
switch (fileMode) {
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
case QFileDialog::DirectoryOnly:
+QT_WARNING_POP
case QFileDialog::Directory: {
QString fn = files.first();
QModelIndex idx = model->index(fn);
@@ -3657,12 +3767,15 @@ void QFileDialogPrivate::_q_enterDirectory(const QModelIndex &index)
const QFileDialog::FileMode fileMode = q->fileMode();
q->setDirectory(path);
emit q->directoryEntered(path);
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
if (fileMode == QFileDialog::Directory
|| fileMode == QFileDialog::DirectoryOnly) {
// ### find out why you have to do both of these.
lineEdit()->setText(QString());
lineEdit()->clear();
}
+QT_WARNING_POP
} else {
// Do not accept when shift-clicking to multi-select a file in environments with single-click-activation (KDE)
if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, nullptr, qFileDialogUi->treeView)
@@ -3695,7 +3808,7 @@ void QFileDialogPrivate::_q_goToDirectory(const QString &path)
}
QDir dir(path2);
if (!dir.exists())
- dir = getEnvironmentVariable(path2);
+ dir.setPath(getEnvironmentVariable(path2));
if (dir.exists() || path2.isEmpty() || path2 == model->myComputer().toString()) {
_q_enterDirectory(index);
@@ -3754,7 +3867,10 @@ void QFileDialogPrivate::_q_selectionChanged()
{
const QFileDialog::FileMode fileMode = q_func()->fileMode();
const QModelIndexList indexes = qFileDialogUi->listView->selectionModel()->selectedRows();
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
bool stripDirs = (fileMode != QFileDialog::DirectoryOnly && fileMode != QFileDialog::Directory);
+QT_WARNING_POP
QStringList allFiles;
for (const auto &index : indexes) {
@@ -3806,10 +3922,13 @@ void QFileDialogPrivate::_q_rowsInserted(const QModelIndex &parent)
void QFileDialogPrivate::_q_fileRenamed(const QString &path, const QString &oldName, const QString &newName)
{
const QFileDialog::FileMode fileMode = q_func()->fileMode();
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
if (fileMode == QFileDialog::Directory || fileMode == QFileDialog::DirectoryOnly) {
if (path == rootPath() && lineEdit()->text() == oldName)
lineEdit()->setText(newName);
}
+QT_WARNING_POP
}
void QFileDialogPrivate::_q_emitUrlSelected(const QUrl &file)
diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h
index a4d289a77a..95e03618ac 100644
--- a/src/widgets/dialogs/qfiledialog.h
+++ b/src/widgets/dialogs/qfiledialog.h
@@ -46,6 +46,8 @@
#include <QtCore/qurl.h>
#include <QtWidgets/qdialog.h>
+#include <functional>
+
QT_REQUIRE_CONFIG(filedialog);
QT_BEGIN_NAMESPACE
@@ -64,19 +66,22 @@ class Q_WIDGETS_EXPORT QFileDialog : public QDialog
Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode)
Q_PROPERTY(FileMode fileMode READ fileMode WRITE setFileMode)
Q_PROPERTY(AcceptMode acceptMode READ acceptMode WRITE setAcceptMode)
+ Q_PROPERTY(QString defaultSuffix READ defaultSuffix WRITE setDefaultSuffix)
+#if QT_DEPRECATED_SINCE(5, 13)
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly DESIGNABLE false)
- Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks DESIGNABLE false)
Q_PROPERTY(bool confirmOverwrite READ confirmOverwrite WRITE setConfirmOverwrite DESIGNABLE false)
- Q_PROPERTY(QString defaultSuffix READ defaultSuffix WRITE setDefaultSuffix)
+ Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks DESIGNABLE false)
Q_PROPERTY(bool nameFilterDetailsVisible READ isNameFilterDetailsVisible
WRITE setNameFilterDetailsVisible DESIGNABLE false)
+#endif
Q_PROPERTY(Options options READ options WRITE setOptions)
Q_PROPERTY(QStringList supportedSchemes READ supportedSchemes WRITE setSupportedSchemes)
public:
enum ViewMode { Detail, List };
Q_ENUM(ViewMode)
- enum FileMode { AnyFile, ExistingFile, Directory, ExistingFiles, DirectoryOnly };
+ enum FileMode { AnyFile, ExistingFile, Directory, ExistingFiles,
+ DirectoryOnly Q_DECL_ENUMERATOR_DEPRECATED_X("Use setOption(ShowDirsOnly, true) instead")};
Q_ENUM(FileMode)
enum AcceptMode { AcceptOpen, AcceptSave };
Q_ENUM(AcceptMode)
@@ -117,8 +122,12 @@ public:
void selectUrl(const QUrl &url);
QList<QUrl> selectedUrls() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use setOption(HideNameFilterDetails, !enabled) instead")
void setNameFilterDetailsVisible(bool enabled);
+ QT_DEPRECATED_X("Use !testOption(HideNameFilterDetails) instead")
bool isNameFilterDetailsVisible() const;
+#endif
void setNameFilter(const QString &filter);
void setNameFilters(const QStringList &filters);
@@ -145,11 +154,15 @@ public:
void setAcceptMode(AcceptMode mode);
AcceptMode acceptMode() const;
+#if QT_DEPRECATED_SINCE(5, 13)
void setReadOnly(bool enabled);
bool isReadOnly() const;
+ QT_DEPRECATED_X("Use setOption(DontResolveSymlinks, !enabled) instead")
void setResolveSymlinks(bool enabled);
+ QT_DEPRECATED_X("Use !testOption(DontResolveSymlinks) instead")
bool resolveSymlinks() const;
+#endif
void setSidebarUrls(const QList<QUrl> &urls);
QList<QUrl> sidebarUrls() const;
@@ -157,8 +170,12 @@ public:
QByteArray saveState() const;
bool restoreState(const QByteArray &state);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use setOption(DontConfirmOverwrite, !enabled) instead")
void setConfirmOverwrite(bool enabled);
+ QT_DEPRECATED_X("Use !testOption(DontConfirmOverwrite) instead")
bool confirmOverwrite() const;
+#endif
void setDefaultSuffix(const QString &suffix);
QString defaultSuffix() const;
@@ -263,6 +280,8 @@ public:
Options options = Options(),
const QStringList &supportedSchemes = QStringList());
+ static void getOpenFileContent(const QString &nameFilter,
+ const std::function<void(const QString &, const QByteArray &)> &fileContentsReady);
protected:
QFileDialog(const QFileDialogArgs &args);
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index 2e49696b77..463c77aa23 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -164,13 +164,9 @@ public:
QDir::Filters filterForMode(QDir::Filters filters) const
{
- const QFileDialog::FileMode fileMode = q_func()->fileMode();
- if (fileMode == QFileDialog::DirectoryOnly) {
- filters |= QDir::Drives | QDir::AllDirs | QDir::Dirs;
+ filters |= QDir::Drives | QDir::AllDirs | QDir::Dirs | QDir::Files;
+ if (q_func()->testOption(QFileDialog::ShowDirsOnly))
filters &= ~QDir::Files;
- } else {
- filters |= QDir::Drives | QDir::AllDirs | QDir::Files | QDir::Dirs;
- }
return filters;
}
@@ -290,7 +286,7 @@ private:
virtual void helperPrepareShow(QPlatformDialogHelper *) override;
virtual void helperDone(QDialog::DialogCode, QPlatformDialogHelper *) override;
- Q_DISABLE_COPY(QFileDialogPrivate)
+ Q_DISABLE_COPY_MOVE(QFileDialogPrivate)
};
class QFileDialogLineEdit : public QLineEdit
diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp
index 477c6bd540..2b81180ecb 100644
--- a/src/widgets/dialogs/qfontdialog.cpp
+++ b/src/widgets/dialogs/qfontdialog.cpp
@@ -534,7 +534,7 @@ void QFontDialogPrivate::updateFamilies()
//and try some fall backs
match_t type = MATCH_NONE;
- if (bestFamilyType <= MATCH_NONE && familyName2 == f.lastResortFamily())
+ if (bestFamilyType <= MATCH_NONE && familyName2 == QStringLiteral("helvetica"))
type = MATCH_LAST_RESORT;
if (bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.family())
type = MATCH_APP;
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index ac1952a642..f143e3b527 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -113,7 +113,7 @@ public:
, copyAvailable(false)
{
QVBoxLayout *layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(QMargins());
QFrame *line = new QFrame(this);
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
@@ -834,7 +834,7 @@ QMessageBox::QMessageBox(QWidget *parent)
The message box is an \l{Qt::ApplicationModal} {application modal}
dialog box.
- On \macos, if \a parent is not 0 and you want your message box
+ On \macos, if \a parent is not \nullptr and you want your message box
to appear as a Qt::Sheet of that parent, set the message box's
\l{setWindowModality()} {window modality} to Qt::WindowModal
(default). Otherwise, the message box will be a standard dialog.
@@ -983,7 +983,7 @@ QMessageBox::StandardButton QMessageBox::standardButton(QAbstractButton *button)
\since 4.2
Returns a pointer corresponding to the standard button \a which,
- or 0 if the standard button doesn't exist in this message box.
+ or \nullptr if the standard button doesn't exist in this message box.
\sa standardButtons, standardButton()
*/
@@ -1106,7 +1106,7 @@ void QMessageBoxPrivate::detectEscapeButton()
\since 4.2
Returns the button that was clicked by the user,
- or 0 if the user hit the \uicontrol Esc key and
+ or \nullptr if the user hit the \uicontrol Esc key and
no \l{setEscapeButton()}{escape button} was set.
If exec() hasn't been called yet, returns nullptr.
@@ -1173,7 +1173,7 @@ void QMessageBox::setDefaultButton(QMessageBox::StandardButton button)
/*! \since 5.2
Sets the checkbox \a cb on the message dialog. The message box takes ownership of the checkbox.
- The argument \a cb can be 0 to remove an existing checkbox from the message box.
+ The argument \a cb can be \nullptr to remove an existing checkbox from the message box.
\sa checkBox()
*/
@@ -1205,7 +1205,7 @@ void QMessageBox::setCheckBox(QCheckBox *cb)
/*! \since 5.2
- Returns the checkbox shown on the dialog. This is 0 if no checkbox is set.
+ Returns the checkbox shown on the dialog. This is \nullptr if no checkbox is set.
\sa setCheckBox()
*/
@@ -1570,7 +1570,7 @@ QList<QAbstractButton *> QMessageBox::buttons() const
\since 4.5
Returns the button role for the specified \a button. This function returns
- \l InvalidRole if \a button is 0 or has not been added to the message box.
+ \l InvalidRole if \a button is \nullptr or has not been added to the message box.
\sa buttons(), addButton()
*/
@@ -1835,7 +1835,7 @@ void QMessageBox::about(QWidget *parent, const QString &title, const QString &te
/*!
Displays a simple message box about Qt, with the given \a title
- and centered over \a parent (if \a parent is not 0). The message
+ and centered over \a parent (if \a parent is not \nullptr). The message
includes the version number of Qt being used by the application.
This is useful for inclusion in the \uicontrol Help menu of an application,
diff --git a/src/widgets/dialogs/qmessagebox.h b/src/widgets/dialogs/qmessagebox.h
index 4b993a9e65..0a2edb1eee 100644
--- a/src/widgets/dialogs/qmessagebox.h
+++ b/src/widgets/dialogs/qmessagebox.h
@@ -284,9 +284,9 @@ public:
Q_SIGNALS:
void buttonClicked(QAbstractButton *button);
-#ifdef Q_QDOC
+#ifdef Q_CLANG_QDOC
public Q_SLOTS:
- int exec();
+ int exec() override;
#endif
protected:
diff --git a/src/widgets/dialogs/qprogressdialog.cpp b/src/widgets/dialogs/qprogressdialog.cpp
index e1fb1055ae..078dd6463b 100644
--- a/src/widgets/dialogs/qprogressdialog.cpp
+++ b/src/widgets/dialogs/qprogressdialog.cpp
@@ -47,7 +47,6 @@
#include "qapplication.h"
#include "qstyle.h"
#include "qpushbutton.h"
-#include "qcursor.h"
#include "qtimer.h"
#include "qelapsedtimer.h"
#include <private/qdialog_p.h>
@@ -94,9 +93,6 @@ public:
bool cancellation_flag;
bool setValue_called;
QElapsedTimer starttime;
-#ifndef QT_NO_CURSOR
- QCursor parentCursor;
-#endif
int showTime;
bool autoClose;
bool autoReset;
@@ -597,12 +593,6 @@ void QProgressDialog::setRange(int minimum, int maximum)
void QProgressDialog::reset()
{
Q_D(QProgressDialog);
-#ifndef QT_NO_CURSOR
- if (value() >= 0) {
- if (parentWidget())
- parentWidget()->setCursor(d->parentCursor);
- }
-#endif
if (d->autoClose || d->forceHide)
hide();
d->bar->reset();
diff --git a/src/widgets/dialogs/qsidebar.cpp b/src/widgets/dialogs/qsidebar.cpp
index d52f18b406..2c8c66e1e2 100644
--- a/src/widgets/dialogs/qsidebar.cpp
+++ b/src/widgets/dialogs/qsidebar.cpp
@@ -381,8 +381,6 @@ QSidebar::QSidebar(QWidget *parent) : QListView(parent)
void QSidebar::setModelAndUrls(QFileSystemModel *model, const QList<QUrl> &newUrls)
{
- // ### TODO make icon size dynamic
- setIconSize(QSize(24,24));
setUniformItemSizes(true);
urlModel = new QUrlModel(this);
urlModel->setFileSystemModel(model);
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index 21e1ff2778..88b187cd7f 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -331,7 +331,7 @@ QWizardHeader::QWizardHeader(QWidget *parent)
titleLabel->setFont(font);
layout = new QGridLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(QMargins());
layout->setSpacing(0);
layout->setRowMinimumHeight(3, 1);
@@ -769,7 +769,7 @@ void QWizardPrivate::reset()
for (int i = history.count() - 1; i >= 0; --i)
q->cleanupPage(history.at(i));
history.clear();
- for (QWizardPage *page : pageMap)
+ for (QWizardPage *page : qAsConst(pageMap))
page->d_func()->initialized = false;
current = -1;
@@ -1032,13 +1032,13 @@ void QWizardPrivate::recreateLayout(const QWizardLayoutInfo &info)
int pageColumn = qMin(1, numColumns - 1);
if (mac) {
- mainLayout->setMargin(0);
+ mainLayout->setContentsMargins(QMargins());
mainLayout->setSpacing(0);
buttonLayout->setContentsMargins(MacLayoutLeftMargin, MacButtonTopMargin, MacLayoutRightMargin, MacLayoutBottomMargin);
- pageVBoxLayout->setMargin(7);
+ pageVBoxLayout->setContentsMargins(7, 7, 7, 7);
} else {
if (modern) {
- mainLayout->setMargin(0);
+ mainLayout->setContentsMargins(QMargins());
mainLayout->setSpacing(0);
pageVBoxLayout->setContentsMargins(deltaMarginLeft, deltaMarginTop,
deltaMarginRight, deltaMarginBottom);
@@ -2374,8 +2374,8 @@ void QWizard::removePage(int id)
/*!
\fn QWizardPage *QWizard::page(int id) const
- Returns the page with the given \a id, or 0 if there is no such
- page.
+ Returns the page with the given \a id, or \nullptr if there is no
+ such page.
\sa addPage(), setPage()
*/
@@ -2462,8 +2462,8 @@ int QWizard::startId() const
}
/*!
- Returns a pointer to the current page, or 0 if there is no current
- page (e.g., before the wizard is shown).
+ Returns a pointer to the current page, or \nullptr if there is no
+ current page (e.g., before the wizard is shown).
This is equivalent to calling page(currentId()).
@@ -2954,7 +2954,7 @@ void QWizard::setDefaultProperty(const char *className, const char *property,
Passing 0 shows no side widget.
- When the \a widget is not 0 the wizard reparents it.
+ When the \a widget is not \nullptr the wizard reparents it.
Any previous side widget is hidden.
@@ -2963,7 +2963,7 @@ void QWizard::setDefaultProperty(const char *className, const char *property,
All widgets set here will be deleted by the wizard when it is
destroyed unless you separately reparent the widget after setting
- some other side widget (or 0).
+ some other side widget (or \nullptr).
By default, no side widget is present.
*/
@@ -2981,7 +2981,7 @@ void QWizard::setSideWidget(QWidget *widget)
/*!
\since 4.7
- Returns the widget on the left side of the wizard or 0.
+ Returns the widget on the left side of the wizard or \nullptr.
By default, no side widget is present.
*/
@@ -3969,7 +3969,7 @@ void QWizardPage::registerField(const QString &name, QWidget *widget, const char
}
/*!
- Returns the wizard associated with this page, or 0 if this page
+ Returns the wizard associated with this page, or \nullptr if this page
hasn't been inserted into a QWizard yet.
\sa QWizard::addPage(), QWizard::setPage()
diff --git a/src/widgets/dialogs/qwizard_win_p.h b/src/widgets/dialogs/qwizard_win_p.h
index d302dedaa3..02c5e52c2c 100644
--- a/src/widgets/dialogs/qwizard_win_p.h
+++ b/src/widgets/dialogs/qwizard_win_p.h
@@ -84,7 +84,7 @@ class QWizard;
class QVistaHelper : public QObject
{
- Q_DISABLE_COPY(QVistaHelper)
+ Q_DISABLE_COPY_MOVE(QVistaHelper)
public:
QVistaHelper(QWizard *wizard);
~QVistaHelper() override;
diff --git a/src/widgets/doc/snippets/code/doc_src_examples_dropsite.qdoc b/src/widgets/doc/snippets/code/doc_src_examples_dropsite.qdoc
deleted file mode 100644
index a91933cdce..0000000000
--- a/src/widgets/doc/snippets/code/doc_src_examples_dropsite.qdoc
+++ /dev/null
@@ -1,55 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//! [0]
-\code
-foreach(variable, container)
-\endcode
-//! [0]
diff --git a/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc b/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc
index 9af04f6b4c..098eaf4717 100644
--- a/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc
+++ b/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc
@@ -514,13 +514,15 @@ QLabel { border-width: 1px 2px 3px 4px } /* 1px 2px 3px 4px */
//! [84]
-QLabel { border-color: red } /* opaque red */
-QLabel { border-color: #FF0000 } /* opaque red */
-QLabel { border-color: rgba(255, 0, 0, 75%) } /* 75% opaque red */
-QLabel { border-color: rgb(255, 0, 0) } /* opaque red */
-QLabel { border-color: rgb(100%, 0%, 0%) } /* opaque red */
-QLabel { border-color: hsv(60, 255, 255) } /* opaque yellow */
-QLabel { border-color: hsva(240, 255, 255, 75%) } /* 75% blue */
+QLabel { border-color: red } /* opaque red */
+QLabel { border-color: #FF0000 } /* opaque red */
+QLabel { border-color: rgba(255, 0, 0, 75%) } /* 75% opaque red */
+QLabel { border-color: rgb(255, 0, 0) } /* opaque red */
+QLabel { border-color: rgb(100%, 0%, 0%) } /* opaque red */
+QLabel { border-color: hsv(60, 100%, 100%) } /* opaque yellow */
+QLabel { border-color: hsva(240, 255, 255, 75%) } /* 75% blue */
+QLabel { border-color: hsl(60, 100%, 50%) } /* opaque yellow */
+QLabel { border-color: hsla(240, 255, 50%, 75%) } /* 75% blue */
//! [84]
diff --git a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
index 06cca37111..1e9daf824b 100644
--- a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
+++ b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
@@ -144,3 +144,14 @@ dialog.exec();
//! [14]
"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
//! [14]
+
+//! [14]
+auto fileOpenCompleted = [](const QSting &fileName, const QByteArray &fileContent) {
+ if (fileName.isEmpty()) {
+ // No file was selected
+ } else {
+ // Use fileName and fileContent
+ }
+}
+QFileDialog::getOpenFileContent("Images (*.png *.xpm *.jpg)", fileContentReady);
+//! [14]
diff --git a/src/widgets/doc/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp b/src/widgets/doc/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp
index 4dad563660..cc1568cb9d 100644
--- a/src/widgets/doc/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp
+++ b/src/widgets/doc/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp
@@ -59,7 +59,7 @@ mapper->toFirst();
//! [1]
-QDataWidgetMapper *mapper = new QDataWidgetMapper();
+QDataWidgetMapper *mapper = new QDataWidgetMapper;
mapper->setModel(myModel);
mapper->addMapping(nameLineEdit, 0);
mapper->addMapping(ageSpinBox, 1);
@@ -67,7 +67,7 @@ mapper->addMapping(ageSpinBox, 1);
//! [2]
-QDataWidgetMapper *mapper = new QDataWidgetMapper();
-connect(myTableView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
- mapper, SLOT(setCurrentModelIndex(QModelIndex)));
+QDataWidgetMapper *mapper = new QDataWidgetMapper;
+connect(myTableView->selectionModel(), &QItemSelectionModel::currentRowChanged,
+ mapper, &QDataWidgetMapper::setCurrentModelIndex);
//! [2]
diff --git a/src/widgets/doc/snippets/code/src_gui_kernel_qapplication.cpp b/src/widgets/doc/snippets/code/src_gui_kernel_qapplication.cpp
index a907a0421f..0a70c1d32a 100644
--- a/src/widgets/doc/snippets/code/src_gui_kernel_qapplication.cpp
+++ b/src/widgets/doc/snippets/code/src_gui_kernel_qapplication.cpp
@@ -100,7 +100,8 @@ QSize MyWidget::sizeHint() const
//! [4]
void showAllHiddenTopLevelWidgets()
{
- foreach (QWidget *widget, QApplication::topLevelWidgets()) {
+ const QWidgetList topLevelWidgets = QApplication::topLevelWidgets();
+ for (QWidget *widget : topLevelWidgets) {
if (widget->isHidden())
widget->show();
}
@@ -111,7 +112,8 @@ void showAllHiddenTopLevelWidgets()
//! [5]
void updateAllWidgets()
{
- foreach (QWidget *widget, QApplication::allWidgets())
+ const QWidgetList allWidgets = QApplication::allWidgets();
+ for (QWidget *widget : allWidgets)
widget->update();
}
//! [5]
@@ -171,13 +173,15 @@ appname -session id
//! [10]
-foreach (const QString &command, mySession.restartCommand())
+const QStringList commands = mySession.restartCommand();
+for (const QString &command : commands)
do_something(command);
//! [10]
//! [11]
-foreach (const QString &command, mySession.discardCommand())
+const QStringList commands = mySession.discardCommand();
+for (const QString &command : commands)
do_something(command);
//! [11]
diff --git a/src/widgets/doc/snippets/code/src_gui_widgets_qmenu.cpp b/src/widgets/doc/snippets/code/src_gui_widgets_qmenu.cpp
index 4b1c4cd645..da3fd28056 100644
--- a/src/widgets/doc/snippets/code/src_gui_widgets_qmenu.cpp
+++ b/src/widgets/doc/snippets/code/src_gui_widgets_qmenu.cpp
@@ -81,7 +81,7 @@ exec(e->globalPos());
//! [6]
QMenu menu;
QAction *at = actions[0]; // Assumes actions is not empty
-foreach (QAction *a, actions)
+for (QAction *a : qAsConst(actions))
menu.addAction(a);
menu.exec(pos, at);
//! [6]
diff --git a/src/widgets/doc/snippets/dialogs/dialogs.cpp b/src/widgets/doc/snippets/dialogs/dialogs.cpp
index cca3ac8d75..7fa793c70f 100644
--- a/src/widgets/doc/snippets/dialogs/dialogs.cpp
+++ b/src/widgets/doc/snippets/dialogs/dialogs.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
typedef QDialog WordCountDialog;
typedef QDialog FindDialog;
@@ -76,7 +76,8 @@ void EditorWindow::find()
{
if (!findDialog) {
findDialog = new FindDialog(this);
- connect(findDialog, SIGNAL(findNext()), this, SLOT(findNext()));
+ connect(findDialog, &FindDialog::findNext,
+ this, &EditorWindow::findNext);
}
findDialog->show();
@@ -249,9 +250,9 @@ Operation::Operation(QObject *parent)
: QObject(parent), steps(0)
{
pd = new QProgressDialog("Operation in progress.", "Cancel", 0, 100);
- connect(pd, SIGNAL(canceled()), this, SLOT(cancel()));
+ connect(pd, &QProgressDialog::canceled, this, &Operation::cancel);
t = new QTimer(this);
- connect(t, SIGNAL(timeout()), this, SLOT(perform()));
+ connect(t, &QTimer::timeout, this, &Operation::perform);
t->start(0);
}
//! [4] //! [5]
diff --git a/src/widgets/doc/snippets/dockwidgets/mainwindow.cpp b/src/widgets/doc/snippets/dockwidgets/mainwindow.cpp
index f6959cc12b..53f91589bf 100644
--- a/src/widgets/doc/snippets/dockwidgets/mainwindow.cpp
+++ b/src/widgets/doc/snippets/dockwidgets/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
@@ -63,8 +63,8 @@ MainWindow::MainWindow(QWidget *parent)
textBrowser = new QTextBrowser(this);
- connect(headingList, SIGNAL(itemClicked(QListWidgetItem*)),
- this, SLOT(updateText(QListWidgetItem*)));
+ connect(headingList, &QListWidget::itemClicked,
+ this, &MainWindow::updateText);
updateText(headingList->item(0));
headingList->setCurrentRow(0);
@@ -119,7 +119,7 @@ void MainWindow::setupMenus()
QAction *exitAct = new QAction(tr("E&xit"), this);
exitAct->setShortcut(tr("Ctrl+Q"));
exitAct->setStatusTip(tr("Exit the application"));
- connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
+ connect(exitAct, &QAction::triggered, qApp, &QApplication::closeAllWindows);
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(exitAct);
diff --git a/src/widgets/doc/snippets/mdiareasnippets.cpp b/src/widgets/doc/snippets/mdiareasnippets.cpp
index b9d6f05daf..dec7aaa1e7 100644
--- a/src/widgets/doc/snippets/mdiareasnippets.cpp
+++ b/src/widgets/doc/snippets/mdiareasnippets.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
void mainWindowExample()
{
@@ -95,7 +95,7 @@ int main(int argv, char **args)
QAction *act = new QAction(qApp);
act->setShortcut(Qt::ALT + Qt::Key_S);
act->setShortcutContext( Qt::ApplicationShortcut );
- QObject::connect(act, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
+ QObject::connect(act, &QAction::triggered, qApp, &QApplication::aboutQt);
QWidget widget5;
widget5.show();
diff --git a/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp b/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp
index c2af9c4cf1..45f1eb7aa3 100644
--- a/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp
+++ b/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp
@@ -73,7 +73,8 @@ listView->setDropIndicatorShown(true);
this->listView = listView;
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
+ connect(quitAction, &QAction::triggered,
+ this, &QWidget::close);
setupListItems();
diff --git a/src/widgets/doc/snippets/qlistview-dnd/model.cpp b/src/widgets/doc/snippets/qlistview-dnd/model.cpp
index 710bbb2964..6835479e7a 100644
--- a/src/widgets/doc/snippets/qlistview-dnd/model.cpp
+++ b/src/widgets/doc/snippets/qlistview-dnd/model.cpp
@@ -54,7 +54,7 @@
A simple model that uses a QStringList as its data source.
*/
-#include <QtGui>
+#include <QtWidgets>
#include "model.h"
@@ -121,7 +121,7 @@ bool DragDropListModel::dropMimeData(const QMimeData *data,
//! [6]
insertRows(beginRow, rows, QModelIndex());
- foreach (const QString &text, newItems) {
+ for (const QString &text : qAsConst(newItems)) {
QModelIndex idx = index(beginRow, 0, QModelIndex());
setData(idx, text);
beginRow++;
@@ -146,12 +146,12 @@ Qt::ItemFlags DragDropListModel::flags(const QModelIndex &index) const
//! [8]
QMimeData *DragDropListModel::mimeData(const QModelIndexList &indexes) const
{
- QMimeData *mimeData = new QMimeData();
+ QMimeData *mimeData = new QMimeData;
QByteArray encodedData;
QDataStream stream(&encodedData, QIODevice::WriteOnly);
- foreach (const QModelIndex &index, indexes) {
+ for (const QModelIndex &index : indexes) {
if (index.isValid()) {
QString text = data(index, Qt::DisplayRole).toString();
stream << text;
diff --git a/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp b/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp
index 1153250b17..70df2b112e 100644
--- a/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp
+++ b/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
@@ -74,7 +74,7 @@ listWidget->setDragDropMode(QAbstractItemView::InternalMove);
this->listWidget = listWidget;
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
+ connect(quitAction, &QAction::triggered, this, &QWidget::close);
setupListItems();
diff --git a/src/widgets/doc/snippets/qlistwidget-using/mainwindow.cpp b/src/widgets/doc/snippets/qlistwidget-using/mainwindow.cpp
index ff69fd2efd..13b20bb856 100644
--- a/src/widgets/doc/snippets/qlistwidget-using/mainwindow.cpp
+++ b/src/widgets/doc/snippets/qlistwidget-using/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
@@ -77,14 +77,13 @@ MainWindow::MainWindow()
listWidget = new QListWidget(this);
listWidget->setSelectionMode(QAbstractItemView::SingleSelection);
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
- connect(ascendingAction, SIGNAL(triggered()), this, SLOT(sortAscending()));
- connect(descendingAction, SIGNAL(triggered()), this, SLOT(sortDescending()));
- connect(insertAction, SIGNAL(triggered()), this, SLOT(insertItem()));
- connect(removeAction, SIGNAL(triggered()), this, SLOT(removeItem()));
- connect(listWidget,
- SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
- this, SLOT(updateMenus(QListWidgetItem*)));
+ connect(quitAction, &QAction::triggered, this, &QWidget::close);
+ connect(ascendingAction, &QAction::triggered, this, &MainWindow::sortAscending);
+ connect(descendingAction, &QAction::triggered, this, &MainWindow::sortDescending);
+ connect(insertAction, &QAction::triggered, this, &MainWindow::insertItem);
+ connect(removeAction, &QAction::triggered, this, &MainWindow::removeItem);
+ connect(listWidget, &QListWidget::currentItemChanged,
+ this, &MainWindow::updateMenus);
setupListItems();
updateMenus(listWidget->currentItem());
diff --git a/src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp b/src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp
index a6284bd578..2d4b1023f1 100644
--- a/src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp
+++ b/src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
int main(int argc, char *argv[])
{
@@ -74,9 +74,8 @@ int main(int argc, char *argv[])
filteredView->setWindowTitle("Filtered view onto a string list model");
QLineEdit *patternEditor = new QLineEdit;
- QObject::
- connect(patternEditor, SIGNAL(textChanged(QString)),
- filterModel, SLOT(setFilterRegExp(QString)));
+ QObject::connect(patternEditor, &QLineEdit::textChanged,
+ filterModel, &QSortFilterProxyModel::setFilterWildcard);
QVBoxLayout *layout = new QVBoxLayout(window);
layout->addWidget(filteredView);
diff --git a/src/widgets/doc/snippets/qstackedlayout/main.cpp b/src/widgets/doc/snippets/qstackedlayout/main.cpp
index 765608848c..9c61939dee 100644
--- a/src/widgets/doc/snippets/qstackedlayout/main.cpp
+++ b/src/widgets/doc/snippets/qstackedlayout/main.cpp
@@ -48,13 +48,12 @@
**
****************************************************************************/
-#include <QtGui>
-#include <QApplication>
+#include <QtWidgets>
class Widget : public QWidget
{
public:
- Widget(QWidget *parent = 0);
+ Widget(QWidget *parent = nullptr);
};
Widget::Widget(QWidget *parent)
@@ -75,8 +74,8 @@ Widget::Widget(QWidget *parent)
pageComboBox->addItem(tr("Page 1"));
pageComboBox->addItem(tr("Page 2"));
pageComboBox->addItem(tr("Page 3"));
- connect(pageComboBox, SIGNAL(activated(int)),
- stackedLayout, SLOT(setCurrentIndex(int)));
+ connect(pageComboBox, QOverload<int>::of(&QComboBox::activated),
+ stackedLayout, &QStackedLayout::setCurrentIndex);
//! [1]
//! [2]
diff --git a/src/widgets/doc/snippets/qstackedwidget/main.cpp b/src/widgets/doc/snippets/qstackedwidget/main.cpp
index a6c9c7afe3..077c281830 100644
--- a/src/widgets/doc/snippets/qstackedwidget/main.cpp
+++ b/src/widgets/doc/snippets/qstackedwidget/main.cpp
@@ -48,8 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
-#include <QApplication>
+#include <QtWidgets>
class Widget : public QWidget
{
@@ -75,8 +74,8 @@ Widget::Widget(QWidget *parent)
pageComboBox->addItem(tr("Page 1"));
pageComboBox->addItem(tr("Page 2"));
pageComboBox->addItem(tr("Page 3"));
- connect(pageComboBox, SIGNAL(activated(int)),
- stackedWidget, SLOT(setCurrentIndex(int)));
+ connect(pageComboBox, QOverload<int>::of(&QComboBox::activated),
+ stackedWidget, &QStackedWidget::setCurrentIndex);
//! [1] //! [2]
QVBoxLayout *layout = new QVBoxLayout;
diff --git a/src/widgets/doc/snippets/qtablewidget-resizing/mainwindow.cpp b/src/widgets/doc/snippets/qtablewidget-resizing/mainwindow.cpp
index 95113153e1..d2c50336f6 100644
--- a/src/widgets/doc/snippets/qtablewidget-resizing/mainwindow.cpp
+++ b/src/widgets/doc/snippets/qtablewidget-resizing/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
@@ -72,9 +72,9 @@ MainWindow::MainWindow()
//! [0]
tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
- connect(tableWidthAction, SIGNAL(triggered()), this, SLOT(changeWidth()));
- connect(tableHeightAction, SIGNAL(triggered()), this, SLOT(changeHeight()));
+ connect(quitAction, &QAction::triggered, this, &QWidget::close);
+ connect(tableWidthAction, &QAction::triggered, this, &MainWindow::changeWidth);
+ connect(tableHeightAction, &QAction::triggered, this, &MainWindow::changeHeight);
setupTableItems();
diff --git a/src/widgets/doc/snippets/qtablewidget-using/mainwindow.cpp b/src/widgets/doc/snippets/qtablewidget-using/mainwindow.cpp
index 15b9457dd5..47b63b2b3f 100644
--- a/src/widgets/doc/snippets/qtablewidget-using/mainwindow.cpp
+++ b/src/widgets/doc/snippets/qtablewidget-using/mainwindow.cpp
@@ -48,8 +48,8 @@
**
****************************************************************************/
-#include <QtGui>
-#include "math.h"
+#include <QtWidgets>
+#include <math.h>
#include "mainwindow.h"
@@ -89,9 +89,9 @@ MainWindow::MainWindow()
tableWidget->setHorizontalHeaderItem(1, squaresHeaderItem);
tableWidget->setHorizontalHeaderItem(2, cubesHeaderItem);
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
- connect(sumItemsAction, SIGNAL(triggered()), this, SLOT(sumItems()));
- connect(averageItemsAction, SIGNAL(triggered()), this, SLOT(averageItems()));
+ connect(quitAction, &QAction::triggered, this, &QWidget::close);
+ connect(sumItemsAction, &QAction::triggered, this, &MainWindow::sumItems);
+ connect(averageItemsAction, &QAction::triggered, this, &MainWindow::averageItems);
setupTableItems();
@@ -119,12 +119,11 @@ void MainWindow::setupTableItems()
void MainWindow::averageItems()
{
- QList<QTableWidgetItem *> selected = tableWidget->selectedItems();
- QTableWidgetItem *item;
+ const QList<QTableWidgetItem *> selected = tableWidget->selectedItems();
int number = 0;
double total = 0;
- foreach (item, selected) {
+ for (QTableWidgetItem *item : selected) {
bool ok;
double value = item->text().toDouble(&ok);
@@ -140,12 +139,11 @@ void MainWindow::averageItems()
void MainWindow::sumItems()
{
//! [4]
- QList<QTableWidgetItem *> selected = tableWidget->selectedItems();
- QTableWidgetItem *item;
+ const QList<QTableWidgetItem *> selected = tableWidget->selectedItems();
int number = 0;
double total = 0;
- foreach (item, selected) {
+ for (QTableWidgetItem *item : selected) {
bool ok;
double value = item->text().toDouble(&ok);
diff --git a/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp b/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp
index ee7e028a13..b9e258cb03 100644
--- a/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp
+++ b/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
@@ -90,16 +90,15 @@ MainWindow::MainWindow()
treeWidget->setHeaderLabels(headers);
//! [2]
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
- connect(ascendingAction, SIGNAL(triggered()), this, SLOT(sortAscending()));
- connect(autoSortAction, SIGNAL(triggered()), this, SLOT(updateSortItems()));
- connect(descendingAction, SIGNAL(triggered()), this, SLOT(sortDescending()));
- connect(findItemsAction, SIGNAL(triggered()), this, SLOT(findItems()));
- connect(insertAction, SIGNAL(triggered()), this, SLOT(insertItem()));
- connect(removeAction, SIGNAL(triggered()), this, SLOT(removeItem()));
- connect(treeWidget,
- SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
- this, SLOT(updateMenus(QTreeWidgetItem*)));
+ connect(quitAction, &QAction::triggered, this, &QWidget::close);
+ connect(ascendingAction, &QAction::triggered, this, &MainWindow::sortAscending);
+ connect(autoSortAction, &QAction::triggered, this, &MainWindow::updateSortItems);
+ connect(descendingAction, &QAction::triggered, this, &MainWindow::sortDescending);
+ connect(findItemsAction, &QAction::triggered, this, &MainWindow::findItems);
+ connect(insertAction, &QAction::triggered, this, &MainWindow::insertItem);
+ connect(removeAction, &QAction::triggered, this, &MainWindow::removeItem);
+ connect(treeWidget, &QTreeWidget::currentItemChanged,
+ this, &MainWindow::updateMenus);
setupTreeItems();
updateMenus(treeWidget->currentItem());
@@ -150,18 +149,16 @@ void MainWindow::findItems()
if (itemText.isEmpty())
return;
-//! [6]
- QTreeWidgetItem *item;
-//! [6]
- foreach (item, treeWidget->selectedItems())
- treeWidget->setItemSelected(item, false);
+ const QList<QTreeWidgetItem *> items = treeWidget->selectedItems();
+ for (QTreeWidgetItem *item : items)
+ item->setSelected(false);
//! [7]
- QList<QTreeWidgetItem *> found = treeWidget->findItems(
+ const QList<QTreeWidgetItem *> found = treeWidget->findItems(
itemText, Qt::MatchWildcard);
- foreach (item, found) {
- treeWidget->setItemSelected(item, true);
+ for (QTreeWidgetItem *item : found) {
+ item->setSelected(true);
// Show the item->text(0) for each item.
}
//! [7]
diff --git a/src/widgets/doc/snippets/qtreewidgetitemiterator-using/mainwindow.cpp b/src/widgets/doc/snippets/qtreewidgetitemiterator-using/mainwindow.cpp
index 5f1f606185..bfe099bbb4 100644
--- a/src/widgets/doc/snippets/qtreewidgetitemiterator-using/mainwindow.cpp
+++ b/src/widgets/doc/snippets/qtreewidgetitemiterator-using/mainwindow.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
@@ -85,16 +85,15 @@ MainWindow::MainWindow()
headers << tr("Subject") << tr("Default");
treeWidget->setHeaderLabels(headers);
- connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
- connect(ascendingAction, SIGNAL(triggered()), this, SLOT(sortAscending()));
- connect(autoSortAction, SIGNAL(triggered()), this, SLOT(updateSortItems()));
- connect(descendingAction, SIGNAL(triggered()), this, SLOT(sortDescending()));
- connect(findItemsAction, SIGNAL(triggered()), this, SLOT(findItems()));
- connect(insertAction, SIGNAL(triggered()), this, SLOT(insertItem()));
- connect(removeAction, SIGNAL(triggered()), this, SLOT(removeItem()));
- connect(treeWidget,
- SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
- this, SLOT(updateMenus(QTreeWidgetItem*)));
+ connect(quitAction, &QAction::triggered, this, &QWidget::close);
+ connect(ascendingAction, &QAction::triggered, this, &MainWindow::sortAscending);
+ connect(autoSortAction, &QAction::triggered, this, &MainWindow::updateSortItems);
+ connect(descendingAction, &QAction::triggered, this, &MainWindow::sortDescending);
+ connect(findItemsAction, &QAction::triggered, this, &MainWindow::findItems);
+ connect(insertAction, &QAction::triggered, this, &MainWindow::insertItem);
+ connect(removeAction, &QAction::triggered, this, &MainWindow::removeItem);
+ connect(treeWidget, &QTreeWidget::currentItemChanged,
+ this, &MainWindow::updateMenus);
setupTreeItems();
updateMenus(treeWidget->currentItem());
diff --git a/src/widgets/doc/snippets/reading-selections/window.cpp b/src/widgets/doc/snippets/reading-selections/window.cpp
index 08805fe4b3..045d66a199 100644
--- a/src/widgets/doc/snippets/reading-selections/window.cpp
+++ b/src/widgets/doc/snippets/reading-selections/window.cpp
@@ -81,9 +81,9 @@ MainWindow::MainWindow(QWidget *parent)
QAction *selectAllAction = actionMenu->addAction(tr("&Select All"));
menuBar()->addMenu(actionMenu);
- connect(fillAction, SIGNAL(triggered()), this, SLOT(fillSelection()));
- connect(clearAction, SIGNAL(triggered()), this, SLOT(clearSelection()));
- connect(selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll()));
+ connect(fillAction, &QAction::triggered, this, &MainWindow::fillSelection);
+ connect(clearAction, &QAction::triggered, this, &MainWindow::clearSelection);
+ connect(selectAllAction, &QAction::triggered, this, &MainWindow::selectAll);
selectionModel = table->selectionModel();
@@ -94,10 +94,9 @@ MainWindow::MainWindow(QWidget *parent)
void MainWindow::fillSelection()
{
//! [0]
- QModelIndexList indexes = selectionModel->selectedIndexes();
- QModelIndex index;
+ const QModelIndexList indexes = selectionModel->selectedIndexes();
- foreach(index, indexes) {
+ for (const QModelIndex &index : indexes) {
QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());
model->setData(index, text);
}
@@ -106,11 +105,10 @@ void MainWindow::fillSelection()
void MainWindow::clearSelection()
{
- QModelIndexList indexes = selectionModel->selectedIndexes();
- QModelIndex index;
+ const QModelIndexList indexes = selectionModel->selectedIndexes();
- foreach(index, indexes)
- model->setData(index, "");
+ for (const QModelIndex &index : indexes)
+ model->setData(index, QString());
}
void MainWindow::selectAll()
diff --git a/src/widgets/doc/snippets/updating-selections/window.cpp b/src/widgets/doc/snippets/updating-selections/window.cpp
index 0bdcf8a64d..26e9b56ae4 100644
--- a/src/widgets/doc/snippets/updating-selections/window.cpp
+++ b/src/widgets/doc/snippets/updating-selections/window.cpp
@@ -74,12 +74,10 @@ MainWindow::MainWindow(QWidget *parent)
table->setModel(model);
selectionModel = table->selectionModel();
- connect(selectionModel,
- SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(updateSelection(QItemSelection,QItemSelection)));
- connect(selectionModel,
- SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(changeCurrent(QModelIndex,QModelIndex)));
+ connect(selectionModel, &QItemSelectionModel::selectionChanged,
+ this, &MainWindow::updateSelection);
+ connect(selectionModel, &QItemSelectionModel::currentChanged,
+ this, &MainWindow::changeCurrent);
statusBar();
setCentralWidget(table);
@@ -89,10 +87,9 @@ MainWindow::MainWindow(QWidget *parent)
void MainWindow::updateSelection(const QItemSelection &selected,
const QItemSelection &deselected)
{
- QModelIndex index;
QModelIndexList items = selected.indexes();
- foreach (index, items) {
+ for (const QModelIndex &index : qAsConst(items)) {
QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());
model->setData(index, text);
//! [0] //! [1]
@@ -102,8 +99,8 @@ void MainWindow::updateSelection(const QItemSelection &selected,
//! [2]
items = deselected.indexes();
- foreach (index, items)
- model->setData(index, "");
+ for (const QModelIndex &index : qAsConst(items)) {
+ model->setData(index, QString());
}
//! [2]
diff --git a/src/widgets/doc/src/model-view-programming.qdoc b/src/widgets/doc/src/model-view-programming.qdoc
index f6b7c80656..9335ff78c9 100644
--- a/src/widgets/doc/src/model-view-programming.qdoc
+++ b/src/widgets/doc/src/model-view-programming.qdoc
@@ -693,9 +693,9 @@
\l QAbstractItemDelegate class.
Delegates are expected to be able to render their contents themselves
- by implementing the \l{QItemDelegate::paint()}{paint()}
- and \l{QItemDelegate::sizeHint()}{sizeHint()} functions.
- However, simple widget-based delegates can subclass \l QItemDelegate
+ by implementing the \l{QStyledItemDelegate::paint()}{paint()}
+ and \l{QStyledItemDelegate::sizeHint()}{sizeHint()} functions.
+ However, simple widget-based delegates can subclass \l QStyledItemDelegate
instead of \l QAbstractItemDelegate, and take advantage of the default
implementations of these functions.
@@ -709,14 +709,14 @@
\section2 Using an existing delegate
- The standard views provided with Qt use instances of \l QItemDelegate
+ The standard views provided with Qt use instances of \l QStyledItemDelegate
to provide editing facilities. This default implementation of the
delegate interface renders items in the usual style for each of the
standard views: \l QListView, \l QTableView, and \l QTreeView.
All the standard roles are handled by the default delegate used by
the standard views. The way these are interpreted is described in the
- QItemDelegate documentation.
+ QStyledItemDelegate documentation.
The delegate used by a view is returned by the
\l{QAbstractItemView::itemDelegate()}{itemDelegate()} function.
@@ -799,7 +799,7 @@
In this case, we ensure that the spin box is up-to-date, and update
the model with the value it contains using the index specified.
- The standard \l QItemDelegate class informs the view when it has
+ The standard \l QStyledItemDelegate class informs the view when it has
finished editing by emitting the
\l{QAbstractItemDelegate::closeEditor()}{closeEditor()} signal.
The view ensures that the editor widget is closed and destroyed. In
@@ -838,11 +838,11 @@
assist any subsequent editing operations. This is achieved by
emitting the \l{QAbstractItemDelegate::closeEditor()}{closeEditor()}
signal with a suitable hint. This is taken care of by the default
- QItemDelegate event filter which we installed on the spin box when
+ QStyledItemDelegate event filter which we installed on the spin box when
it was constructed.
The behavior of the spin box could be adjusted to make it more user
- friendly. In the default event filter supplied by QItemDelegate, if
+ friendly. In the default event filter supplied by QStyledItemDelegate, if
the user hits \uicontrol Return to confirm their choice in the spin box,
the delegate commits the value to the model and closes the spin box.
We can change this behavior by installing our own event filter on the
@@ -1003,8 +1003,8 @@
\snippet reading-selections/window.cpp 0
- The above code uses Qt's convenient \l{Container Classes}{foreach
- keyword} to iterate over, and modify, the items corresponding to the
+ The above code uses a range-based for-loop to iterate over,
+ and modify, the items corresponding to the
indexes returned by the selection model.
The selection model emits signals to indicate changes in the
@@ -1611,7 +1611,6 @@
We can obtain a list of matching items with the \c findItems()
function:
- \snippet qtreewidget-using/mainwindow.cpp 6
\snippet qtreewidget-using/mainwindow.cpp 7
The above code causes items in a tree widget to be selected if they
diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
index 43f9dda49a..00323eace6 100644
--- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
+++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
@@ -2881,14 +2881,20 @@
| \tt{rgba(\e{r}, \e{g}, \e{b}, \e{a})} \br
| \tt{hsv(\e{h}, \e{s}, \e{v})} \br
| \tt{hsva(\e{h}, \e{s}, \e{v}, \e{a})} \br
+ | \tt{hsl(\e{h}, \e{s}, \e{l})} \br
+ | \tt{hsla(\e{h}, \e{s}, \e{l}, \e{a})} \br
| \tt{#\e{rrggbb}} \br
| \l{QColor::setNamedColor()}{Color Name} \br
- \li Specifies a color as RGB (red, green, blue) or RGBA
- (red, green, blue, alpha) or HSV (hue, saturation, value) or HSVA
- (hue, saturation, value, alpha) or a named color. The \c rgb() or \c rgba()
- syntax can be used with integer values between 0 and 255, or with
- percentages. The value of s, v, and a in \c hsv() or \c hsva() must all
- be in the range 0-255; the value of h must be in the range 0-359.
+ \li Specifies a color as RGB (red, green, blue), RGBA (red,
+ green, blue, alpha), HSV (hue, saturation, value), HSVA
+ (hue, saturation, value, alpha), HSL (hue, saturation,
+ lightness), HSLA (hue, saturation, lightness, alpha) or a
+ named color. The \c rgb() or \c rgba() syntax can be used
+ with integer values between 0 and 255, or with percentages.
+ The value of s, v, l and a in \c hsv(), \c hsva() \c hsl()
+ or \c hsla() must all be in the range 0-255 or with
+ percentages, the value of h must be in the range 0-359.
+ The support for HSL(A) is available since 5.13.
Examples:
diff --git a/src/widgets/effects/qgraphicseffect_p.h b/src/widgets/effects/qgraphicseffect_p.h
index c5c7ff5900..2f3bd2f7fd 100644
--- a/src/widgets/effects/qgraphicseffect_p.h
+++ b/src/widgets/effects/qgraphicseffect_p.h
@@ -88,7 +88,7 @@ protected:
private:
Q_DECLARE_PRIVATE(QGraphicsEffectSource)
- Q_DISABLE_COPY(QGraphicsEffectSource)
+ Q_DISABLE_COPY_MOVE(QGraphicsEffectSource)
friend class QGraphicsEffect;
friend class QGraphicsEffectPrivate;
friend class QGraphicsScenePrivate;
diff --git a/src/widgets/effects/qpixmapfilter.cpp b/src/widgets/effects/qpixmapfilter.cpp
index 60edd01d00..e1e8175423 100644
--- a/src/widgets/effects/qpixmapfilter.cpp
+++ b/src/widgets/effects/qpixmapfilter.cpp
@@ -54,6 +54,8 @@
#include "private/qmemrotate_p.h"
#include "private/qdrawhelper_p.h"
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QPixmapFilterPrivate : public QObjectPrivate
@@ -319,7 +321,7 @@ static void convolute(
const QImage processImage = (srcImage.format() != QImage::Format_ARGB32_Premultiplied ) ? srcImage.convertToFormat(QImage::Format_ARGB32_Premultiplied) : srcImage;
// TODO: support also other formats directly without copying
- int *fixedKernel = new int[kernelWidth*kernelHeight];
+ std::unique_ptr<int[]> fixedKernel(new int[kernelWidth * kernelHeight]);
for(int i = 0; i < kernelWidth*kernelHeight; i++)
{
fixedKernel[i] = (int)(65536 * kernel[i]);
@@ -403,7 +405,6 @@ static void convolute(
}
yk++;
}
- delete[] fixedKernel;
}
/*!
diff --git a/src/widgets/graphicsview/qgraphicsgridlayout.cpp b/src/widgets/graphicsview/qgraphicsgridlayout.cpp
index d9005afbef..6b7052a0ab 100644
--- a/src/widgets/graphicsview/qgraphicsgridlayout.cpp
+++ b/src/widgets/graphicsview/qgraphicsgridlayout.cpp
@@ -552,20 +552,19 @@ int QGraphicsGridLayout::count() const
}
/*!
- Returns the layout item at \a index, or 0 if there is no layout item at
- this index.
+ Returns the layout item at \a index, or \nullptr if there is no
+ layout item at this index.
*/
QGraphicsLayoutItem *QGraphicsGridLayout::itemAt(int index) const
{
Q_D(const QGraphicsGridLayout);
if (index < 0 || index >= d->engine.itemCount()) {
qWarning("QGraphicsGridLayout::itemAt: invalid index %d", index);
- return 0;
+ return nullptr;
}
- QGraphicsLayoutItem *item = 0;
if (QGraphicsGridLayoutEngineItem *engineItem = static_cast<QGraphicsGridLayoutEngineItem*>(d->engine.itemAt(index)))
- item = engineItem->layoutItem();
- return item;
+ return engineItem->layoutItem();
+ return nullptr;
}
/*!
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index 86f3d6a2f0..6e53ea94f3 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -661,9 +661,9 @@
\value ItemSceneChange The item is moved to a new scene. This notification is
also sent when the item is added to its initial scene, and when it is removed.
- The item's scene() is the old scene (or 0 if the item has not been added to a
- scene yet). The value argument is the new scene (i.e., a QGraphicsScene
- pointer), or a null pointer if the item is removed from a scene. Do not
+ The item's scene() is the old scene, or \nullptr if the item has not been added
+ to a scene yet. The value argument is the new scene (i.e., a QGraphicsScene
+ pointer), or \nullptr if the item is removed from a scene. Do not
override this change by passing this item to QGraphicsScene::addItem() as this
notification is delivered; instead, you can return the new scene from
itemChange(). Use this feature with caution; objecting to a scene change can
@@ -1542,7 +1542,7 @@ void QGraphicsItemCache::purge()
Constructs a QGraphicsItem with the given \a parent item.
It does not modify the parent object returned by QObject::parent().
- If \a parent is 0, you can add the item to a scene by calling
+ If \a parent is \nullptr, you can add the item to a scene by calling
QGraphicsScene::addItem(). The item will then become a top-level item.
\sa QGraphicsScene::addItem(), setParentItem()
@@ -1650,8 +1650,8 @@ QGraphicsItem::~QGraphicsItem()
}
/*!
- Returns the current scene for the item, or 0 if the item is not stored in
- a scene.
+ Returns the current scene for the item, or \nullptr if the item is
+ not stored in a scene.
To add or move an item to a scene, call QGraphicsScene::addItem().
*/
@@ -1661,15 +1661,15 @@ QGraphicsScene *QGraphicsItem::scene() const
}
/*!
- Returns a pointer to this item's item group, or 0 if this item is not
- member of a group.
+ Returns a pointer to this item's item group, or \nullptr if this
+ item is not member of a group.
\sa QGraphicsItemGroup, QGraphicsScene::createItemGroup()
*/
QGraphicsItemGroup *QGraphicsItem::group() const
{
if (!d_ptr->isMemberOfGroup)
- return 0;
+ return nullptr;
QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
while ((parent = parent->d_ptr->parent)) {
if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(parent))
@@ -1677,11 +1677,11 @@ QGraphicsItemGroup *QGraphicsItem::group() const
}
// Unreachable; if d_ptr->isMemberOfGroup is != 0, then one parent of this
// item is a group item.
- return 0;
+ return nullptr;
}
/*!
- Adds this item to the item group \a group. If \a group is 0, this item is
+ Adds this item to the item group \a group. If \a group is \nullptr, this item is
removed from any current group and added as a child of the previous
group's parent.
@@ -1699,7 +1699,7 @@ void QGraphicsItem::setGroup(QGraphicsItemGroup *group)
/*!
Returns a pointer to this item's parent item. If this item does not have a
- parent, 0 is returned.
+ parent, \nullptr is returned.
\sa setParentItem(), childItems()
*/
@@ -1710,8 +1710,9 @@ QGraphicsItem *QGraphicsItem::parentItem() const
/*!
Returns this item's top-level item. The top-level item is the item's
- topmost ancestor item whose parent is 0. If an item has no parent, its own
- pointer is returned (i.e., a top-level item is its own top-level item).
+ topmost ancestor item whose parent is \nullptr. If an item has no
+ parent, its own pointer is returned (i.e., a top-level item is its
+ own top-level item).
\sa parentItem()
*/
@@ -1734,7 +1735,7 @@ QGraphicsItem *QGraphicsItem::topLevelItem() const
QGraphicsObject *QGraphicsItem::parentObject() const
{
QGraphicsItem *p = d_ptr->parent;
- return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : 0;
+ return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : nullptr;
}
/*!
@@ -1757,23 +1758,24 @@ QGraphicsWidget *QGraphicsItem::parentWidget() const
\since 4.4
Returns a pointer to the item's top level widget (i.e., the item's
- ancestor whose parent is 0, or whose parent is not a widget), or 0 if this
- item does not have a top level widget. If the item is its own top level
- widget, this function returns a pointer to the item itself.
+ ancestor whose parent is \nullptr, or whose parent is not a widget), or
+ \nullptr if this item does not have a top level widget. If the item
+ is its own top level widget, this function returns a pointer to the
+ item itself.
*/
QGraphicsWidget *QGraphicsItem::topLevelWidget() const
{
if (const QGraphicsWidget *p = parentWidget())
return p->topLevelWidget();
- return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : 0;
+ return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : nullptr;
}
/*!
\since 4.4
- Returns the item's window, or 0 if this item does not have a window. If
- the item is a window, it will return itself. Otherwise it will return the
- closest ancestor that is a window.
+ Returns the item's window, or \nullptr if this item does not have a
+ window. If the item is a window, it will return itself. Otherwise
+ it will return the closest ancestor that is a window.
\sa QGraphicsWidget::isWindow()
*/
@@ -1782,15 +1784,15 @@ QGraphicsWidget *QGraphicsItem::window() const
QGraphicsItem *p = panel();
if (p && p->isWindow())
return static_cast<QGraphicsWidget *>(p);
- return 0;
+ return nullptr;
}
/*!
\since 4.6
- Returns the item's panel, or 0 if this item does not have a panel. If the
- item is a panel, it will return itself. Otherwise it will return the
- closest ancestor that is a panel.
+ Returns the item's panel, or \nullptr if this item does not have a
+ panel. If the item is a panel, it will return itself. Otherwise it
+ will return the closest ancestor that is a panel.
\sa isPanel(), ItemIsPanel
*/
@@ -1798,7 +1800,7 @@ QGraphicsItem *QGraphicsItem::panel() const
{
if (d_ptr->flags & ItemIsPanel)
return const_cast<QGraphicsItem *>(this);
- return d_ptr->parent ? d_ptr->parent->panel() : 0;
+ return d_ptr->parent ? d_ptr->parent->panel() : nullptr;
}
/*!
@@ -2397,7 +2399,7 @@ bool QGraphicsItem::isVisible() const
/*!
\since 4.4
Returns \c true if the item is visible to \a parent; otherwise, false is
- returned. \a parent can be 0, in which case this function will return
+ returned. \a parent can be \nullptr, in which case this function will return
whether the item is visible to the scene or not.
An item may not be visible to its ancestors even if isVisible() is true. It
@@ -2925,7 +2927,7 @@ void QGraphicsItem::setOpacity(qreal opacity)
}
/*!
- Returns a pointer to this item's effect if it has one; otherwise 0.
+ Returns a pointer to this item's effect if it has one; otherwise \nullptr.
\since 4.6
*/
@@ -2939,7 +2941,7 @@ QGraphicsEffect *QGraphicsItem::graphicsEffect() const
Sets \a effect as the item's effect. If there already is an effect installed
on this item, QGraphicsItem will delete the existing effect before installing
the new \a effect. You can delete an existing effect by calling
- setGraphicsEffect(0).
+ setGraphicsEffect(\nullptr).
If \a effect is the installed effect on a different item, setGraphicsEffect() will remove
the effect from the item and install it on this item.
@@ -3577,7 +3579,7 @@ void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent, bool hiddenB
/*!
\since 4.6
- Returns this item's focus proxy, or 0 if this item has no
+ Returns this item's focus proxy, or \nullptr if this item has no
focus proxy.
\sa setFocusProxy(), setFocus(), hasFocus()
@@ -3640,7 +3642,7 @@ void QGraphicsItem::setFocusProxy(QGraphicsItem *item)
If this item, a child or descendant of this item currently has input
focus, this function will return a pointer to that item. If
- no descendant has input focus, 0 is returned.
+ no descendant has input focus, \nullptr is returned.
\sa hasFocus(), setFocus(), QWidget::focusWidget()
*/
@@ -3995,6 +3997,7 @@ void QGraphicsItem::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin).
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -4010,6 +4013,7 @@ QMatrix QGraphicsItem::matrix() const
{
return transform().toAffine();
}
+#endif
/*!
\since 4.3
@@ -4320,6 +4324,7 @@ void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -4332,7 +4337,7 @@ QMatrix QGraphicsItem::sceneMatrix() const
d_ptr->ensureSceneTransform();
return d_ptr->sceneTransform.toAffine();
}
-
+#endif
/*!
\since 4.3
@@ -4544,6 +4549,7 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
return x;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -4582,6 +4588,7 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
// Send post-notification.
itemChange(ItemTransformHasChanged, QVariant::fromValue<QTransform>(newTransform));
}
+#endif
/*!
\since 4.3
@@ -4636,6 +4643,7 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
d_ptr->sendScenePosChange();
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -4645,6 +4653,7 @@ void QGraphicsItem::resetMatrix()
{
resetTransform();
}
+#endif
/*!
\since 4.3
@@ -5790,7 +5799,7 @@ void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem, QGraphicsItem
/*!
\internal
- Sets the focusProxy pointer to 0 for all items that have this item as their
+ Sets the focusProxy pointer to \nullptr for all items that have this item as their
focusProxy.
*/
void QGraphicsItemPrivate::resetFocusProxy()
@@ -6001,7 +6010,7 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
Maps the point \a point, which is in this item's coordinate system, to \a
item's coordinate system, and returns the mapped coordinate.
- If \a item is 0, this function returns the same as mapToScene().
+ If \a item is \nullptr, this function returns the same as mapToScene().
\sa itemTransform(), mapToParent(), mapToScene(), transform(), mapFromItem(), {The Graphics
View Coordinate System}
@@ -6071,7 +6080,7 @@ QPointF QGraphicsItem::mapToScene(const QPointF &point) const
Maps the rectangle \a rect, which is in this item's coordinate system, to
\a item's coordinate system, and returns the mapped rectangle as a polygon.
- If \a item is 0, this function returns the same as mapToScene().
+ If \a item is \nullptr, this function returns the same as mapToScene().
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
Graphics View Coordinate System}
@@ -6142,7 +6151,7 @@ QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const
\a item's coordinate system, and returns the mapped rectangle as a new
rectangle (i.e., the bounding rectangle of the resulting polygon).
- If \a item is 0, this function returns the same as mapRectToScene().
+ If \a item is \nullptr, this function returns the same as mapRectToScene().
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
Graphics View Coordinate System}
@@ -6217,7 +6226,7 @@ QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const
this item's coordinate system, and returns the mapped rectangle as a new
rectangle (i.e., the bounding rectangle of the resulting polygon).
- If \a item is 0, this function returns the same as mapRectFromScene().
+ If \a item is \nullptr, this function returns the same as mapRectFromScene().
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
Graphics View Coordinate System}
@@ -6290,7 +6299,7 @@ QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const
Maps the polygon \a polygon, which is in this item's coordinate system, to
\a item's coordinate system, and returns the mapped polygon.
- If \a item is 0, this function returns the same as mapToScene().
+ If \a item is \nullptr, this function returns the same as mapToScene().
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
Graphics View Coordinate System}
@@ -6337,7 +6346,7 @@ QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const
Maps the path \a path, which is in this item's coordinate system, to
\a item's coordinate system, and returns the mapped path.
- If \a item is 0, this function returns the same as mapToScene().
+ If \a item is \nullptr, this function returns the same as mapToScene().
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
Graphics View Coordinate System}
@@ -6384,7 +6393,7 @@ QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const
Maps the point \a point, which is in \a item's coordinate system, to this
item's coordinate system, and returns the mapped coordinate.
- If \a item is 0, this function returns the same as mapFromScene().
+ If \a item is \nullptr, this function returns the same as mapFromScene().
\sa itemTransform(), mapFromParent(), mapFromScene(), transform(), mapToItem(), {The Graphics
View Coordinate System}
@@ -6456,7 +6465,7 @@ QPointF QGraphicsItem::mapFromScene(const QPointF &point) const
this item's coordinate system, and returns the mapped rectangle as a
polygon.
- If \a item is 0, this function returns the same as mapFromScene()
+ If \a item is \nullptr, this function returns the same as mapFromScene()
\sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The Graphics View Coordinate
System}
@@ -6524,7 +6533,7 @@ QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const
Maps the polygon \a polygon, which is in \a item's coordinate system, to
this item's coordinate system, and returns the mapped polygon.
- If \a item is 0, this function returns the same as mapFromScene().
+ If \a item is \nullptr, this function returns the same as mapFromScene().
\sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The
Graphics View Coordinate System}
@@ -6569,7 +6578,7 @@ QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const
Maps the path \a path, which is in \a item's coordinate system, to
this item's coordinate system, and returns the mapped path.
- If \a item is 0, this function returns the same as mapFromScene().
+ If \a item is \nullptr, this function returns the same as mapFromScene().
\sa itemTransform(), mapFromParent(), mapFromScene(), mapToItem(), {The
Graphics View Coordinate System}
@@ -6633,15 +6642,15 @@ bool QGraphicsItem::isAncestorOf(const QGraphicsItem *child) const
/*!
\since 4.4
- Returns the closest common ancestor item of this item and \a other, or 0
- if either \a other is 0, or there is no common ancestor.
+ Returns the closest common ancestor item of this item and \a other,
+ or \nullptr if either \a other is \nullptr, or there is no common ancestor.
\sa isAncestorOf()
*/
QGraphicsItem *QGraphicsItem::commonAncestorItem(const QGraphicsItem *other) const
{
if (!other)
- return 0;
+ return nullptr;
if (other == this)
return const_cast<QGraphicsItem *>(this);
const QGraphicsItem *thisw = this;
@@ -6726,7 +6735,7 @@ void QGraphicsItem::setData(int key, const QVariant &value)
\since 4.2
Returns the given \a item cast to type T if \a item is of type T;
- otherwise, 0 is returned.
+ otherwise, \nullptr is returned.
\note To make this function work correctly with custom items, reimplement
the \l{QGraphicsItem::}{type()} function for each custom QGraphicsItem
diff --git a/src/widgets/graphicsview/qgraphicsitem.h b/src/widgets/graphicsview/qgraphicsitem.h
index c228e765d8..7dd4441ae9 100644
--- a/src/widgets/graphicsview/qgraphicsitem.h
+++ b/src/widgets/graphicsview/qgraphicsitem.h
@@ -283,10 +283,16 @@ public:
inline void ensureVisible(qreal x, qreal y, qreal w, qreal h, int xmargin = 50, int ymargin = 50);
// Local transformation
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use transform() instead")
QMatrix matrix() const;
+ QT_DEPRECATED_X("Use sceneTransform() instead")
QMatrix sceneMatrix() const;
+ QT_DEPRECATED_X("Use setTransform() instead")
void setMatrix(const QMatrix &matrix, bool combine = false);
+ QT_DEPRECATED_X("Use resetTransform() instead")
void resetMatrix();
+#endif
QTransform transform() const;
QTransform sceneTransform() const;
QTransform deviceTransform(const QTransform &viewportTransform) const;
@@ -487,7 +493,9 @@ private:
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsItem::GraphicsItemFlags)
+#ifndef Q_CLANG_QDOC
Q_DECLARE_INTERFACE(QGraphicsItem, "org.qt-project.Qt.QGraphicsItem")
+#endif
inline void QGraphicsItem::setPos(qreal ax, qreal ay)
{ setPos(QPointF(ax, ay)); }
diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
index 572ec141bc..78b91d5c39 100644
--- a/src/widgets/graphicsview/qgraphicsitemanimation.cpp
+++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
@@ -549,6 +549,7 @@ void QGraphicsItemAnimation::setStep(qreal step)
afterAnimationStep(step);
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Resets the item to its starting position and transformation.
@@ -563,6 +564,7 @@ void QGraphicsItemAnimation::reset()
d->startPos = d->item->pos();
d->startMatrix = d->item->matrix();
}
+#endif
/*!
\fn void QGraphicsItemAnimation::beforeAnimationStep(qreal step)
diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.h b/src/widgets/graphicsview/qgraphicsitemanimation.h
index 7417d7729c..f983bd8026 100644
--- a/src/widgets/graphicsview/qgraphicsitemanimation.h
+++ b/src/widgets/graphicsview/qgraphicsitemanimation.h
@@ -96,7 +96,10 @@ public:
public Q_SLOTS:
void setStep(qreal x);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use setStep(0) instead")
void reset();
+#endif
protected:
virtual void beforeAnimationStep(qreal step);
diff --git a/src/widgets/graphicsview/qgraphicslayout.h b/src/widgets/graphicsview/qgraphicslayout.h
index 28b335ceaa..efcafa5e6a 100644
--- a/src/widgets/graphicsview/qgraphicslayout.h
+++ b/src/widgets/graphicsview/qgraphicslayout.h
@@ -83,7 +83,9 @@ private:
friend class QGraphicsWidget;
};
+#ifndef Q_CLANG_QDOC
Q_DECLARE_INTERFACE(QGraphicsLayout, "org.qt-project.Qt.QGraphicsLayout")
+#endif
QT_END_NAMESPACE
diff --git a/src/widgets/graphicsview/qgraphicslayoutitem.cpp b/src/widgets/graphicsview/qgraphicslayoutitem.cpp
index aed154a95f..1192bad51e 100644
--- a/src/widgets/graphicsview/qgraphicslayoutitem.cpp
+++ b/src/widgets/graphicsview/qgraphicslayoutitem.cpp
@@ -193,7 +193,7 @@ QSizeF *QGraphicsLayoutItemPrivate::effectiveSizeHints(const QSizeF &constraint)
/*!
\internal
- Returns the parent item of this layout, or 0 if this layout is
+ Returns the parent item of this layout, or \nullptr if this layout is
not installed on any widget.
If this is the item that the layout is installed on, it will return "itself".
@@ -214,7 +214,7 @@ QGraphicsItem *QGraphicsLayoutItemPrivate::parentItem() const
while (parent && parent->isLayout()) {
parent = parent->parentLayoutItem();
}
- return parent ? parent->graphicsItem() : 0;
+ return parent ? parent->graphicsItem() : nullptr;
}
/*!
@@ -368,7 +368,7 @@ bool QGraphicsLayoutItemPrivate::hasWidthForHeight() const
passing a QGraphicsLayoutItem pointer to QGraphicsLayoutItem's
protected constructor, or by calling setParentLayoutItem(). The
parentLayoutItem() function returns a pointer to the item's layoutItem
- parent. If the item's parent is 0 or if the parent does not inherit
+ parent. If the item's parent is \nullptr or if the parent does not inherit
from QGraphicsItem, the parentLayoutItem() function then returns \nullptr.
isLayout() returns \c true if the QGraphicsLayoutItem subclass is itself a
layout, or false otherwise.
@@ -737,7 +737,7 @@ QRectF QGraphicsLayoutItem::geometry() const
This virtual function provides the \a left, \a top, \a right and \a bottom
contents margins for this QGraphicsLayoutItem. The default implementation
assumes all contents margins are 0. The parameters point to values stored
- in qreals. If any of the pointers is 0, that value will not be updated.
+ in qreals. If any of the pointers is \nullptr, that value will not be updated.
\sa QGraphicsWidget::setContentsMargins()
*/
@@ -826,8 +826,8 @@ void QGraphicsLayoutItem::updateGeometry()
}
/*!
- Returns the parent of this QGraphicsLayoutItem, or 0 if there is no parent,
- or if the parent does not inherit from QGraphicsLayoutItem
+ Returns the parent of this QGraphicsLayoutItem, or \nullptr if there is
+ no parent, or if the parent does not inherit from QGraphicsLayoutItem
(QGraphicsLayoutItem is often used through multiple inheritance with
QObject-derived classes).
@@ -917,7 +917,7 @@ QGraphicsItem *QGraphicsLayoutItem::graphicsItem() const
* advantage of the automatic reparenting capabilities of QGraphicsLayout it
* should set this value.
* Note that if you delete \a item and not delete the layout item, you are
- * responsible of calling setGraphicsItem(0) in order to avoid having a
+ * responsible of calling setGraphicsItem(\nullptr) in order to avoid having a
* dangling pointer.
*
* \sa graphicsItem()
diff --git a/src/widgets/graphicsview/qgraphicslayoutitem.h b/src/widgets/graphicsview/qgraphicslayoutitem.h
index 44f430034b..86a0a87361 100644
--- a/src/widgets/graphicsview/qgraphicslayoutitem.h
+++ b/src/widgets/graphicsview/qgraphicslayoutitem.h
@@ -116,7 +116,9 @@ private:
friend class QGraphicsLayout;
};
+#ifndef Q_CLANG_QDOC
Q_DECLARE_INTERFACE(QGraphicsLayoutItem, "org.qt-project.Qt.QGraphicsLayoutItem")
+#endif
inline void QGraphicsLayoutItem::setMinimumSize(qreal aw, qreal ah)
{ setMinimumSize(QSizeF(aw, ah)); }
diff --git a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp
index af969b346d..da2510a8cb 100644
--- a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp
+++ b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp
@@ -50,15 +50,13 @@ QT_BEGIN_NAMESPACE
QGraphicsLayoutStyleInfo::QGraphicsLayoutStyleInfo(const QGraphicsLayoutPrivate *layout)
: m_layout(layout), m_style(0)
{
- m_widget = new QWidget; // pixelMetric might need a widget ptr
- if (m_widget)
- m_styleOption.initFrom(m_widget);
+ m_widget.reset(new QWidget); // pixelMetric might need a widget ptr
+ m_styleOption.initFrom(m_widget.get());
m_isWindow = m_styleOption.state & QStyle::State_Window;
}
QGraphicsLayoutStyleInfo::~QGraphicsLayoutStyleInfo()
{
- delete m_widget;
}
qreal QGraphicsLayoutStyleInfo::combinedLayoutSpacing(QLayoutPolicy::ControlTypes controls1,
@@ -93,7 +91,7 @@ qreal QGraphicsLayoutStyleInfo::windowMargin(Qt::Orientation orientation) const
const_cast<QStyleOption*>(&m_styleOption), widget());
}
-QWidget *QGraphicsLayoutStyleInfo::widget() const { return m_widget; }
+QWidget *QGraphicsLayoutStyleInfo::widget() const { return m_widget.get(); }
QStyle *QGraphicsLayoutStyleInfo::style() const
{
diff --git a/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h b/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h
index 7886de432c..c3af9f4554 100644
--- a/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h
+++ b/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h
@@ -54,6 +54,8 @@
#include <QtGui/private/qabstractlayoutstyleinfo_p.h>
#include <QtWidgets/qstyleoption.h>
+#include <memory>
+
QT_REQUIRE_CONFIG(graphicsview);
QT_BEGIN_NAMESPACE
@@ -93,7 +95,7 @@ private:
const QGraphicsLayoutPrivate *m_layout;
mutable QStyle *m_style;
QStyleOption m_styleOption;
- QWidget *m_widget;
+ std::unique_ptr<QWidget> m_widget;
};
QT_END_NAMESPACE
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
index 513cf9d361..e9f092020f 100644
--- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
@@ -556,7 +556,7 @@ QGraphicsProxyWidget::~QGraphicsProxyWidget()
exclusively either inside or outside of Graphics View. You cannot embed a
widget as long as it is is visible elsewhere in the UI, at the same time.
- \a widget must be a top-level widget whose parent is 0.
+ \a widget must be a top-level widget whose parent is \nullptr.
When the widget is embedded, its state (e.g., visible, enabled, geometry,
size hints) is copied into the proxy widget. If the embedded widget is
@@ -739,7 +739,7 @@ QWidget *QGraphicsProxyWidget::widget() const
Returns the rectangle for \a widget, which must be a descendant of
widget(), or widget() itself, in this proxy item's local coordinates.
- If no widget is embedded, \a widget is 0, or \a widget is not a
+ If no widget is embedded, \a widget is \nullptr, or \a widget is not a
descendant of the embedded widget, this function returns an empty QRectF.
\sa widget()
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp
index bba992144d..19d9f25307 100644
--- a/src/widgets/graphicsview/qgraphicsscene.cpp
+++ b/src/widgets/graphicsview/qgraphicsscene.cpp
@@ -1923,12 +1923,13 @@ void QGraphicsScene::setBspTreeDepth(int depth)
QGraphicsSceneBspTreeIndex *bspTree = qobject_cast<QGraphicsSceneBspTreeIndex *>(d->index);
if (!bspTree) {
- qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP");
+ qWarning("QGraphicsScene::setBspTreeDepth: cannot apply if indexing method is not BSP");
return;
}
bspTree->setBspTreeDepth(depth);
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\property QGraphicsScene::sortCacheEnabled
\brief whether sort caching is enabled
@@ -1949,6 +1950,7 @@ void QGraphicsScene::setSortCacheEnabled(bool enabled)
return;
d->sortCacheEnabled = enabled;
}
+#endif
/*!
Calculates and returns the bounding rect of all items on the scene. This
@@ -2144,8 +2146,8 @@ QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item,
\overload
\obsolete
- Returns the topmost visible item at the specified \a position, or 0 if
- there are no items at this position.
+ Returns the topmost visible item at the specified \a position, or
+ \nullptr if there are no items at this position.
This function is deprecated and returns incorrect results if the scene
contains items that ignore transformations. Use the overload that takes
@@ -2159,7 +2161,7 @@ QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item,
/*!
\since 4.6
- Returns the topmost visible item at the specified \a position, or 0
+ Returns the topmost visible item at the specified \a position, or \nullptr
if there are no items at this position.
\a deviceTransform is the transformation that applies to the view, and needs to
@@ -2173,7 +2175,7 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform
{
const QList<QGraphicsItem *> itemsAtPoint = items(position, Qt::IntersectsItemShape,
Qt::DescendingOrder, deviceTransform);
- return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
+ return itemsAtPoint.isEmpty() ? nullptr : itemsAtPoint.first();
}
/*!
@@ -2182,7 +2184,7 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform
\since 4.6
Returns the topmost visible item at the position specified by (\a x, \a
- y), or 0 if there are no items at this position.
+ y), or \nullptr if there are no items at this position.
\a deviceTransform is the transformation that applies to the view, and needs to
be provided if the scene contains items that ignore transformations.
@@ -2199,7 +2201,7 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform
\obsolete
Returns the topmost visible item at the position specified by (\a x, \a
- y), or 0 if there are no items at this position.
+ y), or \nullptr if there are no items at this position.
This convenience function is equivalent to calling \c
{itemAt(QPointF(x, y))}.
@@ -2941,9 +2943,9 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
/*!
When the scene is active, this functions returns the scene's current focus
- item, or 0 if no item currently has focus. When the scene is inactive, this
- functions returns the item that will gain input focus when the scene becomes
- active.
+ item, or \nullptr if no item currently has focus. When the scene is inactive,
+ this functions returns the item that will gain input focus when the scene
+ becomes active.
The focus item receives keyboard input when the scene receives a
key event.
@@ -2961,12 +2963,12 @@ QGraphicsItem *QGraphicsScene::focusItem() const
focusReason, after removing focus from any previous item that may have had
focus.
- If \a item is 0, or if it either does not accept focus (i.e., it does not
+ If \a item is \nullptr, or if it either does not accept focus (i.e., it does not
have the QGraphicsItem::ItemIsFocusable flag enabled), or is not visible
or not enabled, this function only removes focus from any previous
focusitem.
- If item is not 0, and the scene does not currently have focus (i.e.,
+ If item is not \nullptr, and the scene does not currently have focus (i.e.,
hasFocus() returns \c false), this function will call setFocus()
automatically.
@@ -3062,9 +3064,9 @@ bool QGraphicsScene::stickyFocus() const
}
/*!
- Returns the current mouse grabber item, or 0 if no item is currently
- grabbing the mouse. The mouse grabber item is the item that receives all
- mouse events sent to the scene.
+ Returns the current mouse grabber item, or \nullptr if no item is
+ currently grabbing the mouse. The mouse grabber item is the item
+ that receives all mouse events sent to the scene.
An item becomes a mouse grabber when it receives and accepts a
mouse press event, and it stays the mouse grabber until either of
@@ -3322,6 +3324,9 @@ void QGraphicsScene::advance()
\l{QWidget::}{enterEvent()} and \l{QWidget::}{leaveEvent()}. Use this
function to obtain those events instead.
+ Returns \c true if \a event has been recognized and processed; otherwise,
+ returns \c false.
+
\sa contextMenuEvent(), keyPressEvent(), keyReleaseEvent(),
mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(),
mouseDoubleClickEvent(), focusInEvent(), focusOutEvent()
@@ -5547,11 +5552,11 @@ bool QGraphicsScene::focusNextPrevChild(bool next)
\a oldFocusItem is a pointer to the item that previously had focus, or
0 if no item had focus before the signal was emitted. \a newFocusItem
- is a pointer to the item that gained input focus, or 0 if focus was lost.
+ is a pointer to the item that gained input focus, or \nullptr if focus was lost.
\a reason is the reason for the focus change (e.g., if the scene was
deactivated while an input field had focus, \a oldFocusItem would point
- to the input field item, \a newFocusItem would be 0, and \a reason would be
- Qt::ActiveWindowFocusReason.
+ to the input field item, \a newFocusItem would be \nullptr, and \a reason
+ would be Qt::ActiveWindowFocusReason.
*/
/*!
@@ -5582,7 +5587,7 @@ QStyle *QGraphicsScene::style() const
the style for all widgets in the scene that do not have a style explicitly
assigned to them.
- If \a style is 0, QGraphicsScene will revert to QApplication::style().
+ If \a style is \nullptr, QGraphicsScene will revert to QApplication::style().
\sa style()
*/
@@ -5703,7 +5708,8 @@ bool QGraphicsScene::isActive() const
/*!
\since 4.6
- Returns the current active panel, or 0 if no panel is currently active.
+ Returns the current active panel, or \nullptr if no panel is
+ currently active.
\sa QGraphicsScene::setActivePanel()
*/
@@ -5720,7 +5726,7 @@ QGraphicsItem *QGraphicsScene::activePanel() const
deactivate any currently active panel.
If the scene is currently inactive, \a item remains inactive until the
- scene becomes active (or, ir \a item is 0, no item will be activated).
+ scene becomes active (or, ir \a item is \nullptr, no item will be activated).
\sa activePanel(), isActive(), QGraphicsItem::isActive()
*/
@@ -5733,8 +5739,8 @@ void QGraphicsScene::setActivePanel(QGraphicsItem *item)
/*!
\since 4.4
- Returns the current active window, or 0 if no window is currently
- active.
+ Returns the current active window, or \nullptr if no window is
+ currently active.
\sa QGraphicsScene::setActiveWindow()
*/
@@ -5743,7 +5749,7 @@ QGraphicsWidget *QGraphicsScene::activeWindow() const
Q_D(const QGraphicsScene);
if (d->activePanel && d->activePanel->isWindow())
return static_cast<QGraphicsWidget *>(d->activePanel);
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/widgets/graphicsview/qgraphicsscene.h b/src/widgets/graphicsview/qgraphicsscene.h
index 287e551db7..3cc00ead08 100644
--- a/src/widgets/graphicsview/qgraphicsscene.h
+++ b/src/widgets/graphicsview/qgraphicsscene.h
@@ -103,7 +103,9 @@ class Q_WIDGETS_EXPORT QGraphicsScene : public QObject
Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth)
Q_PROPERTY(QPalette palette READ palette WRITE setPalette)
Q_PROPERTY(QFont font READ font WRITE setFont)
+#if QT_DEPRECATED_SINCE(5, 13)
Q_PROPERTY(bool sortCacheEnabled READ isSortCacheEnabled WRITE setSortCacheEnabled)
+#endif
Q_PROPERTY(bool stickyFocus READ stickyFocus WRITE setStickyFocus)
Q_PROPERTY(qreal minimumRenderSize READ minimumRenderSize WRITE setMinimumRenderSize)
Q_PROPERTY(bool focusOnTouch READ focusOnTouch WRITE setFocusOnTouch)
@@ -141,8 +143,10 @@ public:
ItemIndexMethod itemIndexMethod() const;
void setItemIndexMethod(ItemIndexMethod method);
- bool isSortCacheEnabled() const;
- void setSortCacheEnabled(bool enabled);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED bool isSortCacheEnabled() const;
+ QT_DEPRECATED void setSortCacheEnabled(bool enabled);
+#endif
int bspTreeDepth() const;
void setBspTreeDepth(int depth);
diff --git a/src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h
index b6387a2c56..eb6bbbf49b 100644
--- a/src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h
+++ b/src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h
@@ -99,7 +99,7 @@ protected:
private :
Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex)
- Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex)
+ Q_DISABLE_COPY_MOVE(QGraphicsSceneBspTreeIndex)
Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache())
Q_PRIVATE_SLOT(d_func(), void _q_updateIndex())
diff --git a/src/widgets/graphicsview/qgraphicssceneevent.cpp b/src/widgets/graphicsview/qgraphicssceneevent.cpp
index 398ef1aaf5..5077a39d67 100644
--- a/src/widgets/graphicsview/qgraphicssceneevent.cpp
+++ b/src/widgets/graphicsview/qgraphicssceneevent.cpp
@@ -319,8 +319,8 @@ QGraphicsSceneEvent::~QGraphicsSceneEvent()
}
/*!
- Returns the widget where the event originated, or 0 if the event
- originates from another application.
+ Returns the widget where the event originated, or \nullptr if the
+ event originates from another application.
*/
QWidget *QGraphicsSceneEvent::widget() const
{
diff --git a/src/widgets/graphicsview/qgraphicssceneindex_p.h b/src/widgets/graphicsview/qgraphicssceneindex_p.h
index bdc57bd9ea..86637e836b 100644
--- a/src/widgets/graphicsview/qgraphicssceneindex_p.h
+++ b/src/widgets/graphicsview/qgraphicssceneindex_p.h
@@ -115,7 +115,7 @@ protected:
friend class QGraphicsItemPrivate;
friend class QGraphicsSceneBspTreeIndex;
private:
- Q_DISABLE_COPY(QGraphicsSceneIndex)
+ Q_DISABLE_COPY_MOVE(QGraphicsSceneIndex)
Q_DECLARE_PRIVATE(QGraphicsSceneIndex)
};
@@ -151,7 +151,7 @@ inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphi
if (order == Qt::DescendingOrder) {
const int n = items->size();
for (int i = 0; i < n / 2; ++i)
- items->swap(i, n - i - 1);
+ items->swapItemsAt(i, n - i - 1);
}
}
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index 24647dd74c..5fe520132f 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -1676,7 +1676,7 @@ void QGraphicsView::setInteractive(bool allowed)
/*!
Returns a pointer to the scene that is currently visualized in the
- view. If no scene is currently visualized, 0 is returned.
+ view. If no scene is currently visualized, \nullptr is returned.
\sa setScene()
*/
diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp
index a4534c73dd..ad3be5766d 100644
--- a/src/widgets/graphicsview/qgraphicswidget.cpp
+++ b/src/widgets/graphicsview/qgraphicswidget.cpp
@@ -159,7 +159,7 @@ QT_BEGIN_NAMESPACE
manage the relationships between parent and child items. These functions
control the stacking order of items as well as their ownership.
- \note The QObject::parent() should always return 0 for QGraphicsWidgets,
+ \note The QObject::parent() should always return \nullptr for QGraphicsWidgets,
but this policy is not strictly defined.
\sa QGraphicsProxyWidget, QGraphicsItem, {Widgets and Layouts}
@@ -518,7 +518,7 @@ void QGraphicsWidget::setContentsMargins(qreal left, qreal top, qreal right, qre
/*!
Gets the widget's contents margins. The margins are stored in \a left, \a
top, \a right and \a bottom, as pointers to qreals. Each argument can
- be \e {omitted} by passing 0.
+ be \e {omitted} by passing \nullptr.
\sa setContentsMargins()
*/
@@ -573,7 +573,7 @@ void QGraphicsWidget::setWindowFrameMargins(qreal left, qreal top, qreal right,
/*!
Gets the widget's window frame margins. The margins are stored in \a left,
\a top, \a right and \a bottom as pointers to qreals. Each argument can
- be \e {omitted} by passing 0.
+ be \e {omitted} by passing \nullptr.
\sa setWindowFrameMargins(), windowFrameRect()
*/
@@ -780,7 +780,7 @@ QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c
\brief The layout of the widget
Any existing layout manager is deleted before the new layout is assigned. If
- \a layout is 0, the widget is left without a layout. Existing subwidgets'
+ \a layout is \nullptr, the widget is left without a layout. Existing subwidgets'
geometries will remain unaffected.
QGraphicsWidget takes ownership of \a layout.
@@ -792,7 +792,7 @@ QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c
explicitly managed by \a layout remain unaffected by the layout after
it has been assigned to this widget.
- If no layout is currently managing this widget, layout() will return 0.
+ If no layout is currently managing this widget, layout() will return \nullptr.
*/
@@ -803,8 +803,8 @@ QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c
*/
/*!
- Returns this widget's layout, or 0 if no layout is currently managing this
- widget.
+ Returns this widget's layout, or \nullptr if no layout is currently
+ managing this widget.
\sa setLayout()
*/
@@ -818,7 +818,7 @@ QGraphicsLayout *QGraphicsWidget::layout() const
\fn void QGraphicsWidget::setLayout(QGraphicsLayout *layout)
Sets the layout for this widget to \a layout. Any existing layout manager
- is deleted before the new layout is assigned. If \a layout is 0, the
+ is deleted before the new layout is assigned. If \a layout is \nullptr, the
widget is left without a layout. Existing subwidgets' geometries will
remain unaffected.
@@ -937,11 +937,11 @@ QStyle *QGraphicsWidget::style() const
Sets the widget's style to \a style. QGraphicsWidget does \e not take
ownership of \a style.
- If no style is assigned, or \a style is 0, the widget will use
+ If no style is assigned, or \a style is \nullptr, the widget will use
QGraphicsScene::style() (if this has been set). Otherwise the widget will
use QApplication::style().
- This function sets the Qt::WA_SetStyle attribute if \a style is not 0;
+ This function sets the Qt::WA_SetStyle attribute if \a style is not \nullptr;
otherwise it clears the attribute.
\sa style()
@@ -1232,6 +1232,9 @@ QVariant QGraphicsWidget::propertyChange(const QString &propertyName, const QVar
event() or in any of the convenience functions; you should not have to
reimplement this function in a subclass of QGraphicsWidget.
+ Returns \c true if \a event has been recognized and processed; otherwise,
+ returns \c false.
+
\sa QGraphicsItem::sceneEvent()
*/
bool QGraphicsWidget::sceneEvent(QEvent *event)
@@ -1871,7 +1874,7 @@ void QGraphicsWidget::setFocusPolicy(Qt::FocusPolicy policy)
/*!
If this widget, a child or descendant of this widget currently has input
focus, this function will return a pointer to that widget. If
- no descendant widget has input focus, 0 is returned.
+ no descendant widget has input focus, \nullptr is returned.
\sa QGraphicsItem::focusItem(), QWidget::focusWidget()
*/
@@ -1880,7 +1883,7 @@ QGraphicsWidget *QGraphicsWidget::focusWidget() const
Q_D(const QGraphicsWidget);
if (d->subFocusItem && d->subFocusItem->d_ptr->isWidget)
return static_cast<QGraphicsWidget *>(d->subFocusItem);
- return 0;
+ return nullptr;
}
#ifndef QT_NO_SHORTCUT
@@ -2022,7 +2025,7 @@ void QGraphicsWidget::addActions(QList<QAction *> actions)
\since 4.5
Inserts the action \a action to this widget's list of actions,
- before the action \a before. It appends the action if \a before is 0 or
+ before the action \a before. It appends the action if \a before is \nullptr or
\a before is not a valid action for this widget.
A QGraphicsWidget should only have one of each action.
@@ -2062,7 +2065,7 @@ void QGraphicsWidget::insertAction(QAction *before, QAction *action)
\since 4.5
Inserts the actions \a actions to this widget's list of actions,
- before the action \a before. It appends the action if \a before is 0 or
+ before the action \a before. It appends the action if \a before is \nullptr or
\a before is not a valid action for this widget.
A QGraphicsWidget can have at most one of each action.
@@ -2131,9 +2134,9 @@ QList<QAction *> QGraphicsWidget::actions() const
\snippet code/src_gui_graphicsview_qgraphicswidget.cpp 2
- If \a first is 0, this indicates that \a second should be the first widget
+ If \a first is \nullptr, this indicates that \a second should be the first widget
to receive input focus should the scene gain Tab focus (i.e., the user
- hits Tab so that focus passes into the scene). If \a second is 0, this
+ hits Tab so that focus passes into the scene). If \a second is \nullptr, this
indicates that \a first should be the first widget to gain focus if the
scene gained BackTab focus.
@@ -2306,7 +2309,7 @@ void QGraphicsWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGrap
QStyleHintReturnMask mask;
bool setMask = style()->styleHint(QStyle::SH_WindowFrame_Mask, &bar, widget, &mask) && !mask.region.isEmpty();
bool hasBorder = !style()->styleHint(QStyle::SH_TitleBar_NoBorder, &bar, widget);
- int frameWidth = style()->pixelMetric(QStyle::PM_MDIFrameWidth, &bar, widget);
+ int frameWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, &bar, widget);
if (setMask) {
painter->save();
painter->setClipRegion(mask.region, Qt::IntersectClip);
diff --git a/src/widgets/graphicsview/qsimplex_p.h b/src/widgets/graphicsview/qsimplex_p.h
index 2342da2437..369f2f5f82 100644
--- a/src/widgets/graphicsview/qsimplex_p.h
+++ b/src/widgets/graphicsview/qsimplex_p.h
@@ -150,7 +150,7 @@ struct QSimplexConstraint
class QSimplex
{
- Q_DISABLE_COPY(QSimplex)
+ Q_DISABLE_COPY_MOVE(QSimplex)
public:
QSimplex();
~QSimplex();
diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp
index 9508aed3d3..448e775a71 100644
--- a/src/widgets/itemviews/qabstractitemdelegate.cpp
+++ b/src/widgets/itemviews/qabstractitemdelegate.cpp
@@ -88,7 +88,7 @@ QT_BEGIN_NAMESPACE
and is part of Qt's \l{Model/View Programming}{model/view framework}.
To render an item in a custom way, you must implement paint() and
- sizeHint(). The QItemDelegate class provides default implementations for
+ sizeHint(). The QStyledItemDelegate class provides default implementations for
these functions; if you do not need custom rendering, subclass that
class instead.
@@ -115,7 +115,7 @@ QT_BEGIN_NAMESPACE
The second approach is to handle user events directly by reimplementing
editorEvent().
- \sa {model-view-programming}{Model/View Programming}, QItemDelegate,
+ \sa {model-view-programming}{Model/View Programming}, QStyledItemDelegate,
{Pixelator Example}, QStyledItemDelegate, QStyle
*/
@@ -345,6 +345,7 @@ bool QAbstractItemDelegate::editorEvent(QEvent *,
return false;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
@@ -364,6 +365,7 @@ QString QAbstractItemDelegate::elidedText(const QFontMetrics &fontMetrics, int w
{
return fontMetrics.elidedText(text, mode, width);
}
+#endif
/*!
\since 4.3
diff --git a/src/widgets/itemviews/qabstractitemdelegate.h b/src/widgets/itemviews/qabstractitemdelegate.h
index 575728e806..5696e55691 100644
--- a/src/widgets/itemviews/qabstractitemdelegate.h
+++ b/src/widgets/itemviews/qabstractitemdelegate.h
@@ -103,8 +103,11 @@ public:
const QStyleOptionViewItem &option,
const QModelIndex &index);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use QFontMetrics::elidedText() instead")
static QString elidedText(const QFontMetrics &fontMetrics, int width,
Qt::TextElideMode mode, const QString &text);
+#endif
virtual bool helpEvent(QHelpEvent *event,
QAbstractItemView *view,
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index e1e45143b4..95631ffa5f 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -940,8 +940,8 @@ void QAbstractItemView::setItemDelegateForRow(int row, QAbstractItemDelegate *de
\since 4.2
Returns the item delegate used by this view and model for the given \a row,
- or 0 if no delegate has been assigned. You can call itemDelegate() to get a
- pointer to the current delegate for a given index.
+ or \nullptr if no delegate has been assigned. You can call itemDelegate()
+ to get a pointer to the current delegate for a given index.
\sa setItemDelegateForRow(), itemDelegateForColumn(), setItemDelegate()
*/
@@ -1689,6 +1689,9 @@ bool QAbstractItemView::event(QEvent *event)
This? mode, if the given \a event is a QEvent::ToolTip,or a
QEvent::WhatsThis. It passes all other
events on to its base class viewportEvent() handler.
+
+ Returns \c true if \a event has been recognized and processed; otherwise,
+ returns \c false.
*/
bool QAbstractItemView::viewportEvent(QEvent *event)
{
@@ -2438,8 +2441,14 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
break;
case Qt::Key_Space:
case Qt::Key_Select:
- if (!edit(currentIndex(), AnyKeyPressed, event) && d->selectionModel)
- d->selectionModel->select(currentIndex(), selectionCommand(currentIndex(), event));
+ if (!edit(currentIndex(), AnyKeyPressed, event)) {
+ if (d->selectionModel)
+ d->selectionModel->select(currentIndex(), selectionCommand(currentIndex(), event));
+ if (event->key() == Qt::Key_Space) {
+ keyboardSearch(event->text());
+ event->accept();
+ }
+ }
#ifdef QT_KEYPAD_NAVIGATION
if ( event->key()==Qt::Key_Select ) {
// Also do Key_Enter action.
@@ -2915,6 +2924,7 @@ void QAbstractItemView::editorDestroyed(QObject *editor)
setState(NoState);
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
Sets the horizontal scroll bar's steps per item to \a steps.
@@ -2972,6 +2982,7 @@ int QAbstractItemView::verticalStepsPerItem() const
{
return 1;
}
+#endif
/*!
Moves to and selects the item best matching the string \a search.
@@ -3205,7 +3216,7 @@ bool QAbstractItemView::isPersistentEditorOpen(const QModelIndex &index) const
This function should only be used to display static content within the
visible area corresponding to an item of data. If you want to display
custom dynamic content or implement a custom editor widget, subclass
- QItemDelegate instead.
+ QStyledItemDelegate instead.
\sa {Delegate Classes}
*/
diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h
index 981582c166..be8fa07c94 100644
--- a/src/widgets/itemviews/qabstractitemview.h
+++ b/src/widgets/itemviews/qabstractitemview.h
@@ -272,10 +272,12 @@ Q_SIGNALS:
protected:
QAbstractItemView(QAbstractItemViewPrivate &, QWidget *parent = nullptr);
- void setHorizontalStepsPerItem(int steps);
- int horizontalStepsPerItem() const;
- void setVerticalStepsPerItem(int steps);
- int verticalStepsPerItem() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED void setHorizontalStepsPerItem(int steps);
+ QT_DEPRECATED int horizontalStepsPerItem() const;
+ QT_DEPRECATED void setVerticalStepsPerItem(int steps);
+ QT_DEPRECATED int verticalStepsPerItem() const;
+#endif
enum CursorAction { MoveUp, MoveDown, MoveLeft, MoveRight,
MoveHome, MoveEnd, MovePageUp, MovePageDown,
diff --git a/src/widgets/itemviews/qcolumnview.cpp b/src/widgets/itemviews/qcolumnview.cpp
index 1fe17721ba..a4eed2d885 100644
--- a/src/widgets/itemviews/qcolumnview.cpp
+++ b/src/widgets/itemviews/qcolumnview.cpp
@@ -801,7 +801,7 @@ void QColumnView::initializeColumn(QAbstractItemView *column) const
}
/*!
- Returns the preview widget, or 0 if there is none.
+ Returns the preview widget, or \nullptr if there is none.
\sa setPreviewWidget(), updatePreviewWidget()
*/
diff --git a/src/widgets/itemviews/qcolumnview_p.h b/src/widgets/itemviews/qcolumnview_p.h
index 9f0d2a40dc..7b36b1f3da 100644
--- a/src/widgets/itemviews/qcolumnview_p.h
+++ b/src/widgets/itemviews/qcolumnview_p.h
@@ -181,6 +181,7 @@ public:
/*!
* This is a delegate that will paint the triangle
*/
+// ### Qt6: QStyledItemDelegate
class QColumnViewDelegate : public QItemDelegate
{
diff --git a/src/widgets/itemviews/qcolumnviewgrip_p.h b/src/widgets/itemviews/qcolumnviewgrip_p.h
index 7e2793074b..5eb8012204 100644
--- a/src/widgets/itemviews/qcolumnviewgrip_p.h
+++ b/src/widgets/itemviews/qcolumnviewgrip_p.h
@@ -82,7 +82,7 @@ protected:
private:
Q_DECLARE_PRIVATE(QColumnViewGrip)
- Q_DISABLE_COPY(QColumnViewGrip)
+ Q_DISABLE_COPY_MOVE(QColumnViewGrip)
};
class QColumnViewGripPrivate : public QWidgetPrivate
diff --git a/src/widgets/itemviews/qdatawidgetmapper.cpp b/src/widgets/itemviews/qdatawidgetmapper.cpp
index 1f0dbff7a9..125ee73194 100644
--- a/src/widgets/itemviews/qdatawidgetmapper.cpp
+++ b/src/widgets/itemviews/qdatawidgetmapper.cpp
@@ -324,6 +324,7 @@ void QDataWidgetMapperPrivate::_q_modelDestroyed()
QDataWidgetMapper::QDataWidgetMapper(QObject *parent)
: QObject(*new QDataWidgetMapperPrivate, parent)
{
+ // ### Qt6: QStyledItemDelegate
setItemDelegate(new QItemDelegate(this));
}
diff --git a/src/widgets/itemviews/qdirmodel.cpp b/src/widgets/itemviews/qdirmodel.cpp
index 78fc623fb5..b94c31fb42 100644
--- a/src/widgets/itemviews/qdirmodel.cpp
+++ b/src/widgets/itemviews/qdirmodel.cpp
@@ -1252,11 +1252,10 @@ void QDirModelPrivate::restorePersistentIndexes()
for (const SavedPersistent &sp : qAsConst(savedPersistent)) {
QPersistentModelIndexData *data = sp.data;
QModelIndex idx = q->index(sp.path, sp.column);
- if (idx != data->index || data->model == 0) {
+ if (idx != data->index || data->index.model() == nullptr) {
//data->model may be equal to 0 if the model is getting destroyed
persistent.indexes.remove(data->index);
data->index = idx;
- data->model = q;
if (idx.isValid())
persistent.indexes.insert(idx, data);
}
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 7bfa51337d..62abf56751 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -2321,9 +2321,10 @@ void QHeaderView::initializeSections()
if (stretchLastSection()) // we've already gotten the size hint
d->maybeRestorePrevLastSectionAndStretchLast();
- //make sure we update the hidden sections
+ // make sure we update the hidden sections
+ // simulate remove from newCount to oldCount
if (newCount < oldCount)
- d->updateHiddenSections(0, newCount-1);
+ d->updateHiddenSections(newCount, oldCount);
}
}
@@ -3116,9 +3117,25 @@ void QHeaderView::scrollContentsBy(int dx, int dy)
\reimp
\internal
*/
-void QHeaderView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &)
+void QHeaderView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
Q_D(QHeaderView);
+ if (!roles.isEmpty()) {
+ const auto doesRoleAffectSize = [](int role) -> bool {
+ switch (role) {
+ case Qt::DisplayRole:
+ case Qt::DecorationRole:
+ case Qt::SizeHintRole:
+ case Qt::FontRole:
+ return true;
+ default:
+ // who knows what a subclass or custom style might do
+ return role >= Qt::UserRole;
+ }
+ };
+ if (std::none_of(roles.begin(), roles.end(), doesRoleAffectSize))
+ return;
+ }
d->invalidateCachedSizeHint();
if (d->hasAutoResizeSections()) {
bool resizeRequired = d->globalResizeMode == ResizeToContents;
@@ -3874,9 +3891,9 @@ void QHeaderViewPrivate::updateDefaultSectionSizeFromStyle()
void QHeaderViewPrivate::recalcSectionStartPos() const // linear (but fast)
{
int pixelpos = 0;
- for (QVector<SectionItem>::const_iterator i = sectionItems.constBegin(); i != sectionItems.constEnd(); ++i) {
- i->calculated_startpos = pixelpos; // write into const mutable
- pixelpos += i->size;
+ for (const SectionItem &i : sectionItems) {
+ i.calculated_startpos = pixelpos; // write into const mutable
+ pixelpos += i.size;
}
sectionStartposRecalc = false;
}
diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp
index dff4cc4593..460764f1b8 100644
--- a/src/widgets/itemviews/qitemdelegate.cpp
+++ b/src/widgets/itemviews/qitemdelegate.cpp
@@ -266,7 +266,7 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
\row \li \l Qt::AccessibleDescriptionRole \li QString
\row \li \l Qt::AccessibleTextRole \li QString
\endomit
- \row \li \l Qt::BackgroundRole \li QBrush
+ \row \li \l Qt::BackgroundRole \li QBrush (\since 4.2)
\row \li \l Qt::BackgroundColorRole \li QColor (obsolete; use Qt::BackgroundRole instead)
\row \li \l Qt::CheckStateRole \li Qt::CheckState
\row \li \l Qt::DecorationRole \li QIcon, QPixmap and QColor
@@ -278,7 +278,7 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
\row \li \l Qt::StatusTipRole \li
\endomit
\row \li \l Qt::TextAlignmentRole \li Qt::Alignment
- \row \li \l Qt::ForegroundRole \li QBrush
+ \row \li \l Qt::ForegroundRole \li QBrush (\since 4.2)
\row \li \l Qt::TextColorRole \li QColor (obsolete; use Qt::ForegroundRole instead)
\omit
\row \li \l Qt::ToolTipRole
@@ -724,8 +724,8 @@ void QItemDelegate::drawDecoration(QPainter *painter, const QStyleOptionViewItem
QPoint p = QStyle::alignedRect(option.direction, option.decorationAlignment,
pixmap.size(), rect).topLeft();
if (option.state & QStyle::State_Selected) {
- QPixmap *pm = selected(pixmap, option.palette, option.state & QStyle::State_Enabled);
- painter->drawPixmap(p, *pm);
+ const QPixmap pm = selectedPixmap(pixmap, option.palette, option.state & QStyle::State_Enabled);
+ painter->drawPixmap(p, pm);
} else {
painter->drawPixmap(p, pixmap);
}
@@ -789,7 +789,7 @@ void QItemDelegate::drawCheck(QPainter *painter,
const QWidget *widget = d->widget(option);
QStyle *style = widget ? widget->style() : QApplication::style();
- style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt, painter, widget);
+ style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &opt, painter, widget);
}
/*!
@@ -1001,17 +1001,32 @@ static QString qPixmapSerial(quint64 i, bool enabled)
return QString((const QChar *)ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr));
}
+#if QT_DEPRECATED_SINCE(5, 13)
+QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const
+{
+ const QString key = qPixmapSerial(pixmap.cacheKey(), enabled);
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ QPixmap *pm = QPixmapCache::find(key);
+ if (pm)
+ return pm;
+ selectedPixmap(pixmap, palette, enabled);
+ return QPixmapCache::find(key);
+QT_WARNING_POP
+}
+#endif
+
/*!
\internal
Returns the selected version of the given \a pixmap using the given \a palette.
The \a enabled argument decides whether the normal or disabled highlight color of
the palette is used.
*/
-QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const
+QPixmap QItemDelegate::selectedPixmap(const QPixmap &pixmap, const QPalette &palette, bool enabled)
{
- QString key = qPixmapSerial(pixmap.cacheKey(), enabled);
- QPixmap *pm = QPixmapCache::find(key);
- if (!pm) {
+ const QString key = qPixmapSerial(pixmap.cacheKey(), enabled);
+ QPixmap pm;
+ if (!QPixmapCache::find(key, &pm)) {
QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
QColor color = palette.color(enabled ? QPalette::Normal : QPalette::Disabled,
@@ -1023,13 +1038,12 @@ QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette,
painter.fillRect(0, 0, img.width(), img.height(), color);
painter.end();
- QPixmap selected = QPixmap(QPixmap::fromImage(img));
- int n = (img.sizeInBytes() >> 10) + 1;
+ pm = QPixmap(QPixmap::fromImage(img));
+ const int n = (img.sizeInBytes() >> 10) + 1;
if (QPixmapCache::cacheLimit() < n)
QPixmapCache::setCacheLimit(n);
- QPixmapCache::insert(key, selected);
- pm = QPixmapCache::find(key);
+ QPixmapCache::insert(key, pm);
}
return pm;
}
@@ -1089,7 +1103,7 @@ QRect QItemDelegate::doCheck(const QStyleOptionViewItem &option,
opt.rect = bounding;
const QWidget *widget = d->widget(option); // cast
QStyle *style = widget ? widget->style() : QApplication::style();
- return style->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, widget);
+ return style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, widget);
}
return QRect();
}
diff --git a/src/widgets/itemviews/qitemdelegate.h b/src/widgets/itemviews/qitemdelegate.h
index 539dec4374..e504615fb2 100644
--- a/src/widgets/itemviews/qitemdelegate.h
+++ b/src/widgets/itemviews/qitemdelegate.h
@@ -113,7 +113,12 @@ protected:
const QStyleOptionViewItem &option) const;
QPixmap decoration(const QStyleOptionViewItem &option, const QVariant &variant) const;
+
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use selectedPixmap() instead")
QPixmap *selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const;
+#endif
+ static QPixmap selectedPixmap(const QPixmap &pixmap, const QPalette &palette, bool enabled);
QRect doCheck(const QStyleOptionViewItem &option, const QRect &bounding,
const QVariant &variant) const;
diff --git a/src/widgets/itemviews/qitemeditorfactory.cpp b/src/widgets/itemviews/qitemeditorfactory.cpp
index 1465ee71a7..2d49dd4421 100644
--- a/src/widgets/itemviews/qitemeditorfactory.cpp
+++ b/src/widgets/itemviews/qitemeditorfactory.cpp
@@ -122,7 +122,7 @@ Q_SIGNALS:
\inmodule QtWidgets
When editing data in an item view, editors are created and
- displayed by a delegate. QItemDelegate, which is the delegate by
+ displayed by a delegate. QStyledItemDelegate, which is the delegate by
default installed on Qt's item views, uses a QItemEditorFactory to
create editors for it. A default unique instance provided by
QItemEditorFactory is used by all item delegates. If you set a
@@ -156,7 +156,7 @@ Q_SIGNALS:
Additional editors can be registered with the registerEditor() function.
- \sa QItemDelegate, {Model/View Programming}, {Color Editor Factory Example}
+ \sa QStyledItemDelegate, {Model/View Programming}, {Color Editor Factory Example}
*/
/*!
@@ -379,7 +379,7 @@ void QItemEditorFactory::setDefaultFactory(QItemEditorFactory *factory)
QItemEditorCreatorBase objects are specialized widget factories that
provide editor widgets for one particular QVariant data type. They
are used by QItemEditorFactory to create editors for
- \l{QItemDelegate}s. Creator bases must be registered with
+ \l{QStyledItemDelegate}s. Creator bases must be registered with
QItemEditorFactory::registerEditor().
An editor should provide a user property for the data it edits.
@@ -461,7 +461,7 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase()
\snippet code/src_gui_itemviews_qitemeditorfactory.cpp 1
The constructor takes the name of the property that contains the
- editing data. QItemDelegate can then access the property by name
+ editing data. QStyledItemDelegate can then access the property by name
when it sets and retrieves editing data. Only use this class if
your editor does not define a user property (using the USER
keyword in the Q_PROPERTY macro). If the widget has a user
@@ -476,7 +476,7 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase()
Constructs an editor creator object using \a valuePropertyName
as the name of the property to be used for editing. The
- property name is used by QItemDelegate when setting and
+ property name is used by QStyledItemDelegate when setting and
getting editor data.
Note that the \a valuePropertyName is only used if the editor
@@ -512,11 +512,11 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase()
\snippet code/src_gui_itemviews_qitemeditorfactory.cpp 2
Setting the \c editorFactory created above in an item delegate via
- QItemDelegate::setItemEditorFactory() makes sure that all values of type
+ QStyledItemDelegate::setItemEditorFactory() makes sure that all values of type
QVariant::DateTime will be edited in \c{MyFancyDateTimeEdit}.
The editor must provide a user property that will contain the
- editing data. The property is used by \l{QItemDelegate}s to set
+ editing data. The property is used by \l{QStyledItemDelegate}s to set
and retrieve the data (using Qt's \l{Meta-Object
System}{meta-object system}). You set the user property with
the USER keyword:
@@ -524,7 +524,7 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase()
\snippet code/src_gui_itemviews_qitemeditorfactory.cpp 3
\sa QItemEditorCreatorBase, QItemEditorCreator,
- QItemEditorFactory, QItemDelegate, {Color Editor Factory Example}
+ QItemEditorFactory, QStyledItemDelegate, {Color Editor Factory Example}
*/
/*!
diff --git a/src/widgets/itemviews/qitemeditorfactory.h b/src/widgets/itemviews/qitemeditorfactory.h
index f2610ad3de..118f6e45e8 100644
--- a/src/widgets/itemviews/qitemeditorfactory.h
+++ b/src/widgets/itemviews/qitemeditorfactory.h
@@ -66,8 +66,8 @@ class QItemEditorCreator : public QItemEditorCreatorBase
{
public:
inline explicit QItemEditorCreator(const QByteArray &valuePropertyName);
- inline QWidget *createWidget(QWidget *parent) const { return new T(parent); }
- inline QByteArray valuePropertyName() const { return propertyName; }
+ inline QWidget *createWidget(QWidget *parent) const override { return new T(parent); }
+ inline QByteArray valuePropertyName() const override { return propertyName; }
private:
QByteArray propertyName;
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index e07514f297..641b15f85b 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -2263,8 +2263,8 @@ int QListModeViewBase::verticalScrollToValue(int index, QListView::ScrollHint hi
} else {
int scrollBarValue = verticalScrollBar()->value();
int numHidden = 0;
- for (int i = 0; i < flowPositions.count() - 1 && i <= scrollBarValue; ++i)
- if (isHidden(i))
+ for (const auto &idx : qAsConst(dd->hiddenRows))
+ if (idx.row() <= scrollBarValue)
++numHidden;
value = qBound(0, scrollValueMap.at(verticalScrollBar()->value()) - numHidden, flowPositions.count() - 1);
}
@@ -2704,21 +2704,24 @@ int QListModeViewBase::perItemScrollToValue(int index, int scrollValue, int view
return scrollValue;
itemExtent += spacing();
- QVector<int> visibleFlowPositions;
- visibleFlowPositions.reserve(flowPositions.count() - 1);
- for (int i = 0; i < flowPositions.count() - 1; i++) { // flowPositions count is +1 larger than actual row count
- if (!isHidden(i))
- visibleFlowPositions.append(flowPositions.at(i));
- }
-
+ QVector<int> hiddenRows = dd->hiddenRowIds();
+ std::sort(hiddenRows.begin(), hiddenRows.end());
+ int hiddenRowsBefore = 0;
+ for (int i = 0; i < hiddenRows.size() - 1; ++i)
+ if (hiddenRows.at(i) > index + hiddenRowsBefore)
+ break;
+ else
+ ++hiddenRowsBefore;
if (!wrap) {
int topIndex = index;
const int bottomIndex = topIndex;
- const int bottomCoordinate = visibleFlowPositions.at(index);
-
+ const int bottomCoordinate = flowPositions.at(index + hiddenRowsBefore);
while (topIndex > 0 &&
- (bottomCoordinate - visibleFlowPositions.at(topIndex - 1) + itemExtent) <= (viewportSize)) {
+ (bottomCoordinate - flowPositions.at(topIndex + hiddenRowsBefore - 1) + itemExtent) <= (viewportSize)) {
topIndex--;
+ // will the next one be a hidden row -> skip
+ while (hiddenRowsBefore > 0 && hiddenRows.at(hiddenRowsBefore - 1) >= topIndex + hiddenRowsBefore - 1)
+ hiddenRowsBefore--;
}
const int itemCount = bottomIndex - topIndex + 1;
@@ -2737,7 +2740,7 @@ int QListModeViewBase::perItemScrollToValue(int index, int scrollValue, int view
? Qt::Horizontal : Qt::Vertical);
if (flowOrientation == orientation) { // scrolling in the "flow" direction
// ### wrapped scrolling in the flow direction
- return visibleFlowPositions.at(index); // ### always pixel based for now
+ return flowPositions.at(index + hiddenRowsBefore); // ### always pixel based for now
} else if (!segmentStartRows.isEmpty()) { // we are scrolling in the "segment" direction
int segment = qBinarySearch<int>(segmentStartRows, index, 0, segmentStartRows.count() - 1);
int leftSegment = segment;
@@ -3371,9 +3374,9 @@ int QListView::visualIndex(const QModelIndex &index) const
d->executePostedLayout();
QListViewItem itm = d->indexToListViewItem(index);
int visualIndex = d->commonListView->itemIndex(itm);
- for (int row = 0; row <= index.row() && visualIndex >= 0; row++) {
- if (d->isHidden(row))
- visualIndex--;
+ for (const auto &idx : qAsConst(d->hiddenRows)) {
+ if (idx.row() <= index.row())
+ --visualIndex;
}
return visualIndex;
}
diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h
index c94357afe9..c6810f8fdc 100644
--- a/src/widgets/itemviews/qlistview_p.h
+++ b/src/widgets/itemviews/qlistview_p.h
@@ -394,6 +394,14 @@ public:
QModelIndex idx = model->index(row, 0, root);
return isPersistent(idx) && hiddenRows.contains(idx);
}
+ // helper to avoid checking for isPersistent and creating persistent indexes as above in isHidden
+ QVector<int> hiddenRowIds() const {
+ QVector<int> rowIds;
+ rowIds.reserve(hiddenRows.size());
+ for (const auto &idx : hiddenRows)
+ rowIds += idx.row();
+ return rowIds;
+ }
inline bool isHiddenOrDisabled(int row) const { return isHidden(row) || !isIndexEnabled(modelIndex(row)); }
void removeCurrentAndDisabled(QVector<QModelIndex> *indexes, const QModelIndex &current) const;
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index b9c0e0a4b7..a9899983c2 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -227,6 +227,22 @@ bool QListModel::setData(const QModelIndex &index, const QVariant &value, int ro
return true;
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+bool QListModel::clearItemData(const QModelIndex &index)
+{
+ if (!checkIndex(index, CheckIndexOption::IndexIsValid))
+ return false;
+ QListWidgetItem *item = items.at(index.row());
+ const auto beginIter = item->d->values.cbegin();
+ const auto endIter = item->d->values.cend();
+ if (std::all_of(beginIter, endIter, [](const QWidgetItemData& data) -> bool { return !data.value.isValid(); }))
+ return true; //it's already cleared
+ item->d->values.clear();
+ emit dataChanged(index, index, QVector<int>{});
+ return true;
+}
+#endif
+
QMap<int, QVariant> QListModel::itemData(const QModelIndex &index) const
{
QMap<int, QVariant> roles;
@@ -277,6 +293,30 @@ bool QListModel::removeRows(int row, int count, const QModelIndex &parent)
return true;
}
+/*!
+ \since 5.13
+ \reimp
+*/
+bool QListModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
+{
+ if (sourceRow < 0
+ || sourceRow + count - 1 >= rowCount(sourceParent)
+ || destinationChild <= 0
+ || destinationChild > rowCount(destinationParent)
+ || sourceRow == destinationChild - 1
+ || count <= 0) {
+ return false;
+ }
+ if (!beginMoveRows(QModelIndex(), sourceRow, sourceRow + count - 1, QModelIndex(), destinationChild))
+ return false;
+ destinationChild--;
+ const int fromRow = destinationChild < sourceRow ? (sourceRow + count - 1) : sourceRow;
+ while (count--)
+ items.move(fromRow, destinationChild);
+ endMoveRows();
+ return true;
+}
+
Qt::ItemFlags QListModel::flags(const QModelIndex &index) const
{
if (!index.isValid() || index.row() >= items.count() || index.model() != this)
@@ -289,7 +329,7 @@ void QListModel::sort(int column, Qt::SortOrder order)
if (column != 0)
return;
- emit layoutAboutToBeChanged();
+ emit layoutAboutToBeChanged({}, QAbstractItemModel::VerticalSortHint);
QVector < QPair<QListWidgetItem*,int> > sorting(items.count());
for (int i = 0; i < items.count(); ++i) {
@@ -313,7 +353,7 @@ void QListModel::sort(int column, Qt::SortOrder order)
}
changePersistentIndexList(fromIndexes, toIndexes);
- emit layoutChanged();
+ emit layoutChanged({}, QAbstractItemModel::VerticalSortHint);
}
/**
@@ -543,24 +583,6 @@ Qt::DropActions QListModel::supportedDropActions() const
*/
/*!
- \fn void QListWidgetItem::setSelected(bool select)
- \since 4.2
-
- Sets the selected state of the item to \a select.
-
- \sa isSelected()
-*/
-
-/*!
- \fn bool QListWidgetItem::isSelected() const
- \since 4.2
-
- Returns \c true if the item is selected; otherwise returns \c false.
-
- \sa setSelected()
-*/
-
-/*!
\fn void QListWidgetItem::setHidden(bool hide)
\since 4.2
@@ -594,14 +616,14 @@ Qt::DropActions QListModel::supportedDropActions() const
\sa type()
*/
-QListWidgetItem::QListWidgetItem(QListWidget *view, int type)
- : rtti(type), view(view), d(new QListWidgetItemPrivate(this)),
+QListWidgetItem::QListWidgetItem(QListWidget *listview, int type)
+ : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)),
itemFlags(Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled
|Qt::ItemIsDragEnabled)
{
- if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
+ if (QListModel *model = listModel())
model->insert(model->rowCount(), this);
}
@@ -621,16 +643,18 @@ QListWidgetItem::QListWidgetItem(QListWidget *view, int type)
\sa type()
*/
-QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *view, int type)
- : rtti(type), view(0), d(new QListWidgetItemPrivate(this)),
+QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *listview, int type)
+ : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)),
itemFlags(Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled
|Qt::ItemIsDragEnabled)
{
- setData(Qt::DisplayRole, text);
- this->view = view;
- if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
+ {
+ QSignalBlocker b(view);
+ setData(Qt::DisplayRole, text);
+ }
+ if (QListModel *model = listModel())
model->insert(model->rowCount(), this);
}
@@ -652,17 +676,19 @@ QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *view, int typ
\sa type()
*/
QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text,
- QListWidget *view, int type)
- : rtti(type), view(0), d(new QListWidgetItemPrivate(this)),
+ QListWidget *listview, int type)
+ : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)),
itemFlags(Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled
|Qt::ItemIsDragEnabled)
{
- setData(Qt::DisplayRole, text);
- setData(Qt::DecorationRole, icon);
- this->view = view;
- if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
+ {
+ QSignalBlocker b(view);
+ setData(Qt::DisplayRole, text);
+ setData(Qt::DecorationRole, icon);
+ }
+ if (QListModel *model = listModel())
model->insert(model->rowCount(), this);
}
@@ -671,7 +697,7 @@ QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text,
*/
QListWidgetItem::~QListWidgetItem()
{
- if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
+ if (QListModel *model = listModel())
model->remove(this);
delete d;
}
@@ -708,7 +734,7 @@ void QListWidgetItem::setData(int role, const QVariant &value)
}
if (!found)
d->values.append(QWidgetItemData(role, value));
- if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : nullptr)) {
+ if (QListModel *model = listModel()) {
const QVector<int> roles((role == Qt::DisplayRole) ?
QVector<int>({Qt::DisplayRole, Qt::EditRole}) :
QVector<int>({role}));
@@ -775,7 +801,7 @@ void QListWidgetItem::write(QDataStream &out) const
\sa data(), flags()
*/
QListWidgetItem::QListWidgetItem(const QListWidgetItem &other)
- : rtti(Type), view(0),
+ : rtti(Type), view(nullptr),
d(new QListWidgetItemPrivate(this)),
itemFlags(other.itemFlags)
{
@@ -797,6 +823,15 @@ QListWidgetItem &QListWidgetItem::operator=(const QListWidgetItem &other)
return *this;
}
+/*!
+ \internal
+ returns the QListModel if a view is set
+ */
+QListModel *QListWidgetItem::listModel() const
+{
+ return (view ? qobject_cast<QListModel*>(view->model()) : nullptr);
+}
+
#ifndef QT_NO_DATASTREAM
/*!
@@ -949,6 +984,50 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item)
*/
/*!
+ \fn void QListWidgetItem::setSelected(bool select)
+ \since 4.2
+
+ Sets the selected state of the item to \a select.
+
+ \sa isSelected()
+*/
+void QListWidgetItem::setSelected(bool select)
+{
+ const QListModel *model = listModel();
+ if (!model || !view->selectionModel())
+ return;
+ const QAbstractItemView::SelectionMode selectionMode = view->selectionMode();
+ if (selectionMode == QAbstractItemView::NoSelection)
+ return;
+ const QModelIndex index = model->index(this);
+ if (selectionMode == QAbstractItemView::SingleSelection)
+ view->selectionModel()->select(index, select
+ ? QItemSelectionModel::ClearAndSelect
+ : QItemSelectionModel::Deselect);
+ else
+ view->selectionModel()->select(index, select
+ ? QItemSelectionModel::Select
+ : QItemSelectionModel::Deselect);
+}
+
+/*!
+ \fn bool QListWidgetItem::isSelected() const
+ \since 4.2
+
+ Returns \c true if the item is selected; otherwise returns \c false.
+
+ \sa setSelected()
+*/
+bool QListWidgetItem::isSelected() const
+{
+ const QListModel *model = listModel();
+ if (!model || !view->selectionModel())
+ return false;
+ const QModelIndex index = model->index(this);
+ return view->selectionModel()->isSelected(index);
+}
+
+/*!
\fn void QListWidgetItem::setFlags(Qt::ItemFlags flags)
Sets the item flags for the list item to \a flags.
@@ -958,7 +1037,7 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item)
void QListWidgetItem::setFlags(Qt::ItemFlags aflags)
{
itemFlags = aflags;
- if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0))
+ if (QListModel *model = listModel())
model->itemChanged(this);
}
@@ -1678,7 +1757,7 @@ QWidget *QListWidget::itemWidget(QListWidgetItem *item) const
This function should only be used to display static content in the place of
a list widget item. If you want to display custom dynamic content or
- implement a custom editor widget, use QListView and subclass QItemDelegate
+ implement a custom editor widget, use QListView and subclass QStyledItemDelegate
instead.
\sa itemWidget(), removeItemWidget(), {Delegate Classes}
@@ -1690,6 +1769,7 @@ void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget)
QAbstractItemView::setIndexWidget(index, widget);
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Returns \c true if \a item is selected; otherwise returns \c false.
@@ -1699,9 +1779,7 @@ void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget)
*/
bool QListWidget::isItemSelected(const QListWidgetItem *item) const
{
- Q_D(const QListWidget);
- QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
- return selectionModel()->isSelected(index);
+ return ((item && item->listWidget() == this) ? item->isSelected() : false);
}
/*!
@@ -1714,20 +1792,10 @@ bool QListWidget::isItemSelected(const QListWidgetItem *item) const
*/
void QListWidget::setItemSelected(const QListWidgetItem *item, bool select)
{
- Q_D(QListWidget);
- QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
-
- if (d->selectionMode == SingleSelection) {
- selectionModel()->select(index, select
- ? QItemSelectionModel::ClearAndSelect
- : QItemSelectionModel::Deselect);
- } else if (d->selectionMode != NoSelection) {
- selectionModel()->select(index, select
- ? QItemSelectionModel::Select
- : QItemSelectionModel::Deselect);
- }
-
+ if (item && item->listWidget() == this)
+ const_cast<QListWidgetItem*>(item)->setSelected(select);
}
+#endif
/*!
Returns a list of all selected items in the list widget.
@@ -1763,6 +1831,7 @@ QList<QListWidgetItem*> QListWidget::findItems(const QString &text, Qt::MatchFla
return items;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Returns \c true if the \a item is explicitly hidden; otherwise returns \c false.
@@ -1786,6 +1855,7 @@ void QListWidget::setItemHidden(const QListWidgetItem *item, bool hide)
{
setRowHidden(row(item), hide);
}
+#endif
/*!
Scrolls the view if necessary to ensure that the \a item is visible.
diff --git a/src/widgets/itemviews/qlistwidget.h b/src/widgets/itemviews/qlistwidget.h
index 947fdb1a2f..c102b144df 100644
--- a/src/widgets/itemviews/qlistwidget.h
+++ b/src/widgets/itemviews/qlistwidget.h
@@ -61,10 +61,10 @@ class Q_WIDGETS_EXPORT QListWidgetItem
friend class QListWidget;
public:
enum ItemType { Type = 0, UserType = 1000 };
- explicit QListWidgetItem(QListWidget *view = nullptr, int type = Type);
- explicit QListWidgetItem(const QString &text, QListWidget *view = nullptr, int type = Type);
+ explicit QListWidgetItem(QListWidget *listview = nullptr, int type = Type);
+ explicit QListWidgetItem(const QString &text, QListWidget *listview = nullptr, int type = Type);
explicit QListWidgetItem(const QIcon &icon, const QString &text,
- QListWidget *view = nullptr, int type = Type);
+ QListWidget *listview = nullptr, int type = Type);
QListWidgetItem(const QListWidgetItem &other);
virtual ~QListWidgetItem();
@@ -72,8 +72,8 @@ public:
inline QListWidget *listWidget() const { return view; }
- inline void setSelected(bool select);
- inline bool isSelected() const;
+ void setSelected(bool select);
+ bool isSelected() const;
inline void setHidden(bool hide);
inline bool isHidden() const;
@@ -114,20 +114,29 @@ public:
inline void setTextAlignment(int alignment)
{ setData(Qt::TextAlignmentRole, alignment); }
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QListWidgetItem::background() instead")
inline QColor backgroundColor() const
- { return qvariant_cast<QColor>(data(Qt::BackgroundColorRole)); }
+ { return qvariant_cast<QColor>(data(Qt::BackgroundRole)); }
+#endif
+ // no QT_DEPRECATED_SINCE because it is a virtual function
+ QT_DEPRECATED_X ("Use QListWidgetItem::setBackground() instead")
virtual void setBackgroundColor(const QColor &color)
- { setData(Qt::BackgroundColorRole, color); }
+ { setData(Qt::BackgroundRole, color); }
inline QBrush background() const
{ return qvariant_cast<QBrush>(data(Qt::BackgroundRole)); }
inline void setBackground(const QBrush &brush)
{ setData(Qt::BackgroundRole, brush); }
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QListWidgetItem::foreground() instead")
inline QColor textColor() const
- { return qvariant_cast<QColor>(data(Qt::TextColorRole)); }
+ { return qvariant_cast<QColor>(data(Qt::ForegroundRole)); }
+ QT_DEPRECATED_X ("Use QListWidgetItem::setForeground() instead")
inline void setTextColor(const QColor &color)
- { setData(Qt::TextColorRole, color); }
+ { setData(Qt::ForegroundRole, color); }
+#endif
inline QBrush foreground() const
{ return qvariant_cast<QBrush>(data(Qt::ForegroundRole)); }
@@ -158,6 +167,7 @@ public:
inline int type() const { return rtti; }
private:
+ QListModel *listModel() const;
int rtti;
QVector<void *> dummy;
QListWidget *view;
@@ -246,13 +256,21 @@ public:
void setItemWidget(QListWidgetItem *item, QWidget *widget);
inline void removeItemWidget(QListWidgetItem *item);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QListWidgetItem::isSelected() instead")
bool isItemSelected(const QListWidgetItem *item) const;
+ QT_DEPRECATED_X ("Use QListWidgetItem::setSelected() instead")
void setItemSelected(const QListWidgetItem *item, bool select);
+#endif
QList<QListWidgetItem*> selectedItems() const;
QList<QListWidgetItem*> findItems(const QString &text, Qt::MatchFlags flags) const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QListWidgetItem::isHidden() instead")
bool isItemHidden(const QListWidgetItem *item) const;
+ QT_DEPRECATED_X ("Use QListWidgetItem::setHidden() instead")
void setItemHidden(const QListWidgetItem *item, bool hide);
+#endif
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
protected:
#endif
@@ -331,17 +349,11 @@ inline void QListWidget::addItem(QListWidgetItem *aitem)
inline QListWidgetItem *QListWidget::itemAt(int ax, int ay) const
{ return itemAt(QPoint(ax, ay)); }
-inline void QListWidgetItem::setSelected(bool aselect)
-{ if (view) view->setItemSelected(this, aselect); }
-
-inline bool QListWidgetItem::isSelected() const
-{ return (view ? view->isItemSelected(this) : false); }
-
inline void QListWidgetItem::setHidden(bool ahide)
-{ if (view) view->setItemHidden(this, ahide); }
+{ if (view) view->setRowHidden(view->row(this), ahide); }
inline bool QListWidgetItem::isHidden() const
-{ return (view ? view->isItemHidden(this) : false); }
+{ return (view ? view->isRowHidden(view->row(this)) : false); }
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qlistwidget_p.h b/src/widgets/itemviews/qlistwidget_p.h
index 9cb3d5966b..65a7124322 100644
--- a/src/widgets/itemviews/qlistwidget_p.h
+++ b/src/widgets/itemviews/qlistwidget_p.h
@@ -100,11 +100,15 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ bool clearItemData(const QModelIndex &index) override;
+#endif
QMap<int, QVariant> itemData(const QModelIndex &index) const override;
bool insertRows(int row, int count = 1, const QModelIndex &parent = QModelIndex()) override;
bool removeRows(int row, int count = 1, const QModelIndex &parent = QModelIndex()) override;
+ bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
diff --git a/src/widgets/itemviews/qstyleditemdelegate.cpp b/src/widgets/itemviews/qstyleditemdelegate.cpp
index 0f7566e8ec..22067851cb 100644
--- a/src/widgets/itemviews/qstyleditemdelegate.cpp
+++ b/src/widgets/itemviews/qstyleditemdelegate.cpp
@@ -139,7 +139,7 @@ public:
\row \li \l Qt::AccessibleDescriptionRole \li QString
\row \li \l Qt::AccessibleTextRole \li QString
\endomit
- \row \li \l Qt::BackgroundRole \li QBrush
+ \row \li \l Qt::BackgroundRole \li QBrush (\since 4.2)
\row \li \l Qt::BackgroundColorRole \li QColor (obsolete; use Qt::BackgroundRole instead)
\row \li \l Qt::CheckStateRole \li Qt::CheckState
\row \li \l Qt::DecorationRole \li QIcon, QPixmap, QImage and QColor
@@ -151,7 +151,7 @@ public:
\row \li \l Qt::StatusTipRole \li
\endomit
\row \li \l Qt::TextAlignmentRole \li Qt::Alignment
- \row \li \l Qt::ForegroundRole \li QBrush
+ \row \li \l Qt::ForegroundRole \li QBrush (\since 4.2)
\row \li \l Qt::TextColorRole \li QColor (obsolete; use Qt::ForegroundRole instead)
\omit
\row \li \l Qt::ToolTipRole
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index 9c509583e6..dd43c6d3e4 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -138,20 +138,21 @@ void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height)
}
/** \internal
- * \return a spans that spans over cell x,y (column,row) or 0 if there is none.
+ * \return a spans that spans over cell x,y (column,row)
+ * or \nullptr if there is none.
*/
QSpanCollection::Span *QSpanCollection::spanAt(int x, int y) const
{
Index::const_iterator it_y = index.lowerBound(-y);
if (it_y == index.end())
- return 0;
+ return nullptr;
SubIndex::const_iterator it_x = (*it_y).lowerBound(-x);
if (it_x == (*it_y).end())
- return 0;
+ return nullptr;
Span *span = *it_x;
if (span->right() >= x && span->bottom() >= y)
return span;
- return 0;
+ return nullptr;
}
@@ -964,6 +965,15 @@ void QTableViewPrivate::_q_updateSpanRemovedColumns(const QModelIndex &parent, i
/*!
\internal
+ Sort the model when the header sort indicator changed
+*/
+void QTableViewPrivate::_q_sortIndicatorChanged(int column, Qt::SortOrder order)
+{
+ model->sort(column, order);
+}
+
+/*!
+ \internal
Draws a table cell.
*/
void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)
@@ -1099,7 +1109,7 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS
\l showGrid property.
The items shown in a table view, like those in the other item views, are
- rendered and edited using standard \l{QItemDelegate}{delegates}. However,
+ rendered and edited using standard \l{QStyledItemDelegate}{delegates}. However,
for some tasks it is sometimes useful to be able to insert widgets in a
table instead. Widgets are set for particular indexes with the
\l{QAbstractItemView::}{setIndexWidget()} function, and
@@ -1171,8 +1181,6 @@ 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;
}
@@ -1443,12 +1451,12 @@ void QTableView::paintEvent(QPaintEvent *event)
//firstVisualRow is the visual index of the first visible row. lastVisualRow is the visual index of the last visible Row.
//same goes for ...VisualColumn
int firstVisualRow = qMax(verticalHeader->visualIndexAt(0),0);
- int lastVisualRow = verticalHeader->visualIndexAt(verticalHeader->viewport()->height());
+ int lastVisualRow = verticalHeader->visualIndexAt(verticalHeader->height());
if (lastVisualRow == -1)
lastVisualRow = d->model->rowCount(d->root) - 1;
int firstVisualColumn = horizontalHeader->visualIndexAt(0);
- int lastVisualColumn = horizontalHeader->visualIndexAt(horizontalHeader->viewport()->width());
+ int lastVisualColumn = horizontalHeader->visualIndexAt(horizontalHeader->width());
if (rightToLeft)
qSwap(firstVisualColumn, lastVisualColumn);
if (firstVisualColumn == -1)
@@ -2634,25 +2642,27 @@ void QTableView::setColumnHidden(int column, bool hide)
void QTableView::setSortingEnabled(bool enable)
{
Q_D(QTableView);
- d->sortingEnabled = enable;
horizontalHeader()->setSortIndicatorShown(enable);
if (enable) {
disconnect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
this, SLOT(_q_selectColumn(int)));
disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)),
this, SLOT(selectColumn(int)));
- connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
- this, SLOT(sortByColumn(int)), Qt::UniqueConnection);
+ //sortByColumn has to be called before we connect or set the sortingEnabled flag
+ // because otherwise it will not call sort on the model.
sortByColumn(horizontalHeader()->sortIndicatorSection(),
horizontalHeader()->sortIndicatorOrder());
+ connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
+ this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection);
} else {
connect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection);
connect(horizontalHeader(), SIGNAL(sectionPressed(int)),
this, SLOT(selectColumn(int)), Qt::UniqueConnection);
disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
- this, SLOT(sortByColumn(int)));
+ this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));
}
+ d->sortingEnabled = enable;
}
bool QTableView::isSortingEnabled() const
@@ -3181,19 +3191,21 @@ void QTableView::resizeColumnsToContents()
d->horizontalHeader->resizeSections(QHeaderView::ResizeToContents);
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
\overload
+ This function is deprecated. Use
+ sortByColumn(int column, Qt::SortOrder order) instead.
Sorts the model by the values in the given \a column.
*/
void QTableView::sortByColumn(int column)
{
Q_D(QTableView);
- if (column == -1)
- return;
- d->model->sort(column, d->horizontalHeader->sortIndicatorOrder());
+ sortByColumn(column, d->horizontalHeader->sortIndicatorOrder());
}
+#endif
/*!
\since 4.2
@@ -3205,8 +3217,14 @@ void QTableView::sortByColumn(int column)
void QTableView::sortByColumn(int column, Qt::SortOrder order)
{
Q_D(QTableView);
+ if (column < 0)
+ return;
+ // If sorting is enabled it will emit a signal connected to
+ // _q_sortIndicatorChanged, which then actually sorts
d->horizontalHeader->setSortIndicator(column, order);
- sortByColumn(column);
+ // If sorting is not enabled, force to sort now
+ if (!d->sortingEnabled)
+ d->model->sort(column, order);
}
/*!
diff --git a/src/widgets/itemviews/qtableview.h b/src/widgets/itemviews/qtableview.h
index 60c2f34103..3275c09f88 100644
--- a/src/widgets/itemviews/qtableview.h
+++ b/src/widgets/itemviews/qtableview.h
@@ -118,7 +118,6 @@ public:
int columnSpan(int row, int column) const;
void clearSpans();
- void sortByColumn(int column, Qt::SortOrder order);
public Q_SLOTS:
void selectRow(int row);
@@ -131,7 +130,11 @@ public Q_SLOTS:
void resizeRowsToContents();
void resizeColumnToContents(int column);
void resizeColumnsToContents();
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QTableView::sortByColumn(int column, Qt::SortOrder order) instead")
void sortByColumn(int column);
+#endif
+ void sortByColumn(int column, Qt::SortOrder order);
void setShowGrid(bool show);
protected Q_SLOTS:
@@ -188,6 +191,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedColumns(QModelIndex,int,int))
Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedRows(QModelIndex,int,int))
Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedColumns(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order))
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h
index a50e6b6410..d55462c28b 100644
--- a/src/widgets/itemviews/qtableview_p.h
+++ b/src/widgets/itemviews/qtableview_p.h
@@ -257,6 +257,7 @@ public:
void _q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end);
void _q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end);
void _q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end);
+ void _q_sortIndicatorChanged(int column, Qt::SortOrder order);
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index d576d323c3..ec4897a7ae 100644
--- a/src/widgets/itemviews/qtablewidget.cpp
+++ b/src/widgets/itemviews/qtablewidget.cpp
@@ -189,7 +189,7 @@ void QTableModel::setItem(int row, int column, QTableWidgetItem *item)
sortedRow = qMax((int)(it - colItems.begin()), 0);
}
if (sortedRow != row) {
- emit layoutAboutToBeChanged();
+ emit layoutAboutToBeChanged({}, QAbstractItemModel::VerticalSortHint);
// move the items @ row to sortedRow
int cc = columnCount();
QVector<QTableWidgetItem*> rowItems(cc);
@@ -209,7 +209,7 @@ void QTableModel::setItem(int row, int column, QTableWidgetItem *item)
changePersistentIndexList(oldPersistentIndexes,
newPersistentIndexes);
- emit layoutChanged();
+ emit layoutChanged({}, QAbstractItemModel::VerticalSortHint);
return;
}
}
@@ -480,6 +480,24 @@ bool QTableModel::setItemData(const QModelIndex &index, const QMap<int, QVariant
return true;
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+bool QTableModel::clearItemData(const QModelIndex &index)
+{
+ if (!checkIndex(index, CheckIndexOption::IndexIsValid))
+ return false;
+ QTableWidgetItem *itm = item(index);
+ if (!itm)
+ return false;
+ const auto beginIter = itm->values.cbegin();
+ const auto endIter = itm->values.cend();
+ if (std::all_of(beginIter, endIter, [](const QWidgetItemData& data) -> bool { return !data.value.isValid(); }))
+ return true; //it's already cleared
+ itm->values.clear();
+ emit dataChanged(index, index, QVector<int>{});
+ return true;
+}
+#endif
+
Qt::ItemFlags QTableModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
@@ -530,12 +548,12 @@ void QTableModel::sort(int column, Qt::SortOrder order)
}
}
- emit layoutAboutToBeChanged();
+ emit layoutAboutToBeChanged({}, QAbstractItemModel::VerticalSortHint);
tableItems = sorted_table;
changePersistentIndexList(from, to); // ### slow
- emit layoutChanged();
+ emit layoutChanged({}, QAbstractItemModel::VerticalSortHint);
}
/*
@@ -580,7 +598,7 @@ void QTableModel::ensureSorted(int column, Qt::SortOrder order,
vit = colItems.insert(vit, item);
if (newRow != oldRow) {
if (!changed) {
- emit layoutAboutToBeChanged();
+ emit layoutAboutToBeChanged({}, QAbstractItemModel::VerticalSortHint);
oldPersistentIndexes = persistentIndexList();
newPersistentIndexes = oldPersistentIndexes;
changed = true;
@@ -615,7 +633,7 @@ void QTableModel::ensureSorted(int column, Qt::SortOrder order,
verticalHeaderItems = newVertical;
changePersistentIndexList(oldPersistentIndexes,
newPersistentIndexes);
- emit layoutChanged();
+ emit layoutChanged({}, QAbstractItemModel::VerticalSortHint);
}
}
@@ -1037,24 +1055,6 @@ QTableWidgetSelectionRange::~QTableWidgetSelectionRange()
*/
/*!
- \fn void QTableWidgetItem::setSelected(bool select)
- \since 4.2
-
- Sets the selected state of the item to \a select.
-
- \sa isSelected()
-*/
-
-/*!
- \fn bool QTableWidgetItem::isSelected() const
- \since 4.2
-
- Returns \c true if the item is selected, otherwise returns \c false.
-
- \sa setSelected()
-*/
-
-/*!
\fn QSize QTableWidgetItem::sizeHint() const
\since 4.1
@@ -1091,6 +1091,44 @@ QTableWidgetSelectionRange::~QTableWidgetSelectionRange()
*/
/*!
+ \fn bool QTableWidgetItem::isSelected() const
+ \since 4.2
+
+ Returns \c true if the item is selected, otherwise returns \c false.
+
+ \sa setSelected()
+*/
+bool QTableWidgetItem::isSelected() const
+{
+ if (!view || !view->selectionModel())
+ return false;
+ const QTableModel *model = qobject_cast<const QTableModel*>(view->model());
+ if (!model)
+ return false;
+ const QModelIndex index = model->index(this);
+ return view->selectionModel()->isSelected(index);
+}
+
+/*!
+ \fn void QTableWidgetItem::setSelected(bool select)
+ \since 4.2
+
+ Sets the selected state of the item to \a select.
+
+ \sa isSelected()
+*/
+void QTableWidgetItem::setSelected(bool select)
+{
+ if (!view || !view->selectionModel())
+ return;
+ const QTableModel *model = qobject_cast<const QTableModel*>(view->model());
+ if (!model)
+ return;
+ const QModelIndex index = model->index(this);
+ view->selectionModel()->select(index, select ? QItemSelectionModel::Select : QItemSelectionModel::Deselect);
+}
+
+/*!
\fn Qt::ItemFlags QTableWidgetItem::flags() const
Returns the flags used to describe the item. These determine whether
@@ -1110,7 +1148,7 @@ QTableWidgetSelectionRange::~QTableWidgetSelectionRange()
void QTableWidgetItem::setFlags(Qt::ItemFlags aflags)
{
itemFlags = aflags;
- if (QTableModel *model = (view ? qobject_cast<QTableModel*>(view->model()) : 0))
+ if (QTableModel *model = tableModel())
model->itemChanged(this);
}
@@ -1301,7 +1339,7 @@ void QTableWidgetItem::setFlags(Qt::ItemFlags aflags)
\sa type()
*/
QTableWidgetItem::QTableWidgetItem(int type)
- : rtti(type), view(0), d(new QTableWidgetItemPrivate(this)),
+ : rtti(type), view(nullptr), d(new QTableWidgetItemPrivate(this)),
itemFlags(Qt::ItemIsEditable
|Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
@@ -1317,7 +1355,7 @@ QTableWidgetItem::QTableWidgetItem(int type)
\sa type()
*/
QTableWidgetItem::QTableWidgetItem(const QString &text, int type)
- : rtti(type), view(0), d(new QTableWidgetItemPrivate(this)),
+ : rtti(type), view(nullptr), d(new QTableWidgetItemPrivate(this)),
itemFlags(Qt::ItemIsEditable
|Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
@@ -1334,7 +1372,7 @@ QTableWidgetItem::QTableWidgetItem(const QString &text, int type)
\sa type()
*/
QTableWidgetItem::QTableWidgetItem(const QIcon &icon, const QString &text, int type)
- : rtti(type), view(0), d(new QTableWidgetItemPrivate(this)),
+ : rtti(type), view(nullptr), d(new QTableWidgetItemPrivate(this)),
itemFlags(Qt::ItemIsEditable
|Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
@@ -1351,9 +1389,8 @@ QTableWidgetItem::QTableWidgetItem(const QIcon &icon, const QString &text, int t
*/
QTableWidgetItem::~QTableWidgetItem()
{
- if (QTableModel *model = (view ? qobject_cast<QTableModel*>(view->model()) : 0))
+ if (QTableModel *model = tableModel())
model->removeItem(this);
- view = 0;
delete d;
}
@@ -1389,7 +1426,7 @@ void QTableWidgetItem::setData(int role, const QVariant &value)
}
if (!found)
values.append(QWidgetItemData(role, value));
- if (QTableModel *model = (view ? qobject_cast<QTableModel*>(view->model()) : nullptr))
+ if (QTableModel *model = tableModel())
{
const QVector<int> roles((role == Qt::DisplayRole) ?
QVector<int>({Qt::DisplayRole, Qt::EditRole}) :
@@ -1444,6 +1481,16 @@ void QTableWidgetItem::write(QDataStream &out) const
}
/*!
+ \internal
+ returns the QTableModel if a view is set
+*/
+QTableModel *QTableWidgetItem::tableModel() const
+{
+ return (view ? qobject_cast<QTableModel*>(view->model()) : nullptr);
+}
+
+
+/*!
\relates QTableWidgetItem
Reads a table widget item from stream \a in into \a item.
@@ -1486,7 +1533,7 @@ QDataStream &operator<<(QDataStream &out, const QTableWidgetItem &item)
\sa data(), flags()
*/
QTableWidgetItem::QTableWidgetItem(const QTableWidgetItem &other)
- : rtti(Type), values(other.values), view(0),
+ : rtti(Type), values(other.values), view(nullptr),
d(new QTableWidgetItemPrivate(this)),
itemFlags(other.itemFlags)
{
@@ -2305,6 +2352,7 @@ void QTableWidget::setCellWidget(int row, int column, QWidget *widget)
QAbstractItemView::setIndexWidget(index, widget);
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Returns \c true if the \a item is selected, otherwise returns \c false.
@@ -2315,9 +2363,7 @@ void QTableWidget::setCellWidget(int row, int column, QWidget *widget)
bool QTableWidget::isItemSelected(const QTableWidgetItem *item) const
{
- Q_D(const QTableWidget);
- QModelIndex index = d->tableModel()->index(item);
- return selectionModel()->isSelected(index);
+ return ((item && item->tableWidget() == this) ? item->isSelected() : false);
}
/*!
@@ -2329,10 +2375,10 @@ bool QTableWidget::isItemSelected(const QTableWidgetItem *item) const
*/
void QTableWidget::setItemSelected(const QTableWidgetItem *item, bool select)
{
- Q_D(QTableWidget);
- QModelIndex index = d->tableModel()->index(item);
- selectionModel()->select(index, select ? QItemSelectionModel::Select : QItemSelectionModel::Deselect);
+ if (item && item->tableWidget() == this)
+ const_cast<QTableWidgetItem*>(item)->setSelected(select);
}
+#endif
/*!
Selects or deselects the \a range depending on \a select.
diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h
index 9de27d164f..d93032f3f0 100644
--- a/src/widgets/itemviews/qtablewidget.h
+++ b/src/widgets/itemviews/qtablewidget.h
@@ -92,8 +92,8 @@ public:
inline int row() const;
inline int column() const;
- inline void setSelected(bool select);
- inline bool isSelected() const;
+ void setSelected(bool select);
+ bool isSelected() const;
inline Qt::ItemFlags flags() const { return itemFlags; }
void setFlags(Qt::ItemFlags flags);
@@ -131,20 +131,28 @@ public:
inline void setTextAlignment(int alignment)
{ setData(Qt::TextAlignmentRole, alignment); }
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QTableWidgetItem::background() instead")
inline QColor backgroundColor() const
- { return qvariant_cast<QColor>(data(Qt::BackgroundColorRole)); }
+ { return qvariant_cast<QColor>(data(Qt::BackgroundRole)); }
+ QT_DEPRECATED_X ("Use QTableWidgetItem::setBackground() instead")
inline void setBackgroundColor(const QColor &color)
- { setData(Qt::BackgroundColorRole, color); }
+ { setData(Qt::BackgroundRole, color); }
+#endif
inline QBrush background() const
{ return qvariant_cast<QBrush>(data(Qt::BackgroundRole)); }
inline void setBackground(const QBrush &brush)
{ setData(Qt::BackgroundRole, brush); }
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QTableWidgetItem::foreground() instead")
inline QColor textColor() const
- { return qvariant_cast<QColor>(data(Qt::TextColorRole)); }
+ { return qvariant_cast<QColor>(data(Qt::ForegroundRole)); }
+ QT_DEPRECATED_X ("Use QTableWidgetItem::setForeground() instead")
inline void setTextColor(const QColor &color)
- { setData(Qt::TextColorRole, color); }
+ { setData(Qt::ForegroundRole, color); }
+#endif
inline QBrush foreground() const
{ return qvariant_cast<QBrush>(data(Qt::ForegroundRole)); }
@@ -175,6 +183,9 @@ public:
inline int type() const { return rtti; }
private:
+ QTableModel *tableModel() const;
+
+private:
int rtti;
QVector<QWidgetItemData> values;
QTableWidget *view;
@@ -268,8 +279,12 @@ public:
void setCellWidget(int row, int column, QWidget *widget);
inline void removeCellWidget(int row, int column);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QTableWidgetItem::isSelected() instead")
bool isItemSelected(const QTableWidgetItem *item) const;
+ QT_DEPRECATED_X ("Use QTableWidgetItem::setSelected() instead")
void setItemSelected(const QTableWidgetItem *item, bool select);
+#endif
void setRangeSelected(const QTableWidgetSelectionRange &range, bool select);
QList<QTableWidgetSelectionRange> selectedRanges() const;
@@ -375,12 +390,6 @@ inline int QTableWidgetItem::row() const
inline int QTableWidgetItem::column() const
{ return (view ? view->column(this) : -1); }
-inline void QTableWidgetItem::setSelected(bool aselect)
-{ if (view) view->setItemSelected(this, aselect); }
-
-inline bool QTableWidgetItem::isSelected() const
-{ return (view ? view->isItemSelected(this) : false); }
-
QT_END_NAMESPACE
#endif // QTABLEWIDGET_H
diff --git a/src/widgets/itemviews/qtablewidget_p.h b/src/widgets/itemviews/qtablewidget_p.h
index 9899272fce..d88326f129 100644
--- a/src/widgets/itemviews/qtablewidget_p.h
+++ b/src/widgets/itemviews/qtablewidget_p.h
@@ -129,6 +129,9 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles) override;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ bool clearItemData(const QModelIndex &index) override;
+#endif
QMap<int, QVariant> itemData(const QModelIndex &index) const override;
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index f3647f656a..3fad6ca3df 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -1089,15 +1089,8 @@ void QTreeView::keyboardSearch(const QString &search)
if (start.column() > 0)
index = index.sibling(index.row(), start.column());
- if (index.isValid()) {
- QItemSelectionModel::SelectionFlags flags = (d->selectionMode == SingleSelection
- ? QItemSelectionModel::SelectionFlags(
- QItemSelectionModel::ClearAndSelect
- |d->selectionBehaviorFlags())
- : QItemSelectionModel::SelectionFlags(
- QItemSelectionModel::NoUpdate));
- selectionModel()->setCurrentIndex(index, flags);
- }
+ if (index.isValid())
+ setCurrentIndex(index);
}
/*!
@@ -1773,7 +1766,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled)
? QPalette::Normal : QPalette::Disabled;
o.backgroundColor = option.palette.color(cg, d->selectionModel->isSelected(index)
- ? QPalette::Highlight : QPalette::Background);
+ ? QPalette::Highlight : QPalette::Window);
int x = 0;
if (!option.showDecorationSelected)
x = header->sectionPosition(0) + d->indentationForItem(d->current);
@@ -1992,21 +1985,7 @@ void QTreeView::keyPressEvent(QKeyEvent *event)
if (d->isIndexValid(current) && d->model && d->itemsExpandable) {
switch (event->key()) {
case Qt::Key_Asterisk: {
- // do layouting only once after expanding is done
- d->doDelayedItemsLayout();
- QStack<QModelIndex> parents;
- parents.push(current);
- while (!parents.isEmpty()) {
- QModelIndex parent = parents.pop();
- for (int row = 0; row < d->model->rowCount(parent); ++row) {
- QModelIndex child = d->model->index(row, 0, parent);
- if (!d->isIndexValid(child))
- break;
- parents.push(child);
- expand(child);
- }
- }
- expand(current);
+ expandRecursively(current);
break; }
case Qt::Key_Plus:
expand(current);
@@ -2160,12 +2139,10 @@ int QTreeView::verticalOffset() const
// ### find a faster way to do this
d->executePostedLayout();
int offset = 0;
- for (int i = 0; i < d->viewItems.count(); ++i) {
- if (i == verticalScrollBar()->value())
- return offset;
+ const int cnt = std::min(d->viewItems.count(), verticalScrollBar()->value());
+ for (int i = 0; i < cnt; ++i)
offset += d->itemHeight(i);
- }
- return 0;
+ return offset;
}
// scroll per pixel
return verticalScrollBar()->value();
@@ -2324,9 +2301,9 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
case MovePageDown:
return d->modelIndex(d->pageDown(vi), current.column());
case MoveHome:
- return d->model->index(0, current.column(), d->root);
+ return d->modelIndex(d->itemForKeyHome(), current.column());
case MoveEnd:
- return d->modelIndex(d->viewItems.count() - 1, current.column());
+ return d->modelIndex(d->itemForKeyEnd(), current.column());
}
return current;
}
@@ -2621,10 +2598,13 @@ void QTreeView::resizeColumnToContents(int column)
d->header->resizeSection(column, qMax(contents, header));
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\obsolete
\overload
+ This function is deprecated. Use
+ sortByColumn(int column, Qt::SortOrder order) instead.
Sorts the model by the values in the given \a column.
*/
void QTreeView::sortByColumn(int column)
@@ -2632,6 +2612,7 @@ void QTreeView::sortByColumn(int column)
Q_D(QTreeView);
sortByColumn(column, d->header->sortIndicatorOrder());
}
+#endif
/*!
\since 4.2
@@ -2647,10 +2628,12 @@ void QTreeView::sortByColumn(int column)
void QTreeView::sortByColumn(int column, Qt::SortOrder order)
{
Q_D(QTreeView);
-
- //If sorting is enabled will emit a signal connected to _q_sortIndicatorChanged, which then actually sorts
+ if (column < 0)
+ return;
+ // If sorting is enabled it will emit a signal connected to
+ // _q_sortIndicatorChanged, which then actually sorts
d->header->setSortIndicator(column, order);
- //If sorting is not enabled, force to sort now.
+ // If sorting is not enabled, force to sort now
if (!d->sortingEnabled)
d->model->sort(column, order);
}
@@ -2694,11 +2677,7 @@ QSize QTreeView::viewportSizeHint() const
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);
+ result += QSize(0, d->header->isHidden() ? 0 : d->header->height());
return result;
}
@@ -2707,7 +2686,7 @@ QSize QTreeView::viewportSizeHint() const
\since 4.2
Expands all expandable items.
- Warning: if the model contains a large number of items,
+ \warning: if the model contains a large number of items,
this function will take some time to execute.
\sa collapseAll(), expand(), collapse(), setExpanded()
@@ -2723,6 +2702,50 @@ void QTreeView::expandAll()
}
/*!
+ \since 5.13
+ Expands the item at the given \a index and all its children to the
+ given \a depth. The \a depth is relative to the given \a index.
+ A \a depth of -1 will expand all children, a \a depth of 0 will
+ only expand the given \a index.
+
+ \warning: if the model contains a large number of items,
+ this function will take some time to execute.
+
+ \sa expandAll()
+*/
+void QTreeView::expandRecursively(const QModelIndex &index, int depth)
+{
+ Q_D(QTreeView);
+
+ if (depth < -1)
+ return;
+ // do layouting only once after expanding is done
+ d->doDelayedItemsLayout();
+ expand(index);
+ if (depth == 0)
+ return;
+ QStack<QPair<QModelIndex, int>> parents;
+ parents.push({index, 0});
+ while (!parents.isEmpty()) {
+ const QPair<QModelIndex, int> elem = parents.pop();
+ const QModelIndex &parent = elem.first;
+ const int curDepth = elem.second;
+ const int rowCount = d->model->rowCount(parent);
+ for (int row = 0; row < rowCount; ++row) {
+ const QModelIndex child = d->model->index(row, 0, parent);
+ if (!d->isIndexValid(child))
+ break;
+ if (depth == -1 || curDepth + 1 < depth)
+ parents.push({child, curDepth + 1});
+ if (d->isIndexExpanded(child))
+ continue;
+ if (d->storeExpanded(child))
+ emit expanded(child);
+ }
+ }
+}
+
+/*!
\since 4.2
Collapses all expanded items.
@@ -3399,7 +3422,11 @@ int QTreeViewPrivate::pageUp(int i) const
int index = itemAtCoordinate(coordinateForItem(i) - viewport->height());
while (isItemHiddenOrDisabled(index))
index--;
- return index == -1 ? 0 : index;
+ if (index == -1)
+ index = 0;
+ while (isItemHiddenOrDisabled(index))
+ index++;
+ return index >= viewItems.count() ? 0 : index;
}
int QTreeViewPrivate::pageDown(int i) const
@@ -3407,6 +3434,26 @@ int QTreeViewPrivate::pageDown(int i) const
int index = itemAtCoordinate(coordinateForItem(i) + viewport->height());
while (isItemHiddenOrDisabled(index))
index++;
+ if (index == -1 || index >= viewItems.count())
+ index = viewItems.count() - 1;
+ while (isItemHiddenOrDisabled(index))
+ index--;
+ return index == -1 ? viewItems.count() - 1 : index;
+}
+
+int QTreeViewPrivate::itemForKeyHome() const
+{
+ int index = 0;
+ while (isItemHiddenOrDisabled(index))
+ index++;
+ return index >= viewItems.count() ? 0 : index;
+}
+
+int QTreeViewPrivate::itemForKeyEnd() const
+{
+ int index = viewItems.count() - 1;
+ while (isItemHiddenOrDisabled(index))
+ index--;
return index == -1 ? viewItems.count() - 1 : index;
}
diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h
index 33dbf1c1ce..e9cc1beedb 100644
--- a/src/widgets/itemviews/qtreeview.h
+++ b/src/widgets/itemviews/qtreeview.h
@@ -143,7 +143,6 @@ public:
void doItemsLayout() override;
void reset() override;
- void sortByColumn(int column, Qt::SortOrder order);
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>()) override;
void selectAll() override;
@@ -158,8 +157,13 @@ public Q_SLOTS:
void expand(const QModelIndex &index);
void collapse(const QModelIndex &index);
void resizeColumnToContents(int column);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QTreeeView::sortByColumn(int column, Qt::SortOrder order) instead")
void sortByColumn(int column);
+#endif
+ void sortByColumn(int column, Qt::SortOrder order);
void expandAll();
+ void expandRecursively(const QModelIndex &index, int depth = -1);
void collapseAll();
void expandToDepth(int depth);
diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h
index 0a0e7aae87..9666a9f8c2 100644
--- a/src/widgets/itemviews/qtreeview_p.h
+++ b/src/widgets/itemviews/qtreeview_p.h
@@ -140,6 +140,8 @@ public:
int pageUp(int item) const;
int pageDown(int item) const;
+ int itemForKeyHome() const;
+ int itemForKeyEnd() const;
int itemHeight(int item) const;
int indentationForItem(int item) const;
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index 9fbfb50029..29cc199526 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -390,6 +390,27 @@ bool QTreeModel::setData(const QModelIndex &index, const QVariant &value, int ro
return false;
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+bool QTreeModel::clearItemData(const QModelIndex &index)
+{
+ if (!checkIndex(index, CheckIndexOption::IndexIsValid))
+ return false;
+ QTreeWidgetItem *itm = item(index);
+ if (!itm)
+ return false;
+ const auto beginIter = itm->values.at(index.column()).cbegin();
+ const auto endIter = itm->values.at(index.column()).cend();
+ if (std::all_of(beginIter, endIter, [](const QWidgetItemData& data) -> bool { return !data.value.isValid(); })
+ && !itm->d->display.at(index.column()).isValid()) {
+ return true; //it's already cleared
+ }
+ itm->d->display[index.column()] = QVariant();
+ itm->values[index.column()].clear();
+ emit dataChanged(index, index, QVector<int>{});
+ return true;
+}
+#endif
+
QMap<int, QVariant> QTreeModel::itemData(const QModelIndex &index) const
{
QMap<int, QVariant> roles;
@@ -635,7 +656,7 @@ void QTreeModel::ensureSorted(int column, Qt::SortOrder order,
// we are going to change the persistent indexes, so we need to prepare
if (!changed) { // this will only happen once
changed = true;
- emit layoutAboutToBeChanged(); // the selection model needs to know
+ emit layoutAboutToBeChanged({parent}, QAbstractItemModel::VerticalSortHint); // the selection model needs to know
oldPersistentIndexes = persistentIndexList();
newPersistentIndexes = oldPersistentIndexes;
}
@@ -668,7 +689,7 @@ void QTreeModel::ensureSorted(int column, Qt::SortOrder order,
if (changed) {
itm->children = lst;
changePersistentIndexList(oldPersistentIndexes, newPersistentIndexes);
- emit layoutChanged();
+ emit layoutChanged({parent}, QAbstractItemModel::VerticalSortHint);
}
}
@@ -988,8 +1009,18 @@ void QTreeModel::timerEvent(QTimerEvent *ev)
Sets the selected state of the item to \a select.
\sa isSelected()
-
*/
+void QTreeWidgetItem::setSelected(bool select)
+{
+ const QTreeModel *model = treeModel();
+ if (!model || !view->selectionModel())
+ return;
+ const QModelIndex index = model->index(this, 0);
+ view->selectionModel()->select(index, (select ? QItemSelectionModel::Select
+ : QItemSelectionModel::Deselect)
+ | QItemSelectionModel::Rows);
+ d->selected = select;
+}
/*!
\fn bool QTreeWidgetItem::isSelected() const
@@ -999,6 +1030,10 @@ void QTreeModel::timerEvent(QTimerEvent *ev)
\sa setSelected()
*/
+bool QTreeWidgetItem::isSelected() const
+{
+ return d->selected;
+}
/*!
\fn void QTreeWidgetItem::setHidden(bool hide)
@@ -1012,12 +1047,18 @@ void QTreeModel::timerEvent(QTimerEvent *ev)
\sa isHidden()
*/
-void QTreeWidgetItem::setHidden(bool ahide)
+void QTreeWidgetItem::setHidden(bool hide)
{
- if (view) {
- view->setItemHidden(this, ahide);
- d->hidden = ahide;
+ const QTreeModel *model = treeModel();
+ if (!model)
+ return;
+ if (this == model->headerItem) {
+ view->header()->setHidden(hide);
+ } else {
+ const QModelIndex index = view->d_func()->index(this);
+ view->setRowHidden(index.row(), index.parent(), hide);
}
+ d->hidden = hide;
}
/*!
@@ -1031,7 +1072,15 @@ void QTreeWidgetItem::setHidden(bool ahide)
bool QTreeWidgetItem::isHidden() const
{
- return (view ? d->hidden : false);
+ const QTreeModel *model = treeModel();
+ if (!model)
+ return false;
+ if (this == model->headerItem)
+ return view->header()->isHidden();
+ if (view->d_func()->hiddenIndexes.isEmpty())
+ return false;
+ QTreeModel::SkipSorting skipSorting(model);
+ return view->d_func()->isRowHidden(view->d_func()->index(this));
}
/*!
@@ -1043,6 +1092,14 @@ bool QTreeWidgetItem::isHidden() const
\sa isExpanded()
*/
+void QTreeWidgetItem::setExpanded(bool expand)
+{
+ const QTreeModel *model = treeModel();
+ if (!model)
+ return;
+ QTreeModel::SkipSorting skipSorting(model);
+ view->setExpanded(view->d_func()->index(this), expand);
+}
/*!
\fn bool QTreeWidgetItem::isExpanded() const
@@ -1052,6 +1109,14 @@ bool QTreeWidgetItem::isHidden() const
\sa setExpanded()
*/
+bool QTreeWidgetItem::isExpanded() const
+{
+ const QTreeModel *model = treeModel();
+ if (!model)
+ return false;
+ QTreeModel::SkipSorting skipSorting(model);
+ return view->isExpanded(view->d_func()->index(this));
+}
/*!
\fn void QTreeWidgetItem::setFirstColumnSpanned(bool span)
@@ -1062,6 +1127,14 @@ bool QTreeWidgetItem::isHidden() const
\sa isFirstColumnSpanned()
*/
+void QTreeWidgetItem::setFirstColumnSpanned(bool span)
+{
+ const QTreeModel *model = treeModel();
+ if (!model || this == model->headerItem)
+ return; // We can't set the header items to spanning
+ const QModelIndex index = model->index(this, 0);
+ view->setFirstColumnSpanned(index.row(), index.parent(), span);
+}
/*!
\fn bool QTreeWidgetItem::isFirstColumnSpanned() const
@@ -1071,6 +1144,14 @@ bool QTreeWidgetItem::isHidden() const
\sa setFirstColumnSpanned()
*/
+bool QTreeWidgetItem::isFirstColumnSpanned() const
+{
+ const QTreeModel *model = treeModel();
+ if (!model || this == model->headerItem)
+ return false;
+ const QModelIndex index = model->index(this, 0);
+ return view->isFirstColumnSpanned(index.row(), index.parent());
+}
/*!
\fn QString QTreeWidgetItem::text(int column) const
@@ -1325,7 +1406,7 @@ bool QTreeWidgetItem::isHidden() const
\sa type()
*/
QTreeWidgetItem::QTreeWidgetItem(int type)
- : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
+ : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr),
itemFlags(Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled
@@ -1344,7 +1425,7 @@ QTreeWidgetItem::QTreeWidgetItem(int type)
\sa type()
*/
QTreeWidgetItem::QTreeWidgetItem(const QStringList &strings, int type)
- : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
+ : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr),
itemFlags(Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled
@@ -1364,16 +1445,16 @@ QTreeWidgetItem::QTreeWidgetItem(const QStringList &strings, int type)
\sa type()
*/
-QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, int type)
- : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
+QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *treeview, int type)
+ : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr),
itemFlags(Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled
|Qt::ItemIsDragEnabled
|Qt::ItemIsDropEnabled)
{
- if (view && view->model()) {
- QTreeModel *model = qobject_cast<QTreeModel*>(view->model());
+ // do not set this->view here otherwise insertChild() will fail
+ if (QTreeModel *model = treeModel(treeview)) {
model->rootItem->addChild(this);
values.reserve(model->headerItem->columnCount());
}
@@ -1389,8 +1470,8 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, int type)
\sa type()
*/
-QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, const QStringList &strings, int type)
- : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
+QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *treeview, const QStringList &strings, int type)
+ : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr),
itemFlags(Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled
@@ -1399,8 +1480,8 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, const QStringList &strings,
{
for (int i = 0; i < strings.count(); ++i)
setText(i, strings.at(i));
- if (view && view->model()) {
- QTreeModel *model = qobject_cast<QTreeModel*>(view->model());
+ // do not set this->view here otherwise insertChild() will fail
+ if (QTreeModel *model = treeModel(treeview)) {
model->rootItem->addChild(this);
values.reserve(model->headerItem->columnCount());
}
@@ -1414,21 +1495,19 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, const QStringList &strings,
\sa type()
*/
-QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, QTreeWidgetItem *after, int type)
- : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
+QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *treeview, QTreeWidgetItem *after, int type)
+ : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr),
itemFlags(Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled
|Qt::ItemIsDragEnabled
|Qt::ItemIsDropEnabled)
{
- if (view) {
- QTreeModel *model = qobject_cast<QTreeModel*>(view->model());
- if (model) {
- int i = model->rootItem->children.indexOf(after) + 1;
- model->rootItem->insertChild(i, this);
- values.reserve(model->headerItem->columnCount());
- }
+ // do not set this->view here otherwise insertChild() will fail
+ if (QTreeModel *model = treeModel(treeview)) {
+ int i = model->rootItem->children.indexOf(after) + 1;
+ model->rootItem->insertChild(i, this);
+ values.reserve(model->headerItem->columnCount());
}
}
@@ -1438,7 +1517,7 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, QTreeWidgetItem *after, int
\sa type()
*/
QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, int type)
- : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
+ : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr),
itemFlags(Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled
@@ -1456,7 +1535,7 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, int type)
\sa type()
*/
QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &strings, int type)
- : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
+ : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr),
itemFlags(Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled
@@ -1478,7 +1557,7 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &str
\sa type()
*/
QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *after, int type)
- : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
+ : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr),
itemFlags(Qt::ItemIsSelectable
|Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled
@@ -1501,7 +1580,7 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *after
QTreeWidgetItem::~QTreeWidgetItem()
{
- QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
+ QTreeModel *model = treeModel();
bool wasSkipSort = false;
if (model) {
wasSkipSort = model->skipPendingSort;
@@ -1663,16 +1742,17 @@ void QTreeWidgetItem::setFlags(Qt::ItemFlags flags)
void QTreeWidgetItemPrivate::updateHiddenStatus(QTreeWidgetItem *item, bool inserting)
{
- QTreeModel *model = (item->view ? qobject_cast<QTreeModel*>(item->view->model()) : 0);
+ QTreeModel *model = item->treeModel();
if (!model)
return;
QStack<QTreeWidgetItem *> parents;
parents.push(item);
while (!parents.isEmpty()) {
QTreeWidgetItem *parent = parents.pop();
- QModelIndex index = model->index(parent, 0);
- if (parent->d->hidden)
+ if (parent->d->hidden) {
+ const QModelIndex index = model->index(parent, 0);
item->view->setRowHidden(index.row(), index.parent(), inserting);
+ }
for (int i = 0; i < parent->children.count(); ++i) {
QTreeWidgetItem *child = parent->children.at(i);
parents.push(child);
@@ -1737,7 +1817,7 @@ void QTreeWidgetItem::setData(int column, int role, const QVariant &value)
if (column < 0)
return;
- QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
+ QTreeModel *model = treeModel();
switch (role) {
case Qt::EditRole:
case Qt::DisplayRole: {
@@ -1945,7 +2025,7 @@ void QTreeWidgetItem::insertChild(int index, QTreeWidgetItem *child)
if (index < 0 || index > children.count() || child == 0 || child->view != 0 || child->par != 0)
return;
- if (QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0)) {
+ if (QTreeModel *model = treeModel()) {
const bool wasSkipSort = model->skipPendingSort;
model->skipPendingSort = true;
if (model->rootItem == this)
@@ -1996,7 +2076,7 @@ QTreeWidgetItem *QTreeWidgetItem::takeChild(int index)
{
// we move this outside the check of the index to allow executing
// pending sorts from inline functions, using this function (hack)
- QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
+ QTreeModel *model = treeModel();
if (model) {
// This will trigger a layoutChanged signal, thus we might want to optimize
// this function by not emitting the rowsRemoved signal etc to the view.
@@ -2054,7 +2134,7 @@ void QTreeWidgetItem::insertChildren(int index, const QList<QTreeWidgetItem*> &c
insertChild(index, children.at(n));
return;
}
- QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
+ QTreeModel *model = treeModel();
QStack<QTreeWidgetItem*> stack;
QList<QTreeWidgetItem*> itemsToInsert;
for (int n = 0; n < children.count(); ++n) {
@@ -2101,7 +2181,7 @@ QList<QTreeWidgetItem*> QTreeWidgetItem::takeChildren()
{
QList<QTreeWidgetItem*> removed;
if (children.count() > 0) {
- QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
+ QTreeModel *model = treeModel();
if (model) {
// This will trigger a layoutChanged signal, thus we might want to optimize
// this function by not emitting the rowsRemoved signal etc to the view.
@@ -2133,7 +2213,7 @@ QList<QTreeWidgetItem*> QTreeWidgetItem::takeChildren()
void QTreeWidgetItemPrivate::sortChildren(int column, Qt::SortOrder order, bool climb)
{
- QTreeModel *model = (q->view ? qobject_cast<QTreeModel*>(q->view->model()) : 0);
+ QTreeModel *model = q->treeModel();
if (!model)
return;
model->sortItems(&q->children, column, order);
@@ -2156,7 +2236,7 @@ void QTreeWidgetItemPrivate::sortChildren(int column, Qt::SortOrder order, bool
*/
void QTreeWidgetItem::sortChildren(int column, Qt::SortOrder order, bool climb)
{
- QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
+ QTreeModel *model = treeModel();
if (!model)
return;
if (model->isChanging())
@@ -2164,9 +2244,9 @@ void QTreeWidgetItem::sortChildren(int column, Qt::SortOrder order, bool climb)
QTreeModel::SkipSorting skipSorting(model);
int oldSortColumn = view->d_func()->explicitSortColumn;
view->d_func()->explicitSortColumn = column;
- emit model->layoutAboutToBeChanged();
+ emit model->layoutAboutToBeChanged({}, QAbstractItemModel::VerticalSortHint);
d->sortChildren(column, order, climb);
- emit model->layoutChanged();
+ emit model->layoutChanged({}, QAbstractItemModel::VerticalSortHint);
view->d_func()->explicitSortColumn = oldSortColumn;
}
@@ -2236,7 +2316,7 @@ void QTreeWidgetItem::emitDataChanged()
*/
void QTreeWidgetItem::itemChanged()
{
- if (QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0))
+ if (QTreeModel *model = treeModel())
model->itemChanged(this);
}
@@ -2245,10 +2325,21 @@ void QTreeWidgetItem::itemChanged()
*/
void QTreeWidgetItem::executePendingSort() const
{
- if (QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0))
+ if (QTreeModel *model = treeModel())
model->executePendingSort();
}
+/*!
+ \internal
+ returns the QTreeModel if a view is set
+*/
+QTreeModel *QTreeWidgetItem::treeModel(QTreeWidget *v) const
+{
+ if (!v)
+ v = view;
+ return (v ? qobject_cast<QTreeModel*>(v->model()) : nullptr);
+}
+
#ifndef QT_NO_DATASTREAM
/*!
@@ -2448,8 +2539,8 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
QStyle::SH_ItemView_ActivateItemOnSingleClick style hint) or
pressing a special key (e.g., \uicontrol Enter).
- The specified \a item is the item that was clicked, or 0 if no
- item was clicked. The \a column is the item's column that was
+ The specified \a item is the item that was clicked, or \nullptr if
+ no item was clicked. The \a column is the item's column that was
clicked, or -1 if no item was clicked.
*/
@@ -2459,8 +2550,8 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
This signal is emitted when the user presses a mouse button inside
the widget.
- The specified \a item is the item that was clicked, or 0 if no
- item was clicked. The \a column is the item's column that was
+ The specified \a item is the item that was clicked, or \nullptr if
+ no item was clicked. The \a column is the item's column that was
clicked, or -1 if no item was clicked.
*/
@@ -2480,8 +2571,8 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
This signal is emitted when the user double clicks inside the
widget.
- The specified \a item is the item that was clicked, or 0 if no
- item was clicked. The \a column is the item's column that was
+ The specified \a item is the item that was clicked, or \nullptr if
+ no item was clicked. The \a column is the item's column that was
clicked. If no item was double clicked, no signal will be emitted.
*/
@@ -2633,8 +2724,8 @@ QTreeWidgetItem *QTreeWidget::invisibleRootItem() const
}
/*!
- Returns the top level item at the given \a index, or 0 if the item does
- not exist.
+ Returns the top level item at the given \a index, or \nullptr if the
+ item does not exist.
\sa topLevelItemCount(), insertTopLevelItem()
*/
@@ -3010,7 +3101,7 @@ QWidget *QTreeWidget::itemWidget(QTreeWidgetItem *item, int column) const
This function should only be used to display static content in the place of
a tree widget item. If you want to display custom dynamic content or
- implement a custom editor widget, use QTreeView and subclass QItemDelegate
+ implement a custom editor widget, use QTreeView and subclass QStyledItemDelegate
instead.
This function cannot be called before the item hierarchy has been set up,
@@ -3027,6 +3118,7 @@ void QTreeWidget::setItemWidget(QTreeWidgetItem *item, int column, QWidget *widg
QAbstractItemView::setIndexWidget(d->index(item, column), widget);
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Returns \c true if the \a item is selected; otherwise returns \c false.
@@ -3038,9 +3130,7 @@ void QTreeWidget::setItemWidget(QTreeWidgetItem *item, int column, QWidget *widg
*/
bool QTreeWidget::isItemSelected(const QTreeWidgetItem *item) const
{
- if (!item)
- return false;
- return item->d->selected;
+ return ((item && item->treeWidget() == this) ? item->isSelected() : false);
}
/*!
@@ -3055,16 +3145,10 @@ bool QTreeWidget::isItemSelected(const QTreeWidgetItem *item) const
*/
void QTreeWidget::setItemSelected(const QTreeWidgetItem *item, bool select)
{
- Q_D(QTreeWidget);
-
- if (!item)
- return;
-
- selectionModel()->select(d->index(item), (select ? QItemSelectionModel::Select
- : QItemSelectionModel::Deselect)
- |QItemSelectionModel::Rows);
- item->d->selected = select;
+ if (item && item->treeWidget() == this)
+ const_cast<QTreeWidgetItem*>(item)->setSelected(select);
}
+#endif
/*!
Returns a list of all selected non-hidden items.
@@ -3081,7 +3165,7 @@ QList<QTreeWidgetItem*> QTreeWidget::selectedItems() const
seen.reserve(indexes.count());
for (const auto &index : indexes) {
QTreeWidgetItem *item = d->item(index);
- if (isItemHidden(item) || seen.contains(item))
+ if (item->isHidden() || seen.contains(item))
continue;
seen.insert(item);
items.append(item);
@@ -3105,6 +3189,7 @@ QList<QTreeWidgetItem*> QTreeWidget::findItems(const QString &text, Qt::MatchFla
return items;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Returns \c true if the \a item is explicitly hidden, otherwise returns \c false.
@@ -3114,13 +3199,7 @@ QList<QTreeWidgetItem*> QTreeWidget::findItems(const QString &text, Qt::MatchFla
*/
bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const
{
- Q_D(const QTreeWidget);
- if (item == d->treeModel()->headerItem)
- return header()->isHidden();
- if (d->hiddenIndexes.isEmpty())
- return false;
- QTreeModel::SkipSorting skipSorting(d->treeModel());
- return d->isRowHidden(d->index(item));
+ return ((item && item->treeWidget() == this) ? item->isHidden() : false);
}
/*!
@@ -3134,16 +3213,8 @@ bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const
*/
void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide)
{
- if (!item)
- return;
- Q_D(QTreeWidget);
- if (item == d->treeModel()->headerItem) {
- header()->setHidden(hide);
- } else {
- const QModelIndex index = d->index(item);
- setRowHidden(index.row(), index.parent(), hide);
- }
- item->d->hidden = hide;
+ if (item && item->treeWidget() == this)
+ const_cast<QTreeWidgetItem*>(item)->setHidden(hide);
}
/*!
@@ -3157,9 +3228,7 @@ void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide)
*/
bool QTreeWidget::isItemExpanded(const QTreeWidgetItem *item) const
{
- Q_D(const QTreeWidget);
- QTreeModel::SkipSorting skipSorting(d->treeModel());
- return isExpanded(d->index(item));
+ return ((item && item->treeWidget() == this) ? item->isExpanded() : false);
}
/*!
@@ -3174,9 +3243,8 @@ bool QTreeWidget::isItemExpanded(const QTreeWidgetItem *item) const
*/
void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand)
{
- Q_D(QTreeWidget);
- QTreeModel::SkipSorting skipSorting(d->treeModel());
- setExpanded(d->index(item), expand);
+ if (item && item->treeWidget() == this)
+ const_cast<QTreeWidgetItem*>(item)->setExpanded(expand);
}
/*!
@@ -3186,14 +3254,14 @@ void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand)
otherwise returns \c false.
\sa setFirstItemColumnSpanned()
+
+ \obsolete
+
+ This function is deprecated. Use \l{QTreeWidgetItem::isFirstColumnSpanned()} instead.
*/
bool QTreeWidget::isFirstItemColumnSpanned(const QTreeWidgetItem *item) const
{
- Q_D(const QTreeWidget);
- if (item == d->treeModel()->headerItem)
- return false; // We can't set the header items to spanning
- const QModelIndex index = d->index(item);
- return isFirstColumnSpanned(index.row(), index.parent());
+ return ((item && item->treeWidget() == this) ? item->isFirstColumnSpanned() : false);
}
/*!
@@ -3203,15 +3271,17 @@ bool QTreeWidget::isFirstItemColumnSpanned(const QTreeWidgetItem *item) const
otherwise the item will show one section per column.
\sa isFirstItemColumnSpanned()
+
+ \obsolete
+
+ This function is deprecated. Use \l{QTreeWidgetItem::setFirstColumnSpanned()} instead.
*/
void QTreeWidget::setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool span)
{
- Q_D(QTreeWidget);
- if (item == d->treeModel()->headerItem)
- return; // We can't set header items to spanning
- const QModelIndex index = d->index(item);
- setFirstColumnSpanned(index.row(), index.parent(), span);
+ if (item && item->treeWidget() == this)
+ const_cast<QTreeWidgetItem*>(item)->setFirstColumnSpanned(span);
}
+#endif
/*!
\since 4.3
diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h
index 975f208702..bed77b336d 100644
--- a/src/widgets/itemviews/qtreewidget.h
+++ b/src/widgets/itemviews/qtreewidget.h
@@ -66,9 +66,9 @@ public:
enum ItemType { Type = 0, UserType = 1000 };
explicit QTreeWidgetItem(int type = Type);
explicit QTreeWidgetItem(const QStringList &strings, int type = Type);
- explicit QTreeWidgetItem(QTreeWidget *view, int type = Type);
- QTreeWidgetItem(QTreeWidget *view, const QStringList &strings, int type = Type);
- QTreeWidgetItem(QTreeWidget *view, QTreeWidgetItem *after, int type = Type);
+ explicit QTreeWidgetItem(QTreeWidget *treeview, int type = Type);
+ QTreeWidgetItem(QTreeWidget *treeview, const QStringList &strings, int type = Type);
+ QTreeWidgetItem(QTreeWidget *treeview, QTreeWidgetItem *after, int type = Type);
explicit QTreeWidgetItem(QTreeWidgetItem *parent, int type = Type);
QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &strings, int type = Type);
QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *after, int type = Type);
@@ -79,17 +79,17 @@ public:
inline QTreeWidget *treeWidget() const { return view; }
- inline void setSelected(bool select);
- inline bool isSelected() const;
+ void setSelected(bool select);
+ bool isSelected() const;
void setHidden(bool hide);
bool isHidden() const;
- inline void setExpanded(bool expand);
- inline bool isExpanded() const;
+ void setExpanded(bool expand);
+ bool isExpanded() const;
- inline void setFirstColumnSpanned(bool span);
- inline bool isFirstColumnSpanned() const;
+ void setFirstColumnSpanned(bool span);
+ bool isFirstColumnSpanned() const;
inline void setDisabled(bool disabled);
inline bool isDisabled() const;
@@ -134,20 +134,28 @@ public:
inline void setTextAlignment(int column, int alignment)
{ setData(column, Qt::TextAlignmentRole, alignment); }
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::background() instead")
inline QColor backgroundColor(int column) const
- { return qvariant_cast<QColor>(data(column, Qt::BackgroundColorRole)); }
+ { return qvariant_cast<QColor>(data(column, Qt::BackgroundRole)); }
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::setBackground() instead")
inline void setBackgroundColor(int column, const QColor &color)
- { setData(column, Qt::BackgroundColorRole, color); }
+ { setData(column, Qt::BackgroundRole, color); }
+#endif
inline QBrush background(int column) const
{ return qvariant_cast<QBrush>(data(column, Qt::BackgroundRole)); }
inline void setBackground(int column, const QBrush &brush)
{ setData(column, Qt::BackgroundRole, brush); }
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::foreground() instead")
inline QColor textColor(int column) const
- { return qvariant_cast<QColor>(data(column, Qt::TextColorRole)); }
+ { return qvariant_cast<QColor>(data(column, Qt::ForegroundRole)); }
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::setForeground() instead")
inline void setTextColor(int column, const QColor &color)
- { setData(column, Qt::TextColorRole, color); }
+ { setData(column, Qt::ForegroundRole, color); }
+#endif
inline QBrush foreground(int column) const
{ return qvariant_cast<QBrush>(data(column, Qt::ForegroundRole)); }
@@ -207,6 +215,7 @@ private:
QVariant childrenCheckState(int column) const;
void itemChanged();
void executePendingSort() const;
+ QTreeModel *treeModel(QTreeWidget *v = nullptr) const;
int rtti;
// One item has a vector of column entries. Each column has a vector of (role, value) pairs.
@@ -306,20 +315,32 @@ public:
void setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget);
inline void removeItemWidget(QTreeWidgetItem *item, int column);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::isSelected() instead")
bool isItemSelected(const QTreeWidgetItem *item) const;
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::setSelected() instead")
void setItemSelected(const QTreeWidgetItem *item, bool select);
+#endif
QList<QTreeWidgetItem*> selectedItems() const;
QList<QTreeWidgetItem*> findItems(const QString &text, Qt::MatchFlags flags,
int column = 0) const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::isHidden() instead")
bool isItemHidden(const QTreeWidgetItem *item) const;
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::setHidden() instead")
void setItemHidden(const QTreeWidgetItem *item, bool hide);
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::isExpanded() instead")
bool isItemExpanded(const QTreeWidgetItem *item) const;
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::setExpanded() instead")
void setItemExpanded(const QTreeWidgetItem *item, bool expand);
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::isFirstColumnSpanned() instead")
bool isFirstItemColumnSpanned(const QTreeWidgetItem *item) const;
+ QT_DEPRECATED_X ("Use QTreeWidgetItem::setFirstColumnSpanned() instead")
void setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool span);
+#endif
QTreeWidgetItem *itemAbove(const QTreeWidgetItem *item) const;
QTreeWidgetItem *itemBelow(const QTreeWidgetItem *item) const;
@@ -404,24 +425,6 @@ inline QTreeWidgetItem *QTreeWidget::itemAt(int ax, int ay) const
inline void QTreeWidget::setHeaderLabel(const QString &alabel)
{ setHeaderLabels(QStringList(alabel)); }
-inline void QTreeWidgetItem::setSelected(bool aselect)
-{ if (view) view->setItemSelected(this, aselect); }
-
-inline bool QTreeWidgetItem::isSelected() const
-{ return (view ? view->isItemSelected(this) : false); }
-
-inline void QTreeWidgetItem::setExpanded(bool aexpand)
-{ if (view) view->setItemExpanded(this, aexpand); }
-
-inline bool QTreeWidgetItem::isExpanded() const
-{ return (view ? view->isItemExpanded(this) : false); }
-
-inline void QTreeWidgetItem::setFirstColumnSpanned(bool aspan)
-{ if (view) view->setFirstItemColumnSpanned(this, aspan); }
-
-inline bool QTreeWidgetItem::isFirstColumnSpanned() const
-{ return (view ? view->isFirstItemColumnSpanned(this) : false); }
-
inline void QTreeWidgetItem::setDisabled(bool disabled)
{ setFlags(disabled ? (flags() & ~Qt::ItemIsEnabled) : flags() | Qt::ItemIsEnabled); }
diff --git a/src/widgets/itemviews/qtreewidget_p.h b/src/widgets/itemviews/qtreewidget_p.h
index adc2c2c421..ee4a633468 100644
--- a/src/widgets/itemviews/qtreewidget_p.h
+++ b/src/widgets/itemviews/qtreewidget_p.h
@@ -99,7 +99,9 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
-
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ bool clearItemData(const QModelIndex &index) override;
+#endif
QMap<int, QVariant> itemData(const QModelIndex &index) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
diff --git a/src/widgets/kernel/qactiongroup.cpp b/src/widgets/kernel/qactiongroup.cpp
index 7934ae1d90..4786437d7e 100644
--- a/src/widgets/kernel/qactiongroup.cpp
+++ b/src/widgets/kernel/qactiongroup.cpp
@@ -316,8 +316,8 @@ bool QActionGroup::isEnabled() const
}
/*!
- Returns the currently checked action in the group, or 0 if none
- are checked.
+ Returns the currently checked action in the group, or \nullptr if
+ none are checked.
*/
QAction *QActionGroup::checkedAction() const
{
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index ebab87b193..7c44bfe39d 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -784,7 +784,7 @@ QWidget *QApplication::activeModalWidget()
/*!
Cleans up any window system resources that were allocated by this
- application. Sets the global variable \c qApp to 0.
+ application. Sets the global variable \c qApp to \nullptr.
*/
QApplication::~QApplication()
@@ -893,8 +893,8 @@ void qt_cleanup()
/*!
\fn QWidget *QApplication::widgetAt(const QPoint &point)
- Returns the widget at global screen position \a point, or 0 if there is no
- Qt widget there.
+ Returns the widget at global screen position \a point, or \nullptr
+ if there is no Qt widget there.
This function can be slow.
@@ -904,9 +904,9 @@ QWidget *QApplication::widgetAt(const QPoint &p)
{
QWidget *window = QApplication::topLevelAt(p);
if (!window)
- return 0;
+ return nullptr;
- QWidget *child = 0;
+ QWidget *child = nullptr;
if (!window->testAttribute(Qt::WA_TransparentForMouseEvents))
child = window->childAt(window->mapFromGlobal(p));
@@ -942,8 +942,8 @@ QWidget *QApplication::widgetAt(const QPoint &p)
\overload
- Returns the widget at global screen position (\a x, \a y), or 0 if there is
- no Qt widget there.
+ Returns the widget at global screen position (\a x, \a y), or
+ \nullptr if there is no Qt widget there.
*/
/*!
@@ -1243,6 +1243,7 @@ QStyle* QApplication::setStyle(const QString& style)
return s;
}
+#if QT_DEPRECATED_SINCE(5, 8)
/*!
Returns the color specification.
\obsolete
@@ -1317,6 +1318,7 @@ void QApplication::setColorSpec(int spec)
{
Q_UNUSED(spec)
}
+#endif
/*!
\property QApplication::globalStrut
@@ -1428,6 +1430,7 @@ void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char*
else
*QApplicationPrivate::set_pal = palette;
QCoreApplication::setAttribute(Qt::AA_SetPalette);
+ emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal);
}
}
@@ -1727,8 +1730,8 @@ QWidgetList QApplication::allWidgets()
}
/*!
- Returns the application widget that has the keyboard input focus, or 0 if
- no widget in this application has the focus.
+ Returns the application widget that has the keyboard input focus,
+ or \nullptr if no widget in this application has the focus.
\sa QWidget::setFocus(), QWidget::hasFocus(), activeWindow(), focusChanged()
*/
@@ -1796,7 +1799,7 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
/*!
Returns the application top-level window that has the keyboard input focus,
- or 0 if no application window has the focus. There might be an
+ or \nullptr if no application window has the focus. There might be an
activeWindow() even if there is no focusWidget(), for example if no widget
in that window accepts key events.
@@ -3891,6 +3894,7 @@ Qt::NavigationMode QApplication::navigationMode()
return QApplicationPrivate::navigationMode;
}
+# if QT_DEPRECATED_SINCE(5, 13)
/*!
Sets whether Qt should use focus navigation suitable for use with a
minimal keypad.
@@ -3933,6 +3937,7 @@ bool QApplication::keypadNavigationEnabled()
return QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadTabOrder ||
QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadDirectional;
}
+# endif
#endif
/*!
diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h
index 7a5d7ba1a9..27e743a28d 100644
--- a/src/widgets/kernel/qapplication.h
+++ b/src/widgets/kernel/qapplication.h
@@ -180,8 +180,12 @@ public:
bool notify(QObject *, QEvent *) override;
#ifdef QT_KEYPAD_NAVIGATION
- static Q_DECL_DEPRECATED void setKeypadNavigationEnabled(bool);
- static bool keypadNavigationEnabled();
+# if QT_DEPRECATED_SINCE(5, 13)
+ static QT_DEPRECATED_X ("Use QApplication::setNavigationMode() instead")
+ void setKeypadNavigationEnabled(bool);
+ static QT_DEPRECATED_X ("Use QApplication::navigationMode() instead")
+ bool keypadNavigationEnabled();
+# endif
static void setNavigationMode(Qt::NavigationMode mode);
static Qt::NavigationMode navigationMode();
#endif
diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp
index 5fb7882932..d17c7eb36c 100644
--- a/src/widgets/kernel/qdesktopwidget.cpp
+++ b/src/widgets/kernel/qdesktopwidget.cpp
@@ -176,26 +176,32 @@ void QDesktopWidgetPrivate::_q_updateScreens()
// Notice that we trigger screenCountChanged even if a screen was removed and another one added,
// in which case the total number of screens did not change. This is the only way for applications
// to notice that a screen was swapped out against another one.
+#if QT_DEPRECATED_SINCE(5, 11)
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
emit q->screenCountChanged(targetLength);
QT_WARNING_POP
+#endif
}
+#if QT_DEPRECATED_SINCE(5, 11)
foreach (int changedScreen, changedScreens)
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
emit q->resized(changedScreen);
QT_WARNING_POP
+#endif
}
void QDesktopWidgetPrivate::_q_availableGeometryChanged()
{
+#if QT_DEPRECATED_SINCE(5, 11)
Q_Q(QDesktopWidget);
if (QScreen *screen = qobject_cast<QScreen *>(q->sender()))
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
emit q->workAreaResized(QGuiApplication::screens().indexOf(screen));
QT_WARNING_POP
+#endif
}
QDesktopWidget::QDesktopWidget()
@@ -212,10 +218,12 @@ QDesktopWidget::~QDesktopWidget()
{
}
+#if QT_DEPRECATED_SINCE(5, 11)
bool QDesktopWidget::isVirtualDesktop() const
{
return QDesktopWidgetPrivate::isVirtualDesktop();
}
+#endif
bool QDesktopWidgetPrivate::isVirtualDesktop()
{
@@ -242,24 +250,27 @@ int QDesktopWidgetPrivate::height()
return geometry().height();
}
+#if QT_DEPRECATED_SINCE(5, 11)
int QDesktopWidget::primaryScreen() const
{
return QDesktopWidgetPrivate::primaryScreen();
}
+#endif
int QDesktopWidgetPrivate::primaryScreen()
{
return 0;
}
-int QDesktopWidget::numScreens() const
+int QDesktopWidgetPrivate::numScreens()
{
- return QDesktopWidgetPrivate::numScreens();
+ return qMax(QGuiApplication::screens().size(), 1);
}
-int QDesktopWidgetPrivate::numScreens()
+#if QT_DEPRECATED_SINCE(5, 11)
+int QDesktopWidget::numScreens() const
{
- return qMax(QGuiApplication::screens().size(), 1);
+ return QDesktopWidgetPrivate::numScreens();
}
QWidget *QDesktopWidget::screen(int screen)
@@ -274,6 +285,7 @@ const QRect QDesktopWidget::availableGeometry(int screenNo) const
{
return QDesktopWidgetPrivate::availableGeometry(screenNo);
}
+#endif
const QRect QDesktopWidgetPrivate::availableGeometry(int screenNo)
{
@@ -281,10 +293,12 @@ const QRect QDesktopWidgetPrivate::availableGeometry(int screenNo)
return screen ? screen->availableGeometry() : QRect();
}
+#if QT_DEPRECATED_SINCE(5, 11)
const QRect QDesktopWidget::screenGeometry(int screenNo) const
{
return QDesktopWidgetPrivate::screenGeometry(screenNo);
}
+#endif
const QRect QDesktopWidgetPrivate::screenGeometry(int screenNo)
{
@@ -344,10 +358,12 @@ int QDesktopWidgetPrivate::screenNumber(const QWidget *w)
return allScreens.indexOf(widgetScreen);
}
+#if QT_DEPRECATED_SINCE(5, 11)
int QDesktopWidget::screenNumber(const QPoint &p) const
{
return QDesktopWidgetPrivate::screenNumber(p);
}
+#endif
int QDesktopWidgetPrivate::screenNumber(const QPoint &p)
{
diff --git a/src/widgets/kernel/qdesktopwidget.h b/src/widgets/kernel/qdesktopwidget.h
index f986f0db20..e5c587984f 100644
--- a/src/widgets/kernel/qdesktopwidget.h
+++ b/src/widgets/kernel/qdesktopwidget.h
@@ -52,9 +52,11 @@ class QDesktopWidgetPrivate;
class Q_WIDGETS_EXPORT QDesktopWidget : public QWidget
{
Q_OBJECT
+#if QT_DEPRECATED_SINCE(5, 11)
Q_PROPERTY(bool virtualDesktop READ isVirtualDesktop)
Q_PROPERTY(int screenCount READ screenCount NOTIFY screenCountChanged)
Q_PROPERTY(int primaryScreen READ primaryScreen NOTIFY primaryScreenChanged)
+#endif
public:
QDesktopWidget();
~QDesktopWidget();
diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp
index 600934b8a1..bd0ea2598a 100644
--- a/src/widgets/kernel/qformlayout.cpp
+++ b/src/widgets/kernel/qformlayout.cpp
@@ -419,13 +419,15 @@ void QFormLayoutPrivate::updateSizes()
if (label) {
maxMinLblWidth = qMax(maxMinLblWidth, label->minSize.width());
maxShLblWidth = qMax(maxShLblWidth, label->sizeHint.width());
- if (field) {
+ }
+ if (field) {
+ if (field->fullRow) {
+ maxMinIfldWidth = qMax(maxMinIfldWidth, field->minSize.width());
+ maxShIfldWidth = qMax(maxShIfldWidth, field->sizeHint.width());
+ } else {
maxMinFldWidth = qMax(maxMinFldWidth, field->minSize.width() + field->sbsHSpace);
maxShFldWidth = qMax(maxShFldWidth, field->sizeHint.width() + field->sbsHSpace);
}
- } else if (field) {
- maxMinIfldWidth = qMax(maxMinIfldWidth, field->minSize.width());
- maxShIfldWidth = qMax(maxShIfldWidth, field->sizeHint.width());
}
prevLbl = label;
@@ -2207,8 +2209,11 @@ void QFormLayoutPrivate::arrangeWidgets(const QVector<QLayoutStruct>& layouts, Q
QSize sz(qMin(label->layoutWidth, label->sizeHint.width()), height);
int x = leftOffset + rect.x() + label->layoutPos;
- if (fixedAlignment(q->labelAlignment(), layoutDirection) & Qt::AlignRight)
+ const auto fAlign = fixedAlignment(q->labelAlignment(), layoutDirection);
+ if (fAlign & Qt::AlignRight)
x += label->layoutWidth - sz.width();
+ else if (fAlign & Qt::AlignHCenter)
+ x += label->layoutWidth / 2 - sz.width() / 2;
QPoint p(x, layouts.at(label->vLayoutIndex).pos);
// ### expansion & sizepolicy stuff
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index 891858b035..cd27c9c5be 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -136,7 +136,7 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r
++m_lastCustomGestureId;
type = Qt::GestureType(m_lastCustomGestureId);
}
- m_recognizers.insertMulti(type, recognizer);
+ m_recognizers.insert(type, recognizer);
return type;
}
@@ -517,7 +517,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
for(ContextIterator it = w->d_func()->gestureContext.constBegin(),
e = w->d_func()->gestureContext.constEnd(); it != e; ++it) {
types.insert(it.key(), 0);
- contexts.insertMulti(w, it.key());
+ contexts.insert(w, it.key());
}
}
// find all gesture contexts for the widget tree
@@ -529,7 +529,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
if (!(it.value() & Qt::DontStartGestureOnChildren)) {
if (!types.contains(it.key())) {
types.insert(it.key(), 0);
- contexts.insertMulti(w, it.key());
+ contexts.insert(w, it.key());
}
}
}
@@ -551,7 +551,7 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.constBegin(),
e = item->QGraphicsItem::d_func()->gestureContext.constEnd(); it != e; ++it) {
types.insert(it.key(), 0);
- contexts.insertMulti(item, it.key());
+ contexts.insert(item, it.key());
}
}
// find all gesture contexts for the graphics object tree
@@ -564,7 +564,7 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
if (!(it.value() & Qt::DontStartGestureOnChildren)) {
if (!types.contains(it.key())) {
types.insert(it.key(), 0);
- contexts.insertMulti(item, it.key());
+ contexts.insert(item, it.key());
}
}
}
diff --git a/src/widgets/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp
index f1c6c96a6d..4f2b505e32 100644
--- a/src/widgets/kernel/qgridlayout.cpp
+++ b/src/widgets/kernel/qgridlayout.cpp
@@ -1330,8 +1330,8 @@ QLayoutItem *QGridLayout::itemAt(int index) const
/*!
\since 4.4
- Returns the layout item that occupies cell (\a row, \a column), or 0 if
- the cell is empty.
+ Returns the layout item that occupies cell (\a row, \a column), or
+ \nullptr if the cell is empty.
\sa getItemPosition(), indexOf()
*/
@@ -1346,7 +1346,7 @@ QLayoutItem *QGridLayout::itemAtPosition(int row, int column) const
return box->item();
}
}
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index eac5674161..e3f6a56875 100644
--- a/src/widgets/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
@@ -109,7 +109,7 @@ static int menuBarHeightForWidth(QWidget *menubar, int w)
/*!
Constructs a new top-level QLayout, with parent \a parent.
- \a parent may not be a \c nullptr.
+ \a parent may not be a \nullptr.
The layout is set directly as the top-level layout for
\a parent. There can be only one top-level layout for a
@@ -282,6 +282,7 @@ bool QLayout::setAlignment(QLayout *l, Qt::Alignment alignment)
return false;
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\property QLayout::margin
\brief the width of the outside border of the layout
@@ -307,6 +308,15 @@ int QLayout::margin() const
}
/*!
+ \obsolete
+*/
+void QLayout::setMargin(int margin)
+{
+ setContentsMargins(margin, margin, margin, margin);
+}
+
+#endif
+/*!
\property QLayout::spacing
\brief the spacing between widgets inside the layout
@@ -344,14 +354,6 @@ int QLayout::spacing() const
}
}
-/*!
- \obsolete
-*/
-void QLayout::setMargin(int margin)
-{
- setContentsMargins(margin, margin, margin, margin);
-}
-
void QLayout::setSpacing(int spacing)
{
if (QBoxLayout* boxlayout = qobject_cast<QBoxLayout*>(this)) {
@@ -474,8 +476,8 @@ QRect QLayout::contentsRect() const
/*!
- Returns the parent widget of this layout, or 0 if this layout is
- not installed on any widget.
+ Returns the parent widget of this layout, or \nullptr if this
+ layout is not installed on any widget.
If the layout is a sub-layout, this function returns the parent
widget of the parent layout.
@@ -490,11 +492,11 @@ QWidget *QLayout::parentWidget() const
QLayout *parentLayout = qobject_cast<QLayout*>(parent());
if (Q_UNLIKELY(!parentLayout)) {
qWarning("QLayout::parentWidget: A layout can only have another layout as a parent.");
- return 0;
+ return nullptr;
}
return parentLayout->parentWidget();
} else {
- return 0;
+ return nullptr;
}
} else {
Q_ASSERT(parent() && parent()->isWidgetType());
@@ -950,8 +952,8 @@ void QLayout::setMenuBar(QWidget *widget)
}
/*!
- Returns the menu bar set for this layout, or 0 if no menu bar is
- set.
+ Returns the menu bar set for this layout, or \nullptr if no
+ menu bar is set.
*/
QWidget *QLayout::menuBar() const
@@ -1130,8 +1132,9 @@ bool QLayout::activate()
Searches for widget \a from and replaces it with widget \a to if found.
Returns the layout item that contains the widget \a from on success.
- Otherwise \c 0 is returned. If \a options contains \c Qt::FindChildrenRecursively
- (the default), sub-layouts are searched for doing the replacement.
+ Otherwise \nullptr is returned.
+ If \a options contains \c Qt::FindChildrenRecursively (the default),
+ sub-layouts are searched for doing the replacement.
Any other flag in \a options is ignored.
Notice that the returned item therefore might not belong to this layout,
diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h
index 616f4e7164..35a04a35b2 100644
--- a/src/widgets/kernel/qlayout.h
+++ b/src/widgets/kernel/qlayout.h
@@ -63,7 +63,9 @@ class Q_WIDGETS_EXPORT QLayout : public QObject, public QLayoutItem
Q_OBJECT
Q_DECLARE_PRIVATE(QLayout)
+#if QT_DEPRECATED_SINCE(5, 13)
Q_PROPERTY(int margin READ margin WRITE setMargin)
+#endif
Q_PROPERTY(int spacing READ spacing WRITE setSpacing)
Q_PROPERTY(SizeConstraint sizeConstraint READ sizeConstraint WRITE setSizeConstraint)
public:
@@ -81,10 +83,12 @@ public:
QLayout();
~QLayout();
+#if QT_DEPRECATED_SINCE(5, 13)
int margin() const;
- int spacing() const;
-
void setMargin(int);
+#endif
+
+ int spacing() const;
void setSpacing(int);
void setContentsMargins(int left, int top, int right, int bottom);
diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp
index 25890e888b..9e6d1c5eac 100644
--- a/src/widgets/kernel/qlayoutitem.cpp
+++ b/src/widgets/kernel/qlayoutitem.cpp
@@ -309,24 +309,24 @@ void QLayoutItem::invalidate()
/*!
If this item is a QLayout, it is returned as a QLayout; otherwise
- 0 is returned. This function provides type-safe casting.
+ \nullptr is returned. This function provides type-safe casting.
\sa spacerItem(), widget()
*/
-QLayout * QLayoutItem::layout()
+QLayout *QLayoutItem::layout()
{
- return 0;
+ return nullptr;
}
/*!
If this item is a QSpacerItem, it is returned as a QSpacerItem;
- otherwise 0 is returned. This function provides type-safe casting.
+ otherwise \nullptr is returned. This function provides type-safe casting.
\sa layout(), widget()
*/
-QSpacerItem * QLayoutItem::spacerItem()
+QSpacerItem *QLayoutItem::spacerItem()
{
- return 0;
+ return nullptr;
}
/*!
@@ -354,7 +354,7 @@ QSpacerItem * QSpacerItem::spacerItem()
/*!
If this item manages a QWidget, returns that widget. Otherwise,
- \c nullptr is returned.
+ \nullptr is returned.
\note While the functions layout() and spacerItem() perform casts, this
function returns another object: QLayout and QSpacerItem inherit QLayoutItem,
@@ -362,9 +362,9 @@ QSpacerItem * QSpacerItem::spacerItem()
\sa layout(), spacerItem()
*/
-QWidget * QLayoutItem::widget()
+QWidget *QLayoutItem::widget()
{
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 89f860150f..cf15614680 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -1118,8 +1118,8 @@ void QOpenGLWidget::setTextureFormat(GLenum texFormat)
/*!
\return the active internal texture format if the widget has already
initialized, the requested format if one was set but the widget has not yet
- been made visible, or 0 if setTextureFormat() was not called and the widget
- has not yet been made visible.
+ been made visible, or \nullptr if setTextureFormat() was not called and the
+ widget has not yet been made visible.
\since 5.10
*/
diff --git a/src/widgets/kernel/qstackedlayout.cpp b/src/widgets/kernel/qstackedlayout.cpp
index 7430d833db..0412dc188d 100644
--- a/src/widgets/kernel/qstackedlayout.cpp
+++ b/src/widgets/kernel/qstackedlayout.cpp
@@ -378,20 +378,20 @@ void QStackedLayout::setCurrentWidget(QWidget *widget)
/*!
- Returns the current widget, or 0 if there are no widgets in this
- layout.
+ Returns the current widget, or \nullptr if there are no widgets
+ in this layout.
\sa currentIndex(), setCurrentWidget()
*/
QWidget *QStackedLayout::currentWidget() const
{
Q_D(const QStackedLayout);
- return d->index >= 0 ? d->list.at(d->index)->widget() : 0;
+ return d->index >= 0 ? d->list.at(d->index)->widget() : nullptr;
}
/*!
- Returns the widget at the given \a index, or 0 if there is no
- widget at the given position.
+ Returns the widget at the given \a index, or \nullptr if there is
+ no widget at the given position.
\sa currentWidget(), indexOf()
*/
@@ -399,7 +399,7 @@ QWidget *QStackedLayout::widget(int index) const
{
Q_D(const QStackedLayout);
if (index < 0 || index >= d->list.size())
- return 0;
+ return nullptr;
return d->list.at(index)->widget();
}
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index cf0f3f153b..f81cb471fa 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -482,8 +482,8 @@ bool QTipLabel::tipChanged(const QPoint &pos, const QString &text, QObject *o)
The \a rect is in the coordinates of the widget you specify with
\a w. If the \a rect is not empty you must specify a widget.
- Otherwise this argument can be 0 but it is used to determine the
- appropriate screen on multi-head systems.
+ Otherwise this argument can be \nullptr but it is used to
+ determine the appropriate screen on multi-head systems.
If \a text is empty the tool tip is hidden. If the text is the
same as the currently shown tooltip, the tip will \e not move.
diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp
index 1fa83d3238..4a798a7490 100644
--- a/src/widgets/kernel/qwhatsthis.cpp
+++ b/src/widgets/kernel/qwhatsthis.cpp
@@ -398,10 +398,10 @@ QWhatsThisPrivate::QWhatsThisPrivate()
#ifdef QT_NO_CURSOR
Q_UNUSED(sentEvent);
#else
- QApplication::setOverrideCursor((!sentEvent || !e.isAccepted())?
+ QGuiApplication::setOverrideCursor((!sentEvent || !e.isAccepted())?
Qt::ForbiddenCursor:Qt::WhatsThisCursor);
} else {
- QApplication::setOverrideCursor(Qt::WhatsThisCursor);
+ QGuiApplication::setOverrideCursor(Qt::WhatsThisCursor);
#endif
}
#ifndef QT_NO_ACCESSIBILITY
@@ -417,7 +417,7 @@ QWhatsThisPrivate::~QWhatsThisPrivate()
action->setChecked(false);
#endif // QT_CONFIG(action)
#ifndef QT_NO_CURSOR
- QApplication::restoreOverrideCursor();
+ QGuiApplication::restoreOverrideCursor();
#endif
#ifndef QT_NO_ACCESSIBILITY
QAccessibleEvent event(this, QAccessible::ContextHelpEnd);
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 2c84ff7161..89a8a7be0f 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -511,10 +511,10 @@ void QWidget::setAutoFillBackground(bool enabled)
Every widget's constructor accepts one or two standard arguments:
\list 1
- \li \c{QWidget *parent = 0} is the parent of the new widget. If it is 0
- (the default), the new widget will be a window. If not, it will be
- a child of \e parent, and be constrained by \e parent's geometry
- (unless you specify Qt::Window as window flag).
+ \li \c{QWidget *parent = \nullptr} is the parent of the new widget.
+ If it is \nullptr (the default), the new widget will be a window.
+ If not, it will be a child of \e parent, and be constrained by
+ \e parent's geometry (unless you specify Qt::Window as window flag).
\li \c{Qt::WindowFlags f = 0} (where available) sets the window flags;
the default is suitable for almost all widgets, but to get, for
example, a window without a window system frame, you must use
@@ -1003,14 +1003,14 @@ struct QWidgetExceptionCleaner
Constructs a widget which is a child of \a parent, with widget
flags set to \a f.
- If \a parent is 0, the new widget becomes a window. If
+ If \a parent is \nullptr, the new widget becomes a window. If
\a parent is another widget, this widget becomes a child window
inside \a parent. The new widget is deleted when its \a parent is
deleted.
The widget flags argument, \a f, is normally 0, but it can be set
- to customize the frame of a window (i.e. \a
- parent must be 0). To customize the frame, use a value composed
+ to customize the frame of a window (i.e. \a parent must be
+ \nullptr). To customize the frame, use a value composed
from the bitwise OR of any of the \l{Qt::WindowFlags}{window flags}.
If you add a child widget to an already visible widget you must
@@ -2418,29 +2418,34 @@ static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrus
}
}
-void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const
+bool QWidgetPrivate::updateBrushOrigin(QPainter *painter, const QBrush &brush) const
{
- Q_Q(const QWidget);
-
#if QT_CONFIG(scrollarea)
- bool resetBrushOrigin = false;
- QPointF oldBrushOrigin;
+ Q_Q(const QWidget);
//If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture
+ if (brush.style() == Qt::NoBrush || brush.style() == Qt::SolidPattern)
+ return false;
QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent);
if (scrollArea && scrollArea->viewport() == q) {
QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data();
QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
- oldBrushOrigin = painter->brushOrigin();
- resetBrushOrigin = true;
painter->setBrushOrigin(-priv->contentsOffset());
-
}
#endif // QT_CONFIG(scrollarea)
+ return true;
+}
+
+void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const
+{
+ Q_Q(const QWidget);
+ bool brushOriginSet = false;
const QBrush autoFillBrush = q->palette().brush(q->backgroundRole());
if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
const QBrush bg = q->palette().brush(QPalette::Window);
+ if (!brushOriginSet)
+ brushOriginSet = updateBrushOrigin(painter, bg);
if (!(flags & DontSetCompositionMode)) {
//copy alpha straight in
QPainter::CompositionMode oldMode = painter->compositionMode();
@@ -2452,8 +2457,11 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int
}
}
- if (q->autoFillBackground())
+ if (q->autoFillBackground()) {
+ if (!brushOriginSet)
+ brushOriginSet = updateBrushOrigin(painter, autoFillBrush);
fillRegion(painter, rgn, autoFillBrush);
+ }
if (q->testAttribute(Qt::WA_StyledBackground)) {
painter->setClipRegion(rgn);
@@ -2461,11 +2469,6 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int
opt.initFrom(q);
q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q);
}
-
-#if QT_CONFIG(scrollarea)
- if (resetBrushOrigin)
- painter->setBrushOrigin(oldBrushOrigin);
-#endif // QT_CONFIG(scrollarea)
}
/*
@@ -2499,12 +2502,12 @@ void QWidgetPrivate::deactivateWidgetCleanup()
The window identifier type depends on the underlying window
system, see \c qwindowdefs.h for the actual definition. If there
- is no widget with this identifier, 0 is returned.
+ is no widget with this identifier, \nullptr is returned.
*/
QWidget *QWidget::find(WId id)
{
- return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : 0;
+ return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : nullptr;
}
@@ -3281,7 +3284,7 @@ void QWidget::addActions(QList<QAction*> actions)
/*!
Inserts the action \a action to this widget's list of actions,
- before the action \a before. It appends the action if \a before is 0 or
+ before the action \a before. It appends the action if \a before is \nullptr or
\a before is not a valid action for this widget.
A QWidget should only have one of each action.
@@ -3315,7 +3318,7 @@ void QWidget::insertAction(QAction *before, QAction *action)
/*!
Inserts the actions \a actions to this widget's list of actions,
- before the action \a before. It appends the action if \a before is 0 or
+ before the action \a before. It appends the action if \a before is \nullptr or
\a before is not a valid action for this widget.
A QWidget can have at most one of each action.
@@ -4234,7 +4237,7 @@ void QWidget::setFixedHeight(int h)
/*!
Translates the widget coordinate \a pos to the coordinate system
- of \a parent. The \a parent must not be 0 and must be a parent
+ of \a parent. The \a parent must not be \nullptr and must be a parent
of the calling widget.
\sa mapFrom(), mapToParent(), mapToGlobal(), underMouse()
@@ -4259,7 +4262,7 @@ QPoint QWidget::mapTo(const QWidget * parent, const QPoint & pos) const
/*!
Translates the widget coordinate \a pos from the coordinate system
of \a parent to this widget's coordinate system. The \a parent
- must not be 0 and must be a parent of the calling widget.
+ must not be \nullptr and must be a parent of the calling widget.
\sa mapTo(), mapFromParent(), mapFromGlobal(), underMouse()
*/
@@ -4338,7 +4341,8 @@ QWidget *QWidget::window() const
\since 4.4
Returns the native parent for this widget, i.e. the next ancestor widget
- that has a system identifier, or 0 if it does not have any native parent.
+ that has a system identifier, or \nullptr if it does not have any native
+ parent.
\sa effectiveWinId()
*/
@@ -4959,9 +4963,9 @@ void QWidget::unsetLayoutDirection()
Some underlying window implementations will reset the cursor if it
leaves a widget even if the mouse is grabbed. If you want to have
a cursor set for all widgets, even when outside the window, consider
- QApplication::setOverrideCursor().
+ QGuiApplication::setOverrideCursor().
- \sa QApplication::setOverrideCursor()
+ \sa QGuiApplication::setOverrideCursor()
*/
#ifndef QT_NO_CURSOR
@@ -5274,7 +5278,7 @@ QPixmap QWidget::grab(const QRect &rectangle)
\brief The graphicsEffect function returns a pointer to the
widget's graphics effect.
- If the widget has no graphics effect, 0 is returned.
+ If the widget has no graphics effect, \nullptr is returned.
\since 4.6
@@ -5318,7 +5322,7 @@ void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
return;
if (d->graphicsEffect) {
- d->invalidateBuffer(rect());
+ d->invalidateBackingStore(rect());
delete d->graphicsEffect;
d->graphicsEffect = 0;
}
@@ -5738,12 +5742,10 @@ void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
QPoint offset = targetOffset;
offset -= paintRegion.boundingRect().topLeft();
QPoint redirectionOffset;
- QPaintDevice *redirected = 0;
+ QPaintDevice *redirected = nullptr;
if (target->devType() == QInternal::Widget)
redirected = static_cast<QWidget *>(target)->d_func()->redirected(&redirectionOffset);
- if (!redirected)
- redirected = QPainter::redirected(target, &redirectionOffset);
if (redirected) {
target = redirected;
@@ -5920,10 +5922,10 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
Finds the nearest widget embedded in a graphics proxy widget along the chain formed by this
widget and its ancestors. The search starts at \a origin (inclusive).
- If successful, the function returns the proxy that embeds the widget, or 0 if no embedded
- widget was found.
+ If successful, the function returns the proxy that embeds the widget, or \nullptr if no
+ embedded widget was found.
*/
-QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin)
+QGraphicsProxyWidget *QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin)
{
if (origin) {
QWExtra *extra = origin->d_func()->extra;
@@ -5931,7 +5933,7 @@ QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget
return extra->proxyWidget;
return nearestGraphicsProxyWidget(origin->parentWidget());
}
- return 0;
+ return nullptr;
}
#endif
@@ -6403,7 +6405,7 @@ void QWidget::setWindowRole(const QString &role)
/*!
- Sets the widget's focus proxy to widget \a w. If \a w is 0, the
+ Sets the widget's focus proxy to widget \a w. If \a w is \nullptr, the
function resets this widget to have no focus proxy.
Some widgets can "have focus", but create a child widget, such as
@@ -6436,15 +6438,15 @@ void QWidget::setFocusProxy(QWidget * w)
/*!
- Returns the focus proxy, or 0 if there is no focus proxy.
+ Returns the focus proxy, or \nullptr if there is no focus proxy.
\sa setFocusProxy()
*/
-QWidget * QWidget::focusProxy() const
+QWidget *QWidget::focusProxy() const
{
Q_D(const QWidget);
- return d->extra ? (QWidget *)d->extra->focus_proxy : 0;
+ return d->extra ? (QWidget *)d->extra->focus_proxy : nullptr;
}
@@ -7343,11 +7345,11 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
if (renderToTexture) {
QRegion updateRegion(q->geometry());
updateRegion += QRect(oldPos, olds);
- q->parentWidget()->d_func()->invalidateBuffer(updateRegion);
+ q->parentWidget()->d_func()->invalidateBackingStore(updateRegion);
} else if (isMove && !isResize) {
moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
} else {
- invalidateBuffer_resizeHelper(oldPos, olds);
+ invalidateBackingStore_resizeHelper(oldPos, olds);
}
}
}
@@ -8109,7 +8111,7 @@ void QWidgetPrivate::show_sys()
QWidgetWindow *window = windowHandle();
if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
- invalidateBuffer(q->rect());
+ invalidateBackingStore(q->rect());
q->setAttribute(Qt::WA_Mapped);
// add our window the modal window list (native dialogs)
if (window && q->isWindow()
@@ -8152,7 +8154,7 @@ void QWidgetPrivate::show_sys()
#ifndef QT_NO_CURSOR
qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show
#endif
- invalidateBuffer(q->rect());
+ invalidateBackingStore(q->rect());
window->setNativeWindowVisibility(true);
// Was the window moved by the Window system or QPlatformWindow::initialGeometry() ?
if (window->isTopLevel()) {
@@ -8266,12 +8268,12 @@ void QWidgetPrivate::hide_sys()
QWidget *p = q->parentWidget();
if (p &&p->isVisible()) {
if (renderToTexture)
- p->d_func()->invalidateBuffer(q->geometry());
+ p->d_func()->invalidateBackingStore(q->geometry());
else
- invalidateBuffer(q->rect());
+ invalidateBackingStore(q->rect());
}
} else {
- invalidateBuffer(q->rect());
+ invalidateBackingStore(q->rect());
}
if (window)
@@ -8825,7 +8827,7 @@ QSize QWidget::minimumSizeHint() const
/*!
\fn QWidget *QWidget::parentWidget() const
- Returns the parent of this widget, or 0 if it does not have any
+ Returns the parent of this widget, or \nullptr if it does not have any
parent widget.
*/
@@ -10235,7 +10237,7 @@ QRegion QWidget::mask() const
}
/*!
- Returns the layout manager that is installed on this widget, or 0
+ Returns the layout manager that is installed on this widget, or \nullptr
if no layout manager is installed.
The layout manager sets the geometry of the widget's children
@@ -11907,7 +11909,7 @@ void QWidget::raise()
QRegion region(rect());
d->subtractOpaqueSiblings(region);
- d->invalidateBuffer(region);
+ d->invalidateBackingStore(region);
}
if (testAttribute(Qt::WA_WState_Created))
d->raise_sys();
@@ -11927,7 +11929,7 @@ void QWidgetPrivate::raise_sys()
} else if (renderToTexture) {
if (QWidget *p = q->parentWidget()) {
setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+ p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry()));
}
}
}
@@ -11977,7 +11979,7 @@ void QWidgetPrivate::lower_sys()
q->windowHandle()->lower();
} else if (QWidget *p = q->parentWidget()) {
setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+ p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry()));
}
}
@@ -12021,7 +12023,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget*)
Q_Q(QWidget);
if (QWidget *p = q->parentWidget()) {
setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+ p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry()));
}
}
@@ -12123,14 +12125,14 @@ bool QWidgetPrivate::navigateToDirection(Direction direction)
Searches for a widget that is positioned in the \a direction, starting
from the current focusWidget.
- Returns the pointer to a found widget or 0, if there was no widget in
- that direction.
+ Returns the pointer to a found widget or \nullptr, if there was no widget
+ in that direction.
*/
QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction)
{
const QWidget *sourceWidget = QApplication::focusWidget();
if (!sourceWidget)
- return 0;
+ return nullptr;
const QRect sourceRect = sourceWidget->rect().translated(sourceWidget->mapToGlobal(QPoint()));
const int sourceX =
(direction == DirectionNorth || direction == DirectionSouth) ?
@@ -12144,7 +12146,7 @@ QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction)
const QPoint sourceCenter = sourceRect.center();
const QWidget *sourceWindow = sourceWidget->window();
- QWidget *targetWidget = 0;
+ QWidget *targetWidget = nullptr;
int shortestDistance = INT_MAX;
const auto targetCandidates = QApplication::allWidgets();
@@ -12463,7 +12465,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
d->aboutToDestroy();
if (!isWindow() && parentWidget())
- parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
+ parentWidget()->d_func()->invalidateBackingStore(d->effectiveRectFor(geometry()));
d->deactivateWidgetCleanup();
if ((windowType() == Qt::Popup) && qApp)
@@ -12811,7 +12813,7 @@ void QWidget::releaseKeyboard()
Returns the widget that is currently grabbing the mouse input.
If no widget in this application is currently grabbing the mouse,
- 0 is returned.
+ \nullptr is returned.
\sa grabMouse(), keyboardGrabber()
*/
@@ -12828,7 +12830,7 @@ QWidget *QWidget::mouseGrabber()
Returns the widget that is currently grabbing the keyboard input.
If no widget in this application is currently grabbing the
- keyboard, 0 is returned.
+ keyboard, \nullptr is returned.
\sa grabMouse(), mouseGrabber()
*/
diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h
index 9d5fe89c70..4e5ef5a111 100644
--- a/src/widgets/kernel/qwidget.h
+++ b/src/widgets/kernel/qwidget.h
@@ -235,7 +235,10 @@ public:
bool isEnabled() const;
bool isEnabledTo(const QWidget *) const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X ("Use isEnabled() instead")
bool isEnabledToTLW() const;
+#endif
public Q_SLOTS:
void setEnabled(bool);
@@ -769,8 +772,10 @@ inline bool QWidget::isEnabled() const
inline bool QWidget::isModal() const
{ return data->window_modality != Qt::NonModal; }
+#if QT_DEPRECATED_SINCE(5, 13)
inline bool QWidget::isEnabledToTLW() const
{ return isEnabled(); }
+#endif
inline int QWidget::minimumWidth() const
{ return minimumSize().width(); }
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 7e4ea2cc0c..797963b931 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -150,7 +150,7 @@ public:
}
private:
- Q_DISABLE_COPY(QWidgetBackingStoreTracker)
+ Q_DISABLE_COPY_MOVE(QWidgetBackingStoreTracker)
private:
QWidgetBackingStore* m_ptr;
@@ -402,6 +402,7 @@ public:
void setUpdatesEnabled_helper(bool );
+ bool updateBrushOrigin(QPainter *, const QBrush &brush) const;
void paintBackground(QPainter *, const QRegion &, int flags = DrawAsRoot) const;
bool isAboutToShow() const;
QRegion prepareToRender(const QRegion &region, QWidget::RenderFlags renderFlags);
@@ -451,10 +452,11 @@ public:
void scrollChildren(int dx, int dy);
void moveRect(const QRect &, int dx, int dy);
void scrollRect(const QRect &, int dx, int dy);
- void invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize);
- // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
- void invalidateBuffer(const QRegion &);
- void invalidateBuffer(const QRect &);
+ void invalidateBackingStore_resizeHelper(const QPoint &oldPos, const QSize &oldSize);
+
+ template <class T>
+ void invalidateBackingStore(const T &);
+
QRegion overlappedRegion(const QRect &rect, bool breakAfterFirst = false) const;
void syncBackingStore();
void syncBackingStore(const QRegion &region);
@@ -606,6 +608,11 @@ public:
return extra ? extra->nativeChildrenForced : false;
}
+ inline QRect effectiveRectFor(const QRegion &region) const
+ {
+ return effectiveRectFor(region.boundingRect());
+ }
+
inline QRect effectiveRectFor(const QRect &rect) const
{
#if QT_CONFIG(graphicseffect)
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index a32eb2a03b..0481dffda8 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -507,6 +507,9 @@ void QWidgetBackingStore::sendUpdateRequest(QWidget *widget, UpdateTime updateTi
}
}
+static inline QRect widgetRectFor(QWidget *, const QRect &r) { return r; }
+static inline QRect widgetRectFor(QWidget *widget, const QRegion &) { return widget->rect(); }
+
/*!
Marks the region of the widget as dirty (if not already marked as dirty) and
posts an UpdateRequest event to the top-level widget (if not already posted).
@@ -517,42 +520,44 @@ void QWidgetBackingStore::sendUpdateRequest(QWidget *widget, UpdateTime updateTi
If the widget paints directly on screen, the event is sent to the widget
instead of the top-level widget, and bufferState is completely ignored.
-
- ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
*/
-void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget,
- UpdateTime updateTime, BufferState bufferState)
+template <class T>
+void QWidgetBackingStore::markDirty(const T &r, QWidget *widget, UpdateTime updateTime, BufferState bufferState)
{
Q_ASSERT(tlw->d_func()->extra);
Q_ASSERT(tlw->d_func()->extra->topextra);
Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize);
Q_ASSERT(widget->isVisible() && widget->updatesEnabled());
Q_ASSERT(widget->window() == tlw);
- Q_ASSERT(!rgn.isEmpty());
+ Q_ASSERT(!r.isEmpty());
#if QT_CONFIG(graphicseffect)
widget->d_func()->invalidateGraphicsEffectsRecursively();
-#endif // QT_CONFIG(graphicseffect)
+#endif
+
+ QRect widgetRect = widgetRectFor(widget, r);
+
+ // ---------------------------------------------------------------------------
if (widget->d_func()->paintOnScreen()) {
if (widget->d_func()->dirty.isEmpty()) {
- widget->d_func()->dirty = rgn;
+ widget->d_func()->dirty = r;
sendUpdateRequest(widget, updateTime);
return;
- } else if (qt_region_strictContains(widget->d_func()->dirty, widget->rect())) {
+ } else if (qt_region_strictContains(widget->d_func()->dirty, widgetRect)) {
if (updateTime == UpdateNow)
sendUpdateRequest(widget, updateTime);
- return; // Already dirty.
+ return; // Already dirty
}
const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty();
- widget->d_func()->dirty += rgn;
+ widget->d_func()->dirty += r;
if (!eventAlreadyPosted || updateTime == UpdateNow)
sendUpdateRequest(widget, updateTime);
return;
}
- const QPoint offset = widget->mapTo(tlw, QPoint());
+ // ---------------------------------------------------------------------------
if (QWidgetPrivate::get(widget)->renderToTexture) {
if (!widget->d_func()->inDirtyList)
@@ -562,133 +567,67 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget,
return;
}
- const QRect widgetRect = widget->d_func()->effectiveRectFor(widget->rect());
- if (qt_region_strictContains(dirty, widgetRect.translated(offset))) {
+ // ---------------------------------------------------------------------------
+
+ QRect effectiveWidgetRect = widget->d_func()->effectiveRectFor(widgetRect);
+ const QPoint offset = widget->mapTo(tlw, QPoint());
+ QRect translatedRect = effectiveWidgetRect.translated(offset);
+#if QT_CONFIG(graphicseffect)
+ // Graphics effects may exceed window size, clamp
+ translatedRect = translatedRect.intersected(QRect(QPoint(), tlw->size()));
+#endif
+ if (qt_region_strictContains(dirty, translatedRect)) {
if (updateTime == UpdateNow)
sendUpdateRequest(tlw, updateTime);
- return; // Already dirty.
+ return; // Already dirty
}
+ // ---------------------------------------------------------------------------
+
if (bufferState == BufferInvalid) {
const bool eventAlreadyPosted = !dirty.isEmpty() || updateRequestSent;
#if QT_CONFIG(graphicseffect)
if (widget->d_func()->graphicsEffect)
- dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()).translated(offset);
+ dirty += widget->d_func()->effectiveRectFor(r).translated(offset);
else
-#endif // QT_CONFIG(graphicseffect)
- dirty += rgn.translated(offset);
+#endif
+ dirty += r.translated(offset);
+
if (!eventAlreadyPosted || updateTime == UpdateNow)
sendUpdateRequest(tlw, updateTime);
return;
}
+ // ---------------------------------------------------------------------------
+
if (dirtyWidgets.isEmpty()) {
- addDirtyWidget(widget, rgn);
+ addDirtyWidget(widget, r);
sendUpdateRequest(tlw, updateTime);
return;
}
+ // ---------------------------------------------------------------------------
+
if (widget->d_func()->inDirtyList) {
- if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) {
+ if (!qt_region_strictContains(widget->d_func()->dirty, effectiveWidgetRect)) {
#if QT_CONFIG(graphicseffect)
if (widget->d_func()->graphicsEffect)
- widget->d_func()->dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect());
+ widget->d_func()->dirty += widget->d_func()->effectiveRectFor(r);
else
-#endif // QT_CONFIG(graphicseffect)
- widget->d_func()->dirty += rgn;
+#endif
+ widget->d_func()->dirty += r;
}
} else {
- addDirtyWidget(widget, rgn);
- }
-
- if (updateTime == UpdateNow)
- sendUpdateRequest(tlw, updateTime);
-}
-
-/*!
- This function is equivalent to calling markDirty(QRegion(rect), ...), but
- is more efficient as it eliminates QRegion operations/allocations and can
- use the rect more precisely for additional cut-offs.
-
- ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
-*/
-void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget,
- UpdateTime updateTime, BufferState bufferState)
-{
- Q_ASSERT(tlw->d_func()->extra);
- Q_ASSERT(tlw->d_func()->extra->topextra);
- Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize);
- Q_ASSERT(widget->isVisible() && widget->updatesEnabled());
- Q_ASSERT(widget->window() == tlw);
- Q_ASSERT(!rect.isEmpty());
-
-#if QT_CONFIG(graphicseffect)
- widget->d_func()->invalidateGraphicsEffectsRecursively();
-#endif // QT_CONFIG(graphicseffect)
-
- if (widget->d_func()->paintOnScreen()) {
- if (widget->d_func()->dirty.isEmpty()) {
- widget->d_func()->dirty = QRegion(rect);
- sendUpdateRequest(widget, updateTime);
- return;
- } else if (qt_region_strictContains(widget->d_func()->dirty, rect)) {
- if (updateTime == UpdateNow)
- sendUpdateRequest(widget, updateTime);
- return; // Already dirty.
- }
-
- const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty();
- widget->d_func()->dirty += rect;
- if (!eventAlreadyPosted || updateTime == UpdateNow)
- sendUpdateRequest(widget, updateTime);
- return;
- }
-
- if (QWidgetPrivate::get(widget)->renderToTexture) {
- if (!widget->d_func()->inDirtyList)
- addDirtyRenderToTextureWidget(widget);
- if (!updateRequestSent || updateTime == UpdateNow)
- sendUpdateRequest(tlw, updateTime);
- return;
+ addDirtyWidget(widget, r);
}
-
- const QRect widgetRect = widget->d_func()->effectiveRectFor(rect);
- QRect translatedRect = widgetRect;
- if (widget != tlw)
- translatedRect.translate(widget->mapTo(tlw, QPoint()));
- // Graphics effects may exceed window size, clamp.
- translatedRect = translatedRect.intersected(QRect(QPoint(), tlw->size()));
- if (qt_region_strictContains(dirty, translatedRect)) {
- if (updateTime == UpdateNow)
- sendUpdateRequest(tlw, updateTime);
- return; // Already dirty
- }
-
- if (bufferState == BufferInvalid) {
- const bool eventAlreadyPosted = !dirty.isEmpty();
- dirty += translatedRect;
- if (!eventAlreadyPosted || updateTime == UpdateNow)
- sendUpdateRequest(tlw, updateTime);
- return;
- }
-
- if (dirtyWidgets.isEmpty()) {
- addDirtyWidget(widget, rect);
- sendUpdateRequest(tlw, updateTime);
- return;
- }
-
- if (widget->d_func()->inDirtyList) {
- if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect))
- widget->d_func()->dirty += widgetRect;
- } else {
- addDirtyWidget(widget, rect);
- }
+ // ---------------------------------------------------------------------------
if (updateTime == UpdateNow)
sendUpdateRequest(tlw, updateTime);
}
+template void QWidgetBackingStore::markDirty<QRect>(const QRect &, QWidget *, UpdateTime, BufferState);
+template void QWidgetBackingStore::markDirty<QRegion>(const QRegion &, QWidget *, UpdateTime, BufferState);
/*!
Marks the \a region of the \a widget as dirty on screen. The \a region will be copied from
@@ -859,11 +798,11 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
if (!extra || !extra->hasMask) {
parentR -= newRect;
} else {
- // invalidateBuffer() excludes anything outside the mask
+ // invalidateBackingStore() excludes anything outside the mask
parentR += newRect & clipR;
}
- pd->invalidateBuffer(parentR);
- invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft()));
+ pd->invalidateBackingStore(parentR);
+ invalidateBackingStore((newRect & clipR).translated(-data.crect.topLeft()));
} else {
QWidgetBackingStore *wbs = x->backingStoreTracker.data();
@@ -894,7 +833,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
if (childUpdatesEnabled) {
if (!overlappedExpose.isEmpty()) {
overlappedExpose.translate(-data.crect.topLeft());
- invalidateBuffer(overlappedExpose);
+ invalidateBackingStore(overlappedExpose);
}
if (!childExpose.isEmpty()) {
childExpose.translate(-data.crect.topLeft());
@@ -944,9 +883,9 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
if (!overlappedRegion(scrollRect.translated(data.crect.topLeft()), true).isEmpty()) {
QRegion region(scrollRect);
subtractOpaqueSiblings(region);
- invalidateBuffer(region);
+ invalidateBackingStore(region);
}else {
- invalidateBuffer(scrollRect);
+ invalidateBackingStore(scrollRect);
}
} else {
const QPoint toplevelOffset = q->mapTo(tlw, QPoint());
@@ -987,7 +926,7 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
return;
if (!overlappedExpose.isEmpty())
- invalidateBuffer(overlappedExpose);
+ invalidateBackingStore(overlappedExpose);
if (!childExpose.isEmpty()) {
wbs->markDirty(childExpose, q);
isScrolled = true;
@@ -1471,26 +1410,11 @@ void QWidgetBackingStore::flush(QWidget *widget)
dirtyOnScreenWidgets->clear();
}
-static inline bool discardInvalidateBufferRequest(QWidget *widget, QTLWExtra *tlwExtra)
-{
- Q_ASSERT(widget);
- if (QApplication::closingDown())
- return true;
-
- if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore)
- return true;
-
- if (!widget->isVisible() || !widget->updatesEnabled())
- return true;
-
- return false;
-}
-
/*!
- Invalidates the buffer when the widget is resized.
+ Invalidates the backing store when the widget is resized.
Static areas are never invalidated unless absolutely needed.
*/
-void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize)
+void QWidgetPrivate::invalidateBackingStore_resizeHelper(const QPoint &oldPos, const QSize &oldSize)
{
Q_Q(QWidget);
Q_ASSERT(!q->isWindow());
@@ -1515,10 +1439,10 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q
if (hasStaticChildren) {
QRegion dirty(newWidgetRect);
dirty -= staticChildren;
- invalidateBuffer(dirty);
+ invalidateBackingStore(dirty);
} else {
// Entire widget needs repaint.
- invalidateBuffer(newWidgetRect);
+ invalidateBackingStore(newWidgetRect);
}
if (!parentAreaExposed)
@@ -1530,14 +1454,14 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q
parentExpose &= QRect(oldPos, oldSize);
if (hasStaticChildren)
parentExpose -= data.crect; // Offset is unchanged, safe to do this.
- q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
+ q->parentWidget()->d_func()->invalidateBackingStore(parentExpose);
} else {
if (hasStaticChildren && !graphicsEffect) {
QRegion parentExpose(QRect(oldPos, oldSize));
parentExpose -= data.crect; // Offset is unchanged, safe to do this.
- q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
+ q->parentWidget()->d_func()->invalidateBackingStore(parentExpose);
} else {
- q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(QRect(oldPos, oldSize)));
+ q->parentWidget()->d_func()->invalidateBackingStore(effectiveRectFor(QRect(oldPos, oldSize)));
}
}
return;
@@ -1558,7 +1482,7 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q
if (!sizeDecreased || !oldWidgetRect.contains(newWidgetRect)) {
QRegion newVisible(newWidgetRect);
newVisible -= oldWidgetRect;
- invalidateBuffer(newVisible);
+ invalidateBackingStore(newVisible);
}
if (!parentAreaExposed)
@@ -1570,74 +1494,56 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q
QRegion parentExpose(oldRect);
parentExpose &= extra->mask.translated(oldPos);
parentExpose -= (extra->mask.translated(data.crect.topLeft()) & data.crect);
- q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
+ q->parentWidget()->d_func()->invalidateBackingStore(parentExpose);
} else {
QRegion parentExpose(oldRect);
parentExpose -= data.crect;
- q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
+ q->parentWidget()->d_func()->invalidateBackingStore(parentExpose);
}
}
/*!
- Invalidates the \a rgn (in widget's coordinates) of the backing store, i.e.
- all widgets intersecting with the region will be repainted when the backing store
- is synced.
-
- ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
+ Invalidates the \a r (in widget's coordinates) of the backing store, i.e.
+ all widgets intersecting with the region will be repainted when the backing
+ store is synced.
*/
-void QWidgetPrivate::invalidateBuffer(const QRegion &rgn)
+template <class T>
+void QWidgetPrivate::invalidateBackingStore(const T &r)
{
- Q_Q(QWidget);
-
- QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
- if (discardInvalidateBufferRequest(q, tlwExtra) || rgn.isEmpty())
+ if (r.isEmpty())
return;
- QRegion wrgn(rgn);
- wrgn &= clipRect();
- if (!graphicsEffect && extra && extra->hasMask)
- wrgn &= extra->mask;
- if (wrgn.isEmpty())
+ if (QApplication::closingDown())
return;
- tlwExtra->backingStoreTracker->markDirty(wrgn, q,
- QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid);
-}
-
-/*!
- This function is equivalent to calling invalidateBuffer(QRegion(rect), ...), but
- is more efficient as it eliminates QRegion operations/allocations and can
- use the rect more precisely for additional cut-offs.
-
- ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
-*/
-void QWidgetPrivate::invalidateBuffer(const QRect &rect)
-{
Q_Q(QWidget);
-
- QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
- if (discardInvalidateBufferRequest(q, tlwExtra) || rect.isEmpty())
+ if (!q->isVisible() || !q->updatesEnabled())
return;
- QRect wRect(rect);
- wRect &= clipRect();
- if (wRect.isEmpty())
+ QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
+ if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore)
return;
- if (graphicsEffect || !extra || !extra->hasMask) {
- tlwExtra->backingStoreTracker->markDirty(wRect, q,
- QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid);
+ T clipped(r);
+ clipped &= clipRect();
+ if (clipped.isEmpty())
return;
- }
- QRegion wRgn(extra->mask);
- wRgn &= wRect;
- if (wRgn.isEmpty())
- return;
+ if (!graphicsEffect && extra && extra->hasMask) {
+ QRegion masked(extra->mask);
+ masked &= clipped;
+ if (masked.isEmpty())
+ return;
- tlwExtra->backingStoreTracker->markDirty(wRgn, q,
+ tlwExtra->backingStoreTracker->markDirty(masked, q,
QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid);
+ } else {
+ tlwExtra->backingStoreTracker->markDirty(clipped, q,
+ QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid);
+ }
}
+// Needed by tst_QWidget
+template Q_AUTOTEST_EXPORT void QWidgetPrivate::invalidateBackingStore<QRect>(const QRect &r);
void QWidgetPrivate::repaint_sys(const QRegion &rgn)
{
diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h
index 53ccda850a..4d15ab138e 100644
--- a/src/widgets/kernel/qwidgetbackingstore_p.h
+++ b/src/widgets/kernel/qwidgetbackingstore_p.h
@@ -118,10 +118,8 @@ public:
return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && dirtyRenderToTextureWidgets.isEmpty());
}
- // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
- void markDirty(const QRegion &rgn, QWidget *widget, UpdateTime updateTime = UpdateLater,
- BufferState bufferState = BufferValid);
- void markDirty(const QRect &rect, QWidget *widget, UpdateTime updateTime = UpdateLater,
+ template <class T>
+ void markDirty(const T &r, QWidget *widget, UpdateTime updateTime = UpdateLater,
BufferState bufferState = BufferValid);
private:
@@ -305,7 +303,7 @@ private:
friend class QWidget;
friend class QBackingStore;
- Q_DISABLE_COPY(QWidgetBackingStore)
+ Q_DISABLE_COPY_MOVE(QWidgetBackingStore)
};
QT_END_NAMESPACE
diff --git a/src/widgets/statemachine/qbasickeyeventtransition_p.h b/src/widgets/statemachine/qbasickeyeventtransition_p.h
index 5007b79739..7e1b978bba 100644
--- a/src/widgets/statemachine/qbasickeyeventtransition_p.h
+++ b/src/widgets/statemachine/qbasickeyeventtransition_p.h
@@ -84,7 +84,7 @@ protected:
void onTransition(QEvent *) override;
private:
- Q_DISABLE_COPY(QBasicKeyEventTransition)
+ Q_DISABLE_COPY_MOVE(QBasicKeyEventTransition)
Q_DECLARE_PRIVATE(QBasicKeyEventTransition)
};
diff --git a/src/widgets/statemachine/qbasicmouseeventtransition_p.h b/src/widgets/statemachine/qbasicmouseeventtransition_p.h
index 93d2a5ec61..132e223535 100644
--- a/src/widgets/statemachine/qbasicmouseeventtransition_p.h
+++ b/src/widgets/statemachine/qbasicmouseeventtransition_p.h
@@ -87,7 +87,7 @@ protected:
void onTransition(QEvent *) override;
private:
- Q_DISABLE_COPY(QBasicMouseEventTransition)
+ Q_DISABLE_COPY_MOVE(QBasicMouseEventTransition)
Q_DECLARE_PRIVATE(QBasicMouseEventTransition)
};
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index c739ddc6e2..a3461d8848 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -100,6 +100,9 @@
#if QT_CONFIG(wizard)
#include <qwizard.h>
#endif
+#if QT_CONFIG(filedialog)
+#include <qsidebar_p.h>
+#endif
#include <qfileinfo.h>
#include <qdir.h>
#if QT_CONFIG(settings)
@@ -191,12 +194,12 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
opt->state & (State_Sunken | State_On), 1,
&opt->palette.brush(QPalette::Button));
break;
- case PE_IndicatorViewItemCheck:
+ case PE_IndicatorItemViewItemCheck:
proxy()->drawPrimitive(PE_IndicatorCheckBox, opt, p, widget);
break;
case PE_IndicatorCheckBox:
if (opt->state & State_NoChange) {
- p->setPen(opt->palette.foreground().color());
+ p->setPen(opt->palette.windowText().color());
p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
p->drawRect(opt->rect);
p->drawLine(opt->rect.topLeft(), opt->rect.bottomRight());
@@ -212,7 +215,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
p->drawArc(opt->rect, 0, 5760);
if (opt->state & (State_Sunken | State_On)) {
ir.adjust(2, 2, -2, -2);
- p->setBrush(opt->palette.foreground());
+ p->setBrush(opt->palette.windowText());
bool oldQt4CompatiblePainting = p->testRenderHint(QPainter::Qt4CompatiblePainting);
p->setRenderHint(QPainter::Qt4CompatiblePainting);
p->drawEllipse(ir);
@@ -231,7 +234,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
else
p->setPen(Qt::white);
} else {
- p->setPen(opt->palette.foreground().color());
+ p->setPen(opt->palette.windowText().color());
}
QRect focusRect = opt->rect.adjusted(1, 1, -1, -1);
p->drawRect(focusRect.adjusted(0, 0, -1, -1)); //draw pen inclusive
@@ -278,7 +281,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken,
frame->lineWidth);
} else {
- qDrawPlainRect(p, frame->rect, frame->palette.foreground().color(), frame->lineWidth);
+ qDrawPlainRect(p, frame->rect, frame->palette.windowText().color(), frame->lineWidth);
}
}
break;
@@ -615,7 +618,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
}
p->setPen(QPen(tab->palette.dark(), qreal(.8)));
- p->setBrush(tab->palette.background());
+ p->setBrush(tab->palette.window());
p->setRenderHint(QPainter::Antialiasing);
p->drawPath(path);
}
@@ -748,7 +751,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-")
% QLatin1String(metaObject()->className()), opt, QSize(size, size))
% HexString<uint>(pe);
- if (!QPixmapCache::find(pixmapName, pixmap)) {
+ if (!QPixmapCache::find(pixmapName, &pixmap)) {
qreal pixelRatio = p->device()->devicePixelRatioF();
int border = qRound(pixelRatio*(size/5));
int sqsize = qRound(pixelRatio*(2*(size/2)));
@@ -1249,8 +1252,9 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *w
// High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize
tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.height()));
- *iconRect = QRect(tr.left(), tr.center().y() - tabIconSize.height() / 2,
- tabIconSize.width(), tabIconSize.height());
+ const int offsetX = (iconSize.width() - tabIconSize.width()) / 2;
+ *iconRect = QRect(tr.left() + offsetX, tr.center().y() - tabIconSize.height() / 2,
+ tabIconSize.width(), tabIconSize.height());
if (!verticalTabs)
*iconRect = proxyStyle->visualRect(opt->direction, opt->rect, *iconRect);
tr.setLeft(tr.left() + tabIconSize.width() + 4);
@@ -1565,7 +1569,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
QPalette pal2 = pb->palette;
// Correct the highlight color if it is the same as the background
- if (pal2.highlight() == pal2.background())
+ if (pal2.highlight() == pal2.window())
pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
QPalette::Highlight));
bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
@@ -1853,14 +1857,14 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
}
}
- p->setPen(QPen(tab->palette.foreground(), 0));
+ p->setPen(QPen(tab->palette.windowText(), 0));
if (selected) {
p->setBrush(tab->palette.base());
} else {
if (widget && widget->parentWidget())
- p->setBrush(widget->parentWidget()->palette().background());
+ p->setBrush(widget->parentWidget()->palette().window());
else
- p->setBrush(tab->palette.background());
+ p->setBrush(tab->palette.window());
}
int y;
@@ -2157,7 +2161,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
const int indent = p->fontMetrics().descent();
proxy()->drawItemText(p, r.adjusted(indent + 1, 1, -indent - 1, -1),
- Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
+ Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette,
dwOpt->state & State_Enabled, dwOpt->title,
QPalette::WindowText);
@@ -2184,7 +2188,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
}
break;
case CE_FocusFrame:
- p->fillRect(opt->rect, opt->palette.foreground());
+ p->fillRect(opt->rect, opt->palette.windowText());
break;
case CE_HeaderSection:
qDrawShadePanel(p, opt->rect, opt->palette,
@@ -2192,7 +2196,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
&opt->palette.brush(QPalette::Button));
break;
case CE_HeaderEmptyArea:
- p->fillRect(opt->rect, opt->palette.background());
+ p->fillRect(opt->rect, opt->palette.window());
break;
#if QT_CONFIG(combobox)
case CE_ComboBoxLabel:
@@ -2296,7 +2300,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
option.state |= QStyle::State_On;
break;
}
- proxy()->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, p, widget);
+ proxy()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, p, widget);
}
// draw the icon
@@ -3137,7 +3141,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
}
d->cachedOption = new QStyleOptionViewItem(*vopt);
}
- if (sr == SE_ViewItemCheckIndicator)
+ if (sr == SE_ItemViewItemCheckIndicator)
r = d->checkRect;
else if (sr == SE_ItemViewItemDecoration)
r = d->decorationRect;
@@ -3153,13 +3157,17 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
///we need to access the widget here because the style option doesn't
//have all the information we need (ie. the layout's margin)
const QToolBar *tb = qobject_cast<const QToolBar*>(widget);
- const int margin = tb && tb->layout() ? tb->layout()->margin() : 2;
+ const QMargins margins = tb && tb->layout() ? tb->layout()->contentsMargins() : QMargins(2, 2, 2, 2);
const int handleExtent = proxy()->pixelMetric(QStyle::PM_ToolBarHandleExtent, opt, tb);
if (tbopt->state & QStyle::State_Horizontal) {
- r = QRect(margin, margin, handleExtent, tbopt->rect.height() - 2*margin);
+ r = QRect(margins.left(), margins.top(),
+ handleExtent,
+ tbopt->rect.height() - (margins.top() + margins.bottom()));
r = QStyle::visualRect(tbopt->direction, tbopt->rect, r);
} else {
- r = QRect(margin, margin, tbopt->rect.width() - 2*margin, handleExtent);
+ r = QRect(margins.left(), margins.top(),
+ tbopt->rect.width() - (margins.left() + margins.right()),
+ handleExtent);
}
}
}
@@ -3256,7 +3264,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl
// Since there is no subrect for tickmarks do a translation here.
p->save();
p->translate(slider->rect.x(), slider->rect.y());
- p->setPen(slider->palette.foreground().color());
+ p->setPen(slider->palette.windowText().color());
int v = slider->minimum;
while (v <= slider->maximum + 1) {
if (v == slider->maximum + 1 && interval == 1)
@@ -3702,7 +3710,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl
QPalette pal = opt->palette;
// draw notches
if (dial->subControls & QStyle::SC_DialTickmarks) {
- p->setPen(pal.foreground().color());
+ p->setPen(pal.windowText().color());
p->drawLines(QStyleHelper::calcLines(dial));
}
@@ -4359,8 +4367,10 @@ QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex
int topMargin = 0;
int topHeight = 0;
int verticalAlignment = proxy()->styleHint(SH_GroupBox_TextLabelVerticalAlignment, groupBox, widget);
- if (groupBox->text.size() || (groupBox->subControls & QStyle::SC_GroupBoxCheckBox)) {
- topHeight = groupBox->fontMetrics.height();
+ bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox;
+ if (groupBox->text.size() || hasCheckBox) {
+ int checkBoxHeight = hasCheckBox ? proxy()->pixelMetric(PM_IndicatorHeight, groupBox, widget) : 0;
+ topHeight = qMax(groupBox->fontMetrics.height(), checkBoxHeight);
if (verticalAlignment & Qt::AlignVCenter)
topMargin = topHeight / 2;
else if (verticalAlignment & Qt::AlignTop)
@@ -4385,20 +4395,24 @@ QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex
case SC_GroupBoxCheckBox:
case SC_GroupBoxLabel: {
QFontMetrics fontMetrics = groupBox->fontMetrics;
- int h = fontMetrics.height();
+ int th = fontMetrics.height();
int tw = fontMetrics.size(Qt::TextShowMnemonic, groupBox->text + QLatin1Char(' ')).width();
int marg = (groupBox->features & QStyleOptionFrame::Flat) ? 0 : 8;
ret = groupBox->rect.adjusted(marg, 0, -marg, 0);
- ret.setHeight(h);
int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, opt, widget);
+ int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, opt, widget);
int indicatorSpace = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, opt, widget) - 1;
bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox;
- int checkBoxSize = hasCheckBox ? (indicatorWidth + indicatorSpace) : 0;
+ int checkBoxWidth = hasCheckBox ? (indicatorWidth + indicatorSpace) : 0;
+ int checkBoxHeight = hasCheckBox ? indicatorHeight : 0;
+
+ int h = qMax(th, checkBoxHeight);
+ ret.setHeight(h);
// Adjusted rect for label + indicatorWidth + indicatorSpace
QRect totalRect = alignedRect(groupBox->direction, groupBox->textAlignment,
- QSize(tw + checkBoxSize, h), ret);
+ QSize(tw + checkBoxWidth, h), ret);
// Adjust totalRect if checkbox is set
if (hasCheckBox) {
@@ -4406,15 +4420,14 @@ QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex
int left = 0;
// Adjust for check box
if (sc == SC_GroupBoxCheckBox) {
- int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, opt, widget);
left = ltr ? totalRect.left() : (totalRect.right() - indicatorWidth);
- int top = totalRect.top() + qMax(0, fontMetrics.height() - indicatorHeight) / 2;
+ int top = totalRect.top() + (h - checkBoxHeight) / 2;
totalRect.setRect(left, top, indicatorWidth, indicatorHeight);
// Adjust for label
} else {
- left = ltr ? (totalRect.left() + checkBoxSize - 2) : totalRect.left();
- totalRect.setRect(left, totalRect.top(),
- totalRect.width() - checkBoxSize, totalRect.height());
+ left = ltr ? (totalRect.left() + checkBoxWidth - 2) : totalRect.left();
+ int top = totalRect.top() + (h - th) / 2;
+ totalRect.setRect(left, top, totalRect.width() - checkBoxWidth, th);
}
}
ret = totalRect;
@@ -4790,9 +4803,16 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
break;
case PM_TabBarIconSize:
- case PM_ListViewIconSize:
ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
break;
+ case PM_ListViewIconSize:
+#if QT_CONFIG(filedialog)
+ if (qobject_cast<const QSidebar *>(widget))
+ ret = int(QStyleHelper::dpiScaled(24.));
+ else
+#endif
+ ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
+ break;
case PM_ButtonIconSize:
case PM_SmallIconSize:
@@ -4972,8 +4992,8 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
break;
#if QT_CONFIG(groupbox)
case CT_GroupBox:
- if (const QGroupBox *grb = static_cast<const QGroupBox *>(widget))
- sz += QSize(!grb->isFlat() ? 16 : 0, 0);
+ if (const QStyleOptionGroupBox *styleOpt = qstyleoption_cast<const QStyleOptionGroupBox *>(opt))
+ sz += QSize(styleOpt->features.testFlag(QStyleOptionFrame::Flat) ? 0 : 16, 0);
break;
#endif // QT_CONFIG(groupbox)
case CT_MdiControls:
diff --git a/src/widgets/styles/qdrawutil.cpp b/src/widgets/styles/qdrawutil.cpp
index 299dbb9f82..d30b43a679 100644
--- a/src/widgets/styles/qdrawutil.cpp
+++ b/src/widgets/styles/qdrawutil.cpp
@@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE
namespace {
class PainterStateGuard {
- Q_DISABLE_COPY(PainterStateGuard)
+ Q_DISABLE_COPY_MOVE(PainterStateGuard)
public:
explicit PainterStateGuard(QPainter *p) : m_painter(p) {}
~PainterStateGuard()
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index c565932889..f3961b2a99 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -261,7 +261,7 @@ static void qt_fusion_draw_arrow(Qt::ArrowType type, QPainter *painter, const QS
QString cacheKey = QStyleHelper::uniqueName(QLatin1String("fusion-arrow"), option, rect.size())
% HexString<uint>(type)
% HexString<uint>(color.rgba());
- if (!QPixmapCache::find(cacheKey, cachePixmap)) {
+ if (!QPixmapCache::find(cacheKey, &cachePixmap)) {
cachePixmap = styleCachePixmap(rect.size());
cachePixmap.fill(Qt::transparent);
QPainter cachePainter(&cachePixmap);
@@ -539,7 +539,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
{
if (option->rect.width() <= 1 || option->rect.height() <= 1)
break;
- QColor arrowColor = option->palette.foreground().color();
+ QColor arrowColor = option->palette.windowText().color();
arrowColor.setAlpha(160);
Qt::ArrowType arrow = Qt::UpArrow;
switch (elem) {
@@ -558,7 +558,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
qt_fusion_draw_arrow(arrow, painter, option, option->rect, arrowColor);
}
break;
- case PE_IndicatorViewItemCheck:
+ case PE_IndicatorItemViewItemCheck:
{
QStyleOptionButton button;
button.QStyleOption::operator=(*option);
@@ -569,7 +569,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
case PE_IndicatorHeaderArrow:
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
QRect r = header->rect;
- QColor arrowColor = header->palette.foreground().color();
+ QColor arrowColor = header->palette.windowText().color();
arrowColor.setAlpha(180);
QPoint offset = QPoint(0, -2);
@@ -598,24 +598,24 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
const int margin = 6;
if (option->state & State_Horizontal) {
const int offset = rect.width()/2;
- painter->setPen(QPen(option->palette.background().color().darker(110)));
+ painter->setPen(QPen(option->palette.window().color().darker(110)));
painter->drawLine(rect.bottomLeft().x() + offset,
rect.bottomLeft().y() - margin,
rect.topLeft().x() + offset,
rect.topLeft().y() + margin);
- painter->setPen(QPen(option->palette.background().color().lighter(110)));
+ painter->setPen(QPen(option->palette.window().color().lighter(110)));
painter->drawLine(rect.bottomLeft().x() + offset + 1,
rect.bottomLeft().y() - margin,
rect.topLeft().x() + offset + 1,
rect.topLeft().y() + margin);
} else { //Draw vertical separator
const int offset = rect.height()/2;
- painter->setPen(QPen(option->palette.background().color().darker(110)));
+ painter->setPen(QPen(option->palette.window().color().darker(110)));
painter->drawLine(rect.topLeft().x() + margin ,
rect.topLeft().y() + offset,
rect.topRight().x() - margin,
rect.topRight().y() + offset);
- painter->setPen(QPen(option->palette.background().color().lighter(110)));
+ painter->setPen(QPen(option->palette.window().color().lighter(110)));
painter->drawLine(rect.topLeft().x() + margin ,
rect.topLeft().y() + offset + 1,
rect.topRight().x() - margin,
@@ -642,8 +642,8 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
{
painter->setPen(QPen(outline));
painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
- QColor frameLight = option->palette.background().color().lighter(160);
- QColor frameShadow = option->palette.background().color().darker(110);
+ QColor frameLight = option->palette.window().color().lighter(160);
+ QColor frameShadow = option->palette.window().color().darker(110);
//paint beveleffect
QRect frame = option->rect.adjusted(1, 1, -1, -1);
@@ -661,14 +661,14 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
painter->save();
{
- QColor softshadow = option->palette.background().color().darker(120);
+ QColor softshadow = option->palette.window().color().darker(120);
QRect rect= option->rect;
painter->setPen(softshadow);
painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
painter->setPen(QPen(option->palette.light(), 1));
painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), QPoint(rect.left() + 1, rect.bottom() - 1));
- painter->setPen(QPen(option->palette.background().color().darker(120)));
+ painter->setPen(QPen(option->palette.window().color().darker(120)));
painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), QPoint(rect.right() - 2, rect.bottom() - 1));
painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), QPoint(rect.right() - 1, rect.bottom() - 1));
@@ -704,7 +704,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
painter->setPen(QPen(option->palette.light(), 1));
painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
QPoint(rect.left() + 1, rect.bottom() - 1));
- painter->setPen(QPen(option->palette.background().color().darker(120)));
+ painter->setPen(QPen(option->palette.window().color().darker(120)));
painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1),
QPoint(rect.right() - 2, rect.bottom() - 1));
painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1),
@@ -748,7 +748,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
painter->translate(0.5, 0.5);
rect = rect.adjusted(0, 0, -1, -1);
- QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.foreground().color(), 85);
+ QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85);
painter->setBrush(Qt::NoBrush);
// Gradient fill
@@ -802,14 +802,14 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
case PE_IndicatorRadioButton:
painter->save();
{
- QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.foreground().color(), 85);
+ QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85);
painter->setBrush((state & State_Sunken) ? pressedColor : option->palette.base().color());
painter->setRenderHint(QPainter::Antialiasing, true);
QPainterPath circle;
const QPointF circleCenter = rect.center() + QPoint(1, 1);
const qreal outlineRadius = (rect.width() + (rect.width() + 1) % 2) / 2.0 - 1;
circle.addEllipse(circleCenter, outlineRadius, outlineRadius);
- painter->setPen(QPen(option->palette.background().color().darker(150)));
+ painter->setPen(QPen(option->palette.window().color().darker(150)));
if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange)
painter->setPen(QPen(highlightedOutline));
painter->drawPath(circle);
@@ -991,7 +991,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
case PE_PanelMenu: {
painter->save();
const QBrush menuBackground = option->palette.base().color().lighter(108);
- QColor borderColor = option->palette.background().color().darker(160);
+ QColor borderColor = option->palette.window().color().darker(160);
qDrawPlainRect(painter, option->rect, borderColor, 1, &menuBackground);
painter->restore();
}
@@ -1256,7 +1256,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
Qt::ElideRight, titleRect.width());
proxy()->drawItemText(painter,
titleRect,
- Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
+ Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette,
dwOpt->state & State_Enabled, titleText,
QPalette::WindowText);
}
@@ -1272,7 +1272,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
pixmapName += QString::number(- int(header->orientation));
QPixmap cache;
- if (!QPixmapCache::find(pixmapName, cache)) {
+ if (!QPixmapCache::find(pixmapName, &cache)) {
cache = styleCachePixmap(rect.size());
cache.fill(Qt::transparent);
QRect pixmapRect(0, 0, rect.width(), rect.height());
@@ -1283,8 +1283,8 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
gradientStopColor = buttonColor.darker(102);
QLinearGradient gradient(pixmapRect.topLeft(), pixmapRect.bottomLeft());
- if (option->palette.background().gradient()) {
- gradient.setStops(option->palette.background().gradient()->stops());
+ if (option->palette.window().gradient()) {
+ gradient.setStops(option->palette.window().gradient()->stops());
} else {
QColor midColor1 = mergedColors(gradientStartColor, gradientStopColor, 60);
QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 40);
@@ -1519,7 +1519,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
proxy()->drawItemText(painter, item.rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
} else {
- QColor shadow = mergedColors(option->palette.background().color().darker(120),
+ QColor shadow = mergedColors(option->palette.window().color().darker(120),
outline.lighter(140), 60);
painter->setPen(QPen(shadow));
painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
@@ -1649,7 +1649,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
if (!ignoreCheckMark && checkable && checked) {
QStyleOption opt = *option;
if (act) {
- QColor activeColor = mergedColors(option->palette.background().color(),
+ QColor activeColor = mergedColors(option->palette.window().color(),
option->palette.highlight().color());
opt.palette.setBrush(QPalette::Button, activeColor);
}
@@ -1731,7 +1731,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
newMI.rect = vSubMenuRect;
newMI.state = !enabled ? State_None : State_Enabled;
if (selected)
- newMI.palette.setColor(QPalette::Foreground,
+ newMI.palette.setColor(QPalette::WindowText,
newMI.palette.highlightedText().color());
proxy()->drawPrimitive(arrow, &newMI, painter, widget);
}
@@ -1812,7 +1812,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
painter->save();
{
painter->fillRect(rect, option->palette.window());
- QColor shadow = mergedColors(option->palette.background().color().darker(120),
+ QColor shadow = mergedColors(option->palette.window().color().darker(120),
outline.lighter(140), 60);
painter->setPen(QPen(shadow));
painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
@@ -1975,7 +1975,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
// ### backgroundrole/foregroundrole should be part of the style option
alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), outline);
} else {
- alphaCornerColor = mergedColors(option->palette.background().color(), outline);
+ alphaCornerColor = mergedColors(option->palette.window().color(), outline);
}
switch (control) {
@@ -2030,7 +2030,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
QPixmap cache;
QString pixmapName = QStyleHelper::uniqueName(QLatin1String("spinbox"), spinBox, spinBox->rect.size());
- if (!QPixmapCache::find(pixmapName, cache)) {
+ if (!QPixmapCache::find(pixmapName, &cache)) {
cache = styleCachePixmap(spinBox->rect.size());
cache.fill(Qt::transparent);
@@ -2039,7 +2039,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
QRect rect = pixmapRect;
QRect r = rect.adjusted(0, 1, 0, -1);
QPainter cachePainter(&cache);
- QColor arrowColor = spinBox->palette.foreground().color();
+ QColor arrowColor = spinBox->palette.windowText().color();
arrowColor.setAlpha(160);
bool isEnabled = (spinBox->state & State_Enabled);
@@ -2174,13 +2174,13 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
QColor highlight = option->palette.highlight().color();
QColor titleBarFrameBorder(active ? highlight.darker(180): outline.darker(110));
- QColor titleBarHighlight(active ? highlight.lighter(120): palette.background().color().lighter(120));
+ QColor titleBarHighlight(active ? highlight.lighter(120): palette.window().color().lighter(120));
QColor textColor(active ? 0xffffff : 0xff000000);
QColor textAlphaColor(active ? 0xffffff : 0xff000000 );
{
// Fill title bar gradient
- QColor titlebarColor = QColor(active ? highlight: palette.background().color());
+ QColor titlebarColor = QColor(active ? highlight: palette.window().color());
QLinearGradient gradient(option->rect.center().x(), option->rect.top(),
option->rect.center().x(), option->rect.bottom());
@@ -2531,7 +2531,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
QColor alphaOutline = outline;
alphaOutline.setAlpha(180);
- QColor arrowColor = option->palette.foreground().color();
+ QColor arrowColor = option->palette.windowText().color();
arrowColor.setAlpha(160);
const QColor bgColor = QStyleHelper::backgroundColor(option->palette, widget);
@@ -2745,7 +2745,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
if (!comboBox->frame)
pixmapName += QLatin1String("-frameless");
- if (!QPixmapCache::find(pixmapName, cache)) {
+ if (!QPixmapCache::find(pixmapName, &cache)) {
cache = styleCachePixmap(comboBox->rect.size());
cache.fill(Qt::transparent);
QPainter cachePainter(&cache);
@@ -2852,7 +2852,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
QRect pixmapRect(0, 0, groove.width(), groove.height());
// draw background groove
- if (!QPixmapCache::find(groovePixmapName, cache)) {
+ if (!QPixmapCache::find(groovePixmapName, &cache)) {
cache = styleCachePixmap(pixmapRect.size());
cache.fill(Qt::transparent);
QPainter groovePainter(&cache);
@@ -2880,7 +2880,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
// draw blue groove highlight
QRect clipRect;
groovePixmapName += QLatin1String("_blue");
- if (!QPixmapCache::find(groovePixmapName, cache)) {
+ if (!QPixmapCache::find(groovePixmapName, &cache)) {
cache = styleCachePixmap(pixmapRect.size());
cache.fill(Qt::transparent);
QPainter groovePainter(&cache);
@@ -2987,7 +2987,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
// draw handle
if ((option->subControls & SC_SliderHandle) ) {
QString handlePixmapName = QStyleHelper::uniqueName(QLatin1String("slider_handle"), option, handle.size());
- if (!QPixmapCache::find(handlePixmapName, cache)) {
+ if (!QPixmapCache::find(handlePixmapName, &cache)) {
cache = styleCachePixmap(handle.size());
cache.fill(Qt::transparent);
QRect pixmapRect(0, 0, handle.width(), handle.height());
@@ -3225,7 +3225,7 @@ QSize QFusionStyle::sizeFromContents(ContentsType type, const QStyleOption *opti
QFont fontBold = menuItem->font;
fontBold.setBold(true);
QFontMetrics fmBold(fontBold);
- w += fmBold.width(menuItem->text) - fm.horizontalAdvance(menuItem->text);
+ w += fmBold.horizontalAdvance(menuItem->text) - fm.horizontalAdvance(menuItem->text);
}
const int checkcol = qMax<int>(maxpmw, QStyleHelper::dpiScaled(QFusionStylePrivate::menuCheckMarkWidth)); // Windows always shows a check column
w += checkcol;
@@ -3673,7 +3673,7 @@ int QFusionStyle::styleHint(StyleHint hint, const QStyleOption *option, const QW
case SH_FontDialog_SelectAssociatedText:
case SH_MenuBar_AltKeyNavigation:
case SH_ComboBox_ListMouseTracking:
- case SH_ScrollBar_StopMouseOverSlider:
+ case SH_Slider_StopMouseOverSlider:
case SH_ScrollBar_MiddleClickAbsolutePosition:
case SH_EtchDisabledText:
case SH_TitleBar_AutoRaise:
@@ -3705,7 +3705,7 @@ int QFusionStyle::styleHint(StyleHint hint, const QStyleOption *option, const QW
return 0;
case SH_Table_GridLineColor:
- return option ? option->palette.background().color().darker(120).rgb() : 0;
+ return option ? option->palette.window().color().darker(120).rgb() : 0;
case SH_MessageBox_TextInteractionFlags:
return Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse;
diff --git a/src/widgets/styles/qfusionstyle_p_p.h b/src/widgets/styles/qfusionstyle_p_p.h
index 169fd9a407..a92041fcfe 100644
--- a/src/widgets/styles/qfusionstyle_p_p.h
+++ b/src/widgets/styles/qfusionstyle_p_p.h
@@ -113,7 +113,7 @@ public:
QColor outline(const QPalette &pal) const {
if (pal.window().style() == Qt::TexturePattern)
return QColor(0, 0, 0, 160);
- return pal.background().color().darker(140);
+ return pal.window().color().darker(140);
}
QColor highlightedOutline(const QPalette &pal) const {
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index 9192dae864..5ee37bd8e9 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -141,8 +141,10 @@ public:
PE_FrameGroupBox,
PE_FrameLineEdit,
PE_FrameMenu,
- PE_FrameStatusBar, // ### Qt 6: remove
- PE_FrameStatusBarItem = PE_FrameStatusBar,
+ PE_FrameStatusBarItem,
+#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove
+ PE_FrameStatusBar Q_DECL_ENUMERATOR_DEPRECATED = PE_FrameStatusBarItem,
+#endif
PE_FrameTabWidget,
PE_FrameWindow,
PE_FrameButtonBevel,
@@ -162,8 +164,10 @@ public:
PE_IndicatorArrowUp,
PE_IndicatorBranch,
PE_IndicatorButtonDropDown,
- PE_IndicatorViewItemCheck, // ### Qt 6: remove
- PE_IndicatorItemViewItemCheck = PE_IndicatorViewItemCheck,
+ PE_IndicatorItemViewItemCheck,
+#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove
+ PE_IndicatorViewItemCheck Q_DECL_ENUMERATOR_DEPRECATED = PE_IndicatorItemViewItemCheck,
+#endif
PE_IndicatorCheckBox,
PE_IndicatorDockWidgetResizeHandle,
PE_IndicatorHeaderArrow,
@@ -308,9 +312,10 @@ public:
SE_TabWidgetLeftCorner,
SE_TabWidgetRightCorner,
- SE_ViewItemCheckIndicator, // ### Qt 6: remove
- SE_ItemViewItemCheckIndicator = SE_ViewItemCheckIndicator,
-
+ SE_ItemViewItemCheckIndicator,
+#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove
+ SE_ViewItemCheckIndicator Q_DECL_ENUMERATOR_DEPRECATED = SE_ItemViewItemCheckIndicator,
+#endif
SE_TabBarTearIndicator,
SE_TabBarTearIndicatorLeft = SE_TabBarTearIndicator,
@@ -506,9 +511,11 @@ public:
PM_DialogButtonsButtonHeight,
PM_MdiSubWindowFrameWidth,
- PM_MDIFrameWidth = PM_MdiSubWindowFrameWidth, // ### Qt 6: remove
PM_MdiSubWindowMinimizedWidth,
- PM_MDIMinimizedWidth = PM_MdiSubWindowMinimizedWidth, // ### Qt 6: remove
+#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove
+ PM_MDIFrameWidth Q_DECL_ENUMERATOR_DEPRECATED = PM_MdiSubWindowFrameWidth,
+ PM_MDIMinimizedWidth Q_DECL_ENUMERATOR_DEPRECATED = PM_MdiSubWindowMinimizedWidth,
+#endif
PM_HeaderMargin,
PM_HeaderMarkSize,
@@ -649,7 +656,9 @@ public:
SH_ComboBox_Popup,
SH_TitleBar_NoBorder,
SH_Slider_StopMouseOverSlider,
- SH_ScrollBar_StopMouseOverSlider = SH_Slider_StopMouseOverSlider, // ### Qt 6: remove
+#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove
+ SH_ScrollBar_StopMouseOverSlider Q_DECL_ENUMERATOR_DEPRECATED = SH_Slider_StopMouseOverSlider,
+#endif
SH_BlinkCursorWhenTextSelected,
SH_RichText_FullWidthSelection,
SH_Menu_Scrollable,
diff --git a/src/widgets/styles/qstyle_p.h b/src/widgets/styles/qstyle_p.h
index 94e4540d0b..cdea29f944 100644
--- a/src/widgets/styles/qstyle_p.h
+++ b/src/widgets/styles/qstyle_p.h
@@ -96,7 +96,7 @@ inline QPixmap styleCachePixmap(const QSize &size)
int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \
bool doPixmapCache = (!option->rect.isEmpty()) \
&& ((txType <= QTransform::TxTranslate) || (painter->deviceTransform().type() == QTransform::TxScale)); \
- if (doPixmapCache && QPixmapCache::find(unique, internalPixmapCache)) { \
+ if (doPixmapCache && QPixmapCache::find(unique, &internalPixmapCache)) { \
painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
} else { \
if (doPixmapCache) { \
diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index 97631a5841..88031a9f1e 100644
--- a/src/widgets/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -3270,7 +3270,7 @@ QStyleOptionViewItem::QStyleOptionViewItem(int version)
\fn template <typename T> T qstyleoption_cast<T>(const QStyleOption *option)
\relates QStyleOption
- Returns a T or 0 depending on the \l{QStyleOption::type}{type} and
+ Returns a T or \nullptr depending on the \l{QStyleOption::type}{type} and
\l{QStyleOption::version}{version} of the given \a option.
Example:
@@ -3285,7 +3285,7 @@ QStyleOptionViewItem::QStyleOptionViewItem(int version)
\overload
\relates QStyleOption
- Returns a T or 0 depending on the type of the given \a option.
+ Returns a T or \nullptr depending on the type of the given \a option.
*/
#if QT_CONFIG(tabwidget)
@@ -4006,7 +4006,7 @@ QStyleHintReturnVariant::~QStyleHintReturnVariant()
\fn template <typename T> T qstyleoption_cast<T>(const QStyleHintReturn *hint)
\relates QStyleHintReturn
- Returns a T or 0 depending on the \l{QStyleHintReturn::type}{type}
+ Returns a T or \nullptr depending on the \l{QStyleHintReturn::type}{type}
and \l{QStyleHintReturn::version}{version} of \a hint.
Example:
@@ -4021,7 +4021,7 @@ QStyleHintReturnVariant::~QStyleHintReturnVariant()
\overload
\relates QStyleHintReturn
- Returns a T or 0 depending on the type of \a hint.
+ Returns a T or \nullptr depending on the type of \a hint.
*/
#if !defined(QT_NO_DEBUG_STREAM)
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index 73b147e622..9a3d938d25 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -44,6 +44,7 @@
#include "private/qcssutil_p.h"
#include <qdebug.h>
+#include <qdir.h>
#include <qapplication.h>
#if QT_CONFIG(menu)
#include <qmenu.h>
@@ -957,8 +958,10 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject
origin = Origin_Padding;
Origin clip = Origin_Border;
if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip)) {
- bg = new QStyleSheetBackgroundData(brush, QStyleSheetStyle::loadPixmap(uri, object),
- repeat, alignment, origin, attachment, clip);
+ QPixmap pixmap = QStyleSheetStyle::loadPixmap(uri, object);
+ if (!uri.isEmpty() && pixmap.isNull())
+ qWarning("Could not create pixmap from %s", qPrintable(QDir::toNativeSeparators(uri)));
+ bg = new QStyleSheetBackgroundData(brush, pixmap, repeat, alignment, origin, attachment, clip);
}
QBrush sfg, fg;
@@ -3243,8 +3246,8 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
#if QT_CONFIG(scrollbar)
case CC_ScrollBar:
if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- QStyleOptionSlider sbOpt(*sb);
if (!rule.hasDrawable()) {
+ QStyleOptionSlider sbOpt(*sb);
sbOpt.rect = rule.borderRect(opt->rect);
rule.drawBackgroundImage(p, opt->rect);
baseStyle()->drawComplexControl(cc, &sbOpt, p, w);
@@ -4222,7 +4225,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, r.width());
drawItemText(p, r,
- alignment | Qt::TextShowMnemonic, dwOpt->palette,
+ alignment, dwOpt->palette,
dwOpt->state & State_Enabled, titleText,
QPalette::WindowText);
@@ -4296,7 +4299,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
switch (pe) {
- case PE_FrameStatusBar: {
+ case PE_FrameStatusBarItem: {
QRenderRule subRule = renderRule(w ? w->parentWidget() : nullptr, opt, PseudoElement_Item);
if (subRule.hasDrawable()) {
subRule.drawRule(p, opt->rect);
@@ -4317,7 +4320,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
pseudoElement = PseudoElement_ExclusiveIndicator;
break;
- case PE_IndicatorViewItemCheck:
+ case PE_IndicatorItemViewItemCheck:
pseudoElement = PseudoElement_ViewItemIndicator;
break;
@@ -5087,10 +5090,11 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
QRenderRule subRule = renderRule(w, opt, pe);
if ((pe == PseudoElement_MenuSeparator) && subRule.hasContentsSize()) {
return QSize(sz.width(), subRule.size().height());
- } else if ((pe == PseudoElement_Item) && (subRule.hasBox() || subRule.hasBorder())) {
- int width = csz.width();
+ }
+ if ((pe == PseudoElement_Item) && (subRule.hasBox() || subRule.hasBorder() || subRule.hasFont)) {
+ QSize sz(csz);
if (mi->text.contains(QLatin1Char('\t')))
- width += 12; //as in QCommonStyle
+ sz.rwidth() += 12; //as in QCommonStyle
bool checkable = mi->checkType != QStyleOptionMenuItem::NotCheckable;
int checkableWidth = 0;
if (checkable) {
@@ -5100,15 +5104,20 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
}
if (!mi->icon.isNull()) {
QPixmap pixmap = mi->icon.pixmap(pixelMetric(PM_SmallIconSize));
- width += pixmap.width();
+ sz.rwidth() += pixmap.width();
+ }
+ if (subRule.hasFont) {
+ QFontMetrics fm(subRule.font);
+ const QRect r = fm.boundingRect(QRect(), Qt::TextSingleLine | Qt::TextShowMnemonic, mi->text);
+ sz = sz.expandedTo(r.size());
}
// padding overrules it all
if (!subRule.hasBox() || subRule.box()->paddings[LeftEdge] == 0) {
- width += checkableWidth;
+ sz.rwidth() += checkableWidth;
if (!mi->icon.isNull() || !checkable)
- width += mi->maxIconWidth;
+ sz.rwidth() += mi->maxIconWidth;
}
- return subRule.boxSize(subRule.adjustSize(QSize(width, csz.height())));
+ return subRule.boxSize(subRule.adjustSize(sz));
}
}
break;
@@ -5779,11 +5788,10 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c
case SE_PushButtonContents:
case SE_PushButtonFocusRect:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- QStyleOptionButton btnOpt(*btn);
if (rule.hasBox() || !rule.hasNativeBorder())
return visualRect(opt->direction, opt->rect, rule.contentsRect(opt->rect));
- return rule.baseStyleCanDraw() ? baseStyle()->subElementRect(se, &btnOpt, w)
- : QWindowsStyle::subElementRect(se, &btnOpt, w);
+ return rule.baseStyleCanDraw() ? baseStyle()->subElementRect(se, btn, w)
+ : QWindowsStyle::subElementRect(se, btn, w);
}
break;
@@ -5838,7 +5846,7 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c
return ParentStyle::subElementRect(se, opt, w);
#if QT_CONFIG(itemviews)
- case SE_ViewItemCheckIndicator:
+ case SE_ItemViewItemCheckIndicator:
if (!qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
return subElementRect(SE_CheckBoxIndicator, opt, w);
}
diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h
index d4edb83525..9c4b87fc32 100644
--- a/src/widgets/styles/qstylesheetstyle_p.h
+++ b/src/widgets/styles/qstylesheetstyle_p.h
@@ -173,7 +173,7 @@ public:
static int numinstances;
private:
- Q_DISABLE_COPY(QStyleSheetStyle)
+ Q_DISABLE_COPY_MOVE(QStyleSheetStyle)
Q_DECLARE_PRIVATE(QStyleSheetStyle)
};
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index 12ca5201c1..4e450813cb 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -248,7 +248,7 @@ void QWindowsStyle::polish(QApplication *app)
d->activeGradientCaptionColor = app->palette().highlight() .color();
d->inactiveCaptionColor = app->palette().dark().color();
d->inactiveGradientCaptionColor = app->palette().dark().color();
- d->inactiveCaptionText = app->palette().background().color();
+ d->inactiveCaptionText = app->palette().window().color();
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) //fetch native title bar colors
if(app->desktopSettingsAware()){
@@ -554,7 +554,7 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid
case SH_MenuBar_MouseTracking:
case SH_Menu_MouseTracking:
case SH_ComboBox_ListMouseTracking:
- case SH_ScrollBar_StopMouseOverSlider:
+ case SH_Slider_StopMouseOverSlider:
case SH_MainWindow_SpaceBelowMenuBar:
ret = 1;
@@ -817,7 +817,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
else if (opt->state & State_Enabled)
fill = opt->palette.base();
else
- fill = opt->palette.background();
+ fill = opt->palette.window();
p->save();
doRestore = true;
qDrawWinPanel(p, opt->rect, opt->palette, true, &fill);
@@ -827,13 +827,13 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
p->setPen(opt->palette.text().color());
}
Q_FALLTHROUGH();
- case PE_IndicatorViewItemCheck:
+ case PE_IndicatorItemViewItemCheck:
if (!doRestore) {
p->save();
doRestore = true;
}
#if QT_CONFIG(itemviews)
- if (pe == PE_IndicatorViewItemCheck) {
+ if (pe == PE_IndicatorItemViewItemCheck) {
const QStyleOptionViewItem *itemViewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt);
p->setPen(itemViewOpt
&& itemViewOpt->showDecorationSelected
@@ -951,14 +951,14 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
if (frame->lineWidth == 2 || pe == PE_Frame) {
QPalette popupPal = frame->palette;
if (pe == PE_FrameMenu) {
- popupPal.setColor(QPalette::Light, frame->palette.background().color());
+ popupPal.setColor(QPalette::Light, frame->palette.window().color());
popupPal.setColor(QPalette::Midlight, frame->palette.light().color());
}
if (pe == PE_Frame && (frame->state & State_Raised))
qDrawWinButton(p, frame->rect, popupPal, frame->state & State_Sunken);
else if (pe == PE_Frame && (frame->state & State_Sunken))
{
- popupPal.setColor(QPalette::Midlight, frame->palette.background().color());
+ popupPal.setColor(QPalette::Midlight, frame->palette.window().color());
qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken);
}
else
@@ -968,7 +968,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
}
} else {
QPalette popupPal = opt->palette;
- popupPal.setColor(QPalette::Light, opt->palette.background().color());
+ popupPal.setColor(QPalette::Light, opt->palette.window().color());
popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
}
@@ -996,7 +996,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
break; }
case PE_FrameWindow: {
QPalette popupPal = opt->palette;
- popupPal.setColor(QPalette::Light, opt->palette.background().color());
+ popupPal.setColor(QPalette::Light, opt->palette.window().color());
popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
break; }
@@ -1315,12 +1315,12 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
x2 -= onlyOne || lastTab ? borderThinkness : 0;
}
- p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.background());
+ p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.window());
// Delete border
if (selected) {
- p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.background());
- p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.background());
+ p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.window());
+ p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.window());
}
// Left
if (firstTab || selected || onlyOne || !previousSelected) {
@@ -1351,12 +1351,12 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
x2 -= lastTab ? borderThinkness : 0;
}
- p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
+ p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window());
// Delete border
if (selected) {
- p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.background());
- p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.background());
+ p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.window());
+ p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.window());
}
// Left
if (firstTab || selected || onlyOne || !previousSelected) {
@@ -1389,12 +1389,12 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
y2 -= lastTab ? borderThinkness : 0;
}
- p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.background());
+ p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.window());
// Delete border
if (selected) {
- p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.background());
- p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.background());
+ p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.window());
+ p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.window());
}
// Top
if (firstTab || selected || onlyOne || !previousSelected) {
@@ -1427,12 +1427,12 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
y2 -= lastTab ? borderThinkness : 0;
}
- p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
+ p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window());
// Delete border
if (selected) {
- p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.background());
- p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.background());
+ p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.window());
+ p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.window());
}
// Top
if (firstTab || selected || onlyOne || !previousSelected) {
@@ -1526,7 +1526,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
br = QBrush(paletteBrush.textureImage());
} else
br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
- p->setBackground(opt->palette.background().color());
+ p->setBackground(opt->palette.window().color());
p->setBrush(br);
}
p->drawRect(opt->rect);
@@ -1693,7 +1693,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
}
QPalette pal2 = pb->palette;
// Correct the highlight color if it is the same as the background
- if (pal2.highlight() == pal2.background())
+ if (pal2.highlight() == pal2.window())
pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
QPalette::Highlight));
bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
@@ -1825,7 +1825,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
titleRect.height(), titleRect.width());
}
proxy()->drawItemText(p, titleRect,
- Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, palette,
+ Qt::AlignLeft | Qt::AlignVCenter, palette,
dwOpt->state & State_Enabled, dwOpt->title,
floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText);
p->setFont(oldFont);
@@ -1843,7 +1843,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
p->setBackground(cb->palette.highlight());
} else {
p->setPen(cb->palette.text().color());
- p->setBackground(cb->palette.background());
+ p->setBackground(cb->palette.window());
}
}
QCommonStyle::drawControl(ce, opt, p, widget);
@@ -2185,7 +2185,7 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp
} else {
p->setPen(cmb->palette.text().color());
- p->setBackground(cmb->palette.background());
+ p->setBackground(cmb->palette.window());
}
if (cmb->state & State_HasFocus && !cmb->editable) {
diff --git a/src/widgets/styles/qwindowsstyle_p.h b/src/widgets/styles/qwindowsstyle_p.h
index 7993b9f1c6..47816ff651 100644
--- a/src/widgets/styles/qwindowsstyle_p.h
+++ b/src/widgets/styles/qwindowsstyle_p.h
@@ -102,7 +102,7 @@ protected:
QWindowsStyle(QWindowsStylePrivate &dd);
private:
- Q_DISABLE_COPY(QWindowsStyle)
+ Q_DISABLE_COPY_MOVE(QWindowsStyle)
Q_DECLARE_PRIVATE(QWindowsStyle)
};
diff --git a/src/widgets/util/qcompleter_p.h b/src/widgets/util/qcompleter_p.h
index 765363744b..21dddf446e 100644
--- a/src/widgets/util/qcompleter_p.h
+++ b/src/widgets/util/qcompleter_p.h
@@ -194,6 +194,7 @@ private:
const QIndexMapper& iv, QMatchData* m);
};
+// ### Qt6: QStyledItemDelegate
class QCompleterItemDelegate : public QItemDelegate
{
public:
diff --git a/src/widgets/util/qflickgesture.cpp b/src/widgets/util/qflickgesture.cpp
index b59fe0d504..a8b2a00a80 100644
--- a/src/widgets/util/qflickgesture.cpp
+++ b/src/widgets/util/qflickgesture.cpp
@@ -130,8 +130,6 @@ private:
, mouseEventSource(Qt::MouseEventNotSynthesized)
{ }
- static PressDelayHandler *inst;
-
public:
enum {
UngrabMouseBefore = 1,
diff --git a/src/widgets/util/qflickgesture_p.h b/src/widgets/util/qflickgesture_p.h
index 74a0f2a0f3..d5ace887ae 100644
--- a/src/widgets/util/qflickgesture_p.h
+++ b/src/widgets/util/qflickgesture_p.h
@@ -77,8 +77,6 @@ public:
friend class QFlickGestureRecognizer;
};
-class PressDelayHandler;
-
class QFlickGesturePrivate : public QGesturePrivate
{
Q_DECLARE_PUBLIC(QFlickGesture)
@@ -89,7 +87,6 @@ public:
QScroller *receiverScroller;
Qt::MouseButton button; // NoButton == Touch
bool macIgnoreWheel;
- static PressDelayHandler *pressDelayHandler;
};
class QFlickGestureRecognizer : public QGestureRecognizer
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index d15f5e5955..a38a50d3df 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -574,7 +574,7 @@ QBalloonTip::QBalloonTip(const QIcon &icon, const QString &title,
layout->addWidget(msgLabel, 1, 0, 1, 3);
#endif
layout->setSizeConstraint(QLayout::SetFixedSize);
- layout->setMargin(3);
+ layout->setContentsMargins(3, 3, 3, 3);
setLayout(layout);
QPalette pal = palette();
diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp
index e928b9fe37..8788c42252 100644
--- a/src/widgets/util/qundostack.cpp
+++ b/src/widgets/util/qundostack.cpp
@@ -102,9 +102,9 @@ QT_BEGIN_NAMESPACE
/*!
Constructs a QUndoCommand object with the given \a parent and \a text.
- If \a parent is not 0, this command is appended to parent's child list.
- The parent command then owns this command and will delete it in its
- destructor.
+ If \a parent is not \nullptr, this command is appended to parent's
+ child list. The parent command then owns this command and will delete
+ it in its destructor.
\sa ~QUndoCommand()
*/
@@ -118,9 +118,9 @@ QUndoCommand::QUndoCommand(const QString &text, QUndoCommand *parent)
/*!
Constructs a QUndoCommand object with parent \a parent.
- If \a parent is not 0, this command is appended to parent's child list.
- The parent command then owns this command and will delete it in its
- destructor.
+ If \a parent is not \nullptr, this command is appended to parent's
+ child list. The parent command then owns this command and will delete
+ it in its destructor.
\sa ~QUndoCommand()
*/
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 598d173144..5ea8330db2 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -185,7 +185,7 @@ QAbstractScrollAreaScrollBarContainer::QAbstractScrollAreaScrollBarContainer(Qt:
orientation(orientation)
{
setLayout(layout);
- layout->setMargin(0);
+ layout->setContentsMargins(QMargins());
layout->setSpacing(0);
layout->addWidget(scrollBar);
layout->setSizeConstraint(QLayout::SetMaximumSize);
@@ -820,7 +820,7 @@ QWidget *QAbstractScrollArea::cornerWidget() const
All widgets set here will be deleted by the scroll area when it is
destroyed unless you separately reparent the widget after setting
- some other corner widget (or 0).
+ some other corner widget (or \nullptr).
Any \e newly set widget should have no current parent.
@@ -1604,8 +1604,10 @@ QSize QAbstractScrollArea::sizeHint() const
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);
+ const bool vbarHidden = d->vbar->isHidden() || d->vbarpolicy == Qt::ScrollBarAlwaysOff;
+ const bool hbarHidden = d->hbar->isHidden() || d->hbarpolicy == Qt::ScrollBarAlwaysOff;
+ const QSize scrollbars(vbarHidden ? 0 : d->vbar->sizeHint().width(),
+ hbarHidden ? 0 : d->hbar->sizeHint().height());
d->sizeHint = frame + scrollbars + viewportSizeHint();
}
return d->sizeHint;
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index 00ac5034e9..6edefaa311 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -688,7 +688,7 @@ QLineEdit *QAbstractSpinBox::lineEdit() const
\fn void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit)
Sets the line edit of the spinbox to be \a lineEdit instead of the
- current line edit widget. \a lineEdit can not be 0.
+ current line edit widget. \a lineEdit cannot be \nullptr.
QAbstractSpinBox takes ownership of the new lineEdit
diff --git a/src/widgets/widgets/qbuttongroup.cpp b/src/widgets/widgets/qbuttongroup.cpp
index fa1ccd347f..669faa92c7 100644
--- a/src/widgets/widgets/qbuttongroup.cpp
+++ b/src/widgets/widgets/qbuttongroup.cpp
@@ -291,8 +291,8 @@ QList<QAbstractButton*> QButtonGroup::buttons() const
}
/*!
- Returns the button group's checked button, or 0 if no buttons are
- checked.
+ Returns the button group's checked button, or \nullptr if no
+ buttons are checked.
\sa buttonClicked()
*/
@@ -305,8 +305,8 @@ QAbstractButton *QButtonGroup::checkedButton() const
/*!
\since 4.1
- Returns the button with the specified \a id, or 0 if no such button
- exists.
+ Returns the button with the specified \a id, or \nullptr if no
+ such button exists.
*/
QAbstractButton *QButtonGroup::button(int id) const
{
diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp
index 2ff383d9c7..47c5267c73 100644
--- a/src/widgets/widgets/qcalendarwidget.cpp
+++ b/src/widgets/widgets/qcalendarwidget.cpp
@@ -1178,9 +1178,9 @@ QVariant QCalendarModel::data(const QModelIndex &index, int role) const
}
QTextCharFormat fmt = formatForCell(row, column);
- if (role == Qt::BackgroundColorRole)
+ if (role == Qt::BackgroundRole)
return fmt.background().color();
- if (role == Qt::TextColorRole)
+ if (role == Qt::ForegroundRole)
return fmt.foreground().color();
if (role == Qt::FontRole)
return fmt.font();
@@ -1555,6 +1555,7 @@ void QCalendarView::mouseReleaseEvent(QMouseEvent *event)
}
}
+// ### Qt6: QStyledItemDelegate
class QCalendarDelegate : public QItemDelegate
{
Q_OBJECT
@@ -1777,7 +1778,7 @@ void QCalendarWidgetPrivate::createNavigationBar(QWidget *widget)
spaceHolder = new QSpacerItem(0,0);
QHBoxLayout *headerLayout = new QHBoxLayout;
- headerLayout->setMargin(0);
+ headerLayout->setContentsMargins(QMargins());
headerLayout->setSpacing(0);
headerLayout->addWidget(prevMonth);
headerLayout->insertStretch(headerLayout->count());
@@ -2100,7 +2101,7 @@ QCalendarWidget::QCalendarWidget(QWidget *parent)
setBackgroundRole(QPalette::Window);
QVBoxLayout *layoutV = new QVBoxLayout(this);
- layoutV->setMargin(0);
+ layoutV->setContentsMargins(QMargins());
d->m_model = new QCalendarModel(this);
QTextCharFormat fmt;
fmt.setForeground(QBrush(Qt::red));
@@ -2147,7 +2148,7 @@ QCalendarWidget::QCalendarWidget(QWidget *parent)
connect(d->yearEdit, SIGNAL(editingFinished()),
this, SLOT(_q_yearEditingFinished()));
- layoutV->setMargin(0);
+ layoutV->setContentsMargins(QMargins());
layoutV->setSpacing(0);
layoutV->addWidget(d->navBarBackground);
layoutV->addWidget(d->m_view);
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index e20a0892b4..e38e1d7750 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -166,7 +166,7 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt
break;
}
if (index.data(Qt::BackgroundRole).canConvert<QBrush>()) {
- menuOption.palette.setBrush(QPalette::All, QPalette::Background,
+ menuOption.palette.setBrush(QPalette::All, QPalette::Window,
qvariant_cast<QBrush>(index.data(Qt::BackgroundRole)));
}
menuOption.text = index.model()->data(index, Qt::DisplayRole).toString()
@@ -472,7 +472,7 @@ QComboBoxPrivateContainer::QComboBoxPrivateContainer(QAbstractItemView *itemView
// we need a vertical layout
QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
layout->setSpacing(0);
- layout->setMargin(0);
+ layout->setContentsMargins(QMargins());
// set item view
setItemView(itemView);
@@ -895,14 +895,21 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const
currentIndex was reset.
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn void QComboBox::currentIndexChanged(const QString &text)
\since 4.1
+ \obsolete
+
+ Use currentTextChanged(const QString &) or currentIndexChanged(int)
+ instead.
+
This signal is sent whenever the currentIndex in the combobox
changes either through user interaction or programmatically. The
item's \a text is passed.
*/
+#endif
/*!
\fn void QComboBox::currentTextChanged(const QString &text)
@@ -1375,7 +1382,12 @@ void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index)
Q_Q(QComboBox);
const QString text = itemText(index);
emit q->currentIndexChanged(index.row());
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
emit q->currentIndexChanged(text);
+ QT_WARNING_POP
+#endif
// signal lineEdit.textChanged already connected to signal currentTextChanged, so don't emit double here
if (!lineEdit)
emit q->currentTextChanged(text);
@@ -1483,6 +1495,7 @@ int QComboBox::maxCount() const
}
#if QT_CONFIG(completer)
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\property QComboBox::autoCompletion
@@ -1576,6 +1589,7 @@ void QComboBox::setAutoCompletionCaseSensitivity(Qt::CaseSensitivity sensitivity
if (d->lineEdit && d->lineEdit->completer())
d->lineEdit->completer()->setCaseSensitivity(sensitivity);
}
+#endif // QT_DEPRECATED_SINCE(5, 13)
#endif // QT_CONFIG(completer)
@@ -1888,8 +1902,8 @@ void QComboBox::setLineEdit(QLineEdit *edit)
}
/*!
- Returns the line edit used to edit items in the combobox, or 0 if there
- is no line edit.
+ Returns the line edit used to edit items in the combobox, or
+ \nullptr if there is no line edit.
Only editable combo boxes have a line edit.
*/
@@ -1941,12 +1955,15 @@ const QValidator *QComboBox::validator() const
performs case insensitive inline completion is automatically created.
\note The completer is removed when the \l editable property becomes \c false.
+ Setting a completer on a QComboBox that is not editable will be ignored.
*/
void QComboBox::setCompleter(QCompleter *c)
{
Q_D(QComboBox);
- if (!d->lineEdit)
+ if (!d->lineEdit) {
+ qWarning("Setting a QCompleter on non-editable QComboBox is not allowed.");
return;
+ }
d->lineEdit->setCompleter(c);
if (c) {
connect(c, SIGNAL(activated(QModelIndex)), this, SLOT(_q_completerActivated(QModelIndex)));
@@ -2017,7 +2034,7 @@ QAbstractItemModel *QComboBox::model() const
}
/*!
- Sets the model to be \a model. \a model must not be 0.
+ Sets the model to be \a model. \a model must not be \nullptr.
If you want to clear the contents of a model, call clear().
\sa clear()
diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h
index 671c883584..64fbebb3c5 100644
--- a/src/widgets/widgets/qcombobox.h
+++ b/src/widgets/widgets/qcombobox.h
@@ -73,8 +73,10 @@ class Q_WIDGETS_EXPORT QComboBox : public QWidget
Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
#if QT_CONFIG(completer)
+#if QT_DEPRECATED_SINCE(5, 13)
Q_PROPERTY(bool autoCompletion READ autoCompletion WRITE setAutoCompletion DESIGNABLE false)
Q_PROPERTY(Qt::CaseSensitivity autoCompletionCaseSensitivity READ autoCompletionCaseSensitivity WRITE setAutoCompletionCaseSensitivity DESIGNABLE false)
+#endif
#endif // QT_CONFIG(completer)
Q_PROPERTY(bool duplicatesEnabled READ duplicatesEnabled WRITE setDuplicatesEnabled)
@@ -93,12 +95,14 @@ public:
int maxCount() const;
#if QT_CONFIG(completer)
+#if QT_DEPRECATED_SINCE(5, 13)
bool autoCompletion() const;
void setAutoCompletion(bool enable);
Qt::CaseSensitivity autoCompletionCaseSensitivity() const;
void setAutoCompletionCaseSensitivity(Qt::CaseSensitivity sensitivity);
#endif
+#endif
bool duplicatesEnabled() const;
void setDuplicatesEnabled(bool enable);
@@ -220,7 +224,10 @@ Q_SIGNALS:
void highlighted(int index);
void highlighted(const QString &);
void currentIndexChanged(int index);
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use currentTextChanged() instead")
void currentIndexChanged(const QString &);
+#endif
void currentTextChanged(const QString &);
protected:
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index 3f75a357e4..71404964da 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -277,7 +277,7 @@ protected:
const QStyleOptionViewItem &option,
const QModelIndex &index) const override {
QStyleOptionMenuItem opt = getStyleOption(option, index);
- painter->fillRect(option.rect, opt.palette.background());
+ painter->fillRect(option.rect, opt.palette.window());
mCombo->style()->drawControl(QStyle::CE_MenuItem, &opt, painter, mCombo);
}
QSize sizeHint(const QStyleOptionViewItem &option,
@@ -293,6 +293,7 @@ private:
QComboBox *mCombo;
};
+// ### Qt6: QStyledItemDelegate ?
// Note that this class is intentionally not using QStyledItemDelegate
// Vista does not use the new theme for combo boxes and there might
// be other side effects from using the new class
diff --git a/src/widgets/widgets/qcommandlinkbutton.h b/src/widgets/widgets/qcommandlinkbutton.h
index 2d01d63df8..3d2dd5784d 100644
--- a/src/widgets/widgets/qcommandlinkbutton.h
+++ b/src/widgets/widgets/qcommandlinkbutton.h
@@ -66,10 +66,16 @@ public:
QString description() const;
void setDescription(const QString &description);
+ // QTBUG-68722
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
protected:
+#else
+public:
+#endif
QSize sizeHint() const override;
int heightForWidth(int) const override;
QSize minimumSizeHint() const override;
+protected:
bool event(QEvent *e) override;
void paintEvent(QPaintEvent *) override;
diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp
index 41d9faa5c2..b874e4e3a9 100644
--- a/src/widgets/widgets/qdatetimeedit.cpp
+++ b/src/widgets/widgets/qdatetimeedit.cpp
@@ -2599,7 +2599,7 @@ void QCalendarPopup::setCalendarWidget(QCalendarWidget *cw)
QVBoxLayout *widgetLayout = qobject_cast<QVBoxLayout*>(layout());
if (!widgetLayout) {
widgetLayout = new QVBoxLayout(this);
- widgetLayout->setMargin(0);
+ widgetLayout->setContentsMargins(QMargins());
widgetLayout->setSpacing(0);
}
delete calendar.data();
diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp
index d93e71e32f..26b86f80be 100644
--- a/src/widgets/widgets/qdialogbuttonbox.cpp
+++ b/src/widgets/widgets/qdialogbuttonbox.cpp
@@ -820,7 +820,7 @@ QDialogButtonBox::StandardButtons QDialogButtonBox::standardButtons() const
/*!
Returns the QPushButton corresponding to the standard button \a which,
- or 0 if the standard button doesn't exist in this button box.
+ or \nullptr if the standard button doesn't exist in this button box.
\sa standardButton(), standardButtons(), buttons()
*/
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index 6c871aae2c..4041c730b8 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -55,6 +55,7 @@
#include <private/qwidgetresizehandler_p.h>
#include <private/qstylesheetstyle_p.h>
+#include <qpa/qplatformtheme.h>
#include "qdockwidget_p.h"
#include "qmainwindowlayout_p.h"
@@ -66,18 +67,21 @@ extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); /
// qmainwindow.cpp
extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
-static inline QMainWindowLayout *qt_mainwindow_layout_from_dock(const QDockWidget *dock)
+static const QMainWindow *mainwindow_from_dock(const QDockWidget *dock)
{
- const QWidget *p = dock->parentWidget();
- while (p) {
- const QMainWindow *window = qobject_cast<const QMainWindow*>(p);
- if (window)
- return qt_mainwindow_layout(window);
- p = p->parentWidget();
+ for (const QWidget *p = dock->parentWidget(); p; p = p->parentWidget()) {
+ if (const QMainWindow *window = qobject_cast<const QMainWindow*>(p))
+ return window;
}
return nullptr;
}
+static inline QMainWindowLayout *qt_mainwindow_layout_from_dock(const QDockWidget *dock)
+{
+ auto mainWindow = mainwindow_from_dock(dock);
+ return mainWindow ? qt_mainwindow_layout(mainWindow) : nullptr;
+}
+
static inline bool hasFeature(const QDockWidgetPrivate *priv, QDockWidget::DockWidgetFeature feature)
{ return (priv->features & feature) == feature; }
@@ -838,8 +842,9 @@ void QDockWidgetPrivate::endDrag(bool abort)
q->releaseMouse();
if (state->dragging) {
- QMainWindowLayout *mwLayout = qt_mainwindow_layout_from_dock(q);
- Q_ASSERT(mwLayout != 0);
+ const QMainWindow *mainWindow = mainwindow_from_dock(q);
+ Q_ASSERT(mainWindow != nullptr);
+ QMainWindowLayout *mwLayout = qt_mainwindow_layout(mainWindow);
if (abort || !mwLayout->plug(state->widgetItem)) {
if (hasFeature(this, QDockWidget::DockWidgetFloatable)) {
@@ -860,8 +865,12 @@ void QDockWidgetPrivate::endDrag(bool abort)
} else {
setResizerActive(false);
}
- if (q->isFloating()) // Might not be floating when dragging a QDockWidgetGroupWindow
+ if (q->isFloating()) { // Might not be floating when dragging a QDockWidgetGroupWindow
undockedGeometry = q->geometry();
+#if QT_CONFIG(tabwidget)
+ tabPosition = mwLayout->tabPosition(mainWindow->dockWidgetArea(q));
+#endif
+ }
q->activateWindow();
} else {
// The tab was not plugged back in the QMainWindow but the QDockWidget cannot
@@ -922,7 +931,8 @@ bool QDockWidgetPrivate::mousePressEvent(QMouseEvent *event)
initDrag(event->pos(), false);
if (state)
- state->ctrlDrag = hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier;
+ state->ctrlDrag = (hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier) ||
+ (!hasFeature(this, QDockWidget::DockWidgetMovable) && q->isFloating());
return true;
}
@@ -1044,7 +1054,8 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event)
initDrag(event->pos(), true);
if (state == 0)
break;
- state->ctrlDrag = event->modifiers() & Qt::ControlModifier;
+ state->ctrlDrag = (event->modifiers() & Qt::ControlModifier) ||
+ (!hasFeature(this, QDockWidget::DockWidgetMovable) && q->isFloating());
startDrag();
break;
case QEvent::NonClientAreaMouseMove:
@@ -1729,8 +1740,8 @@ void QDockWidget::setTitleBarWidget(QWidget *widget)
/*!
\since 4.3
- Returns the custom title bar widget set on the QDockWidget, or 0 if no
- custom title bar has been set.
+ Returns the custom title bar widget set on the QDockWidget, or
+ \nullptr if no custom title bar has been set.
\sa setTitleBarWidget()
*/
diff --git a/src/widgets/widgets/qdockwidget_p.h b/src/widgets/widgets/qdockwidget_p.h
index 766e4ed161..e224ba7143 100644
--- a/src/widgets/widgets/qdockwidget_p.h
+++ b/src/widgets/widgets/qdockwidget_p.h
@@ -57,6 +57,10 @@
#include "QtWidgets/qboxlayout.h"
#include "QtWidgets/qdockwidget.h"
+#if QT_CONFIG(tabwidget)
+# include "QtWidgets/qtabwidget.h"
+#endif
+
QT_REQUIRE_CONFIG(dockwidget);
QT_BEGIN_NAMESPACE
@@ -81,33 +85,32 @@ class QDockWidgetPrivate : public QWidgetPrivate
};
public:
- inline QDockWidgetPrivate()
- : QWidgetPrivate(), state(0),
- features(QDockWidget::DockWidgetClosable
- | QDockWidget::DockWidgetMovable
- | QDockWidget::DockWidgetFloatable),
- allowedAreas(Qt::AllDockWidgetAreas), resizer(0)
- { }
-
void init();
void _q_toggleView(bool); // private slot
void _q_toggleTopLevel(); // private slot
void updateButtons();
- DragState *state;
- QDockWidget::DockWidgetFeatures features;
- Qt::DockWidgetAreas allowedAreas;
+#if QT_CONFIG(tabwidget)
+ QTabWidget::TabPosition tabPosition = QTabWidget::North;
+#endif
+
+ DragState *state = nullptr;
+
+ QDockWidget::DockWidgetFeatures features = QDockWidget::DockWidgetClosable
+ | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable;
+ Qt::DockWidgetAreas allowedAreas = Qt::AllDockWidgetAreas;
QFont font;
#ifndef QT_NO_ACTION
- QAction *toggleViewAction;
+ QAction *toggleViewAction = nullptr;
#endif
// QMainWindow *findMainWindow(QWidget *widget) const;
QRect undockedGeometry;
QString fixedWindowTitle;
+ QString dockedWindowTitle;
bool mousePressEvent(QMouseEvent *event);
bool mouseDoubleClickEvent(QMouseEvent *event);
@@ -128,7 +131,7 @@ public:
bool isAnimating() const;
private:
- QWidgetResizeHandler *resizer;
+ QWidgetResizeHandler *resizer = nullptr;
};
class Q_WIDGETS_EXPORT QDockWidgetLayout : public QLayout
diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp
index 957a464b71..4a99b0f962 100644
--- a/src/widgets/widgets/qfontcombobox.cpp
+++ b/src/widgets/widgets/qfontcombobox.cpp
@@ -236,9 +236,10 @@ void QFontFamilyDelegate::paint(QPainter *painter,
if (QFontDatabase().isSmoothlyScalable(text)) {
icon = &truetype;
}
- QSize actualSize = icon->actualSize(r.size());
-
- icon->paint(painter, r, Qt::AlignLeft|Qt::AlignVCenter);
+ const QSize actualSize = icon->actualSize(r.size());
+ const QRect iconRect = QStyle::alignedRect(option.direction, option.displayAlignment,
+ actualSize, r);
+ icon->paint(painter, iconRect, Qt::AlignLeft|Qt::AlignVCenter);
if (option.direction == Qt::RightToLeft)
r.setRight(r.right() - actualSize.width() - 4);
else
@@ -247,6 +248,7 @@ void QFontFamilyDelegate::paint(QPainter *painter,
QFont old = painter->font();
painter->setFont(font);
+ const Qt::Alignment textAlign = QStyle::visualAlignment(option.direction, option.displayAlignment);
// If the ascent of the font is larger than the height of the rect,
// we will clip the text, so it's better to align the tight bounding rect in this case
// This is specifically for fonts where the ascent is very large compared to
@@ -254,9 +256,11 @@ void QFontFamilyDelegate::paint(QPainter *painter,
QFontMetricsF fontMetrics(font);
if (fontMetrics.ascent() > r.height()) {
QRectF tbr = fontMetrics.tightBoundingRect(text);
- painter->drawText(r.x(), r.y() + (r.height() + tbr.height()) / 2.0, text);
+ QRect textRect(r);
+ textRect.setHeight(textRect.height() + (r.height() - tbr.height()));
+ painter->drawText(textRect, Qt::AlignBottom|Qt::TextSingleLine|textAlign, text);
} else {
- painter->drawText(r, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, text);
+ painter->drawText(r, Qt::AlignVCenter|Qt::TextSingleLine|textAlign, text);
}
if (writingSystem != QFontDatabase::Any)
@@ -270,7 +274,7 @@ void QFontFamilyDelegate::paint(QPainter *painter,
r.setRight(r.right() - w);
else
r.setLeft(r.left() + w);
- painter->drawText(r, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, sample);
+ painter->drawText(r, Qt::AlignVCenter|Qt::TextSingleLine|textAlign, sample);
}
painter->setFont(old);
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index 60f88df9af..a840bf4ee6 100644
--- a/src/widgets/widgets/qlabel.cpp
+++ b/src/widgets/widgets/qlabel.cpp
@@ -1098,7 +1098,7 @@ void QLabel::paintEvent(QPaintEvent *)
QImage scaledImage =
d->cachedimage->scaled(scaledSize,
Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- d->scaledpixmap = new QPixmap(QPixmap::fromImage(scaledImage));
+ d->scaledpixmap = new QPixmap(QPixmap::fromImage(std::move(scaledImage)));
d->scaledpixmap->setDevicePixelRatio(devicePixelRatioF());
}
pix = *d->scaledpixmap;
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 4301a3a2e7..ad3d372bd3 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -586,7 +586,7 @@ void QLineEdit::setEchoMode(EchoMode mode)
#ifndef QT_NO_VALIDATOR
/*!
- Returns a pointer to the current input validator, or 0 if no
+ Returns a pointer to the current input validator, or \nullptr if no
validator has been set.
\sa setValidator()
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 6dcb2dd693..2a5a0c34dc 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -324,7 +324,7 @@ void QLineEditPrivate::drag()
data->setText(control->selectedText());
QDrag *drag = new QDrag(q);
drag->setMimeData(data);
- Qt::DropAction action = drag->start();
+ Qt::DropAction action = drag->exec(Qt::CopyAction);
if (action == Qt::MoveAction && !control->isReadOnly() && drag->target() != q)
control->removeSelection();
}
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 411b482c11..fae3aebba4 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -851,7 +851,11 @@ void QMainWindow::removeToolBar(QToolBar *toolbar)
\sa addToolBar(), addToolBarBreak(), Qt::ToolBarArea
*/
-Qt::ToolBarArea QMainWindow::toolBarArea(QToolBar *toolbar) const
+Qt::ToolBarArea QMainWindow::toolBarArea(
+#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
+ const
+#endif
+ QToolBar *toolbar) const
{ return d_func()->layout->toolBarArea(toolbar); }
/*!
diff --git a/src/widgets/widgets/qmainwindow.h b/src/widgets/widgets/qmainwindow.h
index 8f2a192446..85e3f87d77 100644
--- a/src/widgets/widgets/qmainwindow.h
+++ b/src/widgets/widgets/qmainwindow.h
@@ -158,7 +158,11 @@ public:
bool unifiedTitleAndToolBarOnMac() const;
- Qt::ToolBarArea toolBarArea(QToolBar *toolbar) const;
+ Qt::ToolBarArea toolBarArea(
+#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
+ const
+#endif
+ QToolBar *toolbar) const;
bool toolBarBreak(QToolBar *toolbar) const;
#endif
#if QT_CONFIG(dockwidget)
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 053bfbf024..f54835f23b 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -1388,7 +1388,7 @@ void QMainWindowLayout::insertToolBar(QToolBar *before, QToolBar *toolbar)
invalidate();
}
-Qt::ToolBarArea QMainWindowLayout::toolBarArea(QToolBar *toolbar) const
+Qt::ToolBarArea QMainWindowLayout::toolBarArea(const QToolBar *toolbar) const
{
QInternal::DockPosition pos = layoutState.toolBarAreaLayout.findToolBar(toolbar);
switch (pos) {
@@ -2525,6 +2525,30 @@ void QMainWindowLayout::updateGapIndicator()
#endif // QT_CONFIG(rubberband)
}
+static QTabBar::Shape tabwidgetPositionToTabBarShape(QWidget *w)
+{
+ QTabBar::Shape result = QTabBar::RoundedSouth;
+#if QT_CONFIG(tabwidget)
+ if (qobject_cast<QDockWidget *>(w)) {
+ switch (static_cast<QDockWidgetPrivate *>(qt_widget_private(w))->tabPosition) {
+ case QTabWidget::North:
+ result = QTabBar::RoundedNorth;
+ break;
+ case QTabWidget::South:
+ result = QTabBar::RoundedSouth;
+ break;
+ case QTabWidget::West:
+ result = QTabBar::RoundedWest;
+ break;
+ case QTabWidget::East:
+ result = QTabBar::RoundedEast;
+ break;
+ }
+ }
+#endif // tabwidget
+ return result;
+}
+
void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
{
if (!parentWidget()->isVisible() || parentWidget()->isMinimized()
@@ -2573,8 +2597,9 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
QDockWidgetGroupWindow *floatingTabs = createTabbedDockWindow(); // FIXME
floatingTabs->setGeometry(dropTo->geometry());
QDockAreaLayoutInfo *info = floatingTabs->layoutInfo();
+ const QTabBar::Shape shape = tabwidgetPositionToTabBarShape(dropTo);
*info = QDockAreaLayoutInfo(&layoutState.dockAreaLayout.sep, QInternal::LeftDock,
- Qt::Horizontal, QTabBar::RoundedSouth,
+ Qt::Horizontal, shape,
static_cast<QMainWindow *>(parentWidget()));
info->tabbed = true;
QLayout *parentLayout = dropTo->parentWidget()->layout();
diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h
index 72cbec2350..a375d856bb 100644
--- a/src/widgets/widgets/qmainwindowlayout_p.h
+++ b/src/widgets/widgets/qmainwindowlayout_p.h
@@ -475,7 +475,7 @@ public:
void addToolBar(Qt::ToolBarArea area, QToolBar *toolbar, bool needAddChildWidget = true);
void insertToolBar(QToolBar *before, QToolBar *toolbar);
- Qt::ToolBarArea toolBarArea(QToolBar *toolbar) const;
+ Qt::ToolBarArea toolBarArea(const QToolBar *toolbar) const;
bool toolBarBreak(QToolBar *toolBar) const;
void getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar *toolBar) const;
void removeToolBar(QToolBar *toolbar);
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index f32cd26478..feea7cd050 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -954,14 +954,6 @@ void QMdiAreaPrivate::rearrange(Rearranger *rearranger)
}
}
- if (active && rearranger->type() == Rearranger::RegularTiler && !tileCalledFromResizeEvent) {
- // Move active window in front if necessary. That's the case if we
- // have any windows with staysOnTopHint set.
- int indexToActive = widgets.indexOf((QWidget *)active);
- if (indexToActive > 0)
- widgets.move(indexToActive, 0);
- }
-
QRect domain = viewport->rect();
if (rearranger->type() == Rearranger::RegularTiler && !widgets.isEmpty())
domain = resizeToMinimumTileSize(minSubWindowSize, widgets.count());
@@ -1296,7 +1288,11 @@ QRect QMdiAreaPrivate::resizeToMinimumTileSize(const QSize &minSubWindowSize, in
minAreaHeight += 2 * frame;
}
const QSize diff = QSize(minAreaWidth, minAreaHeight).expandedTo(q->size()) - q->size();
- topLevel->resize(topLevel->size() + diff);
+ // Only resize topLevel widget if scroll bars are disabled.
+ if (hbarpolicy == Qt::ScrollBarAlwaysOff)
+ topLevel->resize(topLevel->size().width() + diff.width(), topLevel->size().height());
+ if (vbarpolicy == Qt::ScrollBarAlwaysOff)
+ topLevel->resize(topLevel->size().width(), topLevel->size().height() + diff.height());
}
QRect domain = viewport->rect();
@@ -1778,7 +1774,7 @@ QSize QMdiArea::minimumSizeHint() const
}
/*!
- Returns a pointer to the current subwindow, or 0 if there is
+ Returns a pointer to the current subwindow, or \nullptr if there is
no current subwindow.
This function will return the same as activeSubWindow() if
@@ -1790,13 +1786,13 @@ QMdiSubWindow *QMdiArea::currentSubWindow() const
{
Q_D(const QMdiArea);
if (d->childWindows.isEmpty())
- return 0;
+ return nullptr;
if (d->active)
return d->active;
if (d->isActivated && !window()->isMinimized())
- return 0;
+ return nullptr;
Q_ASSERT(d->indicesToActivatedChildren.count() > 0);
int index = d->indicesToActivatedChildren.at(0);
@@ -1808,7 +1804,7 @@ QMdiSubWindow *QMdiArea::currentSubWindow() const
/*!
Returns a pointer to the current active subwindow. If no
- window is currently active, 0 is returned.
+ window is currently active, \nullptr is returned.
Subwindows are treated as top-level windows with respect to
window state, i.e., if a widget outside the MDI area is the active
@@ -1825,7 +1821,7 @@ QMdiSubWindow *QMdiArea::activeSubWindow() const
}
/*!
- Activates the subwindow \a window. If \a window is 0, any
+ Activates the subwindow \a window. If \a window is \nullptr, any
current active window is deactivated.
\sa activeSubWindow()
@@ -1834,7 +1830,7 @@ void QMdiArea::setActiveSubWindow(QMdiSubWindow *window)
{
Q_D(QMdiArea);
if (!window) {
- d->activateWindow(0);
+ d->activateWindow(nullptr);
return;
}
@@ -2640,7 +2636,11 @@ bool QMdiArea::eventFilter(QObject *object, QEvent *event)
#endif // QT_CONFIG(tabbar)
Q_FALLTHROUGH();
case QEvent::Hide:
- d->isSubWindowsTiled = false;
+ // Do not reset the isSubWindowsTiled flag if the event is a spontaneous system window event.
+ // This ensures that tiling will be performed during the resizeEvent after an application
+ // window minimize (hide) and then restore (show).
+ if (!event->spontaneous())
+ d->isSubWindowsTiled = false;
break;
#if QT_CONFIG(rubberband)
case QEvent::Close:
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index 794674c427..e25bc6de7a 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -2268,7 +2268,7 @@ QMdiSubWindow::QMdiSubWindow(QWidget *parent, Qt::WindowFlags flags)
setMouseTracking(true);
setLayout(new QVBoxLayout);
setFocusPolicy(Qt::StrongFocus);
- layout()->setMargin(0);
+ layout()->setContentsMargins(QMargins());
d->updateGeometryConstraints();
setAttribute(Qt::WA_Resized, false);
d->titleBarPalette = d->desktopPalette();
@@ -2576,7 +2576,8 @@ void QMdiSubWindow::showSystemMenu()
/*!
\since 4.4
- Returns the area containing this sub-window, or 0 if there is none.
+ Returns the area containing this sub-window, or \nullptr if there
+ is none.
\sa QMdiArea::addSubWindow()
*/
@@ -2590,7 +2591,7 @@ QMdiArea *QMdiSubWindow::mdiArea() const
}
parent = parent->parentWidget();
}
- return 0;
+ return nullptr;
}
/*!
@@ -3341,8 +3342,11 @@ void QMdiSubWindow::mouseMoveEvent(QMouseEvent *mouseEvent)
}
if ((mouseEvent->buttons() & Qt::LeftButton) || d->isInInteractiveMode) {
- if ((d->isResizeOperation() && d->resizeEnabled) || (d->isMoveOperation() && d->moveEnabled))
- d->setNewGeometry(mapToParent(mouseEvent->pos()));
+ if ((d->isResizeOperation() && d->resizeEnabled) || (d->isMoveOperation() && d->moveEnabled)) {
+ // As setNewGeometry moves the window, it invalidates the pos() value of any mouse move events that are
+ // currently queued in the event loop. Map to parent using globalPos() instead.
+ d->setNewGeometry(parentWidget()->mapFromGlobal(mouseEvent->globalPos()));
+ }
return;
}
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 48253b52b0..7dc67c8efe 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -1783,21 +1783,6 @@ QAction *QMenu::addAction(const QString &text, const QObject *receiver, const ch
return action;
}
-/*!\fn template<typename PointerToMemberFunction> QAction *QMenu::addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0)
-
- \since 5.6
-
- \overload
-
- This convenience function creates a new action with the text \a
- text and an optional shortcut \a shortcut. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a method of the \a receiver. The function adds the newly created
- action to the menu's list of actions and returns it.
-
- QMenu takes ownership of the returned QAction.
-*/
-
/*!\fn template<typename Functor> QAction *QMenu::addAction(const QString &text, Functor functor, const QKeySequence &shortcut = 0)
\since 5.6
@@ -1822,25 +1807,11 @@ QAction *QMenu::addAction(const QString &text, const QObject *receiver, const ch
This convenience function creates a new action with the text \a
text and an optional shortcut \a shortcut. The action's
\l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor. The function adds the newly created
- action to the menu's list of actions and returns it.
+ \a functor. The functor can be a pointer to a member function of
+ the \a context object. The newly created action is added to the
+ menu's list of actions and a pointer to it is returned.
- If \a context is destroyed, the functor will not be called.
-
- QMenu takes ownership of the returned QAction.
-*/
-
-/*!\fn template<typename PointerToMemberFunction> QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0)
-
- \since 5.6
-
- \overload
-
- This convenience function creates a new action with an \a icon
- and some \a text and an optional shortcut \a shortcut. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a method of the \a receiver. The function adds the newly created
- action to the menu's list of actions and returns it.
+ If the \a context object is destroyed, the functor will not be called.
QMenu takes ownership of the returned QAction.
*/
@@ -1869,8 +1840,9 @@ QAction *QMenu::addAction(const QString &text, const QObject *receiver, const ch
This convenience function creates a new action with an \a icon
and some \a text and an optional shortcut \a shortcut. The action's
\l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor. The function adds the newly created
- action to the menu's list of actions and returns it.
+ \a functor. The \a functor can be a pointer to a member function
+ of the \a context object. The newly created action is added to the
+ menu's list of actions and a pointer to it is returned.
If \a context is destroyed, the functor will not be called.
@@ -2224,7 +2196,7 @@ void QMenu::setActiveAction(QAction *act)
/*!
- Returns the currently highlighted action, or 0 if no
+ Returns the currently highlighted action, or \nullptr if no
action is currently highlighted.
*/
QAction *QMenu::activeAction() const
@@ -2592,8 +2564,8 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
This is equivalent to \c{exec(pos())}.
This returns the triggered QAction in either the popup menu or one
- of its submenus, or 0 if no item was triggered (normally because
- the user pressed Esc).
+ of its submenus, or \nullptr if no item was triggered (normally
+ because the user pressed Esc).
In most situations you'll want to specify the position yourself,
for example, the current mouse position:
@@ -2619,8 +2591,8 @@ QAction *QMenu::exec()
coordinates into global coordinates, use QWidget::mapToGlobal().
This returns the triggered QAction in either the popup menu or one
- of its submenus, or 0 if no item was triggered (normally because
- the user pressed Esc).
+ of its submenus, or \nullptr if no item was triggered (normally
+ because the user pressed Esc).
Note that all signals are emitted as usual. If you connect a
QAction to a slot and call the menu's exec(), you get the result
@@ -2656,11 +2628,11 @@ QAction *QMenu::exec(const QPoint &p, QAction *action)
QPointer<QObject> guard = this;
(void) eventLoop.exec();
if (guard.isNull())
- return 0;
+ return nullptr;
action = d->syncAction;
- d->syncAction = 0;
- d->eventLoop = 0;
+ d->syncAction = nullptr;
+ d->eventLoop = nullptr;
return action;
}
@@ -2678,7 +2650,7 @@ QAction *QMenu::exec(const QPoint &p, QAction *action)
QGraphicsView).
The function returns the triggered QAction in either the popup
- menu or one of its submenus, or 0 if no item was triggered
+ menu or one of its submenus, or \nullptr if no item was triggered
(normally because the user pressed Esc).
This is equivalent to:
diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h
index 628f818b5e..84ab9e027a 100644
--- a/src/widgets/widgets/qmenu.h
+++ b/src/widgets/widgets/qmenu.h
@@ -82,14 +82,10 @@ public:
QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0);
#ifdef Q_CLANG_QDOC
- template<typename PointerToMemberFunction>
- QAction *addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0);
template<typename Functor>
QAction *addAction(const QString &text, Functor functor, const QKeySequence &shortcut = 0);
template<typename Functor>
QAction *addAction(const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0);
- template<typename PointerToMemberFunction>
- QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0);
template<typename Functor>
QAction *addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut = 0);
template<typename Functor>
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index f740919dc7..12521e7a36 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -95,6 +95,12 @@ static inline int &rperp(Qt::Orientation o, QPoint &pos)
static inline int &rperp(Qt::Orientation o, QSize &size)
{ return o == Qt::Vertical ? size.rwidth() : size.rheight(); }
+static inline int pick(Qt::Orientation o, const QMargins &m)
+{ return o == Qt::Horizontal ? (m.left() + m.right()) : (m.top() + m.bottom()); }
+
+static inline int perp(Qt::Orientation o, const QMargins &m)
+{ return o == Qt::Vertical ? (m.left() + m.right()) : (m.top() + m.bottom()); }
+
class QTornOffMenu;
class QEventLoop;
@@ -115,7 +121,7 @@ private:
class QMenuSloppyState
{
- Q_DISABLE_COPY(QMenuSloppyState)
+ Q_DISABLE_COPY_MOVE(QMenuSloppyState)
public:
QMenuSloppyState()
: m_enabled(false)
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 57f2dec8f7..dc8765ad88 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -1615,7 +1615,7 @@ void QPlainTextEdit::timerEvent(QTimerEvent *e)
const QPoint globalPos = QCursor::pos();
pos = d->viewport->mapFromGlobal(globalPos);
QMouseEvent ev(QEvent::MouseMove, pos, d->viewport->mapTo(d->viewport->topLevelWidget(), pos), globalPos,
- Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ Qt::LeftButton, Qt::LeftButton, QGuiApplication::keyboardModifiers());
mouseMoveEvent(&ev);
}
int deltaY = qMax(pos.y() - visible.top(), visible.bottom() - pos.y()) - visible.height();
@@ -2039,7 +2039,7 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e)
if (backgroundVisible() && !block.isValid() && offset.y() <= er.bottom()
&& (centerOnScroll() || verticalScrollBar()->maximum() == verticalScrollBar()->minimum())) {
- painter.fillRect(QRect(QPoint((int)er.left(), (int)offset.y()), er.bottomRight()), palette().background());
+ painter.fillRect(QRect(QPoint((int)er.left(), (int)offset.y()), er.bottomRight()), palette().window());
}
}
@@ -2892,6 +2892,7 @@ void QPlainTextEdit::setCenterOnScroll(bool enabled)
if (enabled == d->centerOnScroll)
return;
d->centerOnScroll = enabled;
+ d->_q_adjustScrollbars();
}
@@ -2929,6 +2930,27 @@ bool QPlainTextEdit::find(const QRegExp &exp, QTextDocument::FindFlags options)
#endif
/*!
+ \fn bool QPlainTextEdit::find(const QRegularExpression &exp, QTextDocument::FindFlags options)
+
+ \since 5.13
+ \overload
+
+ Finds the next occurrence, matching the regular expression, \a exp, using the given
+ \a options. The QTextDocument::FindCaseSensitively option is ignored for this overload,
+ use QRegularExpression::CaseInsensitiveOption instead.
+
+ Returns \c true if a match was found and changes the cursor to select the match;
+ otherwise returns \c false.
+*/
+#if QT_CONFIG(regularexpression)
+bool QPlainTextEdit::find(const QRegularExpression &exp, QTextDocument::FindFlags options)
+{
+ Q_D(QPlainTextEdit);
+ return d->control->find(exp, options);
+}
+#endif
+
+/*!
\fn void QPlainTextEdit::copyAvailable(bool yes)
This signal is emitted when text is selected or de-selected in the
diff --git a/src/widgets/widgets/qplaintextedit.h b/src/widgets/widgets/qplaintextedit.h
index e5ac4c82b8..a5945d649a 100644
--- a/src/widgets/widgets/qplaintextedit.h
+++ b/src/widgets/widgets/qplaintextedit.h
@@ -60,6 +60,7 @@ class QMenu;
class QPlainTextEditPrivate;
class QMimeData;
class QPagedPaintDevice;
+class QRegularExpression;
class Q_WIDGETS_EXPORT QPlainTextEdit : public QAbstractScrollArea
{
@@ -149,6 +150,9 @@ public:
#ifndef QT_NO_REGEXP
bool find(const QRegExp &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags());
#endif
+#if QT_CONFIG(regularexpression)
+ bool find(const QRegularExpression &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags());
+#endif
inline QString toPlainText() const
{ return document()->toPlainText(); }
diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp
index 8f7271c2dc..b578aa0b18 100644
--- a/src/widgets/widgets/qpushbutton.cpp
+++ b/src/widgets/widgets/qpushbutton.cpp
@@ -545,8 +545,8 @@ void QPushButton::setMenu(QMenu* menu)
}
/*!
- Returns the button's associated popup menu or 0 if no popup menu
- has been set.
+ Returns the button's associated popup menu or \nullptr if no popup
+ menu has been set.
\sa setMenu()
*/
diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp
index 0bfc56f7fa..9994344d79 100644
--- a/src/widgets/widgets/qscrollarea.cpp
+++ b/src/widgets/widgets/qscrollarea.cpp
@@ -217,7 +217,7 @@ void QScrollAreaPrivate::updateScrollBars()
}
/*!
- Returns the scroll area's widget, or 0 if there is none.
+ Returns the scroll area's widget, or \nullptr if there is none.
\sa setWidget()
*/
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 7624b1ed3c..7d454c6359 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -728,6 +728,10 @@ void QDoubleSpinBox::setPrefix(const QString &prefix)
d->prefix = prefix;
d->updateEdit();
+
+ d->cachedSizeHint = QSize();
+ d->cachedMinimumSizeHint = QSize(); // minimumSizeHint cares about the prefix
+ updateGeometry();
}
/*!
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 3b516f36b6..de838a8f93 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -1231,7 +1231,7 @@ QSplitterHandle *QSplitter::createHandle()
/*!
Returns the handle to the left of (or above) the item in the
- splitter's layout at the given \a index, or \c nullptr if there is no such item.
+ splitter's layout at the given \a index, or \nullptr if there is no such item.
The handle at index 0 is always hidden.
For right-to-left languages such as Arabic and Hebrew, the layout
@@ -1250,7 +1250,7 @@ QSplitterHandle *QSplitter::handle(int index) const
/*!
Returns the widget at the given \a index in the splitter's layout,
- or \c nullptr if there is no such widget.
+ or \nullptr if there is no such widget.
\sa count(), handle(), indexOf(), insertWidget()
*/
@@ -1783,6 +1783,7 @@ void QSplitter::setStretchFactor(int index, int stretch)
}
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\relates QSplitter
\obsolete
@@ -1813,6 +1814,7 @@ QTextStream& operator>>(QTextStream& ts, QSplitter& splitter)
splitter.restoreState(std::move(line).toLatin1());
return ts;
}
+#endif
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qsplitter.h b/src/widgets/widgets/qsplitter.h
index 16fac48d1c..ec980d9ee3 100644
--- a/src/widgets/widgets/qsplitter.h
+++ b/src/widgets/widgets/qsplitter.h
@@ -129,8 +129,12 @@ private:
friend class QSplitterHandle;
};
+#if QT_DEPRECATED_SINCE(5, 13)
+QT_DEPRECATED_X("Use QSplitter::saveState() instead")
Q_WIDGETS_EXPORT QTextStream& operator<<(QTextStream&, const QSplitter&);
+QT_DEPRECATED_X("Use QSplitter::restoreState() instead")
Q_WIDGETS_EXPORT QTextStream& operator>>(QTextStream&, QSplitter&);
+#endif
class QSplitterHandlePrivate;
class Q_WIDGETS_EXPORT QSplitterHandle : public QWidget
diff --git a/src/widgets/widgets/qstackedwidget.cpp b/src/widgets/widgets/qstackedwidget.cpp
index 2217dab870..f863964c58 100644
--- a/src/widgets/widgets/qstackedwidget.cpp
+++ b/src/widgets/widgets/qstackedwidget.cpp
@@ -220,7 +220,7 @@ int QStackedWidget::currentIndex() const
}
/*!
- Returns the current widget, or 0 if there are no child widgets.
+ Returns the current widget, or \nullptr if there are no child widgets.
\sa currentIndex(), setCurrentWidget()
*/
@@ -260,8 +260,8 @@ int QStackedWidget::indexOf(QWidget *widget) const
}
/*!
- Returns the widget at the given \a index, or 0 if there is no such
- widget.
+ Returns the widget at the given \a index, or \nullptr if there is
+ no such widget.
\sa currentWidget(), indexOf()
*/
diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp
index ef98bb6950..e9044e6cad 100644
--- a/src/widgets/widgets/qstatusbar.cpp
+++ b/src/widgets/widgets/qstatusbar.cpp
@@ -482,14 +482,14 @@ void QStatusBar::reformat()
#if QT_CONFIG(sizegrip)
if (d->resizer) {
d->box = new QHBoxLayout(this);
- d->box->setMargin(0);
+ d->box->setContentsMargins(QMargins());
vbox = new QVBoxLayout;
d->box->addLayout(vbox);
} else
#endif
{
vbox = d->box = new QVBoxLayout(this);
- d->box->setMargin(0);
+ d->box->setContentsMargins(QMargins());
}
vbox->addSpacing(3);
QBoxLayout* l = new QHBoxLayout;
@@ -689,7 +689,7 @@ void QStatusBar::paintEvent(QPaintEvent *event)
}
}
if (haveMessage) {
- p.setPen(palette().foreground().color());
+ p.setPen(palette().windowText().color());
p.drawText(d->messageRect(), Qt::AlignLeading | Qt::AlignVCenter | Qt::TextSingleLine, d->tempItem);
}
}
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 68453e1842..b13f4da9d2 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -2093,7 +2093,6 @@ void QTabBarPrivate::setupMovableTab()
grabImage.setDevicePixelRatio(q->devicePixelRatioF());
grabImage.fill(Qt::transparent);
QStylePainter p(&grabImage, q);
- p.initFrom(q);
QStyleOptionTab tab;
q->initStyleOption(&tab, pressedIndex);
@@ -2567,7 +2566,7 @@ void QTabBar::setChangeCurrentOnDrag(bool change)
The tab bar will take ownership of the widget and so all widgets set here
will be deleted by the tab bar when it is destroyed unless you separately
- reparent the widget after setting some other widget (or 0).
+ reparent the widget after setting some other widget (or \nullptr).
\sa tabsClosable()
*/
@@ -2597,14 +2596,14 @@ void QTabBar::setTabButton(int index, ButtonPosition position, QWidget *widget)
}
/*!
- Returns the widget set a tab \a index and \a position or 0 if
- one is not set.
+ Returns the widget set a tab \a index and \a position or \nullptr
+ if one is not set.
*/
QWidget *QTabBar::tabButton(int index, ButtonPosition position) const
{
Q_D(const QTabBar);
if (index < 0 || index >= d->tabList.count())
- return 0;
+ return nullptr;
if (position == LeftSide)
return d->tabList.at(index).leftWidget;
else
diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp
index 8a848554e3..547b8a82f9 100644
--- a/src/widgets/widgets/qtabwidget.cpp
+++ b/src/widgets/widgets/qtabwidget.cpp
@@ -579,7 +579,7 @@ void QTabWidget::setTabEnabled(int index, bool enable)
All widgets set here will be deleted by the tab widget when it is
destroyed unless you separately reparent the widget after setting
- some other corner widget (or 0).
+ some other corner widget (or \nullptr).
Note: Corner widgets are designed for \l North and \l South tab positions;
other orientations are known to not work properly.
@@ -605,7 +605,7 @@ void QTabWidget::setCornerWidget(QWidget * widget, Qt::Corner corner)
}
/*!
- Returns the widget shown in the \a corner of the tab widget or 0.
+ Returns the widget shown in the \a corner of the tab widget or \nullptr.
*/
QWidget * QTabWidget::cornerWidget(Qt::Corner corner) const
{
@@ -1146,8 +1146,8 @@ void QTabWidget::keyPressEvent(QKeyEvent *e)
}
/*!
- Returns the tab page at index position \a index or 0 if the \a
- index is out of range.
+ Returns the tab page at index position \a index or \nullptr if the
+ \a index is out of range.
*/
QWidget *QTabWidget::widget(int index) const
{
diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp
index 09541bb53b..bb9a4fed91 100644
--- a/src/widgets/widgets/qtextbrowser.cpp
+++ b/src/widgets/widgets/qtextbrowser.cpp
@@ -276,7 +276,7 @@ void QTextBrowserPrivate::setSource(const QUrl &url)
Q_Q(QTextBrowser);
#ifndef QT_NO_CURSOR
if (q->isVisible())
- QApplication::setOverrideCursor(Qt::WaitCursor);
+ QGuiApplication::setOverrideCursor(Qt::WaitCursor);
#endif
textOrSourceChanged = true;
@@ -310,7 +310,7 @@ void QTextBrowserPrivate::setSource(const QUrl &url)
const QStringRef firstTag = txt.leftRef(txt.indexOf(QLatin1Char('>')) + 1);
if (firstTag.startsWith(QLatin1String("<qt")) && firstTag.contains(QLatin1String("type")) && firstTag.contains(QLatin1String("detail"))) {
#ifndef QT_NO_CURSOR
- QApplication::restoreOverrideCursor();
+ QGuiApplication::restoreOverrideCursor();
#endif
#if QT_CONFIG(whatsthis)
QWhatsThis::showText(QCursor::pos(), txt, q);
@@ -355,7 +355,7 @@ void QTextBrowserPrivate::setSource(const QUrl &url)
#ifndef QT_NO_CURSOR
if (q->isVisible())
- QApplication::restoreOverrideCursor();
+ QGuiApplication::restoreOverrideCursor();
#endif
emit q->sourceChanged(url);
}
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index e3a45680ef..920133d493 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -105,6 +105,14 @@ public:
else
ed->insertFromMimeData(source);
}
+ QVariant loadResource(int type, const QUrl &name) override {
+ auto *ed = qobject_cast<QTextEdit *>(parent());
+ if (!ed)
+ return QWidgetTextControl::loadResource(type, name);
+
+ QUrl resolvedName = ed->d_func()->resolveUrl(name);
+ return ed->loadResource(type, resolvedName);
+ }
};
QTextEditPrivate::QTextEditPrivate()
@@ -2534,6 +2542,27 @@ bool QTextEdit::find(const QRegExp &exp, QTextDocument::FindFlags options)
#endif
/*!
+ \fn bool QTextEdit::find(const QRegularExpression &exp, QTextDocument::FindFlags options)
+
+ \since 5.13
+ \overload
+
+ Finds the next occurrence, matching the regular expression, \a exp, using the given
+ \a options. The QTextDocument::FindCaseSensitively option is ignored for this overload,
+ use QRegularExpression::CaseInsensitiveOption instead.
+
+ Returns \c true if a match was found and changes the cursor to select the match;
+ otherwise returns \c false.
+*/
+#if QT_CONFIG(regularexpression)
+bool QTextEdit::find(const QRegularExpression &exp, QTextDocument::FindFlags options)
+{
+ Q_D(QTextEdit);
+ return d->control->find(exp, options);
+}
+#endif
+
+/*!
\fn void QTextEdit::copyAvailable(bool yes)
This signal is emitted when text is selected or de-selected in the
diff --git a/src/widgets/widgets/qtextedit.h b/src/widgets/widgets/qtextedit.h
index 51d6c2ccba..3aa23aaace 100644
--- a/src/widgets/widgets/qtextedit.h
+++ b/src/widgets/widgets/qtextedit.h
@@ -57,6 +57,7 @@ class QMenu;
class QTextEditPrivate;
class QMimeData;
class QPagedPaintDevice;
+class QRegularExpression;
class Q_WIDGETS_EXPORT QTextEdit : public QAbstractScrollArea
{
@@ -165,6 +166,9 @@ public:
#ifndef QT_NO_REGEXP
bool find(const QRegExp &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags());
#endif
+#if QT_CONFIG(regularexpression)
+ bool find(const QRegularExpression &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags());
+#endif
QString toPlainText() const;
#ifndef QT_NO_TEXTHTMLPARSER
diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp
index 4af71c126e..bcf5a40ae3 100644
--- a/src/widgets/widgets/qtoolbar.cpp
+++ b/src/widgets/widgets/qtoolbar.cpp
@@ -799,18 +799,6 @@ QAction *QToolBar::addAction(const QIcon &icon, const QString &text,
return action;
}
-/*!\fn template<typename PointerToMemberFunction> QAction *QToolBar::addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method)
-
- \since 5.6
-
- \overload
-
- Creates a new action with the given \a text. This action is added to
- the end of the toolbar. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a method of the \a receiver.
-*/
-
/*!\fn template<typename Functor> QAction *QToolBar::addAction(const QString &text, Functor functor)
\since 5.6
@@ -829,24 +817,13 @@ QAction *QToolBar::addAction(const QIcon &icon, const QString &text,
\overload
- Creates a new action with the given \a text. This action is added to
- the end of the toolbar. The action's
+ Creates a new action with the given \a text. This action is added
+ to the end of the toolbar. The action's
\l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor.
-
- If \a context is destroyed, the functor will not be called.
-*/
-
-/*!\fn template<typename PointerToMemberFunction> QAction *QToolBar::addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method)
-
- \since 5.6
+ \a functor. The \a functor can be a pointer to a member function
+ in the \a context object.
- \overload
-
- Creates a new action with the given \a icon and \a text. This
- action is added to the end of the toolbar. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a method of the \a receiver.
+ If the \a context object is destroyed, the \a functor will not be called.
*/
/*!\fn template<typename Functor> QAction *QToolBar::addAction(const QIcon &icon, const QString &text, Functor functor)
@@ -870,9 +847,10 @@ QAction *QToolBar::addAction(const QIcon &icon, const QString &text,
Creates a new action with the given \a icon and \a text. This
action is added to the end of the toolbar. The action's
\l{QAction::triggered()}{triggered()} signal is connected to the
- \a functor.
+ \a functor. The \a functor can be a pointer to a member function
+ of the \a context object.
- If \a context is destroyed, the functor will not be called.
+ If the \a context object is destroyed, the \a functor will not be called.
*/
/*!
@@ -1067,7 +1045,7 @@ void QToolBar::paintEvent(QPaintEvent *)
if (d->layout->expanded || d->layout->animating || isWindow()) {
//if the toolbar is expended, we need to fill the background with the window color
//because some styles may expects that.
- p.fillRect(opt.rect, palette().background());
+ p.fillRect(opt.rect, palette().window());
style->drawControl(QStyle::CE_ToolBar, &opt, &p, this);
style->drawPrimitive(QStyle::PE_FrameMenu, &opt, &p, this);
} else {
diff --git a/src/widgets/widgets/qtoolbar.h b/src/widgets/widgets/qtoolbar.h
index 4ae83190d1..0c434e8d1d 100644
--- a/src/widgets/widgets/qtoolbar.h
+++ b/src/widgets/widgets/qtoolbar.h
@@ -99,15 +99,11 @@ public:
QAction *addAction(const QString &text, const QObject *receiver, const char* member);
QAction *addAction(const QIcon &icon, const QString &text,
const QObject *receiver, const char* member);
-#ifdef Q_QDOC
- template<typename PointerToMemberFunction>
- QAction *addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method);
+#ifdef Q_CLANG_QDOC
template<typename Functor>
QAction *addAction(const QString &text, Functor functor);
template<typename Functor>
QAction *addAction(const QString &text, const QObject *context, Functor functor);
- template<typename PointerToMemberFunction>
- QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method);
template<typename Functor>
QAction *addAction(const QIcon &icon, const QString &text, Functor functor);
template<typename Functor>
@@ -149,7 +145,7 @@ public:
connect(result, &QAction::triggered, slot);
return result;
}
-#endif // !Q_QDOC
+#endif // !Q_CLANG_QDOC
QAction *addSeparator();
QAction *insertSeparator(QAction *before);
diff --git a/src/widgets/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp
index edf497111b..adc329131c 100644
--- a/src/widgets/widgets/qtoolbararealayout.cpp
+++ b/src/widgets/widgets/qtoolbararealayout.cpp
@@ -789,7 +789,7 @@ void QToolBarAreaLayout::deleteAllLayoutItems()
}
}
-QInternal::DockPosition QToolBarAreaLayout::findToolBar(QToolBar *toolBar) const
+QInternal::DockPosition QToolBarAreaLayout::findToolBar(const QToolBar *toolBar) const
{
for (int i = 0; i < QInternal::DockCount; ++i) {
const QToolBarAreaLayoutInfo &dock = docks[i];
@@ -1078,7 +1078,11 @@ bool QToolBarAreaLayout::insertGap(const QList<int> &path, QLayoutItem *item)
void QToolBarAreaLayout::remove(const QList<int> &path)
{
Q_ASSERT(path.count() == 3);
- docks[path.at(0)].lines[path.at(1)].toolBarItems.removeAt(path.at(2));
+ QToolBarAreaLayoutInfo &dock = docks[path.at(0)];
+ QToolBarAreaLayoutLine &line = dock.lines[path.at(1)];
+ line.toolBarItems.removeAt(path.at(2));
+ if (line.toolBarItems.isEmpty())
+ dock.lines.removeAt(path.at(1));
}
void QToolBarAreaLayout::remove(QLayoutItem *item)
diff --git a/src/widgets/widgets/qtoolbararealayout_p.h b/src/widgets/widgets/qtoolbararealayout_p.h
index dffbab1f21..17747ef29b 100644
--- a/src/widgets/widgets/qtoolbararealayout_p.h
+++ b/src/widgets/widgets/qtoolbararealayout_p.h
@@ -196,7 +196,7 @@ public:
void insertItem(QInternal::DockPosition pos, QLayoutItem *item);
void insertItem(QToolBar *before, QLayoutItem *item);
- QInternal::DockPosition findToolBar(QToolBar *toolBar) const;
+ QInternal::DockPosition findToolBar(const QToolBar *toolBar) const;
bool toolBarBreak(QToolBar *toolBar) const;
void getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar *toolBar) const;
diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp
index f2d329d59d..d50e19a5ed 100644
--- a/src/widgets/widgets/qtoolbarlayout.cpp
+++ b/src/widgets/widgets/qtoolbarlayout.cpp
@@ -119,8 +119,9 @@ void QToolBarLayout::updateMarginAndSpacing()
QStyle *style = tb->style();
QStyleOptionToolBar opt;
tb->initStyleOption(&opt);
- setMargin(style->pixelMetric(QStyle::PM_ToolBarItemMargin, &opt, tb)
- + style->pixelMetric(QStyle::PM_ToolBarFrameWidth, &opt, tb));
+ const int margin = style->pixelMetric(QStyle::PM_ToolBarItemMargin, &opt, tb)
+ + style->pixelMetric(QStyle::PM_ToolBarFrameWidth, &opt, tb);
+ setContentsMargins(margin, margin, margin, margin);
setSpacing(style->pixelMetric(QStyle::PM_ToolBarItemSpacing, &opt, tb));
}
@@ -268,7 +269,7 @@ void QToolBarLayout::updateGeomArray() const
tb->initStyleOption(&opt);
const int handleExtent = movable()
? style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb) : 0;
- const int margin = this->margin();
+ const QMargins margins = contentsMargins();
const int spacing = this->spacing();
const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb);
Qt::Orientation o = tb->orientation();
@@ -330,12 +331,12 @@ void QToolBarLayout::updateGeomArray() const
that->empty = count == 0;
rpick(o, that->minSize) += handleExtent;
- that->minSize += QSize(2*margin, 2*margin);
+ that->minSize += QSize(pick(Qt::Horizontal, margins), pick(Qt::Vertical, margins));
if (items.count() > 1)
rpick(o, that->minSize) += spacing + extensionExtent;
rpick(o, that->hint) += handleExtent;
- that->hint += QSize(2*margin, 2*margin);
+ that->hint += QSize(pick(Qt::Horizontal, margins), pick(Qt::Vertical, margins));
that->dirty = false;
}
@@ -384,7 +385,7 @@ void QToolBarLayout::setGeometry(const QRect &rect)
QStyle *style = tb->style();
QStyleOptionToolBar opt;
tb->initStyleOption(&opt);
- const int margin = this->margin();
+ const QMargins margins = contentsMargins();
const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb);
Qt::Orientation o = tb->orientation();
@@ -403,14 +404,18 @@ void QToolBarLayout::setGeometry(const QRect &rect)
QSize hint = sizeHint();
QPoint pos;
- rpick(o, pos) = pick(o, rect.bottomRight()) - margin - extensionExtent + 2;
+ rpick(o, pos) = pick(o, rect.bottomRight()) -
+ pick(o, QSize(margins.bottom(), margins.right())) - extensionExtent + 2;
if (area == Qt::LeftToolBarArea || area == Qt::TopToolBarArea)
- rperp(o, pos) = perp(o, rect.topLeft()) + margin;
+ rperp(o, pos) = perp(o, rect.topLeft()) +
+ perp(o, QSize(margins.top(), margins.left()));
else
- rperp(o, pos) = perp(o, rect.bottomRight()) - margin - (perp(o, hint) - 2*margin) + 1;
+ rperp(o, pos) = perp(o, rect.bottomRight()) -
+ perp(o, QSize(margins.bottom(), margins.right())) -
+ (perp(o, hint) - perp(o, margins)) + 1;
QSize size;
rpick(o, size) = extensionExtent;
- rperp(o, size) = perp(o, hint) - 2*margin;
+ rperp(o, size) = perp(o, hint) - perp(o, margins);
QRect r(pos, size);
if (o == Qt::Horizontal)
@@ -443,13 +448,13 @@ bool QToolBarLayout::layoutActions(const QSize &size)
tb->initStyleOption(&opt);
const int handleExtent = movable()
? style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb) : 0;
- const int margin = this->margin();
+ const QMargins margins = contentsMargins();
const int spacing = this->spacing();
const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb);
Qt::Orientation o = tb->orientation();
bool extensionMenuContainsOnlyWidgetActions = true;
- int space = pick(o, rect.size()) - 2*margin - handleExtent;
+ int space = pick(o, rect.size()) - pick(o, margins) - handleExtent;
if (space <= 0)
return false; // nothing to do.
@@ -458,7 +463,7 @@ bool QToolBarLayout::layoutActions(const QSize &size)
bool ranOutOfSpace = false;
int rows = 0;
- int rowPos = perp(o, rect.topLeft()) + margin;
+ int rowPos = perp(o, rect.topLeft()) + perp(o, QSize(margins.top(), margins.left()));
int i = 0;
while (i < items.count()) {
QVector<QLayoutStruct> a = geomArray;
@@ -521,14 +526,14 @@ bool QToolBarLayout::layoutActions(const QSize &size)
}
QPoint pos;
- rpick(o, pos) = margin + handleExtent + a[j].pos;
+ rpick(o, pos) = pick(o, QSize(margins.top(), margins.left())) + handleExtent + a[j].pos;
rperp(o, pos) = rowPos;
QSize size;
rpick(o, size) = a[j].size;
if (expanded)
rperp(o, size) = rowHeight;
else
- rperp(o, size) = perp(o, rect.size()) - 2*margin;
+ rperp(o, size) = perp(o, rect.size()) - perp(o, QSize(margins.top(), margins.left()));
QRect r(pos, size);
if (o == Qt::Horizontal)
@@ -589,7 +594,7 @@ QSize QToolBarLayout::expandedSize(const QSize &size) const
tb->initStyleOption(&opt);
const int handleExtent = movable()
? style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb) : 0;
- const int margin = this->margin();
+ const QMargins margins = contentsMargins();
const int spacing = this->spacing();
const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb);
@@ -609,9 +614,9 @@ QSize QToolBarLayout::expandedSize(const QSize &size) const
if (rows == 1)
++rows; // we want to expand to at least two rows
int space = total_w/rows + spacing + extensionExtent;
- space = qMax(space, min_w - 2*margin - handleExtent);
+ space = qMax(space, min_w - pick(o, margins) - handleExtent);
if (win != 0)
- space = qMin(space, pick(o, win->size()) - 2*margin - handleExtent);
+ space = qMin(space, pick(o, win->size()) - pick(o, margins) - handleExtent);
int w = 0;
int h = 0;
@@ -644,11 +649,11 @@ QSize QToolBarLayout::expandedSize(const QSize &size) const
h += rowHeight + spacing;
}
- w += 2*margin + handleExtent + spacing + extensionExtent;
+ w += pick(Qt::Horizontal, margins) + handleExtent + spacing + extensionExtent;
w = qMax(w, min_w);
if (win != 0)
w = qMin(w, pick(o, win->size()));
- h += 2*margin - spacing; //there is no spacing before the first row
+ h += pick(Qt::Vertical, margins) - spacing; //there is no spacing before the first row
QSize result;
rpick(o, result) = w;
diff --git a/src/widgets/widgets/qtoolbox.cpp b/src/widgets/widgets/qtoolbox.cpp
index 46ade0277c..1c83485bff 100644
--- a/src/widgets/widgets/qtoolbox.cpp
+++ b/src/widgets/widgets/qtoolbox.cpp
@@ -294,7 +294,7 @@ QToolBox::QToolBox(QWidget *parent, Qt::WindowFlags f)
{
Q_D(QToolBox);
d->layout = new QVBoxLayout(this);
- d->layout->setMargin(0);
+ d->layout->setContentsMargins(QMargins());
setBackgroundRole(QPalette::Button);
}
@@ -437,7 +437,7 @@ void QToolBoxPrivate::relayout()
Q_Q(QToolBox);
delete layout;
layout = new QVBoxLayout(q);
- layout->setMargin(0);
+ layout->setContentsMargins(QMargins());
for (QToolBoxPrivate::PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i) {
layout->addWidget((*i).button);
layout->addWidget((*i).sv);
@@ -504,7 +504,8 @@ int QToolBox::currentIndex() const
}
/*!
- Returns a pointer to the current widget, or 0 if there is no such item.
+ Returns a pointer to the current widget, or \nullptr if there is
+ no such item.
\sa currentIndex(), setCurrentWidget()
*/
@@ -512,7 +513,7 @@ int QToolBox::currentIndex() const
QWidget * QToolBox::currentWidget() const
{
Q_D(const QToolBox);
- return d->currentPage ? d->currentPage->widget : 0;
+ return d->currentPage ? d->currentPage->widget : nullptr;
}
/*!
@@ -530,15 +531,15 @@ void QToolBox::setCurrentWidget(QWidget *widget)
}
/*!
- Returns the widget at position \a index, or 0 if there is no such
- item.
+ Returns the widget at position \a index, or \nullptr if there is
+ no such item.
*/
QWidget *QToolBox::widget(int index) const
{
Q_D(const QToolBox);
if (index < 0 || index >= (int) d->pageList.size())
- return 0;
+ return nullptr;
return d->pageList.at(index).widget;
}
diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp
index 6a24712319..b00b219386 100644
--- a/src/widgets/widgets/qtoolbutton.cpp
+++ b/src/widgets/widgets/qtoolbutton.cpp
@@ -669,7 +669,8 @@ void QToolButton::setMenu(QMenu* menu)
}
/*!
- Returns the associated menu, or 0 if no menu has been defined.
+ Returns the associated menu, or \nullptr if no menu has been
+ defined.
\sa setMenu()
*/
@@ -678,7 +679,7 @@ QMenu* QToolButton::menu() const
Q_D(const QToolButton);
if (d->menuAction)
return d->menuAction->menu();
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/widgets/widgets/qwidgetresizehandler_p.h b/src/widgets/widgets/qwidgetresizehandler_p.h
index b87bbd6229..89bc759cc2 100644
--- a/src/widgets/widgets/qwidgetresizehandler_p.h
+++ b/src/widgets/widgets/qwidgetresizehandler_p.h
@@ -100,7 +100,7 @@ protected:
void keyPressEvent(QKeyEvent *e);
private:
- Q_DISABLE_COPY(QWidgetResizeHandler)
+ Q_DISABLE_COPY_MOVE(QWidgetResizeHandler)
enum MousePosition {
Nowhere,
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index e179ea3b40..711c4bfd2a 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -57,9 +57,6 @@
#include <qtimer.h>
#include "private/qtextdocumentlayout_p.h"
#include "private/qabstracttextdocumentlayout_p.h"
-#if QT_CONFIG(textedit)
-#include "private/qtextedit_p.h"
-#endif
#include "qtextdocument.h"
#include "private/qtextdocument_p.h"
#include "qtextlist.h"
@@ -218,6 +215,14 @@ bool QWidgetTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e)
else if (e == QKeySequence::SelectPreviousLine) {
op = QTextCursor::Up;
mode = QTextCursor::KeepAnchor;
+ {
+ QTextBlock block = cursor.block();
+ QTextLine line = currentTextLine(cursor);
+ if (!block.previous().isValid()
+ && line.isValid()
+ && line.lineNumber() == 0)
+ op = QTextCursor::Start;
+ }
}
else if (e == QKeySequence::SelectNextLine) {
op = QTextCursor::Down;
@@ -1357,15 +1362,8 @@ process:
QVariant QWidgetTextControl::loadResource(int type, const QUrl &name)
{
-#if !QT_CONFIG(textedit)
Q_UNUSED(type);
Q_UNUSED(name);
-#else
- if (QTextEdit *textEdit = qobject_cast<QTextEdit *>(parent())) {
- QUrl resolvedName = textEdit->d_func()->resolveUrl(name);
- return textEdit->loadResource(type, resolvedName);
- }
-#endif
return QVariant();
}
@@ -3094,6 +3092,19 @@ bool QWidgetTextControl::find(const QRegExp &exp, QTextDocument::FindFlags optio
}
#endif
+#if QT_CONFIG(regularexpression)
+bool QWidgetTextControl::find(const QRegularExpression &exp, QTextDocument::FindFlags options)
+{
+ Q_D(QWidgetTextControl);
+ QTextCursor search = d->doc->find(exp, d->cursor, options);
+ if (search.isNull())
+ return false;
+
+ setTextCursor(search);
+ return true;
+}
+#endif
+
QString QWidgetTextControl::toPlainText() const
{
return document()->toPlainText();
diff --git a/src/widgets/widgets/qwidgettextcontrol_p.h b/src/widgets/widgets/qwidgettextcontrol_p.h
index 4b2acbd934..202ba36454 100644
--- a/src/widgets/widgets/qwidgettextcontrol_p.h
+++ b/src/widgets/widgets/qwidgettextcontrol_p.h
@@ -80,6 +80,7 @@ class QMenu;
class QWidgetTextControlPrivate;
class QAbstractScrollArea;
class QEvent;
+class QRegularExpression;
class QTimerEvent;
class Q_WIDGETS_EXPORT QWidgetTextControl : public QInputControl
@@ -119,6 +120,9 @@ public:
#ifndef QT_NO_REGEXP
bool find(const QRegExp &exp, QTextDocument::FindFlags options = 0);
#endif
+#if QT_CONFIG(regularexpression)
+ bool find(const QRegularExpression &exp, QTextDocument::FindFlags options = 0);
+#endif
QString toPlainText() const;
#ifndef QT_NO_TEXTHTMLPARSER
@@ -263,7 +267,7 @@ protected:
virtual bool event(QEvent *e) override;
private:
- Q_DISABLE_COPY(QWidgetTextControl)
+ Q_DISABLE_COPY_MOVE(QWidgetTextControl)
Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentCharFormatAndSelection())
Q_PRIVATE_SLOT(d_func(), void _q_emitCursorPosChanged(const QTextCursor &))
Q_PRIVATE_SLOT(d_func(), void _q_deleteSelected())
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index 5893d8448e..cffc1974af 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -48,7 +48,9 @@
#include <qhash.h>
#include <qiodevice.h>
#include <qlist.h>
-#include <qregexp.h>
+#if QT_CONFIG(regularexpression)
+#include <qregularexpression.h>
+#endif
#if QT_CONFIG(textcodec)
#include <qtextcodec.h>
#endif
@@ -5181,7 +5183,7 @@ QDomNodePrivate* QDomTextPrivate::cloneNode(bool deep)
QDomTextPrivate* QDomTextPrivate::splitText(int offset)
{
if (!parent()) {
- qWarning("QDomText::splitText The node has no parent. So I can not split");
+ qWarning("QDomText::splitText The node has no parent. So I cannot split");
return 0;
}
@@ -6430,7 +6432,7 @@ void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNod
const QDomNodePrivate* n = first;
if(encUsed == QDomNode::EncodingFromDocument) {
-#if QT_CONFIG(textcodec)
+#if QT_CONFIG(textcodec) && QT_CONFIG(regularexpression)
const QDomNodePrivate* n = first;
QTextCodec *codec = 0;
@@ -6438,11 +6440,11 @@ void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNod
if (n && n->isProcessingInstruction() && n->nodeName() == QLatin1String("xml")) {
// we have an XML declaration
QString data = n->nodeValue();
- QRegExp encoding(QString::fromLatin1("encoding\\s*=\\s*((\"([^\"]*)\")|('([^']*)'))"));
- encoding.indexIn(data);
- QString enc = encoding.cap(3);
+ QRegularExpression encoding(QString::fromLatin1("encoding\\s*=\\s*((\"([^\"]*)\")|('([^']*)'))"));
+ auto match = encoding.match(data);
+ QString enc = match.captured(3);
if (enc.isEmpty())
- enc = encoding.cap(5);
+ enc = match.captured(5);
if (!enc.isEmpty())
codec = QTextCodec::codecForName(std::move(enc).toLatin1());
}
diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp
index 7b6669b057..0e3a87e883 100644
--- a/src/xml/sax/qxml.cpp
+++ b/src/xml/sax/qxml.cpp
@@ -43,7 +43,9 @@
#include "qtextcodec.h"
#endif
#include "qbuffer.h"
-#include "qregexp.h"
+#if QT_CONFIG(regularexpression)
+#include "qregularexpression.h"
+#endif
#include "qmap.h"
#include "qhash.h"
#include "qstack.h"
@@ -193,19 +195,23 @@ static const signed char charLookupTable[256]={
*/
static bool stripTextDecl(QString& str)
{
- QString textDeclStart(QLatin1String("<?xml"));
+ QLatin1String textDeclStart("<?xml");
if (str.startsWith(textDeclStart)) {
- QRegExp textDecl(QString::fromLatin1(
+#if QT_CONFIG(regularexpression)
+ QRegularExpression textDecl(QString::fromLatin1(
"^<\\?xml\\s+"
"(version\\s*=\\s*((['\"])[-a-zA-Z0-9_.:]+\\3))?"
"\\s*"
"(encoding\\s*=\\s*((['\"])[A-Za-z][-a-zA-Z0-9_.]*\\6))?"
"\\s*\\?>"
- ));
+ ));
QString strTmp = str.replace(textDecl, QLatin1String(""));
if (strTmp.length() != str.length())
return false; // external entity has wrong TextDecl
str = strTmp;
+#else
+ return false;
+#endif
}
return true;
}
@@ -2607,8 +2613,9 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing()
is returned. If no such feature exists the return value is
undefined.
- If \a ok is not 0: \c{*}\a{ok} is set to true if the reader has the
- feature called \a name; otherwise \c{*}\a{ok} is set to false.
+ If \a ok is not \nullptr: \c{*}\a{ok} is set to true if the
+ reader has the feature called \a name; otherwise \c{*}\a{ok} is
+ set to false.
\sa setFeature(), hasFeature()
*/
@@ -2637,7 +2644,7 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing()
If the reader has the property \a name, this function returns the
value of the property; otherwise the return value is undefined.
- If \a ok is not 0: if the reader has the \a name property
+ If \a ok is not \nullptr: if the reader has the \a name property
\c{*}\a{ok} is set to true; otherwise \c{*}\a{ok} is set to false.
\sa setProperty(), hasProperty()
@@ -2670,9 +2677,9 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing()
*/
/*!
- \fn QXmlEntityResolver* QXmlReader::entityResolver() const
+ \fn QXmlEntityResolver *QXmlReader::entityResolver() const
- Returns the entity resolver or 0 if none was set.
+ Returns the entity resolver or \nullptr if none was set.
\sa setEntityResolver()
*/
@@ -2686,9 +2693,9 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing()
*/
/*!
- \fn QXmlDTDHandler* QXmlReader::DTDHandler() const
+ \fn QXmlDTDHandler *QXmlReader::DTDHandler() const
- Returns the DTD handler or 0 if none was set.
+ Returns the DTD handler or \nullptr if none was set.
\sa setDTDHandler()
*/
@@ -2702,9 +2709,9 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing()
*/
/*!
- \fn QXmlContentHandler* QXmlReader::contentHandler() const
+ \fn QXmlContentHandler *QXmlReader::contentHandler() const
- Returns the content handler or 0 if none was set.
+ Returns the content handler or \nullptr if none was set.
\sa setContentHandler()
*/
@@ -2719,9 +2726,9 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing()
*/
/*!
- \fn QXmlErrorHandler* QXmlReader::errorHandler() const
+ \fn QXmlErrorHandler *QXmlReader::errorHandler() const
- Returns the error handler or 0 if none is set.
+ Returns the error handler or \nullptr if none is set.
\sa setErrorHandler()
*/
@@ -2735,9 +2742,9 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing()
*/
/*!
- \fn QXmlLexicalHandler* QXmlReader::lexicalHandler() const
+ \fn QXmlLexicalHandler *QXmlReader::lexicalHandler() const
- Returns the lexical handler or 0 if none was set.
+ Returns the lexical handler or \nullptr if none was set.
\sa setLexicalHandler()
*/
@@ -2751,9 +2758,9 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing()
*/
/*!
- \fn QXmlDeclHandler* QXmlReader::declHandler() const
+ \fn QXmlDeclHandler *QXmlReader::declHandler() const
- Returns the declaration handler or 0 if none was set.
+ Returns the declaration handler or \nullptr if none was set.
\sa setDeclHandler()
*/