summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/qml/qmlbinding.cpp62
-rw-r--r--src/declarative/qml/qmlbinding_p.h6
-rw-r--r--src/declarative/qml/qmlcomponent.cpp17
-rw-r--r--src/declarative/qml/qmlengine.cpp5
-rw-r--r--src/declarative/qml/qmlengine_p.h5
-rw-r--r--src/declarative/qml/qmlexpression.cpp1
-rw-r--r--src/declarative/qml/qmlexpression_p.h2
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;