Update keyToValue and keysToValue in QMetaEnum

Add a ok return value for whether found or not.

Task-number: QTBUG-21672
Reviewed-by: Olivier Goffart
Change-Id: Ic0ea7455dccf1ac91705bcc1479444eb4091ded3
Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
Reviewed-by: Liang Qi <liang.qi@nokia.com>
This commit is contained in:
Liang Qi 2011-10-18 11:06:42 +02:00 committed by Qt by Nokia
parent 15fee6e744
commit b1b843dcf5
3 changed files with 87 additions and 28 deletions

View File

@ -1890,12 +1890,17 @@ const char *QMetaEnum::scope() const
Returns the integer value of the given enumeration \a key, or -1
if \a key is not defined.
If \a key is not defined, *\a{ok} is set to false; otherwise
*\a{ok} is set to true.
For flag types, use keysToValue().
\sa valueToKey(), isFlag(), keysToValue()
*/
int QMetaEnum::keyToValue(const char *key) const
int QMetaEnum::keyToValue(const char *key, bool *ok) const
{
if (ok != 0)
*ok = false;
if (!mobj || !key)
return -1;
uint scope = 0;
@ -1909,10 +1914,14 @@ int QMetaEnum::keyToValue(const char *key) const
}
int count = mobj->d.data[handle + 2];
int data = mobj->d.data[handle + 3];
for (int i = 0; i < count; ++i)
for (int i = 0; i < count; ++i) {
if ((!scope || (qstrlen(mobj->d.stringdata) == scope && strncmp(qualified_key, mobj->d.stringdata, scope) == 0))
&& strcmp(key, mobj->d.stringdata + mobj->d.data[data + 2*i]) == 0)
&& strcmp(key, mobj->d.stringdata + mobj->d.data[data + 2*i]) == 0) {
if (ok != 0)
*ok = true;
return mobj->d.data[data + 2*i + 1];
}
}
return -1;
}
@ -1941,13 +1950,22 @@ const char* QMetaEnum::valueToKey(int value) const
the \a keys using the OR operator, or -1 if \a keys is not
defined. Note that the strings in \a keys must be '|'-separated.
If \a key is not defined, *\a{ok} is set to false; otherwise
*\a{ok} is set to true.
\sa isFlag(), valueToKey(), valueToKeys()
*/
int QMetaEnum::keysToValue(const char *keys) const
int QMetaEnum::keysToValue(const char *keys, bool *ok) const
{
if (!mobj)
if (ok != 0)
*ok = false;
if (!mobj || !keys)
return -1;
if (ok != 0)
*ok = true;
QStringList l = QString::fromLatin1(keys).split(QLatin1Char('|'));
if (l.isEmpty())
return 0;
//#### TODO write proper code, do not use QStringList
int value = 0;
int count = mobj->d.data[handle + 2];
@ -1971,8 +1989,11 @@ int QMetaEnum::keysToValue(const char *keys) const
value |= mobj->d.data[data + 2*i + 1];
break;
}
if (i < 0)
if (i < 0) {
if (ok != 0)
*ok = false;
value |= -1;
}
}
return value;
}
@ -2295,10 +2316,13 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
uint t = QVariant::Invalid;
if (isEnumType()) {
if (v.type() == QVariant::String) {
bool ok;
if (isFlagType())
v = QVariant(menum.keysToValue(value.toByteArray()));
v = QVariant(menum.keysToValue(value.toByteArray(), &ok));
else
v = QVariant(menum.keyToValue(value.toByteArray()));
v = QVariant(menum.keyToValue(value.toByteArray(), &ok));
if (!ok)
return false;
} else if (v.type() != QVariant::Int && v.type() != QVariant::UInt) {
int enumMetaTypeId = QMetaType::type(qualifiedName(menum));
if ((enumMetaTypeId == 0) || (v.userType() != enumMetaTypeId) || !v.constData())

View File

@ -158,9 +158,9 @@ public:
const char *scope() const;
int keyToValue(const char *key) const;
int keyToValue(const char *key, bool *ok = 0) const;
const char* valueToKey(int value) const;
int keysToValue(const char * keys) const;
int keysToValue(const char * keys, bool *ok = 0) const;
QByteArray valueToKeys(int value) const;
inline const QMetaObject *enclosingMetaObject() const { return mobj; }

View File

@ -62,6 +62,7 @@ namespace MyNamespace {
Q_PROPERTY(MyFlags myFlags READ myFlags WRITE setMyFlags)
Q_ENUMS(MyEnum)
Q_ENUMS(MyAnotherEnum)
Q_FLAGS(MyFlags)
public:
enum MyEnum {
@ -69,7 +70,11 @@ namespace MyNamespace {
MyEnum2,
MyEnum3
};
enum MyAnotherEnum {
MyAnotherEnum1 = 1,
MyAnotherEnum2 = 2,
MyAnotherEnum3 = -1
};
enum MyFlag {
MyFlag1 = 0x01,
MyFlag2 = 0x02,
@ -933,36 +938,66 @@ void tst_QMetaObject::customPropertyType()
void tst_QMetaObject::checkScope()
{
MyNamespace::MyClass obj;
bool ok;
const QMetaObject *mo = obj.metaObject();
QMetaEnum me = mo->enumerator(mo->indexOfEnumerator("MyEnum"));
QVERIFY(me.isValid());
QVERIFY(!me.isFlag());
QCOMPARE(QLatin1String(me.scope()), QLatin1String("MyNamespace::MyClass"));
QCOMPARE(me.keyToValue("MyNamespace::MyClass::MyEnum2"), 1);
QCOMPARE(me.keyToValue("MyClass::MyEnum2"), -1);
QCOMPARE(me.keyToValue("MyNamespace::MyEnum2"), -1);
QCOMPARE(me.keyToValue("MyEnum2"), 1);
QCOMPARE(me.keyToValue("MyEnum"), -1);
QCOMPARE(me.keyToValue("MyNamespace::MyClass::MyEnum2", &ok), 1);
QCOMPARE(ok, true);
QCOMPARE(me.keyToValue("MyClass::MyEnum2", &ok), -1);
QCOMPARE(ok, false);
QCOMPARE(me.keyToValue("MyNamespace::MyEnum2", &ok), -1);
QCOMPARE(ok, false);
QCOMPARE(me.keyToValue("MyEnum2", &ok), 1);
QCOMPARE(ok, true);
QCOMPARE(me.keyToValue("MyEnum", &ok), -1);
QCOMPARE(ok, false);
QCOMPARE(QLatin1String(me.valueToKey(1)), QLatin1String("MyEnum2"));
QMetaEnum me2 = mo->enumerator(mo->indexOfEnumerator("MyAnotherEnum"));
QVERIFY(me2.isValid());
QVERIFY(!me2.isFlag());
QCOMPARE(me2.keyToValue("MyAnotherEnum1", &ok), 1);
QCOMPARE(ok, true);
QCOMPARE(me2.keyToValue("MyAnotherEnum2", &ok), 2);
QCOMPARE(ok, true);
QCOMPARE(me2.keyToValue("MyAnotherEnum3", &ok), -1);
QCOMPARE(ok, true);
QCOMPARE(me2.keyToValue("MyAnotherEnum", &ok), -1);
QCOMPARE(ok, false);
QMetaEnum mf = mo->enumerator(mo->indexOfEnumerator("MyFlags"));
QVERIFY(mf.isValid());
QVERIFY(mf.isFlag());
QCOMPARE(QLatin1String(mf.scope()), QLatin1String("MyNamespace::MyClass"));
QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag2"), 2);
QCOMPARE(mf.keysToValue("MyClass::MyFlag2"), -1);
QCOMPARE(mf.keysToValue("MyNamespace::MyFlag2"), -1);
QCOMPARE(mf.keysToValue("MyFlag2"), 2);
QCOMPARE(mf.keysToValue("MyFlag"), -1);
QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag2", &ok), 2);
QCOMPARE(ok, true);
QCOMPARE(mf.keysToValue("MyClass::MyFlag2", &ok), -1);
QCOMPARE(ok, false);
QCOMPARE(mf.keysToValue("MyNamespace::MyFlag2", &ok), -1);
QCOMPARE(ok, false);
QCOMPARE(mf.keysToValue("MyFlag2", &ok), 2);
QCOMPARE(ok, true);
QCOMPARE(mf.keysToValue("MyFlag", &ok), -1);
QCOMPARE(ok, false);
QCOMPARE(QLatin1String(mf.valueToKey(2)), QLatin1String("MyFlag2"));
QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag1|MyNamespace::MyClass::MyFlag2"), 3);
QCOMPARE(mf.keysToValue("MyClass::MyFlag1|MyClass::MyFlag2"), -1);
QCOMPARE(mf.keysToValue("MyNamespace::MyFlag1|MyNamespace::MyFlag2"), -1);
QCOMPARE(mf.keysToValue("MyFlag1|MyFlag2"), 3);
QCOMPARE(mf.keysToValue("MyFlag2|MyFlag2"), 2);
QCOMPARE(mf.keysToValue("MyFlag1|MyNamespace::MyClass::MyFlag2"), 3);
QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag2|MyNamespace::MyClass::MyFlag2"), 2);
QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag1|MyNamespace::MyClass::MyFlag2", &ok), 3);
QCOMPARE(ok, true);
QCOMPARE(mf.keysToValue("MyClass::MyFlag1|MyClass::MyFlag2", &ok), -1);
QCOMPARE(ok, false);
QCOMPARE(mf.keysToValue("MyNamespace::MyFlag1|MyNamespace::MyFlag2", &ok), -1);
QCOMPARE(ok, false);
QCOMPARE(mf.keysToValue("MyFlag1|MyFlag2", &ok), 3);
QCOMPARE(ok, true);
QCOMPARE(mf.keysToValue("MyFlag2|MyFlag2", &ok), 2);
QCOMPARE(ok, true);
QCOMPARE(mf.keysToValue("MyFlag1|MyNamespace::MyClass::MyFlag2", &ok), 3);
QCOMPARE(ok, true);
QCOMPARE(mf.keysToValue("MyNamespace::MyClass::MyFlag2|MyNamespace::MyClass::MyFlag2", &ok), 2);
QCOMPARE(ok, true);
QCOMPARE(QLatin1String(mf.valueToKeys(3)), QLatin1String("MyFlag1|MyFlag2"));
}