summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2010-02-26 02:03:53 (GMT)
committerMartin Jones <martin.jones@nokia.com>2010-02-26 02:03:53 (GMT)
commit77ba224d71da1e28761760b724b078107d307168 (patch)
tree05bd48941a3fccc5b1536dcc1d51c0fb546849e3
parent5fb329228bd1cd1126428b045a41a4a9c1033dc5 (diff)
parente3d78a41a7d0533972169aeb6ca00b5655c5c404 (diff)
downloadQt-77ba224d71da1e28761760b724b078107d307168.zip
Qt-77ba224d71da1e28761760b724b078107d307168.tar.gz
Qt-77ba224d71da1e28761760b724b078107d307168.tar.bz2
Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-qml
-rwxr-xr-xconfigure.exebin1221632 -> 1223680 bytes
-rw-r--r--src/corelib/kernel/qvariant.cpp4
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp16
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h3
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp81
-rw-r--r--src/declarative/qml/qdeclarativeproperty.h3
-rw-r--r--src/declarative/qml/qdeclarativeproperty_p.h1
-rw-r--r--tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp149
-rw-r--r--tests/auto/declarative/qdeclarativestates/data/basicChanges4.qml19
-rw-r--r--tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp67
10 files changed, 277 insertions, 66 deletions
diff --git a/configure.exe b/configure.exe
index f937ea2..39a1747 100755
--- a/configure.exe
+++ b/configure.exe
Binary files differ
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 384a3cd..227a60d 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1936,13 +1936,13 @@ static const ushort map_from_three[MapFromThreeCount] =
QVariant::Date,
QVariant::Time,
QVariant::DateTime,
- QVariant::EasingCurve,
QVariant::ByteArray,
QVariant::BitArray,
QVariant::KeySequence,
QVariant::Pen,
QVariant::LongLong,
- QVariant::ULongLong
+ QVariant::ULongLong,
+ QVariant::EasingCurve
};
/*!
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index 9dc090b..5da207d 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -1314,8 +1314,9 @@ int QDeclarativeCompiler::componentTypeRef()
return output->types.count() - 1;
}
-int QDeclarativeCompiler::findSignalByName(const QMetaObject *mo, const QByteArray &name)
+QMetaMethod QDeclarativeCompiler::findSignalByName(const QMetaObject *mo, const QByteArray &name)
{
+ Q_ASSERT(mo);
int methods = mo->methodCount();
for (int ii = methods - 1; ii >= 0; --ii) {
QMetaMethod method = mo->method(ii);
@@ -1324,7 +1325,7 @@ int QDeclarativeCompiler::findSignalByName(const QMetaObject *mo, const QByteArr
methodName = methodName.left(idx);
if (methodName == name)
- return ii;
+ return method;
}
// If no signal is found, but the signal is of the form "onBlahChanged",
@@ -1332,11 +1333,14 @@ int QDeclarativeCompiler::findSignalByName(const QMetaObject *mo, const QByteArr
if (name.endsWith("Changed")) {
QByteArray propName = name.mid(0, name.length() - 7);
int propIdx = mo->indexOfProperty(propName.constData());
- if (propIdx >= 0)
- return mo->property(propIdx).notifySignalIndex();
+ if (propIdx >= 0) {
+ QMetaProperty prop = mo->property(propIdx);
+ if (prop.hasNotifySignal())
+ return prop.notifySignal();
+ }
}
- return -1;
+ return QMetaMethod();
}
bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj,
@@ -1351,7 +1355,7 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
if(name[0] >= 'A' && name[0] <= 'Z')
name[0] = name[0] - 'A' + 'a';
- int sigIdx = findSignalByName(obj->metaObject(), name);
+ int sigIdx = findSignalByName(obj->metaObject(), name).methodIndex();
if (sigIdx == -1) {
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index 627490d..2ea3366 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -159,6 +159,8 @@ public:
static bool isAttachedPropertyName(const QByteArray &);
static bool isSignalPropertyName(const QByteArray &);
+ static QMetaMethod findSignalByName(const QMetaObject *, const QByteArray &name);
+
private:
static void reset(QDeclarativeCompiledData *);
@@ -263,7 +265,6 @@ private:
int componentTypeRef();
- static int findSignalByName(const QMetaObject *, const QByteArray &name);
static QDeclarativeType *toQmlType(QDeclarativeParser::Object *from);
bool canCoerce(int to, QDeclarativeParser::Object *from);
bool canCoerce(int to, int from);
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index 88f356d..fbea6ac 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -53,6 +53,7 @@
#include "qdeclarativedeclarativedata_p.h"
#include "qdeclarativestringconverters_p.h"
#include "qdeclarativelist_p.h"
+#include "qdeclarativecompiler_p.h"
#include <QStringList>
#include <QtCore/qdebug.h>
@@ -62,10 +63,30 @@
QT_BEGIN_NAMESPACE
/*!
- \class QDeclarativeProperty
- \brief The QDeclarativeProperty class abstracts accessing QML properties.
- \internal
- */
+\class QDeclarativeProperty
+\brief The QDeclarativeProperty class abstracts accessing properties on objects created from QML.
+
+As QML uses Qt's meta-type system all of the existing QMetaObject classes can be used to introspect
+and interact with objects created by QML. However, some of the new features provided by QML - such
+as type safety and attached properties - are most easily used through the QDeclarativeProperty class
+that simplifies some of their natural complexity.
+
+Unlike QMetaProperty which represents a property on a class type, QDeclarativeProperty encapsulates
+a property on a specific object instance. To read a property's value, programmers create a
+QDeclarativeProperty instance and call the read() method. Likewise to write a property value the
+write() method is used.
+
+\code
+
+QObject *object = declarativeComponent.create();
+
+QDeclarativeProperty property(object, "font.pixelSize");
+qWarning() << "Current pixel size:" << property.read().toInt();
+property.write(24);
+qWarning() << "Pixel size should now be 24:" << property.read().toInt();
+
+\endcode
+*/
/*!
Create an invalid QDeclarativeProperty.
@@ -235,7 +256,7 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name
QString signalName = terminal.mid(2);
signalName[0] = signalName.at(0).toLower();
- QMetaMethod method = findSignal(currentObject, signalName);
+ QMetaMethod method = QDeclarativeCompiler::findSignalByName(currentObject->metaObject(), signalName.toLatin1().constData());
if (method.signature()) {
object = currentObject;
core.load(method);
@@ -297,7 +318,7 @@ QDeclarativePropertyPrivate::propertyTypeCategory() const
{
uint type = q->type();
- if (type & QDeclarativeProperty::ValueTypeProperty) {
+ if (isValueType()) {
return QDeclarativeProperty::Normal;
} else if (type & QDeclarativeProperty::Property) {
int type = propertyType();
@@ -322,7 +343,7 @@ QDeclarativePropertyPrivate::propertyTypeCategory() const
*/
const char *QDeclarativeProperty::propertyTypeName() const
{
- if (type() & ValueTypeProperty) {
+ if (d->isValueType()) {
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(d->context);
QDeclarativeValueType *valueType = 0;
@@ -364,10 +385,15 @@ int QDeclarativeProperty::propertyType() const
return d->propertyType();
}
+bool QDeclarativePropertyPrivate::isValueType() const
+{
+ return valueType.valueTypeCoreIdx != -1;
+}
+
int QDeclarativePropertyPrivate::propertyType() const
{
uint type = q->type();
- if (type & QDeclarativeProperty::ValueTypeProperty) {
+ if (isValueType()) {
return valueType.valueTypePropType;
} else if (type & QDeclarativeProperty::Property) {
if (core.propType == (int)QVariant::LastType)
@@ -386,8 +412,6 @@ QDeclarativeProperty::Type QDeclarativeProperty::type() const
{
if (d->core.flags & QDeclarativePropertyCache::Data::IsFunction)
return SignalProperty;
- else if (d->valueType.valueTypeCoreIdx != -1)
- return (Type)(Property | ValueTypeProperty);
else if (d->core.isValid())
return (Type)(Property | ((d->isDefaultProperty)?Default:0));
else
@@ -494,7 +518,7 @@ QString QDeclarativeProperty::name() const
if (!d->isNameCached) {
// ###
if (!d->object) {
- } else if (type() & ValueTypeProperty) {
+ } else if (d->isValueType()) {
QString rv = d->core.name(d->object) + QLatin1Char('.');
QDeclarativeEnginePrivate *ep = d->context?QDeclarativeEnginePrivate::get(d->context->engine()):0;
@@ -686,23 +710,6 @@ QDeclarativePropertyPrivate::setSignalExpression(const QDeclarativeProperty &tha
}
}
-QMetaMethod QDeclarativePropertyPrivate::findSignal(QObject *obj, const QString &name)
-{
- const QMetaObject *mo = obj->metaObject();
-
- int methods = mo->methodCount();
- for (int ii = methods - 1; ii >= 0; --ii) {
- QMetaMethod method = mo->method(ii);
- QString methodName = QString::fromUtf8(method.signature());
- int idx = methodName.indexOf(QLatin1Char('('));
- methodName = methodName.left(idx);
-
- if (methodName == name)
- return method;
- }
- return QMetaMethod();
-}
-
/*!
Returns the property value.
*/
@@ -725,8 +732,7 @@ QVariant QDeclarativeProperty::read() const
QVariant QDeclarativePropertyPrivate::readValueProperty()
{
- uint type = q->type();
- if(type & QDeclarativeProperty::ValueTypeProperty) {
+ if(isValueType()) {
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context);
QDeclarativeValueType *valueType = 0;
@@ -805,8 +811,7 @@ bool QDeclarativePropertyPrivate::writeValueProperty(const QVariant &value, Writ
}
bool rv = false;
- uint type = q->type();
- if (type & QDeclarativeProperty::ValueTypeProperty) {
+ if (isValueType()) {
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context);
QDeclarativeValueType *writeBack = 0;
@@ -1113,7 +1118,7 @@ int QDeclarativePropertyPrivate::valueTypeCoreIndex(const QDeclarativeProperty &
}
struct SerializedData {
- QDeclarativeProperty::Type type;
+ bool isValueType;
QDeclarativePropertyCache::Data core;
};
@@ -1128,7 +1133,7 @@ QByteArray QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObj
QMetaProperty subProp = subObject->property(subIndex);
ValueTypeSerializedData sd;
- sd.type = QDeclarativeProperty::ValueTypeProperty;
+ sd.isValueType = true;
sd.core.load(metaObject->property(index));
sd.valueType.flags = QDeclarativePropertyCache::Data::flagsForProperty(subProp);
sd.valueType.valueTypeCoreIdx = subIndex;
@@ -1142,7 +1147,7 @@ QByteArray QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObj
QByteArray QDeclarativePropertyPrivate::saveProperty(const QMetaObject *metaObject, int index)
{
SerializedData sd;
- sd.type = QDeclarativeProperty::Property;
+ sd.isValueType = false;
sd.core.load(metaObject->property(index));
QByteArray rv((const char *)&sd, sizeof(sd));
@@ -1161,12 +1166,12 @@ QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QD
prop.d->context = ctxt;
const SerializedData *sd = (const SerializedData *)data.constData();
- if (sd->type == QDeclarativeProperty::Property) {
- prop.d->core = sd->core;
- } else if(sd->type == QDeclarativeProperty::ValueTypeProperty) {
+ if (sd->isValueType) {
const ValueTypeSerializedData *vt = (const ValueTypeSerializedData *)sd;
prop.d->core = vt->core;
prop.d->valueType = vt->valueType;
+ } else {
+ prop.d->core = sd->core;
}
return prop;
diff --git a/src/declarative/qml/qdeclarativeproperty.h b/src/declarative/qml/qdeclarativeproperty.h
index be1065e..3504a15 100644
--- a/src/declarative/qml/qdeclarativeproperty.h
+++ b/src/declarative/qml/qdeclarativeproperty.h
@@ -73,8 +73,7 @@ public:
enum Type { Invalid = 0x00,
Property = 0x01,
SignalProperty = 0x02,
- Default = 0x08,
- ValueTypeProperty = 0x10
+ Default = 0x08
};
QDeclarativeProperty();
diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h
index d0ad09c..eb5fa9a 100644
--- a/src/declarative/qml/qdeclarativeproperty_p.h
+++ b/src/declarative/qml/qdeclarativeproperty_p.h
@@ -97,6 +97,7 @@ public:
QMetaMethod findSignal(QObject *, const QString &);
+ bool isValueType() const;
int propertyType() const;
QDeclarativeProperty::PropertyTypeCategory propertyTypeCategory() const;
diff --git a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp
index d4b0808..c72c9e7 100644
--- a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp
+++ b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp
@@ -181,6 +181,7 @@ class PropertyObject : public QObject
Q_PROPERTY(QRect wrectProperty READ wrectProperty WRITE setWRectProperty);
Q_PROPERTY(QUrl url READ url WRITE setUrl);
Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty);
+ Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal)
Q_CLASSINFO("DefaultProperty", "defaultProperty");
public:
@@ -199,13 +200,18 @@ public:
void setResettableProperty(int r) { m_resetProperty = r; }
void resetProperty() { m_resetProperty = 9; }
+ int propertyWithNotify() const { return m_propertyWithNotify; }
+ void setPropertyWithNotify(int i) { m_propertyWithNotify = i; emit oddlyNamedNotifySignal(); }
+
signals:
void clicked();
+ void oddlyNamedNotifySignal();
private:
int m_resetProperty;
QRect m_rect;
QUrl m_url;
+ int m_propertyWithNotify;
};
QML_DECLARE_TYPE(PropertyObject);
@@ -458,6 +464,54 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string()
delete obj;
}
+
+ {
+ QDeclarativeProperty prop(&dobject, QString("onPropertyWithNotifyChanged"));
+
+ QGuard<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
+ binding->setTarget(prop);
+ QVERIFY(binding != 0);
+ QGuard<QDeclarativeExpression> expression(new QDeclarativeExpression());
+ QVERIFY(expression != 0);
+
+ QObject *obj = new QObject;
+
+ QCOMPARE(prop.name(), QString("onOddlyNamedNotifySignal"));
+ QCOMPARE(prop.read(), QVariant());
+ QCOMPARE(prop.write(QVariant("Hello")), false);
+ QCOMPARE(prop.hasChangedNotifier(), false);
+ QCOMPARE(prop.needsChangedNotifier(), false);
+ QCOMPARE(prop.connectNotifier(0, SLOT(deleteLater())), false);
+ QCOMPARE(prop.connectNotifier(obj, SLOT(deleteLater())), false);
+ QCOMPARE(prop.connectNotifier(obj, 0), false);
+ QCOMPARE(prop.connectNotifier(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
+ QCOMPARE(prop.connectNotifier(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
+ QCOMPARE(prop.connectNotifier(obj, -1), false);
+ QCOMPARE(QString(prop.method().signature()), QString("oddlyNamedNotifySignal()"));
+ QCOMPARE(prop.type(), QDeclarativeProperty::SignalProperty);
+ QCOMPARE(prop.isProperty(), false);
+ QCOMPARE(prop.isDefault(), false);
+ QCOMPARE(prop.isWritable(), false);
+ QCOMPARE(prop.isDesignable(), false);
+ QCOMPARE(prop.isResettable(), false);
+ QCOMPARE(prop.isValid(), true);
+ QCOMPARE(prop.object(), &dobject);
+ QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory);
+ QCOMPARE(prop.propertyType(), 0);
+ QCOMPARE(prop.propertyTypeName(), (const char *)0);
+ QCOMPARE(prop.property().name(), (const char *)0);
+ QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
+ QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0);
+ QVERIFY(binding == 0);
+ QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
+ QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0);
+ QVERIFY(expression != 0);
+ QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression);
+ QCOMPARE(prop.coreIndex(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()"));
+ QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
+
+ delete obj;
+ }
}
void tst_qdeclarativeproperty::qmlmetaproperty_object_context()
@@ -708,6 +762,54 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context()
delete obj;
}
+
+ {
+ QDeclarativeProperty prop(&dobject, QString("onPropertyWithNotifyChanged"), engine.rootContext());
+
+ QGuard<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
+ binding->setTarget(prop);
+ QVERIFY(binding != 0);
+ QGuard<QDeclarativeExpression> expression(new QDeclarativeExpression());
+ QVERIFY(expression != 0);
+
+ QObject *obj = new QObject;
+
+ QCOMPARE(prop.name(), QString("onOddlyNamedNotifySignal"));
+ QCOMPARE(prop.read(), QVariant());
+ QCOMPARE(prop.write(QVariant("Hello")), false);
+ QCOMPARE(prop.hasChangedNotifier(), false);
+ QCOMPARE(prop.needsChangedNotifier(), false);
+ QCOMPARE(prop.connectNotifier(0, SLOT(deleteLater())), false);
+ QCOMPARE(prop.connectNotifier(obj, SLOT(deleteLater())), false);
+ QCOMPARE(prop.connectNotifier(obj, 0), false);
+ QCOMPARE(prop.connectNotifier(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
+ QCOMPARE(prop.connectNotifier(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
+ QCOMPARE(prop.connectNotifier(obj, -1), false);
+ QCOMPARE(QString(prop.method().signature()), QString("oddlyNamedNotifySignal()"));
+ QCOMPARE(prop.type(), QDeclarativeProperty::SignalProperty);
+ QCOMPARE(prop.isProperty(), false);
+ QCOMPARE(prop.isDefault(), false);
+ QCOMPARE(prop.isWritable(), false);
+ QCOMPARE(prop.isDesignable(), false);
+ QCOMPARE(prop.isResettable(), false);
+ QCOMPARE(prop.isValid(), true);
+ QCOMPARE(prop.object(), &dobject);
+ QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory);
+ QCOMPARE(prop.propertyType(), 0);
+ QCOMPARE(prop.propertyTypeName(), (const char *)0);
+ QCOMPARE(prop.property().name(), (const char *)0);
+ QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
+ QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding) == 0);
+ QVERIFY(binding == 0);
+ QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
+ QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression) == 0);
+ QVERIFY(expression != 0);
+ QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression);
+ QCOMPARE(prop.coreIndex(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()"));
+ QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
+
+ delete obj;
+ }
}
void tst_qdeclarativeproperty::name()
@@ -742,6 +844,18 @@ void tst_qdeclarativeproperty::name()
}
{
+ PropertyObject o;
+ QDeclarativeProperty p(&o, "onPropertyWithNotifyChanged");
+ QCOMPARE(p.name(), QString("onOddlyNamedNotifySignal"));
+ }
+
+ {
+ QObject o;
+ QDeclarativeProperty p(&o, "onPropertyWithNotifyChanged");
+ QCOMPARE(p.name(), QString());
+ }
+
+ {
QObject o;
QDeclarativeProperty p(&o, "foo");
QCOMPARE(p.name(), QString());
@@ -831,6 +945,18 @@ void tst_qdeclarativeproperty::read()
QCOMPARE(p.read(), QVariant());
}
+ // Automatic signal property
+ {
+ PropertyObject o;
+ QDeclarativeProperty p(&o, "onPropertyWithNotifyChanged");
+ QCOMPARE(p.read(), QVariant());
+
+ QVERIFY(0 == QDeclarativePropertyPrivate::setSignalExpression(p, new QDeclarativeExpression()));
+ QVERIFY(0 != QDeclarativePropertyPrivate::signalExpression(p));
+
+ QCOMPARE(p.read(), QVariant());
+ }
+
// Deleted object
{
PropertyObject *o = new PropertyObject;
@@ -937,6 +1063,20 @@ void tst_qdeclarativeproperty::write()
QVERIFY(0 != QDeclarativePropertyPrivate::signalExpression(p));
}
+ // Automatic signal property
+ {
+ PropertyObject o;
+ QDeclarativeProperty p(&o, "onPropertyWithNotifyChanged");
+ QCOMPARE(p.write(QVariant("console.log(1921)")), false);
+
+ QVERIFY(0 == QDeclarativePropertyPrivate::setSignalExpression(p, new QDeclarativeExpression()));
+ QVERIFY(0 != QDeclarativePropertyPrivate::signalExpression(p));
+
+ QCOMPARE(p.write(QVariant("console.log(1921)")), false);
+
+ QVERIFY(0 != QDeclarativePropertyPrivate::signalExpression(p));
+ }
+
// Value-type property
{
PropertyObject o;
@@ -1066,6 +1206,15 @@ void tst_qdeclarativeproperty::reset()
QCOMPARE(p.isResettable(), false);
QCOMPARE(p.reset(), false);
}
+
+ // Automatic signal property
+ {
+ PropertyObject o;
+ QDeclarativeProperty p(&o, "onPropertyWithNotifyChanged");
+
+ QCOMPARE(p.isResettable(), false);
+ QCOMPARE(p.reset(), false);
+ }
}
void tst_qdeclarativeproperty::writeObjectToList()
diff --git a/tests/auto/declarative/qdeclarativestates/data/basicChanges4.qml b/tests/auto/declarative/qdeclarativestates/data/basicChanges4.qml
new file mode 100644
index 0000000..a373cfc
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativestates/data/basicChanges4.qml
@@ -0,0 +1,19 @@
+import Qt.test 1.0
+import Qt 4.6
+
+MyRectangle {
+ id: rect
+ width: 100; height: 100
+ color: "red"
+
+ states: State {
+ name: "aBlueDay"
+ PropertyChanges {
+ target: rect
+ onPropertyWithNotifyChanged: { rect.color = "blue"; }
+ }
+ }
+
+ Component.onCompleted: rect.state = "aBlueDay"
+}
+
diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
index facf159..8d3ca7a 100644
--- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
+++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
@@ -47,6 +47,29 @@
#include <private/qdeclarativepropertychanges_p.h>
#include <private/qdeclarativestategroup_p.h>
+
+class MyRect : public QDeclarativeRectangle
+{
+ Q_OBJECT
+ Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal)
+public:
+ MyRect() {}
+
+ void doSomething() { emit didSomething(); }
+
+ int propertyWithNotify() const { return m_prop; }
+ void setPropertyWithNotify(int i) { m_prop = i; emit oddlyNamedNotifySignal(); }
+Q_SIGNALS:
+ void didSomething();
+ void oddlyNamedNotifySignal();
+
+private:
+ int m_prop;
+};
+
+QML_DECLARE_TYPE(MyRect)
+
+
class tst_qdeclarativestates : public QObject
{
Q_OBJECT
@@ -85,6 +108,11 @@ private slots:
void reset();
};
+void tst_qdeclarativestates::initTestCase()
+{
+ QML_REGISTER_TYPE(Qt.test, 1, 0, MyRectangle,MyRect);
+}
+
QByteArray tst_qdeclarativestates::fullDataPath(const QString &path)
{
return QUrl::fromLocalFile(SRCDIR + path).toString().toUtf8();
@@ -158,6 +186,28 @@ void tst_qdeclarativestates::basicChanges()
QCOMPARE(rect->border()->width(),1);
}
+
+ {
+ // Test basicChanges4.qml can magically connect to propertyWithNotify's notify
+ // signal using 'onPropertyWithNotifyChanged' even though the signal name is
+ // actually 'oddlyNamedNotifySignal'
+
+ QDeclarativeComponent component(&engine, SRCDIR "/data/basicChanges4.qml");
+ QVERIFY(component.isReady());
+
+ MyRect *rect = qobject_cast<MyRect*>(component.create());
+ QVERIFY(rect != 0);
+
+ QMetaProperty prop = rect->metaObject()->property(rect->metaObject()->indexOfProperty("propertyWithNotify"));
+ QVERIFY(prop.hasNotifySignal());
+ QString notifySignal = QByteArray(prop.notifySignal().signature());
+ QVERIFY(!notifySignal.startsWith("propertyWithNotifyChanged("));
+
+ QCOMPARE(rect->color(), QColor(Qt::red));
+
+ rect->setPropertyWithNotify(100);
+ QCOMPARE(rect->color(), QColor(Qt::blue));
+ }
}
void tst_qdeclarativestates::basicExtension()
@@ -337,23 +387,6 @@ void tst_qdeclarativestates::basicBinding()
}
}
-class MyRect : public QDeclarativeRectangle
-{
- Q_OBJECT
-public:
- MyRect() {}
- void doSomething() { emit didSomething(); }
-Q_SIGNALS:
- void didSomething();
-};
-
-QML_DECLARE_TYPE(MyRect)
-
-void tst_qdeclarativestates::initTestCase()
-{
- QML_REGISTER_TYPE(Qt.test, 1, 0, MyRectangle,MyRect);
-}
-
void tst_qdeclarativestates::signalOverride()
{
QDeclarativeEngine engine;