aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4engine.cpp6
-rw-r--r--src/qml/qml/qqmlproperty.cpp26
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp88
3 files changed, 114 insertions, 6 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 54dd5979cf..eecf874e19 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -1390,11 +1390,11 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
case QMetaType::UShort:
return QV4::Encode((int)*reinterpret_cast<const unsigned short*>(ptr));
case QMetaType::Char:
- return QV4::Encode((int)*reinterpret_cast<const char*>(ptr));
+ return newString(QChar::fromLatin1(*reinterpret_cast<const char *>(ptr)))->asReturnedValue();
case QMetaType::UChar:
- return QV4::Encode((int)*reinterpret_cast<const unsigned char*>(ptr));
+ return newString(QChar::fromLatin1(*reinterpret_cast<const unsigned char *>(ptr)))->asReturnedValue();
case QMetaType::QChar:
- return QV4::Encode((int)(*reinterpret_cast<const QChar*>(ptr)).unicode());
+ return newString(*reinterpret_cast<const QChar *>(ptr))->asReturnedValue();
case QMetaType::QDateTime:
return QV4::Encode(newDateObject(*reinterpret_cast<const QDateTime *>(ptr)));
case QMetaType::QDate:
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index d45f3ac19b..931adb9a13 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1387,8 +1387,30 @@ bool QQmlPropertyPrivate::write(QObject *object,
bool ok = false;
QVariant v;
- if (variantType == QVariant::String)
- v = QQmlStringConverters::variantFromString(value.toString(), propertyType, &ok);
+ if (variantType == QVariant::String) {
+ const QString &str = value.toString();
+ const bool targetIsChar = (propertyType == qMetaTypeId<QChar>()
+ || propertyType == qMetaTypeId<char>()
+ || propertyType == qMetaTypeId<unsigned char>());
+ // If the string contains only one character and the target is a char, try converting it.
+ if (targetIsChar) {
+ if (str.size() != 1)
+ return false; // We can only convert if the string contains exactly one character.
+
+ const QChar &qChar = str.at(0);
+ if (propertyType == qMetaTypeId<QChar>()) {
+ v = qChar;
+ ok = true;
+ } else if (propertyType == qMetaTypeId<char>() || propertyType == qMetaTypeId<unsigned char>()) {
+ const char c = qChar.toLatin1();
+ v = c;
+ ok = (qChar == c);
+ }
+ } else {
+ v = QQmlStringConverters::variantFromString(str, propertyType, &ok);
+ }
+ }
+
if (!ok) {
v = value;
if (v.convert(propertyType)) {
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index f8af13582e..c4b2325843 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -326,10 +326,16 @@ class PropertyObject : public QObject
Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal)
Q_PROPERTY(MyQmlObject *qmlObject READ qmlObject)
Q_PROPERTY(MyQObject *qObject READ qObject WRITE setQObject NOTIFY qObjectChanged)
+ Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty)
+ Q_PROPERTY(char charProperty READ charProperty WRITE setCharProperty)
+ Q_PROPERTY(QChar qcharProperty READ qcharProperty WRITE setQcharProperty)
+ Q_PROPERTY(QChar constQChar READ constQChar STORED false CONSTANT FINAL)
+ Q_PROPERTY(char constChar READ constChar STORED false CONSTANT FINAL)
+ Q_PROPERTY(int constInt READ constInt STORED false CONSTANT FINAL)
Q_CLASSINFO("DefaultProperty", "defaultProperty")
public:
- PropertyObject() : m_resetProperty(9), m_qObject(0) {}
+ PropertyObject() : m_resetProperty(9), m_qObject(0), m_stringProperty("foo") {}
int defaultProperty() { return 10; }
QRect rectProperty() { return QRect(10, 10, 1, 209); }
@@ -361,6 +367,18 @@ public:
}
}
+ QString stringProperty() const { return m_stringProperty;}
+ char charProperty() const { return m_charProperty; }
+ QChar qcharProperty() const { return m_qcharProperty; }
+
+ QChar constQChar() const { return 0x25cf; /* Unicode: black circle */ }
+ char constChar() const { return 'A'; }
+ int constInt() const { return 123456; }
+
+ void setStringProperty(QString arg) { m_stringProperty = arg; }
+ void setCharProperty(char arg) { m_charProperty = arg; }
+ void setQcharProperty(QChar arg) { m_qcharProperty = arg; }
+
signals:
void clicked();
void oddlyNamedNotifySignal();
@@ -374,6 +392,9 @@ private:
int m_propertyWithNotify;
MyQmlObject m_qmlObject;
MyQObject *m_qObject;
+ QString m_stringProperty;
+ char m_charProperty;
+ QChar m_qcharProperty;
};
QML_DECLARE_TYPE(PropertyObject);
@@ -1382,6 +1403,71 @@ void tst_qqmlproperty::write()
QCOMPARE(o.url(), result);
}
+ // Char/string-property
+ {
+ PropertyObject o;
+ QQmlProperty charProperty(&o, "charProperty");
+ QQmlProperty qcharProperty(&o, "qcharProperty");
+ QQmlProperty stringProperty(&o, "stringProperty");
+
+ const int black_circle = 0x25cf;
+
+ QCOMPARE(charProperty.write(QString("foo")), false);
+ QCOMPARE(charProperty.write('Q'), true);
+ QCOMPARE(charProperty.read(), QVariant('Q'));
+ QCOMPARE(charProperty.write(QString("t")), true);
+ QCOMPARE(charProperty.read(), QVariant('t'));
+
+ QCOMPARE(qcharProperty.write(QString("foo")), false);
+ QCOMPARE(qcharProperty.write('Q'), true);
+ QCOMPARE(qcharProperty.read(), QVariant('Q'));
+ QCOMPARE(qcharProperty.write(QString("t")), true);
+ QCOMPARE(qcharProperty.read(), QVariant('t'));
+ QCOMPARE(qcharProperty.write(QChar(black_circle)), true);
+ QCOMPARE(qcharProperty.read(), QVariant(QChar(black_circle)));
+
+ QCOMPARE(o.stringProperty(), QString("foo")); // Default value
+ QCOMPARE(stringProperty.write(QString("bar")), true);
+ QCOMPARE(o.stringProperty(), QString("bar"));
+ QCOMPARE(stringProperty.write(QVariant(1234)), true);
+ QCOMPARE(stringProperty.read().toString(), QString::number(1234));
+ QCOMPARE(stringProperty.write(QChar(black_circle)), true);
+ QCOMPARE(stringProperty.read(), QVariant(QString(QChar(black_circle))));
+
+ { // char -> QString
+ QQmlComponent component(&engine);
+ component.setData("import Test 1.0\nPropertyObject { stringProperty: constChar }", QUrl());
+ PropertyObject *obj = qobject_cast<PropertyObject*>(component.create());
+ QVERIFY(obj != 0);
+ if (obj) {
+ QQmlProperty stringProperty(obj, "stringProperty");
+ QCOMPARE(stringProperty.read(), QVariant(QString(obj->constChar())));
+ }
+ }
+
+ { // QChar -> QString
+ QQmlComponent component(&engine);
+ component.setData("import Test 1.0\nPropertyObject { stringProperty: constQChar }", QUrl());
+ PropertyObject *obj = qobject_cast<PropertyObject*>(component.create());
+ QVERIFY(obj != 0);
+ if (obj) {
+ QQmlProperty stringProperty(obj, "stringProperty");
+ QCOMPARE(stringProperty.read(), QVariant(QString(obj->constQChar())));
+ }
+ }
+
+ { // int -> QString
+ QQmlComponent component(&engine);
+ component.setData("import Test 1.0\nPropertyObject { stringProperty: constInt }", QUrl());
+ PropertyObject *obj = qobject_cast<PropertyObject*>(component.create());
+ QVERIFY(obj != 0);
+ if (obj) {
+ QQmlProperty stringProperty(obj, "stringProperty");
+ QCOMPARE(stringProperty.read(), QVariant(QString::number(obj->constInt())));
+ }
+ }
+ }
+
// VariantMap-property
QVariantMap vm;
vm.insert("key", "value");