From b1b843dcf5165f5b204adbd3cf36c0c8fa3605c0 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Tue, 18 Oct 2011 11:06:42 +0200 Subject: Update keyToValue and keysToValue in QMetaEnum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Liang Qi --- src/corelib/kernel/qmetaobject.cpp | 40 +++++++++--- src/corelib/kernel/qmetaobject.h | 4 +- .../corelib/kernel/qmetaobject/tst_qmetaobject.cpp | 71 ++++++++++++++++------ 3 files changed, 87 insertions(+), 28 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 494e7af141..9f404f80cb 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -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()) diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index df6afa8860..47ccc9e2b7 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -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; } diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index a813a917d7..29b2af44ed 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -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")); } -- cgit v1.2.3