diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-10-28 04:57:16 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-10-28 04:57:16 (GMT) |
commit | d42846123ec17641d1e8a8082fab0d04ce93e8a1 (patch) | |
tree | cb3e89e38a1a441870e1bc89c9f732a57449b7c5 /src/declarative | |
parent | eaab2a271f0d73d5a413902169efe32741208c42 (diff) | |
download | Qt-d42846123ec17641d1e8a8082fab0d04ce93e8a1.zip Qt-d42846123ec17641d1e8a8082fab0d04ce93e8a1.tar.gz Qt-d42846123ec17641d1e8a8082fab0d04ce93e8a1.tar.bz2 |
Do not display transient binding errors
During QML startup, it is common to have "errors" in bindings as the apps
state stabilizes. These are not real errors, but just a consequence of
implementing a declarative UI in an imperative world. Now during startup,
the display of errors is delayed until the startup completes, and then only
bindings that are still in an error state are displayed.
QT-2373
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; |