/*QUuid*/ 1 << QVariant::String
};
+#ifndef QT_BOOTSTRAPPED
+/*!
+ Returns 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))
+ return canConvertMetaObject(fromObject->metaObject(), toType.metaObject());
+#else
+ Q_UNUSED(fromId);
+ Q_UNUSED(toId);
+ Q_UNUSED(fromObject);
+#endif
+ return false;
+}
+
+
/*!
Returns true if the variant's type can be cast to the requested
type, \a targetTypeId. Such casting is done automatically when calling the
\row \li \l ULongLong \li \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt
\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.
+
\sa convert()
*/
bool QVariant::canConvert(int targetTypeId) const
if (currentType == uint(targetTypeId))
return true;
- if (targetTypeId < 0 || targetTypeId >= QMetaType::User)
+ if (targetTypeId < 0)
return false;
+ if (targetTypeId >= QMetaType::User)
+ return canConvertMetaObject(currentType, targetTypeId, d.data.o);
// FIXME It should be LastCoreType intead of Uuid
if (currentType > int(QMetaType::QUuid) || targetTypeId > int(QMetaType::QUuid)) {
case QMetaType::Short:
case QMetaType::UShort:
return qCanConvertMatrix[QVariant::Int] & (1 << currentType) || currentType == QVariant::Int;
+ case QMetaType::QWidgetStar:
+ case QMetaType::QObjectStar:
+ return canConvertMetaObject(currentType, targetTypeId, d.data.o);
default:
return false;
}
done, the variant is cleared. Returns true if the current type of
the variant was successfully cast; otherwise returns false.
+ A QVariant containing a pointer to a type derived from QObject will also convert
+ and 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.
+
\warning For historical reasons, converting a null QVariant results
in a null value of the desired type (e.g., an empty string for
QString) and a result of false.
if (oldValue.isNull())
return false;
+ if ((QMetaType::typeFlags(d.type) & QMetaType::PointerToQObject) && (QMetaType::typeFlags(targetTypeId) & QMetaType::PointerToQObject)) {
+ create(targetTypeId, &oldValue.d.data.o);
+ return true;
+ }
+
bool isOk = true;
if (!handlerManager[d.type]->convert(&oldValue.d, targetTypeId, data(), &isOk))
isOk = false;
\snippet code/src_corelib_kernel_qvariant.cpp 5
+ If the QVariant contains a pointer to a type derived from QObject then
+ \c{T} may be any QObject type. If the pointer stored in the QVariant can be
+ qobject_cast to T, then that result is returned. Otherwise a null pointer is
+ returned. Note that this only works for QObject subclasses which use the
+ Q_OBJECT macro.
+
\sa setValue(), fromValue(), canConvert()
*/
\snippet code/src_corelib_kernel_qvariant.cpp 6
+ A QVariant containing a pointer to a type derived from QObject will also return true for this
+ function if a qobject_cast to the template type \c{T} would succeed. Note that this only works
+ for QObject subclasses which use the Q_OBJECT macro.
+
\sa convert()
*/
QCOMPARE(o != 0, success);
if (success) {
QCOMPARE(o->objectName(), QString::fromLatin1("Hello"));
+ QVERIFY(data.canConvert<QObject*>());
+ QVERIFY(data.canConvert(QMetaType::QObjectStar));
+ QVERIFY(data.canConvert(::qMetaTypeId<QObject*>()));
+ QVERIFY(data.value<QObject*>());
+ QVERIFY(data.convert(QMetaType::QObjectStar));
+ QCOMPARE(data.userType(), int(QMetaType::QObjectStar));
+ } else {
+ QVERIFY(!data.canConvert<QObject*>());
+ QVERIFY(!data.canConvert(QMetaType::QObjectStar));
+ QVERIFY(!data.canConvert(::qMetaTypeId<QObject*>()));
+ QVERIFY(!data.value<QObject*>());
+ QVERIFY(!data.convert(QMetaType::QObjectStar));
+ QVERIFY(data.userType() != QMetaType::QObjectStar);
}
}