summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/global/qt-html-templates-offline.qdocconf2
-rw-r--r--doc/global/qt-html-templates-online.qdocconf2
-rw-r--r--mkspecs/linux-clang-32/qmake.conf20
-rw-r--r--mkspecs/linux-clang-32/qplatformdefs.h40
-rw-r--r--mkspecs/linux-clang-libc++-32/qmake.conf10
-rw-r--r--mkspecs/linux-clang-libc++-32/qplatformdefs.h40
-rw-r--r--src/corelib/configure.json7
-rw-r--r--src/corelib/global/qglobal.cpp13
-rw-r--r--src/corelib/global/qglobal.h9
-rw-r--r--src/corelib/io/qbuffer.cpp4
-rw-r--r--src/corelib/io/qdir.cpp6
-rw-r--r--src/corelib/io/qfiledevice.h2
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice_p.h12
-rw-r--r--src/corelib/io/qresource.cpp6
-rw-r--r--src/corelib/io/qresource_p.h56
-rw-r--r--src/corelib/itemmodels/itemmodels.pri8
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.cpp11
-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/qsortfilterproxymodel.cpp2
-rw-r--r--src/corelib/itemmodels/qstringlistmodel.cpp86
-rw-r--r--src/corelib/itemmodels/qstringlistmodel.h7
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib.cpp5
-rw-r--r--src/corelib/kernel/qmetatype.cpp4
-rw-r--r--src/corelib/kernel/qobject.cpp3
-rw-r--r--src/corelib/kernel/qobject_p.h4
-rw-r--r--src/corelib/mimetypes/qmimeprovider_p.h16
-rw-r--r--src/corelib/plugin/qplugin.h26
-rw-r--r--src/corelib/statemachine/qsignaltransition_p.h2
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp4
-rw-r--r--src/corelib/tools/qbytearray.cpp4
-rw-r--r--src/corelib/tools/qlocale.cpp28
-rw-r--r--src/corelib/tools/qlocale.h8
-rw-r--r--src/corelib/tools/qlocale.qdoc627
-rw-r--r--src/corelib/tools/qlocale_data_p.h32
-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.h197
-rw-r--r--src/corelib/tools/qstring.h6
-rw-r--r--src/corelib/tools/tools.pri1
-rw-r--r--src/gui/accessible/qaccessibleobject.h2
-rw-r--r--src/gui/image/qimageiohandler.h2
-rw-r--r--src/gui/image/qppmhandler.cpp2
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.cpp6
-rw-r--r--src/gui/itemmodels/qstandarditemmodel_p.h2
-rw-r--r--src/gui/kernel/qguiapplication.h2
-rw-r--r--src/gui/kernel/qoffscreensurface.h2
-rw-r--r--src/gui/kernel/qopenglcontext_p.h2
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h2
-rw-r--r--src/gui/kernel/qplatformgraphicsbuffer.h2
-rw-r--r--src/gui/kernel/qplatforminputcontext.h2
-rw-r--r--src/gui/kernel/qsessionmanager_p.h2
-rw-r--r--src/gui/kernel/qsimpledrag_p.h2
-rw-r--r--src/gui/kernel/qwindow.cpp27
-rw-r--r--src/gui/kernel/qwindow.h5
-rw-r--r--src/gui/kernel/qwindow_p.h2
-rw-r--r--src/gui/opengl/qopenglpaintdevice.h2
-rw-r--r--src/gui/opengl/qopenglshaderprogram.h4
-rw-r--r--src/gui/painting/qcolor.cpp23
-rw-r--r--src/gui/painting/qcolor.h6
-rw-r--r--src/gui/painting/qpdfwriter.cpp2
-rw-r--r--src/gui/text/qsyntaxhighlighter.h2
-rw-r--r--src/gui/text/qtextodfwriter.cpp2
-rw-r--r--src/network/access/qnetworkcookiejar.cpp21
-rw-r--r--src/network/kernel/qauthenticator.cpp15
-rw-r--r--src/network/kernel/qauthenticator_p.h2
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp18
-rw-r--r--src/sql/models/qsqltablemodel.cpp10
-rw-r--r--src/sql/models/qsqltablemodel.h3
-rw-r--r--src/widgets/itemviews/qheaderview.cpp6
-rw-r--r--src/widgets/itemviews/qitemdelegate.cpp2
-rw-r--r--src/widgets/itemviews/qlistview.cpp35
-rw-r--r--src/widgets/itemviews/qlistview_p.h8
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp44
-rw-r--r--src/widgets/itemviews/qlistwidget_p.h4
-rw-r--r--src/widgets/itemviews/qtableview.cpp4
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp30
-rw-r--r--src/widgets/itemviews/qtablewidget_p.h3
-rw-r--r--src/widgets/itemviews/qtreeview.cpp11
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp29
-rw-r--r--src/widgets/itemviews/qtreewidget_p.h4
-rw-r--r--src/widgets/styles/qcommonstyle.cpp2
-rw-r--r--src/widgets/styles/qstyle.h4
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp11
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp3
-rw-r--r--tests/auto/corelib/itemmodels/itemmodels.pro1
-rw-r--r--tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro5
-rw-r--r--tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp823
-rw-r--r--tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp176
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro1
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore3
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp39
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/staticplugin/staticplugin.pro7
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst/tst.pro5
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp37
-rw-r--r--tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp30
-rw-r--r--tests/auto/corelib/tools/qlocale/tst_qlocale.cpp18
-rw-r--r--tests/auto/corelib/tools/qoffsetstringarray/qoffsetstringarray.pro6
-rw-r--r--tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp121
-rw-r--r--tests/auto/corelib/tools/tools.pro1
-rw-r--r--tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp6
-rw-r--r--tests/auto/tools/rcc/data/sizes/data/data-0.txt0
-rw-r--r--tests/auto/tools/rcc/data/sizes/data/data-1.txt1
-rw-r--r--tests/auto/tools/rcc/data/sizes/data/data-2.txt1
-rw-r--r--tests/auto/tools/rcc/data/sizes/data/data-35.txt1
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-0.expected88
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-0.qrc5
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-1.expected89
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-1.qrc5
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected126
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-2-0-35-1.qrc8
-rw-r--r--tests/auto/tools/rcc/rcc.pro7
-rw-r--r--tests/auto/tools/rcc/tst_rcc.cpp47
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp4
-rw-r--r--tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp4
-rw-r--r--tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp133
-rw-r--r--tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp26
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp9
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp45
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp11
-rw-r--r--tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp18
-rw-r--r--tests/benchmarks/widgets/itemviews/itemviews.pro3
-rw-r--r--tests/benchmarks/widgets/itemviews/qlistview/qlistview.pro7
-rw-r--r--tests/benchmarks/widgets/itemviews/qlistview/tst_qlistview.cpp68
-rw-r--r--tests/manual/widgets/itemviews/itemviews.pro8
-rw-r--r--tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/main.cpp88
-rw-r--r--tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro8
-rwxr-xr-xutil/local_database/cldr2qlocalexml.py139
-rw-r--r--util/local_database/enumdata.py1533
-rw-r--r--util/local_database/xpathlite.py4
131 files changed, 4939 insertions, 1375 deletions
diff --git a/doc/global/qt-html-templates-offline.qdocconf b/doc/global/qt-html-templates-offline.qdocconf
index d5780a35da..f9baab9d19 100644
--- a/doc/global/qt-html-templates-offline.qdocconf
+++ b/doc/global/qt-html-templates-offline.qdocconf
@@ -3,6 +3,8 @@ include(html-config.qdocconf)
include(html-header-offline.qdocconf)
include(html-footer.qdocconf)
+defines += offlinedocs
+
#uncomment if navigation bar is not wanted
#HTML.nonavigationbar = "true"
diff --git a/doc/global/qt-html-templates-online.qdocconf b/doc/global/qt-html-templates-online.qdocconf
index 69c399d05a..f1437a2d9c 100644
--- a/doc/global/qt-html-templates-online.qdocconf
+++ b/doc/global/qt-html-templates-online.qdocconf
@@ -4,6 +4,8 @@ HTML.tocdepth = 2
include(html-header-online.qdocconf)
include(html-footer-online.qdocconf)
+defines += onlinedocs
+
#uncomment if navigation bar is not wanted
#HTML.nonavigationbar = "true"
diff --git a/mkspecs/linux-clang-32/qmake.conf b/mkspecs/linux-clang-32/qmake.conf
new file mode 100644
index 0000000000..de872e7431
--- /dev/null
+++ b/mkspecs/linux-clang-32/qmake.conf
@@ -0,0 +1,20 @@
+#
+# qmake configuration for linux-clang
+#
+
+MAKEFILE_GENERATOR = UNIX
+CONFIG += incremental
+
+QMAKE_INCREMENTAL_STYLE = sublib
+
+include(../common/linux.conf)
+
+QMAKE_CFLAGS = -m32
+QMAKE_LFLAGS = -m32
+
+include(../common/gcc-base-unix.conf)
+include(../common/clang.conf)
+
+QMAKE_LFLAGS += -ccc-gcc-name g++
+
+load(qt_config)
diff --git a/mkspecs/linux-clang-32/qplatformdefs.h b/mkspecs/linux-clang-32/qplatformdefs.h
new file mode 100644
index 0000000000..8f5ce17858
--- /dev/null
+++ b/mkspecs/linux-clang-32/qplatformdefs.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../linux-clang/qplatformdefs.h"
diff --git a/mkspecs/linux-clang-libc++-32/qmake.conf b/mkspecs/linux-clang-libc++-32/qmake.conf
new file mode 100644
index 0000000000..f4c006d383
--- /dev/null
+++ b/mkspecs/linux-clang-libc++-32/qmake.conf
@@ -0,0 +1,10 @@
+#
+# qmake configuration for linux-clang and libc++
+#
+
+include(../linux-clang-32/qmake.conf)
+
+QMAKE_CXXFLAGS += -stdlib=libc++
+QMAKE_LFLAGS += -stdlib=libc++
+
+load(qt_config)
diff --git a/mkspecs/linux-clang-libc++-32/qplatformdefs.h b/mkspecs/linux-clang-libc++-32/qplatformdefs.h
new file mode 100644
index 0000000000..8f5ce17858
--- /dev/null
+++ b/mkspecs/linux-clang-libc++-32/qplatformdefs.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../linux-clang/qplatformdefs.h"
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index 183eb3a13e..f09ef6c1dd 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -793,6 +793,13 @@
"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.",
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index a369bbe490..6c608dab74 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -2142,11 +2142,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)
{
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index b608489576..f56629faa1 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -591,11 +591,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
@@ -1186,9 +1186,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/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/qdir.cpp b/src/corelib/io/qdir.cpp
index 39422c3401..fb3a2f0aea 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -1040,7 +1040,7 @@ QStringList QDir::nameFilters() const
list of filters specified by \a nameFilters.
Each name filter is a wildcard (globbing) filter that understands
- \c{*} and \c{?} wildcards. (See \l{QRegularExpression wildcard matching}.)
+ \c{*} and \c{?} wildcards. (See \l{Wildcard matching}.)
For example, the following code sets three name filters on a QDir
to ensure that only files with extensions typically used for C++
@@ -2120,7 +2120,7 @@ QString QDir::rootPath()
patterns in the list of \a filters; otherwise returns \c false. The
matching is case insensitive.
- \sa {QRegularExpression Wildcard matching}, QRegularExpression::wildcardToRegularExpression(),
+ \sa {Wildcard matching}, QRegularExpression::wildcardToRegularExpression(),
entryList(), entryInfoList()
*/
bool QDir::match(const QStringList &filters, const QString &fileName)
@@ -2143,7 +2143,7 @@ bool QDir::match(const QStringList &filters, const QString &fileName)
contain multiple patterns separated by spaces or semicolons.
The matching is case insensitive.
- \sa {QRegularExpression wildcard matching}, QRegularExpression::wildcardToRegularExpression,
+ \sa {Wildcard matching}, QRegularExpression::wildcardToRegularExpression,
entryList(), entryInfoList()
*/
bool QDir::match(const QString &filter, const QString &fileName)
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/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/qresource.cpp b/src/corelib/io/qresource.cpp
index 367cd78d65..19ce9ef517 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -905,8 +905,8 @@ 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)
@@ -988,7 +988,7 @@ public:
}
}
QString mappingFile() const { return fileName; }
- virtual ResourceRootType type() const override { return Resource_File; }
+ ResourceRootType type() const override { return Resource_File; }
bool registerSelf(const QString &f) {
bool fromMM = false;
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/itemmodels/itemmodels.pri b/src/corelib/itemmodels/itemmodels.pri
index 068a8c4b3a..5a977c6623 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
diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp
index b7c49a53e4..095ab6fc71 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.cpp
+++ b/src/corelib/itemmodels/qabstractproxymodel.cpp
@@ -313,6 +313,17 @@ 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
+ */
+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 c4e5d67908..6d9daee75a 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..bbfe2dce16
--- /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 proxy index.
+*/
+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 index is valid, the flags come from the source model for this index.
+ If the 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/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index 31b9bbc990..5d1a916df0 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 567e6fa35e..3cc0bee8ef 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.
@@ -185,18 +221,22 @@ bool QStringListModel::setData(const QModelIndex &index, const QVariant &value,
if (index.row() >= 0 && index.row() < lst.size()
&& (role == Qt::EditRole || role == Qt::DisplayRole)) {
lst.replace(index.row(), value.toString());
- 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
+ */
+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.
@@ -249,6 +289,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 a40c13ae40..6c83917054 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/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp
index 4c780a9294..d2201df41b 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/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index eb67544f21..af838ab090 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
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 3cb8c45b41..1917f318c6 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -2142,7 +2142,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 can not be blocked.
All the objects's children are destroyed immediately after this
signal is emitted.
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 6aea40cf4a..c4e1c69883 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -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/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h
index b2be545cf8..97504fe99a 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/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/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/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 24734f99ac..6f0306f80c 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/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index b53a60b9bf..1e591d6d69 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -3885,9 +3885,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)) {
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index ddc973cb37..38bd195fba 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());
@@ -2353,7 +2358,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
return QLocale(*systemLocalePrivate->data());
}
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index f3afb8c406..af0eb2929e 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 {
@@ -1091,6 +1096,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;
diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc
index 5c0a9b63e5..0f83a765a5 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()
diff --git a/src/corelib/tools/qlocale_data_p.h b/src/corelib/tools/qlocale_data_p.h
index aeeec2b085..fcff04011f 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-08-13 from the
+ This part of the file was generated on 2018-08-15 from the
Common Locale Data Repository v33.1
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[] = {
564, // Cantonese
0, // Osage
0, // Tangut
+ 566, // Ido
+ 567, // Lojban
+ 568, // Sicilian
+ 569, // Southern Kurdish
+ 570, // Western Balochi
0 // trailing 0
};
@@ -1823,6 +1833,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 , 38181,77 , 38181,77 , 158,27 , 38181,77 , 38181,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 , 5731,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 , 951,5 , 951,5 , 412,8 , 441,14 , 198,6 , 215,13 , 4671,39 , 4671,39 , 158,27 , 4671,39 , 4671,39 , 158,27 , 2023,28 , 2023,28 , 2051,14 , 2023,28 , 2023,28 , 2051,14 , 60,2 , 57,2 , 45,4 , 5,17 , 22,23 , {72,75,68}, 130,3 , 17057,11 , 4,4 , 4,0 , 5742,2 , 5744,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 , 951,5 , 951,5 , 412,8 , 420,13 , 198,6 , 204,11 , 4671,39 , 4710,38 , 158,27 , 4671,39 , 4710,38 , 158,27 , 2002,21 , 2023,28 , 2051,14 , 2002,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 129,1 , 3122,13 , 4,4 , 4,0 , 5758,2 , 5760,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}, 172,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 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
};
@@ -6667,6 +6682,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[] = {
@@ -7030,6 +7050,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[] =
@@ -8213,6 +8238,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 f2e11499c8..f7dbb3a815 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;
@@ -364,8 +366,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;
@@ -375,6 +375,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..076316396b
--- /dev/null
+++ b/src/corelib/tools/qoffsetstringarray_p.h
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** 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];
+
+ constexpr StaticString(const StaticString<N> &other) noexcept = default;
+};
+
+
+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>{};
+}
+
+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...));
+}
+} // 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/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/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/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/image/qimageiohandler.h b/src/gui/image/qimageiohandler.h
index 35984dd6a5..990df96534 100644
--- a/src/gui/image/qimageiohandler.h
+++ b/src/gui/image/qimageiohandler.h
@@ -141,7 +141,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/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index 53e3fa293d..1863c58ff0 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -123,7 +123,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)
diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp
index 8ec88ebc60..aa640f4d7e 100644
--- a/src/gui/itemmodels/qstandarditemmodel.cpp
+++ b/src/gui/itemmodels/qstandarditemmodel.cpp
@@ -3010,11 +3010,17 @@ 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.
\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/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/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_p.h b/src/gui/kernel/qopenglcontext_p.h
index 4f2f951d61..1cb7390687 100644
--- a/src/gui/kernel/qopenglcontext_p.h
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -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/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index bfcb658172..2c050535d8 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -153,7 +153,7 @@ public:
Q_ENUM(ButtonLayout)
QPlatformDialogHelper();
- virtual ~QPlatformDialogHelper();
+ ~QPlatformDialogHelper();
virtual QVariant styleHint(StyleHint hint) const;
diff --git a/src/gui/kernel/qplatformgraphicsbuffer.h b/src/gui/kernel/qplatformgraphicsbuffer.h
index 0aeef946e6..65c24bebc9 100644
--- a/src/gui/kernel/qplatformgraphicsbuffer.h
+++ b/src/gui/kernel/qplatformgraphicsbuffer.h
@@ -78,7 +78,7 @@ public:
OriginTopLeft
};
- 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/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/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/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 3d7d22959d..17a18f3c9a 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1328,16 +1328,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)
{
@@ -1354,19 +1356,28 @@ void QWindow::setTransientParent(QWindow *parent)
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 bf5e645114..25f9a8a9b2 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -148,6 +148,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;
@@ -191,6 +192,7 @@ public:
bool blockedByModalWindow;
bool updateRequestPending;
+ bool transientParentPropertySet = false;
QPointer<QWindow> transientParent;
QPointer<QScreen> topLevelScreen;
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/qopenglshaderprogram.h b/src/gui/opengl/qopenglshaderprogram.h
index 84eb8d6956..bdd18c9d68 100644
--- a/src/gui/opengl/qopenglshaderprogram.h
+++ b/src/gui/opengl/qopenglshaderprogram.h
@@ -80,7 +80,7 @@ public:
Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit)
explicit QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent = nullptr);
- virtual ~QOpenGLShader();
+ ~QOpenGLShader();
QOpenGLShader::ShaderType shaderType() const;
@@ -115,7 +115,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/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 1d7375d1df..ef3296a6d4 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -2487,6 +2487,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
@@ -2498,7 +2507,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;
@@ -2518,6 +2527,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.
@@ -2527,7 +2546,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;
diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h
index f7a9e9db59..a9b05ae7e3 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
diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp
index e6c5cabd7f..5f0fad2a4e 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/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/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index d8218ab613..5f6a24cc5d 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();
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/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/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
index c70d507b99..00a0643dd1 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
@@ -1930,13 +1930,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;
@@ -1946,9 +1946,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;
@@ -1970,6 +1968,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/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/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 7bfa51337d..b7de69d63a 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -3874,9 +3874,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..9c65d5fddd 100644
--- a/src/widgets/itemviews/qitemdelegate.cpp
+++ b/src/widgets/itemviews/qitemdelegate.cpp
@@ -1089,7 +1089,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/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index e5769940d4..fdac332367 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -2246,8 +2246,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);
}
@@ -2687,21 +2687,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;
@@ -2720,7 +2723,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;
@@ -3354,9 +3357,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 181386d4d0..3f997ef7e3 100644
--- a/src/widgets/itemviews/qlistview_p.h
+++ b/src/widgets/itemviews/qlistview_p.h
@@ -377,6 +377,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 72e0a67a64..895622616e 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);
}
/**
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/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index 9725a768de..e7edd08d2a 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -1383,12 +1383,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)
diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index 11925af7a0..169cc5a17c 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);
}
}
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 b534de5c6a..920e3b346b 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -1088,15 +1088,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);
}
/*!
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index a0af27115d..4768869843 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);
}
}
@@ -2164,9 +2185,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;
}
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/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 3ee3e856bc..87d233f024 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -3067,7 +3067,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;
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index 9192dae864..8256f908db 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -308,8 +308,8 @@ public:
SE_TabWidgetLeftCorner,
SE_TabWidgetRightCorner,
- SE_ViewItemCheckIndicator, // ### Qt 6: remove
- SE_ItemViewItemCheckIndicator = SE_ViewItemCheckIndicator,
+ SE_ItemViewItemCheckIndicator,
+ SE_ViewItemCheckIndicator = SE_ItemViewItemCheckIndicator, // ### Qt 6: remove
SE_TabBarTearIndicator,
SE_TabBarTearIndicatorLeft = SE_TabBarTearIndicator,
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index c2ffcc82b1..5c9d19a49d 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>
@@ -952,8 +953,12 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject
Attachment attachment = Attachment_Scroll;
origin = Origin_Padding;
Origin clip = Origin_Border;
- if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip))
- bg = new QStyleSheetBackgroundData(brush, QPixmap(uri), repeat, alignment, origin, attachment, clip);
+ if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip)) {
+ QPixmap pixmap(uri);
+ 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;
QBrush sbg, abg;
@@ -5818,7 +5823,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/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 40b1077656..63db93d43f 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -1609,7 +1609,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();
@@ -2892,6 +2892,7 @@ void QPlainTextEdit::setCenterOnScroll(bool enabled)
if (enabled == d->centerOnScroll)
return;
d->centerOnScroll = enabled;
+ d->_q_adjustScrollbars();
}
diff --git a/tests/auto/corelib/itemmodels/itemmodels.pro b/tests/auto/corelib/itemmodels/itemmodels.pro
index bcb6e604f8..0346341be6 100644
--- a/tests/auto/corelib/itemmodels/itemmodels.pro
+++ b/tests/auto/corelib/itemmodels/itemmodels.pro
@@ -5,6 +5,7 @@ SUBDIRS = qabstractitemmodel \
qtHaveModule(gui): SUBDIRS += \
qabstractproxymodel \
+ qconcatenatetablesproxymodel \
qidentityproxymodel \
qitemselectionmodel \
qsortfilterproxymodel_recursive \
diff --git a/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro
new file mode 100644
index 0000000000..ee4ea28b5b
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase
+TARGET = tst_qconcatenatetablesproxymodel
+QT = core gui testlib
+
+SOURCES = tst_qconcatenatetablesproxymodel.cpp
diff --git a/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
new file mode 100644
index 0000000000..40617c1f7d
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
@@ -0,0 +1,823 @@
+/****************************************************************************
+**
+** 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 <QSignalSpy>
+#include <QSortFilterProxyModel>
+#include <QTest>
+#include <QStandardItemModel>
+#include <QIdentityProxyModel>
+#include <QItemSelectionModel>
+#include <QMimeData>
+#include <QStringListModel>
+#include <QAbstractItemModelTester>
+
+#include <qconcatenatetablesproxymodel.h>
+
+Q_DECLARE_METATYPE(QModelIndex)
+
+// Extracts a full row from a model as a string
+// Works best if every cell contains only one character
+static QString extractRowTexts(QAbstractItemModel *model, int row, const QModelIndex &parent = QModelIndex())
+{
+ QString result;
+ const int colCount = model->columnCount();
+ for (int col = 0; col < colCount; ++col) {
+ const QString txt = model->index(row, col, parent).data().toString();
+ result += txt.isEmpty() ? QStringLiteral(" ") : txt;
+ }
+ return result;
+}
+
+// Extracts a full column from a model as a string
+// Works best if every cell contains only one character
+static QString extractColumnTexts(QAbstractItemModel *model, int column, const QModelIndex &parent = QModelIndex())
+{
+ QString result;
+ const int rowCount = model->rowCount();
+ for (int row = 0; row < rowCount; ++row) {
+ const QString txt = model->index(row, column, parent).data().toString();
+ result += txt.isEmpty() ? QStringLiteral(" ") : txt;
+ }
+ return result;
+}
+
+static QString rowSpyToText(const QSignalSpy &spy)
+{
+ if (!spy.isValid())
+ return QStringLiteral("THE SIGNALSPY IS INVALID!");
+ QString str;
+ for (int i = 0; i < spy.count(); ++i) {
+ str += spy.at(i).at(1).toString() + QLatin1Char(',') + spy.at(i).at(2).toString();
+ if (i + 1 < spy.count())
+ str += QLatin1Char(';');
+ }
+ return str;
+}
+
+class tst_QConcatenateTablesProxyModel : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void init();
+ void shouldAggregateTwoModelsCorrectly();
+ void shouldAggregateThenRemoveTwoEmptyModelsCorrectly();
+ void shouldAggregateTwoEmptyModelsWhichThenGetFilled();
+ void shouldHandleDataChanged();
+ void shouldHandleSetData();
+ void shouldHandleSetItemData();
+ void shouldHandleRowInsertionAndRemoval();
+ void shouldAggregateAnotherModelThenRemoveModels();
+ void shouldUseSmallestColumnCount();
+ void shouldIncreaseColumnCountWhenRemovingFirstModel();
+ void shouldHandleColumnInsertionAndRemoval();
+ void shouldPropagateLayoutChanged();
+ void shouldReactToModelReset();
+ void shouldUpdateColumnsOnModelReset();
+ void shouldPropagateDropOnItem_data();
+ void shouldPropagateDropOnItem();
+ void shouldPropagateDropBetweenItems();
+ void shouldPropagateDropBetweenItemsAtModelBoundary();
+ void shouldPropagateDropAfterLastRow_data();
+ void shouldPropagateDropAfterLastRow();
+
+private:
+ QStandardItemModel mod;
+ QStandardItemModel mod2;
+ QStandardItemModel mod3;
+};
+
+void tst_QConcatenateTablesProxyModel::init()
+{
+ // Prepare some source models to use later on
+ mod.clear();
+ mod.appendRow({ new QStandardItem(QStringLiteral("A")), new QStandardItem(QStringLiteral("B")), new QStandardItem(QStringLiteral("C")) });
+ mod.setHorizontalHeaderLabels(QStringList() << QStringLiteral("H1") << QStringLiteral("H2") << QStringLiteral("H3"));
+ mod.setVerticalHeaderLabels(QStringList() << QStringLiteral("One"));
+
+ mod2.clear();
+ mod2.appendRow({ new QStandardItem(QStringLiteral("D")), new QStandardItem(QStringLiteral("E")), new QStandardItem(QStringLiteral("F")) });
+ mod2.setHorizontalHeaderLabels(QStringList() << QStringLiteral("H1") << QStringLiteral("H2") << QStringLiteral("H3"));
+ mod2.setVerticalHeaderLabels(QStringList() << QStringLiteral("Two"));
+
+ mod3.clear();
+ mod3.appendRow({ new QStandardItem(QStringLiteral("1")), new QStandardItem(QStringLiteral("2")), new QStandardItem(QStringLiteral("3")) });
+ mod3.appendRow({ new QStandardItem(QStringLiteral("4")), new QStandardItem(QStringLiteral("5")), new QStandardItem(QStringLiteral("6")) });
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateTwoModelsCorrectly()
+{
+ // Given a combining proxy
+ QConcatenateTablesProxyModel pm;
+
+ // When adding two source models
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ // Then the proxy should show 2 rows
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // ... and correct headers
+ QCOMPARE(pm.headerData(0, Qt::Horizontal).toString(), QStringLiteral("H1"));
+ QCOMPARE(pm.headerData(1, Qt::Horizontal).toString(), QStringLiteral("H2"));
+ QCOMPARE(pm.headerData(2, Qt::Horizontal).toString(), QStringLiteral("H3"));
+ QCOMPARE(pm.headerData(0, Qt::Vertical).toString(), QStringLiteral("One"));
+ QCOMPARE(pm.headerData(1, Qt::Vertical).toString(), QStringLiteral("Two"));
+
+ QVERIFY(!pm.canFetchMore(QModelIndex()));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateThenRemoveTwoEmptyModelsCorrectly()
+{
+ // Given a combining proxy
+ QConcatenateTablesProxyModel pm;
+
+ // When adding two empty models
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ QIdentityProxyModel i1, i2;
+ pm.addSourceModel(&i1);
+ pm.addSourceModel(&i2);
+
+ // Then the proxy should still be empty (and no signals emitted)
+ QCOMPARE(pm.rowCount(), 0);
+ QCOMPARE(pm.columnCount(), 0);
+ QCOMPARE(rowATBISpy.count(), 0);
+ QCOMPARE(rowInsertedSpy.count(), 0);
+
+ // When removing the empty models
+ pm.removeSourceModel(&i1);
+ pm.removeSourceModel(&i2);
+
+ // Then the proxy should still be empty (and no signals emitted)
+ QCOMPARE(pm.rowCount(), 0);
+ QCOMPARE(pm.columnCount(), 0);
+ QCOMPARE(rowATBRSpy.count(), 0);
+ QCOMPARE(rowRemovedSpy.count(), 0);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateTwoEmptyModelsWhichThenGetFilled()
+{
+ // Given a combining proxy with two empty models
+ QConcatenateTablesProxyModel pm;
+ QIdentityProxyModel i1, i2;
+ pm.addSourceModel(&i1);
+ pm.addSourceModel(&i2);
+
+ // When filling them afterwards
+ i1.setSourceModel(&mod);
+ i2.setSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ // Then the proxy should show 2 rows
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // ... and correct headers
+ QCOMPARE(pm.headerData(0, Qt::Horizontal).toString(), QStringLiteral("H1"));
+ QCOMPARE(pm.headerData(1, Qt::Horizontal).toString(), QStringLiteral("H2"));
+ QCOMPARE(pm.headerData(2, Qt::Horizontal).toString(), QStringLiteral("H3"));
+ QCOMPARE(pm.headerData(0, Qt::Vertical).toString(), QStringLiteral("One"));
+ QCOMPARE(pm.headerData(1, Qt::Vertical).toString(), QStringLiteral("Two"));
+
+ QVERIFY(!pm.canFetchMore(QModelIndex()));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleDataChanged()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+ // When a cell in a source model changes
+ mod.item(0, 0)->setData("a", Qt::EditRole);
+
+ // Then the change should be notified to the proxy
+ QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(dataChangedSpy.at(0).at(0).toModelIndex(), pm.index(0, 0));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("aBC"));
+
+ // Same test with the other model
+ mod2.item(0, 2)->setData("f", Qt::EditRole);
+
+ QCOMPARE(dataChangedSpy.count(), 2);
+ QCOMPARE(dataChangedSpy.at(1).at(0).toModelIndex(), pm.index(1, 2));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEf"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleSetData()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+ // When changing a cell using setData
+ pm.setData(pm.index(0, 0), "a");
+
+ // Then the change should be notified to the proxy
+ QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(dataChangedSpy.at(0).at(0).toModelIndex(), pm.index(0, 0));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("aBC"));
+
+ // Same test with the other model
+ pm.setData(pm.index(1, 2), "f");
+
+ QCOMPARE(dataChangedSpy.count(), 2);
+ QCOMPARE(dataChangedSpy.at(1).at(0).toModelIndex(), pm.index(1, 2));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEf"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleSetItemData()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+ // When changing a cell using setData
+ pm.setItemData(pm.index(0, 0), QMap<int, QVariant>{ std::make_pair<int, QVariant>(Qt::DisplayRole, QStringLiteral("X")),
+ std::make_pair<int, QVariant>(Qt::UserRole, 88) });
+
+ // Then the change should be notified to the proxy
+ QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(dataChangedSpy.at(0).at(0).toModelIndex(), pm.index(0, 0));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("XBC"));
+ QCOMPARE(pm.index(0, 0).data(Qt::UserRole).toInt(), 88);
+
+ // Same test with the other model
+ pm.setItemData(pm.index(1, 2), QMap<int, QVariant>{ std::make_pair<int, QVariant>(Qt::DisplayRole, QStringLiteral("Y")),
+ std::make_pair<int, QVariant>(Qt::UserRole, 89) });
+
+ QCOMPARE(dataChangedSpy.count(), 2);
+ QCOMPARE(dataChangedSpy.at(1).at(0).toModelIndex(), pm.index(1, 2));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEY"));
+ QCOMPARE(pm.index(1, 2).data(Qt::UserRole).toInt(), 89);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleRowInsertionAndRemoval()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+
+ // When a source model inserts a new row
+ QList<QStandardItem *> row;
+ row.append(new QStandardItem(QStringLiteral("1")));
+ row.append(new QStandardItem(QStringLiteral("2")));
+ row.append(new QStandardItem(QStringLiteral("3")));
+ mod2.insertRow(0, row);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowSpyToText(rowATBISpy), QStringLiteral("1,1"));
+ QCOMPARE(rowSpyToText(rowInsertedSpy), QStringLiteral("1,1"));
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When removing that row
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ mod2.removeRow(0);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowATBRSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.count(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // When removing the last row from mod2
+ rowATBRSpy.clear();
+ rowRemovedSpy.clear();
+ mod2.removeRow(0);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowATBRSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.count(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(pm.rowCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateAnotherModelThenRemoveModels()
+{
+ // Given two models combined, and a third model
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+
+ // When adding the new source model
+ pm.addSourceModel(&mod3);
+
+ // Then the proxy should notify its users about the two rows inserted
+ QCOMPARE(rowSpyToText(rowATBISpy), QStringLiteral("2,3"));
+ QCOMPARE(rowSpyToText(rowInsertedSpy), QStringLiteral("2,3"));
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("456"));
+
+ // When removing that source model again
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ pm.removeSourceModel(&mod3);
+
+ // Then the proxy should notify its users about the row removed
+ QCOMPARE(rowATBRSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 2);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 3);
+ QCOMPARE(rowRemovedSpy.count(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 2);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 3);
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // When removing model 2
+ rowATBRSpy.clear();
+ rowRemovedSpy.clear();
+ pm.removeSourceModel(&mod2);
+ QCOMPARE(rowATBRSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.count(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(pm.rowCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+
+ // When removing model 1
+ rowATBRSpy.clear();
+ rowRemovedSpy.clear();
+ pm.removeSourceModel(&mod);
+ QCOMPARE(rowATBRSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 0);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 0);
+ QCOMPARE(rowRemovedSpy.count(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 0);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 0);
+ QCOMPARE(pm.rowCount(), 0);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldUseSmallestColumnCount()
+{
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ mod2.setColumnCount(1);
+ pm.addSourceModel(&mod3);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(pm.columnCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("A"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("D"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("1"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("4"));
+
+ const QModelIndex indexA = pm.mapFromSource(mod.index(0, 0));
+ QVERIFY(indexA.isValid());
+ QCOMPARE(indexA, pm.index(0, 0));
+
+ const QModelIndex indexB = pm.mapFromSource(mod.index(0, 1));
+ QVERIFY(!indexB.isValid());
+
+ const QModelIndex indexD = pm.mapFromSource(mod2.index(0, 0));
+ QVERIFY(indexD.isValid());
+ QCOMPARE(indexD, pm.index(1, 0));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldIncreaseColumnCountWhenRemovingFirstModel()
+{
+ // Given a model with 2 columns and one with 3 columns
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+ mod.setColumnCount(2);
+ pm.addSourceModel(&mod2);
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 2);
+
+ QSignalSpy colATBISpy(&pm, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy colInsertedSpy(&pm, SIGNAL(columnsInserted(QModelIndex,int,int)));
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+
+ // When removing the first source model
+ pm.removeSourceModel(&mod);
+
+ // Then the proxy should notify its users about the row removed, and the column added
+ QCOMPARE(pm.rowCount(), 1);
+ QCOMPARE(pm.columnCount(), 3);
+ QCOMPARE(rowSpyToText(rowATBRSpy), QStringLiteral("0,0"));
+ QCOMPARE(rowSpyToText(rowRemovedSpy), QStringLiteral("0,0"));
+ QCOMPARE(rowSpyToText(colATBISpy), QStringLiteral("2,2"));
+ QCOMPARE(rowSpyToText(colInsertedSpy), QStringLiteral("2,2"));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("DEF"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleColumnInsertionAndRemoval()
+{
+ // Given two models combined, one with 2 columns and one with 3
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+ mod.setColumnCount(2);
+ pm.addSourceModel(&mod2);
+ QSignalSpy colATBISpy(&pm, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy colInsertedSpy(&pm, SIGNAL(columnsInserted(QModelIndex,int,int)));
+ QSignalSpy colATBRSpy(&pm, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy colRemovedSpy(&pm, SIGNAL(columnsRemoved(QModelIndex,int,int)));
+
+ // When the first source model inserts a new column
+ QCOMPARE(mod.columnCount(), 2);
+ mod.setColumnCount(3);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowSpyToText(colATBISpy), QStringLiteral("2,2"));
+ QCOMPARE(rowSpyToText(colInsertedSpy), QStringLiteral("2,2"));
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("AB "));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // And when removing two columns
+ mod.setColumnCount(1);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowSpyToText(colATBRSpy), QStringLiteral("1,2"));
+ QCOMPARE(rowSpyToText(colRemovedSpy), QStringLiteral("1,2"));
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("A"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("D"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateLayoutChanged()
+{
+ // Given two source models, the second one being a QSFPM
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QSortFilterProxyModel qsfpm;
+ qsfpm.setSourceModel(&mod3);
+ pm.addSourceModel(&qsfpm);
+
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("456"));
+
+ // And a selection (row 1)
+ QItemSelectionModel selection(&pm);
+ selection.select(pm.index(1, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows);
+ const QModelIndexList lst = selection.selectedIndexes();
+ QCOMPARE(lst.count(), 3);
+ for (int col = 0; col < lst.count(); ++col) {
+ QCOMPARE(lst.at(col).row(), 1);
+ QCOMPARE(lst.at(col).column(), col);
+ }
+
+ QSignalSpy layoutATBCSpy(&pm, SIGNAL(layoutAboutToBeChanged()));
+ QSignalSpy layoutChangedSpy(&pm, SIGNAL(layoutChanged()));
+
+ // When changing the sorting in the QSFPM
+ qsfpm.sort(0, Qt::DescendingOrder);
+
+ // Then the proxy should emit the layoutChanged signals, and show re-sorted data
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("123"));
+ QCOMPARE(layoutATBCSpy.count(), 1);
+ QCOMPARE(layoutChangedSpy.count(), 1);
+
+ // And the selection should be updated accordingly (it became row 2)
+ const QModelIndexList lstAfter = selection.selectedIndexes();
+ QCOMPARE(lstAfter.count(), 3);
+ for (int col = 0; col < lstAfter.count(); ++col) {
+ QCOMPARE(lstAfter.at(col).row(), 2);
+ QCOMPARE(lstAfter.at(col).column(), col);
+ }
+}
+
+void tst_QConcatenateTablesProxyModel::shouldReactToModelReset()
+{
+ // Given two source models, the second one being a QSFPM
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QSortFilterProxyModel qsfpm;
+ qsfpm.setSourceModel(&mod3);
+ pm.addSourceModel(&qsfpm);
+
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("456"));
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+ QSignalSpy colATBRSpy(&pm, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy colRemovedSpy(&pm, SIGNAL(columnsRemoved(QModelIndex,int,int)));
+ QSignalSpy modelATBResetSpy(&pm, SIGNAL(modelAboutToBeReset()));
+ QSignalSpy modelResetSpy(&pm, SIGNAL(modelReset()));
+
+ // When changing the source model of the QSFPM
+ qsfpm.setSourceModel(&mod2);
+
+ // Then the proxy should emit the reset signals, and show the new data
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+ QCOMPARE(rowATBRSpy.count(), 0);
+ QCOMPARE(rowRemovedSpy.count(), 0);
+ QCOMPARE(rowATBISpy.count(), 0);
+ QCOMPARE(rowInsertedSpy.count(), 0);
+ QCOMPARE(colATBRSpy.count(), 0);
+ QCOMPARE(colRemovedSpy.count(), 0);
+ QCOMPARE(modelATBResetSpy.count(), 1);
+ QCOMPARE(modelResetSpy.count(), 1);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldUpdateColumnsOnModelReset()
+{
+ // Given two source models, the first one being a QSFPM
+ QConcatenateTablesProxyModel pm;
+
+ QSortFilterProxyModel qsfpm;
+ qsfpm.setSourceModel(&mod3);
+ pm.addSourceModel(&qsfpm);
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("ABC"));
+
+ // ... and a model with only 2 columns
+ QStandardItemModel mod2Columns;
+ mod2Columns.appendRow({ new QStandardItem(QStringLiteral("W")), new QStandardItem(QStringLiteral("X")) });
+
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+ QSignalSpy colATBRSpy(&pm, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy colRemovedSpy(&pm, SIGNAL(columnsRemoved(QModelIndex,int,int)));
+ QSignalSpy modelATBResetSpy(&pm, SIGNAL(modelAboutToBeReset()));
+ QSignalSpy modelResetSpy(&pm, SIGNAL(modelReset()));
+
+ // When changing the source model of the QSFPM
+ qsfpm.setSourceModel(&mod2Columns);
+
+ // Then the proxy should reset, and show the new data
+ QCOMPARE(modelATBResetSpy.count(), 1);
+ QCOMPARE(modelResetSpy.count(), 1);
+ QCOMPARE(rowATBRSpy.count(), 0);
+ QCOMPARE(rowRemovedSpy.count(), 0);
+ QCOMPARE(rowATBISpy.count(), 0);
+ QCOMPARE(rowInsertedSpy.count(), 0);
+ QCOMPARE(colATBRSpy.count(), 0);
+ QCOMPARE(colRemovedSpy.count(), 0);
+
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("WX"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("AB"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropOnItem_data()
+{
+ QTest::addColumn<int>("sourceRow");
+ QTest::addColumn<int>("destRow");
+ QTest::addColumn<QString>("expectedResult");
+
+ QTest::newRow("0-3") << 0 << 3 << QStringLiteral("ABCA");
+ QTest::newRow("1-2") << 1 << 2 << QStringLiteral("ABBD");
+ QTest::newRow("2-1") << 2 << 1 << QStringLiteral("ACCD");
+ QTest::newRow("3-0") << 3 << 0 << QStringLiteral("DBCD");
+
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropOnItem()
+{
+ // Given two source models who handle drops
+
+ // Note: QStandardItemModel handles drop onto items by inserting child rows,
+ // which is good for QTreeView but not for QTableView or QConcatenateTablesProxyModel.
+ // So we use QStringListModel here instead.
+ QConcatenateTablesProxyModel pm;
+ QStringListModel model1({QStringLiteral("A"), QStringLiteral("B")});
+ QStringListModel model2({QStringLiteral("C"), QStringLiteral("D")});
+ pm.addSourceModel(&model1);
+ pm.addSourceModel(&model2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(extractColumnTexts(&pm, 0), QStringLiteral("ABCD"));
+
+ // When dragging one item
+ QFETCH(int, sourceRow);
+ QMimeData* mimeData = pm.mimeData({pm.index(sourceRow, 0)});
+ QVERIFY(mimeData);
+
+ // and dropping onto another item
+ QFETCH(int, destRow);
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, -1, -1, pm.index(destRow, 0)));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, -1, -1, pm.index(destRow, 0)));
+ delete mimeData;
+
+ // Then the result should be as expected
+ QFETCH(QString, expectedResult);
+ QCOMPARE(extractColumnTexts(&pm, 0), expectedResult);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropBetweenItems()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod3);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When dragging the last row
+ QModelIndexList indexes;
+ indexes.reserve(pm.columnCount());
+ for (int col = 0; col < pm.columnCount(); ++col) {
+ indexes.append(pm.index(2, col));
+ }
+ QMimeData* mimeData = pm.mimeData(indexes);
+ QVERIFY(mimeData);
+
+ // and dropping it before row 1
+ const int destRow = 1;
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ delete mimeData;
+
+ // Then a new row should be inserted
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("DEF"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropBetweenItemsAtModelBoundary()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod3);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When dragging the first row
+ QModelIndexList indexes;
+ indexes.reserve(pm.columnCount());
+ for (int col = 0; col < pm.columnCount(); ++col) {
+ indexes.append(pm.index(0, col));
+ }
+ QMimeData* mimeData = pm.mimeData(indexes);
+ QVERIFY(mimeData);
+
+ // and dropping it before row 2
+ const int destRow = 2;
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ delete mimeData;
+
+ // Then a new row should be inserted
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("DEF"));
+
+ // and it should be part of the second model
+ QCOMPARE(mod2.rowCount(), 2);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropAfterLastRow_data()
+{
+ QTest::addColumn<int>("destRow");
+
+ // Dropping after the last row is documented to be done with destRow == -1.
+ QTest::newRow("-1") << -1;
+ // However, sometimes QTreeView calls dropMimeData with destRow == rowCount...
+ // Not sure if that's a bug or not, but let's support it in the model, just in case.
+ QTest::newRow("3") << 3;
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropAfterLastRow()
+{
+ QFETCH(int, destRow);
+
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod3);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When dragging the second row
+ QModelIndexList indexes;
+ indexes.reserve(pm.columnCount());
+ for (int col = 0; col < pm.columnCount(); ++col) {
+ indexes.append(pm.index(1, col));
+ }
+ QMimeData* mimeData = pm.mimeData(indexes);
+ QVERIFY(mimeData);
+
+ // and dropping it after the last row
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ delete mimeData;
+
+ // Then a new row should be inserted at the end
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("456"));
+
+}
+
+QTEST_GUILESS_MAIN(tst_QConcatenateTablesProxyModel)
+
+#include "tst_qconcatenatetablesproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp b/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp
index 9a54c0a70d..16e5170a47 100644
--- a/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp
+++ b/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp
@@ -82,8 +82,116 @@ private slots:
void setData_emits_both_roles();
void supportedDragDropActions();
+
+ void moveRows_data();
+ void moveRows();
+ void moveRowsInvalid_data();
+ void moveRowsInvalid();
+
+ void itemData();
+ void setItemData();
};
+void tst_QStringListModel::moveRowsInvalid_data()
+{
+ QTest::addColumn<QStringListModel*>("baseModel");
+ QTest::addColumn<QModelIndex>("startParent");
+ QTest::addColumn<int>("startRow");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<QModelIndex>("destinationParent");
+ QTest::addColumn<int>("destination");
+
+ QStringListModel* tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("destination_equal_source") << tempModel << QModelIndex() << 0 << 1 << QModelIndex() << 1;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("count_equal_0") << tempModel << QModelIndex() << 0 << 0 << QModelIndex() << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("move_child") << tempModel << tempModel->index(0, 0) << 0 << 1 << QModelIndex() << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("move_to_child") << tempModel << QModelIndex() << 0 << 1 << tempModel->index(0, 0) << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("negative_count") << tempModel << QModelIndex() << 0 << -1 << QModelIndex() << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("negative_source_row") << tempModel << QModelIndex() << -1 << 1 << QModelIndex() << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("negative_destination_row") << tempModel << QModelIndex() << 0 << 1 << QModelIndex() << -1;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("source_row_equal_rowCount") << tempModel << QModelIndex() << tempModel->rowCount() << 1 << QModelIndex() << 1;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("destination_row_greater_rowCount") << tempModel << QModelIndex() << 0 << 1 << QModelIndex() << tempModel->rowCount() + 1;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("move_row_within_source_range") << tempModel << QModelIndex() << 0 << 3 << QModelIndex() << 2;
+ tempModel = new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ QTest::addRow("destination_row_before_0") << tempModel << QModelIndex() << 1 << 1 << QModelIndex() << 0;
+}
+
+void tst_QStringListModel::moveRowsInvalid()
+{
+ QFETCH(QStringListModel* const, baseModel);
+ QFETCH(const QModelIndex, startParent);
+ QFETCH(const int, startRow);
+ QFETCH(const int, count);
+ QFETCH(const QModelIndex, destinationParent);
+ QFETCH(const int, destination);
+
+ QSignalSpy rowMovedSpy(baseModel, &QAbstractItemModel::rowsMoved);
+ QSignalSpy rowAboutMovedSpy(baseModel, &QAbstractItemModel::rowsAboutToBeMoved);
+ QVERIFY(rowMovedSpy.isValid());
+ QVERIFY(rowAboutMovedSpy.isValid());
+ QVERIFY(!baseModel->moveRows(startParent, startRow, count, destinationParent, destination));
+ QCOMPARE(rowMovedSpy.size(), 0);
+ QCOMPARE(rowAboutMovedSpy.size(), 0);
+ delete baseModel;
+}
+
+void tst_QStringListModel::moveRows_data()
+{
+ QTest::addColumn<int>("startRow");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<int>("destination");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("1_Item_from_top_to_middle") << 0 << 1 << 3 << QStringList{"B", "C", "A", "D", "E", "F"};
+ QTest::newRow("1_Item_from_top_to_bottom") << 0 << 1 << 6 << QStringList{"B", "C", "D", "E", "F", "A"};
+ QTest::newRow("1_Item_from_middle_to_top") << 2 << 1 << 1 << QStringList{"C", "A", "B", "D", "E", "F"};
+ QTest::newRow("1_Item_from_bottom_to_middle") << 5 << 1 << 3 << QStringList{"A", "B", "F", "C", "D", "E"};
+ QTest::newRow("1_Item_from_bottom to_top") << 5 << 1 << 1 << QStringList{"F", "A", "B", "C", "D", "E"};
+ QTest::newRow("1_Item_from_middle_to_bottom") << 2 << 1 << 6 << QStringList{"A", "B", "D", "E", "F", "C"};
+ QTest::newRow("1_Item_from_middle_to_middle_before") << 2 << 1 << 1 << QStringList{"C", "A", "B", "D", "E", "F"};
+ QTest::newRow("1_Item_from_middle_to_middle_after") << 2 << 1 << 4 << QStringList{"A", "B", "D", "C", "E", "F"};
+
+ QTest::newRow("2_Items_from_top_to_middle") << 0 << 2 << 3 << QStringList{"C", "A", "B", "D", "E", "F"};
+ QTest::newRow("2_Items_from_top_to_bottom") << 0 << 2 << 6 << QStringList{"C", "D", "E", "F", "A", "B"};
+ QTest::newRow("2_Items_from_middle_to_top") << 2 << 2 << 1 << QStringList{"C", "D", "A", "B", "E", "F"};
+ QTest::newRow("2_Items_from_bottom_to_middle") << 4 << 2 << 3 << QStringList{"A", "B", "E", "F", "C", "D"};
+ QTest::newRow("2_Items_from_bottom_to_top") << 4 << 2 << 1 << QStringList{"E", "F", "A", "B", "C", "D"};
+ QTest::newRow("2_Items_from_middle_to_bottom") << 2 << 2 << 6 << QStringList{"A", "B", "E", "F", "C", "D"};
+ QTest::newRow("2_Items_from_middle_to_middle_before") << 3 << 2 << 2 << QStringList{"A", "D", "E", "B", "C", "F"};
+ QTest::newRow("2_Items_from_middle_to_middle_after") << 1 << 2 << 5 << QStringList{"A", "D", "E", "B", "C", "F"};
+}
+
+void tst_QStringListModel::moveRows()
+{
+ QFETCH(const int, startRow);
+ QFETCH(const int, count);
+ QFETCH(const int, destination);
+ QFETCH(const QStringList, expected);
+ QStringListModel baseModel(QStringList{"A", "B", "C", "D", "E", "F"});
+ QSignalSpy rowMovedSpy(&baseModel, &QAbstractItemModel::rowsMoved);
+ QSignalSpy rowAboutMovedSpy(&baseModel, &QAbstractItemModel::rowsAboutToBeMoved);
+ QVERIFY(baseModel.moveRows(QModelIndex(), startRow, count, QModelIndex(), destination));
+ QCOMPARE(baseModel.stringList(), expected);
+ QCOMPARE(rowMovedSpy.size(), 1);
+ QCOMPARE(rowAboutMovedSpy.size(), 1);
+ for (const QList<QVariant> &signalArgs : {rowMovedSpy.first(), rowAboutMovedSpy.first()}){
+ QVERIFY(!signalArgs.at(0).value<QModelIndex>().isValid());
+ QCOMPARE(signalArgs.at(1).toInt(), startRow);
+ QCOMPARE(signalArgs.at(2).toInt(), startRow + count - 1);
+ QVERIFY(!signalArgs.at(3).value<QModelIndex>().isValid());
+ QCOMPARE(signalArgs.at(4).toInt(), destination);
+ }
+}
+
void tst_QStringListModel::rowsAboutToBeRemoved_rowsRemoved_data()
{
QTest::addColumn<QStringList>("input");
@@ -246,6 +354,74 @@ void tst_QStringListModel::setData_emits_both_roles()
expected);
}
+void tst_QStringListModel::itemData()
+{
+ QStringListModel testModel{ QStringList {
+ QStringLiteral("One"),
+ QStringLiteral("Two"),
+ QStringLiteral("Three"),
+ QStringLiteral("Four"),
+ QStringLiteral("Five")
+ }};
+ QMap<int, QVariant> compareMap;
+ QCOMPARE(testModel.itemData(QModelIndex()), compareMap);
+ compareMap.insert(Qt::DisplayRole, QStringLiteral("Two"));
+ compareMap.insert(Qt::EditRole, QStringLiteral("Two"));
+ QCOMPARE(testModel.itemData(testModel.index(1, 0)), compareMap);
+}
+
+void tst_QStringListModel::setItemData()
+{
+ QStringListModel testModel{ QStringList {
+ QStringLiteral("One"),
+ QStringLiteral("Two"),
+ QStringLiteral("Three"),
+ QStringLiteral("Four"),
+ QStringLiteral("Five")
+ }};
+ QSignalSpy dataChangedSpy(&testModel, &QAbstractItemModel::dataChanged);
+ QModelIndex changeIndex = testModel.index(1, 0);
+ const QVector<int> changeRoles{Qt::DisplayRole, Qt::EditRole};
+ const QString changedString("Changed");
+ QMap<int, QVariant> newItemData{std::make_pair<int>(Qt::DisplayRole, changedString)};
+ // invalid index does nothing and returns false
+ QVERIFY(!testModel.setItemData(QModelIndex(), newItemData));
+ // valid data is set, return value is true and dataChanged is emitted once
+ QVERIFY(testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(changeIndex.data(Qt::DisplayRole).toString(), changedString);
+ QCOMPARE(changeIndex.data(Qt::EditRole).toString(), changedString);
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QVariantList dataChangedArguments = dataChangedSpy.takeFirst();
+ QCOMPARE(dataChangedArguments.at(0).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(1).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(2).value<QVector<int> >(), changeRoles);
+ // Unsupported roles do nothing return false
+ newItemData.clear();
+ newItemData.insert(Qt::UserRole, changedString);
+ QVERIFY(!testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(dataChangedSpy.size(), 0);
+ // If some but not all the roles are supported it returns false and does nothing
+ newItemData.insert(Qt::EditRole, changedString);
+ changeIndex = testModel.index(2, 0);
+ QVERIFY(!testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(changeIndex.data(Qt::DisplayRole).toString(), QStringLiteral("Three"));
+ QCOMPARE(changeIndex.data(Qt::EditRole).toString(), QStringLiteral("Three"));
+ QCOMPARE(dataChangedSpy.size(), 0);
+ // Qt::EditRole and Qt::DisplayRole are both set, Qt::EditRole takes precedence
+ newItemData.clear();
+ newItemData.insert(Qt::EditRole, changedString);
+ newItemData.insert(Qt::DisplayRole, QStringLiteral("Ignored"));
+ changeIndex = testModel.index(3, 0);
+ QVERIFY(testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(changeIndex.data(Qt::DisplayRole).toString(), changedString);
+ QCOMPARE(changeIndex.data(Qt::EditRole).toString(), changedString);
+ QCOMPARE(dataChangedSpy.size(), 1);
+ dataChangedArguments = dataChangedSpy.takeFirst();
+ QCOMPARE(dataChangedArguments.at(0).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(1).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(2).value<QVector<int> >(), changeRoles);
+}
+
void tst_QStringListModel::supportedDragDropActions()
{
QStringListModel model;
diff --git a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
index 541e73636c..5efe68f4af 100644
--- a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
+++ b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
@@ -3,6 +3,7 @@ TEMPLATE = subdirs
tst.depends = lib theplugin
SUBDIRS = lib \
+ staticplugin \
theplugin \
tst
!android:!win32:!darwin {
diff --git a/tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore b/tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore
new file mode 100644
index 0000000000..26f7ecd506
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore
@@ -0,0 +1,3 @@
+*staticplugin.prl
+libstaticplugin.a
+staticplugin.lib
diff --git a/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp b/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp
new file mode 100644
index 0000000000..d891839b1e
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite 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 <QtPlugin>
+#include <QObject>
+
+class StaticPlugin : public QObject
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "SomeIID")
+public:
+ StaticPlugin() {}
+};
+
+#include "main.moc"
diff --git a/tests/auto/corelib/plugin/qpluginloader/staticplugin/staticplugin.pro b/tests/auto/corelib/plugin/qpluginloader/staticplugin/staticplugin.pro
new file mode 100644
index 0000000000..ff65ab728c
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/staticplugin/staticplugin.pro
@@ -0,0 +1,7 @@
+TEMPLATE = lib
+CONFIG += plugin static
+SOURCES = main.cpp
+QT = core
+
+# Add extra metadata to the plugin
+QMAKE_MOC_OPTIONS += -M ExtraMetaData=StaticPlugin -M ExtraMetaData=foo
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro b/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro
index c20e56ba4c..a3885f4134 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro
+++ b/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro
@@ -8,9 +8,14 @@ HEADERS = ../theplugin/plugininterface.h
win32 {
CONFIG(debug, debug|release) {
TARGET = ../../debug/tst_qpluginloader
+ LIBS += -L../staticplugin/debug
} else {
TARGET = ../../release/tst_qpluginloader
+ LIBS += -L../staticplugin/release
}
+} else {
+ LIBS += -L../staticplugin
}
+LIBS += -lstaticplugin
TESTDATA += ../elftest ../machtest
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
index c517c0809a..4316ea14ea 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 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 test suite of the Qt Toolkit.
@@ -121,8 +121,11 @@ private slots:
void reloadPlugin();
void preloadedPlugin_data();
void preloadedPlugin();
+ void staticPlugins();
};
+Q_IMPORT_PLUGIN(StaticPlugin)
+
void tst_QPluginLoader::cleanup()
{
// check if the library/plugin was leaked
@@ -520,5 +523,37 @@ void tst_QPluginLoader::preloadedPlugin()
QVERIFY(lib.unload());
}
+void tst_QPluginLoader::staticPlugins()
+{
+ const QObjectList instances = QPluginLoader::staticInstances();
+ QVERIFY(instances.size());
+
+ bool found = false;
+ for (QObject *obj : instances) {
+ found = obj->metaObject()->className() == QLatin1String("StaticPlugin");
+ if (found)
+ break;
+ }
+ QVERIFY(found);
+
+ const auto plugins = QPluginLoader::staticPlugins();
+ QCOMPARE(plugins.size(), instances.size());
+
+ // find the metadata
+ QJsonObject metaData;
+ for (const auto &p : plugins) {
+ metaData = p.metaData();
+ found = metaData.value("className").toString() == QLatin1String("StaticPlugin");
+ if (found)
+ break;
+ }
+ QVERIFY(found);
+
+ QCOMPARE(metaData.value("version").toInt(), QT_VERSION);
+ QCOMPARE(metaData.value("IID").toString(), "SomeIID");
+ QCOMPARE(metaData.value("ExtraMetaData"), QJsonArray({ "StaticPlugin", "foo" }));
+}
+
+
QTEST_MAIN(tst_QPluginLoader)
#include "tst_qpluginloader.moc"
diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
index edea4713a1..1c1631760b 100644
--- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
@@ -2662,28 +2662,30 @@ void tst_QTextStream::useCase2()
// ------------------------------------------------------------------------------
void tst_QTextStream::manipulators_data()
{
- QTest::addColumn<int>("flags");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<int>("alignFlag");
+ QTest::addColumn<int>("numberFlag");
QTest::addColumn<int>("width");
QTest::addColumn<double>("realNumber");
QTest::addColumn<int>("intNumber");
QTest::addColumn<QString>("textData");
QTest::addColumn<QByteArray>("result");
- QTest::newRow("no flags") << 0 << 0 << 5.0 << 5 << QString("five") << QByteArray("55five");
- QTest::newRow("rightadjust") << 0 << 10 << 5.0 << 5 << QString("five") << QByteArray(" 5 5 five");
-
- // ### FIX
-// QTest::newRow("leftadjust") << int(QTextStream::left) << 10 << 5.0 << 5 << QString("five") << QByteArray("5 5 five ");
-// QTest::newRow("showpos") << int(QTextStream::showpos) << 10 << 5.0 << 5 << QString("five") << QByteArray(" +5 +5 five");
-// QTest::newRow("showpos2") << int(QTextStream::showpos) << 5 << 3.14 << -5 << QString("five") << QByteArray("+3.14 -5 five");
-// QTest::newRow("hex") << int(QTextStream::hex | QTextStream::showbase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0x5 five");
-// QTest::newRow("hex uppercase") << int(QTextStream::hex | QTextStream::uppercase | QTextStream::showbase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0X5 five");
+ QTest::newRow("no flags") << 10 << 0 << 0 << 0 << 5.0 << 5 << QString("five") << QByteArray("55five");
+ QTest::newRow("rightadjust") << 10 << int(QTextStream::AlignRight) << 0 << 10 << 5.0 << 5 << QString("five") << QByteArray(" 5 5 five");
+ QTest::newRow("leftadjust") << 10 << int(QTextStream::AlignLeft) << 0 << 10 << 5.0 << 5 << QString("five") << QByteArray("5 5 five ");
+ QTest::newRow("showpos") << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 10 << 5.0 << 5 << QString("five") << QByteArray(" +5 +5 five");
+ QTest::newRow("showpos2") << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 5 << 3.14 << -5 << QString("five") << QByteArray("+3.14 -5 five");
+ QTest::newRow("hex") << 16 << int(QTextStream::AlignRight) << int(QTextStream::ShowBase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0x5 five");
+ QTest::newRow("hex") << 16 << int(QTextStream::AlignRight) << int(QTextStream::ShowBase | QTextStream::UppercaseBase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0X5 five");
}
// ------------------------------------------------------------------------------
void tst_QTextStream::manipulators()
{
-// QFETCH(int, flags);
+ QFETCH(int, base);
+ QFETCH(int, alignFlag);
+ QFETCH(int, numberFlag);
QFETCH(int, width);
QFETCH(double, realNumber);
QFETCH(int, intNumber);
@@ -2697,14 +2699,16 @@ void tst_QTextStream::manipulators()
stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
stream.setAutoDetectUnicode(true);
-// stream.setFlags(flags);
+ stream.setIntegerBase(base);
+ stream.setFieldAlignment(QTextStream::FieldAlignment(alignFlag));
+ stream.setNumberFlags(QTextStream::NumberFlag(numberFlag));
stream.setFieldWidth(width);
stream << realNumber;
stream << intNumber;
stream << textData;
stream.flush();
- QCOMPARE(buffer.data().constData(), result.constData());
+ QCOMPARE(buffer.data(), result);
}
void tst_QTextStream::generateBOM()
diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
index 261689d401..ff36beadcb 100644
--- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
@@ -1869,9 +1869,11 @@ static void setWinLocaleInfo(LCTYPE type, const QString &value)
# define LOCALE_SSHORTTIME 0x00000079
#endif
-class RestoreLocaleHelper {
+class RestoreLocaleHelper
+{
public:
- RestoreLocaleHelper() {
+ RestoreLocaleHelper()
+ {
m_decimal = getWinLocaleInfo(LOCALE_SDECIMAL);
m_thousand = getWinLocaleInfo(LOCALE_STHOUSAND);
m_sdate = getWinLocaleInfo(LOCALE_SSHORTDATE);
@@ -1879,7 +1881,8 @@ public:
m_time = getWinLocaleInfo(LOCALE_SSHORTTIME);
}
- ~RestoreLocaleHelper() {
+ ~RestoreLocaleHelper()
+ {
// restore these, or the user will get a surprise
setWinLocaleInfo(LOCALE_SDECIMAL, m_decimal);
setWinLocaleInfo(LOCALE_STHOUSAND, m_thousand);
@@ -1887,12 +1890,10 @@ public:
setWinLocaleInfo(LOCALE_SLONGDATE, m_ldate);
setWinLocaleInfo(LOCALE_SSHORTTIME, m_time);
- // make sure QLocale::system() gets updated
- QLocalePrivate::updateSystemPrivate();
+ QSystemLocale dummy; // to provoke a refresh of the system locale
}
QString m_decimal, m_thousand, m_sdate, m_ldate, m_time;
-
};
void tst_QLocale::windowsDefaultLocale()
@@ -1908,8 +1909,7 @@ void tst_QLocale::windowsDefaultLocale()
const QString shortTimeFormat = QStringLiteral("h^m^s");
setWinLocaleInfo(LOCALE_SSHORTTIME, shortTimeFormat);
- // make sure QLocale::system() gets updated
- QLocalePrivate::updateSystemPrivate();
+ QSystemLocale dummy; // to provoke a refresh of the system locale
QLocale locale = QLocale::system();
// make sure we are seeing the system's format strings
@@ -2650,9 +2650,11 @@ void tst_QLocale::textDirection_data()
case QLocale::Sabaean:
case QLocale::Samaritan:
case QLocale::Sindhi:
+ case QLocale::SouthernKurdish:
case QLocale::Syriac:
case QLocale::Uighur:
case QLocale::Urdu:
+ case QLocale::WesternBalochi:
case QLocale::Yiddish:
// false if there is no locale data for language:
rightToLeft = (QLocale(QLocale::Language(language)).language()
diff --git a/tests/auto/corelib/tools/qoffsetstringarray/qoffsetstringarray.pro b/tests/auto/corelib/tools/qoffsetstringarray/qoffsetstringarray.pro
new file mode 100644
index 0000000000..c8e6a8e05a
--- /dev/null
+++ b/tests/auto/corelib/tools/qoffsetstringarray/qoffsetstringarray.pro
@@ -0,0 +1,6 @@
+CONFIG += testcase
+TARGET = tst_qoffsetstringarray
+QT = core testlib core-private
+CONFIG += c++11
+CONFIG += strict_c++
+SOURCES = $$PWD/tst_qoffsetstringarray.cpp
diff --git a/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp b/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp
new file mode 100644
index 0000000000..dfa0450b18
--- /dev/null
+++ b/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite 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 <QtTest/QtTest>
+
+#include <private/qoffsetstringarray_p.h>
+
+
+class tst_QOffsetStringArray : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void init();
+ void access();
+};
+
+
+constexpr const auto messages = qOffsetStringArray(
+ "level - 0",
+ "level - 1",
+ "level - 2",
+ "level - 3",
+ "level - 4",
+ ""
+);
+
+constexpr const auto messages257 = qOffsetStringArray(
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "end"
+);
+
+constexpr const auto messagesBigOffsets = qOffsetStringArray(
+ " 10 20 30 40 50 60 70 80 90",
+ " 10 20 30 40 50 60 70 80 90",
+ " 10 20 30 40 50 60 70 80 90",
+ " 10 20 30 40 50 60 70 80 90"
+);
+
+void tst_QOffsetStringArray::init()
+{
+ static_assert(messages.sizeString == 51, "message.sizeString");
+ static_assert(messages.sizeOffsets == 6, "message.sizeOffsets");
+ static_assert(std::is_same<decltype(messages)::Type, quint8>::value, "messages::Type != quint8");
+
+ static_assert(messages257.sizeOffsets == 257, "messages257.sizeOffsets");
+ static_assert(messages257.sizeString == 260, "messages257.sizeString");
+ static_assert(std::is_same<decltype(messages257)::Type, quint16>::value,
+ "messages257::Type != quint16");
+
+ static_assert(messagesBigOffsets.sizeOffsets == 4, "messagesBigOffsets.sizeOffsets");
+ static_assert(messagesBigOffsets.sizeString == 364, "messagesBigOffsets.sizeString");
+ static_assert(std::is_same<decltype(messagesBigOffsets)::Type, quint16>::value,
+ "messagesBigOffsets::Type != quint16");
+}
+
+void tst_QOffsetStringArray::access()
+{
+ QCOMPARE(messages[0], "level - 0");
+ QCOMPARE(messages[1], "level - 1");
+ QCOMPARE(messages[2], "level - 2");
+ QCOMPARE(messages[3], "level - 3");
+ QCOMPARE(messages[4], "level - 4");
+ QCOMPARE(messages[5], "");
+ QCOMPARE(messages[6], "");
+}
+
+
+QTEST_APPLESS_MAIN(tst_QOffsetStringArray)
+#include "tst_qoffsetstringarray.moc"
diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro
index f28cf21b8b..2a975e67d1 100644
--- a/tests/auto/corelib/tools/tools.pro
+++ b/tests/auto/corelib/tools/tools.pro
@@ -35,6 +35,7 @@ SUBDIRS=\
qmap_strictiterators \
qmargins \
qmessageauthenticationcode \
+ qoffsetstringarray \
qpair \
qpoint \
qpointf \
diff --git a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
index 8b49679042..6c3443a735 100644
--- a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
+++ b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
@@ -35,7 +35,9 @@
#include <QtNetwork/QNetworkCookieJar>
#include <QtNetwork/QNetworkCookie>
#include <QtNetwork/QNetworkRequest>
+#if QT_CONFIG(topleveldomain)
#include "private/qtldurl_p.h"
+#endif
class tst_QNetworkCookieJar: public QObject
{
@@ -47,7 +49,7 @@ private slots:
void setCookiesFromUrl();
void cookiesForUrl_data();
void cookiesForUrl();
-#ifdef QT_BUILD_INTERNAL
+#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(topleveldomain)
void effectiveTLDs_data();
void effectiveTLDs();
#endif
@@ -398,7 +400,7 @@ void tst_QNetworkCookieJar::cookiesForUrl()
}
// This test requires private API.
-#ifdef QT_BUILD_INTERNAL
+#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(topleveldomain)
void tst_QNetworkCookieJar::effectiveTLDs_data()
{
QTest::addColumn<QString>("domain");
diff --git a/tests/auto/tools/rcc/data/sizes/data/data-0.txt b/tests/auto/tools/rcc/data/sizes/data/data-0.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/data/data-0.txt
diff --git a/tests/auto/tools/rcc/data/sizes/data/data-1.txt b/tests/auto/tools/rcc/data/sizes/data/data-1.txt
new file mode 100644
index 0000000000..b516b2c489
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/data/data-1.txt
@@ -0,0 +1 @@
+@ \ No newline at end of file
diff --git a/tests/auto/tools/rcc/data/sizes/data/data-2.txt b/tests/auto/tools/rcc/data/sizes/data/data-2.txt
new file mode 100644
index 0000000000..a616ad491b
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/data/data-2.txt
@@ -0,0 +1 @@
+01 \ No newline at end of file
diff --git a/tests/auto/tools/rcc/data/sizes/data/data-35.txt b/tests/auto/tools/rcc/data/sizes/data/data-35.txt
new file mode 100644
index 0000000000..19a8036a15
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/data/data-35.txt
@@ -0,0 +1 @@
+0123456789 0123456789 0123456789 12 \ No newline at end of file
diff --git a/tests/auto/tools/rcc/data/sizes/size-0.expected b/tests/auto/tools/rcc/data/sizes/size-0.expected
new file mode 100644
index 0000000000..e862310153
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-0.expected
@@ -0,0 +1,88 @@
+/****************************************************************************
+** Resource object code
+**
+IGNORE: ** Created by: The Resource Compiler for Qt version 5.11.2
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+static const unsigned char qt_resource_data[] = {
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-0.txt
+ 0x0,0x0,0x0,0x0,
+
+
+};
+
+static const unsigned char qt_resource_name[] = {
+ // data
+ 0x0,0x4,
+ 0x0,0x6,0xa8,0xa1,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,
+ // data-0.txt
+ 0x0,0xa,
+ 0x4,0xe,0xa,0xb4,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x30,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+
+};
+
+static const unsigned char qt_resource_struct[] = {
+ // :
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data/data-0.txt
+ 0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
+TIMESTAMP:data/data-0.txt
+
+};
+
+#ifdef QT_NAMESPACE
+# define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
+# define QT_RCC_MANGLE_NAMESPACE0(x) x
+# define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
+# define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
+# define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
+ QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
+#else
+# define QT_RCC_PREPEND_NAMESPACE(name) name
+# define QT_RCC_MANGLE_NAMESPACE(name) name
+#endif
+
+#ifdef QT_NAMESPACE
+namespace QT_NAMESPACE {
+#endif
+
+bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+#ifdef QT_NAMESPACE
+}
+#endif
+
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)();
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)();
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+namespace {
+ struct initializer {
+ initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources)(); }
+ ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); }
+ } dummy;
+}
diff --git a/tests/auto/tools/rcc/data/sizes/size-0.qrc b/tests/auto/tools/rcc/data/sizes/size-0.qrc
new file mode 100644
index 0000000000..9f47732fe2
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-0.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>data/data-0.txt</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/tools/rcc/data/sizes/size-1.expected b/tests/auto/tools/rcc/data/sizes/size-1.expected
new file mode 100644
index 0000000000..9e5161272a
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-1.expected
@@ -0,0 +1,89 @@
+/****************************************************************************
+** Resource object code
+**
+IGNORE:** Created by: The Resource Compiler for Qt version 5.11.2
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+static const unsigned char qt_resource_data[] = {
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-1.txt
+ 0x0,0x0,0x0,0x1,
+ 0x40,
+
+
+};
+
+static const unsigned char qt_resource_name[] = {
+ // data
+ 0x0,0x4,
+ 0x0,0x6,0xa8,0xa1,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,
+ // data-1.txt
+ 0x0,0xa,
+ 0x4,0x11,0xa,0xb4,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x31,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+
+};
+
+static const unsigned char qt_resource_struct[] = {
+ // :
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data/data-1.txt
+ 0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
+TIMESTAMP:data/data-1.txt
+
+};
+
+#ifdef QT_NAMESPACE
+# define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
+# define QT_RCC_MANGLE_NAMESPACE0(x) x
+# define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
+# define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
+# define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
+ QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
+#else
+# define QT_RCC_PREPEND_NAMESPACE(name) name
+# define QT_RCC_MANGLE_NAMESPACE(name) name
+#endif
+
+#ifdef QT_NAMESPACE
+namespace QT_NAMESPACE {
+#endif
+
+bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+#ifdef QT_NAMESPACE
+}
+#endif
+
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)();
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)();
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+namespace {
+ struct initializer {
+ initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources)(); }
+ ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); }
+ } dummy;
+}
diff --git a/tests/auto/tools/rcc/data/sizes/size-1.qrc b/tests/auto/tools/rcc/data/sizes/size-1.qrc
new file mode 100644
index 0000000000..9fde9a1722
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-1.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>data/data-1.txt</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected
new file mode 100644
index 0000000000..0fc953351a
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected
@@ -0,0 +1,126 @@
+/****************************************************************************
+** Resource object code
+**
+IGNORE: ** Created by: The Resource Compiler for Qt version 5.11.2
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+static const unsigned char qt_resource_data[] = {
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-2.txt
+ 0x0,0x0,0x0,0x2,
+ 0x30,
+ 0x31,
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-35.txt
+ 0x0,0x0,0x0,0x23,
+ 0x30,
+ 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x20,0x30,0x31,0x32,0x33,0x34,0x35,
+ 0x36,0x37,0x38,0x39,0x20,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x20,
+ 0x31,0x32,
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-1.txt
+ 0x0,0x0,0x0,0x1,
+ 0x40,
+
+IGNORE: // /data/dev/qt-5/qtbase/tests/auto/tools/rcc/data/sizes/data/data-0.txt
+ 0x0,0x0,0x0,0x0,
+
+
+};
+
+static const unsigned char qt_resource_name[] = {
+ // data
+ 0x0,0x4,
+ 0x0,0x6,0xa8,0xa1,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,
+ // data-2.txt
+ 0x0,0xa,
+ 0x4,0x8,0xa,0xb4,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x32,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+ // data-35.txt
+ 0x0,0xb,
+ 0x0,0xb5,0x4f,0x74,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x33,0x0,0x35,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+ // data-1.txt
+ 0x0,0xa,
+ 0x4,0x11,0xa,0xb4,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x31,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+ // data-0.txt
+ 0x0,0xa,
+ 0x4,0xe,0xa,0xb4,
+ 0x0,0x64,
+ 0x0,0x61,0x0,0x74,0x0,0x61,0x0,0x2d,0x0,0x30,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+
+};
+
+static const unsigned char qt_resource_struct[] = {
+ // :
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x2,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/data/data-35.txt
+ 0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x6,
+TIMESTAMP:data/data-35.txt
+ // :/data/data-2.txt
+ 0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
+TIMESTAMP:data/data-2.txt
+ // :/data/data-0.txt
+ 0x0,0x0,0x0,0x5e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x32,
+TIMESTAMP:data/data-0.txt
+ // :/data/data-1.txt
+ 0x0,0x0,0x0,0x44,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2d,
+TIMESTAMP:data/data-1.txt
+
+};
+
+#ifdef QT_NAMESPACE
+# define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
+# define QT_RCC_MANGLE_NAMESPACE0(x) x
+# define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
+# define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
+# define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
+ QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
+#else
+# define QT_RCC_PREPEND_NAMESPACE(name) name
+# define QT_RCC_MANGLE_NAMESPACE(name) name
+#endif
+
+#ifdef QT_NAMESPACE
+namespace QT_NAMESPACE {
+#endif
+
+bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+#ifdef QT_NAMESPACE
+}
+#endif
+
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)();
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)();
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)()
+{
+ QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData)
+ (0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+namespace {
+ struct initializer {
+ initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources)(); }
+ ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); }
+ } dummy;
+}
diff --git a/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.qrc b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.qrc
new file mode 100644
index 0000000000..039c9203ff
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.qrc
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>data/data-2.txt</file>
+ <file>data/data-0.txt</file>
+ <file>data/data-35.txt</file>
+ <file>data/data-1.txt</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/tools/rcc/rcc.pro b/tests/auto/tools/rcc/rcc.pro
index 264b8ecc66..3fdc4132a7 100644
--- a/tests/auto/tools/rcc/rcc.pro
+++ b/tests/auto/tools/rcc/rcc.pro
@@ -3,3 +3,10 @@ QT = core testlib
TARGET = tst_rcc
SOURCES += tst_rcc.cpp
+
+RESOURCES += \
+ $$PWD/data/images/images.qrc \
+ $$PWD/data/sizes/size-0.qrc \
+ $$PWD/data/sizes/size-2-0-35-1.qrc \
+ $$PWD/data/sizes/size-1.qrc
+
diff --git a/tests/auto/tools/rcc/tst_rcc.cpp b/tests/auto/tools/rcc/tst_rcc.cpp
index 54a2854ede..0876af6759 100644
--- a/tests/auto/tools/rcc/tst_rcc.cpp
+++ b/tests/auto/tools/rcc/tst_rcc.cpp
@@ -55,9 +55,13 @@ private slots:
void rcc_data();
void rcc();
+
void binary_data();
void binary();
+ void readback_data();
+ void readback();
+
void cleanupTestCase();
private:
@@ -126,6 +130,13 @@ void tst_rcc::rcc_data()
if (dataPath.isEmpty())
QFAIL("data path not found");
QTest::newRow("images") << dataPath << "images.qrc" << "images.expected";
+
+ QString sizesPath = QFINDTESTDATA("data/sizes/");
+ if (sizesPath.isEmpty())
+ QFAIL("data path not found");
+ QTest::newRow("size-0") << sizesPath << "size-0.qrc" << "size-0.expected";
+ QTest::newRow("size-1") << sizesPath << "size-1.qrc" << "size-1.expected";
+ QTest::newRow("size-2-0-35-1") << sizesPath << "size-2-0-35-1.qrc" << "size-2-0-35-1.expected";
}
void tst_rcc::rcc()
@@ -353,6 +364,42 @@ void tst_rcc::binary()
QLocale::setDefault(oldDefaultLocale);
}
+void tst_rcc::readback_data()
+{
+ QTest::addColumn<QString>("resourceName");
+ QTest::addColumn<QString>("fileSystemName");
+
+ QTest::newRow("data-0") << ":data/data-0.txt" << "sizes/data/data-0.txt";
+ QTest::newRow("data-1") << ":data/data-1.txt" << "sizes/data/data-1.txt";
+ QTest::newRow("data-2") << ":data/data-2.txt" << "sizes/data/data-2.txt";
+ QTest::newRow("data-35") << ":data/data-35.txt" << "sizes/data/data-35.txt";
+ QTest::newRow("circle") << ":images/circle.png" << "images/images/circle.png";
+ QTest::newRow("square") << ":images/square.png" << "images/images/square.png";
+ QTest::newRow("triangle") << ":images/subdir/triangle.png"
+ << "images/images/subdir/triangle.png";
+}
+
+void tst_rcc::readback()
+{
+ QFETCH(QString, resourceName);
+ QFETCH(QString, fileSystemName);
+
+ QString dataPath = QFINDTESTDATA("data/");
+ if (dataPath.isEmpty())
+ QFAIL("data path not found");
+
+ QFile resourceFile(resourceName);
+ QVERIFY(resourceFile.open(QIODevice::ReadOnly));
+ QByteArray resourceData = resourceFile.readAll();
+ resourceFile.close();
+
+ QFile fileSystemFile(dataPath + fileSystemName);
+ QVERIFY(fileSystemFile.open(QIODevice::ReadOnly));
+ QByteArray fileSystemData = fileSystemFile.readAll();
+ fileSystemFile.close();
+
+ QCOMPARE(resourceData, fileSystemData);
+}
void tst_rcc::cleanupTestCase()
{
diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
index a8f6906056..adedace8b2 100644
--- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
+++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
@@ -1215,7 +1215,7 @@ void tst_QItemDelegate::editorEvent()
option.checkState = Qt::CheckState(checkState);
const int checkMargin = qApp->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, 0) + 1;
- QPoint pos = inCheck ? qApp->style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &option, 0).center() + QPoint(checkMargin, 0) : QPoint(200,200);
+ QPoint pos = inCheck ? qApp->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &option, 0).center() + QPoint(checkMargin, 0) : QPoint(200,200);
QEvent *event = new QMouseEvent((QEvent::Type)type,
pos,
@@ -1371,7 +1371,7 @@ void tst_QItemDelegate::QTBUG4435_keepSelectionOnCheck()
option.features = QStyleOptionViewItem::HasDisplay | QStyleOptionViewItem::HasCheckIndicator;
option.checkState = Qt::CheckState(model.index(0, 0).data(Qt::CheckStateRole).toInt());
const int checkMargin = qApp->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, 0) + 1;
- QPoint pos = qApp->style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &option, 0).center()
+ QPoint pos = qApp->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &option, 0).center()
+ QPoint(checkMargin, 0);
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, pos);
QTRY_VERIFY(view.selectionModel()->isColumnSelected(0, QModelIndex()));
diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
index 5227db64ec..433b9e55e1 100644
--- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
+++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
@@ -873,6 +873,10 @@ void tst_QListView::setCurrentIndex()
}
}
}
+ while (model.rowCount()) {
+ view.setCurrentIndex(model.index(model.rowCount() - 1, 0));
+ model.removeRow(model.rowCount() - 1);
+ }
}
class PublicListView : public QListView
diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
index 98b44fe8aa..d8e14df353 100644
--- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
+++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
@@ -31,6 +31,7 @@
#include <QtGui/QtGui>
#include <QtWidgets/QtWidgets>
#include <qlist.h>
+#include <QSignalSpy>
#include <qlistwidget.h>
#include <private/qlistwidget_p.h>
@@ -116,6 +117,14 @@ private slots:
void QTBUG14363_completerWithAnyKeyPressedEditTriggers();
void mimeData();
void QTBUG50891_ensureSelectionModelSignalConnectionsAreSet();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ void clearItemData();
+#endif
+
+ void moveRows_data();
+ void moveRows();
+ void moveRowsInvalid_data();
+ void moveRowsInvalid();
protected slots:
void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last)
@@ -148,6 +157,108 @@ private:
};
+void tst_QListWidget::moveRowsInvalid_data()
+{
+ QTest::addColumn<QListWidget*>("baseWidget");
+ QTest::addColumn<QModelIndex>("startParent");
+ QTest::addColumn<int>("startRow");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<QModelIndex>("destinationParent");
+ QTest::addColumn<int>("destination");
+
+ const auto createWidget = []() -> QListWidget* {
+ QListWidget* result = new QListWidget;
+ result->addItems(QStringList{"A", "B", "C", "D", "E", "F"});
+ return result;
+ };
+
+ QTest::addRow("destination_equal_source") << createWidget() << QModelIndex() << 0 << 1 << QModelIndex() << 1;
+ QTest::addRow("count_equal_0") << createWidget() << QModelIndex() << 0 << 0 << QModelIndex() << 2;
+ QListWidget* tempWidget = createWidget();
+ QTest::addRow("move_child") << tempWidget << tempWidget->model()->index(0, 0) << 0 << 1 << QModelIndex() << 2;
+ tempWidget = createWidget();
+ QTest::addRow("move_to_child") << tempWidget << QModelIndex() << 0 << 1 << tempWidget->model()->index(0, 0) << 2;
+ QTest::addRow("negative_count") << createWidget() << QModelIndex() << 0 << -1 << QModelIndex() << 2;
+ QTest::addRow("negative_source_row") << createWidget() << QModelIndex() << -1 << 1 << QModelIndex() << 2;
+ QTest::addRow("negative_destination_row") << createWidget() << QModelIndex() << 0 << 1 << QModelIndex() << -1;
+ QTest::addRow("source_row_equal_rowCount") << createWidget() << QModelIndex() << 6 << 1 << QModelIndex() << 1;
+ QTest::addRow("destination_row_greater_rowCount") << createWidget() << QModelIndex() << 0 << 1 << QModelIndex() << 6 + 1;
+ QTest::addRow("move_row_within_source_range") << createWidget() << QModelIndex() << 0 << 3 << QModelIndex() << 2;
+ QTest::addRow("destination_row_before_0") << createWidget() << QModelIndex() << 1 << 1 << QModelIndex() << 0;
+}
+
+void tst_QListWidget::moveRowsInvalid()
+{
+ QFETCH(QListWidget* const, baseWidget);
+ QFETCH(const QModelIndex, startParent);
+ QFETCH(const int, startRow);
+ QFETCH(const int, count);
+ QFETCH(const QModelIndex, destinationParent);
+ QFETCH(const int, destination);
+ QAbstractItemModel *baseModel = baseWidget->model();
+ QSignalSpy rowMovedSpy(baseModel, &QAbstractItemModel::rowsMoved);
+ QSignalSpy rowAboutMovedSpy(baseModel, &QAbstractItemModel::rowsAboutToBeMoved);
+ QVERIFY(rowMovedSpy.isValid());
+ QVERIFY(rowAboutMovedSpy.isValid());
+ QVERIFY(!baseModel->moveRows(startParent, startRow, count, destinationParent, destination));
+ QCOMPARE(rowMovedSpy.size(), 0);
+ QCOMPARE(rowAboutMovedSpy.size(), 0);
+ delete baseWidget;
+}
+
+void tst_QListWidget::moveRows_data()
+{
+ QTest::addColumn<int>("startRow");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<int>("destination");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("1_Item_from_top_to_middle") << 0 << 1 << 3 << QStringList{"B", "C", "A", "D", "E", "F"};
+ QTest::newRow("1_Item_from_top_to_bottom") << 0 << 1 << 6 << QStringList{"B", "C", "D", "E", "F", "A"};
+ QTest::newRow("1_Item_from_middle_to_top") << 2 << 1 << 1 << QStringList{"C", "A", "B", "D", "E", "F"};
+ QTest::newRow("1_Item_from_bottom_to_middle") << 5 << 1 << 3 << QStringList{"A", "B", "F", "C", "D", "E"};
+ QTest::newRow("1_Item_from_bottom to_top") << 5 << 1 << 1 << QStringList{"F", "A", "B", "C", "D", "E"};
+ QTest::newRow("1_Item_from_middle_to_bottom") << 2 << 1 << 6 << QStringList{"A", "B", "D", "E", "F", "C"};
+ QTest::newRow("1_Item_from_middle_to_middle_before") << 2 << 1 << 1 << QStringList{"C", "A", "B", "D", "E", "F"};
+ QTest::newRow("1_Item_from_middle_to_middle_after") << 2 << 1 << 4 << QStringList{"A", "B", "D", "C", "E", "F"};
+
+ QTest::newRow("2_Items_from_top_to_middle") << 0 << 2 << 3 << QStringList{"C", "A", "B", "D", "E", "F"};
+ QTest::newRow("2_Items_from_top_to_bottom") << 0 << 2 << 6 << QStringList{"C", "D", "E", "F", "A", "B"};
+ QTest::newRow("2_Items_from_middle_to_top") << 2 << 2 << 1 << QStringList{"C", "D", "A", "B", "E", "F"};
+ QTest::newRow("2_Items_from_bottom_to_middle") << 4 << 2 << 3 << QStringList{"A", "B", "E", "F", "C", "D"};
+ QTest::newRow("2_Items_from_bottom_to_top") << 4 << 2 << 1 << QStringList{"E", "F", "A", "B", "C", "D"};
+ QTest::newRow("2_Items_from_middle_to_bottom") << 2 << 2 << 6 << QStringList{"A", "B", "E", "F", "C", "D"};
+ QTest::newRow("2_Items_from_middle_to_middle_before") << 3 << 2 << 2 << QStringList{"A", "D", "E", "B", "C", "F"};
+ QTest::newRow("2_Items_from_middle_to_middle_after") << 1 << 2 << 5 << QStringList{"A", "D", "E", "B", "C", "F"};
+}
+
+void tst_QListWidget::moveRows()
+{
+ QFETCH(const int, startRow);
+ QFETCH(const int, count);
+ QFETCH(const int, destination);
+ QFETCH(const QStringList, expected);
+ QListWidget baseWidget;
+ baseWidget.addItems(QStringList{"A", "B", "C", "D", "E", "F"});
+ QAbstractItemModel *baseModel = baseWidget.model();
+ QSignalSpy rowMovedSpy(baseModel, &QAbstractItemModel::rowsMoved);
+ QSignalSpy rowAboutMovedSpy(baseModel, &QAbstractItemModel::rowsAboutToBeMoved);
+ QVERIFY(baseModel->moveRows(QModelIndex(), startRow, count, QModelIndex(), destination));
+ QCOMPARE(baseModel->rowCount(), expected.size());
+ for (int i = 0; i < expected.size(); ++i)
+ QCOMPARE(baseModel->index(i, 0).data().toString(), expected.at(i));
+ QCOMPARE(rowMovedSpy.size(), 1);
+ QCOMPARE(rowAboutMovedSpy.size(), 1);
+ for (const QList<QVariant> &signalArgs : {rowMovedSpy.first(), rowAboutMovedSpy.first()}){
+ QVERIFY(!signalArgs.at(0).value<QModelIndex>().isValid());
+ QCOMPARE(signalArgs.at(1).toInt(), startRow);
+ QCOMPARE(signalArgs.at(2).toInt(), startRow + count - 1);
+ QVERIFY(!signalArgs.at(3).value<QModelIndex>().isValid());
+ QCOMPARE(signalArgs.at(4).toInt(), destination);
+ }
+}
+
+
typedef QList<int> IntList;
tst_QListWidget::tst_QListWidget(): testWidget(0), rcParent(8), rcFirst(8,0), rcLast(8,0)
@@ -1743,5 +1854,27 @@ void tst_QListWidget::QTBUG50891_ensureSelectionModelSignalConnectionsAreSet()
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+void tst_QListWidget::clearItemData()
+{
+ QListWidget list;
+ for (int i = 0 ; i < 4; ++i)
+ new QListWidgetItem(QString::number(i), &list);
+ QSignalSpy dataChangeSpy(list.model(), &QAbstractItemModel::dataChanged);
+ QVERIFY(dataChangeSpy.isValid());
+ QVERIFY(!list.model()->clearItemData(QModelIndex()));
+ QCOMPARE(dataChangeSpy.size(), 0);
+ QVERIFY(list.model()->clearItemData(list.model()->index(0, 0)));
+ QVERIFY(!list.model()->index(0, 0).data().isValid());
+ QCOMPARE(dataChangeSpy.size(), 1);
+ const QList<QVariant> dataChangeArgs = dataChangeSpy.takeFirst();
+ QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), list.model()->index(0, 0));
+ QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), list.model()->index(0, 0));
+ QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
+ QVERIFY(list.model()->clearItemData(list.model()->index(0, 0)));
+ QCOMPARE(dataChangeSpy.size(), 0);
+}
+#endif
+
QTEST_MAIN(tst_QListWidget)
#include "tst_qlistwidget.moc"
diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
index 208ce27c8f..510fe5659d 100644
--- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
+++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
@@ -89,6 +89,9 @@ private slots:
void itemWithHeaderItems();
void mimeData();
void selectedRowAfterSorting();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ void clearItemData();
+#endif
private:
QTableWidget *testWidget;
@@ -1610,5 +1613,28 @@ void tst_QTableWidget::selectedRowAfterSorting()
}
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+void tst_QTableWidget::clearItemData()
+{
+ QTableWidget table(3,3);
+ for (int r = 0; r < 3; r++)
+ for (int c = 0; c < 3; c++)
+ table.setItem(r,c,new QTableWidgetItem(QStringLiteral("0")));
+ QSignalSpy dataChangeSpy(table.model(), &QAbstractItemModel::dataChanged);
+ QVERIFY(dataChangeSpy.isValid());
+ QVERIFY(!table.model()->clearItemData(QModelIndex()));
+ QCOMPARE(dataChangeSpy.size(), 0);
+ QVERIFY(table.model()->clearItemData(table.model()->index(0, 0)));
+ QVERIFY(!table.model()->index(0, 0).data().isValid());
+ QCOMPARE(dataChangeSpy.size(), 1);
+ const QList<QVariant> dataChangeArgs = dataChangeSpy.takeFirst();
+ QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), table.model()->index(0, 0));
+ QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), table.model()->index(0, 0));
+ QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
+ QVERIFY(table.model()->clearItemData(table.model()->index(0, 0)));
+ QCOMPARE(dataChangeSpy.size(), 0);
+}
+#endif
+
QTEST_MAIN(tst_QTableWidget)
#include "tst_qtablewidget.moc"
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index a79341b66f..39051c4969 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -2435,6 +2435,8 @@ void tst_QTreeView::selection()
for (int i = 0;i < 10; ++i)
m.setData(m.index(i, 0), i);
treeView.setModel(&m);
+ treeView.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&treeView));
treeView.setSelectionBehavior(QAbstractItemView::SelectRows);
treeView.setSelectionMode(QAbstractItemView::ExtendedSelection);
@@ -2446,6 +2448,13 @@ void tst_QTreeView::selection()
QTest::mousePress(treeView.viewport(), Qt::LeftButton, 0, treeView.visualRect(m.index(1, 0)).center());
QTest::keyPress(treeView.viewport(), Qt::Key_Down);
+ auto selectedRows = treeView.selectionModel()->selectedRows();
+ QCOMPARE(selectedRows.size(), 1);
+ QCOMPARE(selectedRows.first(), m.index(2, 0, QModelIndex()));
+ QTest::keyPress(treeView.viewport(), Qt::Key_5);
+ selectedRows = treeView.selectionModel()->selectedRows();
+ QCOMPARE(selectedRows.size(), 1);
+ QCOMPARE(selectedRows.first(), m.index(5, 0, QModelIndex()));
}
//From task 151686 QTreeView ExtendedSelection selects hidden rows
diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
index 8c93df9073..4a6244826e 100644
--- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
+++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
@@ -161,6 +161,9 @@ private slots:
void getMimeDataWithInvalidItem();
void testVisualItemRect();
void reparentHiddenItem();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ void clearItemData();
+#endif
public slots:
void itemSelectionChanged();
@@ -3004,7 +3007,7 @@ void tst_QTreeWidget::task191552_rtl()
opt.features = QStyleOptionViewItem::HasDisplay | QStyleOptionViewItem::HasCheckIndicator;
opt.checkState = Qt::Checked;
opt.widget = &tw;
- const QRect checkRect = tw.style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, &tw);
+ const QRect checkRect = tw.style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, &tw);
QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::NoModifier, checkRect.center());
QCOMPARE(item->checkState(0), Qt::Unchecked);
@@ -3218,7 +3221,7 @@ void tst_QTreeWidget::nonEditableTristate()
option.checkState = item->checkState(0);
const int checkMargin = qApp->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, 0) + 1;
- QPoint pos = qApp->style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &option, 0).center() + QPoint(checkMargin, 0);
+ QPoint pos = qApp->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &option, 0).center() + QPoint(checkMargin, 0);
QTest::mouseClick(tree->viewport(), Qt::LeftButton, Qt::NoModifier, pos);
QCOMPARE(int(item->checkState(0)), int(Qt::Checked));
@@ -3529,5 +3532,43 @@ void tst_QTreeWidget::reparentHiddenItem()
QVERIFY(grandChild->isHidden());
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+void tst_QTreeWidget::clearItemData()
+{
+ QTreeWidget tree;
+ QAbstractItemModel* model = tree.model();
+ QVERIFY(model->insertColumn(0));
+ QVERIFY(model->insertRow(0));
+ const QModelIndex parentIdx = model->index(0, 0);
+ QVERIFY(model->insertColumn(0, parentIdx));
+ QVERIFY(model->insertRow(0, parentIdx));
+ const QModelIndex childIdx = model->index(0, 0, parentIdx);
+ model->setData(parentIdx, QStringLiteral("parent"));
+ model->setData(parentIdx, QStringLiteral("parent"), Qt::UserRole);
+ model->setData(childIdx, QStringLiteral("child"));
+ QSignalSpy dataChangeSpy(model, &QAbstractItemModel::dataChanged);
+ QVERIFY(dataChangeSpy.isValid());
+ QVERIFY(!model->clearItemData(QModelIndex()));
+ QCOMPARE(dataChangeSpy.size(), 0);
+ QVERIFY(model->clearItemData(parentIdx));
+ QVERIFY(!model->data(parentIdx).isValid());
+ QVERIFY(!model->data(parentIdx, Qt::UserRole).isValid());
+ QCOMPARE(dataChangeSpy.size(), 1);
+ QList<QVariant> dataChangeArgs = dataChangeSpy.takeFirst();
+ QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), parentIdx);
+ QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), parentIdx);
+ QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
+ QVERIFY(model->clearItemData(parentIdx));
+ QCOMPARE(dataChangeSpy.size(), 0);
+ QVERIFY(model->clearItemData(childIdx));
+ QVERIFY(!model->data(childIdx).isValid());
+ QCOMPARE(dataChangeSpy.size(), 1);
+ dataChangeArgs = dataChangeSpy.takeFirst();
+ QCOMPARE(dataChangeArgs.at(0).value<QModelIndex>(), childIdx);
+ QCOMPARE(dataChangeArgs.at(1).value<QModelIndex>(), childIdx);
+ QVERIFY(dataChangeArgs.at(2).value<QVector<int>>().isEmpty());
+}
+#endif
+
QTEST_MAIN(tst_QTreeWidget)
#include "tst_qtreewidget.moc"
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
index a88fd8d19c..634e258250 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -1143,8 +1143,16 @@ void tst_QMenu::QTBUG7411_submenus_activate()
QTRY_VERIFY(sub1.isVisible());
}
+static bool isPlatformWayland()
+{
+ return !QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive);
+}
+
void tst_QMenu::QTBUG30595_rtl_submenu()
{
+ if (isPlatformWayland())
+ QSKIP("Creating xdg_popups on Wayland requires real input events. Positions would be off.");
+
QMenu menu("Test Menu");
menu.setLayoutDirection(Qt::RightToLeft);
QMenu sub("&sub");
@@ -1179,6 +1187,9 @@ void tst_QMenu::QTBUG20403_nested_popup_on_shortcut_trigger()
#ifndef Q_OS_MACOS
void tst_QMenu::click_while_dismissing_submenu()
{
+ if (isPlatformWayland())
+ QSKIP("Wayland: Creating (grabbing) popups requires real mouse events.");
+
QMenu menu("Test Menu");
QAction *action = menu.addAction("action");
QMenu sub("&sub");
diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
index cfa2ddc4cc..b66e30ad35 100644
--- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
+++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
@@ -147,6 +147,9 @@ private slots:
void contextMenu();
#endif
void inputMethodCursorRect();
+#if QT_CONFIG(scrollbar)
+ void updateAfterChangeCenterOnScroll();
+#endif
private:
void createSelection();
@@ -1727,5 +1730,20 @@ void tst_QPlainTextEdit::inputMethodCursorRect()
QCOMPARE(cursorRectV.toRect(), cursorRect.toRect());
}
+#if QT_CONFIG(scrollbar)
+// QTBUG-64730: Verify that the scrollbar is updated after center on scroll was set
+void tst_QPlainTextEdit::updateAfterChangeCenterOnScroll()
+{
+ ed->setPlainText("Line1\nLine2Line3\nLine3");
+ ed->show();
+ ed->setCenterOnScroll(true);
+ const int maxWithCenterOnScroll = ed->verticalScrollBar()->maximum();
+ ed->setCenterOnScroll(false);
+ const int maxWithoutCenterOnScroll = ed->verticalScrollBar()->maximum();
+ QVERIFY(maxWithCenterOnScroll > maxWithoutCenterOnScroll);
+}
+
+#endif
+
QTEST_MAIN(tst_QPlainTextEdit)
#include "tst_qplaintextedit.moc"
diff --git a/tests/benchmarks/widgets/itemviews/itemviews.pro b/tests/benchmarks/widgets/itemviews/itemviews.pro
index a23cdf7b97..0c3256f307 100644
--- a/tests/benchmarks/widgets/itemviews/itemviews.pro
+++ b/tests/benchmarks/widgets/itemviews/itemviews.pro
@@ -1,4 +1,5 @@
TEMPLATE = subdirs
SUBDIRS = \
qtableview \
- qheaderview
+ qheaderview \
+ qlistview
diff --git a/tests/benchmarks/widgets/itemviews/qlistview/qlistview.pro b/tests/benchmarks/widgets/itemviews/qlistview/qlistview.pro
new file mode 100644
index 0000000000..68537d09ea
--- /dev/null
+++ b/tests/benchmarks/widgets/itemviews/qlistview/qlistview.pro
@@ -0,0 +1,7 @@
+QT += widgets testlib
+
+TEMPLATE = app
+TARGET = tst_bench_qlistview
+
+SOURCES += tst_qlistview.cpp
+
diff --git a/tests/benchmarks/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/benchmarks/widgets/itemviews/qlistview/tst_qlistview.cpp
new file mode 100644
index 0000000000..01496743c2
--- /dev/null
+++ b/tests/benchmarks/widgets/itemviews/qlistview/tst_qlistview.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite 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 <qtest.h>
+#include <QListView>
+#include <QStandardItemModel>
+
+
+class tst_QListView : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QListView() = default;
+ virtual ~tst_QListView() = default;
+
+private slots:
+ void benchSetCurrentIndex();
+};
+
+void tst_QListView::benchSetCurrentIndex()
+{
+ QStandardItemModel sm(50000, 1);
+ QListView lv;
+ lv.setModel(&sm);
+ const int rc = lv.model()->rowCount();
+ for (int i = 0; i < rc; i+= 100)
+ lv.setRowHidden(i, true);
+ lv.setCurrentIndex(lv.model()->index(0, 0, QModelIndex()));
+ lv.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&lv));
+
+ QBENCHMARK_ONCE {
+ while (lv.currentIndex().row() < rc - 20)
+ lv.setCurrentIndex(lv.model()->index(lv.currentIndex().row() + 17,
+ lv.currentIndex().column(),
+ QModelIndex()));
+ }
+}
+
+
+QTEST_MAIN(tst_QListView)
+#include "tst_qlistview.moc"
diff --git a/tests/manual/widgets/itemviews/itemviews.pro b/tests/manual/widgets/itemviews/itemviews.pro
index 53f658d54d..8884cc3aae 100644
--- a/tests/manual/widgets/itemviews/itemviews.pro
+++ b/tests/manual/widgets/itemviews/itemviews.pro
@@ -1,2 +1,8 @@
TEMPLATE = subdirs
-SUBDIRS = delegate qheaderview qtreeview qtreewidget tableview-span-navigation
+SUBDIRS = delegate \
+ qconcatenatetablesproxymodel \
+ qheaderview \
+ qtreeview \
+ qtreewidget \
+ tableview-span-navigation \
+
diff --git a/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/main.cpp b/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/main.cpp
new file mode 100644
index 0000000000..2c1825f29f
--- /dev/null
+++ b/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/main.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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 QtGui module 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 <QApplication>
+#include <QConcatenateTablesProxyModel>
+#include <QStandardItemModel>
+#include <QTableView>
+#include <QTreeView>
+
+static void prepareModel(const QString &prefix, QStandardItemModel *model)
+{
+ for (int row = 0; row < model->rowCount(); ++row) {
+ for (int column = 0; column < model->columnCount(); ++column) {
+ QStandardItem *item = new QStandardItem(prefix + QString(" %1,%2").arg(row).arg(column));
+ item->setDragEnabled(true);
+ item->setDropEnabled(true);
+ model->setItem(row, column, item);
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QStandardItemModel firstModel(4, 4);
+ prepareModel("First", &firstModel);
+ QStandardItemModel secondModel(2, 2);
+
+ QConcatenateTablesProxyModel proxy;
+ proxy.addSourceModel(&firstModel);
+ proxy.addSourceModel(&secondModel);
+
+ prepareModel("Second", &secondModel);
+
+ QTableView tableView;
+ tableView.setWindowTitle("concat proxy, in QTableView");
+ tableView.setDragDropMode(QAbstractItemView::DragDrop);
+ tableView.setModel(&proxy);
+ tableView.show();
+
+ QTreeView treeView;
+ treeView.setWindowTitle("concat proxy, in QTreeView");
+ treeView.setDragDropMode(QAbstractItemView::DragDrop);
+ treeView.setModel(&proxy);
+ treeView.show();
+
+ // For comparison, views on top on QStandardItemModel
+
+ QTableView tableViewTest;
+ tableViewTest.setWindowTitle("first model, in QTableView");
+ tableViewTest.setDragDropMode(QAbstractItemView::DragDrop);
+ tableViewTest.setModel(&firstModel);
+ tableViewTest.show();
+
+ QTreeView treeViewTest;
+ treeViewTest.setWindowTitle("first model, in QTreeView");
+ treeViewTest.setDragDropMode(QAbstractItemView::DragDrop);
+ treeViewTest.setModel(&firstModel);
+ treeViewTest.show();
+
+ return app.exec();
+}
diff --git a/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro b/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro
new file mode 100644
index 0000000000..19904212a7
--- /dev/null
+++ b/tests/manual/widgets/itemviews/qconcatenatetablesproxymodel/qconcatenatetablesproxymodel.pro
@@ -0,0 +1,8 @@
+
+TEMPLATE = app
+TARGET = qconcatenatetablesproxymodel
+INCLUDEPATH += .
+
+QT += widgets
+
+SOURCES += main.cpp
diff --git a/util/local_database/cldr2qlocalexml.py b/util/local_database/cldr2qlocalexml.py
index ce45f631a6..bc999e1b65 100755
--- a/util/local_database/cldr2qlocalexml.py
+++ b/util/local_database/cldr2qlocalexml.py
@@ -51,6 +51,7 @@ order.
import os
import sys
import re
+import textwrap
import enumdata
import xpathlite
@@ -59,6 +60,10 @@ from dateconverter import convert_date
from localexml import Locale
findEntryInFile = xpathlite._findEntryInFile
+def wrappedwarn(prefix, tokens):
+ return sys.stderr.write(
+ '\n'.join(textwrap.wrap(prefix + ', '.join(tokens),
+ subsequent_indent=' ', width=80)) + '\n')
def parse_number_format(patterns, data):
# this is a very limited parsing of the number format for currency only.
@@ -164,9 +169,9 @@ def getNumberSystems(cache={}):
entry = dict(ns[1])
name = entry[u'id']
if u'digits' in entry and ord(entry[u'digits'][0]) > 0xffff:
- # FIXME: make this redundant:
+ # FIXME, QTBUG-69324: make this redundant:
# omit number system if zero doesn't fit in single-char16 UTF-16 :-(
- sys.stderr.write('skipping number system "%s" [can\'t represent its zero, U+%X, QTBUG-69324]\n'
+ sys.stderr.write('skipping number system "%s" [can\'t represent its zero, U+%X]\n'
% (name, ord(entry[u'digits'][0])))
else:
cache[name] = entry
@@ -243,7 +248,7 @@ def _generateLocaleInfo(path, language_code, script_code, country_code, variant_
numbering_system = None
try:
numbering_system = findEntry(path, "numbers/defaultNumberingSystem")
- except:
+ except xpathlite.Error:
pass
def findEntryDef(path, xpath, value=''):
try:
@@ -438,6 +443,38 @@ def integrateWeekData(filePath):
else:
locale.weekendEnd = weekendEndByCountryCode["001"]
+def splitLocale(name):
+ """Split name into (language, script, territory) triple as generator.
+
+ Ignores any trailing fields (with a warning), leaves script (a capitalised
+ four-letter token) or territory (either a number or an all-uppercase token)
+ empty if unspecified, returns a single-entry generator if name is a single
+ tag (i.e. contains no underscores). Always yields 1 or 3 values, never 2."""
+ tags = iter(name.split('_'))
+ yield tags.next() # Language
+ tag = tags.next()
+
+ # Script is always four letters, always capitalised:
+ if len(tag) == 4 and tag[0].isupper() and tag[1:].islower():
+ yield tag
+ try:
+ tag = tags.next()
+ except StopIteration:
+ tag = ''
+ else:
+ yield ''
+
+ # Territory is upper-case or numeric:
+ if tag and tag.isupper() or tag.isdigit():
+ yield tag
+ tag = ''
+ else:
+ yield ''
+
+ # If nothing is left, StopIteration will avoid the warning:
+ tag = (tag if tag else tags.next(),)
+ sys.stderr.write('Ignoring unparsed cruft %s in %s\n' % ('_'.join(tag + tuple(tags)), name))
+
if len(sys.argv) != 2:
usage()
@@ -451,34 +488,30 @@ cldr_files = os.listdir(cldr_dir)
locale_database = {}
# see http://www.unicode.org/reports/tr35/tr35-info.html#Default_Content
-defaultContent_locales = {}
+defaultContent_locales = []
for ns in findTagsInFile(os.path.join(cldr_dir, '..', 'supplemental',
'supplementalMetadata.xml'),
'metadata/defaultContent'):
for data in ns[1:][0]:
if data[0] == u"locales":
- defaultContent_locales = data[1].split()
+ defaultContent_locales += data[1].split()
+skips = []
for file in defaultContent_locales:
- items = file.split("_")
- if len(items) == 3:
- language_code = items[0]
- script_code = items[1]
- country_code = items[2]
- else:
- if len(items) != 2:
- sys.stderr.write('skipping defaultContent locale "' + file + '" [neither lang_script_country nor lang_country]\n')
- continue
- language_code = items[0]
- script_code = ""
- country_code = items[1]
- if len(country_code) == 4:
- sys.stderr.write('skipping defaultContent locale "' + file + '" [long country code]\n')
- continue
+ try:
+ language_code, script_code, country_code = splitLocale(file)
+ except ValueError:
+ sys.stderr.write('skipping defaultContent locale "' + file + '" [neither two nor three tags]\n')
+ continue
+
+ if not (script_code or country_code):
+ sys.stderr.write('skipping defaultContent locale "' + file + '" [second tag is neither script nor territory]\n')
+ continue
+
try:
l = _generateLocaleInfo(cldr_dir + "/" + file + ".xml", language_code, script_code, country_code)
if not l:
- sys.stderr.write('skipping defaultContent locale "' + file + '" [no locale info generated]\n')
+ skips.append(file)
continue
except xpathlite.Error as e:
sys.stderr.write('skipping defaultContent locale "%s" (%s)\n' % (file, str(e)))
@@ -486,11 +519,15 @@ for file in defaultContent_locales:
locale_database[(l.language_id, l.script_id, l.country_id, l.variant_code)] = l
+if skips:
+ wrappedwarn('skipping defaultContent locales [no locale info generated]: ', skips)
+ skips = []
+
for file in cldr_files:
try:
l = generateLocaleInfo(cldr_dir + "/" + file)
if not l:
- sys.stderr.write('skipping file "' + file + '" [no locale info generated]\n')
+ skips.append(file)
continue
except xpathlite.Error as e:
sys.stderr.write('skipping file "%s" (%s)\n' % (file, str(e)))
@@ -498,6 +535,9 @@ for file in cldr_files:
locale_database[(l.language_id, l.script_id, l.country_id, l.variant_code)] = l
+if skips:
+ wrappedwarn('skipping files [no locale info generated]: ', skips)
+
integrateWeekData(cldr_dir+"/../supplemental/supplementalData.xml")
locale_keys = locale_database.keys()
locale_keys.sort()
@@ -548,34 +588,35 @@ def _parseLocale(l):
if l == "und":
raise xpathlite.Error("we are treating unknown locale like C")
- items = l.split("_")
- language_code = items[0]
+ parsed = splitLocale(l)
+ language_code = parsed.next()
+ script_code = country_code = ''
+ try:
+ script_code, country_code = parsed
+ except ValueError:
+ pass
+
if language_code != "und":
language_id = enumdata.languageCodeToId(language_code)
if language_id == -1:
raise xpathlite.Error('unknown language code "%s"' % language_code)
language = enumdata.language_list[language_id][0]
- if len(items) > 1:
- script_code = items[1]
- country_code = ""
- if len(items) > 2:
- country_code = items[2]
- if len(script_code) == 4:
- script_id = enumdata.scriptCodeToId(script_code)
- if script_id == -1:
- raise xpathlite.Error('unknown script code "%s"' % script_code)
- script = enumdata.script_list[script_id][0]
- else:
- country_code = script_code
- if country_code:
- country_id = enumdata.countryCodeToId(country_code)
- if country_id == -1:
- raise xpathlite.Error('unknown country code "%s"' % country_code)
- country = enumdata.country_list[country_id][0]
+ if script_code:
+ script_id = enumdata.scriptCodeToId(script_code)
+ if script_id == -1:
+ raise xpathlite.Error('unknown script code "%s"' % script_code)
+ script = enumdata.script_list[script_id][0]
+
+ if country_code:
+ country_id = enumdata.countryCodeToId(country_code)
+ if country_id == -1:
+ raise xpathlite.Error('unknown country code "%s"' % country_code)
+ country = enumdata.country_list[country_id][0]
return (language, script, country)
+skips = []
print " <likelySubtags>"
for ns in findTagsInFile(cldr_dir + "/../supplemental/likelySubtags.xml", "likelySubtags"):
tmp = {}
@@ -583,14 +624,13 @@ for ns in findTagsInFile(cldr_dir + "/../supplemental/likelySubtags.xml", "likel
tmp[data[0]] = data[1]
try:
- (from_language, from_script, from_country) = _parseLocale(tmp[u"from"])
+ from_language, from_script, from_country = _parseLocale(tmp[u"from"])
+ to_language, to_script, to_country = _parseLocale(tmp[u"to"])
except xpathlite.Error as e:
- sys.stderr.write('skipping likelySubtag "%s" -> "%s" (%s)\n' % (tmp[u"from"], tmp[u"to"], str(e)))
- continue
- try:
- (to_language, to_script, to_country) = _parseLocale(tmp[u"to"])
- except xpathlite.Error as e:
- sys.stderr.write('skipping likelySubtag "%s" -> "%s" (%s)\n' % (tmp[u"from"], tmp[u"to"], str(e)))
+ if tmp[u'to'].startswith(tmp[u'from']) and str(e) == 'unknown language code "%s"' % tmp[u'from']:
+ skips.append(tmp[u'to'])
+ else:
+ sys.stderr.write('skipping likelySubtag "%s" -> "%s" (%s)\n' % (tmp[u"from"], tmp[u"to"], str(e)))
continue
# substitute according to http://www.unicode.org/reports/tr35/#Likely_Subtags
if to_country == "AnyCountry" and from_country != to_country:
@@ -611,7 +651,8 @@ for ns in findTagsInFile(cldr_dir + "/../supplemental/likelySubtags.xml", "likel
print " </to>"
print " </likelySubtag>"
print " </likelySubtags>"
-
+if skips:
+ wrappedwarn('skipping likelySubtags (for unknown language codes): ', skips)
print " <localeList>"
Locale.C().toXml()
diff --git a/util/local_database/enumdata.py b/util/local_database/enumdata.py
index e24ac02b07..26bb74d1fe 100644
--- a/util/local_database/enumdata.py
+++ b/util/local_database/enumdata.py
@@ -37,366 +37,371 @@
### Qt 6: restore alphabetic order in each list.
language_list = {
- 0 : ["AnyLanguage", " "],
- 1 : ["C", " "],
- 2 : ["Abkhazian", "ab"],
- 3 : ["Oromo", "om"], # macrolanguage
- 4 : ["Afar", "aa"],
- 5 : ["Afrikaans", "af"],
- 6 : ["Albanian", "sq"], # macrolanguage
- 7 : ["Amharic", "am"],
- 8 : ["Arabic", "ar"], # macrolanguage
- 9 : ["Armenian", "hy"],
- 10 : ["Assamese", "as"],
- 11 : ["Aymara", "ay"], # macrolanguage
- 12 : ["Azerbaijani", "az"], # macrolanguage
- 13 : ["Bashkir", "ba"],
- 14 : ["Basque", "eu"],
- 15 : ["Bengali", "bn"],
- 16 : ["Dzongkha", "dz"],
- 17 : ["Bihari", "bh"],
- 18 : ["Bislama", "bi"],
- 19 : ["Breton", "br"],
- 20 : ["Bulgarian", "bg"],
- 21 : ["Burmese", "my"],
- 22 : ["Belarusian", "be"],
- 23 : ["Khmer", "km"],
- 24 : ["Catalan", "ca"],
- 25 : ["Chinese", "zh"], # macrolanguage
- 26 : ["Corsican", "co"],
- 27 : ["Croatian", "hr"],
- 28 : ["Czech", "cs"],
- 29 : ["Danish", "da"],
- 30 : ["Dutch", "nl"],
- 31 : ["English", "en"],
- 32 : ["Esperanto", "eo"],
- 33 : ["Estonian", "et"], # macrolanguage
- 34 : ["Faroese", "fo"],
- 35 : ["Fijian", "fj"],
- 36 : ["Finnish", "fi"],
- 37 : ["French", "fr"],
- 38 : ["Western Frisian", "fy"],
- 39 : ["Gaelic", "gd"],
- 40 : ["Galician", "gl"],
- 41 : ["Georgian", "ka"],
- 42 : ["German", "de"],
- 43 : ["Greek", "el"],
- 44 : ["Greenlandic", "kl"],
- 45 : ["Guarani", "gn"], # macrolanguage
- 46 : ["Gujarati", "gu"],
- 47 : ["Hausa", "ha"],
- 48 : ["Hebrew", "he"],
- 49 : ["Hindi", "hi"],
- 50 : ["Hungarian", "hu"],
- 51 : ["Icelandic", "is"],
- 52 : ["Indonesian", "id"],
- 53 : ["Interlingua", "ia"],
- 54 : ["Interlingue", "ie"],
- 55 : ["Inuktitut", "iu"], # macrolanguage
- 56 : ["Inupiak", "ik"], # macrolanguage
- 57 : ["Irish", "ga"],
- 58 : ["Italian", "it"],
- 59 : ["Japanese", "ja"],
- 60 : ["Javanese", "jv"],
- 61 : ["Kannada", "kn"],
- 62 : ["Kashmiri", "ks"],
- 63 : ["Kazakh", "kk"],
- 64 : ["Kinyarwanda", "rw"],
- 65 : ["Kirghiz", "ky"],
- 66 : ["Korean", "ko"],
- 67 : ["Kurdish", "ku"], # macrolanguage
- 68 : ["Rundi", "rn"],
- 69 : ["Lao", "lo"],
- 70 : ["Latin", "la"],
- 71 : ["Latvian", "lv"], # macrolanguage
- 72 : ["Lingala", "ln"],
- 73 : ["Lithuanian", "lt"],
- 74 : ["Macedonian", "mk"],
- 75 : ["Malagasy", "mg"], # macrolanguage
- 76 : ["Malay", "ms"], # macrolanguage
- 77 : ["Malayalam", "ml"],
- 78 : ["Maltese", "mt"],
- 79 : ["Maori", "mi"],
- 80 : ["Marathi", "mr"],
- 81 : ["Marshallese", "mh"],
- 82 : ["Mongolian", "mn"], # macrolanguage
- 83 : ["Nauru", "na"],
- 84 : ["Nepali", "ne"], # macrolanguage
- 85 : ["Norwegian Bokmal", "nb"],
- 86 : ["Occitan", "oc"],
- 87 : ["Oriya", "or"], # macrolanguage
- 88 : ["Pashto", "ps"], # macrolanguage
- 89 : ["Persian", "fa"], # macrolanguage
- 90 : ["Polish", "pl"],
- 91 : ["Portuguese", "pt"],
- 92 : ["Punjabi", "pa"],
- 93 : ["Quechua", "qu"], # macrolanguage
- 94 : ["Romansh", "rm"],
- 95 : ["Romanian", "ro"],
- 96 : ["Russian", "ru"],
- 97 : ["Samoan", "sm"],
- 98 : ["Sango", "sg"],
- 99 : ["Sanskrit", "sa"],
- 100 : ["Serbian", "sr"],
- 101 : ["Ossetic", "os"],
- 102 : ["Southern Sotho", "st"],
- 103 : ["Tswana", "tn"],
- 104 : ["Shona", "sn"],
- 105 : ["Sindhi", "sd"],
- 106 : ["Sinhala", "si"],
- 107 : ["Swati", "ss"],
- 108 : ["Slovak", "sk"],
- 109 : ["Slovenian", "sl"],
- 110 : ["Somali", "so"],
- 111 : ["Spanish", "es"],
- 112 : ["Sundanese", "su"],
- 113 : ["Swahili", "sw"], # macrolanguage
- 114 : ["Swedish", "sv"],
- 115 : ["Sardinian", "sc"], # macrolanguage
- 116 : ["Tajik", "tg"],
- 117 : ["Tamil", "ta"],
- 118 : ["Tatar", "tt"],
- 119 : ["Telugu", "te"],
- 120 : ["Thai", "th"],
- 121 : ["Tibetan", "bo"],
- 122 : ["Tigrinya", "ti"],
- 123 : ["Tongan", "to"],
- 124 : ["Tsonga", "ts"],
- 125 : ["Turkish", "tr"],
- 126 : ["Turkmen", "tk"],
- 127 : ["Tahitian", "ty"],
- 128 : ["Uighur", "ug"],
- 129 : ["Ukrainian", "uk"],
- 130 : ["Urdu", "ur"],
- 131 : ["Uzbek", "uz"], # macrolanguage
- 132 : ["Vietnamese", "vi"],
- 133 : ["Volapuk", "vo"],
- 134 : ["Welsh", "cy"],
- 135 : ["Wolof", "wo"],
- 136 : ["Xhosa", "xh"],
- 137 : ["Yiddish", "yi"], # macrolanguage
- 138 : ["Yoruba", "yo"],
- 139 : ["Zhuang", "za"], # macrolanguage
- 140 : ["Zulu", "zu"],
- 141 : ["Norwegian Nynorsk", "nn"],
- 142 : ["Bosnian", "bs"],
- 143 : ["Divehi", "dv"],
- 144 : ["Manx", "gv"],
- 145 : ["Cornish", "kw"],
- 146 : ["Akan", "ak"], # macrolanguage
- 147 : ["Konkani", "kok"],
- 148 : ["Ga", "gaa"],
- 149 : ["Igbo", "ig" ],
- 150 : ["Kamba", "kam"],
- 151 : ["Syriac", "syr"],
- 152 : ["Blin", "byn"],
- 153 : ["Geez", "gez"],
- 154 : ["Koro", "kfo"],
- 155 : ["Sidamo", "sid"],
- 156 : ["Atsam", "cch"],
- 157 : ["Tigre", "tig"],
- 158 : ["Jju", "kaj"],
- 159 : ["Friulian", "fur"],
- 160 : ["Venda", "ve" ],
- 161 : ["Ewe", "ee" ],
- 162 : ["Walamo", "wal"],
- 163 : ["Hawaiian", "haw"],
- 164 : ["Tyap", "kcg"],
- 165 : ["Nyanja", "ny" ],
- 166 : ["Filipino", "fil"],
- 167 : ["Swiss German", "gsw"],
- 168 : ["Sichuan Yi", "ii" ],
- 169 : ["Kpelle", "kpe"],
- 170 : ["Low German", "nds"],
- 171 : ["South Ndebele", "nr" ],
- 172 : ["Northern Sotho", "nso"],
- 173 : ["Northern Sami", "se" ],
- 174 : ["Taroko", "trv"],
- 175 : ["Gusii", "guz"],
- 176 : ["Taita", "dav"],
- 177 : ["Fulah", "ff"], # macrolanguage
- 178 : ["Kikuyu", "ki"],
- 179 : ["Samburu", "saq"],
- 180 : ["Sena", "seh"],
- 181 : ["North Ndebele", "nd"],
- 182 : ["Rombo", "rof"],
- 183 : ["Tachelhit", "shi"],
- 184 : ["Kabyle", "kab"],
- 185 : ["Nyankole", "nyn"],
- 186 : ["Bena", "bez"],
- 187 : ["Vunjo", "vun"],
- 188 : ["Bambara", "bm"],
- 189 : ["Embu", "ebu"],
- 190 : ["Cherokee", "chr"],
- 191 : ["Morisyen", "mfe"],
- 192 : ["Makonde", "kde"],
- 193 : ["Langi", "lag"],
- 194 : ["Ganda", "lg"],
- 195 : ["Bemba", "bem"],
- 196 : ["Kabuverdianu", "kea"],
- 197 : ["Meru", "mer"],
- 198 : ["Kalenjin", "kln"],
- 199 : ["Nama", "naq"],
- 200 : ["Machame", "jmc"],
- 201 : ["Colognian", "ksh"],
- 202 : ["Masai", "mas"],
- 203 : ["Soga", "xog"],
- 204 : ["Luyia", "luy"],
- 205 : ["Asu", "asa"],
- 206 : ["Teso", "teo"],
- 207 : ["Saho", "ssy"],
- 208 : ["Koyra Chiini", "khq"],
- 209 : ["Rwa", "rwk"],
- 210 : ["Luo", "luo"],
- 211 : ["Chiga", "cgg"],
- 212 : ["Central Morocco Tamazight", "tzm"],
- 213 : ["Koyraboro Senni", "ses"],
- 214 : ["Shambala", "ksb"],
- 215 : ["Bodo", "brx"],
- 216 : ["Avaric", "av"],
- 217 : ["Chamorro", "ch"],
- 218 : ["Chechen", "ce"],
- 219 : ["Church", "cu"], # macrolanguage
- 220 : ["Chuvash", "cv"],
- 221 : ["Cree", "cr"], # macrolanguage
- 222 : ["Haitian", "ht"],
- 223 : ["Herero", "hz"],
- 224 : ["Hiri Motu", "ho"],
- 225 : ["Kanuri", "kr"], # macrolanguage
- 226 : ["Komi", "kv"], # macrolanguage
- 227 : ["Kongo", "kg"], # macrolanguage
- 228 : ["Kwanyama", "kj"],
- 229 : ["Limburgish", "li"],
- 230 : ["Luba Katanga", "lu"],
- 231 : ["Luxembourgish", "lb"],
- 232 : ["Navaho", "nv"],
- 233 : ["Ndonga", "ng"],
- 234 : ["Ojibwa", "oj"], # macrolanguage
- 235 : ["Pali", "pi"], # macrolanguage
- 236 : ["Walloon", "wa"],
- 237 : ["Aghem", "agq"],
- 238 : ["Basaa", "bas"],
- 239 : ["Zarma", "dje"],
- 240 : ["Duala", "dua"],
- 241 : ["Jola Fonyi", "dyo"],
- 242 : ["Ewondo", "ewo"],
- 243 : ["Bafia", "ksf"],
- 244 : ["Makhuwa Meetto", "mgh"],
- 245 : ["Mundang", "mua"],
- 246 : ["Kwasio", "nmg"],
- 247 : ["Nuer", "nus"],
- 248 : ["Sakha", "sah"],
- 249 : ["Sangu", "sbp"],
- 250 : ["Congo Swahili", "swc"],
- 251 : ["Tasawaq", "twq"],
- 252 : ["Vai", "vai"],
- 253 : ["Walser", "wae"],
- 254 : ["Yangben", "yav"],
- 255 : ["Avestan", "ae"],
- 256 : ["Asturian", "ast"],
- 257 : ["Ngomba", "jgo"],
- 258 : ["Kako", "kkj"],
- 259 : ["Meta", "mgo"],
- 260 : ["Ngiemboon", "nnh"],
- 261 : ["Aragonese", "an"],
- 262 : ["Akkadian", "akk"],
- 263 : ["Ancient Egyptian", "egy"],
- 264 : ["Ancient Greek", "grc"],
- 265 : ["Aramaic", "arc"],
- 266 : ["Balinese", "ban"],
- 267 : ["Bamun", "bax"],
- 268 : ["Batak Toba", "bbc"],
- 269 : ["Buginese", "bug"],
- 270 : ["Buhid", "bku"],
- 271 : ["Carian", "xcr"],
- 272 : ["Chakma", "ccp"],
- 273 : ["Classical Mandaic", "myz"],
- 274 : ["Coptic", "cop"],
- 275 : ["Dogri", "doi"], # macrolanguage
- 276 : ["Eastern Cham", "cjm"],
- 277 : ["Eastern Kayah", "eky"],
- 278 : ["Etruscan", "ett"],
- 279 : ["Gothic", "got"],
- 280 : ["Hanunoo", "hnn"],
- 281 : ["Ingush", "inh"],
- 282 : ["Large Flowery Miao", "hmd"],
- 283 : ["Lepcha", "lep"],
- 284 : ["Limbu", "lif"],
- 285 : ["Lisu", "lis"],
- 286 : ["Lu", "khb"],
- 287 : ["Lycian", "xlc"],
- 288 : ["Lydian", "xld"],
- 289 : ["Mandingo", "man"], # macrolanguage
- 290 : ["Manipuri", "mni"],
- 291 : ["Meroitic", "xmr"],
- 292 : ["Northern Thai", "nod"],
- 293 : ["Old Irish", "sga"],
- 294 : ["Old Norse", "non"],
- 295 : ["Old Persian", "peo"],
- 296 : ["Old Turkish", "otk"],
- 297 : ["Pahlavi", "pal"],
- 298 : ["Parthian", "xpr"],
- 299 : ["Phoenician", "phn"],
- 300 : ["Prakrit Language", "pra"],
- 301 : ["Rejang", "rej"],
- 302 : ["Sabaean", "xsa"],
- 303 : ["Samaritan", "smp"],
- 304 : ["Santali", "sat"],
- 305 : ["Saurashtra", "saz"],
- 306 : ["Sora", "srb"],
- 307 : ["Sylheti", "syl"],
- 308 : ["Tagbanwa", "tbw"],
- 309 : ["Tai Dam", "blt"],
- 310 : ["Tai Nua", "tdd"],
- 311 : ["Ugaritic", "uga"],
- 312 : ["Akoose", "bss"],
- 313 : ["Lakota", "lkt"],
- 314 : ["Standard Moroccan Tamazight", "zgh"],
- 315 : ["Mapuche", "arn"],
- 316 : ["Central Kurdish", "ckb"],
- 317 : ["Lower Sorbian", "dsb"],
- 318 : ["Upper Sorbian", "hsb"],
- 319 : ["Kenyang", "ken"],
- 320 : ["Mohawk", "moh"],
- 321 : ["Nko", "nqo"],
- 322 : ["Prussian", "prg"],
- 323 : ["Kiche", "quc"],
- 324 : ["Southern Sami", "sma"],
- 325 : ["Lule Sami", "smj"],
- 326 : ["Inari Sami", "smn"],
- 327 : ["Skolt Sami", "sms"],
- 328 : ["Warlpiri", "wbp"],
- 329 : ["Manichaean Middle Persian", "xmn"],
- 330 : ["Mende", "men"],
- 331 : ["Ancient North Arabian", "xna"],
- 332 : ["Linear A", "lab"],
- 333 : ["Hmong Njua", "hnj"],
- 334 : ["Ho", "hoc"],
- 335 : ["Lezghian", "lez"],
- 336 : ["Bassa", "bsq"],
- 337 : ["Mono", "mru"],
- 338 : ["Tedim Chin", "ctd"],
- 339 : ["Maithili", "mai"],
- 340 : ["Ahom", "aho"],
- 341 : ["American Sign Language", "ase"],
- 342 : ["Ardhamagadhi Prakrit", "pka"],
- 343 : ["Bhojpuri", "bho"],
- 344 : ["Hieroglyphic Luwian", "hlu"],
- 345 : ["Literary Chinese", "lzh"],
- 346 : ["Mazanderani", "mzn"],
- 347 : ["Mru", "mro"],
- 348 : ["Newari", "new"],
- 349 : ["Northern Luri", "lrc"],
- 350 : ["Palauan", "pau"],
- 351 : ["Papiamento", "pap"],
- 352 : ["Saraiki", "skr"],
- 353 : ["Tokelau", "tkl"],
- 354 : ["Tok Pisin", "tpi"],
- 355 : ["Tuvalu", "tvl"],
- 356 : ["Uncoded Languages", "mis"],
- 357 : ["Cantonese", "yue"],
- 358 : ["Osage", "osa"],
- 359 : ["Tangut", "txg"]
+ 0: ["AnyLanguage", " "],
+ 1: ["C", " "],
+ 2: ["Abkhazian", "ab"],
+ 3: ["Oromo", "om"], # macrolanguage
+ 4: ["Afar", "aa"],
+ 5: ["Afrikaans", "af"],
+ 6: ["Albanian", "sq"], # macrolanguage
+ 7: ["Amharic", "am"],
+ 8: ["Arabic", "ar"], # macrolanguage
+ 9: ["Armenian", "hy"],
+ 10: ["Assamese", "as"],
+ 11: ["Aymara", "ay"], # macrolanguage
+ 12: ["Azerbaijani", "az"], # macrolanguage
+ 13: ["Bashkir", "ba"],
+ 14: ["Basque", "eu"],
+ 15: ["Bengali", "bn"],
+ 16: ["Dzongkha", "dz"],
+ 17: ["Bihari", "bh"],
+ 18: ["Bislama", "bi"],
+ 19: ["Breton", "br"],
+ 20: ["Bulgarian", "bg"],
+ 21: ["Burmese", "my"],
+ 22: ["Belarusian", "be"],
+ 23: ["Khmer", "km"],
+ 24: ["Catalan", "ca"],
+ 25: ["Chinese", "zh"], # macrolanguage
+ 26: ["Corsican", "co"],
+ 27: ["Croatian", "hr"],
+ 28: ["Czech", "cs"],
+ 29: ["Danish", "da"],
+ 30: ["Dutch", "nl"],
+ 31: ["English", "en"],
+ 32: ["Esperanto", "eo"],
+ 33: ["Estonian", "et"], # macrolanguage
+ 34: ["Faroese", "fo"],
+ 35: ["Fijian", "fj"],
+ 36: ["Finnish", "fi"],
+ 37: ["French", "fr"],
+ 38: ["Western Frisian", "fy"],
+ 39: ["Gaelic", "gd"],
+ 40: ["Galician", "gl"],
+ 41: ["Georgian", "ka"],
+ 42: ["German", "de"],
+ 43: ["Greek", "el"],
+ 44: ["Greenlandic", "kl"],
+ 45: ["Guarani", "gn"], # macrolanguage
+ 46: ["Gujarati", "gu"],
+ 47: ["Hausa", "ha"],
+ 48: ["Hebrew", "he"],
+ 49: ["Hindi", "hi"],
+ 50: ["Hungarian", "hu"],
+ 51: ["Icelandic", "is"],
+ 52: ["Indonesian", "id"],
+ 53: ["Interlingua", "ia"],
+ 54: ["Interlingue", "ie"],
+ 55: ["Inuktitut", "iu"], # macrolanguage
+ 56: ["Inupiak", "ik"], # macrolanguage
+ 57: ["Irish", "ga"],
+ 58: ["Italian", "it"],
+ 59: ["Japanese", "ja"],
+ 60: ["Javanese", "jv"],
+ 61: ["Kannada", "kn"],
+ 62: ["Kashmiri", "ks"],
+ 63: ["Kazakh", "kk"],
+ 64: ["Kinyarwanda", "rw"],
+ 65: ["Kirghiz", "ky"],
+ 66: ["Korean", "ko"],
+ 67: ["Kurdish", "ku"], # macrolanguage
+ 68: ["Rundi", "rn"],
+ 69: ["Lao", "lo"],
+ 70: ["Latin", "la"],
+ 71: ["Latvian", "lv"], # macrolanguage
+ 72: ["Lingala", "ln"],
+ 73: ["Lithuanian", "lt"],
+ 74: ["Macedonian", "mk"],
+ 75: ["Malagasy", "mg"], # macrolanguage
+ 76: ["Malay", "ms"], # macrolanguage
+ 77: ["Malayalam", "ml"],
+ 78: ["Maltese", "mt"],
+ 79: ["Maori", "mi"],
+ 80: ["Marathi", "mr"],
+ 81: ["Marshallese", "mh"],
+ 82: ["Mongolian", "mn"], # macrolanguage
+ 83: ["Nauru", "na"],
+ 84: ["Nepali", "ne"], # macrolanguage
+ 85: ["Norwegian Bokmal", "nb"],
+ 86: ["Occitan", "oc"],
+ 87: ["Oriya", "or"], # macrolanguage
+ 88: ["Pashto", "ps"], # macrolanguage
+ 89: ["Persian", "fa"], # macrolanguage
+ 90: ["Polish", "pl"],
+ 91: ["Portuguese", "pt"],
+ 92: ["Punjabi", "pa"],
+ 93: ["Quechua", "qu"], # macrolanguage
+ 94: ["Romansh", "rm"],
+ 95: ["Romanian", "ro"],
+ 96: ["Russian", "ru"],
+ 97: ["Samoan", "sm"],
+ 98: ["Sango", "sg"],
+ 99: ["Sanskrit", "sa"],
+ 100: ["Serbian", "sr"],
+ 101: ["Ossetic", "os"],
+ 102: ["Southern Sotho", "st"],
+ 103: ["Tswana", "tn"],
+ 104: ["Shona", "sn"],
+ 105: ["Sindhi", "sd"],
+ 106: ["Sinhala", "si"],
+ 107: ["Swati", "ss"],
+ 108: ["Slovak", "sk"],
+ 109: ["Slovenian", "sl"],
+ 110: ["Somali", "so"],
+ 111: ["Spanish", "es"],
+ 112: ["Sundanese", "su"],
+ 113: ["Swahili", "sw"], # macrolanguage
+ 114: ["Swedish", "sv"],
+ 115: ["Sardinian", "sc"], # macrolanguage
+ 116: ["Tajik", "tg"],
+ 117: ["Tamil", "ta"],
+ 118: ["Tatar", "tt"],
+ 119: ["Telugu", "te"],
+ 120: ["Thai", "th"],
+ 121: ["Tibetan", "bo"],
+ 122: ["Tigrinya", "ti"],
+ 123: ["Tongan", "to"],
+ 124: ["Tsonga", "ts"],
+ 125: ["Turkish", "tr"],
+ 126: ["Turkmen", "tk"],
+ 127: ["Tahitian", "ty"],
+ 128: ["Uighur", "ug"],
+ 129: ["Ukrainian", "uk"],
+ 130: ["Urdu", "ur"],
+ 131: ["Uzbek", "uz"], # macrolanguage
+ 132: ["Vietnamese", "vi"],
+ 133: ["Volapuk", "vo"],
+ 134: ["Welsh", "cy"],
+ 135: ["Wolof", "wo"],
+ 136: ["Xhosa", "xh"],
+ 137: ["Yiddish", "yi"], # macrolanguage
+ 138: ["Yoruba", "yo"],
+ 139: ["Zhuang", "za"], # macrolanguage
+ 140: ["Zulu", "zu"],
+ 141: ["Norwegian Nynorsk", "nn"],
+ 142: ["Bosnian", "bs"],
+ 143: ["Divehi", "dv"],
+ 144: ["Manx", "gv"],
+ 145: ["Cornish", "kw"],
+ 146: ["Akan", "ak"], # macrolanguage
+ 147: ["Konkani", "kok"],
+ 148: ["Ga", "gaa"],
+ 149: ["Igbo", "ig" ],
+ 150: ["Kamba", "kam"],
+ 151: ["Syriac", "syr"],
+ 152: ["Blin", "byn"],
+ 153: ["Geez", "gez"],
+ 154: ["Koro", "kfo"],
+ 155: ["Sidamo", "sid"],
+ 156: ["Atsam", "cch"],
+ 157: ["Tigre", "tig"],
+ 158: ["Jju", "kaj"],
+ 159: ["Friulian", "fur"],
+ 160: ["Venda", "ve" ],
+ 161: ["Ewe", "ee" ],
+ 162: ["Walamo", "wal"],
+ 163: ["Hawaiian", "haw"],
+ 164: ["Tyap", "kcg"],
+ 165: ["Nyanja", "ny" ],
+ 166: ["Filipino", "fil"],
+ 167: ["Swiss German", "gsw"],
+ 168: ["Sichuan Yi", "ii" ],
+ 169: ["Kpelle", "kpe"],
+ 170: ["Low German", "nds"],
+ 171: ["South Ndebele", "nr" ],
+ 172: ["Northern Sotho", "nso"],
+ 173: ["Northern Sami", "se" ],
+ 174: ["Taroko", "trv"],
+ 175: ["Gusii", "guz"],
+ 176: ["Taita", "dav"],
+ 177: ["Fulah", "ff"], # macrolanguage
+ 178: ["Kikuyu", "ki"],
+ 179: ["Samburu", "saq"],
+ 180: ["Sena", "seh"],
+ 181: ["North Ndebele", "nd"],
+ 182: ["Rombo", "rof"],
+ 183: ["Tachelhit", "shi"],
+ 184: ["Kabyle", "kab"],
+ 185: ["Nyankole", "nyn"],
+ 186: ["Bena", "bez"],
+ 187: ["Vunjo", "vun"],
+ 188: ["Bambara", "bm"],
+ 189: ["Embu", "ebu"],
+ 190: ["Cherokee", "chr"],
+ 191: ["Morisyen", "mfe"],
+ 192: ["Makonde", "kde"],
+ 193: ["Langi", "lag"],
+ 194: ["Ganda", "lg"],
+ 195: ["Bemba", "bem"],
+ 196: ["Kabuverdianu", "kea"],
+ 197: ["Meru", "mer"],
+ 198: ["Kalenjin", "kln"],
+ 199: ["Nama", "naq"],
+ 200: ["Machame", "jmc"],
+ 201: ["Colognian", "ksh"],
+ 202: ["Masai", "mas"],
+ 203: ["Soga", "xog"],
+ 204: ["Luyia", "luy"],
+ 205: ["Asu", "asa"],
+ 206: ["Teso", "teo"],
+ 207: ["Saho", "ssy"],
+ 208: ["Koyra Chiini", "khq"],
+ 209: ["Rwa", "rwk"],
+ 210: ["Luo", "luo"],
+ 211: ["Chiga", "cgg"],
+ 212: ["Central Morocco Tamazight", "tzm"],
+ 213: ["Koyraboro Senni", "ses"],
+ 214: ["Shambala", "ksb"],
+ 215: ["Bodo", "brx"],
+ 216: ["Avaric", "av"],
+ 217: ["Chamorro", "ch"],
+ 218: ["Chechen", "ce"],
+ 219: ["Church", "cu"], # macrolanguage
+ 220: ["Chuvash", "cv"],
+ 221: ["Cree", "cr"], # macrolanguage
+ 222: ["Haitian", "ht"],
+ 223: ["Herero", "hz"],
+ 224: ["Hiri Motu", "ho"],
+ 225: ["Kanuri", "kr"], # macrolanguage
+ 226: ["Komi", "kv"], # macrolanguage
+ 227: ["Kongo", "kg"], # macrolanguage
+ 228: ["Kwanyama", "kj"],
+ 229: ["Limburgish", "li"],
+ 230: ["Luba Katanga", "lu"],
+ 231: ["Luxembourgish", "lb"],
+ 232: ["Navaho", "nv"],
+ 233: ["Ndonga", "ng"],
+ 234: ["Ojibwa", "oj"], # macrolanguage
+ 235: ["Pali", "pi"], # macrolanguage
+ 236: ["Walloon", "wa"],
+ 237: ["Aghem", "agq"],
+ 238: ["Basaa", "bas"],
+ 239: ["Zarma", "dje"],
+ 240: ["Duala", "dua"],
+ 241: ["Jola Fonyi", "dyo"],
+ 242: ["Ewondo", "ewo"],
+ 243: ["Bafia", "ksf"],
+ 244: ["Makhuwa Meetto", "mgh"],
+ 245: ["Mundang", "mua"],
+ 246: ["Kwasio", "nmg"],
+ 247: ["Nuer", "nus"],
+ 248: ["Sakha", "sah"],
+ 249: ["Sangu", "sbp"],
+ 250: ["Congo Swahili", "swc"],
+ 251: ["Tasawaq", "twq"],
+ 252: ["Vai", "vai"],
+ 253: ["Walser", "wae"],
+ 254: ["Yangben", "yav"],
+ 255: ["Avestan", "ae"],
+ 256: ["Asturian", "ast"],
+ 257: ["Ngomba", "jgo"],
+ 258: ["Kako", "kkj"],
+ 259: ["Meta", "mgo"],
+ 260: ["Ngiemboon", "nnh"],
+ 261: ["Aragonese", "an"],
+ 262: ["Akkadian", "akk"],
+ 263: ["Ancient Egyptian", "egy"],
+ 264: ["Ancient Greek", "grc"],
+ 265: ["Aramaic", "arc"],
+ 266: ["Balinese", "ban"],
+ 267: ["Bamun", "bax"],
+ 268: ["Batak Toba", "bbc"],
+ 269: ["Buginese", "bug"],
+ 270: ["Buhid", "bku"],
+ 271: ["Carian", "xcr"],
+ 272: ["Chakma", "ccp"],
+ 273: ["Classical Mandaic", "myz"],
+ 274: ["Coptic", "cop"],
+ 275: ["Dogri", "doi"], # macrolanguage
+ 276: ["Eastern Cham", "cjm"],
+ 277: ["Eastern Kayah", "eky"],
+ 278: ["Etruscan", "ett"],
+ 279: ["Gothic", "got"],
+ 280: ["Hanunoo", "hnn"],
+ 281: ["Ingush", "inh"],
+ 282: ["Large Flowery Miao", "hmd"],
+ 283: ["Lepcha", "lep"],
+ 284: ["Limbu", "lif"],
+ 285: ["Lisu", "lis"],
+ 286: ["Lu", "khb"],
+ 287: ["Lycian", "xlc"],
+ 288: ["Lydian", "xld"],
+ 289: ["Mandingo", "man"], # macrolanguage
+ 290: ["Manipuri", "mni"],
+ 291: ["Meroitic", "xmr"],
+ 292: ["Northern Thai", "nod"],
+ 293: ["Old Irish", "sga"],
+ 294: ["Old Norse", "non"],
+ 295: ["Old Persian", "peo"],
+ 296: ["Old Turkish", "otk"],
+ 297: ["Pahlavi", "pal"],
+ 298: ["Parthian", "xpr"],
+ 299: ["Phoenician", "phn"],
+ 300: ["Prakrit Language", "pra"],
+ 301: ["Rejang", "rej"],
+ 302: ["Sabaean", "xsa"],
+ 303: ["Samaritan", "smp"],
+ 304: ["Santali", "sat"],
+ 305: ["Saurashtra", "saz"],
+ 306: ["Sora", "srb"],
+ 307: ["Sylheti", "syl"],
+ 308: ["Tagbanwa", "tbw"],
+ 309: ["Tai Dam", "blt"],
+ 310: ["Tai Nua", "tdd"],
+ 311: ["Ugaritic", "uga"],
+ 312: ["Akoose", "bss"],
+ 313: ["Lakota", "lkt"],
+ 314: ["Standard Moroccan Tamazight", "zgh"],
+ 315: ["Mapuche", "arn"],
+ 316: ["Central Kurdish", "ckb"],
+ 317: ["Lower Sorbian", "dsb"],
+ 318: ["Upper Sorbian", "hsb"],
+ 319: ["Kenyang", "ken"],
+ 320: ["Mohawk", "moh"],
+ 321: ["Nko", "nqo"],
+ 322: ["Prussian", "prg"],
+ 323: ["Kiche", "quc"],
+ 324: ["Southern Sami", "sma"],
+ 325: ["Lule Sami", "smj"],
+ 326: ["Inari Sami", "smn"],
+ 327: ["Skolt Sami", "sms"],
+ 328: ["Warlpiri", "wbp"],
+ 329: ["Manichaean Middle Persian", "xmn"],
+ 330: ["Mende", "men"],
+ 331: ["Ancient North Arabian", "xna"],
+ 332: ["Linear A", "lab"],
+ 333: ["Hmong Njua", "hnj"],
+ 334: ["Ho", "hoc"],
+ 335: ["Lezghian", "lez"],
+ 336: ["Bassa", "bsq"],
+ 337: ["Mono", "mru"],
+ 338: ["Tedim Chin", "ctd"],
+ 339: ["Maithili", "mai"],
+ 340: ["Ahom", "aho"],
+ 341: ["American Sign Language", "ase"],
+ 342: ["Ardhamagadhi Prakrit", "pka"],
+ 343: ["Bhojpuri", "bho"],
+ 344: ["Hieroglyphic Luwian", "hlu"],
+ 345: ["Literary Chinese", "lzh"],
+ 346: ["Mazanderani", "mzn"],
+ 347: ["Mru", "mro"],
+ 348: ["Newari", "new"],
+ 349: ["Northern Luri", "lrc"],
+ 350: ["Palauan", "pau"],
+ 351: ["Papiamento", "pap"],
+ 352: ["Saraiki", "skr"],
+ 353: ["Tokelau", "tkl"],
+ 354: ["Tok Pisin", "tpi"],
+ 355: ["Tuvalu", "tvl"],
+ 356: ["Uncoded Languages", "mis"],
+ 357: ["Cantonese", "yue"],
+ 358: ["Osage", "osa"],
+ 359: ["Tangut", "txg"],
+ 360: ["Ido", "io"],
+ 361: ["Lojban", "jbo"],
+ 362: ["Sicilian", "scn"],
+ 363: ["Southern Kurdish", "sdh"],
+ 364: ["Western Balochi", "bgn"],
}
language_aliases = {
@@ -419,268 +424,268 @@ language_aliases = {
}
country_list = {
- 0 : ["AnyCountry", "ZZ"],
- 1 : ["Afghanistan", "AF"],
- 2 : ["Albania", "AL"],
- 3 : ["Algeria", "DZ"],
- 4 : ["American Samoa", "AS"],
- 5 : ["Andorra", "AD"],
- 6 : ["Angola", "AO"],
- 7 : ["Anguilla", "AI"],
- 8 : ["Antarctica", "AQ"],
- 9 : ["Antigua And Barbuda", "AG"],
- 10 : ["Argentina", "AR"],
- 11 : ["Armenia", "AM"],
- 12 : ["Aruba", "AW"],
- 13 : ["Australia", "AU"],
- 14 : ["Austria", "AT"],
- 15 : ["Azerbaijan", "AZ"],
- 16 : ["Bahamas", "BS"],
- 17 : ["Bahrain", "BH"],
- 18 : ["Bangladesh", "BD"],
- 19 : ["Barbados", "BB"],
- 20 : ["Belarus", "BY"],
- 21 : ["Belgium", "BE"],
- 22 : ["Belize", "BZ"],
- 23 : ["Benin", "BJ"],
- 24 : ["Bermuda", "BM"],
- 25 : ["Bhutan", "BT"],
- 26 : ["Bolivia", "BO"],
- 27 : ["Bosnia And Herzegowina", "BA"],
- 28 : ["Botswana", "BW"],
- 29 : ["Bouvet Island", "BV"],
- 30 : ["Brazil", "BR"],
- 31 : ["British Indian Ocean Territory", "IO"],
- 32 : ["Brunei", "BN"],
- 33 : ["Bulgaria", "BG"],
- 34 : ["Burkina Faso", "BF"],
- 35 : ["Burundi", "BI"],
- 36 : ["Cambodia", "KH"],
- 37 : ["Cameroon", "CM"],
- 38 : ["Canada", "CA"],
- 39 : ["Cape Verde", "CV"],
- 40 : ["Cayman Islands", "KY"],
- 41 : ["Central African Republic", "CF"],
- 42 : ["Chad", "TD"],
- 43 : ["Chile", "CL"],
- 44 : ["China", "CN"],
- 45 : ["Christmas Island", "CX"],
- 46 : ["Cocos Islands", "CC"],
- 47 : ["Colombia", "CO"],
- 48 : ["Comoros", "KM"],
- 49 : ["Congo Kinshasa", "CD"],
- 50 : ["Congo Brazzaville", "CG"],
- 51 : ["Cook Islands", "CK"],
- 52 : ["Costa Rica", "CR"],
- 53 : ["Ivory Coast", "CI"],
- 54 : ["Croatia", "HR"],
- 55 : ["Cuba", "CU"],
- 56 : ["Cyprus", "CY"],
- 57 : ["Czech Republic", "CZ"],
- 58 : ["Denmark", "DK"],
- 59 : ["Djibouti", "DJ"],
- 60 : ["Dominica", "DM"],
- 61 : ["Dominican Republic", "DO"],
- 62 : ["East Timor", "TL"],
- 63 : ["Ecuador", "EC"],
- 64 : ["Egypt", "EG"],
- 65 : ["El Salvador", "SV"],
- 66 : ["Equatorial Guinea", "GQ"],
- 67 : ["Eritrea", "ER"],
- 68 : ["Estonia", "EE"],
- 69 : ["Ethiopia", "ET"],
- 70 : ["Falkland Islands", "FK"],
- 71 : ["Faroe Islands", "FO"],
- 72 : ["Fiji", "FJ"],
- 73 : ["Finland", "FI"],
- 74 : ["France", "FR"],
- 75 : ["Guernsey", "GG"],
- 76 : ["French Guiana", "GF"],
- 77 : ["French Polynesia", "PF"],
- 78 : ["French Southern Territories", "TF"],
- 79 : ["Gabon", "GA"],
- 80 : ["Gambia", "GM"],
- 81 : ["Georgia", "GE"],
- 82 : ["Germany", "DE"],
- 83 : ["Ghana", "GH"],
- 84 : ["Gibraltar", "GI"],
- 85 : ["Greece", "GR"],
- 86 : ["Greenland", "GL"],
- 87 : ["Grenada", "GD"],
- 88 : ["Guadeloupe", "GP"],
- 89 : ["Guam", "GU"],
- 90 : ["Guatemala", "GT"],
- 91 : ["Guinea", "GN"],
- 92 : ["Guinea Bissau", "GW"],
- 93 : ["Guyana", "GY"],
- 94 : ["Haiti", "HT"],
- 95 : ["Heard And McDonald Islands", "HM"],
- 96 : ["Honduras", "HN"],
- 97 : ["Hong Kong", "HK"],
- 98 : ["Hungary", "HU"],
- 99 : ["Iceland", "IS"],
- 100 : ["India", "IN"],
- 101 : ["Indonesia", "ID"],
- 102 : ["Iran", "IR"],
- 103 : ["Iraq", "IQ"],
- 104 : ["Ireland", "IE"],
- 105 : ["Israel", "IL"],
- 106 : ["Italy", "IT"],
- 107 : ["Jamaica", "JM"],
- 108 : ["Japan", "JP"],
- 109 : ["Jordan", "JO"],
- 110 : ["Kazakhstan", "KZ"],
- 111 : ["Kenya", "KE"],
- 112 : ["Kiribati", "KI"],
- 113 : ["North Korea", "KP"],
- 114 : ["South Korea", "KR"],
- 115 : ["Kuwait", "KW"],
- 116 : ["Kyrgyzstan", "KG"],
- 117 : ["Laos", "LA"],
- 118 : ["Latvia", "LV"],
- 119 : ["Lebanon", "LB"],
- 120 : ["Lesotho", "LS"],
- 121 : ["Liberia", "LR"],
- 122 : ["Libya", "LY"],
- 123 : ["Liechtenstein", "LI"],
- 124 : ["Lithuania", "LT"],
- 125 : ["Luxembourg", "LU"],
- 126 : ["Macau", "MO"],
- 127 : ["Macedonia", "MK"],
- 128 : ["Madagascar", "MG"],
- 129 : ["Malawi", "MW"],
- 130 : ["Malaysia", "MY"],
- 131 : ["Maldives", "MV"],
- 132 : ["Mali", "ML"],
- 133 : ["Malta", "MT"],
- 134 : ["Marshall Islands", "MH"],
- 135 : ["Martinique", "MQ"],
- 136 : ["Mauritania", "MR"],
- 137 : ["Mauritius", "MU"],
- 138 : ["Mayotte", "YT"],
- 139 : ["Mexico", "MX"],
- 140 : ["Micronesia", "FM"],
- 141 : ["Moldova", "MD"],
- 142 : ["Monaco", "MC"],
- 143 : ["Mongolia", "MN"],
- 144 : ["Montserrat", "MS"],
- 145 : ["Morocco", "MA"],
- 146 : ["Mozambique", "MZ"],
- 147 : ["Myanmar", "MM"],
- 148 : ["Namibia", "NA"],
- 149 : ["Nauru", "NR"],
- 150 : ["Nepal", "NP"],
- 151 : ["Netherlands", "NL"],
- 152 : ["Cura Sao", "CW"],
- 153 : ["New Caledonia", "NC"],
- 154 : ["New Zealand", "NZ"],
- 155 : ["Nicaragua", "NI"],
- 156 : ["Niger", "NE"],
- 157 : ["Nigeria", "NG"],
- 158 : ["Niue", "NU"],
- 159 : ["Norfolk Island", "NF"],
- 160 : ["Northern Mariana Islands", "MP"],
- 161 : ["Norway", "NO"],
- 162 : ["Oman", "OM"],
- 163 : ["Pakistan", "PK"],
- 164 : ["Palau", "PW"],
- 165 : ["Palestinian Territories", "PS"],
- 166 : ["Panama", "PA"],
- 167 : ["Papua New Guinea", "PG"],
- 168 : ["Paraguay", "PY"],
- 169 : ["Peru", "PE"],
- 170 : ["Philippines", "PH"],
- 171 : ["Pitcairn", "PN"],
- 172 : ["Poland", "PL"],
- 173 : ["Portugal", "PT"],
- 174 : ["Puerto Rico", "PR"],
- 175 : ["Qatar", "QA"],
- 176 : ["Reunion", "RE"],
- 177 : ["Romania", "RO"],
- 178 : ["Russia", "RU"],
- 179 : ["Rwanda", "RW"],
- 180 : ["Saint Kitts And Nevis", "KN"],
- 181 : ["Saint Lucia", "LC"],
- 182 : ["Saint Vincent And The Grenadines", "VC"],
- 183 : ["Samoa", "WS"],
- 184 : ["San Marino", "SM"],
- 185 : ["Sao Tome And Principe", "ST"],
- 186 : ["Saudi Arabia", "SA"],
- 187 : ["Senegal", "SN"],
- 188 : ["Seychelles", "SC"],
- 189 : ["Sierra Leone", "SL"],
- 190 : ["Singapore", "SG"],
- 191 : ["Slovakia", "SK"],
- 192 : ["Slovenia", "SI"],
- 193 : ["Solomon Islands", "SB"],
- 194 : ["Somalia", "SO"],
- 195 : ["South Africa", "ZA"],
- 196 : ["South Georgia And The South Sandwich Islands", "GS"],
- 197 : ["Spain", "ES"],
- 198 : ["Sri Lanka", "LK"],
- 199 : ["Saint Helena", "SH"],
- 200 : ["Saint Pierre And Miquelon", "PM"],
- 201 : ["Sudan", "SD"],
- 202 : ["Suriname", "SR"],
- 203 : ["Svalbard And Jan Mayen Islands", "SJ"],
- 204 : ["Swaziland", "SZ"],
- 205 : ["Sweden", "SE"],
- 206 : ["Switzerland", "CH"],
- 207 : ["Syria", "SY"],
- 208 : ["Taiwan", "TW"],
- 209 : ["Tajikistan", "TJ"],
- 210 : ["Tanzania", "TZ"],
- 211 : ["Thailand", "TH"],
- 212 : ["Togo", "TG"],
- 213 : ["Tokelau", "TK"],
- 214 : ["Tonga", "TO"],
- 215 : ["Trinidad And Tobago", "TT"],
- 216 : ["Tunisia", "TN"],
- 217 : ["Turkey", "TR"],
- 218 : ["Turkmenistan", "TM"],
- 219 : ["Turks And Caicos Islands", "TC"],
- 220 : ["Tuvalu", "TV"],
- 221 : ["Uganda", "UG"],
- 222 : ["Ukraine", "UA"],
- 223 : ["United Arab Emirates", "AE"],
- 224 : ["United Kingdom", "GB"],
- 225 : ["United States", "US"],
- 226 : ["United States Minor Outlying Islands", "UM"],
- 227 : ["Uruguay", "UY"],
- 228 : ["Uzbekistan", "UZ"],
- 229 : ["Vanuatu", "VU"],
- 230 : ["Vatican City State", "VA"],
- 231 : ["Venezuela", "VE"],
- 232 : ["Vietnam", "VN"],
- 233 : ["British Virgin Islands", "VG"],
- 234 : ["United States Virgin Islands", "VI"],
- 235 : ["Wallis And Futuna Islands", "WF"],
- 236 : ["Western Sahara", "EH"],
- 237 : ["Yemen", "YE"],
- 238 : ["Canary Islands", "IC"],
- 239 : ["Zambia", "ZM"],
- 240 : ["Zimbabwe", "ZW"],
- 241 : ["Clipperton Island", "CP"],
- 242 : ["Montenegro", "ME"],
- 243 : ["Serbia", "RS"],
- 244 : ["Saint Barthelemy", "BL"],
- 245 : ["Saint Martin", "MF"],
- 246 : ["Latin America", "419"],
- 247 : ["Ascension Island", "AC"],
- 248 : ["Aland Islands", "AX"],
- 249 : ["Diego Garcia", "DG"],
- 250 : ["Ceuta And Melilla", "EA"],
- 251 : ["Isle Of Man", "IM"],
- 252 : ["Jersey", "JE"],
- 253 : ["Tristan Da Cunha", "TA"],
- 254 : ["South Sudan", "SS"],
- 255 : ["Bonaire", "BQ"],
- 256 : ["Sint Maarten", "SX"],
- 257 : ["Kosovo", "XK"],
- 258 : ["European Union", "EU"],
- 259 : ["Outlying Oceania", "QO"],
- 260 : ["World", "001"],
- 261 : ["Europe", "150"]
+ 0: ["AnyCountry", "ZZ"],
+ 1: ["Afghanistan", "AF"],
+ 2: ["Albania", "AL"],
+ 3: ["Algeria", "DZ"],
+ 4: ["American Samoa", "AS"],
+ 5: ["Andorra", "AD"],
+ 6: ["Angola", "AO"],
+ 7: ["Anguilla", "AI"],
+ 8: ["Antarctica", "AQ"],
+ 9: ["Antigua And Barbuda", "AG"],
+ 10: ["Argentina", "AR"],
+ 11: ["Armenia", "AM"],
+ 12: ["Aruba", "AW"],
+ 13: ["Australia", "AU"],
+ 14: ["Austria", "AT"],
+ 15: ["Azerbaijan", "AZ"],
+ 16: ["Bahamas", "BS"],
+ 17: ["Bahrain", "BH"],
+ 18: ["Bangladesh", "BD"],
+ 19: ["Barbados", "BB"],
+ 20: ["Belarus", "BY"],
+ 21: ["Belgium", "BE"],
+ 22: ["Belize", "BZ"],
+ 23: ["Benin", "BJ"],
+ 24: ["Bermuda", "BM"],
+ 25: ["Bhutan", "BT"],
+ 26: ["Bolivia", "BO"],
+ 27: ["Bosnia And Herzegowina", "BA"],
+ 28: ["Botswana", "BW"],
+ 29: ["Bouvet Island", "BV"],
+ 30: ["Brazil", "BR"],
+ 31: ["British Indian Ocean Territory", "IO"],
+ 32: ["Brunei", "BN"],
+ 33: ["Bulgaria", "BG"],
+ 34: ["Burkina Faso", "BF"],
+ 35: ["Burundi", "BI"],
+ 36: ["Cambodia", "KH"],
+ 37: ["Cameroon", "CM"],
+ 38: ["Canada", "CA"],
+ 39: ["Cape Verde", "CV"],
+ 40: ["Cayman Islands", "KY"],
+ 41: ["Central African Republic", "CF"],
+ 42: ["Chad", "TD"],
+ 43: ["Chile", "CL"],
+ 44: ["China", "CN"],
+ 45: ["Christmas Island", "CX"],
+ 46: ["Cocos Islands", "CC"],
+ 47: ["Colombia", "CO"],
+ 48: ["Comoros", "KM"],
+ 49: ["Congo Kinshasa", "CD"],
+ 50: ["Congo Brazzaville", "CG"],
+ 51: ["Cook Islands", "CK"],
+ 52: ["Costa Rica", "CR"],
+ 53: ["Ivory Coast", "CI"],
+ 54: ["Croatia", "HR"],
+ 55: ["Cuba", "CU"],
+ 56: ["Cyprus", "CY"],
+ 57: ["Czech Republic", "CZ"],
+ 58: ["Denmark", "DK"],
+ 59: ["Djibouti", "DJ"],
+ 60: ["Dominica", "DM"],
+ 61: ["Dominican Republic", "DO"],
+ 62: ["East Timor", "TL"],
+ 63: ["Ecuador", "EC"],
+ 64: ["Egypt", "EG"],
+ 65: ["El Salvador", "SV"],
+ 66: ["Equatorial Guinea", "GQ"],
+ 67: ["Eritrea", "ER"],
+ 68: ["Estonia", "EE"],
+ 69: ["Ethiopia", "ET"],
+ 70: ["Falkland Islands", "FK"],
+ 71: ["Faroe Islands", "FO"],
+ 72: ["Fiji", "FJ"],
+ 73: ["Finland", "FI"],
+ 74: ["France", "FR"],
+ 75: ["Guernsey", "GG"],
+ 76: ["French Guiana", "GF"],
+ 77: ["French Polynesia", "PF"],
+ 78: ["French Southern Territories", "TF"],
+ 79: ["Gabon", "GA"],
+ 80: ["Gambia", "GM"],
+ 81: ["Georgia", "GE"],
+ 82: ["Germany", "DE"],
+ 83: ["Ghana", "GH"],
+ 84: ["Gibraltar", "GI"],
+ 85: ["Greece", "GR"],
+ 86: ["Greenland", "GL"],
+ 87: ["Grenada", "GD"],
+ 88: ["Guadeloupe", "GP"],
+ 89: ["Guam", "GU"],
+ 90: ["Guatemala", "GT"],
+ 91: ["Guinea", "GN"],
+ 92: ["Guinea Bissau", "GW"],
+ 93: ["Guyana", "GY"],
+ 94: ["Haiti", "HT"],
+ 95: ["Heard And McDonald Islands", "HM"],
+ 96: ["Honduras", "HN"],
+ 97: ["Hong Kong", "HK"],
+ 98: ["Hungary", "HU"],
+ 99: ["Iceland", "IS"],
+ 100: ["India", "IN"],
+ 101: ["Indonesia", "ID"],
+ 102: ["Iran", "IR"],
+ 103: ["Iraq", "IQ"],
+ 104: ["Ireland", "IE"],
+ 105: ["Israel", "IL"],
+ 106: ["Italy", "IT"],
+ 107: ["Jamaica", "JM"],
+ 108: ["Japan", "JP"],
+ 109: ["Jordan", "JO"],
+ 110: ["Kazakhstan", "KZ"],
+ 111: ["Kenya", "KE"],
+ 112: ["Kiribati", "KI"],
+ 113: ["North Korea", "KP"],
+ 114: ["South Korea", "KR"],
+ 115: ["Kuwait", "KW"],
+ 116: ["Kyrgyzstan", "KG"],
+ 117: ["Laos", "LA"],
+ 118: ["Latvia", "LV"],
+ 119: ["Lebanon", "LB"],
+ 120: ["Lesotho", "LS"],
+ 121: ["Liberia", "LR"],
+ 122: ["Libya", "LY"],
+ 123: ["Liechtenstein", "LI"],
+ 124: ["Lithuania", "LT"],
+ 125: ["Luxembourg", "LU"],
+ 126: ["Macau", "MO"],
+ 127: ["Macedonia", "MK"],
+ 128: ["Madagascar", "MG"],
+ 129: ["Malawi", "MW"],
+ 130: ["Malaysia", "MY"],
+ 131: ["Maldives", "MV"],
+ 132: ["Mali", "ML"],
+ 133: ["Malta", "MT"],
+ 134: ["Marshall Islands", "MH"],
+ 135: ["Martinique", "MQ"],
+ 136: ["Mauritania", "MR"],
+ 137: ["Mauritius", "MU"],
+ 138: ["Mayotte", "YT"],
+ 139: ["Mexico", "MX"],
+ 140: ["Micronesia", "FM"],
+ 141: ["Moldova", "MD"],
+ 142: ["Monaco", "MC"],
+ 143: ["Mongolia", "MN"],
+ 144: ["Montserrat", "MS"],
+ 145: ["Morocco", "MA"],
+ 146: ["Mozambique", "MZ"],
+ 147: ["Myanmar", "MM"],
+ 148: ["Namibia", "NA"],
+ 149: ["Nauru", "NR"],
+ 150: ["Nepal", "NP"],
+ 151: ["Netherlands", "NL"],
+ 152: ["Cura Sao", "CW"],
+ 153: ["New Caledonia", "NC"],
+ 154: ["New Zealand", "NZ"],
+ 155: ["Nicaragua", "NI"],
+ 156: ["Niger", "NE"],
+ 157: ["Nigeria", "NG"],
+ 158: ["Niue", "NU"],
+ 159: ["Norfolk Island", "NF"],
+ 160: ["Northern Mariana Islands", "MP"],
+ 161: ["Norway", "NO"],
+ 162: ["Oman", "OM"],
+ 163: ["Pakistan", "PK"],
+ 164: ["Palau", "PW"],
+ 165: ["Palestinian Territories", "PS"],
+ 166: ["Panama", "PA"],
+ 167: ["Papua New Guinea", "PG"],
+ 168: ["Paraguay", "PY"],
+ 169: ["Peru", "PE"],
+ 170: ["Philippines", "PH"],
+ 171: ["Pitcairn", "PN"],
+ 172: ["Poland", "PL"],
+ 173: ["Portugal", "PT"],
+ 174: ["Puerto Rico", "PR"],
+ 175: ["Qatar", "QA"],
+ 176: ["Reunion", "RE"],
+ 177: ["Romania", "RO"],
+ 178: ["Russia", "RU"],
+ 179: ["Rwanda", "RW"],
+ 180: ["Saint Kitts And Nevis", "KN"],
+ 181: ["Saint Lucia", "LC"],
+ 182: ["Saint Vincent And The Grenadines", "VC"],
+ 183: ["Samoa", "WS"],
+ 184: ["San Marino", "SM"],
+ 185: ["Sao Tome And Principe", "ST"],
+ 186: ["Saudi Arabia", "SA"],
+ 187: ["Senegal", "SN"],
+ 188: ["Seychelles", "SC"],
+ 189: ["Sierra Leone", "SL"],
+ 190: ["Singapore", "SG"],
+ 191: ["Slovakia", "SK"],
+ 192: ["Slovenia", "SI"],
+ 193: ["Solomon Islands", "SB"],
+ 194: ["Somalia", "SO"],
+ 195: ["South Africa", "ZA"],
+ 196: ["South Georgia And The South Sandwich Islands", "GS"],
+ 197: ["Spain", "ES"],
+ 198: ["Sri Lanka", "LK"],
+ 199: ["Saint Helena", "SH"],
+ 200: ["Saint Pierre And Miquelon", "PM"],
+ 201: ["Sudan", "SD"],
+ 202: ["Suriname", "SR"],
+ 203: ["Svalbard And Jan Mayen Islands", "SJ"],
+ 204: ["Swaziland", "SZ"],
+ 205: ["Sweden", "SE"],
+ 206: ["Switzerland", "CH"],
+ 207: ["Syria", "SY"],
+ 208: ["Taiwan", "TW"],
+ 209: ["Tajikistan", "TJ"],
+ 210: ["Tanzania", "TZ"],
+ 211: ["Thailand", "TH"],
+ 212: ["Togo", "TG"],
+ 213: ["Tokelau", "TK"],
+ 214: ["Tonga", "TO"],
+ 215: ["Trinidad And Tobago", "TT"],
+ 216: ["Tunisia", "TN"],
+ 217: ["Turkey", "TR"],
+ 218: ["Turkmenistan", "TM"],
+ 219: ["Turks And Caicos Islands", "TC"],
+ 220: ["Tuvalu", "TV"],
+ 221: ["Uganda", "UG"],
+ 222: ["Ukraine", "UA"],
+ 223: ["United Arab Emirates", "AE"],
+ 224: ["United Kingdom", "GB"],
+ 225: ["United States", "US"],
+ 226: ["United States Minor Outlying Islands", "UM"],
+ 227: ["Uruguay", "UY"],
+ 228: ["Uzbekistan", "UZ"],
+ 229: ["Vanuatu", "VU"],
+ 230: ["Vatican City State", "VA"],
+ 231: ["Venezuela", "VE"],
+ 232: ["Vietnam", "VN"],
+ 233: ["British Virgin Islands", "VG"],
+ 234: ["United States Virgin Islands", "VI"],
+ 235: ["Wallis And Futuna Islands", "WF"],
+ 236: ["Western Sahara", "EH"],
+ 237: ["Yemen", "YE"],
+ 238: ["Canary Islands", "IC"],
+ 239: ["Zambia", "ZM"],
+ 240: ["Zimbabwe", "ZW"],
+ 241: ["Clipperton Island", "CP"],
+ 242: ["Montenegro", "ME"],
+ 243: ["Serbia", "RS"],
+ 244: ["Saint Barthelemy", "BL"],
+ 245: ["Saint Martin", "MF"],
+ 246: ["Latin America", "419"],
+ 247: ["Ascension Island", "AC"],
+ 248: ["Aland Islands", "AX"],
+ 249: ["Diego Garcia", "DG"],
+ 250: ["Ceuta And Melilla", "EA"],
+ 251: ["Isle Of Man", "IM"],
+ 252: ["Jersey", "JE"],
+ 253: ["Tristan Da Cunha", "TA"],
+ 254: ["South Sudan", "SS"],
+ 255: ["Bonaire", "BQ"],
+ 256: ["Sint Maarten", "SX"],
+ 257: ["Kosovo", "XK"],
+ 258: ["European Union", "EU"],
+ 259: ["Outlying Oceania", "QO"],
+ 260: ["World", "001"],
+ 261: ["Europe", "150"],
}
country_aliases = {
@@ -698,148 +703,148 @@ country_aliases = {
}
script_list = {
- 0 : ["AnyScript", "Zzzz"],
- 1 : ["Arabic", "Arab"],
- 2 : ["Cyrillic", "Cyrl"],
- 3 : ["Deseret", "Dsrt"],
- 4 : ["Gurmukhi", "Guru"],
- 5 : ["Simplified Han", "Hans"],
- 6 : ["Traditional Han", "Hant"],
- 7 : ["Latin", "Latn"],
- 8 : ["Mongolian", "Mong"],
- 9 : ["Tifinagh", "Tfng"],
- 10 : ["Armenian", "Armn"],
- 11 : ["Bengali", "Beng"],
- 12 : ["Cherokee", "Cher"],
- 13 : ["Devanagari", "Deva"],
- 14 : ["Ethiopic", "Ethi"],
- 15 : ["Georgian", "Geor"],
- 16 : ["Greek", "Grek"],
- 17 : ["Gujarati", "Gujr"],
- 18 : ["Hebrew", "Hebr"],
- 19 : ["Japanese", "Jpan"],
- 20 : ["Khmer", "Khmr"],
- 21 : ["Kannada", "Knda"],
- 22 : ["Korean", "Kore"],
- 23 : ["Lao", "Laoo"],
- 24 : ["Malayalam", "Mlym"],
- 25 : ["Myanmar", "Mymr"],
- 26 : ["Oriya", "Orya"],
- 27 : ["Tamil", "Taml"],
- 28 : ["Telugu", "Telu"],
- 29 : ["Thaana", "Thaa"],
- 30 : ["Thai", "Thai"],
- 31 : ["Tibetan", "Tibt"],
- 32 : ["Sinhala", "Sinh"],
- 33 : ["Syriac", "Syrc"],
- 34 : ["Yi", "Yiii"],
- 35 : ["Vai", "Vaii"],
- 36 : ["Avestan", "Avst"],
- 37 : ["Balinese", "Bali"],
- 38 : ["Bamum", "Bamu"],
- 39 : ["Batak", "Batk"],
- 40 : ["Bopomofo", "Bopo"],
- 41 : ["Brahmi", "Brah"],
- 42 : ["Buginese", "Bugi"],
- 43 : ["Buhid", "Buhd"],
- 44 : ["Canadian Aboriginal", "Cans"],
- 45 : ["Carian", "Cari"],
- 46 : ["Chakma", "Cakm"],
- 47 : ["Cham", "Cham"],
- 48 : ["Coptic", "Copt"],
- 49 : ["Cypriot", "Cprt"],
- 50 : ["Egyptian Hieroglyphs", "Egyp"],
- 51 : ["Fraser", "Lisu"],
- 52 : ["Glagolitic", "Glag"],
- 53 : ["Gothic", "Goth"],
- 54 : ["Han", "Hani"],
- 55 : ["Hangul", "Hang"],
- 56 : ["Hanunoo", "Hano"],
- 57 : ["Imperial Aramaic", "Armi"],
- 58 : ["Inscriptional Pahlavi", "Phli"],
- 59 : ["Inscriptional Parthian", "Prti"],
- 60 : ["Javanese", "Java"],
- 61 : ["Kaithi", "Kthi"],
- 62 : ["Katakana", "Kana"],
- 63 : ["Kayah Li", "Kali"],
- 64 : ["Kharoshthi", "Khar"],
- 65 : ["Lanna", "Lana"],
- 66 : ["Lepcha", "Lepc"],
- 67 : ["Limbu", "Limb"],
- 68 : ["Linear B", "Linb"],
- 69 : ["Lycian", "Lyci"],
- 70 : ["Lydian", "Lydi"],
- 71 : ["Mandaean", "Mand"],
- 72 : ["Meitei Mayek", "Mtei"],
- 73 : ["Meroitic", "Mero"],
- 74 : ["Meroitic Cursive", "Merc"],
- 75 : ["Nko", "Nkoo"],
- 76 : ["New Tai Lue", "Talu"],
- 77 : ["Ogham", "Ogam"],
- 78 : ["Ol Chiki", "Olck"],
- 79 : ["Old Italic", "Ital"],
- 80 : ["Old Persian", "Xpeo"],
- 81 : ["Old South Arabian", "Sarb"],
- 82 : ["Orkhon", "Orkh"],
- 83 : ["Osmanya", "Osma"],
- 84 : ["Phags Pa", "Phag"],
- 85 : ["Phoenician", "Phnx"],
- 86 : ["Pollard Phonetic", "Plrd"],
- 87 : ["Rejang", "Rjng"],
- 88 : ["Runic", "Runr"],
- 89 : ["Samaritan", "Samr"],
- 90 : ["Saurashtra", "Saur"],
- 91 : ["Sharada", "Shrd"],
- 92 : ["Shavian", "Shaw"],
- 93 : ["Sora Sompeng", "Sora"],
- 94 : ["Cuneiform", "Xsux"],
- 95 : ["Sundanese", "Sund"],
- 96 : ["Syloti Nagri", "Sylo"],
- 97 : ["Tagalog", "Tglg"],
- 98 : ["Tagbanwa", "Tagb"],
- 99 : ["Tai Le", "Tale"],
- 100 : ["Tai Viet", "Tavt"],
- 101 : ["Takri", "Takr"],
- 102 : ["Ugaritic", "Ugar"],
- 103 : ["Braille", "Brai"],
- 104 : ["Hiragana", "Hira"],
- 105 : ["Caucasian Albanian", "Aghb"],
- 106 : ["Bassa Vah", "Bass"],
- 107 : ["Duployan", "Dupl"],
- 108 : ["Elbasan", "Elba"],
- 109 : ["Grantha", "Gran"],
- 110 : ["Pahawh Hmong", "Hmng"],
- 111 : ["Khojki", "Khoj"],
- 112 : ["Linear A", "Lina"],
- 113 : ["Mahajani", "Mahj"],
- 114 : ["Manichaean", "Mani"],
- 115 : ["Mende Kikakui", "Mend"],
- 116 : ["Modi", "Modi"],
- 117 : ["Mro", "Mroo"],
- 118 : ["Old North Arabian", "Narb"],
- 119 : ["Nabataean", "Nbat"],
- 120 : ["Palmyrene", "Palm"],
- 121 : ["Pau Cin Hau", "Pauc"],
- 122 : ["Old Permic", "Perm"],
- 123 : ["Psalter Pahlavi", "Phlp"],
- 124 : ["Siddham", "Sidd"],
- 125 : ["Khudawadi", "Sind"],
- 126 : ["Tirhuta", "Tirh"],
- 127 : ["Varang Kshiti", "Wara"],
- 128 : ["Ahom", "Ahom"],
- 129 : ["Anatolian Hieroglyphs", "Hluw"],
- 130 : ["Hatran", "Hatr"],
- 131 : ["Multani", "Mult"],
- 132 : ["Old Hungarian", "Hung"],
- 133 : ["Sign Writing", "Sgnw"],
- 134 : ["Adlam", "Adlm"],
- 135 : ["Bhaiksuki", "Bhks"],
- 136 : ["Marchen", "Marc"],
- 137 : ["Newa", "Newa"],
- 138 : ["Osage", "Osge"],
- 139 : ["Tangut", "Tang"],
- 140 : ["Han with Bopomofo", "Hanb"],
- 141 : ["Jamo", "Jamo"]
+ 0: ["AnyScript", "Zzzz"],
+ 1: ["Arabic", "Arab"],
+ 2: ["Cyrillic", "Cyrl"],
+ 3: ["Deseret", "Dsrt"],
+ 4: ["Gurmukhi", "Guru"],
+ 5: ["Simplified Han", "Hans"],
+ 6: ["Traditional Han", "Hant"],
+ 7: ["Latin", "Latn"],
+ 8: ["Mongolian", "Mong"],
+ 9: ["Tifinagh", "Tfng"],
+ 10: ["Armenian", "Armn"],
+ 11: ["Bengali", "Beng"],
+ 12: ["Cherokee", "Cher"],
+ 13: ["Devanagari", "Deva"],
+ 14: ["Ethiopic", "Ethi"],
+ 15: ["Georgian", "Geor"],
+ 16: ["Greek", "Grek"],
+ 17: ["Gujarati", "Gujr"],
+ 18: ["Hebrew", "Hebr"],
+ 19: ["Japanese", "Jpan"],
+ 20: ["Khmer", "Khmr"],
+ 21: ["Kannada", "Knda"],
+ 22: ["Korean", "Kore"],
+ 23: ["Lao", "Laoo"],
+ 24: ["Malayalam", "Mlym"],
+ 25: ["Myanmar", "Mymr"],
+ 26: ["Oriya", "Orya"],
+ 27: ["Tamil", "Taml"],
+ 28: ["Telugu", "Telu"],
+ 29: ["Thaana", "Thaa"],
+ 30: ["Thai", "Thai"],
+ 31: ["Tibetan", "Tibt"],
+ 32: ["Sinhala", "Sinh"],
+ 33: ["Syriac", "Syrc"],
+ 34: ["Yi", "Yiii"],
+ 35: ["Vai", "Vaii"],
+ 36: ["Avestan", "Avst"],
+ 37: ["Balinese", "Bali"],
+ 38: ["Bamum", "Bamu"],
+ 39: ["Batak", "Batk"],
+ 40: ["Bopomofo", "Bopo"],
+ 41: ["Brahmi", "Brah"],
+ 42: ["Buginese", "Bugi"],
+ 43: ["Buhid", "Buhd"],
+ 44: ["Canadian Aboriginal", "Cans"],
+ 45: ["Carian", "Cari"],
+ 46: ["Chakma", "Cakm"],
+ 47: ["Cham", "Cham"],
+ 48: ["Coptic", "Copt"],
+ 49: ["Cypriot", "Cprt"],
+ 50: ["Egyptian Hieroglyphs", "Egyp"],
+ 51: ["Fraser", "Lisu"],
+ 52: ["Glagolitic", "Glag"],
+ 53: ["Gothic", "Goth"],
+ 54: ["Han", "Hani"],
+ 55: ["Hangul", "Hang"],
+ 56: ["Hanunoo", "Hano"],
+ 57: ["Imperial Aramaic", "Armi"],
+ 58: ["Inscriptional Pahlavi", "Phli"],
+ 59: ["Inscriptional Parthian", "Prti"],
+ 60: ["Javanese", "Java"],
+ 61: ["Kaithi", "Kthi"],
+ 62: ["Katakana", "Kana"],
+ 63: ["Kayah Li", "Kali"],
+ 64: ["Kharoshthi", "Khar"],
+ 65: ["Lanna", "Lana"],
+ 66: ["Lepcha", "Lepc"],
+ 67: ["Limbu", "Limb"],
+ 68: ["Linear B", "Linb"],
+ 69: ["Lycian", "Lyci"],
+ 70: ["Lydian", "Lydi"],
+ 71: ["Mandaean", "Mand"],
+ 72: ["Meitei Mayek", "Mtei"],
+ 73: ["Meroitic", "Mero"],
+ 74: ["Meroitic Cursive", "Merc"],
+ 75: ["Nko", "Nkoo"],
+ 76: ["New Tai Lue", "Talu"],
+ 77: ["Ogham", "Ogam"],
+ 78: ["Ol Chiki", "Olck"],
+ 79: ["Old Italic", "Ital"],
+ 80: ["Old Persian", "Xpeo"],
+ 81: ["Old South Arabian", "Sarb"],
+ 82: ["Orkhon", "Orkh"],
+ 83: ["Osmanya", "Osma"],
+ 84: ["Phags Pa", "Phag"],
+ 85: ["Phoenician", "Phnx"],
+ 86: ["Pollard Phonetic", "Plrd"],
+ 87: ["Rejang", "Rjng"],
+ 88: ["Runic", "Runr"],
+ 89: ["Samaritan", "Samr"],
+ 90: ["Saurashtra", "Saur"],
+ 91: ["Sharada", "Shrd"],
+ 92: ["Shavian", "Shaw"],
+ 93: ["Sora Sompeng", "Sora"],
+ 94: ["Cuneiform", "Xsux"],
+ 95: ["Sundanese", "Sund"],
+ 96: ["Syloti Nagri", "Sylo"],
+ 97: ["Tagalog", "Tglg"],
+ 98: ["Tagbanwa", "Tagb"],
+ 99: ["Tai Le", "Tale"],
+ 100: ["Tai Viet", "Tavt"],
+ 101: ["Takri", "Takr"],
+ 102: ["Ugaritic", "Ugar"],
+ 103: ["Braille", "Brai"],
+ 104: ["Hiragana", "Hira"],
+ 105: ["Caucasian Albanian", "Aghb"],
+ 106: ["Bassa Vah", "Bass"],
+ 107: ["Duployan", "Dupl"],
+ 108: ["Elbasan", "Elba"],
+ 109: ["Grantha", "Gran"],
+ 110: ["Pahawh Hmong", "Hmng"],
+ 111: ["Khojki", "Khoj"],
+ 112: ["Linear A", "Lina"],
+ 113: ["Mahajani", "Mahj"],
+ 114: ["Manichaean", "Mani"],
+ 115: ["Mende Kikakui", "Mend"],
+ 116: ["Modi", "Modi"],
+ 117: ["Mro", "Mroo"],
+ 118: ["Old North Arabian", "Narb"],
+ 119: ["Nabataean", "Nbat"],
+ 120: ["Palmyrene", "Palm"],
+ 121: ["Pau Cin Hau", "Pauc"],
+ 122: ["Old Permic", "Perm"],
+ 123: ["Psalter Pahlavi", "Phlp"],
+ 124: ["Siddham", "Sidd"],
+ 125: ["Khudawadi", "Sind"],
+ 126: ["Tirhuta", "Tirh"],
+ 127: ["Varang Kshiti", "Wara"],
+ 128: ["Ahom", "Ahom"],
+ 129: ["Anatolian Hieroglyphs", "Hluw"],
+ 130: ["Hatran", "Hatr"],
+ 131: ["Multani", "Mult"],
+ 132: ["Old Hungarian", "Hung"],
+ 133: ["Sign Writing", "Sgnw"],
+ 134: ["Adlam", "Adlm"],
+ 135: ["Bhaiksuki", "Bhks"],
+ 136: ["Marchen", "Marc"],
+ 137: ["Newa", "Newa"],
+ 138: ["Osage", "Osge"],
+ 139: ["Tangut", "Tang"],
+ 140: ["Han with Bopomofo", "Hanb"],
+ 141: ["Jamo", "Jamo"],
}
script_aliases = {
diff --git a/util/local_database/xpathlite.py b/util/local_database/xpathlite.py
index a1ed42812d..b3f8325569 100644
--- a/util/local_database/xpathlite.py
+++ b/util/local_database/xpathlite.py
@@ -213,12 +213,8 @@ def _fixedLookupChain(dirname, name):
return items
def _findEntry(base, path, draft=None, attribute=None):
- file = base
if base.endswith(".xml"):
- filename = base
base = base[:-4]
- else:
- file = base + ".xml"
(dirname, filename) = os.path.split(base)
items = _fixedLookupChain(dirname, filename)