diff options
Diffstat (limited to 'src/declarative')
-rw-r--r-- | src/declarative/qml/qmlbinding.cpp | 62 | ||||
-rw-r--r-- | src/declarative/qml/qmlbinding_p.h | 6 | ||||
-rw-r--r-- | src/declarative/qml/qmlcomponent.cpp | 17 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine.cpp | 5 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine_p.h | 5 | ||||
-rw-r--r-- | src/declarative/qml/qmlexpression.cpp | 1 | ||||
-rw-r--r-- | src/declarative/qml/qmlexpression_p.h | 2 |
7 files changed, 88 insertions, 10 deletions
diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp index ab4343c..317a4b3 100644 --- a/src/declarative/qml/qmlbinding.cpp +++ b/src/declarative/qml/qmlbinding.cpp @@ -58,10 +58,46 @@ QT_BEGIN_NAMESPACE QML_DEFINE_NOCREATE_TYPE(QmlBinding); QmlBindingData::QmlBindingData() -: updating(false), enabled(false) +: updating(false), enabled(false), nextError(0), prevError(0) { } +QmlBindingData::~QmlBindingData() +{ + removeError(); +} + +void QmlBindingData::removeError() +{ + if (!prevError) return; + + if (nextError) nextError->prevError = prevError; + *prevError = nextError; + nextError = 0; + prevError = 0; +} + +bool QmlBindingData::addError() +{ + if (prevError) return false; + + QmlContext *c = context(); + if (!c) return false; + QmlEngine *e = c->engine(); + if (!e) return false; + + QmlEnginePrivate *p = QmlEnginePrivate::get(e); + + if (p->inProgressCreations == 0) return false; // Not in construction + + prevError = &p->erroredBindings; + nextError = p->erroredBindings; + p->erroredBindings = this; + if (nextError) nextError->prevError = &nextError; + + return true; +} + QmlBindingPrivate::QmlBindingPrivate() : QmlExpressionPrivate(new QmlBindingData) { @@ -131,9 +167,9 @@ void QmlBinding::update(QmlMetaProperty::WriteFlags flags) bool isUndefined = false; QVariant value = this->value(&isUndefined); - if (this->hasError()) { - qWarning().nospace() << qPrintable(this->error().toString()); - } else if (!isUndefined && data->property.object() && !data->property.write(value, flags)) { + if (!isUndefined && data->property.object() && + !data->property.write(value, flags)) { + QString fileName = data->fileName; int line = data->line; if (fileName.isEmpty()) fileName = QLatin1String("<Unknown File>"); @@ -141,9 +177,21 @@ void QmlBinding::update(QmlMetaProperty::WriteFlags flags) const char *valueType = 0; if (value.userType() == QVariant::Invalid) valueType = "null"; else valueType = QMetaType::typeName(value.userType()); - qWarning().nospace() << qPrintable(fileName) << ":" << line - << " Unable to assign " << valueType << " to " - << QMetaType::typeName(data->property.propertyType()); + + data->error.setUrl(fileName); + data->error.setLine(line); + data->error.setColumn(-1); + data->error.setDescription(QLatin1String("Unable to assign ") + + QLatin1String(valueType) + + QLatin1String(" to ") + + QLatin1String(QMetaType::typeName(data->property.propertyType()))); + } + + if (data->error.isValid()) { + if (!data->addError()) + qWarning().nospace() << qPrintable(this->error().toString()); + } else { + data->removeError(); } } diff --git a/src/declarative/qml/qmlbinding_p.h b/src/declarative/qml/qmlbinding_p.h index 2c0c6b9..c9378cb 100644 --- a/src/declarative/qml/qmlbinding_p.h +++ b/src/declarative/qml/qmlbinding_p.h @@ -63,11 +63,17 @@ class QmlBindingData : public QmlExpressionData { public: QmlBindingData(); + virtual ~QmlBindingData(); bool updating:1; bool enabled:1; QmlMetaProperty property; + + void removeError(); + bool addError(); + QmlBindingData *nextError; + QmlBindingData **prevError; }; class QmlBindingPrivate : public QmlExpressionPrivate diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp index 0894758..3767695 100644 --- a/src/declarative/qml/qmlcomponent.cpp +++ b/src/declarative/qml/qmlcomponent.cpp @@ -55,6 +55,7 @@ #include "qmlbinding.h" #include <QtCore/qdebug.h> #include <QApplication> +#include <private/qmlbinding_p.h> #include "qmlscriptparser_p.h" @@ -197,6 +198,12 @@ QmlComponent::QmlComponent(QObject *parent) QmlComponent::~QmlComponent() { Q_D(QmlComponent); + + if (d->completePending) { + qWarning("QmlComponent: Component destroyed while completion pending"); + d->completeCreate(); + } + if (d->typeData) { d->typeData->remWaiter(d); d->typeData->release(); @@ -574,8 +581,10 @@ QmlComponentPrivate::beginCreate(QmlContext *context, const QBitField &bindings) ep->bindValues.clear(); ep->parserStatus.clear(); completePending = true; + QmlEnginePrivate::get(engine)->inProgressCreations++; } + if (rv) { QFx_setParent_noEvent(ctxt, rv); } else { @@ -643,6 +652,14 @@ void QmlComponentPrivate::completeCreate() bindValues.clear(); parserStatus.clear(); completePending = false; + QmlEnginePrivate *p = QmlEnginePrivate::get(engine); + p->inProgressCreations--; + if (0 == p->inProgressCreations) { + while (p->erroredBindings) { + qWarning().nospace() << qPrintable(p->erroredBindings->error.toString()); + p->erroredBindings->removeError(); + } + } } } diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 0e239ce..3da8aa9 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -126,8 +126,9 @@ static QString userLocalDataPath(const QString& app) QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) : rootContext(0), currentExpression(0), isDebugging(false), contextClass(0), objectClass(0), valueTypeClass(0), globalClass(0), - nodeListClass(0), namedNodeMapClass(0), sqlQueryClass(0), cleanup(0), scriptEngine(this), - componentAttacheds(0), rootComponent(0), networkAccessManager(0), typeManager(e), uniqueId(1) + nodeListClass(0), namedNodeMapClass(0), sqlQueryClass(0), cleanup(0), erroredBindings(0), + inProgressCreations(0), scriptEngine(this), componentAttacheds(0), rootComponent(0), + networkAccessManager(0), typeManager(e), uniqueId(1) { QScriptValue qtObject = scriptEngine.newQMetaObject(StaticQtMetaObject::get()); diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index 69b121e..efd26bf 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -98,6 +98,7 @@ class QmlTypeNameCache; class QmlComponentAttached; class QmlListScriptClass; class QmlCleanup; +class QmlBindingData; class QmlEnginePrivate : public QObjectPrivate { @@ -143,6 +144,10 @@ public: // Registered cleanup handlers QmlCleanup *cleanup; + // Bindings that have had errors during startup + QmlBindingData *erroredBindings; + int inProgressCreations; + struct QmlScriptEngine : public QScriptEngine { QmlScriptEngine(QmlEnginePrivate *priv) diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index 8231bf8..e5e5cf9 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -293,6 +293,7 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUnd QFxPerfTimer<QFxPerf::BindValueQt> perfqt; #endif + QmlExpressionData *data = this->data; QmlContextPrivate *ctxtPriv = data->context()->d_func(); QmlEngine *engine = data->context()->engine(); QmlEnginePrivate *ep = QmlEnginePrivate::get(engine); diff --git a/src/declarative/qml/qmlexpression_p.h b/src/declarative/qml/qmlexpression_p.h index b453a96..4e13de3 100644 --- a/src/declarative/qml/qmlexpression_p.h +++ b/src/declarative/qml/qmlexpression_p.h @@ -83,7 +83,7 @@ class QmlExpressionData : public QmlAbstractExpression, public QmlRefCount { public: QmlExpressionData(); - ~QmlExpressionData(); + virtual ~QmlExpressionData(); QmlExpressionPrivate *q; |