summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/sqlite/qt_attribution.json4
-rw-r--r--src/3rdparty/sqlite/sqlite3.c58
-rw-r--r--src/3rdparty/sqlite/sqlite3.h14
-rwxr-xr-xsrc/3rdparty/sqlite/update_sqlite.sh2
-rw-r--r--src/corelib/CMakeLists.txt4
-rw-r--r--src/corelib/compat/removed_api.cpp14
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp16
-rw-r--r--src/corelib/doc/src/jni.qdoc10
-rw-r--r--src/corelib/kernel/qassociativeiterable.cpp14
-rw-r--r--src/corelib/kernel/qassociativeiterable.h51
-rw-r--r--src/corelib/kernel/qiterable.cpp38
-rw-r--r--src/corelib/kernel/qiterable.h12
-rw-r--r--src/corelib/kernel/qjniobject.cpp175
-rw-r--r--src/corelib/kernel/qjniobject.h11
-rw-r--r--src/corelib/kernel/qjnitypes.h3
-rw-r--r--src/corelib/kernel/qmetaassociation.cpp209
-rw-r--r--src/corelib/kernel/qmetaassociation.h273
-rw-r--r--src/corelib/kernel/qmetacontainer.h123
-rw-r--r--src/corelib/kernel/qmetasequence.cpp176
-rw-r--r--src/corelib/kernel/qmetasequence.h308
-rw-r--r--src/corelib/kernel/qmetatype.cpp188
-rw-r--r--src/corelib/kernel/qsequentialiterable.cpp14
-rw-r--r--src/corelib/kernel/qsequentialiterable.h39
-rw-r--r--src/corelib/kernel/qvariant.cpp10
-rw-r--r--src/corelib/kernel/qvariant.h27
-rw-r--r--src/gui/accessible/linux/atspiadaptor.cpp44
-rw-r--r--src/gui/platform/unix/qxkbcommon.cpp6
-rw-r--r--src/gui/text/qfont.cpp69
-rw-r--r--src/gui/text/qfont_p.h2
-rw-r--r--src/gui/text/qtextengine.cpp4
-rw-r--r--src/gui/text/qtextengine_p.h2
-rw-r--r--src/network/access/qhttp2protocolhandler_p.h1
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.cpp1
-rw-r--r--src/plugins/platforms/wasm/qwasmdrag.cpp13
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp267
-rw-r--r--src/plugins/tls/schannel/qtls_schannel.cpp9
-rw-r--r--src/sql/doc/qtsql.qdocconf3
-rw-r--r--src/sql/doc/src/sql-programming.qdoc2
-rw-r--r--src/widgets/CMakeLists.txt8
-rw-r--r--src/widgets/kernel/qtooltip.cpp17
-rw-r--r--src/widgets/styles/images/fusion_normalizedockup-10.png (renamed from src/widgets/styles/images/fusion_normalizedockup_10.png)bin234 -> 234 bytes
-rw-r--r--src/widgets/styles/images/fusion_normalizedockup-20.png (renamed from src/widgets/styles/images/fusion_normalizedockup_20.png)bin342 -> 342 bytes
-rw-r--r--src/widgets/styles/images/fusion_normalizedockup-48.png (renamed from src/widgets/styles/images/fusion_normalizedockup_48.png)bin487 -> 487 bytes
-rw-r--r--src/widgets/styles/images/fusion_normalizedockup-64.png (renamed from src/widgets/styles/images/fusion_normalizedockup_64.png)bin579 -> 579 bytes
44 files changed, 1906 insertions, 335 deletions
diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json
index 2f8bbc30a94..392d7adf0e3 100644
--- a/src/3rdparty/sqlite/qt_attribution.json
+++ b/src/3rdparty/sqlite/qt_attribution.json
@@ -7,10 +7,10 @@
"Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.",
"Homepage": "https://www.sqlite.org/",
- "Version": "3.51.0",
+ "Version": "3.51.1",
"PURL": "pkg:github/sqlite/sqlite@version-$<VERSION>",
"CPE": "cpe:2.3:a:sqlite:sqlite:$<VERSION>:*:*:*:*:*:*:*",
- "DownloadLocation": "https://www.sqlite.org/2025/sqlite-amalgamation-3510000.zip",
+ "DownloadLocation": "https://www.sqlite.org/2025/sqlite-amalgamation-3510100.zip",
"License": "SQLite Blessing",
"LicenseId": "blessing",
"Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed."
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index 03d65b62820..912ac26944c 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.51.0. By combining all the individual C code files into this
+** version 3.51.1. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -18,7 +18,7 @@
** separate file. This file contains only code for the core SQLite library.
**
** The content in this amalgamation comes from Fossil check-in
-** fb2c931ae597f8d00a37574ff67aeed3eced with changes in files:
+** 281fc0e9afc38674b9b0991943b9e9d1e64c with changes in files:
**
**
*/
@@ -467,12 +467,12 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.51.0"
-#define SQLITE_VERSION_NUMBER 3051000
-#define SQLITE_SOURCE_ID "2025-11-04 19:38:17 fb2c931ae597f8d00a37574ff67aeed3eced4e5547f9120744ae4bfa8e74527b"
-#define SQLITE_SCM_BRANCH "trunk"
-#define SQLITE_SCM_TAGS "release major-release version-3.51.0"
-#define SQLITE_SCM_DATETIME "2025-11-04T19:38:17.314Z"
+#define SQLITE_VERSION "3.51.1"
+#define SQLITE_VERSION_NUMBER 3051001
+#define SQLITE_SOURCE_ID "2025-11-28 17:28:25 281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af38a88"
+#define SQLITE_SCM_BRANCH "branch-3.51"
+#define SQLITE_SCM_TAGS "release version-3.51.1"
+#define SQLITE_SCM_DATETIME "2025-11-28T17:28:25.933Z"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -10747,7 +10747,7 @@ SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
** &nbsp; ){
** &nbsp; // do something with pVal
** &nbsp; }
-** &nbsp; if( rc!=SQLITE_OK ){
+** &nbsp; if( rc!=SQLITE_DONE ){
** &nbsp; // an error has occurred
** &nbsp; }
** </pre></blockquote>)^
@@ -38004,6 +38004,7 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){
return 0;
}
+
/************** End of hash.c ************************************************/
/************** Begin file opcodes.c *****************************************/
/* Automatically generated. Do not edit */
@@ -130655,6 +130656,7 @@ SQLITE_PRIVATE void sqlite3SchemaClear(void *p){
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem));
}
+
sqlite3HashClear(&temp2);
sqlite3HashInit(&pSchema->tblHash);
for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
@@ -160976,9 +160978,12 @@ SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
addModuleArgument(pParse, pTab, 0);
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
+ db->nSchemaLock++;
rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
+ db->nSchemaLock--;
if( rc ){
sqlite3ErrorMsg(pParse, "%s", zErr);
+ pParse->rc = rc;
sqlite3DbFree(db, zErr);
sqlite3VtabEponymousTableClear(db, pMod);
}
@@ -174040,8 +174045,22 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
}
#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
- if( pTabList->a[pLevel->iFrom].fg.fromExists ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
+ if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){
+ /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS
+ ** loop(s) will be the inner-most loops of the join. There might be
+ ** multiple EXISTS loops, but they will all be nested, and the join
+ ** order will not have been changed by the query planner. If the
+ ** inner-most EXISTS loop sees a single successful row, it should
+ ** break out of *all* EXISTS loops. But only the inner-most of the
+ ** nested EXISTS loops should do this breakout. */
+ int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */
+ while( nOuter<i ){
+ if( !pTabList->a[pLevel[-nOuter-1].iFrom].fg.fromExists ) break;
+ nOuter++;
+ }
+ testcase( nOuter>0 );
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk);
+ VdbeComment((v, "EXISTS break"));
}
/* The common case: Advance to the next row */
if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
@@ -186225,6 +186244,7 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
/* Clear the TEMP schema separately and last */
if( db->aDb[1].pSchema ){
sqlite3SchemaClear(db->aDb[1].pSchema);
+ assert( db->aDb[1].pSchema->trigHash.count==0 );
}
sqlite3VtabUnlockList(db);
@@ -187553,7 +187573,7 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
*/
SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){
int rc = SQLITE_OK;
- if( !sqlite3SafetyCheckSickOrOk(db) ){
+ if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
@@ -249220,6 +249240,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
while( 1 ){
u64 iDelta = 0;
+ if( i>=n ) break;
if( eDetail==FTS5_DETAIL_NONE ){
/* todo */
if( i<n && a[i]==0 ){
@@ -260283,7 +260304,7 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2025-11-04 19:38:17 fb2c931ae597f8d00a37574ff67aeed3eced4e5547f9120744ae4bfa8e74527b", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2025-11-28 17:28:25 281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af38a88", -1, SQLITE_TRANSIENT);
}
/*
@@ -265104,7 +265125,12 @@ static int fts5VocabOpenMethod(
return rc;
}
+/*
+** Restore cursor pCsr to the state it was in immediately after being
+** created by the xOpen() method.
+*/
static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
+ int nCol = pCsr->pFts5->pConfig->nCol;
pCsr->rowid = 0;
sqlite3Fts5IterClose(pCsr->pIter);
sqlite3Fts5StructureRelease(pCsr->pStruct);
@@ -265114,6 +265140,12 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
pCsr->nLeTerm = -1;
pCsr->zLeTerm = 0;
pCsr->bEof = 0;
+ pCsr->iCol = 0;
+ pCsr->iInstPos = 0;
+ pCsr->iInstOff = 0;
+ pCsr->colUsed = 0;
+ memset(pCsr->aCnt, 0, sizeof(i64)*nCol);
+ memset(pCsr->aDoc, 0, sizeof(i64)*nCol);
}
/*
diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h
index 70a4a1b1a5e..76c567d050a 100644
--- a/src/3rdparty/sqlite/sqlite3.h
+++ b/src/3rdparty/sqlite/sqlite3.h
@@ -146,12 +146,12 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.51.0"
-#define SQLITE_VERSION_NUMBER 3051000
-#define SQLITE_SOURCE_ID "2025-11-04 19:38:17 fb2c931ae597f8d00a37574ff67aeed3eced4e5547f9120744ae4bfa8e74527b"
-#define SQLITE_SCM_BRANCH "trunk"
-#define SQLITE_SCM_TAGS "release major-release version-3.51.0"
-#define SQLITE_SCM_DATETIME "2025-11-04T19:38:17.314Z"
+#define SQLITE_VERSION "3.51.1"
+#define SQLITE_VERSION_NUMBER 3051001
+#define SQLITE_SOURCE_ID "2025-11-28 17:28:25 281fc0e9afc38674b9b0991943b9e9d1e64c6cbdb133d35f6f5c87ff6af38a88"
+#define SQLITE_SCM_BRANCH "branch-3.51"
+#define SQLITE_SCM_TAGS "release version-3.51.1"
+#define SQLITE_SCM_DATETIME "2025-11-28T17:28:25.933Z"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -10426,7 +10426,7 @@ SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
** &nbsp; ){
** &nbsp; // do something with pVal
** &nbsp; }
-** &nbsp; if( rc!=SQLITE_OK ){
+** &nbsp; if( rc!=SQLITE_DONE ){
** &nbsp; // an error has occurred
** &nbsp; }
** </pre></blockquote>)^
diff --git a/src/3rdparty/sqlite/update_sqlite.sh b/src/3rdparty/sqlite/update_sqlite.sh
index 4b8e1869d8c..3f7447dc4e5 100755
--- a/src/3rdparty/sqlite/update_sqlite.sh
+++ b/src/3rdparty/sqlite/update_sqlite.sh
@@ -8,7 +8,7 @@
version_maj=3
version_min=51
-version_patch=0
+version_patch=1
year=2025
version=${version_maj}.${version_min}.${version_patch}
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt
index e12d824cebb..5d3d3024e0b 100644
--- a/src/corelib/CMakeLists.txt
+++ b/src/corelib/CMakeLists.txt
@@ -175,12 +175,12 @@ qt_internal_add_module(Core
kernel/qfunctions_p.h
kernel/qiterable.cpp kernel/qiterable.h kernel/qiterable_impl.h
kernel/qmath.cpp kernel/qmath.h
- kernel/qmetaassociation.cpp
+ kernel/qmetaassociation.cpp kernel/qmetaassociation.h
kernel/qmetacontainer.cpp kernel/qmetacontainer.h
kernel/qmetaobject.cpp kernel/qmetaobject.h kernel/qmetaobject_p.h
kernel/qmetaobject_moc_p.h
kernel/qmetaobjectbuilder.cpp kernel/qmetaobjectbuilder_p.h
- kernel/qmetasequence.cpp
+ kernel/qmetasequence.cpp kernel/qmetasequence.h
kernel/qmetatype.cpp kernel/qmetatype.h kernel/qmetatype_p.h
kernel/qmimedata.cpp kernel/qmimedata.h
kernel/qtmetamacros.h kernel/qtmocconstants.h kernel/qtmochelpers.h
diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp
index 7fe8aeb63b7..63fce94dfac 100644
--- a/src/corelib/compat/removed_api.cpp
+++ b/src/corelib/compat/removed_api.cpp
@@ -1291,13 +1291,6 @@ QByteArray QMetaEnum::valueToKeys(int value) const
#include "qmutex.h"
-#include "qbytearray.h"
-
-QByteArray QByteArray::percentDecoded(char percent) const
-{
- return fromPercentEncoding(*this, percent);
-}
-
#if QT_CONFIG(thread)
void QBasicMutex::destroyInternal(QMutexPrivate *d)
{
@@ -1495,6 +1488,13 @@ bool QObject::doSetProperty(const char *name, const QVariant *lvalue, QVariant *
#if QT_CORE_REMOVED_SINCE(6, 11)
+#include "qbytearray.h"
+
+QByteArray QByteArray::percentDecoded(char percent) const
+{
+ return fromPercentEncoding(*this, percent);
+}
+
#if QT_CONFIG(thread)
// some of the previously inlined API became removed
#include "qreadwritelock.h"
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp
index e23f6c9d103..1d7a3fa6409 100644
--- a/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qvariant.cpp
@@ -7,8 +7,8 @@
#include <QVariant>
#include <QColor>
#include <QPalette>
-#include <QSequentialIterable>
-#include <QAssociativeIterable>
+#include <QMetaSequence>
+#include <QMetaAssociation>
QString tr(const char *s)
{
@@ -125,14 +125,14 @@ QVariant examples()
QVariant variant = QVariant::fromValue(intList);
if (variant.canConvert<QVariantList>()) {
- QSequentialIterable iterable = variant.value<QSequentialIterable>();
+ QMetaSequence::Iterable iterable = variant.value<QMetaSequence::Iterable>();
// Can use C++11 range-for:
for (const QVariant &v : iterable) {
qDebug() << v;
}
// Can use iterators:
- QSequentialIterable::const_iterator it = iterable.begin();
- const QSequentialIterable::const_iterator end = iterable.end();
+ QMetaSequence::Iterable::const_iterator it = iterable.begin();
+ const QMetaSequence::Iterable::const_iterator end = iterable.end();
for ( ; it != end; ++it) {
qDebug() << *it;
}
@@ -149,14 +149,14 @@ QVariant examples()
QVariant variant = QVariant::fromValue(mapping);
if (variant.canConvert<QVariantHash>()) {
- QAssociativeIterable iterable = variant.value<QAssociativeIterable>();
+ QMetaAssociation::Iterable iterable = variant.value<QMetaAssociation::Iterable>();
// Can use C++11 range-for over the values:
for (const QVariant &v : iterable) {
qDebug() << v;
}
// Can use iterators:
- QAssociativeIterable::const_iterator it = iterable.begin();
- const QAssociativeIterable::const_iterator end = iterable.end();
+ QMetaAssociation::Iterable::const_iterator it = iterable.begin();
+ const QMetaAssociation::Iterable::const_iterator end = iterable.end();
for ( ; it != end; ++it) {
qDebug() << *it; // The current value
qDebug() << it.key();
diff --git a/src/corelib/doc/src/jni.qdoc b/src/corelib/doc/src/jni.qdoc
index d05dd44ff60..72b29506c34 100644
--- a/src/corelib/doc/src/jni.qdoc
+++ b/src/corelib/doc/src/jni.qdoc
@@ -65,10 +65,10 @@
\endcode
The C++ classes \c{QtJniTypes::File} and \c{QtJniTypes::FileWriter} are
- then QJniObject-like types that can be used to instantiate the
- corresponding Java class, to call methods, and to pass such instances
- through QJniObject variadic template methods with automatic, compile-time
- signature deduction.
+ then QJniObject-like types (specializations of QtJniTypes::JObject, to be
+ precise) that can be used to instantiate the corresponding Java class, to
+ call methods, and to pass such instances through QJniObject variadic
+ template methods with automatic, compile-time signature deduction.
\code
using namespace QtJniTypes;
@@ -89,7 +89,7 @@
});
\endcode
- \sa Q_DECLARE_JNI_NATIVE_METHOD, Q_JNI_NATIVE_METHOD
+ \sa Q_DECLARE_JNI_NATIVE_METHOD, Q_JNI_NATIVE_METHOD, QtJniTypes::JObject
*/
/*!
diff --git a/src/corelib/kernel/qassociativeiterable.cpp b/src/corelib/kernel/qassociativeiterable.cpp
index 8e3072169dd..7c85ce2c10a 100644
--- a/src/corelib/kernel/qassociativeiterable.cpp
+++ b/src/corelib/kernel/qassociativeiterable.cpp
@@ -7,6 +7,10 @@
QT_BEGIN_NAMESPACE
+#if QT_DEPRECATED_SINCE(6, 13)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+
/*!
\class QAssociativeIterator
\internal
@@ -103,6 +107,7 @@ QVariantConstPointer QAssociativeConstIterator::operator->() const
/*!
\class QAssociativeIterable
+ \deprecated [6.13] Use QMetaAssociation::Iterable instead.
\since 5.2
\inmodule QtCore
\brief The QAssociativeIterable class is an iterable interface for an associative container in a QVariant.
@@ -111,8 +116,6 @@ QVariantConstPointer QAssociativeConstIterator::operator->() const
a QVariant. An instance of QAssociativeIterable can be extracted from a QVariant if it can
be converted to a QVariantHash or QVariantMap or if a custom mutable view has been registered.
- \snippet code/src_corelib_kernel_qvariant.cpp 10
-
The container itself is not copied before iterating over it.
\sa QVariant
@@ -270,20 +273,20 @@ void QAssociativeIterable::setValue(const QVariant &key, const QVariant &mapped)
/*!
\typealias QAssociativeIterable::const_iterator
+ \deprecated [6.13] Use QMetaAssociation::Iterable::ConstIterator instead.
\inmodule QtCore
\brief The QAssociativeIterable::const_iterator allows iteration over a container in a QVariant.
A QAssociativeIterable::const_iterator can only be created by a QAssociativeIterable instance,
and can be used in a way similar to other stl-style iterators.
- \snippet code/src_corelib_kernel_qvariant.cpp 10
-
\sa QAssociativeIterable
*/
/*!
\typealias QAssociativeIterable::iterator
\since 6.0
+ \deprecated [6.13] Use QMetaAssociation::Iterable::Iterator instead.
\inmodule QtCore
\brief The QAssociativeIterable::iterator allows iteration over a container in a QVariant.
@@ -293,4 +296,7 @@ void QAssociativeIterable::setValue(const QVariant &key, const QVariant &mapped)
\sa QAssociativeIterable
*/
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 13)
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qassociativeiterable.h b/src/corelib/kernel/qassociativeiterable.h
index f3963d350ea..02038133fa5 100644
--- a/src/corelib/kernel/qassociativeiterable.h
+++ b/src/corelib/kernel/qassociativeiterable.h
@@ -9,7 +9,13 @@
QT_BEGIN_NAMESPACE
-class Q_CORE_EXPORT QAssociativeIterator : public QIterator<QMetaAssociation>
+#if QT_DEPRECATED_SINCE(6, 13)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+
+class
+QT_DEPRECATED_VERSION_X_6_13("Use QMetaAssociation::Iterable::Iterator instead.")
+QAssociativeIterator : public QIterator<QMetaAssociation>
{
public:
using key_type = QVariant;
@@ -21,14 +27,16 @@ public:
: QIterator(std::move(it))
{}
- QVariant key() const;
- QVariantRef<QAssociativeIterator> value() const;
+ Q_CORE_EXPORT QVariant key() const;
+ Q_CORE_EXPORT QVariantRef<QAssociativeIterator> value() const;
- QVariantRef<QAssociativeIterator> operator*() const;
- QVariantPointer<QAssociativeIterator> operator->() const;
+ Q_CORE_EXPORT QVariantRef<QAssociativeIterator> operator*() const;
+ Q_CORE_EXPORT QVariantPointer<QAssociativeIterator> operator->() const;
};
-class Q_CORE_EXPORT QAssociativeConstIterator : public QConstIterator<QMetaAssociation>
+class
+QT_DEPRECATED_VERSION_X_6_13("Use QMetaAssociation::Iterable::ConstIterator instead.")
+QAssociativeConstIterator : public QConstIterator<QMetaAssociation>
{
public:
using key_type = QVariant;
@@ -40,14 +48,16 @@ public:
: QConstIterator(std::move(it))
{}
- QVariant key() const;
- QVariant value() const;
+ Q_CORE_EXPORT QVariant key() const;
+ Q_CORE_EXPORT QVariant value() const;
- QVariant operator*() const;
- QVariantConstPointer operator->() const;
+ Q_CORE_EXPORT QVariant operator*() const;
+ Q_CORE_EXPORT QVariantConstPointer operator->() const;
};
-class Q_CORE_EXPORT QAssociativeIterable : public QIterable<QMetaAssociation>
+class
+QT_DEPRECATED_VERSION_X_6_13("Use QMetaAssociation::Iterable instead.")
+QAssociativeIterable : public QIterable<QMetaAssociation>
{
public:
using iterator = QTaggedIterator<QAssociativeIterator, void>;
@@ -86,14 +96,12 @@ public:
{
}
- // ### Qt7: Pass QMetaType as value rather than const ref.
QAssociativeIterable(const QMetaAssociation &metaAssociation, const QMetaType &metaType,
void *iterable)
: QIterable(metaAssociation, metaType.alignOf(), iterable)
{
}
- // ### Qt7: Pass QMetaType as value rather than const ref.
QAssociativeIterable(const QMetaAssociation &metaAssociation, const QMetaType &metaType,
const void *iterable)
: QIterable(metaAssociation, metaType.alignOf(), iterable)
@@ -117,16 +125,16 @@ public:
iterator mutableBegin() { return iterator(QIterable::mutableBegin()); }
iterator mutableEnd() { return iterator(QIterable::mutableEnd()); }
- const_iterator find(const QVariant &key) const;
+ Q_CORE_EXPORT const_iterator find(const QVariant &key) const;
const_iterator constFind(const QVariant &key) const { return find(key); }
- iterator mutableFind(const QVariant &key);
+ Q_CORE_EXPORT iterator mutableFind(const QVariant &key);
- bool containsKey(const QVariant &key);
- void insertKey(const QVariant &key);
- void removeKey(const QVariant &key);
+ Q_CORE_EXPORT bool containsKey(const QVariant &key);
+ Q_CORE_EXPORT void insertKey(const QVariant &key);
+ Q_CORE_EXPORT void removeKey(const QVariant &key);
- QVariant value(const QVariant &key) const;
- void setValue(const QVariant &key, const QVariant &mapped);
+ Q_CORE_EXPORT QVariant value(const QVariant &key) const;
+ Q_CORE_EXPORT void setValue(const QVariant &key, const QVariant &mapped);
};
template<>
@@ -168,6 +176,9 @@ Q_DECLARE_TYPEINFO(QAssociativeIterable, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(QAssociativeIterable::iterator, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(QAssociativeIterable::const_iterator, Q_RELOCATABLE_TYPE);
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 13)
+
QT_END_NAMESPACE
#endif // QASSOCIATIVEITERABLE_H
diff --git a/src/corelib/kernel/qiterable.cpp b/src/corelib/kernel/qiterable.cpp
index 976aafd13e5..ca2893e1090 100644
--- a/src/corelib/kernel/qiterable.cpp
+++ b/src/corelib/kernel/qiterable.cpp
@@ -2,9 +2,12 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/qiterable.h>
+#include <QtCore/qloggingcategory.h>
QT_BEGIN_NAMESPACE
+Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg);
+
/*!
\class QBaseIterator
\inmodule QtCore
@@ -119,7 +122,7 @@ QT_BEGIN_NAMESPACE
A QIterator can only be created by a QIterable instance, and can be used
in a way similar to other stl-style iterators. Generally, QIterator should
not be used directly, but through its derived classes provided by
- QSequentialIterable and QAssociativeIterable.
+ QMetaSequence::Iterable and QMetaAssociation::Iterable.
\sa QIterable
*/
@@ -155,7 +158,7 @@ QT_BEGIN_NAMESPACE
next item in the container and returns an iterator to the new current
item.
- Calling this function on QSequentialIterable::constEnd() leads to undefined results.
+ Calling this function on QMetaSequence::Iterable::constEnd() leads to undefined results.
\sa operator--()
*/
@@ -176,7 +179,7 @@ QT_BEGIN_NAMESPACE
The prefix \c{--} operator (\c{--it}) makes the preceding item
current and returns an iterator to the new current item.
- Calling this function on QSequentialIterable::constBegin() leads to undefined results.
+ Calling this function on QMetaSequence::Iterable::constBegin() leads to undefined results.
If the container in the QVariant does not support bi-directional iteration, calling this function
leads to undefined results.
@@ -389,7 +392,7 @@ QT_BEGIN_NAMESPACE
\class QIterable
\inmodule QtCore
\since 6.0
- \brief QIterable is a template class that is the base class for QSequentialIterable and QAssociativeIterable.
+ \brief QIterable is a template class that is the base class for QMetaSequence::Iterable and QMetaAssociation::Iterable.
*/
/*!
@@ -454,7 +457,7 @@ QT_BEGIN_NAMESPACE
/*!
\fn template<class Container> QIterator<Container> QIterable<Container>::mutableEnd()
- Returns a QSequentialIterable::iterator for the end of the container. This
+ Returns a QMetaSequence::Iterable::iterator for the end of the container. This
can be used in stl-style iteration.
\sa mutableBegin(), constEnd()
@@ -464,6 +467,17 @@ QT_BEGIN_NAMESPACE
\fn template<class Container> qsizetype QIterable<Container>::size() const
Returns the number of values in the container.
+
+ \note If the underlying container does not provide a native way to query
+ the size, this method will synthesize the access using iterators.
+ This behavior is deprecated and will be removed in a future version
+ of Qt.
+*/
+
+/*!
+ \fn template<class Container> void QIterable<Container>::clear()
+
+ Clears the container.
*/
/*!
@@ -473,7 +487,7 @@ QT_BEGIN_NAMESPACE
\brief QTaggedIterator is a template class that wraps an iterator and exposes standard iterator traits.
In order to use an iterator any of the standard algorithms, its iterator
- traits need to be known. As QSequentialIterable can work with many different
+ traits need to be known. As QMetaSequence::Iterable can work with many different
kinds of containers, we cannot declare the traits in the iterator classes
themselves. A QTaggedIterator gives you a way to explicitly declare a trait for
a concrete instance of an iterator or QConstIterator.
@@ -512,7 +526,7 @@ QT_BEGIN_NAMESPACE
next item in the container and returns an iterator to the new current
item.
- Calling this function on QSequentialIterable::constEnd() leads to undefined results.
+ Calling this function on QMetaSequence::Iterable::constEnd() leads to undefined results.
\sa operator--()
*/
@@ -533,7 +547,7 @@ QT_BEGIN_NAMESPACE
The prefix \c{--} operator (\c{--it}) makes the preceding item
current and returns an iterator to the new current item.
- Calling this function on QSequentialIterable::constBegin() leads to undefined results.
+ Calling this function on QMetaSequence::Iterable::constBegin() leads to undefined results.
If the container in the QVariant does not support bi-directional iteration, calling this function
leads to undefined results.
@@ -609,4 +623,12 @@ QT_BEGIN_NAMESPACE
\sa operator+(), operator-=(), QIterable::canReverseIterate()
*/
+/*!
+ \internal
+ */
+void QtPrivate::warnSynthesizedAccess(const char *text)
+{
+ qCWarning(lcSynthesizedIterableAccess, "%s", text);
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qiterable.h b/src/corelib/kernel/qiterable.h
index 5e25dd1c0a5..baab2897967 100644
--- a/src/corelib/kernel/qiterable.h
+++ b/src/corelib/kernel/qiterable.h
@@ -64,6 +64,8 @@ namespace QtPrivate {
return m_pointer.tag() == Mutable ? reinterpret_cast<Type *>(m_pointer.data()) : nullptr;
}
};
+
+ Q_CORE_EXPORT void warnSynthesizedAccess(const char *text);
}
template<class Iterator, typename IteratorCategory>
@@ -499,6 +501,11 @@ public:
const void *container = constIterable();
if (m_metaContainer.hasSize())
return m_metaContainer.size(container);
+
+ // ### Qt7: Return -1 here. We shouldn't second-guess the underlying container
+ QtPrivate::warnSynthesizedAccess(
+ "size() called on an iterable without native size accessor. This is slow");
+
if (!m_metaContainer.hasConstIterator())
return -1;
@@ -510,6 +517,11 @@ public:
return size;
}
+ void clear()
+ {
+ m_metaContainer.clear(mutableIterable());
+ }
+
Container metaContainer() const
{
return m_metaContainer;
diff --git a/src/corelib/kernel/qjniobject.cpp b/src/corelib/kernel/qjniobject.cpp
index 59117bd01d4..abef9fdd663 100644
--- a/src/corelib/kernel/qjniobject.cpp
+++ b/src/corelib/kernel/qjniobject.cpp
@@ -1527,4 +1527,179 @@ jobject QJniObject::javaObject() const
return d->m_jobject;
}
+/*!
+ \class QtJniTypes::JObjectBase
+ \brief The JObjectBase in the QtJniTypes namespace is the base of all declared Java types.
+ \inmodule QtCore
+ \internal
+*/
+
+/*!
+ \class QtJniTypes::JObject
+ \inmodule QtCore
+ \brief The JObject template in the QtJniTypes namespace is the base of declared Java types.
+ \since Qt 6.8
+
+ This template gets specialized when using the Q_DECLARE_JNI_CLASS macro. The
+ specialization produces a unique type in the QtJniTypes namespace. This
+ allows the type system to deduce the correct signature in JNI calls when an
+ instance of the specialized type is passed as a parameter.
+
+ Instances can be implicitly converted to and from QJniObject and jobject,
+ and provide the same template API as QJniObject to call methods and access
+ properties. Since instances of JObject know about the Java type they hold,
+ APIs to access static methods or fields do not require the class name as an
+ explicit parameter.
+
+ \sa Q_DECLARE_JNI_CLASS
+*/
+
+/*!
+ \fn template <typename Type> QtJniTypes::JObject<Type>::JObject()
+
+ Default-constructs the JObject instance. This also default-constructs an
+ instance of the represented Java type.
+*/
+
+/*!
+ \fn template <typename Type> QtJniTypes::JObject<Type>::JObject(const QJniObject &other)
+
+ Constructs a JObject instance that holds a reference to the same jobject as \a other.
+*/
+
+/*!
+ \fn template <typename Type> QtJniTypes::JObject<Type>::JObject(jobject other)
+
+ Constructs a JObject instance that holds a reference to \a other.
+*/
+
+/*!
+ \fn template <typename Type> QtJniTypes::JObject<Type>::JObject(QJniObject &&other)
+
+ Move-constructs a JObject instance from \a other.
+*/
+
+/*!
+ \fn template <typename Type> bool QtJniTypes::JObject<Type>::isValid() const
+
+ Returns whether the JObject instance holds a valid reference to a jobject.
+
+ \sa QJniObject::isValid()
+*/
+
+/*!
+ \fn template <typename Type> jclass QtJniTypes::JObject<Type>::objectClass() const
+
+ Returns the Java class that this JObject is an instance of as a jclass.
+
+ \sa className(), QJniObject::objectClass()
+*/
+
+/*!
+ \fn template <typename Type> QString QtJniTypes::JObject<Type>::toString() const
+
+ Returns a QString with a string representation of the Java object.
+
+ \sa QJniObject::toString()
+*/
+
+/*!
+ \fn template <typename Type> QByteArray QtJniTypes::JObject<Type>::className() const
+
+ Returns the name of the Java class that this object is an instance of.
+
+ \sa objectClass(), QJniObject::className()
+*/
+
+/*!
+ \fn template <typename Type> bool QtJniTypes::JObject<Type>::isClassAvailable()
+
+ Returns whether the class that this JObject specialization represents is
+ available.
+
+ \sa QJniObject::isClassAvailable()
+*/
+
+/*!
+ \fn template <typename Type> JObject QtJniTypes::JObject<Type>::fromJObject(jobject object)
+
+ Constructs a JObject instance from \a object and returns that instance.
+*/
+
+/*!
+ \fn template <typename Type> template <typename ...Args> JObject QtJniTypes::JObject<Type>::construct(Args &&...args)
+
+ Constructs a Java object from \a args and returns a JObject instance that
+ holds a reference to that Java object.
+*/
+
+/*!
+ \fn template <typename Type> JObject QtJniTypes::JObject<Type>::fromLocalRef(jobject ref)
+
+ Constructs a JObject that holds a local reference to \a ref, and returns
+ that object.
+*/
+
+/*!
+ \fn template <typename Type> template <typename Ret, typename ...Args> auto QtJniTypes::JObject<Type>::callStaticMethod(const char *methodName, Args &&...args)
+
+ Calls the static method \a methodName with arguments \a args, and returns
+ the result of type \c Ret (unless \c Ret is \c void). If \c Ret is a
+ jobject type, then the returned value will be a QJniObject.
+
+ \sa QJniObject::callStaticMethod()
+*/
+
+/*!
+ \fn template <typename Type> bool QtJniTypes::JObject<Type>::registerNativeMethods(std::initializer_list<JNINativeMethod> methods)
+
+ Registers the Java methods in \a methods with the Java class represented by
+ the JObject specialization, and returns whether the registration was successful.
+
+ \sa QJniEnvironment::registerNativeMethods()
+*/
+
+/*!
+ \fn template <typename Type> template <typename T> auto QtJniTypes::JObject<Type>::getStaticField(const char *field)
+
+ Returns the value of the static field \a field.
+
+ \sa QJniObject::getStaticField()
+*/
+
+/*!
+ \fn template <typename Type> template <typename Ret, typename T> auto QtJniTypes::JObject<Type>::setStaticField(const char *field, T &&value)
+
+ Sets the static field \a field to \a value.
+
+ \sa QJniObject::setStaticField()
+*/
+
+/*!
+ \fn template <typename Type> template <typename Ret, typename ...Args> auto QtJniTypes::JObject<Type>::callMethod(const char *method, Args &&...args) const
+
+ Calls the instance method \a method with arguments \a args, and returns
+ the result of type \c Ret (unless \c Ret is \c void). If \c Ret is a
+ jobject type, then the returned value will be a QJniObject.
+
+ \sa QJniObject::callMethod()
+*/
+
+/*!
+ \fn template <typename Type> template <typename T> auto QtJniTypes::JObject<Type>::getField(const char *field) const
+
+ Returns the value of the instance field \a field.
+
+ \sa QJniObject::getField()
+*/
+
+/*!
+ \fn template <typename Type> template <typename Ret, typename T> auto QtJniTypes::JObject<Type>::setField(const char *field, T &&value)
+
+ Sets the value of the instance field \a field to \a value.
+
+ \sa QJniObject::setField()
+*/
+
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qjniobject.h b/src/corelib/kernel/qjniobject.h
index 06dfc328b4b..c38bf60e051 100644
--- a/src/corelib/kernel/qjniobject.h
+++ b/src/corelib/kernel/qjniobject.h
@@ -812,7 +812,7 @@ inline bool operator!=(const QJniObject &obj1, const QJniObject &obj2)
}
namespace QtJniTypes {
-struct QT_TECH_PREVIEW_API JObjectBase
+struct JObjectBase
{
operator QJniObject() const { return m_object; }
@@ -841,7 +841,7 @@ protected:
};
template<typename Type>
-class QT_TECH_PREVIEW_API JObject : public JObjectBase
+class JObject : public JObjectBase
{
public:
using Class = Type;
@@ -885,6 +885,13 @@ public:
return JObject(QJniObject::fromLocalRef(lref));
}
+#ifdef Q_QDOC // from JObjectBase, which we don't document
+ bool isValid() const;
+ jclass objectClass() const;
+ QString toString() const;
+ template <typename T = jobject> object() const;
+#endif
+
static bool registerNativeMethods(std::initializer_list<JNINativeMethod> methods)
{
QJniEnvironment env;
diff --git a/src/corelib/kernel/qjnitypes.h b/src/corelib/kernel/qjnitypes.h
index 935388311a5..8ee367d188f 100644
--- a/src/corelib/kernel/qjnitypes.h
+++ b/src/corelib/kernel/qjnitypes.h
@@ -19,12 +19,11 @@
QT_BEGIN_NAMESPACE
-// QT_TECH_PREVIEW_API
#define Q_DECLARE_JNI_TYPE_HELPER(Type) \
struct Type##Tag { explicit Type##Tag() = default; }; \
using Type = JObject<Type##Tag>; \
-// QT_TECH_PREVIEW_API
+// internal - Q_DECLARE_JNI_CLASS is the public macro
#define Q_DECLARE_JNI_TYPE(Type, Signature) \
namespace QtJniTypes { \
Q_DECLARE_JNI_TYPE_HELPER(Type) \
diff --git a/src/corelib/kernel/qmetaassociation.cpp b/src/corelib/kernel/qmetaassociation.cpp
index dc239424e6d..7fbb356d9a0 100644
--- a/src/corelib/kernel/qmetaassociation.cpp
+++ b/src/corelib/kernel/qmetaassociation.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#include <QtCore/qmetacontainer.h>
+#include <QtCore/qmetaassociation.h>
#include <QtCore/qmetatype.h>
QT_BEGIN_NAMESPACE
@@ -287,7 +287,6 @@ QMetaType QMetaAssociation::mappedMetaType() const
Returns \c true if the QMetaAssociation \a lhs represents the same container type
as the QMetaAssociation \a rhs, otherwise returns \c false.
*/
-
/*!
\fn bool QMetaAssociation::operator!=(const QMetaAssociation &lhs, const QMetaAssociation &rhs)
@@ -295,5 +294,211 @@ QMetaType QMetaAssociation::mappedMetaType() const
type than the QMetaAssociation \a rhs, otherwise returns \c false.
*/
+/*!
+ \class QMetaAssociation::Iterable
+ \inherits QIterable
+ \since 6.11
+ \inmodule QtCore
+ \brief QMetaAssociation::Iterable is an iterable interface for an associative container in a QVariant.
+
+ This class allows several methods of accessing the elements of an
+ associative container held within a QVariant. An instance of
+ QMetaAssociation::Iterable can be extracted from a QVariant if it can be
+ converted to a QVariantHash or QVariantMap or if a custom mutable view has
+ been registered.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 10
+
+ The container itself is not copied before iterating over it.
+
+ \sa QVariant
+*/
+
+/*!
+ \typealias QMetaAssociation::Iterable::RandomAccessIterator
+ Exposes an iterator using std::random_access_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaAssociation::Iterable::BidirectionalIterator
+ Exposes an iterator using std::bidirectional_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaAssociation::Iterable::ForwardIterator
+ Exposes an iterator using std::forward_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaAssociation::Iterable::InputIterator
+ Exposes an iterator using std::input_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaAssociation::Iterable::RandomAccessConstIterator
+ Exposes a const_iterator using std::random_access_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaAssociation::Iterable::BidirectionalConstIterator
+ Exposes a const_iterator using std::bidirectional_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaAssociation::Iterable::ForwardConstIterator
+ Exposes a const_iterator using std::forward_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaAssociation::Iterable::InputConstIterator
+ Exposes a const_iterator using std::input_iterator_tag.
+*/
+
+/*!
+ \class QMetaAssociation::Iterable::ConstIterator
+ \inherits QConstIterator
+ \since 6.11
+ \inmodule QtCore
+ \brief QMetaAssociation::Iterable::ConstIterator allows iteration over a container in a QVariant.
+
+ A QMetaAssociation::Iterable::ConstIterator can only be created by a
+ QMetaAssociation::Iterable instance, and can be used in a way similar to
+ other stl-style iterators.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 10
+
+ \sa QMetaAssociation::Iterable
+*/
+
+/*!
+ \class QMetaAssociation::Iterable::Iterator
+ \inherits QIterator
+ \since 6.11
+ \inmodule QtCore
+ \brief The QMetaAssociation::Iterable::Iterator allows iteration over a container in a QVariant.
+
+ A QMetaAssociation::Iterable::Iterator can only be created by a
+ QMetaAssociation::Iterable instance, and can be used in a way similar to
+ other stl-style iterators.
+
+ \sa QMetaAssociation::Iterable
+*/
+
+/*!
+ \fn QMetaAssociation::Iterable::ConstIterator QMetaAssociation::Iterable::find(const QVariant &key) const
+ Retrieves a ConstIterator pointing to the element at the given \a key, or
+ the end of the container if that key does not exist. If the \a key isn't
+ convertible to the expected type, the end of the container is returned.
+ */
+
+/*!
+ \fn QMetaAssociation::Iterable::Iterator QMetaAssociation::Iterable::mutableFind(const QVariant &key)
+ Retrieves an iterator pointing to the element at the given \a key, or
+ the end of the container if that key does not exist. If the \a key isn't
+ convertible to the expected type, the end of the container is returned.
+ */
+
+/*!
+ \fn bool QMetaAssociation::Iterable::containsKey(const QVariant &key) const
+ Returns \c true if the container has an entry with the given \a key, or
+ \c false otherwise. If the \a key isn't convertible to the expected type,
+ \c false is returned.
+ */
+
+/*!
+ \fn void QMetaAssociation::Iterable::insertKey(const QVariant &key)
+ Inserts a new entry with the given \a key, or resets the mapped value of
+ any existing entry with the given \a key to the default constructed
+ mapped value. The \a key is coerced to the expected type: If it isn't
+ convertible, a default value is inserted.
+ */
+
+/*!
+ \fn void QMetaAssociation::Iterable::removeKey(const QVariant &key)
+ Removes the entry with the given \a key from the container. The \a key is
+ coerced to the expected type: If it isn't convertible, the default value
+ is removed.
+ */
+
+/*!
+ \fn QVariant QMetaAssociation::Iterable::value(const QVariant &key) const
+ Retrieves the mapped value at the given \a key, or a QVariant of a
+ default-constructed instance of the mapped type, if the key does not
+ exist. If the \a key is not convertible to the key type, the mapped value
+ associated with the default-constructed key is returned.
+ */
+
+/*!
+ \fn void QMetaAssociation::Iterable::setValue(const QVariant &key, const QVariant &mapped)
+ Sets the mapped value associated with \a key to \a mapped, if possible.
+ Inserts a new entry if none exists yet, for the given \a key. If the
+ \a key is not convertible to the key type, the value for the
+ default-constructed key type is overwritten.
+ */
+
+
+/*!
+ \fn QVariant QMetaAssociation::Iterable::Iterator::key() const
+ Returns the key this iterator points to.
+*/
+
+/*!
+ \fn QVariant::Reference<QMetaAssociation::Iterable::Iterator> QMetaAssociation::Iterable::Iterator::value() const
+ Returns the mapped value this iterator points to. If the container does not
+ provide a mapped value (for example a set), returns an invalid
+ QVariant::Reference.
+*/
+
+/*!
+ \fn QVariant::Reference<QMetaAssociation::Iterable::Iterator> QMetaAssociation::Iterable::Iterator::operator*() const
+ Returns the current item, converted to a QVariant::Reference. The resulting
+ QVariant::Reference resolves to the mapped value if there is one, or to the
+ key value if not.
+*/
+
+/*!
+ \fn QVariant::Pointer<QMetaAssociation::Iterable::Iterator> QMetaAssociation::Iterable::Iterator::operator->() const
+ Returns the current item, converted to a QVariant::Pointer. The resulting
+ QVariant::Pointer resolves to the mapped value if there is one, or to the
+ key value if not.
+*/
+
+/*!
+ \fn QVariant::Reference<QMetaAssociation::Iterable::Iterator> QMetaAssociation::Iterable::Iterator::operator[](qsizetype n) const
+ Returns the item offset from the current one by \a n, converted to a
+ QVariant::Reference. The resulting QVariant::Reference resolves to the
+ mapped value if there is one, or to the key value if not.
+*/
+
+/*!
+ \fn QVariant QMetaAssociation::Iterable::ConstIterator::key() const
+ Returns the key this iterator points to.
+*/
+
+/*!
+ \fn QVariant QMetaAssociation::Iterable::ConstIterator::value() const
+ Returns the mapped value this iterator points to, or an invalid QVariant if
+ there is no mapped value.
+*/
+
+/*!
+ \fn QVariant QMetaAssociation::Iterable::ConstIterator::operator*() const
+ Returns the current item, converted to a QVariant. The returned value is the
+ mapped value at the current iterator if there is one, or otherwise the key.
+*/
+
+/*!
+ \fn QVariant::ConstPointer<QMetaAssociation::Iterable::ConstIterator> QMetaAssociation::Iterable::ConstIterator::operator->() const
+ Returns the current item, converted to a QVariant::ConstPointer. The
+ QVariant::ConstPointer will resolve to the mapped value at the current
+ iterator if there is one, or otherwise the key.
+*/
+
+/*!
+ \fn QVariant QMetaAssociation::Iterable::ConstIterator::operator[](qsizetype n) const
+ Returns the item offset from the current one by \a n, converted to a
+ QVariant. The returned value is the mapped value at the current iterator if
+ there is one, or otherwise the key.
+*/
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qmetaassociation.h b/src/corelib/kernel/qmetaassociation.h
new file mode 100644
index 00000000000..d7b3fb65242
--- /dev/null
+++ b/src/corelib/kernel/qmetaassociation.h
@@ -0,0 +1,273 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QMETAASSOCIATION_H
+#define QMETAASSOCIATION_H
+
+#if 0
+#pragma qt_class(QMetaAssociation)
+#endif
+
+#include <QtCore/qiterable.h>
+#include <QtCore/qiterable_impl.h>
+#include <QtCore/qmetacontainer.h>
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtMetaContainerPrivate {
+
+class AssociativeIterator : public QIterator<QMetaAssociation>
+{
+public:
+ using key_type = QVariant;
+ using mapped_type = QVariant;
+ using reference = QVariant::Reference<AssociativeIterator>;
+ using pointer = QVariant::Pointer<AssociativeIterator>;
+
+ static constexpr bool canNoexceptAssignQVariant = false;
+ static constexpr bool canNoexceptConvertToQVariant = false;
+
+ AssociativeIterator(QIterator &&it) : QIterator(std::move(it)) {}
+
+ key_type key() const
+ {
+ const QMetaAssociation meta = metaContainer();
+ return QIterablePrivate::retrieveElement(meta.keyMetaType(), [&](void *dataPtr) {
+ meta.keyAtIterator(constIterator(), dataPtr);
+ });
+ }
+ reference value() const { return operator*(); }
+
+ reference operator*() const { return reference(*this); }
+ pointer operator->() const { return pointer(*this); }
+ reference operator[](qsizetype n) const { return reference(*this + n); }
+};
+
+class AssociativeConstIterator : public QConstIterator<QMetaAssociation>
+{
+public:
+ using key_type = QVariant;
+ using mapped_type = QVariant;
+ using reference = QVariant::ConstReference<AssociativeConstIterator>;
+ using pointer = QVariant::ConstPointer<AssociativeConstIterator>;
+
+ static constexpr bool canNoexceptConvertToQVariant = false;
+
+ AssociativeConstIterator(QConstIterator &&it) : QConstIterator(std::move(it)) {}
+
+ key_type key() const
+ {
+ const QMetaAssociation meta = metaContainer();
+ return QIterablePrivate::retrieveElement(meta.keyMetaType(), [&](void *dataPtr) {
+ meta.keyAtConstIterator(constIterator(), dataPtr);
+ });
+ }
+
+ mapped_type value() const { return operator*(); }
+
+ mapped_type operator*() const;
+ pointer operator->() const { return pointer(*this); }
+ mapped_type operator[](qsizetype n) const;
+};
+
+} // namespace QtMetaContainerPrivate
+
+namespace QtPrivate {
+
+template<typename Referred>
+QVariant associativeIteratorToVariant(const Referred &referred)
+{
+ const auto metaAssociation = referred.metaContainer();
+ const QMetaType metaType(metaAssociation.mappedMetaType());
+ if (metaType.isValid(QT6_CALL_NEW_OVERLOAD)) {
+ return QIterablePrivate::retrieveElement(metaType, [&](void *dataPtr) {
+ metaAssociation.mappedAtConstIterator(referred.constIterator(), dataPtr);
+ });
+ }
+
+ return QIterablePrivate::retrieveElement(metaType, [&](void *dataPtr) {
+ metaAssociation.keyAtConstIterator(referred.constIterator(), dataPtr);
+ });
+}
+
+} // namespace QtPrivate
+
+template<>
+inline QVariant::Reference<QtMetaContainerPrivate::AssociativeIterator>::operator QVariant() const
+{
+ return QtPrivate::associativeIteratorToVariant(m_referred);
+}
+
+template<>
+inline QVariant::Reference<QtMetaContainerPrivate::AssociativeIterator> &
+QVariant::Reference<QtMetaContainerPrivate::AssociativeIterator>::operator=(const QVariant &value)
+{
+ const auto metaAssociation = m_referred.metaContainer();
+ const QMetaType metaType(metaAssociation.mappedMetaType());
+ if (!metaType.isValid(QT6_CALL_NEW_OVERLOAD))
+ return *this;
+
+ QtPrivate::QVariantTypeCoercer coercer;
+ metaAssociation.setMappedAtIterator(
+ m_referred.constIterator(), coercer.coerce(value, metaType));
+ return *this;
+}
+
+template<>
+inline QVariant::ConstReference<QtMetaContainerPrivate::AssociativeConstIterator>::operator QVariant() const
+{
+ return QtPrivate::associativeIteratorToVariant(m_referred);
+}
+
+namespace QtMetaContainerPrivate {
+inline AssociativeConstIterator::mapped_type AssociativeConstIterator::operator*() const
+{
+ return reference(*this);
+}
+
+inline AssociativeConstIterator::mapped_type AssociativeConstIterator::operator[](qsizetype n) const
+{
+ return reference(*this + n);
+}
+
+class Association : public QIterable<QMetaAssociation>
+{
+public:
+ using Iterator
+ = QTaggedIterator<AssociativeIterator, void>;
+ using RandomAccessIterator
+ = QTaggedIterator<AssociativeIterator, std::random_access_iterator_tag>;
+ using BidirectionalIterator
+ = QTaggedIterator<AssociativeIterator, std::bidirectional_iterator_tag>;
+ using ForwardIterator
+ = QTaggedIterator<AssociativeIterator, std::forward_iterator_tag>;
+ using InputIterator
+ = QTaggedIterator<AssociativeIterator, std::input_iterator_tag>;
+
+ using ConstIterator
+ = QTaggedIterator<AssociativeConstIterator, void>;
+ using RandomAccessConstIterator
+ = QTaggedIterator<AssociativeConstIterator, std::random_access_iterator_tag>;
+ using BidirectionalConstIterator
+ = QTaggedIterator<AssociativeConstIterator, std::bidirectional_iterator_tag>;
+ using ForwardConstIterator
+ = QTaggedIterator<AssociativeConstIterator, std::forward_iterator_tag>;
+ using InputConstIterator
+ = QTaggedIterator<AssociativeConstIterator, std::input_iterator_tag>;
+
+ using iterator = Iterator;
+ using const_iterator = ConstIterator;
+
+ template<class T>
+ Association(const T *p) : QIterable(QMetaAssociation::fromContainer<T>(), p) {}
+
+ template<class T>
+ Association(T *p) : QIterable(QMetaAssociation::fromContainer<T>(), p) {}
+
+ Association() : QIterable(QMetaAssociation(), nullptr) {}
+
+ template<typename Pointer>
+ Association(const QMetaAssociation &metaAssociation, Pointer iterable)
+ : QIterable(metaAssociation, iterable)
+ {
+ }
+
+ Association(const QMetaAssociation &metaAssociation, QMetaType metaType, void *iterable)
+ : QIterable(metaAssociation, metaType.alignOf(), iterable)
+ {
+ }
+
+ Association(const QMetaAssociation &metaAssociation, QMetaType metaType, const void *iterable)
+ : QIterable(metaAssociation, metaType.alignOf(), iterable)
+ {
+ }
+
+ Association(QIterable<QMetaAssociation> &&other)
+ : QIterable(std::move(other))
+ {}
+
+ Association &operator=(QIterable<QMetaAssociation> &&other)
+ {
+ QIterable::operator=(std::move(other));
+ return *this;
+ }
+
+ ConstIterator begin() const { return constBegin(); }
+ ConstIterator end() const { return constEnd(); }
+
+ ConstIterator constBegin() const { return ConstIterator(QIterable::constBegin()); }
+ ConstIterator constEnd() const { return ConstIterator(QIterable::constEnd()); }
+
+ Iterator mutableBegin() { return Iterator(QIterable::mutableBegin()); }
+ Iterator mutableEnd() { return Iterator(QIterable::mutableEnd()); }
+
+ ConstIterator find(const QVariant &key) const
+ {
+ const QMetaAssociation meta = metaContainer();
+ QtPrivate::QVariantTypeCoercer coercer;
+ if (const void *keyData = coercer.convert(key, meta.keyMetaType())) {
+ return ConstIterator(QConstIterator<QMetaAssociation>(
+ this, meta.createConstIteratorAtKey(constIterable(), keyData)));
+ }
+ return constEnd();
+ }
+
+ ConstIterator constFind(const QVariant &key) const { return find(key); }
+
+ Iterator mutableFind(const QVariant &key)
+ {
+ const QMetaAssociation meta = metaContainer();
+ QtPrivate::QVariantTypeCoercer coercer;
+ if (const void *keyData = coercer.convert(key, meta.keyMetaType()))
+ return Iterator(QIterator(this, meta.createIteratorAtKey(mutableIterable(), keyData)));
+ return mutableEnd();
+ }
+
+ bool containsKey(const QVariant &key) const
+ {
+ const QMetaAssociation meta = metaContainer();
+ QtPrivate::QVariantTypeCoercer keyCoercer;
+ if (const void *keyData = keyCoercer.convert(key, meta.keyMetaType()))
+ return meta.containsKey(constIterable(), keyData);
+ return false;
+ }
+
+ void insertKey(const QVariant &key)
+ {
+ const QMetaAssociation meta = metaContainer();
+ QtPrivate::QVariantTypeCoercer keyCoercer;
+ meta.insertKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType()));
+ }
+
+ void removeKey(const QVariant &key)
+ {
+ const QMetaAssociation meta = metaContainer();
+ QtPrivate::QVariantTypeCoercer keyCoercer;
+ meta.removeKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType()));
+ }
+
+ QVariant value(const QVariant &key) const
+ {
+ const QMetaAssociation meta = metaContainer();
+ return QIterablePrivate::retrieveElement(meta.mappedMetaType(), [&](void *dataPtr) {
+ QtPrivate::QVariantTypeCoercer coercer;
+ meta.mappedAtKey(constIterable(), coercer.coerce(key, meta.keyMetaType()), dataPtr);
+ });
+ }
+
+ void setValue(const QVariant &key, const QVariant &mapped)
+ {
+ const QMetaAssociation meta = metaContainer();
+ QtPrivate::QVariantTypeCoercer keyCoercer;
+ QtPrivate::QVariantTypeCoercer mappedCoercer;
+ meta.setMappedAtKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType()),
+ mappedCoercer.coerce(mapped, meta.mappedMetaType()));
+ }
+};
+
+} // namespace QtMetaContainerPrivate
+
+QT_END_NAMESPACE
+
+#endif // QMETAASSOCIATION_H
diff --git a/src/corelib/kernel/qmetacontainer.h b/src/corelib/kernel/qmetacontainer.h
index 1bed7f9f7b3..f8e73a8b0a2 100644
--- a/src/corelib/kernel/qmetacontainer.h
+++ b/src/corelib/kernel/qmetacontainer.h
@@ -22,6 +22,11 @@ constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType();
namespace QtMetaContainerPrivate {
+class Sequence;
+class SequentialIterator;
+class Association;
+class AssociativeIterator;
+
enum IteratorCapability : quint8 {
InputCapability = 1 << 0,
ForwardCapability = 1 << 1,
@@ -922,9 +927,67 @@ protected:
const QtMetaContainerPrivate::QMetaContainerInterface *d_ptr = nullptr;
};
+// ### Qt7: Move this to qmetasequence.h, including QtMetaContainerPrivate parts above.
class Q_CORE_EXPORT QMetaSequence : public QMetaContainer
{
public:
+#ifdef Q_QDOC
+ class Iterable : public QIterable<QMetaSequence>
+ {
+ public:
+ class Iterator : public QIterator<QMetaSequence>
+ {
+ public:
+ QVariant::Reference<Iterator> operator*() const;
+ QVariant::Pointer<Iterator> operator->() const;
+ QVariant::Reference<Iterator> operator[](qsizetype n) const;
+ };
+
+ class ConstIterator : public QConstIterator<QMetaSequence>
+ {
+ public:
+ QVariant operator*() const;
+ QVariant::ConstPointer<ConstIterator> operator->() const;
+ QVariant operator[](qsizetype n) const;
+ };
+
+ using RandomAccessIterator = Iterator;
+ using BidirectionalIterator = Iterator;
+ using ForwardIterator = Iterator;
+ using InputIterator = Iterator;
+
+ using RandomAccessConstIterator = ConstIterator;
+ using BidirectionalConstIterator = ConstIterator;
+ using ForwardConstIterator = ConstIterator;
+ using InputConstIterator = ConstIterator;
+
+ ConstIterator begin() const;
+ ConstIterator end() const;
+
+ ConstIterator constBegin() const;
+ ConstIterator constEnd() const;
+
+ Iterator mutableBegin();
+ Iterator mutableEnd();
+
+ QVariant at(qsizetype idx) const;
+ void set(qsizetype idx, const QVariant &value);
+ void append(const QVariant &value);
+ void prepend(const QVariant &value);
+ void removeLast();
+ void removeFirst();
+
+#if QT_DEPRECATED_SINCE(6, 11)
+ enum Position: quint8 { Unspecified, AtBegin, AtEnd };
+ void addValue(const QVariant &value, Position position = Unspecified);
+ void removeValue(Position position = Unspecified);
+ QMetaType valueMetaType() const;
+#endif // QT_DEPRECATED_SINCE(6, 11)
+ };
+#else
+ using Iterable = QtMetaContainerPrivate::Sequence;
+#endif
+
QMetaSequence() = default;
explicit QMetaSequence(const QtMetaContainerPrivate::QMetaSequenceInterface *d) : QMetaContainer(d) {}
@@ -999,9 +1062,69 @@ private:
}
};
+// ### Qt7: Move this to qmetaassociation.h, including QtMetaContainerPrivate parts above.
class Q_CORE_EXPORT QMetaAssociation : public QMetaContainer
{
public:
+#ifdef Q_QDOC
+ class Iterable : public QIterable<QMetaAssociation>
+ {
+ public:
+ class Iterator : public QIterator<QMetaAssociation>
+ {
+ public:
+ QVariant key() const;
+ QVariant value() const;
+
+ QVariant::Reference<Iterator> operator*() const;
+ QVariant::Pointer<Iterator> operator->() const;
+ QVariant::Reference<Iterator> operator[](qsizetype n) const;
+ };
+
+ class ConstIterator : public QConstIterator<QMetaAssociation>
+ {
+ public:
+ QVariant key() const;
+ QVariant value() const;
+
+ QVariant operator*() const;
+ QVariant::ConstPointer<ConstIterator> operator->() const;
+ QVariant operator[](qsizetype n) const;
+ };
+
+ using RandomAccessIterator = Iterator;
+ using BidirectionalIterator = Iterator;
+ using ForwardIterator = Iterator;
+ using InputIterator = Iterator;
+
+ using RandomAccessConstIterator = ConstIterator;
+ using BidirectionalConstIterator = ConstIterator;
+ using ForwardConstIterator = ConstIterator;
+ using InputConstIterator = ConstIterator;
+
+ ConstIterator begin() const;
+ ConstIterator end() const;
+
+ ConstIterator constBegin() const;
+ ConstIterator constEnd() const;
+
+ Iterator mutableBegin();
+ Iterator mutableEnd();
+
+ ConstIterator find(const QVariant &key) const;
+ ConstIterator constFind(const QVariant &key) const;
+ Iterator mutableFind(const QVariant &key);
+
+ bool containsKey(const QVariant &key) const;
+ void insertKey(const QVariant &key);
+ void removeKey(const QVariant &key);
+ QVariant value(const QVariant &key) const;
+ void setValue(const QVariant &key, const QVariant &mapped);
+ };
+#else
+ using Iterable = QtMetaContainerPrivate::Association;
+#endif
+
QMetaAssociation() = default;
explicit QMetaAssociation(const QtMetaContainerPrivate::QMetaAssociationInterface *d) : QMetaContainer(d) {}
diff --git a/src/corelib/kernel/qmetasequence.cpp b/src/corelib/kernel/qmetasequence.cpp
index 1d3f3dfd080..2a3a923d5ca 100644
--- a/src/corelib/kernel/qmetasequence.cpp
+++ b/src/corelib/kernel/qmetasequence.cpp
@@ -1,8 +1,8 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#include "qmetacontainer.h"
-#include "qmetatype.h"
+#include <QtCore/qmetasequence.h>
+#include <QtCore/qmetatype.h>
QT_BEGIN_NAMESPACE
@@ -468,4 +468,176 @@ void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) con
type than the QMetaSequence \a rhs, otherwise returns \c false.
*/
+/*!
+ \class QMetaSequence::Iterable
+ \inherits QIterable
+ \since 6.11
+ \inmodule QtCore
+ \brief The QMetaSequence::Iterable class is an iterable interface for a container in a QVariant.
+
+ This class allows several methods of accessing the values of a container
+ held within a QVariant. An instance of QMetaSequence::Iterable can be
+ extracted from a QVariant if it can be converted to a QVariantList, or if
+ the container it contains is registered using
+ Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE. Most sequential containers found
+ in Qt and some found in the C++ standard library are automatically
+ registered.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 9
+
+ The container itself is not copied before iterating over it.
+
+ \sa QVariant
+*/
+
+/*!
+ \typealias QMetaSequence::Iterable::RandomAccessIterator
+ Exposes an iterator using std::random_access_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaSequence::Iterable::BidirectionalIterator
+ Exposes an iterator using std::bidirectional_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaSequence::Iterable::ForwardIterator
+ Exposes an iterator using std::forward_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaSequence::Iterable::InputIterator
+ Exposes an iterator using std::input_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaSequence::Iterable::RandomAccessConstIterator
+ Exposes a const_iterator using std::random_access_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaSequence::Iterable::BidirectionalConstIterator
+ Exposes a const_iterator using std::bidirectional_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaSequence::Iterable::ForwardConstIterator
+ Exposes a const_iterator using std::forward_iterator_tag.
+*/
+
+/*!
+ \typealias QMetaSequence::Iterable::InputConstIterator
+ Exposes a const_iterator using std::input_iterator_tag.
+*/
+
+/*!
+ \enum QMetaSequence::Iterable::Position
+ \deprecated [6.11] Use append(), prepend(), removeFirst(), or removeLast()
+
+ Specifies the position at which an element shall be added to or removed from
+ the iterable.
+
+ \value AtBegin
+ Add or remove at the beginning of the iterable.
+ \value AtEnd
+ Add or remove at the end of the iterable.
+ \value Unspecified
+ Add or remove at an unspecified position in the iterable.
+ */
+
+/*!
+ \fn void QMetaSequence::Iterable::addValue(const QVariant &value, Position position)
+ \deprecated [6.11] Use append() or prepend()
+ Adds \a value to the container, at \a position, if possible.
+ */
+
+/*!
+ \deprecated [6.11] Use removeFirst() or removeLast()
+ \fn void QMetaSequence::Iterable::removeValue(Position position)
+ Removes a value from the container, at \a position, if possible.
+ */
+
+/*!
+ \deprecated [6.11] Use QMetaSequence::valueMetaType()
+ \fn QMetaType QMetaSequence::Iterable::valueMetaType() const
+ Returns the meta type for values stored in the underlying container.
+ */
+
+/*!
+ \fn QVariant QMetaSequence::Iterable::at(qsizetype idx) const
+ Returns the value at position \a idx in the container.
+
+ \note If the underlying container does not provide a native way to retrieve
+ an element at an index, this method will synthesize the access using
+ iterators. This behavior is deprecated and will be removed in a future
+ version of Qt.
+*/
+
+/*!
+ \fn void QMetaSequence::Iterable::set(qsizetype idx, const QVariant &value)
+ Sets the element at position \a idx in the container to \a value.
+
+ \note If the underlying container does not provide a native way to assign
+ an element at an index, this method will synthesize the assignment
+ using iterators. This behavior is deprecated and will be removed in a
+ future version of Qt.
+*/
+
+/*!
+ \class QMetaSequence::Iterable::ConstIterator
+ \inmodule QtCore
+ \inherits QConstIterator
+ \since 6.11
+ \brief QMetaSequence::Iterable::ConstIterator allows iteration over a container in a QVariant.
+
+ A QMetaSequence::Iterable::ConstIterator can only be created by a
+ QMetaSequence::Iterable instance, and can be used in a way similar to other
+ stl-style iterators.
+
+ \snippet code/src_corelib_kernel_qvariant.cpp 9
+*/
+
+/*!
+ \class QMetaSequence::Iterable::Iterator
+ \inmodule QtCore
+ \inherits QIterator
+ \since 6.11
+ \brief QMetaSequence::Iterable::Iterator allows iteration over a container in a QVariant.
+
+ A QMetaSequence::Iterable::Iterator can only be created by a QMetaSequence::Iterable
+ instance, and can be used in a way similar to other stl-style iterators.
+*/
+
+/*!
+ \fn QVariant::Reference<QMetaSequence::Iterable::Iterator> QMetaSequence::Iterable::Iterator::operator*() const
+ Returns the current item, converted to a QVariant::Reference.
+*/
+
+/*!
+ \fn QVariant::Pointer<QMetaSequence::Iterable::Iterator> QMetaSequence::Iterable::Iterator::operator->() const
+ Returns the current item, converted to a QVariant::Pointer.
+*/
+
+/*!
+ \fn QVariant::Reference<QMetaSequence::Iterable::Iterator> QMetaSequence::Iterable::Iterator::operator[](qsizetype n) const
+ Returns the item offset from the current one by \a n, converted to a
+ QVariant::Reference.
+*/
+
+/*!
+ \fn QVariant QMetaSequence::Iterable::ConstIterator::operator*() const
+ Returns the current item, converted to a QVariant.
+*/
+
+/*!
+ \fn QVariant::ConstPointer<QMetaSequence::Iterable::ConstIterator> QMetaSequence::Iterable::ConstIterator::operator->() const
+ Returns the current item, converted to a QVariant::ConstPointer.
+*/
+
+/*!
+ \fn QVariant QMetaSequence::Iterable::ConstIterator::operator[](qsizetype n) const
+ Returns the item offset from the current one by \a n, converted to a
+ QVariant.
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qmetasequence.h b/src/corelib/kernel/qmetasequence.h
new file mode 100644
index 00000000000..e9505054159
--- /dev/null
+++ b/src/corelib/kernel/qmetasequence.h
@@ -0,0 +1,308 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QMETASEQUENCE_H
+#define QMETASEQUENCE_H
+
+#if 0
+#pragma qt_class(QMetaSequence)
+#endif
+
+#include <QtCore/qiterable.h>
+#include <QtCore/qiterable_impl.h>
+#include <QtCore/qmetacontainer.h>
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtMetaContainerPrivate {
+
+class SequentialIterator : public QIterator<QMetaSequence>
+{
+public:
+ using value_type = QVariant;
+ using reference = QVariant::Reference<SequentialIterator>;
+ using pointer = QVariant::Pointer<SequentialIterator>;
+
+ static constexpr bool canNoexceptAssignQVariant = false;
+ static constexpr bool canNoexceptConvertToQVariant = false;
+
+ SequentialIterator(QIterator &&it) : QIterator(std::move(it)) {}
+
+ reference operator*() const { return reference(*this); }
+ pointer operator->() const { return pointer(*this); }
+ reference operator[](qsizetype n) const { return reference(*this + n); }
+};
+
+class SequentialConstIterator : public QConstIterator<QMetaSequence>
+{
+public:
+ using value_type = QVariant;
+ using reference = QVariant::ConstReference<SequentialConstIterator>;
+ using pointer = QVariant::ConstPointer<SequentialConstIterator>;
+
+ static constexpr bool canNoexceptConvertToQVariant = false;
+
+ SequentialConstIterator(QConstIterator &&it) : QConstIterator(std::move(it)) {}
+
+ value_type operator*() const;
+ pointer operator->() const { return pointer(*this); }
+ value_type operator[](qsizetype n) const;
+};
+
+} // namespace QtMetaContainerPrivate
+
+namespace QtPrivate {
+template<typename Referred>
+QVariant sequentialIteratorToVariant(const Referred &referred)
+{
+ const auto metaSequence = referred.metaContainer();
+ return QIterablePrivate::retrieveElement(metaSequence.valueMetaType(), [&](void *dataPtr) {
+ metaSequence.valueAtConstIterator(referred.constIterator(), dataPtr);
+ });
+}
+} // namespace QtPrivate
+
+template<>
+inline QVariant::Reference<QtMetaContainerPrivate::SequentialIterator>::operator QVariant() const
+{
+ return QtPrivate::sequentialIteratorToVariant(m_referred);
+}
+
+template<>
+inline QVariant::Reference<QtMetaContainerPrivate::SequentialIterator> &
+QVariant::Reference<QtMetaContainerPrivate::SequentialIterator>::operator=(const QVariant &value)
+{
+ QtPrivate::QVariantTypeCoercer coercer;
+ m_referred.metaContainer().setValueAtIterator(
+ m_referred.mutableIterator(),
+ coercer.coerce(value, m_referred.metaContainer().valueMetaType()));
+ return *this;
+}
+
+template<>
+inline QVariant::ConstReference<QtMetaContainerPrivate::SequentialConstIterator>::operator QVariant() const
+{
+ return QtPrivate::sequentialIteratorToVariant(m_referred);
+}
+
+namespace QtMetaContainerPrivate {
+inline SequentialConstIterator::value_type SequentialConstIterator::operator*() const
+{
+ return reference(*this);
+}
+
+inline SequentialConstIterator::value_type SequentialConstIterator::operator[](qsizetype n) const
+{
+ return reference(*this + n);
+}
+
+class Sequence : public QIterable<QMetaSequence>
+{
+public:
+ using Iterator = QTaggedIterator<SequentialIterator, void>;
+ using RandomAccessIterator
+ = QTaggedIterator<SequentialIterator, std::random_access_iterator_tag>;
+ using BidirectionalIterator
+ = QTaggedIterator<SequentialIterator, std::bidirectional_iterator_tag>;
+ using ForwardIterator
+ = QTaggedIterator<SequentialIterator, std::forward_iterator_tag>;
+ using InputIterator
+ = QTaggedIterator<SequentialIterator, std::input_iterator_tag>;
+
+ using ConstIterator
+ = QTaggedIterator<SequentialConstIterator, void>;
+ using RandomAccessConstIterator
+ = QTaggedIterator<SequentialConstIterator, std::random_access_iterator_tag>;
+ using BidirectionalConstIterator
+ = QTaggedIterator<SequentialConstIterator, std::bidirectional_iterator_tag>;
+ using ForwardConstIterator
+ = QTaggedIterator<SequentialConstIterator, std::forward_iterator_tag>;
+ using InputConstIterator
+ = QTaggedIterator<SequentialConstIterator, std::input_iterator_tag>;
+
+ using iterator = Iterator;
+ using const_iterator = ConstIterator;
+
+ template<class T>
+ Sequence(const T *p)
+ : QIterable(QMetaSequence::fromContainer<T>(), p)
+ {
+ Q_UNUSED(m_revision);
+ }
+
+ template<class T>
+ Sequence(T *p)
+ : QIterable(QMetaSequence::fromContainer<T>(), p)
+ {
+ }
+
+ Sequence()
+ : QIterable(QMetaSequence(), nullptr)
+ {
+ }
+
+ template<typename Pointer>
+ Sequence(const QMetaSequence &metaSequence, Pointer iterable)
+ : QIterable(metaSequence, iterable)
+ {
+ }
+
+ Sequence(const QMetaSequence &metaSequence, QMetaType metaType, void *iterable)
+ : QIterable(metaSequence, metaType.alignOf(), iterable)
+ {
+ }
+
+ Sequence(const QMetaSequence &metaSequence, QMetaType metaType, const void *iterable)
+ : QIterable(metaSequence, metaType.alignOf(), iterable)
+ {
+ }
+
+ Sequence(QIterable<QMetaSequence> &&other) : QIterable(std::move(other)) {}
+
+ Sequence &operator=(QIterable<QMetaSequence> &&other)
+ {
+ QIterable::operator=(std::move(other));
+ return *this;
+ }
+
+ ConstIterator begin() const { return constBegin(); }
+ ConstIterator end() const { return constEnd(); }
+
+ ConstIterator constBegin() const { return ConstIterator(QIterable::constBegin()); }
+ ConstIterator constEnd() const { return ConstIterator(QIterable::constEnd()); }
+
+ Iterator mutableBegin() { return Iterator(QIterable::mutableBegin()); }
+ Iterator mutableEnd() { return Iterator(QIterable::mutableEnd()); }
+
+ QVariant at(qsizetype idx) const
+ {
+ const QMetaSequence meta = metaContainer();
+ return QIterablePrivate::retrieveElement(meta.valueMetaType(), [&](void *dataPtr) {
+ if (meta.canGetValueAtIndex()) {
+ meta.valueAtIndex(constIterable(), idx, dataPtr);
+ return;
+ }
+
+ // ### Qt7: Drop this code. We shouldn't second-guess the underlying container
+ QtPrivate::warnSynthesizedAccess(
+ "at() called on an iterable without native indexed accessors. This is slow");
+ void *it = meta.constBegin(m_iterable.constPointer());
+ meta.advanceConstIterator(it, idx);
+ meta.valueAtConstIterator(it, dataPtr);
+ meta.destroyConstIterator(it);
+ });
+ }
+
+ void set(qsizetype idx, const QVariant &value)
+ {
+ const QMetaSequence meta = metaContainer();
+ QtPrivate::QVariantTypeCoercer coercer;
+ const void *dataPtr = coercer.coerce(value, meta.valueMetaType());
+ if (meta.canSetValueAtIndex()) {
+ meta.setValueAtIndex(mutableIterable(), idx, dataPtr);
+ return;
+ }
+
+ // ### Qt7: Drop this code. We shouldn't second-guess the underlying container
+ QtPrivate::warnSynthesizedAccess(
+ "set() called on an iterable without native indexed accessors. This is slow");
+ void *it = meta.begin(m_iterable.mutablePointer());
+ meta.advanceIterator(it, idx);
+ meta.setValueAtIterator(it, dataPtr);
+ meta.destroyIterator(it);
+ }
+
+ void append(const QVariant &value)
+ {
+ const QMetaSequence meta = metaContainer();
+ QtPrivate::QVariantTypeCoercer coercer;
+ meta.addValueAtEnd(mutableIterable(), coercer.coerce(value, meta.valueMetaType()));
+ }
+
+ void prepend(const QVariant &value)
+ {
+ const QMetaSequence meta = metaContainer();
+ QtPrivate::QVariantTypeCoercer coercer;
+ meta.addValueAtBegin(mutableIterable(), coercer.coerce(value, meta.valueMetaType()));
+ }
+
+ void removeLast()
+ {
+ metaContainer().removeValueAtEnd(mutableIterable());
+ }
+
+ void removeFirst()
+ {
+ metaContainer().removeValueAtBegin(mutableIterable());
+ }
+
+#if QT_DEPRECATED_SINCE(6, 11)
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+
+ enum
+ QT_DEPRECATED_VERSION_X_6_11("Use append(), prepend(), removeLast(), or removeFirst() instead.")
+ Position: quint8
+ {
+ Unspecified, AtBegin, AtEnd
+ };
+
+ QT_DEPRECATED_VERSION_X_6_11("Use append() or prepend() instead.")
+ void addValue(const QVariant &value, Position position = Unspecified)
+ {
+ const QMetaSequence meta = metaContainer();
+ QtPrivate::QVariantTypeCoercer coercer;
+ const void *valuePtr = coercer.coerce(value, meta.valueMetaType());
+
+ switch (position) {
+ case AtBegin:
+ if (meta.canAddValueAtBegin())
+ meta.addValueAtBegin(mutableIterable(), valuePtr);
+ break;
+ case AtEnd:
+ if (meta.canAddValueAtEnd())
+ meta.addValueAtEnd(mutableIterable(), valuePtr);
+ break;
+ case Unspecified:
+ if (meta.canAddValue())
+ meta.addValue(mutableIterable(), valuePtr);
+ break;
+ }
+ }
+
+ QT_DEPRECATED_VERSION_X_6_11("Use removeLast() or removeFirst() instead.")
+ void removeValue(Position position = Unspecified)
+ {
+ const QMetaSequence meta = metaContainer();
+
+ switch (position) {
+ case AtBegin:
+ if (meta.canRemoveValueAtBegin())
+ meta.removeValueAtBegin(mutableIterable());
+ break;
+ case AtEnd:
+ if (meta.canRemoveValueAtEnd())
+ meta.removeValueAtEnd(mutableIterable());
+ break;
+ case Unspecified:
+ if (meta.canRemoveValue())
+ meta.removeValue(mutableIterable());
+ break;
+ }
+ }
+
+ QT_DEPRECATED_VERSION_X_6_11("Use QMetaSequence::valueMetaType() instead.")
+ QMetaType valueMetaType() const
+ {
+ return metaContainer().valueMetaType();
+ }
+
+ QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 11)
+};
+} // namespace QtMetaContainerPrivate
+
+QT_END_NAMESPACE
+
+#endif // QMETASEQUENCE_H
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 1850a148d19..565f9182e68 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -43,7 +43,9 @@
# include "qjsonvalue.h"
# include "qline.h"
# include "qloggingcategory.h"
+# include "qmetaassociation.h"
# include "qmetaobject.h"
+# include "qmetasequence.h"
# include "qobject.h"
# include "qpoint.h"
# include "qrect.h"
@@ -2151,25 +2153,28 @@ static bool convertToEnum(QMetaType fromType, const void *from, QMetaType toType
}
}
-static bool convertIterableToVariantList(QMetaType fromType, const void *from, void *to)
+template<typename Iterable>
+bool convertIterableToVariantList(QMetaType fromType, const void *from, void *to)
{
- QSequentialIterable list;
- if (!QMetaType::convert(fromType, from, QMetaType::fromType<QSequentialIterable>(), &list))
+ Iterable list;
+ if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &list))
return false;
QVariantList &l = *static_cast<QVariantList *>(to);
l.clear();
- l.reserve(list.size());
+ if (list.metaContainer().hasSize())
+ l.reserve(list.size());
auto end = list.end();
for (auto it = list.begin(); it != end; ++it)
l << *it;
return true;
}
-static bool convertIterableToVariantMap(QMetaType fromType, const void *from, void *to)
+template<typename Iterable>
+bool convertIterableToVariantMap(QMetaType fromType, const void *from, void *to)
{
- QAssociativeIterable map;
- if (!QMetaType::convert(fromType, from, QMetaType::fromType<QAssociativeIterable>(), &map))
+ Iterable map;
+ if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &map))
return false;
QVariantMap &h = *static_cast<QVariantMap *>(to);
@@ -2180,10 +2185,11 @@ static bool convertIterableToVariantMap(QMetaType fromType, const void *from, vo
return true;
}
-static bool convertIterableToVariantHash(QMetaType fromType, const void *from, void *to)
+template<typename Iterable>
+bool convertIterableToVariantHash(QMetaType fromType, const void *from, void *to)
{
- QAssociativeIterable map;
- if (!QMetaType::convert(fromType, from, QMetaType::fromType<QAssociativeIterable>(), &map))
+ Iterable map;
+ if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &map))
return false;
QVariantHash &h = *static_cast<QVariantHash *>(to);
@@ -2225,33 +2231,34 @@ static bool convertIterableToVariantPair(QMetaType fromType, const void *from, v
return true;
}
+template<typename Iterable>
static bool convertToSequentialIterable(QMetaType fromType, const void *from, void *to)
{
using namespace QtMetaTypePrivate;
const int fromTypeId = fromType.id();
- QSequentialIterable &i = *static_cast<QSequentialIterable *>(to);
+ Iterable &i = *static_cast<Iterable *>(to);
switch (fromTypeId) {
case QMetaType::QVariantList:
- i = QSequentialIterable(reinterpret_cast<const QVariantList *>(from));
+ i = Iterable(reinterpret_cast<const QVariantList *>(from));
return true;
case QMetaType::QStringList:
- i = QSequentialIterable(reinterpret_cast<const QStringList *>(from));
+ i = Iterable(reinterpret_cast<const QStringList *>(from));
return true;
case QMetaType::QByteArrayList:
- i = QSequentialIterable(reinterpret_cast<const QByteArrayList *>(from));
+ i = Iterable(reinterpret_cast<const QByteArrayList *>(from));
return true;
case QMetaType::QString:
- i = QSequentialIterable(reinterpret_cast<const QString *>(from));
+ i = Iterable(reinterpret_cast<const QString *>(from));
return true;
case QMetaType::QByteArray:
- i = QSequentialIterable(reinterpret_cast<const QByteArray *>(from));
+ i = Iterable(reinterpret_cast<const QByteArray *>(from));
return true;
default: {
- QSequentialIterable impl;
+ QIterable<QMetaSequence> j(QMetaSequence(), nullptr);
if (QMetaType::convert(
- fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &impl)) {
- i = std::move(impl);
+ fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
+ i = std::move(j);
return true;
}
}
@@ -2289,27 +2296,28 @@ static bool canImplicitlyViewAsSequentialIterable(QMetaType fromType)
}
}
+template<typename Iterable>
static bool viewAsSequentialIterable(QMetaType fromType, void *from, void *to)
{
using namespace QtMetaTypePrivate;
const int fromTypeId = fromType.id();
- QSequentialIterable &i = *static_cast<QSequentialIterable *>(to);
+ Iterable &i = *static_cast<Iterable *>(to);
switch (fromTypeId) {
case QMetaType::QVariantList:
- i = QSequentialIterable(reinterpret_cast<QVariantList *>(from));
+ i = Iterable(reinterpret_cast<QVariantList *>(from));
return true;
case QMetaType::QStringList:
- i = QSequentialIterable(reinterpret_cast<QStringList *>(from));
+ i = Iterable(reinterpret_cast<QStringList *>(from));
return true;
case QMetaType::QByteArrayList:
- i = QSequentialIterable(reinterpret_cast<QByteArrayList *>(from));
+ i = Iterable(reinterpret_cast<QByteArrayList *>(from));
return true;
case QMetaType::QString:
- i = QSequentialIterable(reinterpret_cast<QString *>(from));
+ i = Iterable(reinterpret_cast<QString *>(from));
return true;
case QMetaType::QByteArray:
- i = QSequentialIterable(reinterpret_cast<QByteArray *>(from));
+ i = Iterable(reinterpret_cast<QByteArray *>(from));
return true;
default: {
QIterable<QMetaSequence> j(QMetaSequence(), nullptr);
@@ -2324,24 +2332,25 @@ static bool viewAsSequentialIterable(QMetaType fromType, void *from, void *to)
return false;
}
+template<typename Iterable>
static bool convertToAssociativeIterable(QMetaType fromType, const void *from, void *to)
{
using namespace QtMetaTypePrivate;
- QAssociativeIterable &i = *static_cast<QAssociativeIterable *>(to);
+ Iterable &i = *static_cast<Iterable *>(to);
if (fromType.id() == QMetaType::QVariantMap) {
- i = QAssociativeIterable(reinterpret_cast<const QVariantMap *>(from));
+ i = Iterable(reinterpret_cast<const QVariantMap *>(from));
return true;
}
if (fromType.id() == QMetaType::QVariantHash) {
- i = QAssociativeIterable(reinterpret_cast<const QVariantHash *>(from));
+ i = Iterable(reinterpret_cast<const QVariantHash *>(from));
return true;
}
- QAssociativeIterable impl;
+ QIterable<QMetaAssociation> j(QMetaAssociation(), nullptr);
if (QMetaType::convert(
- fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &impl)) {
- i = std::move(impl);
+ fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
+ i = std::move(j);
return true;
}
@@ -2384,18 +2393,19 @@ static bool canImplicitlyViewAsAssociativeIterable(QMetaType fromType)
}
}
+template<typename Iterable>
static bool viewAsAssociativeIterable(QMetaType fromType, void *from, void *to)
{
using namespace QtMetaTypePrivate;
int fromTypeId = fromType.id();
- QAssociativeIterable &i = *static_cast<QAssociativeIterable *>(to);
+ Iterable &i = *static_cast<Iterable *>(to);
if (fromTypeId == QMetaType::QVariantMap) {
- i = QAssociativeIterable(reinterpret_cast<QVariantMap *>(from));
+ i = Iterable(reinterpret_cast<QVariantMap *>(from));
return true;
}
if (fromTypeId == QMetaType::QVariantHash) {
- i = QAssociativeIterable(reinterpret_cast<QVariantHash *>(from));
+ i = Iterable(reinterpret_cast<QVariantHash *>(from));
return true;
}
@@ -2493,20 +2503,54 @@ bool QMetaType::convert(QMetaType fromType, const void *from, QMetaType toType,
return true;
// handle iterables
- if (toTypeId == QVariantList && convertIterableToVariantList(fromType, from, to))
+ if (toTypeId == QVariantList
+ && convertIterableToVariantList<QMetaSequence::Iterable>(fromType, from, to)) {
return true;
+ }
- if (toTypeId == QVariantMap && convertIterableToVariantMap(fromType, from, to))
+ if (toTypeId == QVariantMap
+ && convertIterableToVariantMap<QMetaAssociation::Iterable>(fromType, from, to)) {
return true;
+ }
- if (toTypeId == QVariantHash && convertIterableToVariantHash(fromType, from, to))
+ if (toTypeId == QVariantHash
+ && convertIterableToVariantHash<QMetaAssociation::Iterable>(fromType, from, to)) {
return true;
+ }
+
+ if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
+ return convertToSequentialIterable<QMetaSequence::Iterable>(fromType, from, to);
+
+ if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
+ return convertToAssociativeIterable<QMetaAssociation::Iterable>(fromType, from, to);
+
+#if QT_DEPRECATED_SINCE(6, 13)
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+
+ if (toTypeId == QVariantList
+ && convertIterableToVariantList<QSequentialIterable>(fromType, from, to)) {
+ return true;
+ }
+
+ if (toTypeId == QVariantMap
+ && convertIterableToVariantMap<QAssociativeIterable>(fromType, from, to)) {
+ return true;
+ }
+
+ if (toTypeId == QVariantHash
+ && convertIterableToVariantHash<QAssociativeIterable>(fromType, from, to)) {
+ return true;
+ }
if (toTypeId == qMetaTypeId<QSequentialIterable>())
- return convertToSequentialIterable(fromType, from, to);
+ return convertToSequentialIterable<QSequentialIterable>(fromType, from, to);
if (toTypeId == qMetaTypeId<QAssociativeIterable>())
- return convertToAssociativeIterable(fromType, from, to);
+ return convertToAssociativeIterable<QAssociativeIterable>(fromType, from, to);
+
+ QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 13)
return convertMetaObject(fromType, from, toType, to);
}
@@ -2528,11 +2572,24 @@ bool QMetaType::view(QMetaType fromType, void *from, QMetaType toType, void *to)
if (f)
return (*f)(from, to);
+ if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
+ return viewAsSequentialIterable<QMetaSequence::Iterable>(fromType, from, to);
+
+ if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
+ return viewAsAssociativeIterable<QMetaAssociation::Iterable>(fromType, from, to);
+
+#if QT_DEPRECATED_SINCE(6, 13)
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+
if (toTypeId == qMetaTypeId<QSequentialIterable>())
- return viewAsSequentialIterable(fromType, from, to);
+ return viewAsSequentialIterable<QSequentialIterable>(fromType, from, to);
if (toTypeId == qMetaTypeId<QAssociativeIterable>())
- return viewAsAssociativeIterable(fromType, from, to);
+ return viewAsAssociativeIterable<QAssociativeIterable>(fromType, from, to);
+
+ QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 13)
return convertMetaObject(fromType, from, toType, to);
}
@@ -2545,14 +2602,14 @@ bool QMetaType::view(QMetaType fromType, void *from, QMetaType toType, void *to)
function if a qobject_cast from the type described by \a fromType to the type described
by \a toType would succeed.
- You can create a mutable view of type QSequentialIterable on any container registered with
+ You can create a mutable view of type QMetaSequence::Iterable on any container registered with
Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE().
- Similarly you can create a mutable view of type QAssociativeIterable on any container
+ Similarly you can create a mutable view of type QMetaAssociation::Iterable on any container
registered with Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE().
- \sa convert(), QSequentialIterable, Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(),
- QAssociativeIterable, Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE()
+ \sa convert(), QMetaSequence::Iterable, Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(),
+ QMetaAssociation::Iterable, Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE()
*/
bool QMetaType::canView(QMetaType fromType, QMetaType toType)
{
@@ -2566,12 +2623,25 @@ bool QMetaType::canView(QMetaType fromType, QMetaType toType)
if (f)
return true;
+ if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
+ return canImplicitlyViewAsSequentialIterable(fromType);
+
+ if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
+ return canImplicitlyViewAsAssociativeIterable(fromType);
+
+#if QT_DEPRECATED_SINCE(6, 13)
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+
if (toTypeId == qMetaTypeId<QSequentialIterable>())
return canImplicitlyViewAsSequentialIterable(fromType);
if (toTypeId == qMetaTypeId<QAssociativeIterable>())
return canImplicitlyViewAsAssociativeIterable(fromType);
+ QT_WARNING_POP
+#endif
+
if (canConvertMetaObject(fromType, toType))
return true;
@@ -2660,8 +2730,8 @@ bool QMetaType::canView(QMetaType fromType, QMetaType toType)
Similarly, a cast from an associative container will also return true for this
function the \a toType is QVariantHash or QVariantMap.
- \sa convert(), QSequentialIterable, Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(), QAssociativeIterable,
- Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE()
+ \sa convert(), QMetaSequence::Iterable, Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(),
+ QMetaAssociation::Iterable, Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE()
*/
bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
{
@@ -2682,11 +2752,32 @@ bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
if (f)
return true;
+ if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
+ return canConvertToSequentialIterable(fromType);
+
+ if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
+ return canConvertToAssociativeIterable(fromType);
+
+ if (toTypeId == QVariantList
+ && canConvert(fromType, QMetaType::fromType<QMetaSequence::Iterable>())) {
+ return true;
+ }
+
+ if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
+ && canConvert(fromType, QMetaType::fromType<QMetaAssociation::Iterable>())) {
+ return true;
+ }
+
+#if QT_DEPRECATED_SINCE(6, 13)
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+
if (toTypeId == qMetaTypeId<QSequentialIterable>())
return canConvertToSequentialIterable(fromType);
if (toTypeId == qMetaTypeId<QAssociativeIterable>())
return canConvertToAssociativeIterable(fromType);
+
if (toTypeId == QVariantList
&& canConvert(fromType, QMetaType::fromType<QSequentialIterable>())) {
return true;
@@ -2697,6 +2788,9 @@ bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
return true;
}
+ QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 13)
+
if (toTypeId == QVariantPair && hasRegisteredConverterFunction(
fromType, QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>()))
return true;
diff --git a/src/corelib/kernel/qsequentialiterable.cpp b/src/corelib/kernel/qsequentialiterable.cpp
index 32c58266045..5b040404654 100644
--- a/src/corelib/kernel/qsequentialiterable.cpp
+++ b/src/corelib/kernel/qsequentialiterable.cpp
@@ -7,8 +7,13 @@
QT_BEGIN_NAMESPACE
+#if QT_DEPRECATED_SINCE(6, 13)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+
/*!
\class QSequentialIterable
+ \deprecated [6.13] Use QMetaSequence::Iterable instead.
\since 5.2
\inmodule QtCore
\brief The QSequentialIterable class is an iterable interface for a container in a QVariant.
@@ -17,8 +22,6 @@ QT_BEGIN_NAMESPACE
a QVariant. An instance of QSequentialIterable can be extracted from a QVariant if it can
be converted to a QVariantList.
- \snippet code/src_corelib_kernel_qvariant.cpp 9
-
The container itself is not copied before iterating over it.
\sa QVariant
@@ -160,17 +163,17 @@ void QSequentialIterable::set(qsizetype idx, const QVariant &value)
/*!
\typealias QSequentialIterable::const_iterator
+ \deprecated [6.13] Use QMetaSequence::Iterable::ConstIterator instead.
\brief The QSequentialIterable::const_iterator allows iteration over a container in a QVariant.
A QSequentialIterable::const_iterator can only be created by a QSequentialIterable instance,
and can be used in a way similar to other stl-style iterators.
-
- \snippet code/src_corelib_kernel_qvariant.cpp 9
*/
/*!
\typealias QSequentialIterable::iterator
\since 6.0
+ \deprecated [6.13] Use QMetaSequence::Iterable::Iterator instead.
\brief The QSequentialIterable::iterator allows iteration over a container in a QVariant.
A QSequentialIterable::iterator can only be created by a QSequentialIterable instance,
@@ -221,4 +224,7 @@ QVariantConstPointer QSequentialConstIterator::operator->() const
return QVariantConstPointer(operator*());
}
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 13)
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qsequentialiterable.h b/src/corelib/kernel/qsequentialiterable.h
index dac146d2ad3..738bebf3631 100644
--- a/src/corelib/kernel/qsequentialiterable.h
+++ b/src/corelib/kernel/qsequentialiterable.h
@@ -9,7 +9,13 @@
QT_BEGIN_NAMESPACE
-class Q_CORE_EXPORT QSequentialIterator : public QIterator<QMetaSequence>
+#if QT_DEPRECATED_SINCE(6, 13)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+
+class
+QT_DEPRECATED_VERSION_X_6_13("Use QMetaSequence::Iterable::Iterator instead.")
+QSequentialIterator : public QIterator<QMetaSequence>
{
public:
using value_type = QVariant;
@@ -20,11 +26,13 @@ public:
: QIterator(std::move(it))
{}
- QVariantRef<QSequentialIterator> operator*() const;
- QVariantPointer<QSequentialIterator> operator->() const;
+ Q_CORE_EXPORT QVariantRef<QSequentialIterator> operator*() const;
+ Q_CORE_EXPORT QVariantPointer<QSequentialIterator> operator->() const;
};
-class Q_CORE_EXPORT QSequentialConstIterator : public QConstIterator<QMetaSequence>
+class
+QT_DEPRECATED_VERSION_X_6_13("Use QMetaSequence::Iterable::ConstIterator instead.")
+QSequentialConstIterator : public QConstIterator<QMetaSequence>
{
public:
using value_type = QVariant;
@@ -35,11 +43,13 @@ public:
: QConstIterator(std::move(it))
{}
- QVariant operator*() const;
- QVariantConstPointer operator->() const;
+ Q_CORE_EXPORT QVariant operator*() const;
+ Q_CORE_EXPORT QVariantConstPointer operator->() const;
};
-class Q_CORE_EXPORT QSequentialIterable : public QIterable<QMetaSequence>
+class
+QT_DEPRECATED_VERSION_X_6_13("Use QMetaSequence::Iterable instead.")
+QSequentialIterable : public QIterable<QMetaSequence>
{
public:
using iterator = QTaggedIterator<QSequentialIterator, void>;
@@ -79,14 +89,12 @@ public:
{
}
- // ### Qt7: Pass QMetaType as value rather than const ref.
QSequentialIterable(const QMetaSequence &metaSequence, const QMetaType &metaType,
void *iterable)
: QIterable(metaSequence, metaType.alignOf(), iterable)
{
}
- // ### Qt7: Pass QMetaType as value rather than const ref.
QSequentialIterable(const QMetaSequence &metaSequence, const QMetaType &metaType,
const void *iterable)
: QIterable(metaSequence, metaType.alignOf(), iterable)
@@ -110,14 +118,14 @@ public:
iterator mutableBegin() { return iterator(QIterable::mutableBegin()); }
iterator mutableEnd() { return iterator(QIterable::mutableEnd()); }
- QVariant at(qsizetype idx) const;
- void set(qsizetype idx, const QVariant &value);
+ Q_CORE_EXPORT QVariant at(qsizetype idx) const;
+ Q_CORE_EXPORT void set(qsizetype idx, const QVariant &value);
enum Position { Unspecified, AtBegin, AtEnd };
- void addValue(const QVariant &value, Position position = Unspecified);
- void removeValue(Position position = Unspecified);
+ Q_CORE_EXPORT void addValue(const QVariant &value, Position position = Unspecified);
+ Q_CORE_EXPORT void removeValue(Position position = Unspecified);
- QMetaType valueMetaType() const;
+ Q_CORE_EXPORT QMetaType valueMetaType() const;
};
template<>
@@ -150,6 +158,9 @@ Q_DECLARE_TYPEINFO(QSequentialIterable, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(QSequentialIterable::iterator, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(QSequentialIterable::const_iterator, Q_RELOCATABLE_TYPE);
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 13)
+
QT_END_NAMESPACE
#endif // QSEQUENTIALITERABLE_H
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 57089f164b2..d2b2aa1cebb 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -2852,9 +2852,14 @@ const void *QtPrivate::QVariantTypeCoercer::coerce(const QVariant &value, const
return converted.constData();
}
+#if QT_DEPRECATED_SINCE(6, 13)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+
/*!
\class QVariantRef
\since 6.0
+ \deprecated [6.13] Use QVariant::Reference instead.
\inmodule QtCore
\brief The QVariantRef acts as a non-const reference to a QVariant.
@@ -2909,6 +2914,7 @@ const void *QtPrivate::QVariantTypeCoercer::coerce(const QVariant &value, const
/*!
\class QVariantConstPointer
\since 6.0
+ \deprecated [6.13] Use QVariant::ConstPointer instead.
\inmodule QtCore
\brief Emulated const pointer to QVariant based on a pointer.
@@ -2946,6 +2952,7 @@ const QVariant *QVariantConstPointer::operator->() const
/*!
\class QVariantPointer
\since 6.0
+ \deprecated [6.13] Use QVariant::Pointer instead.
\inmodule QtCore
\brief QVariantPointer is a template class that emulates a pointer to QVariant based on a pointer.
@@ -2974,6 +2981,9 @@ const QVariant *QVariantConstPointer::operator->() const
implement operator->().
*/
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 13)
+
/*!
\class QVariant::ConstReference
\since 6.11
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 9117c827afe..47fb34cbe65 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -983,8 +983,13 @@ private:
};
}
-template<typename Pointer>
-class QVariantRef
+#if QT_DEPRECATED_SINCE(6, 13)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+
+template<typename Pointer> class
+QT_DEPRECATED_VERSION_X_6_13("Use QVariant::Reference instead.")
+QVariantRef
{
private:
const Pointer *m_pointer = nullptr;
@@ -1008,20 +1013,23 @@ public:
}
};
-class Q_CORE_EXPORT QVariantConstPointer
+class
+QT_DEPRECATED_VERSION_X_6_13("Use QVariant::ConstPointer instead.")
+QVariantConstPointer
{
private:
QVariant m_variant;
public:
- explicit QVariantConstPointer(QVariant variant);
+ Q_CORE_EXPORT explicit QVariantConstPointer(QVariant variant);
- QVariant operator*() const;
- const QVariant *operator->() const;
+ Q_CORE_EXPORT QVariant operator*() const;
+ Q_CORE_EXPORT const QVariant *operator->() const;
};
-template<typename Pointer>
-class QVariantPointer
+template<typename Pointer> class
+QT_DEPRECATED_VERSION_X_6_13("Use QVariant::Pointer instead.")
+QVariantPointer
{
private:
const Pointer *m_pointer = nullptr;
@@ -1032,6 +1040,9 @@ public:
Pointer operator->() const { return *m_pointer; }
};
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 13)
+
QT_END_NAMESPACE
#endif // QVARIANT_H
diff --git a/src/gui/accessible/linux/atspiadaptor.cpp b/src/gui/accessible/linux/atspiadaptor.cpp
index dad0ac2b74a..dae83437b89 100644
--- a/src/gui/accessible/linux/atspiadaptor.cpp
+++ b/src/gui/accessible/linux/atspiadaptor.cpp
@@ -132,7 +132,7 @@ AtSpiAdaptor::~AtSpiAdaptor()
*/
QString AtSpiAdaptor::introspect(const QString &path) const
{
- static const QLatin1StringView accessibleIntrospection(
+ constexpr auto accessibleIntrospection =
" <interface name=\"org.a11y.atspi.Accessible\">\n"
" <property access=\"read\" type=\"s\" name=\"Name\"/>\n"
" <property access=\"read\" type=\"s\" name=\"Description\"/>\n"
@@ -182,9 +182,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"s\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView actionIntrospection(
+ constexpr auto actionIntrospection =
" <interface name=\"org.a11y.atspi.Action\">\n"
" <property access=\"read\" type=\"i\" name=\"NActions\"/>\n"
" <method name=\"GetDescription\">\n"
@@ -208,9 +208,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView applicationIntrospection(
+ constexpr auto applicationIntrospection =
" <interface name=\"org.a11y.atspi.Application\">\n"
" <property access=\"read\" type=\"s\" name=\"ToolkitName\"/>\n"
" <property access=\"read\" type=\"s\" name=\"Version\"/>\n"
@@ -223,9 +223,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"s\" name=\"address\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView collectionIntrospection(
+ constexpr auto collectionIntrospection =
" <interface name=\"org.a11y.atspi.Collection\">\n"
" <method name=\"GetMatches\">\n"
" <arg direction=\"in\" name=\"rule\" type=\"(aiia{ss}iaiiasib)\"/>\n"
@@ -266,9 +266,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"QSpiReferenceSet\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView componentIntrospection(
+ constexpr auto componentIntrospection =
" <interface name=\"org.a11y.atspi.Component\">\n"
" <method name=\"Contains\">\n"
" <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
@@ -329,9 +329,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView editableTextIntrospection(
+ constexpr auto editableTextIntrospection =
" <interface name=\"org.a11y.atspi.EditableText\">\n"
" <method name=\"SetTextContents\">\n"
" <arg direction=\"in\" type=\"s\" name=\"newContents\"/>\n"
@@ -362,9 +362,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView selectionIntrospection(
+ constexpr auto selectionIntrospection =
" <interface name=\"org.a11y.atspi.Selection\">\n"
" <property name=\"NSelectedChildren\" type=\"i\" access=\"read\"/>\n"
" <method name=\"GetSelectedChild\">\n"
@@ -395,9 +395,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView tableIntrospection(
+ constexpr auto tableIntrospection =
" <interface name=\"org.a11y.atspi.Table\">\n"
" <property access=\"read\" type=\"i\" name=\"NRows\"/>\n"
" <property access=\"read\" type=\"i\" name=\"NColumns\"/>\n"
@@ -503,9 +503,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\" name=\"is_selected\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView tableCellIntrospection(
+ constexpr auto tableCellIntrospection =
" <interface name=\"org.a11y.atspi.TableCell\">\n"
" <property access=\"read\" name=\"ColumnSpan\" type=\"i\" />\n"
" <property access=\"read\" name=\"Position\" type=\"(ii)\">\n"
@@ -531,9 +531,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <annotation value=\"QSpiObjectReferenceArray\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView textIntrospection(
+ constexpr auto textIntrospection =
" <interface name=\"org.a11y.atspi.Text\">\n"
" <property access=\"read\" type=\"i\" name=\"CharacterCount\"/>\n"
" <property access=\"read\" type=\"i\" name=\"CaretOffset\"/>\n"
@@ -670,9 +670,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView valueIntrospection(
+ constexpr auto valueIntrospection =
" <interface name=\"org.a11y.atspi.Value\">\n"
" <property access=\"read\" type=\"d\" name=\"MinimumValue\"/>\n"
" <property access=\"read\" type=\"d\" name=\"MaximumValue\"/>\n"
@@ -682,7 +682,7 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"in\" type=\"d\" name=\"value\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
QAccessibleInterface * interface = interfaceFromPath(path);
if (!interface) {
diff --git a/src/gui/platform/unix/qxkbcommon.cpp b/src/gui/platform/unix/qxkbcommon.cpp
index ebac9f108e8..e755892cf36 100644
--- a/src/gui/platform/unix/qxkbcommon.cpp
+++ b/src/gui/platform/unix/qxkbcommon.cpp
@@ -328,6 +328,12 @@ static constexpr const auto KeyTbl = qMakeArray(
Xkb2Qt<XKB_KEY_XF86Option, Qt::Key_Option>,
Xkb2Qt<XKB_KEY_XF86Paste, Qt::Key_Paste>,
Xkb2Qt<XKB_KEY_XF86Phone, Qt::Key_Phone>,
+#ifdef XKB_KEY_XF86PickupPhone
+ Xkb2Qt<XKB_KEY_XF86PickupPhone, Qt::Key_Call>,
+#endif
+#ifdef XKB_KEY_XF86HangupPhone
+ Xkb2Qt<XKB_KEY_XF86HangupPhone, Qt::Key_Hangup>,
+#endif
Xkb2Qt<XKB_KEY_XF86Reply, Qt::Key_Reply>,
Xkb2Qt<XKB_KEY_XF86Reload, Qt::Key_Reload>,
Xkb2Qt<XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows>,
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 2b2f2a27fcd..17ed5fb7ed4 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -2170,6 +2170,7 @@ QString QFont::key() const
\li Style strategy
\li Font style
\li Font features
+ \li Variable axes
\endlist
\sa fromString()
@@ -2195,12 +2196,12 @@ QString QFont::toString() const
QString::number((int)styleStrategy()) + comma +
styleName();
- QMap<Tag, quint32> sortedFeatures;
+ fontDescription += comma + QString::number(d->features.size());
for (const auto &[tag, value] : std::as_const(d->features).asKeyValueRange())
- sortedFeatures.insert(tag, value);
+ fontDescription += comma + QLatin1StringView{tag.toString()} + u'=' + QString::number(value);
- fontDescription += comma + QString::number(sortedFeatures.size());
- for (const auto &[tag, value] : std::as_const(sortedFeatures).asKeyValueRange())
+ fontDescription += comma + QString::number(d->request.variableAxisValues.size());
+ for (const auto &[tag, value] : std::as_const(d->request.variableAxisValues).asKeyValueRange())
fontDescription += comma + QLatin1StringView{tag.toString()} + u'=' + QString::number(value);
return fontDescription;
@@ -2216,7 +2217,7 @@ size_t qHash(const QFont &font, size_t seed) noexcept
return qHash(QFontPrivate::get(font)->request, seed);
}
-static std::optional<std::pair<QFont::Tag, quint32>> tagAndValueFromString(QStringView view)
+static std::optional<std::pair<QFont::Tag, quint32>> fontFeatureFromString(QStringView view)
{
const int separator = view.indexOf(u'=');
if (separator == -1)
@@ -2234,6 +2235,24 @@ static std::optional<std::pair<QFont::Tag, quint32>> tagAndValueFromString(QStri
return std::make_pair(*tag, value);
}
+static std::optional<std::pair<QFont::Tag, float>> variableAxisFromString(QStringView view)
+{
+ const int separator = view.indexOf(u'=');
+ if (separator == -1)
+ return std::nullopt;
+
+ const std::optional<QFont::Tag> tag = QFont::Tag::fromString(view.sliced(0, separator));
+ if (!tag)
+ return std::nullopt;
+
+ bool valueOk = false;
+ const float value = view.sliced(separator + 1).toFloat(&valueOk);
+ if (!valueOk)
+ return std::nullopt;
+
+ return std::make_pair(*tag, value);
+}
+
/*!
Sets this font to match the description \a descrip. The description
is a comma-separated list of the font attributes, as returned by
@@ -2263,6 +2282,8 @@ bool QFont::fromString(const QString &descrip)
setUnderline(l[5].toInt());
setStrikeOut(l[6].toInt());
setFixedPitch(l[7].toInt());
+ if (!d->request.fixedPitch) // assume 'false' fixedPitch equals default
+ d->request.ignorePitch = true;
} else if (count >= 10) {
if (l[2].toInt() > 0)
setPixelSize(l[2].toInt());
@@ -2275,6 +2296,8 @@ bool QFont::fromString(const QString &descrip)
setUnderline(l[6].toInt());
setStrikeOut(l[7].toInt());
setFixedPitch(l[8].toInt());
+ if (!d->request.fixedPitch) // assume 'false' fixedPitch equals default
+ d->request.ignorePitch = true;
if (count >= 16) {
setCapitalization((Capitalization)l[10].toInt());
setLetterSpacing((SpacingType)l[11].toInt(), l[12].toDouble());
@@ -2291,19 +2314,33 @@ bool QFont::fromString(const QString &descrip)
d->request.styleName.clear();
clearFeatures();
- if (count >= 18) {
- const int featureCount = l[17].toInt();
- if (count >= featureCount + 18) {
- for (int i = 0; i < featureCount; ++i) {
- if (const auto feature = tagAndValueFromString(l[18 + i]))
- setFeature(feature->first, feature->second);
- }
- }
+ clearVariableAxes();
+
+ int position = 17;
+ if (position >= count)
+ return true;
+
+ const int featureCount = l[position++].toInt();
+ if (position + featureCount > count)
+ return true;
+
+ for (int i = 0; i < featureCount; ++i) {
+ if (const auto feature = fontFeatureFromString(l[position++]))
+ setFeature(feature->first, feature->second);
}
- }
- if (count >= 9 && !d->request.fixedPitch) // assume 'false' fixedPitch equals default
- d->request.ignorePitch = true;
+ if (position >= count)
+ return true;
+
+ const int variableAxisCount = l[position++].toInt();
+ if (position + variableAxisCount > count)
+ return true;
+
+ for (int i = 0; i < variableAxisCount; ++i) {
+ if (const auto axis = variableAxisFromString(l[position++]))
+ setVariableAxis(axis->first, axis->second);
+ }
+ }
return true;
}
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index 27bc2a6a7cc..76ff29f6e91 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -192,7 +192,7 @@ public:
QFixed letterSpacing;
QFixed wordSpacing;
- QHash<QFont::Tag, quint32> features;
+ QMap<QFont::Tag, quint32> features;
mutable QFontPrivate *scFont;
QFont smallCapsFont() const { return QFont(smallCapsFontPrivate()); }
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 29fda652ef6..ede5409b112 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1414,7 +1414,7 @@ void QTextEngine::shapeText(int item) const
#endif
bool letterSpacingIsAbsolute;
bool shapingEnabled = false;
- QHash<QFont::Tag, quint32> features;
+ QMap<QFont::Tag, quint32> features;
QFixed letterSpacing, wordSpacing;
#ifndef QT_NO_RAWFONT
if (useRawFont) {
@@ -1610,7 +1610,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
int stringBaseIndex, int stringLength, int itemLength,
QFontEngine *fontEngine, QSpan<uint> itemBoundaries,
bool kerningEnabled, bool hasLetterSpacing,
- const QHash<QFont::Tag, quint32> &fontFeatures) const
+ const QMap<QFont::Tag, quint32> &fontFeatures) const
{
uint glyphs_shaped = 0;
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index e513fd598ba..f27463f7728 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -628,7 +628,7 @@ private:
int stringLength, int itemLength, QFontEngine *fontEngine,
QSpan<uint> itemBoundaries, bool kerningEnabled,
bool hasLetterSpacing,
- const QHash<QFont::Tag, quint32> &features) const;
+ const QMap<QFont::Tag, quint32> &features) const;
#endif
int endOfLine(int lineNum);
diff --git a/src/network/access/qhttp2protocolhandler_p.h b/src/network/access/qhttp2protocolhandler_p.h
index 2fde9e4c9d5..37e960b19dc 100644
--- a/src/network/access/qhttp2protocolhandler_p.h
+++ b/src/network/access/qhttp2protocolhandler_p.h
@@ -93,7 +93,6 @@ private:
// Stream's lifecycle management:
QHttp2Stream *createNewStream(const HttpMessagePair &message, bool uploadDone = false);
void connectStream(const HttpMessagePair &message, QHttp2Stream *stream);
- quint32 popStreamToResume();
QHttp2Connection *h2Connection;
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
index 881a233e694..5b86c1e1725 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
@@ -254,6 +254,7 @@ QDirectFbKeyMap::QDirectFbKeyMap()
insert(DIKS_FAVORITES , Qt::Key_Favorites);
insert(DIKS_KEYBOARD , Qt::Key_Keyboard);
insert(DIKS_PHONE , Qt::Key_Phone);
+ insert(DIKS_CALL , Qt::Key_Call)
insert(DIKS_PROGRAM , Qt::Key_Guide);
insert(DIKS_TIME , Qt::Key_Time);
diff --git a/src/plugins/platforms/wasm/qwasmdrag.cpp b/src/plugins/platforms/wasm/qwasmdrag.cpp
index 730816b9a99..1eed2acde53 100644
--- a/src/plugins/platforms/wasm/qwasmdrag.cpp
+++ b/src/plugins/platforms/wasm/qwasmdrag.cpp
@@ -16,6 +16,8 @@
#include <QtCore/qtimer.h>
#include <QFile>
+#include <private/qshapedpixmapdndwindow_p.h>
+
#include <functional>
#include <string>
#include <utility>
@@ -92,9 +94,8 @@ Qt::DropAction QWasmDrag::drag(QDrag *drag)
Qt::DropAction dragResult = Qt::IgnoreAction;
if (qstdweb::haveJspi()) {
- QEventLoop loop;
- m_dragState = std::make_unique<DragState>(drag, window, [&loop]() { loop.quit(); });
- loop.exec();
+ m_dragState = std::make_unique<DragState>(drag, window, [this]() { QSimpleDrag::cancelDrag(); });
+ QSimpleDrag::drag(drag);
dragResult = m_dragState->dropAction;
m_dragState.reset();
}
@@ -110,14 +111,16 @@ void QWasmDrag::onNativeDragStarted(DragEvent *event)
Q_ASSERT_X(event->type == EventType::DragStart, Q_FUNC_INFO,
"The event is not a DragStart event");
- event->webEvent.call<void>("preventDefault");
-
// It is possible for a drag start event to arrive from another window.
if (!m_dragState || m_dragState->window != event->targetWindow) {
event->cancelDragStart();
return;
}
+ // We have our own window
+ if (shapedPixmapWindow())
+ shapedPixmapWindow()->setVisible(false);
+
m_dragState->dragImage = std::make_unique<DragState::DragImage>(
m_dragState->drag->pixmap(), m_dragState->drag->mimeData(), event->targetWindow);
event->dataTransfer.setDragImage(m_dragState->dragImage->htmlElement(),
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index 13682256370..6fd857828d3 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -87,34 +87,35 @@ inline ControlState calcControlState(const QStyleOption *option)
} // namespace StyleOptionHelper
-#define AcceptMedium u"\uF78C"_s
-// QStringLiteral(u"\uE73C")
-#define Dash12 u"\uE629"_s
-#define CheckMark u"\uE73E"_s
-
-#define CaretLeftSolid8 u"\uEDD9"_s
-#define CaretRightSolid8 u"\uEDDA"_s
-#define CaretUpSolid8 u"\uEDDB"_s
-#define CaretDownSolid8 u"\uEDDC"_s
-
-#define ChevronDown u"\uE70D"_s
-#define ChevronUp u"\uE70E"_s
-
-#define ChevronDownMed u"\uE972"_s
-#define ChevronLeftMed u"\uE973"_s
-#define ChevronRightMed u"\uE974"_s
-
-#define ChevronUpSmall u"\uE96D"_s
-#define ChevronDownSmall u"\uE96E"_s
-
-#define ChromeMinimize u"\uE921"_s
-#define ChromeMaximize u"\uE922"_s
-#define ChromeRestore u"\uE923"_s
-#define ChromeClose u"\uE8BB"_s
+enum class Icon : ushort
+{
+ AcceptMedium = 0xF78C,
+ Dash12 = 0xE629,
+ CheckMark = 0xE73E,
+ CaretLeftSolid8 = 0xEDD9,
+ CaretRightSolid8 = 0xEDDA,
+ CaretUpSolid8 = 0xEDDB,
+ CaretDownSolid8 = 0xEDDC,
+ ChevronDown = 0xE70D,
+ ChevronUp = 0xE70E,
+ ChevronDownMed = 0xE972,
+ ChevronLeftMed = 0xE973,
+ ChevronRightMed = 0xE974,
+ ChevronUpSmall = 0xE96D,
+ ChevronDownSmall = 0xE96E,
+ ChromeMinimize = 0xE921,
+ ChromeMaximize = 0xE922,
+ ChromeRestore = 0xE923,
+ ChromeClose = 0xE8BB,
+ More = 0xE712,
+ Help = 0xE897,
+ Clear = 0xE894,
+};
-#define More u"\uE712"_s
-#define Help u"\uE897"_s
-#define Clear u"\uE894"_s
+static inline QString fluentIcon(Icon i)
+{
+ return QChar(ushort(i));
+}
template <typename R, typename P, typename B>
static inline void drawRoundedRect(QPainter *p, R &&rect, P &&pen, B &&brush)
@@ -316,7 +317,7 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
{
QWindows11StylePrivate *d = const_cast<QWindows11StylePrivate*>(d_func());
- const auto drawTitleBarButton = [&](ComplexControl control, SubControl sc, const QString &str) {
+ const auto drawTitleBarButton = [&](ComplexControl control, SubControl sc, Icon ico) {
using namespace StyleOptionHelper;
const QRect buttonRect = proxy()->subControlRect(control, option, sc, widget);
if (buttonRect.isValid()) {
@@ -324,10 +325,10 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
if (hover)
painter->fillRect(buttonRect, winUI3Color(subtleHighlightColor));
painter->setPen(option->palette.color(QPalette::WindowText));
- painter->drawText(buttonRect, Qt::AlignCenter, str);
+ painter->drawText(buttonRect, Qt::AlignCenter, fluentIcon(ico));
}
};
- const auto drawTitleBarCloseButton = [&](ComplexControl control, SubControl sc, const QString &str) {
+ const auto drawTitleBarCloseButton = [&](ComplexControl control, SubControl sc, Icon ico) {
using namespace StyleOptionHelper;
const QRect buttonRect = proxy()->subControlRect(control, option, sc, widget);
if (buttonRect.isValid()) {
@@ -349,7 +350,7 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
break;
}
painter->setPen(pen);
- painter->drawText(buttonRect, Qt::AlignCenter, str);
+ painter->drawText(buttonRect, Qt::AlignCenter, fluentIcon(ico));
}
};
@@ -416,18 +417,13 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
sb, sb->rect.size());
if (cp.needsPainting()) {
const auto frameRect = QRectF(option->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5));
- drawRoundedRect(cp.painter(), frameRect, Qt::NoPen, option->palette.brush(QPalette::Base));
+ drawRoundedRect(cp.painter(), frameRect, Qt::NoPen, inputFillBrush(option, widget));
if (sb->frame && (sub & SC_SpinBoxFrame))
drawLineEditFrame(cp.painter(), frameRect, option);
- const bool isMouseOver = state & State_MouseOver;
- const bool hasFocus = state & State_HasFocus;
- const bool isEnabled = state & QStyle::State_Enabled;
- if (isEnabled && isMouseOver && !hasFocus && !highContrastTheme)
- drawRoundedRect(cp.painter(), frameRect, Qt::NoPen, winUI3Color(subtleHighlightColor));
-
const auto drawUpDown = [&](QStyle::SubControl sc) {
+ const bool isEnabled = state & QStyle::State_Enabled;
const bool isUp = sc == SC_SpinBoxUp;
const QRect rect = proxy()->subControlRect(CC_SpinBox, option, sc, widget);
if (isEnabled && sb->activeSubControls & sc)
@@ -437,7 +433,7 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
cp->setFont(d->assetFont);
cp->setPen(sb->palette.buttonText().color());
cp->setBrush(Qt::NoBrush);
- cp->drawText(rect, Qt::AlignCenter, isUp ? ChevronUp : ChevronDown);
+ cp->drawText(rect, Qt::AlignCenter, fluentIcon(isUp ? Icon::ChevronUp : Icon::ChevronDown));
};
if (sub & SC_SpinBoxUp) drawUpDown(SC_SpinBoxUp);
if (sub & SC_SpinBoxDown) drawUpDown(SC_SpinBoxDown);
@@ -586,21 +582,22 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
case CC_ComboBox:
if (const QStyleOptionComboBox *combobox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
const auto frameRect = QRectF(option->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5));
- drawRoundedRect(painter, frameRect, Qt::NoPen, option->palette.brush(QPalette::Base));
+ QStyleOption opt(*option);
+ opt.state.setFlag(QStyle::State_On, false);
+ drawRoundedRect(painter, frameRect, Qt::NoPen,
+ combobox->editable ? inputFillBrush(option, widget)
+ : controlFillBrush(&opt, ControlType::Control));
if (combobox->frame)
drawLineEditFrame(painter, frameRect, combobox, combobox->editable);
const bool hasFocus = state & State_HasFocus;
- QStyleOption opt(*option);
- opt.state.setFlag(QStyle::State_On, false);
- drawRoundedRect(painter, frameRect, Qt::NoPen, controlFillBrush(&opt, ControlType::Control));
if (sub & SC_ComboBoxArrow) {
- QRectF rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget).adjusted(4, 0, -4, 1);
+ QRectF rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
painter->setFont(d->assetFont);
painter->setPen(controlTextColor(option));
- painter->drawText(rect, Qt::AlignCenter, ChevronDownMed);
+ painter->drawText(rect, Qt::AlignCenter, fluentIcon(Icon::ChevronDownMed));
}
if (state & State_KeyboardFocusChange && hasFocus) {
QStyleOptionFocusRect fropt;
@@ -662,9 +659,9 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
f.setPointSize(6);
cp->setFont(f);
cp->setPen(Qt::gray);
- const auto str = vertical ? CaretDownSolid8
- : (isRtl ? CaretLeftSolid8 : CaretRightSolid8);
- cp->drawText(rect, Qt::AlignCenter, str);
+ const auto ico = vertical ? Icon::CaretDownSolid8
+ : (isRtl ? Icon::CaretLeftSolid8 : Icon::CaretRightSolid8);
+ cp->drawText(rect, Qt::AlignCenter, fluentIcon(ico));
}
}
if (sub & SC_ScrollBarSubLine) {
@@ -674,9 +671,9 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
f.setPointSize(6);
cp->setFont(f);
cp->setPen(Qt::gray);
- const auto str = vertical ? CaretUpSolid8
- : (isRtl ? CaretRightSolid8 : CaretLeftSolid8);
- cp->drawText(rect, Qt::AlignCenter, str);
+ const auto ico = vertical ? Icon::CaretUpSolid8
+ : (isRtl ? Icon::CaretRightSolid8 : Icon::CaretLeftSolid8);
+ cp->drawText(rect, Qt::AlignCenter, fluentIcon(ico));
}
}
}
@@ -686,9 +683,9 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
QFont buttonFont = QFont(d->assetFont);
buttonFont.setPointSize(8);
painter->setFont(buttonFont);
- drawTitleBarCloseButton(CC_MdiControls, SC_MdiCloseButton, ChromeClose);
- drawTitleBarButton(CC_MdiControls, SC_MdiNormalButton, ChromeRestore);
- drawTitleBarButton(CC_MdiControls, SC_MdiMinButton, ChromeMinimize);
+ drawTitleBarCloseButton(CC_MdiControls, SC_MdiCloseButton, Icon::ChromeClose);
+ drawTitleBarButton(CC_MdiControls, SC_MdiNormalButton, Icon::ChromeRestore);
+ drawTitleBarButton(CC_MdiControls, SC_MdiMinButton, Icon::ChromeMinimize);
}
break;
case CC_TitleBar:
@@ -716,18 +713,18 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
// min button
if (shouldDrawButton(SC_TitleBarMinButton, Qt::WindowMinimizeButtonHint) &&
!(titlebar->titleBarState & Qt::WindowMinimized)) {
- drawTitleBarButton(CC_TitleBar, SC_TitleBarMinButton, ChromeMinimize);
+ drawTitleBarButton(CC_TitleBar, SC_TitleBarMinButton, Icon::ChromeMinimize);
}
// max button
if (shouldDrawButton(SC_TitleBarMaxButton, Qt::WindowMaximizeButtonHint) &&
!(titlebar->titleBarState & Qt::WindowMaximized)) {
- drawTitleBarButton(CC_TitleBar, SC_TitleBarMaxButton, ChromeMaximize);
+ drawTitleBarButton(CC_TitleBar, SC_TitleBarMaxButton, Icon::ChromeMaximize);
}
// close button
if (shouldDrawButton(SC_TitleBarCloseButton, Qt::WindowSystemMenuHint))
- drawTitleBarCloseButton(CC_TitleBar, SC_TitleBarCloseButton, ChromeClose);
+ drawTitleBarCloseButton(CC_TitleBar, SC_TitleBarCloseButton, Icon::ChromeClose);
// normalize button
if ((titlebar->subControls & SC_TitleBarNormalButton) &&
@@ -735,20 +732,20 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
(titlebar->titleBarState & Qt::WindowMinimized)) ||
((titlebar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
(titlebar->titleBarState & Qt::WindowMaximized)))) {
- drawTitleBarButton(CC_TitleBar, SC_TitleBarNormalButton, ChromeRestore);
+ drawTitleBarButton(CC_TitleBar, SC_TitleBarNormalButton, Icon::ChromeRestore);
}
// context help button
if (shouldDrawButton(SC_TitleBarContextHelpButton, Qt::WindowContextHelpButtonHint))
- drawTitleBarButton(CC_TitleBar, SC_TitleBarContextHelpButton, Help);
+ drawTitleBarButton(CC_TitleBar, SC_TitleBarContextHelpButton, Icon::Help);
// shade button
if (shouldDrawButton(SC_TitleBarShadeButton, Qt::WindowShadeButtonHint))
- drawTitleBarButton(CC_TitleBar, SC_TitleBarShadeButton, ChevronUpSmall);
+ drawTitleBarButton(CC_TitleBar, SC_TitleBarShadeButton, Icon::ChevronUpSmall);
// unshade button
if (shouldDrawButton(SC_TitleBarUnshadeButton, Qt::WindowShadeButtonHint))
- drawTitleBarButton(CC_TitleBar, SC_TitleBarUnshadeButton, ChevronDownSmall);
+ drawTitleBarButton(CC_TitleBar, SC_TitleBarUnshadeButton, Icon::ChevronDownSmall);
// window icon for system menu
if (shouldDrawButton(SC_TitleBarSysMenu, Qt::WindowSystemMenuHint)) {
@@ -872,9 +869,9 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
f.setPointSize(6);
painter->setFont(f);
painter->setPen(header->palette.text().color());
- painter->drawText(option->rect, Qt::AlignCenter,
- indicator == QStyleOptionHeader::SortUp ? ChevronDown
- : ChevronUp);
+ const auto ico = indicator == QStyleOptionHeader::SortUp ? Icon::ChevronDown
+ : Icon::ChevronUp;
+ painter->drawText(option->rect, Qt::AlignCenter, fluentIcon(ico));
}
}
break;
@@ -892,8 +889,9 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
painter->setFont(d->assetFont);
painter->setPen(controlTextColor(option, QPalette::Window));
qreal clipWidth = 1.0;
+ const QString str = fluentIcon(Icon::AcceptMedium);
QFontMetrics fm(d->assetFont);
- QRectF clipRect = fm.boundingRect(AcceptMedium);
+ QRectF clipRect = fm.boundingRect(str);
if (d->transitionsEnabled() && option->styleObject) {
QNumberStyleAnimation *animation = qobject_cast<QNumberStyleAnimation *>(
d->animation(option->styleObject));
@@ -904,13 +902,13 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
clipRect.moveCenter(center);
clipRect.setLeft(rect.x() + (rect.width() - clipRect.width()) / 2.0 + 0.5);
clipRect.setWidth(clipWidth * clipRect.width());
- painter->drawText(clipRect, Qt::AlignVCenter | Qt::AlignLeft, AcceptMedium);
+ painter->drawText(clipRect, Qt::AlignVCenter | Qt::AlignLeft, str);
} else if (isPartial) {
QFont f(d->assetFont);
f.setPointSize(6);
painter->setFont(f);
painter->setPen(controlTextColor(option, QPalette::Window));
- painter->drawText(rect, Qt::AlignCenter, Dash12);
+ painter->drawText(rect, Qt::AlignCenter, fluentIcon(Icon::Dash12));
}
}
break;
@@ -923,8 +921,10 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
painter->setFont(f);
painter->setPen(option->palette.color(isOpen ? QPalette::Active : QPalette::Disabled,
QPalette::WindowText));
- const auto str = isOpen ? ChevronDownMed : (isReverse ? ChevronLeftMed : ChevronRightMed);
- painter->drawText(option->rect, Qt::AlignCenter, str);
+ const auto ico = isOpen ? Icon::ChevronDownMed
+ : (isReverse ? Icon::ChevronLeftMed
+ : Icon::ChevronRightMed);
+ painter->drawText(option->rect, Qt::AlignCenter, fluentIcon(ico));
}
}
break;
@@ -995,10 +995,17 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
}
case PE_PanelLineEdit:
if (const auto *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- const auto frameRect = QRectF(option->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5));
- drawRoundedRect(painter, frameRect, Qt::NoPen, inputFillBrush(option, widget));
- if (panel->lineWidth > 0)
- proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget);
+ const bool isInSpinBox =
+ widget && qobject_cast<const QAbstractSpinBox *>(widget->parent()) != nullptr;
+ const bool isInComboBox =
+ widget && qobject_cast<const QComboBox *>(widget->parent()) != nullptr;
+ if (!isInSpinBox && !isInComboBox) {
+ const auto frameRect =
+ QRectF(option->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5));
+ drawRoundedRect(painter, frameRect, Qt::NoPen, inputFillBrush(option, widget));
+ if (panel->lineWidth > 0)
+ proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget);
+ }
}
break;
case PE_FrameLineEdit: {
@@ -1511,7 +1518,7 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
if (isEnabled)
penColor.setAlpha(percentToAlpha(60.63)); // fillColorTextSecondary
painter->setPen(penColor);
- painter->drawText(vindRect, Qt::AlignCenter, ChevronDownMed);
+ painter->drawText(vindRect, Qt::AlignCenter, fluentIcon(Icon::ChevronDownMed));
}
}
break;
@@ -1587,8 +1594,7 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
QPainterStateGuard psg(painter);
painter->setFont(d->assetFont);
painter->setPen(option->palette.text().color());
- const auto textToDraw = QStringLiteral(u"\uE73E");
- painter->drawText(vRect, Qt::AlignCenter, textToDraw);
+ painter->drawText(vRect, Qt::AlignCenter, fluentIcon(Icon::CheckMark));
}
if (menuitem->menuHasCheckableItems)
xOffset += checkMarkWidth + contentItemHMargin;
@@ -1669,8 +1675,8 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
QRect vSubMenuRect = visualMenuRect(submenuRect);
painter->setPen(option->palette.text().color());
const bool isReverse = option->direction == Qt::RightToLeft;
- const auto str = isReverse ? ChevronLeftMed : ChevronRightMed;
- painter->drawText(vSubMenuRect, Qt::AlignCenter, str);
+ const auto ico = isReverse ? Icon::ChevronLeftMed : Icon::ChevronRightMed;
+ painter->drawText(vSubMenuRect, Qt::AlignCenter, fluentIcon(ico));
}
}
break;
@@ -1936,32 +1942,31 @@ QRect QWindows11Style::subControlRect(ComplexControl control, const QStyleOption
#if QT_CONFIG(spinbox)
case CC_SpinBox:
if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
- QSize bs;
- int fw = spinbox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
- bs.setHeight(qMax(8, spinbox->rect.height() - fw));
- bs.setWidth(16);
- int y = fw + spinbox->rect.y();
- int x, lx, rx;
- x = spinbox->rect.x() + spinbox->rect.width() - fw - 2 * bs.width();
- lx = fw;
- rx = x - fw;
+ const bool hasButtons = spinbox->buttonSymbols != QAbstractSpinBox::NoButtons;
+ const int fw = spinbox->frame
+ ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget)
+ : 0;
+ const int buttonHeight = hasButtons
+ ? qMin(spinbox->rect.height() - 3 * fw, spinbox->fontMetrics.height() * 5 / 4)
+ : 0;
+ const QSize buttonSize(buttonHeight * 6 / 5, buttonHeight);
+ const int textFieldLength = spinbox->rect.width() - 2 * fw - 2 * buttonSize.width();
+ const QPoint topLeft(spinbox->rect.topLeft() + QPoint(fw, fw));
switch (subControl) {
case SC_SpinBoxUp:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ case SC_SpinBoxDown: {
+ if (!hasButtons)
return QRect();
- ret = QRect(x, y, bs.width(), bs.height());
- break;
- case SC_SpinBoxDown:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
- return QRect();
- ret = QRect(x + bs.width(), y, bs.width(), bs.height());
+ const int yOfs = ((spinbox->rect.height() - 2 * fw) - buttonSize.height()) / 2;
+ ret = QRect(topLeft.x() + textFieldLength, topLeft.y() + yOfs, buttonSize.width(),
+ buttonSize.height());
+ if (subControl == SC_SpinBoxDown)
+ ret.moveRight(ret.right() + buttonSize.width());
break;
+ }
case SC_SpinBoxEditField:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) {
- ret = QRect(lx, fw, spinbox->rect.width() - 2*fw, spinbox->rect.height() - 2*fw);
- } else {
- ret = QRect(lx, fw, rx, spinbox->rect.height() - 2*fw);
- }
+ ret = QRect(topLeft,
+ spinbox->rect.bottomRight() - QPoint(fw + 2 * buttonSize.width(), fw));
break;
case SC_SpinBoxFrame:
ret = spinbox->rect;
@@ -2076,16 +2081,37 @@ QRect QWindows11Style::subControlRect(ComplexControl control, const QStyleOption
break;
}
case CC_ComboBox: {
- if (subControl == SC_ComboBoxArrow) {
+ if (const auto *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
const auto indicatorWidth =
proxy()->pixelMetric(PM_MenuButtonIndicator, option, widget);
- const int endX = option->rect.right() - contentHMargin - 2;
- const int startX = endX - indicatorWidth;
- const QRect rect(QPoint(startX, option->rect.top()),
- QPoint(endX, option->rect.bottom()));
- ret = visualRect(option->direction, option->rect, rect);
- } else {
- ret = QWindowsVistaStyle::subControlRect(control, option, subControl, widget);
+ switch (subControl) {
+ case SC_ComboBoxArrow: {
+ const int fw =
+ cb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, cb, widget) : 0;
+ const int buttonHeight =
+ qMin(cb->rect.height() - 3 * fw, cb->fontMetrics.height() * 5 / 4);
+ const QSize buttonSize(buttonHeight * 6 / 5, buttonHeight);
+ const int textFieldLength = cb->rect.width() - 2 * fw - buttonSize.width();
+ const QPoint topLeft(cb->rect.topLeft() + QPoint(fw, fw));
+ const int yOfs = ((cb->rect.height() - 2 * fw) - buttonSize.height()) / 2;
+ ret = QRect(topLeft.x() + textFieldLength, topLeft.y() + yOfs, buttonSize.width(),
+ buttonSize.height());
+ ret = visualRect(option->direction, option->rect, ret);
+ break;
+ }
+ case SC_ComboBoxEditField: {
+ ret = option->rect;
+ if (cb->frame) {
+ const int fw = proxy()->pixelMetric(PM_ComboBoxFrameWidth, cb, widget);
+ ret = ret.marginsRemoved(QMargins(fw, fw, fw, fw));
+ }
+ ret.setWidth(ret.width() - indicatorWidth - contentHMargin * 2);
+ break;
+ }
+ default:
+ ret = QWindowsVistaStyle::subControlRect(control, option, subControl, widget);
+ break;
+ }
}
break;
}
@@ -2177,15 +2203,15 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o
break;
#endif // QT_CONFIG(menu)
#if QT_CONFIG(spinbox)
- case QStyle::CT_SpinBox: {
+ case CT_SpinBox: {
if (const auto *spinBoxOpt = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
// Add button + frame widths
- const qreal dpi = QStyleHelper::dpi(option);
const bool hasButtons = (spinBoxOpt->buttonSymbols != QAbstractSpinBox::NoButtons);
const int margins = 8;
- const int buttonWidth = hasButtons ? qRound(QStyleHelper::dpiScaled(16, dpi)) : 0;
- const int frameWidth = spinBoxOpt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth,
- spinBoxOpt, widget) : 0;
+ const int buttonWidth = hasButtons ? 16 + contentItemHMargin : 0;
+ const int frameWidth = spinBoxOpt->frame
+ ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget)
+ : 0;
contentSize += QSize(2 * buttonWidth + 2 * frameWidth + 2 * margins, 2 * frameWidth);
}
@@ -2196,7 +2222,7 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o
case CT_ComboBox:
if (const auto *comboBoxOpt = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
contentSize = QWindowsStyle::sizeFromContents(type, option, size, widget); // don't rely on QWindowsThemeData
- contentSize += QSize(4, 4); // default win11 style margins
+ contentSize += QSize(0, 4); // for the lineedit frame
if (comboBoxOpt->subControls & SC_ComboBoxArrow) {
const auto w = proxy()->pixelMetric(PM_MenuButtonIndicator, option, widget);
contentSize.rwidth() += w + contentItemHMargin;
@@ -2204,6 +2230,13 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o
}
break;
#endif
+ case CT_LineEdit: {
+ if (qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ contentSize = QWindowsStyle::sizeFromContents(type, option, size, widget); // don't rely on QWindowsThemeData
+ contentSize += QSize(0, 4); // for the lineedit frame
+ }
+ break;
+ }
case CT_HeaderSection:
// windows vista does not honor the indicator (as it was drawn above the text, not on the
// side) so call QWindowsStyle::styleHint directly to get the correct size hint
@@ -2335,7 +2368,7 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option,
QFont f(d->assetFont);
f.setPointSize(qRound(fontSize * 0.9f)); // a little bit smaller
QFontMetrics fm(f);
- const auto width = fm.horizontalAdvance(ChevronDownMed);
+ const auto width = fm.horizontalAdvance(fluentIcon(Icon::ChevronDownMed));
m_fontPoint2ChevronDownMedWidth.insert(fontSize, width);
res += width;
} else {
@@ -2346,6 +2379,8 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option,
}
break;
}
+ case PM_ComboBoxFrameWidth:
+ case PM_SpinBoxFrameWidth:
case PM_DefaultFrameWidth:
res = 2;
break;
@@ -2601,7 +2636,7 @@ QIcon QWindows11Style::standardIcon(StandardPixmap standardIcon,
switch (standardIcon) {
case SP_LineEditClearButton: {
if (d->m_lineEditClearButton.isNull()) {
- auto e = new WinFontIconEngine(Clear, d->assetFont);
+ auto e = new WinFontIconEngine(fluentIcon(Icon::Clear), d->assetFont);
d->m_lineEditClearButton = QIcon(e);
}
return d->m_lineEditClearButton;
@@ -2609,7 +2644,7 @@ QIcon QWindows11Style::standardIcon(StandardPixmap standardIcon,
case SP_ToolBarHorizontalExtensionButton:
case SP_ToolBarVerticalExtensionButton: {
if (d->m_toolbarExtensionButton.isNull()) {
- auto e = new WinFontIconEngine(More, d->assetFont);
+ auto e = new WinFontIconEngine(fluentIcon(Icon::More), d->assetFont);
e->setScale(1.0);
d->m_toolbarExtensionButton = QIcon(e);
}
diff --git a/src/plugins/tls/schannel/qtls_schannel.cpp b/src/plugins/tls/schannel/qtls_schannel.cpp
index 667f2d8a6c3..1034e99b7e0 100644
--- a/src/plugins/tls/schannel/qtls_schannel.cpp
+++ b/src/plugins/tls/schannel/qtls_schannel.cpp
@@ -2267,14 +2267,19 @@ static void attachPrivateKeyToCertificate(const QSslCertificate &certificate,
}
const auto freeProvider = qScopeGuard([provider]() { NCryptFreeObject(provider); });
- const QString certName = certificate.subjectInfo(QSslCertificate::CommonName).front();
+ const QString certName = [certificate]() {
+ if (auto cn = certificate.subjectInfo(QSslCertificate::CommonName); !cn.isEmpty())
+ return cn.front();
+ return QString();
+ }();
QSpan<const QChar> nameSpan(certName);
NCryptBuffer nbuffer{ ULONG(nameSpan.size_bytes() + sizeof(char16_t)),
NCRYPTBUFFER_PKCS_KEY_NAME,
const_reinterpret_cast<void *>(nameSpan.data()) };
NCryptBufferDesc bufferDesc{ NCRYPTBUFFER_VERSION, 1, &nbuffer };
+ auto *bufferDescPtr = nameSpan.isEmpty() ? nullptr : &bufferDesc;
NCRYPT_KEY_HANDLE ncryptKey = 0;
- status = NCryptImportKey(provider, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, &bufferDesc, &ncryptKey,
+ status = NCryptImportKey(provider, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, bufferDescPtr, &ncryptKey,
PBYTE(buffer.data()), buffer.size(), 0);
if (status != SEC_E_OK) {
qCWarning(lcTlsBackendSchannel())
diff --git a/src/sql/doc/qtsql.qdocconf b/src/sql/doc/qtsql.qdocconf
index 2545bcf4050..03efa743957 100644
--- a/src/sql/doc/qtsql.qdocconf
+++ b/src/sql/doc/qtsql.qdocconf
@@ -58,3 +58,6 @@ manifestmeta.highlighted.names = \
# Enforce zero documentation warnings
warninglimit = 0
+
+# Report warnings for images without alt text
+reportmissingalttextforimages = true
diff --git a/src/sql/doc/src/sql-programming.qdoc b/src/sql/doc/src/sql-programming.qdoc
index 07daf942ac4..948baec6f38 100644
--- a/src/sql/doc/src/sql-programming.qdoc
+++ b/src/sql/doc/src/sql-programming.qdoc
@@ -419,7 +419,9 @@
\table
\row \li \inlineimage noforeignkeys.png
+ {Table showing city and country as numeric foreign key values}
\li \inlineimage foreignkeys.png
+ {Table showing city and country resolved to text strings}
\endtable
The screenshot on the left shows a plain QSqlTableModel in a
diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt
index f4fc96b867d..d43b6ec4fb2 100644
--- a/src/widgets/CMakeLists.txt
+++ b/src/widgets/CMakeLists.txt
@@ -339,12 +339,12 @@ set(qstyle_resource_fusion_files
"styles/images/fusion_closedock-32.png"
"styles/images/fusion_closedock-48.png"
"styles/images/fusion_closedock-64.png"
- "styles/images/fusion_normalizedockup_10.png"
+ "styles/images/fusion_normalizedockup-10.png"
"styles/images/fusion_normalizedockup-16.png"
- "styles/images/fusion_normalizedockup_20.png"
+ "styles/images/fusion_normalizedockup-20.png"
"styles/images/fusion_normalizedockup-32.png"
- "styles/images/fusion_normalizedockup_48.png"
- "styles/images/fusion_normalizedockup_64.png"
+ "styles/images/fusion_normalizedockup-48.png"
+ "styles/images/fusion_normalizedockup-64.png"
"styles/images/fusion_titlebar-min-10.png"
"styles/images/fusion_titlebar-min-16.png"
"styles/images/fusion_titlebar-min-20.png"
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index d989feb7f91..fa17c94a23f 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -389,13 +389,16 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
p += offset;
#if QT_CONFIG(wayland)
- create();
- if (auto waylandWindow = dynamic_cast<QNativeInterface::Private::QWaylandWindow*>(windowHandle()->handle())) {
- // based on the existing code below, by default position at 'p' stored at the bottom right of our rect
- // then flip to the other arbitrary 4x24 space if constrained
- const QRect controlGeometry(QRect(p.x() - 4, p.y() - 24, 4, 24));
- waylandWindow->setParentControlGeometry(controlGeometry);
- waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::ToolTip);
+ if (w) {
+ create();
+ if (auto waylandWindow = dynamic_cast<QNativeInterface::Private::QWaylandWindow*>(windowHandle()->handle())) {
+ // based on the existing code below, by default position at 'p' stored at the bottom right of our rect
+ // then flip to the other arbitrary 4x24 space if constrained
+ const QRect controlGeometry = QRect(p.x() - 4, p.y() - 24, 4, 24)
+ .translated(-w->window()->mapToGlobal(QPoint(0, 0)));
+ waylandWindow->setParentControlGeometry(controlGeometry);
+ waylandWindow->setExtendedWindowType(QNativeInterface::Private::QWaylandWindow::ToolTip);
+ }
}
#endif
diff --git a/src/widgets/styles/images/fusion_normalizedockup_10.png b/src/widgets/styles/images/fusion_normalizedockup-10.png
index 7516e4ee4f8..7516e4ee4f8 100644
--- a/src/widgets/styles/images/fusion_normalizedockup_10.png
+++ b/src/widgets/styles/images/fusion_normalizedockup-10.png
Binary files differ
diff --git a/src/widgets/styles/images/fusion_normalizedockup_20.png b/src/widgets/styles/images/fusion_normalizedockup-20.png
index 2bc9421d5ac..2bc9421d5ac 100644
--- a/src/widgets/styles/images/fusion_normalizedockup_20.png
+++ b/src/widgets/styles/images/fusion_normalizedockup-20.png
Binary files differ
diff --git a/src/widgets/styles/images/fusion_normalizedockup_48.png b/src/widgets/styles/images/fusion_normalizedockup-48.png
index 6c497abdded..6c497abdded 100644
--- a/src/widgets/styles/images/fusion_normalizedockup_48.png
+++ b/src/widgets/styles/images/fusion_normalizedockup-48.png
Binary files differ
diff --git a/src/widgets/styles/images/fusion_normalizedockup_64.png b/src/widgets/styles/images/fusion_normalizedockup-64.png
index 5ec620e5a04..5ec620e5a04 100644
--- a/src/widgets/styles/images/fusion_normalizedockup_64.png
+++ b/src/widgets/styles/images/fusion_normalizedockup-64.png
Binary files differ