return true;
int value = 0;
- bool ok;
+ bool ok = false;
if (type && toQmlType(obj) == type) {
// When these two match, we can short cut the search
}
} else {
// Otherwise we have to search the whole type
- // This matches the logic in QV8TypeWrapper
- QByteArray enumName = enumValue.toUtf8();
- const QMetaObject *metaObject = type ? type->baseMetaObject() : StaticQtMetaObject::get();
- ok = false;
- for (int ii = metaObject->enumeratorCount() - 1; !ok && ii >= 0; --ii) {
- QMetaEnum e = metaObject->enumerator(ii);
- value = e.keyToValue(enumName.constData(), &ok);
+ if (type) {
+ value = type->enumValue(QHashedStringRef(enumValue), &ok);
+ } else {
+ QByteArray enumName = enumValue.toUtf8();
+ const QMetaObject *metaObject = StaticQtMetaObject::get();
+ for (int ii = metaObject->enumeratorCount() - 1; !ok && ii >= 0; --ii) {
+ QMetaEnum e = metaObject->enumerator(ii);
+ value = e.keyToValue(enumName.constData(), &ok);
+ }
}
}
{
Q_ASSERT_X(ok, "QQmlCompiler::evaluateEnum", "ok must not be a null pointer");
*ok = false;
- QQmlType *type = 0;
+
if (scope != QLatin1String("Qt")) {
+ QQmlType *type = 0;
unit->imports().resolveType(scope, &type, 0, 0, 0, 0);
- if (!type)
- return -1;
-
+ return type ? type->enumValue(QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1;
}
- const QMetaObject *mo = type ? type->metaObject() : StaticQtMetaObject::get();
+
+ const QMetaObject *mo = StaticQtMetaObject::get();
int i = mo->enumeratorCount();
while (i--) {
int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok);
void init() const;
void initEnums() const;
+ void insertEnums(const QMetaObject *metaObject) const;
bool m_isInterface : 1;
const char *m_iid;
QWriteLocker lock(metaTypeDataLock());
if (m_isEnumSetup) return;
- const QMetaObject *metaObject = m_baseMetaObject;
- for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
+ insertEnums(m_baseMetaObject);
- QMetaEnum e = metaObject->enumerator(ii);
+ m_isEnumSetup = true;
+}
- for (int jj = 0; jj < e.keyCount(); ++jj)
- m_enums.insert(QString::fromUtf8(e.key(jj)), e.value(jj));
+void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
+{
+ // Add any enum values defined by 'related' classes
+ if (metaObject->d.relatedMetaObjects) {
+ const QMetaObject **related = metaObject->d.relatedMetaObjects;
+ if (related) {
+ while (*related)
+ insertEnums(*related++);
+ }
}
- m_isEnumSetup = true;
+ // Add any enum values defined by this class, overwriting any inherited values
+ for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
+ QMetaEnum e = metaObject->enumerator(ii);
+ for (int jj = 0; jj < e.keyCount(); ++jj)
+ m_enums.insert(QString::fromUtf8(e.key(jj)), e.value(jj));
+ }
}
QByteArray QQmlType::typeName() const
return d->m_index;
}
-int QQmlType::enumValue(const QHashedStringRef &name) const
+int QQmlType::enumValue(const QHashedStringRef &name, bool *ok) const
{
+ Q_ASSERT(ok);
+ *ok = true;
+
d->initEnums();
int *rv = d->m_enums.value(name);
- return rv?*rv:-1;
+ if (rv)
+ return *rv;
+
+ *ok = false;
+ return -1;
}
-int QQmlType::enumValue(const QHashedV8String &name) const
+int QQmlType::enumValue(const QHashedCStringRef &name, bool *ok) const
{
+ Q_ASSERT(ok);
+ *ok = true;
+
d->initEnums();
int *rv = d->m_enums.value(name);
- return rv?*rv:-1;
+ if (rv)
+ return *rv;
+
+ *ok = false;
+ return -1;
+}
+
+int QQmlType::enumValue(const QHashedV8String &name, bool *ok) const
+{
+ Q_ASSERT(ok);
+ *ok = true;
+
+ d->initEnums();
+
+ int *rv = d->m_enums.value(name);
+ if (rv)
+ return *rv;
+
+ *ok = false;
+ return -1;
}
QQmlTypeModule::QQmlTypeModule()
static CompareFunction anchorLineCompareFunction;
};
+class QHashedCStringRef;
class QHashedV8String;
class Q_QML_PRIVATE_EXPORT QQmlType
{
int index() const;
- int enumValue(const QHashedStringRef &) const;
- int enumValue(const QHashedV8String &) const;
+ int enumValue(const QHashedStringRef &, bool *ok) const;
+ int enumValue(const QHashedCStringRef &, bool *ok) const;
+ int enumValue(const QHashedV8String &, bool *ok) const;
private:
QQmlType *superType() const;
friend class QQmlTypePrivate;
QQmlType *type = resource->type;
if (QV8Engine::startsWithUpper(property)) {
- int value = type->enumValue(propertystring);
- if (-1 != value)
+ bool ok = false;
+ int value = type->enumValue(propertystring, &ok);
+ if (ok)
return v8::Integer::New(value);
// Fall through to return empty handle
MyTypeObject {
flagProperty: if(1) "FlagVal1 | FlagVal3"
enumProperty: if(1) "EnumVal2"
+ relatedEnumProperty: if(1) "RelatedValue"
stringProperty: if(1) "Hello World!"
uintProperty: if(1) 10
intProperty: if(1) -19
Component.onCompleted: {
flagProperty = "FlagVal1 | FlagVal3"
enumProperty = "EnumVal2"
+ relatedEnumProperty = "RelatedValue"
stringProperty = "Hello World!"
uintProperty = 10
intProperty = -19
import Qt.test 1.0 as Namespace
MyQmlObject {
+ // Enum property type
+ enumProperty: MyQmlObject.EnumValue2
+
+ // Enum property whose value is from a related type
+ relatedEnumProperty: MyQmlObject.RelatedValue
+
+ // Enum property whose value is defined in an unrelated type
+ unrelatedEnumProperty: MyTypeObject.RelatedValue
+
+ // Enum property whose value is defined in the Qt namespace
+ qtEnumProperty: Qt.CaseInsensitive
+
// Enums from non-namespaced type
property int a: MyQmlObject.EnumValue1
property int b: MyQmlObject.EnumValue2
// Test that enums don't mask attached properties
property int i: MyQmlObject.value
property int j: Namespace.MyQmlObject.value
+
+ // Enums from a related type
+ property int k: MyQmlObject.RelatedValue
+
+ // Enum values defined both in a type and a related type
+ property int l: MyQmlObject.MultiplyDefined
}
// -1 enum
property int j: MyQmlObject.EnumValue5
+ // Enums from a related type
+ property int k: MyQmlObject.RelatedValue
+
// Count the onChanged signals to see whether
// they're assigned as literals or via bindings
property int ac: 0
property int hc: 0
property int ic: 0
property int jc: 0
+ property int kc: 0
onAChanged: ac++
onBChanged: bc++
onHChanged: hc++
onIChanged: ic++
onJChanged: jc++
+ onKChanged: kc++
}
int m_value2;
};
+class MyEnumContainer : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(RelatedEnum)
+
+public:
+ enum RelatedEnum { RelatedInvalid = -1, RelatedValue = 42, MultiplyDefined = 666 };
+};
+
class MyQmlObject : public QObject
{
Q_OBJECT
Q_ENUMS(MyEnum)
Q_ENUMS(MyEnum2)
+ Q_ENUMS(MyEnum3)
+ Q_ENUMS(MyEnumContainer::RelatedEnum)
Q_PROPERTY(int deleteOnSet READ deleteOnSet WRITE setDeleteOnSet)
Q_PROPERTY(bool trueProperty READ trueProperty CONSTANT)
Q_PROPERTY(bool falseProperty READ falseProperty CONSTANT)
Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty NOTIFY intChanged)
Q_PROPERTY(QJSValue qjsvalue READ qjsvalue WRITE setQJSValue NOTIFY qjsvalueChanged)
Q_PROPERTY(QJSValue qjsvalueWithReset READ qjsvalue WRITE setQJSValue RESET resetQJSValue NOTIFY qjsvalueChanged)
+ Q_PROPERTY(MyEnum enumProperty READ enumProperty WRITE setEnumProperty)
+ Q_PROPERTY(MyEnumContainer::RelatedEnum relatedEnumProperty READ relatedEnumProperty WRITE setRelatedEnumProperty)
+ Q_PROPERTY(MyEnumContainer::RelatedEnum unrelatedEnumProperty READ unrelatedEnumProperty WRITE setUnrelatedEnumProperty)
+ Q_PROPERTY(MyEnum qtEnumProperty READ qtEnumProperty WRITE setQtEnumProperty)
public:
MyQmlObject(): myinvokableObject(0), m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13), m_intProperty(0), m_buttons(0) {}
enum MyEnum { EnumValue1 = 0, EnumValue2 = 1 };
enum MyEnum2 { EnumValue3 = 2, EnumValue4 = 3, EnumValue5 = -1 };
+ enum MyEnum3 { MultiplyDefined = 333 };
bool trueProperty() const { return true; }
bool falseProperty() const { return false; }
Q_INVOKABLE MyEnum2 getEnumValue() const { return EnumValue4; }
+ MyEnum enumPropertyValue;
+ MyEnum enumProperty() const {
+ return enumPropertyValue;
+ }
+ void setEnumProperty(MyEnum v) {
+ enumPropertyValue = v;
+ }
+
+ MyEnumContainer::RelatedEnum relatedEnumPropertyValue;
+ MyEnumContainer::RelatedEnum relatedEnumProperty() const {
+ return relatedEnumPropertyValue;
+ }
+ void setRelatedEnumProperty(MyEnumContainer::RelatedEnum v) {
+ relatedEnumPropertyValue = v;
+ }
+
+ MyEnumContainer::RelatedEnum unrelatedEnumPropertyValue;
+ MyEnumContainer::RelatedEnum unrelatedEnumProperty() const {
+ return unrelatedEnumPropertyValue;
+ }
+ void setUnrelatedEnumProperty(MyEnumContainer::RelatedEnum v) {
+ unrelatedEnumPropertyValue = v;
+ }
+
+ MyEnum qtEnumPropertyValue;
+ MyEnum qtEnumProperty() const {
+ return qtEnumPropertyValue;
+ }
+ void setQtEnumProperty(MyEnum v) {
+ qtEnumPropertyValue = v;
+ }
+
signals:
void basicSignal();
void argumentSignal(int a, QString b, qreal c, MyEnum2 d, Qt::MouseButtons e);
{
Q_OBJECT
Q_ENUMS(MyEnum)
+ Q_ENUMS(MyEnumContainer::RelatedEnum)
Q_FLAGS(MyFlags)
Q_PROPERTY(QString id READ id WRITE setId)
Q_PROPERTY(QQmlComponent *componentProperty READ componentProperty WRITE setComponentProperty)
Q_PROPERTY(MyFlags flagProperty READ flagProperty WRITE setFlagProperty)
Q_PROPERTY(MyEnum enumProperty READ enumProperty WRITE setEnumProperty)
+ Q_PROPERTY(MyEnumContainer::RelatedEnum relatedEnumProperty READ relatedEnumProperty WRITE setRelatedEnumProperty)
Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty)
Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty)
Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty)
enumPropertyValue = v;
}
+ MyEnumContainer::RelatedEnum relatedEnumPropertyValue;
+ MyEnumContainer::RelatedEnum relatedEnumProperty() const {
+ return relatedEnumPropertyValue;
+ }
+ void setRelatedEnumProperty(MyEnumContainer::RelatedEnum v) {
+ relatedEnumPropertyValue = v;
+ }
+
QString stringPropertyValue;
QString stringProperty() const {
return stringPropertyValue;
QVERIFY(object != 0);
QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
+ QCOMPARE(object->relatedEnumProperty(), MyEnumContainer::RelatedValue);
QCOMPARE(object->stringProperty(), QString("Hello World!"));
QCOMPARE(object->uintProperty(), uint(10));
QCOMPARE(object->intProperty(), -19);
QVERIFY(object != 0);
QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
+ QCOMPARE(object->relatedEnumProperty(), MyEnumContainer::RelatedValue);
QCOMPARE(object->stringProperty(), QString("Hello World!"));
QCOMPARE(object->uintProperty(), uint(10));
QCOMPARE(object->intProperty(), -19);
QObject *object = component.create();
QVERIFY(object != 0);
+ QCOMPARE(object->property("enumProperty").toInt(), (int)MyQmlObject::EnumValue2);
+ QCOMPARE(object->property("relatedEnumProperty").toInt(), (int)MyEnumContainer::RelatedValue);
+ QCOMPARE(object->property("unrelatedEnumProperty").toInt(), (int)MyEnumContainer::RelatedValue);
+ QCOMPARE(object->property("qtEnumProperty").toInt(), (int)Qt::CaseInsensitive);
QCOMPARE(object->property("a").toInt(), 0);
QCOMPARE(object->property("b").toInt(), 1);
QCOMPARE(object->property("c").toInt(), 2);
QCOMPARE(object->property("h").toInt(), 3);
QCOMPARE(object->property("i").toInt(), 19);
QCOMPARE(object->property("j").toInt(), 19);
+ QCOMPARE(object->property("k").toInt(), 42);
+ QCOMPARE(object->property("l").toInt(), 333);
delete object;
}
QCOMPARE(object->property("h").toInt(), 2);
QCOMPARE(object->property("i").toInt(), 3);
QCOMPARE(object->property("j").toInt(), -1);
+ QCOMPARE(object->property("k").toInt(), 42);
// count of change signals
QCOMPARE(object->property("ac").toInt(), 0);
QCOMPARE(object->property("hc").toInt(), 1); // namespace -> binding
QCOMPARE(object->property("ic").toInt(), 1); // namespace -> binding
QCOMPARE(object->property("jc").toInt(), 0);
+ QCOMPARE(object->property("kc").toInt(), 0);
delete object;
}
import Test 1.0
+import QtQuick 2.0
+
MyTypeObject {
flagProperty: "FlagVal1 | FlagVal3"
enumProperty: "EnumVal2"
qtEnumProperty: Qt.RichText
mirroredEnumProperty: Qt.AlignHCenter
+ relatedEnumProperty: "RelatedValue"
stringProperty: "Hello World!"
uintProperty: 10
intProperty: -19
};
+class MyEnumContainer : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(RelatedEnum)
+
+public:
+ enum RelatedEnum { RelatedInvalid = -1, RelatedValue = 42 };
+};
+
class MyTypeObject : public QObject
{
Q_OBJECT
Q_ENUMS(MyEnum)
Q_ENUMS(MyMirroredEnum)
+ Q_ENUMS(MyEnumContainer::RelatedEnum)
Q_FLAGS(MyFlags)
Q_PROPERTY(QString id READ id WRITE setId)
Q_PROPERTY(MyEnum readOnlyEnumProperty READ readOnlyEnumProperty)
Q_PROPERTY(Qt::TextFormat qtEnumProperty READ qtEnumProperty WRITE setQtEnumProperty NOTIFY qtEnumPropertyChanged)
Q_PROPERTY(MyMirroredEnum mirroredEnumProperty READ mirroredEnumProperty WRITE setMirroredEnumProperty NOTIFY mirroredEnumPropertyChanged)
+ Q_PROPERTY(MyEnumContainer::RelatedEnum relatedEnumProperty READ relatedEnumProperty WRITE setRelatedEnumProperty)
Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty NOTIFY stringPropertyChanged)
Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty NOTIFY uintPropertyChanged)
Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty NOTIFY intPropertyChanged)
emit mirroredEnumPropertyChanged();
}
+ MyEnumContainer::RelatedEnum relatedEnumPropertyValue;
+ MyEnumContainer::RelatedEnum relatedEnumProperty() const {
+ return relatedEnumPropertyValue;
+ }
+ void setRelatedEnumProperty(MyEnumContainer::RelatedEnum v) {
+ relatedEnumPropertyValue = v;
+ }
+
QString stringPropertyValue;
QString stringProperty() const {
return stringPropertyValue;
QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
QCOMPARE(object->qtEnumProperty(), Qt::RichText);
QCOMPARE(object->mirroredEnumProperty(), MyTypeObject::MirroredEnumVal3);
+ QCOMPARE(object->relatedEnumProperty(), MyEnumContainer::RelatedValue);
QCOMPARE(object->stringProperty(), QString("Hello World!"));
QCOMPARE(object->uintProperty(), uint(10));
QCOMPARE(object->intProperty(), -19);