summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-05-20 09:57:08 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-05-20 09:57:08 (GMT)
commit691e83425ac5883922837bc5fd1efb5385db9871 (patch)
tree908ff0897699323cc9f0fe9401449bf66c86064a
parente2d70563652a89384d13c9a1d7ac1c839a81e9be (diff)
downloadQt-691e83425ac5883922837bc5fd1efb5385db9871.zip
Qt-691e83425ac5883922837bc5fd1efb5385db9871.tar.gz
Qt-691e83425ac5883922837bc5fd1efb5385db9871.tar.bz2
Add string-->enum conversion for properties and slots
-rw-r--r--src/script/qscriptengine_p.cpp5
-rw-r--r--src/script/qscriptenginefwd_p.h1
-rw-r--r--src/script/qscriptextqobject.cpp33
-rw-r--r--tests/auto/qscriptqobject/tst_qscriptqobject.cpp66
4 files changed, 96 insertions, 9 deletions
diff --git a/src/script/qscriptengine_p.cpp b/src/script/qscriptengine_p.cpp
index a2e58de..84a420d 100644
--- a/src/script/qscriptengine_p.cpp
+++ b/src/script/qscriptengine_p.cpp
@@ -1662,6 +1662,11 @@ bool QScriptEnginePrivate::convert(const QScriptValueImpl &value,
return false;
}
+QScriptEngine::DemarshalFunction QScriptEnginePrivate::demarshalFunction(int type) const
+{
+ return m_customTypes.value(type).demarshal;
+}
+
QScriptValuePrivate *QScriptEnginePrivate::registerValue(const QScriptValueImpl &value)
{
if (value.isString()) {
diff --git a/src/script/qscriptenginefwd_p.h b/src/script/qscriptenginefwd_p.h
index 2ea66c5..855317c 100644
--- a/src/script/qscriptenginefwd_p.h
+++ b/src/script/qscriptenginefwd_p.h
@@ -350,6 +350,7 @@ public:
QScriptValueImpl create(int type, const void *ptr);
static bool convert(const QScriptValueImpl &value, int type, void *ptr,
QScriptEnginePrivate *eng);
+ QScriptEngine::DemarshalFunction demarshalFunction(int type) const;
QScriptValueImpl arrayFromStringList(const QStringList &lst);
static QStringList stringListFromArray(const QScriptValueImpl &arr);
diff --git a/src/script/qscriptextqobject.cpp b/src/script/qscriptextqobject.cpp
index d18c3da..4522807 100644
--- a/src/script/qscriptextqobject.cpp
+++ b/src/script/qscriptextqobject.cpp
@@ -425,7 +425,7 @@ static void callQtMethod(QScriptContextPrivate *context, QMetaMethod::MethodType
matchDistance += 10;
}
}
- } else if (actual.isNumber()) {
+ } else if (actual.isNumber() || actual.isString()) {
// see if it's an enum value
QMetaEnum m;
if (argType.isMetaEnum()) {
@@ -436,11 +436,21 @@ static void callQtMethod(QScriptContextPrivate *context, QMetaMethod::MethodType
m = meta->enumerator(mi);
}
if (m.isValid()) {
- int ival = actual.toInt32();
- if (m.valueToKey(ival) != 0) {
- qVariantSetValue(v, ival);
- converted = true;
- matchDistance += 10;
+ if (actual.isNumber()) {
+ int ival = actual.toInt32();
+ if (m.valueToKey(ival) != 0) {
+ qVariantSetValue(v, ival);
+ converted = true;
+ matchDistance += 10;
+ }
+ } else {
+ QString sval = actual.toString();
+ int ival = m.keyToValue(sval.toLatin1());
+ if (ival != -1) {
+ qVariantSetValue(v, ival);
+ converted = true;
+ matchDistance += 10;
+ }
}
}
}
@@ -1809,7 +1819,16 @@ void QScript::QtPropertyFunction::execute(QScriptContextPrivate *context)
}
} else {
// set
- QVariant v = variantFromValue(eng_p, prop.userType(), context->argument(0));
+ QScriptValueImpl arg = context->argument(0);
+ QVariant v;
+ if (prop.isEnumType() && arg.isString()
+ && !eng_p->demarshalFunction(prop.userType())) {
+ // give QMetaProperty::write() a chance to convert from
+ // string to enum value
+ v = arg.toString();
+ } else {
+ v = variantFromValue(eng_p, prop.userType(), arg);
+ }
QScriptable *scriptable = scriptableFromQObject(qobject);
QScriptEngine *oldEngine = 0;
diff --git a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp
index 9b9dd16..1025d2a 100644
--- a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp
+++ b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp
@@ -107,6 +107,7 @@ class MyQObject : public QObject
Q_PROPERTY(int readOnlyProperty READ readOnlyProperty)
Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
Q_PROPERTY(CustomType propWithCustomType READ propWithCustomType WRITE setPropWithCustomType)
+ Q_PROPERTY(Policy enumProperty READ enumProperty WRITE setEnumProperty)
Q_ENUMS(Policy Strategy)
Q_FLAGS(Ability)
@@ -144,6 +145,7 @@ public:
m_hiddenValue(456.0),
m_writeOnlyValue(789),
m_readOnlyValue(987),
+ m_enumValue(BarPolicy),
m_qtFunctionInvoked(-1)
{ }
@@ -205,6 +207,11 @@ public:
void setPropWithCustomType(const CustomType &c)
{ m_customType = c; }
+ Policy enumProperty() const
+ { return m_enumValue; }
+ void setEnumProperty(Policy policy)
+ { m_enumValue = policy; }
+
int qtFunctionInvoked() const
{ return m_qtFunctionInvoked; }
@@ -255,8 +262,8 @@ public:
{ m_qtFunctionInvoked = 36; m_actuals << policy; }
Q_INVOKABLE Policy myInvokableReturningEnum()
{ m_qtFunctionInvoked = 37; return BazPolicy; }
- Q_INVOKABLE MyQObject::Policy myInvokableReturningQualifiedEnum()
- { m_qtFunctionInvoked = 38; return BazPolicy; }
+ Q_INVOKABLE MyQObject::Strategy myInvokableReturningQualifiedEnum()
+ { m_qtFunctionInvoked = 38; return BazStrategy; }
Q_INVOKABLE QVector<int> myInvokableReturningVectorOfInt()
{ m_qtFunctionInvoked = 11; return QVector<int>(); }
Q_INVOKABLE void myInvokableWithVectorOfIntArg(const QVector<int> &)
@@ -410,6 +417,7 @@ protected:
int m_readOnlyValue;
QKeySequence m_shortcut;
CustomType m_customType;
+ Policy m_enumValue;
int m_qtFunctionInvoked;
QVariantList m_actuals;
QByteArray m_connectedSignal;
@@ -417,6 +425,7 @@ protected:
};
Q_DECLARE_METATYPE(MyQObject*)
+Q_DECLARE_METATYPE(MyQObject::Policy)
class MyOtherQObject : public MyQObject
{
@@ -530,6 +539,24 @@ static QScriptValue getSetProperty(QScriptContext *ctx, QScriptEngine *)
return ctx->callee().property("value");
}
+static QScriptValue policyToScriptValue(QScriptEngine *engine, const MyQObject::Policy &policy)
+{
+ return qScriptValueFromValue(engine, policy);
+}
+
+static void policyFromScriptValue(const QScriptValue &value, MyQObject::Policy &policy)
+{
+ QString str = value.toString();
+ if (str == QLatin1String("red"))
+ policy = MyQObject::FooPolicy;
+ else if (str == QLatin1String("green"))
+ policy = MyQObject::BarPolicy;
+ else if (str == QLatin1String("blue"))
+ policy = MyQObject::BazPolicy;
+ else
+ policy = (MyQObject::Policy)-1;
+}
+
void tst_QScriptExtQObject::getSetStaticProperty()
{
QCOMPARE(m_engine->evaluate("myObject.noSuchProperty").isUndefined(), true);
@@ -751,6 +778,31 @@ void tst_QScriptExtQObject::getSetStaticProperty()
QScriptValue::ReadOnly);
}
+ // enum property
+ QCOMPARE(m_myObject->enumProperty(), MyQObject::BarPolicy);
+ {
+ QScriptValue val = m_engine->evaluate("myObject.enumProperty");
+ QVERIFY(val.isNumber());
+ QCOMPARE(val.toInt32(), (int)MyQObject::BarPolicy);
+ }
+ m_engine->evaluate("myObject.enumProperty = 2");
+ QCOMPARE(m_myObject->enumProperty(), MyQObject::BazPolicy);
+ m_engine->evaluate("myObject.enumProperty = 'BarPolicy'");
+ QCOMPARE(m_myObject->enumProperty(), MyQObject::BarPolicy);
+ m_engine->evaluate("myObject.enumProperty = 'ScoobyDoo'");
+ // ### ouch! Shouldn't QMetaProperty::write() rather not change the value...?
+ QCOMPARE(m_myObject->enumProperty(), (MyQObject::Policy)-1);
+ // enum property with custom conversion
+ qScriptRegisterMetaType<MyQObject::Policy>(m_engine, policyToScriptValue, policyFromScriptValue);
+ m_engine->evaluate("myObject.enumProperty = 'red'");
+ QCOMPARE(m_myObject->enumProperty(), MyQObject::FooPolicy);
+ m_engine->evaluate("myObject.enumProperty = 'green'");
+ QCOMPARE(m_myObject->enumProperty(), MyQObject::BarPolicy);
+ m_engine->evaluate("myObject.enumProperty = 'blue'");
+ QCOMPARE(m_myObject->enumProperty(), MyQObject::BazPolicy);
+ m_engine->evaluate("myObject.enumProperty = 'nada'");
+ QCOMPARE(m_myObject->enumProperty(), (MyQObject::Policy)-1);
+
// auto-dereferencing of pointers
{
QBrush b = QColor(0xCA, 0xFE, 0xBA, 0xBE);
@@ -1879,6 +1931,16 @@ void tst_QScriptExtQObject::classEnums()
QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), int(MyQObject::BazPolicy));
m_myObject->resetQtFunctionInvoked();
+ QCOMPARE(m_engine->evaluate("myObject.myInvokableWithEnumArg('BarPolicy')").isUndefined(), true);
+ QCOMPARE(m_myObject->qtFunctionInvoked(), 10);
+ QCOMPARE(m_myObject->qtFunctionActuals().size(), 1);
+ QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), int(MyQObject::BarPolicy));
+
+ m_myObject->resetQtFunctionInvoked();
+ QVERIFY(m_engine->evaluate("myObject.myInvokableWithEnumArg('NoSuchPolicy')").isError());
+ QCOMPARE(m_myObject->qtFunctionInvoked(), -1);
+
+ m_myObject->resetQtFunctionInvoked();
QCOMPARE(m_engine->evaluate("myObject.myInvokableWithQualifiedEnumArg(MyQObject.BazPolicy)").isUndefined(), true);
QCOMPARE(m_myObject->qtFunctionInvoked(), 36);
QCOMPARE(m_myObject->qtFunctionActuals().size(), 1);