QVariant: fix conversions of string keys to Q_ENUM that are QFlags<>

Since Qt 6.0, QMetaType stores the name obtained from the C++ compiler,
which means we know a type like Qt::Alignment by its proper, full name
of QFlags<Qt::AlignmentFlag>. However, the meta object records only the
bare name of the enumeration, not the full flags.

Pick-to: 6.2 6.3 6.4
Fixes: QTBUG-105932
Fixes: QTBUG-96185
Change-Id: Ic6547f8247454b47baa8fffd170eab977e306377
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
bb10
Thiago Macieira 2022-08-25 15:59:39 -03:00 committed by Fabian Kosmale
parent 845697bf11
commit 98e21f0979
2 changed files with 16 additions and 5 deletions

View File

@ -1871,10 +1871,16 @@ static QMetaEnum metaEnumFromType(QMetaType t)
{
if (t.flags() & QMetaType::IsEnumeration) {
if (const QMetaObject *metaObject = t.metaObject()) {
const QByteArray enumName = t.name();
const char *lastColon = std::strrchr(enumName, ':');
return metaObject->enumerator(metaObject->indexOfEnumerator(
lastColon ? lastColon + 1 : enumName.constData()));
QByteArrayView qflagsNamePrefix = "QFlags<";
QByteArray enumName = t.name();
if (enumName.endsWith('>') && enumName.startsWith(qflagsNamePrefix)) {
// extract the template argument
enumName.chop(1);
enumName = enumName.sliced(qflagsNamePrefix.size());
}
if (qsizetype lastColon = enumName.lastIndexOf(':'); lastColon != -1)
enumName = enumName.sliced(lastColon + 1);
return metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
}
}
return QMetaEnum();
@ -2524,7 +2530,7 @@ bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
return true;
}
const ConverterFunction * const f =
customTypesConversionRegistry()->function(qMakePair(fromTypeId, toTypeId));
customTypesConversionRegistry()->function(std::make_pair(fromTypeId, toTypeId));
if (f)
return true;

View File

@ -4714,6 +4714,11 @@ void tst_QVariant::metaEnums()
METAENUMS_TEST(MetaEnumTest_Enum5_value);
METAENUMS_TEST(MetaEnumTest_Enum6_value);
METAENUMS_TEST(MetaEnumTest_Enum8_value);
#undef METAENUMS_TEST
testVariantMeta(Qt::RichText, &ok, "RichText");
testVariantMeta(Qt::Alignment(Qt::AlignBottom), &ok, "AlignBottom");
}
void tst_QVariant::nullConvert()