aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Koenig <tobias.koenig@kdab.com>2015-09-24 10:24:20 +0200
committerTobias Koenig <tobias.koenig@kdab.com>2015-09-24 11:11:54 +0000
commit61ce37de40711ef2d4a6b4989d8183e1711fc47d (patch)
treede0826e4e555047e10fcb41d3871c3edba4649e8
parentfe7d35e3cbc7b6db42fbc66e26a63d321260cea0 (diff)
Improve warning for QtQml.Binding
Print a warning if there is no property with the given name of the specified target object, or the property is read-only. Change-Id: I5dc2e8330fb1ce53be396b7bf5baf13c1702d2f4 Task-number: QTBUG-39243 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
-rw-r--r--src/qml/types/qqmlbind.cpp36
-rw-r--r--tests/auto/qml/qqmlbinding/data/readonlyProperty.qml13
-rw-r--r--tests/auto/qml/qqmlbinding/data/unknownProperty.qml11
-rw-r--r--tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp34
4 files changed, 91 insertions, 3 deletions
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index a154da8323..df429e5bc1 100644
--- a/src/qml/types/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -36,6 +36,7 @@
#include <private/qqmlnullablevalue_p.h>
#include <private/qqmlproperty_p.h>
#include <private/qqmlbinding_p.h>
+#include <private/qqmlmetatype_p.h>
#include <qqmlengine.h>
#include <qqmlcontext.h>
@@ -49,6 +50,29 @@
QT_BEGIN_NAMESPACE
+namespace {
+
+void validateProperty(QObject *target, const QString &propertyName, QObject *binding)
+{
+ if (!target)
+ return;
+
+ const QMetaObject *mo = target->metaObject();
+ const int index = mo->indexOfProperty(propertyName.toUtf8());
+ if (index == -1) {
+ qmlInfo(binding) << "Property '" << propertyName << "' does not exist on " << QQmlMetaType::prettyTypeName(target) << ".";
+ return;
+ }
+
+ const QMetaProperty mp = mo->property(index);
+ if (!mp.isWritable()) {
+ qmlInfo(binding) << "Property '" << propertyName << "' on " << QQmlMetaType::prettyTypeName(target) << " is read-only.";
+ return;
+ }
+}
+
+}
+
class QQmlBindPrivate : public QObjectPrivate
{
public:
@@ -186,8 +210,10 @@ void QQmlBind::setObject(QObject *obj)
d->when = true;
}
d->obj = obj;
- if (d->componentComplete)
+ if (d->componentComplete) {
+ validateProperty(d->obj, d->propName, this);
d->prop = QQmlProperty(d->obj, d->propName);
+ }
eval();
}
@@ -213,8 +239,10 @@ void QQmlBind::setProperty(const QString &p)
d->when = true;
}
d->propName = p;
- if (d->componentComplete)
+ if (d->componentComplete) {
+ validateProperty(d->obj, d->propName, this);
d->prop = QQmlProperty(d->obj, d->propName);
+ }
eval();
}
@@ -253,8 +281,10 @@ void QQmlBind::componentComplete()
{
Q_D(QQmlBind);
d->componentComplete = true;
- if (!d->prop.isValid())
+ if (!d->prop.isValid()) {
+ validateProperty(d->obj, d->propName, this);
d->prop = QQmlProperty(d->obj, d->propName);
+ }
eval();
}
diff --git a/tests/auto/qml/qqmlbinding/data/readonlyProperty.qml b/tests/auto/qml/qqmlbinding/data/readonlyProperty.qml
new file mode 100644
index 0000000000..fa8d93d355
--- /dev/null
+++ b/tests/auto/qml/qqmlbinding/data/readonlyProperty.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+
+ readonly property string name: "John"
+
+ Binding {
+ target: root
+ property: "name"
+ value: "Doe"
+ }
+}
diff --git a/tests/auto/qml/qqmlbinding/data/unknownProperty.qml b/tests/auto/qml/qqmlbinding/data/unknownProperty.qml
new file mode 100644
index 0000000000..36157bb4e7
--- /dev/null
+++ b/tests/auto/qml/qqmlbinding/data/unknownProperty.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+
+ Binding {
+ target: root
+ property: "unknown"
+ value: 42
+ }
+}
diff --git a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
index 2d267cc668..3e49f3b3c4 100644
--- a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
+++ b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
@@ -50,6 +50,8 @@ private slots:
void restoreBindingWithLoop();
void restoreBindingWithoutCrash();
void deletedObject();
+ void warningOnUnknownProperty();
+ void warningOnReadOnlyProperty();
private:
QQmlEngine engine;
@@ -224,6 +226,38 @@ void tst_qqmlbinding::deletedObject()
delete rect;
}
+void tst_qqmlbinding::warningOnUnknownProperty()
+{
+ QQmlTestMessageHandler messageHandler;
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("unknownProperty.qml"));
+ QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QVERIFY(item);
+ delete item;
+
+ QCOMPARE(messageHandler.messages().count(), 1);
+
+ const QString expectedMessage = c.url().toString() + QLatin1String(":6:5: QML Binding: Property 'unknown' does not exist on Item.");
+ QCOMPARE(messageHandler.messages().first(), expectedMessage);
+}
+
+void tst_qqmlbinding::warningOnReadOnlyProperty()
+{
+ QQmlTestMessageHandler messageHandler;
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("readonlyProperty.qml"));
+ QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QVERIFY(item);
+ delete item;
+
+ QCOMPARE(messageHandler.messages().count(), 1);
+
+ const QString expectedMessage = c.url().toString() + QLatin1String(":8:5: QML Binding: Property 'name' on Item is read-only.");
+ QCOMPARE(messageHandler.messages().first(), expectedMessage);
+}
+
QTEST_MAIN(tst_qqmlbinding)
#include "tst_qqmlbinding.moc"