diff options
author | Olivier Goffart <ogoffart@woboq.com> | 2014-08-10 18:22:52 +0200 |
---|---|---|
committer | Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> | 2015-02-15 08:48:01 +0000 |
commit | 0b7ec36816edd6093af37e005b20fe9561b4944e (patch) | |
tree | f69b644e9e26851a36f412492971e918ab2c2db2 /src | |
parent | 2b75c156b6f285398af2c4998d9f4181d273fdce (diff) |
Add conversion between Q_ENUMs and strings in QVariant
Change-Id: I9264a68d162cf20db0167dd3f976a007477786d1
Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qvariant.cpp | 74 |
1 files changed, 71 insertions, 3 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 248ca4923b..34f4c6884f 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com> +** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com> ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -57,6 +57,7 @@ #endif #include "private/qvariant_p.h" #include "qmetatype_p.h" +#include <qmetaobject.h> #ifndef QT_NO_GEOM_VARIANT #include "qsize.h" @@ -66,6 +67,7 @@ #endif #include <float.h> +#include <cstring> QT_BEGIN_NAMESPACE @@ -334,6 +336,27 @@ static const void *constData(const QVariant::Private &d) return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.c); } +#ifndef QT_NO_QOBJECT +/*! + \internal + returns a QMetaEnum for a given meta tape type id if possible +*/ +static QMetaEnum metaEnumFromType(int type) +{ + QMetaType t(type); + if (t.flags() & QMetaType::IsEnumeration) { + if (const QMetaObject *metaObject = t.metaObject()) { + const char *enumName = QMetaType::typeName(type); + const char *lastColon = std::strrchr(enumName, ':'); + if (lastColon) + enumName = lastColon + 1; + return metaObject->enumerator(metaObject->indexOfEnumerator(enumName)); + } + } + return QMetaEnum(); +} +#endif + /*! \internal @@ -433,6 +456,15 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) *str = v_cast<QUuid>(d)->toString(); break; default: +#ifndef QT_NO_QOBJECT + { + QMetaEnum en = metaEnumFromType(d->type); + if (en.isValid()) { + *str = QString::fromUtf8(en.valueToKeys(qConvertToNumber(d, ok))); + return *ok; + } + } +#endif return false; } break; @@ -601,6 +633,15 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) *ba = QByteArray(d->data.b ? "true" : "false"); break; default: +#ifndef QT_NO_QOBJECT + { + QMetaEnum en = metaEnumFromType(d->type); + if (en.isValid()) { + *ba = en.valueToKeys(qConvertToNumber(d, ok)); + return *ok; + } + } +#endif return false; } } @@ -861,6 +902,31 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) } break; default: +#ifndef QT_NO_QOBJECT + if (d->type == QVariant::String || d->type == QVariant::ByteArray) { + QMetaEnum en = metaEnumFromType(t); + if (en.isValid()) { + QByteArray keys = (d->type == QVariant::String) ? v_cast<QString>(d)->toUtf8() : *v_cast<QByteArray>(d); + int value = en.keysToValue(keys.constData(), ok); + if (*ok) { + switch (QMetaType::sizeOf(t)) { + case 1: + *static_cast<signed char *>(result) = value; + return true; + case 2: + *static_cast<qint16 *>(result) = value; + return true; + case 4: + *static_cast<qint32 *>(result) = value; + return true; + case 8: + *static_cast<qint64 *>(result) = value; + return true; + } + } + } + } +#endif return false; } return true; @@ -3006,10 +3072,12 @@ bool QVariant::canConvert(int targetTypeId) const case QVariant::Bitmap: return currentType == QVariant::Pixmap || currentType == QVariant::Image; case QVariant::ByteArray: - return currentType == QVariant::Color; + return currentType == QVariant::Color + || ((QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration) && QMetaType::metaObjectForType(currentType)); case QVariant::String: return currentType == QVariant::KeySequence || currentType == QVariant::Font - || currentType == QVariant::Color; + || currentType == QVariant::Color + || ((QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration) && QMetaType::metaObjectForType(currentType)); case QVariant::KeySequence: return currentType == QVariant::String || currentType == QVariant::Int; case QVariant::Font: |