summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qdeclarativebinding.cpp
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2010-04-08 06:13:31 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2010-04-08 06:18:43 (GMT)
commitdf1788b4dbbb2826ae63f26bdf166342595343f4 (patch)
treeb021f683c6da72f9c46d0decbf0f8aa97dd2a9d4 /src/declarative/qml/qdeclarativebinding.cpp
parent942a605a52dbbd6dfa824e3b76e37576c7d79f6e (diff)
downloadQt-df1788b4dbbb2826ae63f26bdf166342595343f4.zip
Qt-df1788b4dbbb2826ae63f26bdf166342595343f4.tar.gz
Qt-df1788b4dbbb2826ae63f26bdf166342595343f4.tar.bz2
Cleanup handling of errors in bindings and scripts
QML used to silently ignore a log of errors - such as a failed assignment to a QObject property. These errors are now all reported as exceptions in JavaScript. Other questionable activities, like assigning a JavaScript array to a "property var" property which appeared to work, thanks to QtScript's transparent conversion of arrays to a QVariantList, are now blocked entirely. QTBUG-9152 QTBUG-9382 QTBUG-9341 QTBUG-6886
Diffstat (limited to 'src/declarative/qml/qdeclarativebinding.cpp')
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp44
1 files changed, 37 insertions, 7 deletions
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index 71cf3cb..9a7a242 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -148,14 +148,46 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
idx, a);
} else {
+ QDeclarativeEnginePrivate *ep = (data->context() && data->context()->engine)?
+ QDeclarativeEnginePrivate::get(data->context()->engine):0;
+
bool isUndefined = false;
- QVariant value = this->value(&isUndefined);
+ QVariant value;
+
+ QScriptValue scriptValue = d->scriptValue(0, &isUndefined);
+ if (data->property.propertyTypeCategory() == QDeclarativeProperty::List) {
+ value = ep->scriptValueToVariant(scriptValue, qMetaTypeId<QList<QObject *> >());
+ } else {
+ value = ep->scriptValueToVariant(scriptValue, data->property.propertyType());
+ if (value.userType() == QMetaType::QObjectStar && !qvariant_cast<QObject*>(value)) {
+ // If the object is null, we extract the predicted type. While this isn't
+ // 100% reliable, in many cases it gives us better error messages if we
+ // assign this null-object to an incompatible property
+ int type = ep->objectClass->objectType(scriptValue);
+ value = QVariant(type, (void *)0);
+ }
+ }
+
+ if (data->error.isValid()) {
+
+ } else if (!scriptValue.isVariant() && value.userType() == QMetaType::QVariantList &&
+ data->property.propertyType() == qMetaTypeId<QVariant>()) {
+
+ // This case catches QtScript's automatic conversion to QVariantList for arrays
+ QUrl url = QUrl(data->url);
+ int line = data->line;
+ if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>"));
+
+ data->error.setUrl(url);
+ data->error.setLine(line);
+ data->error.setColumn(-1);
+ data->error.setDescription(QLatin1String("Unable to assign JavaScript array to QML variant property"));
- if (isUndefined && !data->error.isValid() && data->property.isResettable()) {
+ } else if (isUndefined && data->property.isResettable()) {
data->property.reset();
- } else if (isUndefined && !data->error.isValid()) {
+ } else if (isUndefined) {
QUrl url = QUrl(data->url);
int line = data->line;
@@ -166,7 +198,7 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
data->error.setColumn(-1);
data->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + QLatin1String(QMetaType::typeName(data->property.propertyType())));
- } else if (!isUndefined && data->property.object() &&
+ } else if (data->property.object() &&
!QDeclarativePropertyPrivate::write(data->property, value, flags)) {
QUrl url = QUrl(data->url);
@@ -187,9 +219,7 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
}
if (data->error.isValid()) {
- QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine)?
- QDeclarativeEnginePrivate::get(data->context()->engine):0;
- if (!data->addError(p))
+ if (!data->addError(ep))
qWarning().nospace() << qPrintable(this->error().toString());
} else {
data->removeError();