void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) { Q_D(QDeclarativeBinding); if (!d->enabled || !d->context() || !d->context()->isValid()) return; if (!d->updating) { d->updating = true; bool wasDeleted = false; d->deleted = &wasDeleted; if (d->property.propertyType() == qMetaTypeId<QDeclarativeBinding *>()) { int idx = d->property.index(); Q_ASSERT(idx != -1); QDeclarativeBinding *t = this; int status = -1; void *a[] = { &t, 0, &status, &flags }; QMetaObject::metacall(d->property.object(), QMetaObject::WriteProperty, idx, a); if (wasDeleted) return; } else { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(d->context()->engine); bool isUndefined = false; QVariant value; QScriptValue scriptValue = d->scriptValue(0, &isUndefined); if (wasDeleted) return; if (d->property.propertyTypeCategory() == QDeclarativeProperty::List) { value = ep->scriptValueToVariant(scriptValue, qMetaTypeId<QList<QObject *> >()); } else if (scriptValue.isNull() && d->property.propertyTypeCategory() == QDeclarativeProperty::Object) { value = QVariant::fromValue((QObject *)0); } else { value = ep->scriptValueToVariant(scriptValue, d->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); QObject *o = 0; value = QVariant(type, (void *)&o); } } if (d->error.isValid()) { } else if (isUndefined && d->property.isResettable()) { d->property.reset(); } else if (isUndefined && d->property.propertyType() == qMetaTypeId<QVariant>()) { QDeclarativePropertyPrivate::write(d->property, QVariant(), flags); } else if (isUndefined) { QUrl url = QUrl(d->url); int line = d->line; if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>")); d->error.setUrl(url); d->error.setLine(line); d->error.setColumn(-1); d->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + QLatin1String(QMetaType::typeName(d->property.propertyType())) + QLatin1String(" ") + d->property.name()); } else if (!scriptValue.isRegExp() && scriptValue.isFunction()) { QUrl url = QUrl(d->url); int line = d->line; if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>")); d->error.setUrl(url); d->error.setLine(line); d->error.setColumn(-1); d->error.setDescription(QLatin1String("Unable to assign a function to a property.")); } else if (d->property.object() && !QDeclarativePropertyPrivate::write(d->property, value, flags)) { if (wasDeleted) return; QUrl url = QUrl(d->url); int line = d->line; if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>")); const char *valueType = 0; if (value.userType() == QVariant::Invalid) valueType = "null"; else valueType = QMetaType::typeName(value.userType()); d->error.setUrl(url); d->error.setLine(line); d->error.setColumn(-1); d->error.setDescription(QLatin1String("Unable to assign ") + QLatin1String(valueType) + QLatin1String(" to ") + QLatin1String(QMetaType::typeName(d->property.propertyType()))); } if (wasDeleted) return; if (d->error.isValid()) { if (!d->addError(ep)) ep->warning(this->error()); } else { d->removeError(); } } d->updating = false; d->deleted = 0; } else { qmlInfo(d->property.object()) << tr("Binding loop detected for property \"%1\"").arg(d->property.name()); } }
void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script) { if (!engine) return; QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); const QString &code = script.code; const QString &url = script.file; const QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = script.pragmas; Q_ASSERT(!url.isEmpty()); if (pragmas & QDeclarativeParser::Object::ScriptBlock::Shared) { QHash<QString, QScriptValue>::Iterator iter = enginePriv->m_sharedScriptImports.find(url); if (iter == enginePriv->m_sharedScriptImports.end()) { QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); scriptContext->pushScope(enginePriv->contextClass->newUrlContext(url)); scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject()); QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine); scriptContext->pushScope(scope); scriptEngine->evaluate(code, url, 1); if (scriptEngine->hasUncaughtException()) { QDeclarativeError error; QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); enginePriv->warning(error); } scriptEngine->popContext(); iter = enginePriv->m_sharedScriptImports.insert(url, scope); } importedScripts.append(*iter); } else { QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); scriptContext->pushScope(enginePriv->contextClass->newUrlContext(this, 0, url)); scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject()); QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine); scriptContext->pushScope(scope); scriptEngine->evaluate(code, url, 1); if (scriptEngine->hasUncaughtException()) { QDeclarativeError error; QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); enginePriv->warning(error); } scriptEngine->popContext(); importedScripts.append(scope); } }