QMetaProperty::write should reset the property if an empty QVariant is given

[ChangeLog][QtCore][QMetaProperty] write() now resets the property if an
empty QVariant is given, or set a default constructed object if the
property is not resettable

Change-Id: I9f9b57114e740f03ec4db6f223c1e8280a3d5209
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@theqtcompany.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
This commit is contained in:
Olivier Goffart 2015-10-06 10:14:26 +02:00 committed by Olivier Goffart (Woboq GmbH)
parent 54b5287adf
commit de70798859
4 changed files with 30 additions and 6 deletions

View File

@ -3028,6 +3028,11 @@ QVariant QMetaProperty::read(const QObject *object) const
Writes \a value as the property's value to the given \a object. Returns
true if the write succeeded; otherwise returns \c false.
If \a value is not of the same type type as the property, a conversion
is attempted. An empty QVariant() is equivalent to a call to reset()
if this property is resetable, or setting a default-constructed object
otherwise.
\sa read(), reset(), isWritable()
*/
bool QMetaProperty::write(QObject *object, const QVariant &value) const
@ -3068,8 +3073,15 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
if (t == QMetaType::UnknownType)
return false;
}
if (t != QMetaType::QVariant && int(t) != value.userType() && !v.convert(t))
return false;
if (t != QMetaType::QVariant && int(t) != value.userType()) {
if (!value.isValid()) {
if (isResettable())
return reset(object);
v = QVariant(t, 0);
} else if (!v.convert(t)) {
return false;
}
}
}
// the status variable is changed by qt_metacall to indicate what it did

View File

@ -3831,7 +3831,7 @@ int QObjectPrivate::signalIndex(const char *signalName,
\b{Note:} Dynamic properties starting with "_q_" are reserved for internal
purposes.
\sa property(), metaObject(), dynamicPropertyNames()
\sa property(), metaObject(), dynamicPropertyNames(), QMetaProperty::write()
*/
bool QObject::setProperty(const char *name, const QVariant &value)
{

View File

@ -55,7 +55,7 @@ class tst_QMetaProperty : public QObject
Q_OBJECT
Q_PROPERTY(EnumType value WRITE setValue READ getValue)
Q_PROPERTY(EnumType value2 WRITE set_value READ get_value)
Q_PROPERTY(QString value7 MEMBER value7)
Q_PROPERTY(QString value7 MEMBER value7 RESET resetValue7)
Q_PROPERTY(int value8 READ value8)
Q_PROPERTY(int value9 READ value9 CONSTANT)
Q_PROPERTY(int value10 READ value10 FINAL)
@ -79,6 +79,7 @@ public:
void set_value(EnumType) {}
EnumType get_value() const { return EnumType1; }
void resetValue7() { value7 = QStringLiteral("reset"); }
int value8() const { return 1; }
int value9() const { return 1; }
int value10() const { return 1; }
@ -236,6 +237,17 @@ void tst_QMetaProperty::conversion()
QVERIFY(!customP.write(this, QVariant::fromValue(this)));
QVERIFY(!value7P.write(this, QVariant::fromValue(this)));
QVERIFY(!value7P.write(this, QVariant::fromValue<QObject*>(this)));
// none of this should have changed the values
QCOMPARE(value7, hello);
QCOMPARE(custom.str, hello);
// Empty variant should be converted to default object
QVERIFY(customP.write(this, QVariant()));
QCOMPARE(custom.str, QString());
// or reset resetable
QVERIFY(value7P.write(this, QVariant()));
QCOMPARE(value7, QLatin1Literal("reset"));
}
QTEST_MAIN(tst_QMetaProperty)

View File

@ -1925,7 +1925,7 @@ void tst_QObject::property()
QCOMPARE(object.property("string"), QVariant("String1"));
QVERIFY(object.setProperty("string", "String2"));
QCOMPARE(object.property("string"), QVariant("String2"));
QVERIFY(!object.setProperty("string", QVariant()));
QVERIFY(object.setProperty("string", QVariant()));
const int idx = mo->indexOfProperty("variant");
QVERIFY(idx != -1);
@ -2027,7 +2027,7 @@ void tst_QObject::property()
QCOMPARE(object.property("customString"), QVariant("String1"));
QVERIFY(object.setProperty("customString", "String2"));
QCOMPARE(object.property("customString"), QVariant("String2"));
QVERIFY(!object.setProperty("customString", QVariant()));
QVERIFY(object.setProperty("customString", QVariant()));
}
void tst_QObject::metamethod()