Update keyToValue and keysToValue in QMetaEnum
authorLiang Qi <liang.qi@nokia.com>
Tue, 18 Oct 2011 09:06:42 +0000 (11:06 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 19 Oct 2011 20:27:09 +0000 (22:27 +0200)
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>
src/corelib/kernel/qmetaobject.cpp
src/corelib/kernel/qmetaobject.h
tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp

index 494e7af..9f404f8 100644 (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())
index df6afa8..47ccc9e 100644 (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; }
index a813a91..29b2af4 100644 (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"));
 }