diff options
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 142 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qvariant.cpp | 396 | ||||
-rw-r--r-- | tests/auto/corelib/io/qsettings/tst_qsettings.cpp | 3 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/qvariant.pro | 2 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 16 |
7 files changed, 159 insertions, 402 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 446511c14d..e8f359a366 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1829,6 +1829,18 @@ static bool convertToEnum(const void *from, int fromTypeId, void *to, const QMet } } +#ifndef QT_BOOTSTRAPPED +static bool canConvertMetaObject(const QMetaType &fromType, const QMetaType &toType) +{ + if ((fromType.flags() & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) { + return fromType.metaObject()->inherits(toType.metaObject()) || + toType.metaObject()->inherits(fromType.metaObject()); + } + return false; +} +#endif + + /*! Converts the object at \a from from \a fromTypeId to the preallocated space at \a to typed \a toTypeId. Returns \c true, if the conversion succeeded, otherwise false. @@ -1836,6 +1848,16 @@ static bool convertToEnum(const void *from, int fromTypeId, void *to, const QMet */ bool QMetaType::convert(const void *from, int fromTypeId, void *to, int toTypeId) { + if (fromTypeId == UnknownType || toTypeId == UnknownType) + return false; + + if (fromTypeId == toTypeId) { + // just make a copy + QMetaType(fromTypeId).destruct(to); + QMetaType(fromTypeId).construct(to, from); + return true; + } + if (auto moduleHelper = qModuleHelperForType(qMax(fromTypeId, toTypeId))) { if (moduleHelper->convert(from, fromTypeId, to, toTypeId)) return true; @@ -1862,6 +1884,126 @@ bool QMetaType::convert(const void *from, int fromTypeId, void *to, int toTypeId } /*! + Returns \c true if QMetaType::convert can convert from \a fromType to + \a toType. + + The following conversions are supported by Qt: + + \table + \header \li Type \li Automatically Cast To + \row \li \l QMetaType::Bool \li \l QMetaType::QChar, \l QMetaType::Double, + \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString, + \l QMetaType::UInt, \l QMetaType::ULongLong + \row \li \l QMetaType::QByteArray \li \l QMetaType::Double, + \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString, + \l QMetaType::UInt, \l QMetaType::ULongLong, \l QMetaType::QUuid + \row \li \l QMetaType::QChar \li \l QMetaType::Bool, \l QMetaType::Int, + \l QMetaType::UInt, \l QMetaType::LongLong, \l QMetaType::ULongLong + \row \li \l QMetaType::QColor \li \l QMetaType::QString + \row \li \l QMetaType::QDate \li \l QMetaType::QDateTime, + \l QMetaType::QString + \row \li \l QMetaType::QDateTime \li \l QMetaType::QDate, + \l QMetaType::QString, \l QMetaType::QTime + \row \li \l QMetaType::Double \li \l QMetaType::Bool, \l QMetaType::Int, + \l QMetaType::LongLong, \l QMetaType::QString, \l QMetaType::UInt, + \l QMetaType::ULongLong + \row \li \l QMetaType::QFont \li \l QMetaType::QString + \row \li \l QMetaType::Int \li \l QMetaType::Bool, \l QMetaType::QChar, + \l QMetaType::Double, \l QMetaType::LongLong, \l QMetaType::QString, + \l QMetaType::UInt, \l QMetaType::ULongLong + \row \li \l QMetaType::QKeySequence \li \l QMetaType::Int, + \l QMetaType::QString + \row \li \l QMetaType::QVariantList \li \l QMetaType::QStringList (if the + list's items can be converted to QStrings) + \row \li \l QMetaType::LongLong \li \l QMetaType::Bool, + \l QMetaType::QByteArray, \l QMetaType::QChar, \l QMetaType::Double, + \l QMetaType::Int, \l QMetaType::QString, \l QMetaType::UInt, + \l QMetaType::ULongLong + \row \li \l QMetaType::QPoint \li QMetaType::QPointF + \row \li \l QMetaType::QRect \li QMetaType::QRectF + \row \li \l QMetaType::QString \li \l QMetaType::Bool, + \l QMetaType::QByteArray, \l QMetaType::QChar, \l QMetaType::QColor, + \l QMetaType::QDate, \l QMetaType::QDateTime, \l QMetaType::Double, + \l QMetaType::QFont, \l QMetaType::Int, \l QMetaType::QKeySequence, + \l QMetaType::LongLong, \l QMetaType::QStringList, \l QMetaType::QTime, + \l QMetaType::UInt, \l QMetaType::ULongLong, \l QMetaType::QUuid + \row \li \l QMetaType::QStringList \li \l QMetaType::QVariantList, + \l QMetaType::QString (if the list contains exactly one item) + \row \li \l QMetaType::QTime \li \l QMetaType::QString + \row \li \l QMetaType::UInt \li \l QMetaType::Bool, \l QMetaType::QChar, + \l QMetaType::Double, \l QMetaType::Int, \l QMetaType::LongLong, + \l QMetaType::QString, \l QMetaType::ULongLong + \row \li \l QMetaType::ULongLong \li \l QMetaType::Bool, + \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int, + \l QMetaType::LongLong, \l QMetaType::QString, \l QMetaType::UInt + \row \li \l QMetaType::QUuid \li \l QMetaType::QByteArray, \l QMetaType::QString + \endtable + + Casting between primitive type (int, float, bool etc.) is supported. + + Converting between pointers of types derived from QObject will also return true for this + function if a qobject_cast from the type described by \a fromType to the type described + by \a toType would succeed. + + A cast from a sequential container will also return true for this + function if the \a toType is QVariantList. + + 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() +*/ +bool QMetaType::canConvert(const QMetaType &fromType, const QMetaType &toType) +{ + int fromTypeId = fromType.id(); + int toTypeId = toType.id(); + + if (fromTypeId == UnknownType || toTypeId == UnknownType) + return false; + + if (fromTypeId == toTypeId) + return true; + + if (auto moduleHelper = qModuleHelperForType(qMax(fromTypeId, toTypeId))) { + if (moduleHelper->convert(nullptr, fromTypeId, nullptr, toTypeId)) + return true; + } + const QMetaType::ConverterFunction * const f = + customTypesConversionRegistry()->function(qMakePair(fromTypeId, toTypeId)); + if (f) + return true; + + if (fromType.flags() & QMetaType::IsEnumeration) { + if (toTypeId == QMetaType::QString || toTypeId == QMetaType::QByteArray) + return true; + return QMetaType::canConvert(QMetaType(LongLong), toType); + } + if (toType.flags() & QMetaType::IsEnumeration) { + if (fromTypeId == QMetaType::QString || fromTypeId == QMetaType::QByteArray) + return true; + return QMetaType::canConvert(fromType, QMetaType(LongLong)); + } + if (toTypeId == Nullptr && fromType.flags() & QMetaType::IsPointer) + return true; +#ifndef QT_BOOTSTRAPPED + if (canConvertMetaObject(fromType, toType)) + return true; +#endif + + return false; +} + +/*! + bool QMetaType::compare(const void *lhs, const void *rhs, int typeId, int* result) + \deprecated Use the non-static compare method instead + + Compares the objects at \a lhs and \a rhs. Both objects need to be of type \a typeId. + \a result is set to less than, equal to or greater than zero, if \a lhs is less than, equal to + or greater than \a rhs. Returns \c true, if the comparison succeeded, otherwise \c false. +*/ + +/*! \fn bool QMetaType::hasRegisteredConverterFunction() Returns \c true, if the meta type system has a registered conversion from type From to type To. \since 5.2 diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index b4217bc3a1..4a3ed1affc 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -524,6 +524,7 @@ public: #endif static bool convert(const void *from, int fromTypeId, void *to, int toTypeId); + static bool canConvert(const QMetaType &fromType, const QMetaType &toType); #if QT_DEPRECATED_SINCE(6, 0) QT_DEPRECATED_VERSION_6_0 static bool compare(const void *lhs, const void *rhs, int typeId, int *result) diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 4f0664dc28..c16e4a0e06 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1962,219 +1962,17 @@ QVariantList QVariant::toList() const return qVariantToHelper<QVariantList>(d); } - -static const quint32 qCanConvertMatrix[QMetaType::LastCoreType + 1] = -{ -/*Invalid*/ 0, - -/*Bool*/ 1 << QMetaType::Double | 1 << QMetaType::Int | 1 << QMetaType::UInt - | 1 << QMetaType::LongLong | 1 << QMetaType::ULongLong | 1 << QMetaType::QByteArray - | 1 << QMetaType::QString | 1 << QMetaType::QChar, - -/*Int*/ 1 << QMetaType::UInt | 1 << QMetaType::QString | 1 << QMetaType::Double - | 1 << QMetaType::Bool | 1 << QMetaType::LongLong | 1 << QMetaType::ULongLong - | 1 << QMetaType::QChar | 1 << QMetaType::QByteArray | 1 << QMetaType::Int, - -/*UInt*/ 1 << QMetaType::Int | 1 << QMetaType::QString | 1 << QMetaType::Double - | 1 << QMetaType::Bool | 1 << QMetaType::LongLong | 1 << QMetaType::ULongLong - | 1 << QMetaType::QChar | 1 << QMetaType::QByteArray, - -/*LLong*/ 1 << QMetaType::Int | 1 << QMetaType::QString | 1 << QMetaType::Double - | 1 << QMetaType::Bool | 1 << QMetaType::UInt | 1 << QMetaType::ULongLong - | 1 << QMetaType::QChar | 1 << QMetaType::QByteArray, - -/*ULlong*/ 1 << QMetaType::Int | 1 << QMetaType::QString | 1 << QMetaType::Double - | 1 << QMetaType::Bool | 1 << QMetaType::UInt | 1 << QMetaType::LongLong - | 1 << QMetaType::QChar | 1 << QMetaType::QByteArray, - -/*double*/ 1 << QMetaType::Int | 1 << QMetaType::QString | 1 << QMetaType::ULongLong - | 1 << QMetaType::Bool | 1 << QMetaType::UInt | 1 << QMetaType::LongLong - | 1 << QMetaType::QByteArray, - -/*QChar*/ 1 << QMetaType::Int | 1 << QMetaType::UInt | 1 << QMetaType::LongLong - | 1 << QMetaType::ULongLong, - -/*QMap*/ 0, - -/*QList*/ 1 << QMetaType::QStringList, - -/*QString*/ 1 << QMetaType::QStringList | 1 << QMetaType::QByteArray | 1 << QMetaType::Int - | 1 << QMetaType::UInt | 1 << QMetaType::Bool | 1 << QMetaType::Double - | 1 << QMetaType::QDate | 1 << QMetaType::QTime | 1 << QMetaType::QDateTime - | 1 << QMetaType::LongLong | 1 << QMetaType::ULongLong | 1 << QMetaType::QChar - | 1 << QMetaType::QUrl | 1 << QMetaType::QUuid, - -/*QStringList*/ 1 << QMetaType::QVariantList | 1 << QMetaType::QString, - -/*QByteArray*/ 1 << QMetaType::QString | 1 << QMetaType::Int | 1 << QMetaType::UInt | 1 << QMetaType::Bool - | 1 << QMetaType::Double | 1 << QMetaType::LongLong | 1 << QMetaType::ULongLong - | 1 << QMetaType::QUuid, - -/*QBitArray*/ 0, - -/*QDate*/ 1 << QMetaType::QString | 1 << QMetaType::QDateTime, - -/*QTime*/ 1 << QMetaType::QString | 1 << QMetaType::QDateTime, - -/*QDateTime*/ 1 << QMetaType::QString | 1 << QMetaType::QDate, - -/*QUrl*/ 1 << QMetaType::QString, - -/*QLocale*/ 0, - -/*QRect*/ 1 << QMetaType::QRectF, - -/*QRectF*/ 1 << QMetaType::QRect, - -/*QSize*/ 1 << QMetaType::QSizeF, - -/*QSizeF*/ 1 << QMetaType::QSize, - -/*QLine*/ 1 << QMetaType::QLineF, - -/*QLineF*/ 1 << QMetaType::QLine, - -/*QPoint*/ 1 << QMetaType::QPointF, - -/*QPointF*/ 1 << QMetaType::QPoint, - -/*unused, was: QRegExp*/ 0, - -/*QHash*/ 0, - -/*QEasingCurve*/ 0, - -/*QUuid*/ 1 << QMetaType::QString | 1 << QMetaType::QByteArray, -}; -static const size_t qCanConvertMatrixMaximumTargetType = 8 * sizeof(*qCanConvertMatrix); - -#ifndef QT_BOOTSTRAPPED -/* - Returns \c true if from inherits to. -*/ -static bool canConvertMetaObject(const QMetaObject *from, const QMetaObject *to) -{ - if (from && to == &QObject::staticMetaObject) - return true; - - while (from) { - if (from == to) - return true; - from = from->superClass(); - } - - return false; -} -#endif - -static bool canConvertMetaObject(int fromId, int toId, QObject *fromObject) -{ -#ifndef QT_BOOTSTRAPPED - QMetaType toType(toId); - if ((QMetaType::typeFlags(fromId) & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) { - if (!fromObject) - return true; - return canConvertMetaObject(fromObject->metaObject(), toType.metaObject()); - } -#else - Q_UNUSED(fromId); - Q_UNUSED(toId); - Q_UNUSED(fromObject); -#endif - return false; -} - - /*! Returns \c true if the variant's type can be cast to the requested type, \a targetTypeId. Such casting is done automatically when calling the toInt(), toBool(), ... methods. - The following casts are done automatically: - - \table - \header \li Type \li Automatically Cast To - \row \li \l QMetaType::Bool \li \l QMetaType::QChar, \l QMetaType::Double, - \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString, - \l QMetaType::UInt, \l QMetaType::ULongLong - \row \li \l QMetaType::QByteArray \li \l QMetaType::Double, - \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString, - \l QMetaType::UInt, \l QMetaType::ULongLong, \l QMetaType::QUuid - \row \li \l QMetaType::QChar \li \l QMetaType::Bool, \l QMetaType::Int, - \l QMetaType::UInt, \l QMetaType::LongLong, \l QMetaType::ULongLong - \row \li \l QMetaType::QColor \li \l QMetaType::QString - \row \li \l QMetaType::QDate \li \l QMetaType::QDateTime, - \l QMetaType::QString - \row \li \l QMetaType::QDateTime \li \l QMetaType::QDate, - \l QMetaType::QString, \l QMetaType::QTime - \row \li \l QMetaType::Double \li \l QMetaType::Bool, \l QMetaType::Int, - \l QMetaType::LongLong, \l QMetaType::QString, \l QMetaType::UInt, - \l QMetaType::ULongLong - \row \li \l QMetaType::QFont \li \l QMetaType::QString - \row \li \l QMetaType::Int \li \l QMetaType::Bool, \l QMetaType::QChar, - \l QMetaType::Double, \l QMetaType::LongLong, \l QMetaType::QString, - \l QMetaType::UInt, \l QMetaType::ULongLong - \row \li \l QMetaType::QKeySequence \li \l QMetaType::Int, - \l QMetaType::QString - \row \li \l QMetaType::QVariantList \li \l QMetaType::QStringList (if the - list's items can be converted to QStrings) - \row \li \l QMetaType::LongLong \li \l QMetaType::Bool, - \l QMetaType::QByteArray, \l QMetaType::QChar, \l QMetaType::Double, - \l QMetaType::Int, \l QMetaType::QString, \l QMetaType::UInt, - \l QMetaType::ULongLong - \row \li \l QMetaType::QPoint \li QMetaType::QPointF - \row \li \l QMetaType::QRect \li QMetaType::QRectF - \row \li \l QMetaType::QString \li \l QMetaType::Bool, - \l QMetaType::QByteArray, \l QMetaType::QChar, \l QMetaType::QColor, - \l QMetaType::QDate, \l QMetaType::QDateTime, \l QMetaType::Double, - \l QMetaType::QFont, \l QMetaType::Int, \l QMetaType::QKeySequence, - \l QMetaType::LongLong, \l QMetaType::QStringList, \l QMetaType::QTime, - \l QMetaType::UInt, \l QMetaType::ULongLong, \l QMetaType::QUuid - \row \li \l QMetaType::QStringList \li \l QMetaType::QVariantList, - \l QMetaType::QString (if the list contains exactly one item) - \row \li \l QMetaType::QTime \li \l QMetaType::QString - \row \li \l QMetaType::UInt \li \l QMetaType::Bool, \l QMetaType::QChar, - \l QMetaType::Double, \l QMetaType::Int, \l QMetaType::LongLong, - \l QMetaType::QString, \l QMetaType::ULongLong - \row \li \l QMetaType::ULongLong \li \l QMetaType::Bool, - \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int, - \l QMetaType::LongLong, \l QMetaType::QString, \l QMetaType::UInt - \row \li \l QMetaType::QUuid \li \l QMetaType::QByteArray, \l QMetaType::QString - \endtable - - A QVariant containing a pointer to a type derived from QObject will also return true for this - function if a qobject_cast to the type described by \a targetTypeId would succeed. Note that - this only works for QObject subclasses which use the Q_OBJECT macro. - - A QVariant containing a sequential container will also return true for this - function if the \a targetTypeId is QVariantList. It is possible to iterate over - the contents of the container without extracting it as a (copied) QVariantList: - - \snippet code/src_corelib_kernel_qvariant.cpp 9 - - This requires that the value_type of the container is itself a metatype. - - Similarly, a QVariant containing a sequential container will also return true for this - function the \a targetTypeId is QVariantHash or QVariantMap. It is possible to iterate over - the contents of the container without extracting it as a (copied) QVariantHash or QVariantMap: - - \snippet code/src_corelib_kernel_qvariant.cpp 10 - - \sa convert(), QSequentialIterable, Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(), QAssociativeIterable, - Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE() + \sa QMetaType::canConvert() */ bool QVariant::canConvert(int targetTypeId) const { - if (d.typeId() == targetTypeId) - return true; - -#if QT_CONFIG(itemmodel) - if ((targetTypeId == QMetaType::QModelIndex - && d.typeId() == QMetaType::QPersistentModelIndex) - || (targetTypeId == QMetaType::QPersistentModelIndex - && d.typeId() == QMetaType::QModelIndex)) + if (d.typeId() == targetTypeId && targetTypeId != QMetaType::UnknownType) return true; -#endif if (targetTypeId == QMetaType::QVariantList && (d.typeId() == QMetaType::QVariantList || d.typeId() == QMetaType::QStringList @@ -2197,193 +1995,7 @@ bool QVariant::canConvert(int targetTypeId) const return true; } - if ((d.typeId() >= QMetaType::LastCoreType|| targetTypeId >= QMetaType::LastCoreType) - && QMetaType::hasRegisteredConverterFunction(d.typeId(), targetTypeId)) { - return true; - } - - // TODO Reimplement this function, currently it works but it is a historical mess. - uint currentType = d.typeId(); - if (currentType == QMetaType::SChar || currentType == QMetaType::Char) - currentType = QMetaType::UInt; - if (targetTypeId == QMetaType::SChar || currentType == QMetaType::Char) - targetTypeId = QMetaType::UInt; - if (currentType == QMetaType::Short || currentType == QMetaType::UShort) - currentType = QMetaType::Int; - if (targetTypeId == QMetaType::Short || currentType == QMetaType::UShort) - targetTypeId = QMetaType::Int; - if (currentType == QMetaType::Float) - currentType = QMetaType::Double; - if (targetTypeId == QMetaType::Float) - targetTypeId = QMetaType::Double; - - if (currentType == uint(targetTypeId)) - return true; - - if (targetTypeId < 0) - return false; - if (targetTypeId >= QMetaType::User) { - if (QMetaType::typeFlags(targetTypeId) & QMetaType::IsEnumeration) { - targetTypeId = QMetaType::Int; - } else { - return canConvertMetaObject(currentType, targetTypeId, d.get<QObject *>()); - } - } - - if (currentType == QMetaType::QJsonValue || targetTypeId == QMetaType::QJsonValue) { - switch (currentType == QMetaType::QJsonValue ? targetTypeId : currentType) { - case QMetaType::Nullptr: - case QMetaType::QString: - case QMetaType::Bool: - case QMetaType::Int: - case QMetaType::UInt: - case QMetaType::Double: - case QMetaType::Float: - case QMetaType::ULong: - case QMetaType::Long: - case QMetaType::LongLong: - case QMetaType::ULongLong: - case QMetaType::UShort: - case QMetaType::UChar: - case QMetaType::Char: - case QMetaType::SChar: - case QMetaType::Short: - case QMetaType::QVariantList: - case QMetaType::QVariantMap: - case QMetaType::QVariantHash: - case QMetaType::QCborValue: - case QMetaType::QCborArray: - case QMetaType::QCborMap: - return true; - default: - return false; - } - } - if (currentType == QMetaType::QJsonArray) - return targetTypeId == QMetaType::QVariantList || targetTypeId == QMetaType::QCborValue - || targetTypeId == QMetaType::QCborArray; - if (currentType == QMetaType::QJsonObject) - return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash - || targetTypeId == QMetaType::QCborValue || targetTypeId == QMetaType::QCborMap; - - if (currentType == QMetaType::QCborValue || targetTypeId == QMetaType::QCborValue) { - switch (currentType == QMetaType::QCborValue ? targetTypeId : currentType) { - case QMetaType::UnknownType: - case QMetaType::Nullptr: - case QMetaType::Bool: - case QMetaType::Int: - case QMetaType::UInt: - case QMetaType::Double: - case QMetaType::Float: - case QMetaType::ULong: - case QMetaType::Long: - case QMetaType::LongLong: - case QMetaType::ULongLong: - case QMetaType::UShort: - case QMetaType::UChar: - case QMetaType::Char: - case QMetaType::SChar: - case QMetaType::Short: - case QMetaType::QString: - case QMetaType::QByteArray: - case QMetaType::QDateTime: - case QMetaType::QUrl: -#if QT_CONFIG(regularexpression) - case QMetaType::QRegularExpression: -#endif - case QMetaType::QUuid: - case QMetaType::QVariantList: - case QMetaType::QVariantMap: - case QMetaType::QVariantHash: - case QMetaType::QJsonValue: - case QMetaType::QJsonArray: - case QMetaType::QJsonObject: - case QMetaType::QJsonDocument: - case QMetaType::QCborArray: - case QMetaType::QCborMap: - case QMetaType::QCborSimpleType: - return true; - default: - return false; - } - } - if (currentType == QMetaType::QCborArray) - return targetTypeId == QMetaType::QVariantList || targetTypeId == QMetaType::QCborValue - || targetTypeId == QMetaType::QJsonArray; - if (currentType == QMetaType::QCborMap) - return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash - || targetTypeId == QMetaType::QCborValue || targetTypeId == QMetaType::QJsonObject; - - // FIXME It should be LastCoreType intead of Uuid - if (currentType > int(QMetaType::QUuid) || targetTypeId > int(QMetaType::QUuid)) { - switch (uint(targetTypeId)) { - case QVariant::Int: -#if QT_CONFIG(shortcut) - if (currentType == QVariant::KeySequence) - return true; - Q_FALLTHROUGH(); -#endif - case QVariant::UInt: - case QVariant::LongLong: - case QVariant::ULongLong: - return currentType == QMetaType::ULong - || currentType == QMetaType::Long - || currentType == QMetaType::UShort - || currentType == QMetaType::UChar - || currentType == QMetaType::Char - || currentType == QMetaType::SChar - || currentType == QMetaType::Short - || QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration; - case QVariant::Image: - return currentType == QVariant::Pixmap || currentType == QVariant::Bitmap; - case QVariant::Pixmap: - return currentType == QVariant::Image || currentType == QVariant::Bitmap - || currentType == QVariant::Brush; - case QVariant::Bitmap: - return currentType == QVariant::Pixmap || currentType == QVariant::Image; - case QVariant::ByteArray: - return currentType == QVariant::Color || currentType == QMetaType::Nullptr - || ((QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration) && QMetaType::metaObjectForType(currentType)); - case QVariant::String: - return currentType == QVariant::Font - || currentType == QVariant::Color || currentType == QMetaType::Nullptr -#if QT_CONFIG(shortcut) - || currentType == QVariant::KeySequence -#endif - || ((QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration) && QMetaType::metaObjectForType(currentType)); -#if QT_CONFIG(shortcut) - case QVariant::KeySequence: - return currentType == QVariant::String || currentType == QVariant::Int; -#endif - case QVariant::Font: - return currentType == QVariant::String; - case QVariant::Color: - return currentType == QVariant::String || currentType == QVariant::ByteArray - || currentType == QVariant::Brush; - case QVariant::Brush: - return currentType == QVariant::Color || currentType == QVariant::Pixmap; - case QMetaType::Long: - case QMetaType::Char: - case QMetaType::SChar: - case QMetaType::UChar: - case QMetaType::ULong: - case QMetaType::Short: - case QMetaType::UShort: - return currentType == QVariant::Int - || (currentType < qCanConvertMatrixMaximumTargetType - && qCanConvertMatrix[QVariant::Int] & (1U << currentType)) - || QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration; - case QMetaType::QObjectStar: - return canConvertMetaObject(currentType, targetTypeId, d.get<QObject *>()); - default: - return false; - } - } - - if (targetTypeId == String && currentType == StringList) - return d.get<QStringList>().count() == 1; - return currentType < qCanConvertMatrixMaximumTargetType - && qCanConvertMatrix[targetTypeId] & (1U << currentType); + return QMetaType::canConvert(d.type(), QMetaType(targetTypeId)); } /*! @@ -2409,7 +2021,7 @@ bool QVariant::canConvert(int targetTypeId) const bool QVariant::convert(int targetTypeId) { if (d.typeId() == targetTypeId) - return true; + return (targetTypeId != QMetaType::UnknownType); QVariant oldValue = *this; diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index aa893309e8..a84825d1e6 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -929,7 +929,8 @@ void tst_QSettings::testIniParsing() if ( settings.status() == QSettings::NoError ) { // else no point proceeding QVariant v = settings.value(key); - QVERIFY(v.canConvert(expect.type())); + if (expect.isValid()) + QVERIFY(v.canConvert(expect.type())); // check some types so as to give prettier error messages if ( v.type() == QVariant::String ) { QCOMPARE(v.toString(), expect.toString()); diff --git a/tests/auto/corelib/kernel/qvariant/CMakeLists.txt b/tests/auto/corelib/kernel/qvariant/CMakeLists.txt index f1baaefe43..8b122a48e2 100644 --- a/tests/auto/corelib/kernel/qvariant/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qvariant/CMakeLists.txt @@ -13,6 +13,7 @@ qt_add_test(tst_qvariant ../../../other/qvariant_common PUBLIC_LIBRARIES Qt::CorePrivate + Qt::Gui ) # Resources: diff --git a/tests/auto/corelib/kernel/qvariant/qvariant.pro b/tests/auto/corelib/kernel/qvariant/qvariant.pro index a620be0091..7416023808 100644 --- a/tests/auto/corelib/kernel/qvariant/qvariant.pro +++ b/tests/auto/corelib/kernel/qvariant/qvariant.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qvariant -QT = core-private testlib +QT = core-private gui testlib INCLUDEPATH += $$PWD/../../../other/qvariant_common SOURCES = tst_qvariant.cpp RESOURCES += qvariant.qrc diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index a722e53f48..d4af02baf1 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -477,7 +477,7 @@ void tst_QVariant::canConvert_data() << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; var = QVariant(); QTest::newRow("Invalid") - << var << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N; + << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N; var = QVariant(QList<QVariant>()); QTest::newRow("List") << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N; @@ -520,12 +520,12 @@ void tst_QVariant::canConvert_data() var = QVariant::fromValue<signed char>(-1); QTest::newRow("SChar") << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; - var = QVariant((short)-3); + var = QVariant::fromValue((short)-3); QTest::newRow("Short") - << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; - var = QVariant((ushort)7); + << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; + var = QVariant::fromValue((ushort)7); QTest::newRow("UShort") - << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; + << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; var = QVariant::fromValue<QJsonValue>(QJsonValue(QStringLiteral("hello"))); QTest::newRow("JsonValue") << var << N << N << Y << N << N << N << N << N << N << Y << N << N << Y << N << N << Y << Y << Y << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; @@ -2705,17 +2705,17 @@ void tst_QVariant::canConvertQStringList_data() const QTest::addColumn<QStringList>("input"); QTest::addColumn<QString>("result"); - QTest::newRow("An empty list") << false << QStringList() << QString(); + QTest::newRow("An empty list") << true << QStringList() << QString(); QTest::newRow("A single item") << true << QStringList(QLatin1String("foo")) << QString::fromLatin1("foo"); QTest::newRow("A single, but empty item") << true << QStringList(QString()) << QString(); QStringList l; l << "a" << "b"; - QTest::newRow("Two items") << false << l << QString(); + QTest::newRow("Two items") << true << l << QString(); l << "c"; - QTest::newRow("Three items") << false << l << QString(); + QTest::newRow("Three items") << true << l << QString(); } template<typename T> void convertMetaType() |