QQmlBinding * QQmlBinding::createBinding(Identifier id, QObject *obj, QQmlContext *ctxt) { if (id < 0) return 0; QQmlBinding *rv = 0; QQmlContextData *ctxtdata = QQmlContextData::get(ctxt); QQmlEnginePrivate *engine = QQmlEnginePrivate::get(ctxt->engine()); if (engine && ctxtdata && !ctxtdata->url.isEmpty()) { QQmlTypeData *typeData = engine->typeLoader.getType(ctxtdata->url); Q_ASSERT(typeData); if (QQmlCompiledData *cdata = typeData->compiledData()) { QV4::ExecutionEngine *v4 = engine->v4engine(); QV4::Scope valueScope(v4); QV4::Function *runtimeFunction = cdata->compilationUnit->runtimeFunctions[cdata->customParserBindings[id]]; QV4::ScopedValue function(valueScope, QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxtdata, obj, runtimeFunction)); rv = new QQmlBinding(function, obj, ctxtdata); } typeData->release(); } return rv; }
QQmlBinding * QQmlBinding::createBinding(Identifier id, QObject *obj, QQmlContext *ctxt, const QString &url, quint16 lineNumber) { if (id < 0) return 0; QQmlBinding *rv = 0; QQmlContextData *ctxtdata = QQmlContextData::get(ctxt); if (ctxt->engine() && ctxtdata && !ctxtdata->url.isEmpty()) { QQmlEnginePrivate *engine = QQmlEnginePrivate::get(ctxt->engine()); if (engine) { QQmlTypeData *typeData = engine->typeLoader.getType(ctxtdata->url); Q_ASSERT(typeData); if (QQmlCompiledData *cdata = typeData->compiledData()) { rv = new QQmlBinding(cdata->primitives.at(id), true, obj, ctxtdata, url, lineNumber, 0); } typeData->release(); } } return rv; }
QQmlBinding::QQmlBinding(const QQmlScriptString &script, QObject *obj, QQmlContext *ctxt) : QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding) { if (ctxt && !ctxt->isValid()) return; const QQmlScriptStringPrivate *scriptPrivate = script.d.data(); if (!ctxt && (!scriptPrivate->context || !scriptPrivate->context->isValid())) return; bool needRewrite = true; QString code; int id = scriptPrivate->bindingId; if (id >= 0) { QQmlContextData *ctxtdata = QQmlContextData::get(scriptPrivate->context); QQmlEnginePrivate *engine = QQmlEnginePrivate::get(scriptPrivate->context->engine()); if (engine && ctxtdata && !ctxtdata->url.isEmpty()) { QQmlTypeData *typeData = engine->typeLoader.getType(ctxtdata->url); Q_ASSERT(typeData); if (QQmlCompiledData *cdata = typeData->compiledData()) { needRewrite = false; code = cdata->primitives.at(id); m_url = cdata->name; } typeData->release(); } } if (needRewrite) { QQmlRewrite::RewriteBinding rewriteBinding; code = rewriteBinding(scriptPrivate->script); } setNotifyOnValueChanged(true); QQmlAbstractExpression::setContext(QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context)); setScopeObject(obj ? obj : scriptPrivate->scope); m_expression = scriptPrivate->script.toUtf8(); m_lineNumber = scriptPrivate->lineNumber; m_columnNumber = scriptPrivate->columnNumber; v8function = evalFunction(context(), scopeObject(), code, QString(), m_lineNumber); }
void tst_qqmltranslation::idTranslation() { QTranslator translator; translator.load(QLatin1String("qmlid_fr"), dataDirectory()); QCoreApplication::installTranslator(&translator); QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("idtranslation.qml")); QObject *object = component.create(); QVERIFY(object != 0); { QQmlContext *context = qmlContext(object); QQmlEnginePrivate *engine = QQmlEnginePrivate::get(context->engine()); QQmlTypeData *typeData = engine->typeLoader.getType(context->baseUrl()); QQmlCompiledData *cdata = typeData->compiledData(); QVERIFY(cdata); const QV4::CompiledData::Unit *unit = cdata->compilationUnit->data; const QV4::CompiledData::Object *rootObject = unit->objectAt(unit->indexOfRootObject); const QV4::CompiledData::Binding *binding = rootObject->bindingTable(); for (quint32 i = 0; i < rootObject->nBindings; ++i, ++binding) { const QString propertyName = unit->stringAt(binding->propertyNameIndex); if (propertyName == "idTranslation") { if (binding->type != QV4::CompiledData::Binding::Type_TranslationById) qDebug() << "binding for property" << propertyName << "is not a compiled translation"; QCOMPARE(binding->type, quint32(QV4::CompiledData::Binding::Type_TranslationById)); } else { QVERIFY(binding->type != QV4::CompiledData::Binding::Type_Translation); } } } QCOMPARE(object->property("idTranslation").toString(), QLatin1String("bonjour tout le monde")); QCOMPARE(object->property("idTranslation2").toString(), QLatin1String("bonjour tout le monde")); QCOMPARE(object->property("idTranslation3").toString(), QLatin1String("bonjour tout le monde")); QCoreApplication::removeTranslator(&translator); delete object; }
QQmlBinding::QQmlBinding(const QQmlScriptString &script, QObject *obj, QQmlContext *ctxt) : QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding) { if (ctxt && !ctxt->isValid()) return; const QQmlScriptStringPrivate *scriptPrivate = script.d.data(); if (!ctxt && (!scriptPrivate->context || !scriptPrivate->context->isValid())) return; QString url; QV4::Function *runtimeFunction = 0; QQmlContextData *ctxtdata = QQmlContextData::get(scriptPrivate->context); QQmlEnginePrivate *engine = QQmlEnginePrivate::get(scriptPrivate->context->engine()); if (engine && ctxtdata && !ctxtdata->url.isEmpty()) { QQmlTypeData *typeData = engine->typeLoader.getType(ctxtdata->url); Q_ASSERT(typeData); if (QQmlCompiledData *cdata = typeData->compiledData()) { url = cdata->name; if (scriptPrivate->bindingId != QQmlBinding::Invalid) runtimeFunction = cdata->compilationUnit->runtimeFunctions.at(scriptPrivate->bindingId); } typeData->release(); } setNotifyOnValueChanged(true); QQmlAbstractExpression::setContext(QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context)); setScopeObject(obj ? obj : scriptPrivate->scope); if (runtimeFunction) { v4function = QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxtdata, scopeObject(), runtimeFunction); } else { QString code = scriptPrivate->script; v4function = qmlBinding(context(), scopeObject(), code, url, scriptPrivate->lineNumber); } }
void tst_qqmltranslation::translation() { QFETCH(QString, translation); QFETCH(QUrl, testFile); QFETCH(bool, verifyCompiledData); QTranslator translator; translator.load(translation, dataDirectory()); QCoreApplication::installTranslator(&translator); QQmlEngine engine; QQmlComponent component(&engine, testFile); QObject *object = component.create(); QVERIFY(object != 0); if (verifyCompiledData) { QQmlContext *context = qmlContext(object); QQmlEnginePrivate *engine = QQmlEnginePrivate::get(context->engine()); QQmlTypeData *typeData = engine->typeLoader.getType(context->baseUrl()); QQmlCompiledData *cdata = typeData->compiledData(); QVERIFY(cdata); QSet<QString> compiledTranslations; compiledTranslations << QStringLiteral("basic") << QStringLiteral("disambiguation") << QStringLiteral("singular") << QStringLiteral("plural"); const QV4::CompiledData::Unit *unit = cdata->compilationUnit->data; const QV4::CompiledData::Object *rootObject = unit->objectAt(unit->indexOfRootObject); const QV4::CompiledData::Binding *binding = rootObject->bindingTable(); for (quint32 i = 0; i < rootObject->nBindings; ++i, ++binding) { const QString propertyName = unit->stringAt(binding->propertyNameIndex); const bool expectCompiledTranslation = compiledTranslations.contains(propertyName); if (expectCompiledTranslation) { if (binding->type != QV4::CompiledData::Binding::Type_Translation) qDebug() << "binding for property" << propertyName << "is not a compiled translation"; QCOMPARE(binding->type, quint32(QV4::CompiledData::Binding::Type_Translation)); } else { if (binding->type == QV4::CompiledData::Binding::Type_Translation) qDebug() << "binding for property" << propertyName << "is not supposed to be a compiled translation"; QVERIFY(binding->type != QV4::CompiledData::Binding::Type_Translation); } } } QCOMPARE(object->property("basic").toString(), QLatin1String("bonjour")); QCOMPARE(object->property("basic2").toString(), QLatin1String("au revoir")); QCOMPARE(object->property("basic3").toString(), QLatin1String("bonjour")); QCOMPARE(object->property("disambiguation").toString(), QLatin1String("salut")); QCOMPARE(object->property("disambiguation2").toString(), QString::fromUtf8("\xc3\xa0 plus tard")); QCOMPARE(object->property("disambiguation3").toString(), QLatin1String("salut")); QCOMPARE(object->property("noop").toString(), QLatin1String("bonjour")); QCOMPARE(object->property("noop2").toString(), QLatin1String("au revoir")); QCOMPARE(object->property("singular").toString(), QLatin1String("1 canard")); QCOMPARE(object->property("singular2").toString(), QLatin1String("1 canard")); QCOMPARE(object->property("plural").toString(), QLatin1String("2 canards")); QCOMPARE(object->property("plural2").toString(), QLatin1String("2 canards")); QCoreApplication::removeTranslator(&translator); delete object; }