diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2020-03-24 11:21:25 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2020-04-02 22:23:04 +0200 |
commit | e40098c5303e7af4b12c64093b120405c63fdf8d (patch) | |
tree | 9636894ed820567731f9b4dd41870392ce052a70 | |
parent | 63bf6ac4c483cc64b48c410c6e1afb404f2bcbd1 (diff) |
Add support for translation bindings on QProperty based properties
Change-Id: I439653123cdc96df97a1801664655c9d28a8b9b5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r-- | src/qml/jsapi/qjsengine_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlapplicationengine.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertybinding.cpp | 24 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertybinding_p.h | 12 | ||||
-rw-r--r-- | tests/auto/qml/qqmltranslation/.prev_CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/auto/qml/qqmltranslation/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml | 3 | ||||
-rw-r--r-- | tests/auto/qml/qqmltranslation/data/translationChange.qml | 1 | ||||
-rw-r--r-- | tests/auto/qml/qqmltranslation/qqmltranslation.pro | 2 | ||||
-rw-r--r-- | tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp | 15 |
11 files changed, 64 insertions, 10 deletions
diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h index 37376a1485..0aff6595b6 100644 --- a/src/qml/jsapi/qjsengine_p.h +++ b/src/qml/jsapi/qjsengine_p.h @@ -53,6 +53,7 @@ #include <QtCore/private/qobject_p.h> #include <QtCore/qmutex.h> +#include <QtCore/qproperty.h> #include "qjsengine.h" #include "private/qtqmlglobal_p.h" #include <private/qqmlmetatype_p.h> @@ -107,7 +108,7 @@ public: // Shared by QQmlEngine mutable QRecursiveMutex mutex; - QString uiLanguage; + QProperty<QString> uiLanguage; // These methods may be called from the QML loader thread inline QQmlPropertyCache *cache(QObject *obj, QTypeRevision version = QTypeRevision()); diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index a633d3f58b..6fe8dc5227 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -95,7 +95,7 @@ void QQmlApplicationEnginePrivate::_q_loadTranslations() Q_Q(QQmlApplicationEngine); QScopedPointer<QTranslator> translator(new QTranslator); - if (!uiLanguage.isEmpty()) { + if (!uiLanguage.value().isEmpty()) { QLocale locale(uiLanguage); if (translator->load(locale, QLatin1String("qml"), QLatin1String("_"), translationsDirectory, QLatin1String(".qm"))) { if (activeTranslator) diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 2ee2969d43..564835ff8b 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -919,9 +919,13 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper bs->takeExpression(expr); } else if (bindingProperty->isQProperty()) { - // ### TODO: support binding->isTranslationBinding() - QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex]; - auto qmlBinding = QQmlPropertyBinding::create(bindingProperty, runtimeFunction, _scopeObject, context, currentQmlContext()); + QUntypedPropertyBinding qmlBinding; + if (binding->isTranslationBinding()) { + qmlBinding = QQmlTranslationPropertyBinding::create(bindingProperty, compilationUnit, binding); + } else { + QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex]; + qmlBinding = QQmlPropertyBinding::create(bindingProperty, runtimeFunction, _scopeObject, context, currentQmlContext()); + } void *argv[] = { &qmlBinding }; _bindingTarget->qt_metacall(QMetaObject::SetQPropertyBinding, bindingProperty->coreIndex(), argv); } else { diff --git a/src/qml/qml/qqmlpropertybinding.cpp b/src/qml/qml/qqmlpropertybinding.cpp index ca64cf412a..9fffafa649 100644 --- a/src/qml/qml/qqmlpropertybinding.cpp +++ b/src/qml/qml/qqmlpropertybinding.cpp @@ -57,7 +57,7 @@ QUntypedPropertyBinding QQmlPropertyBinding::create(const QQmlPropertyData *pd, void QQmlPropertyBinding::expressionChanged() { - setDirty(true); + markDirtyAndNotifyObservers(); } QQmlPropertyBinding::QQmlPropertyBinding(const QMetaType &mt) @@ -98,4 +98,26 @@ QUntypedPropertyBinding::BindingEvaluationResult QQmlPropertyBinding::evaluateAn return true; } +QUntypedPropertyBinding QQmlTranslationPropertyBinding::create(const QQmlPropertyData *pd, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding) +{ + auto translationBinding = [compilationUnit, binding](const QMetaType &metaType, void *dataPtr) { + // Create a dependency to the uiLanguage + QJSEnginePrivate::get(compilationUnit->engine)->uiLanguage.value(); + + QVariant resultVariant(compilationUnit->bindingValueAsString(binding)); + if (metaType.id() != QMetaType::QString) + resultVariant.convert(metaType.id()); + + int compareResult = 0; + if (QMetaType::compare(dataPtr, resultVariant.constData(), metaType.id(), &compareResult) + && compareResult == 0) + return false; + QMetaType::destruct(metaType.id(), dataPtr); + QMetaType::construct(metaType.id(), dataPtr, resultVariant.constData()); + return true; + }; + + return QUntypedPropertyBinding(QMetaType(pd->propType()), translationBinding, QPropertyBindingSourceLocation()); +} + QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlpropertybinding_p.h b/src/qml/qml/qqmlpropertybinding_p.h index 3bd6772413..5097f40e6f 100644 --- a/src/qml/qml/qqmlpropertybinding_p.h +++ b/src/qml/qml/qqmlpropertybinding_p.h @@ -61,8 +61,8 @@ QT_BEGIN_NAMESPACE -class QQmlPropertyBinding final : public QQmlJavaScriptExpression, - public QPropertyBindingPrivate +class QQmlPropertyBinding : public QQmlJavaScriptExpression, + public QPropertyBindingPrivate { public: static QUntypedPropertyBinding create(const QQmlPropertyData *pd, QV4::Function *function, @@ -78,6 +78,14 @@ private: void *dataPtr); }; +class QQmlTranslationPropertyBinding +{ +public: + static QUntypedPropertyBinding create(const QQmlPropertyData *pd, + const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, + const QV4::CompiledData::Binding *binding); +}; + QT_END_NAMESPACE #endif // QQMLPROPERTYBINDING_P_H diff --git a/tests/auto/qml/qqmltranslation/.prev_CMakeLists.txt b/tests/auto/qml/qqmltranslation/.prev_CMakeLists.txt index f62dfd9a3e..576f836cf9 100644 --- a/tests/auto/qml/qqmltranslation/.prev_CMakeLists.txt +++ b/tests/auto/qml/qqmltranslation/.prev_CMakeLists.txt @@ -21,6 +21,7 @@ qt_add_test(tst_qqmltranslation Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::Quick TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmltranslation/CMakeLists.txt b/tests/auto/qml/qqmltranslation/CMakeLists.txt index 8e280cc1de..8b665dd1b5 100644 --- a/tests/auto/qml/qqmltranslation/CMakeLists.txt +++ b/tests/auto/qml/qqmltranslation/CMakeLists.txt @@ -21,6 +21,7 @@ qt_add_test(tst_qqmltranslation Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::Quick TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml b/tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml index 294fff3284..0d994761c4 100644 --- a/tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml +++ b/tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml @@ -1,5 +1,6 @@ import QtQuick 2.0 +import Test 1.0 -Item { +CppTranslationBase { property string baseProperty: qsTr("translate me"); } diff --git a/tests/auto/qml/qqmltranslation/data/translationChange.qml b/tests/auto/qml/qqmltranslation/data/translationChange.qml index ae3231935c..54ba82018d 100644 --- a/tests/auto/qml/qqmltranslation/data/translationChange.qml +++ b/tests/auto/qml/qqmltranslation/data/translationChange.qml @@ -18,6 +18,7 @@ TranslationChangeBase { property string text2: weDoTranslations() property string text3 property string fromListModel: listModel.get(0).text + qProperty: qsTr("translate me") states: [ State { diff --git a/tests/auto/qml/qqmltranslation/qqmltranslation.pro b/tests/auto/qml/qqmltranslation/qqmltranslation.pro index ac329a204b..266ad51a79 100644 --- a/tests/auto/qml/qqmltranslation/qqmltranslation.pro +++ b/tests/auto/qml/qqmltranslation/qqmltranslation.pro @@ -9,4 +9,4 @@ include (../../shared/util.pri) TESTDATA = data/* -QT += core-private gui-private qml-private testlib +QT += core-private gui-private qml-private testlib quick diff --git a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp index a75a00bd01..bb5a5bf7e3 100644 --- a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp +++ b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp @@ -31,6 +31,7 @@ #include <QQmlComponent> #include <QTranslator> #include <QQmlContext> +#include <QQuickItem> #include <private/qqmlengine_p.h> #include <private/qqmltypedata_p.h> #include "../../shared/util.h" @@ -165,6 +166,15 @@ void tst_qqmltranslation::idTranslation() delete object; } +class CppTranslationBase : public QQuickItem +{ + Q_OBJECT + QML_ELEMENT + Q_PROPERTY(QString qProperty) + + QProperty<QString> qProperty; +}; + class DummyTranslator : public QTranslator { Q_OBJECT @@ -193,6 +203,8 @@ void tst_qqmltranslation::translationChange() { QQmlEngine engine; + qmlRegisterTypesAndRevisions<CppTranslationBase>("Test", 1); + QQmlComponent component(&engine, testFileUrl("translationChange.qml")); QScopedPointer<QObject> object(component.create()); QVERIFY(!object.isNull()); @@ -202,18 +214,21 @@ void tst_qqmltranslation::translationChange() QCOMPARE(object->property("text2").toString(), QString::fromUtf8("translate me")); QCOMPARE(object->property("text3").toString(), QString::fromUtf8("translate me")); QCOMPARE(object->property("fromListModel").toString(), QString::fromUtf8("translate me")); + QCOMPARE(object->property("qProperty").toString(), QString::fromUtf8("translate me")); DummyTranslator translator; QCoreApplication::installTranslator(&translator); QEvent ev(QEvent::LanguageChange); QCoreApplication::sendEvent(&engine, &ev); + engine.setUiLanguage("xxx"); QCOMPARE(object->property("baseProperty").toString(), QString::fromUtf8("do not translate")); QCOMPARE(object->property("text1").toString(), QString::fromUtf8("xxx")); QCOMPARE(object->property("text2").toString(), QString::fromUtf8("xxx")); QCOMPARE(object->property("text3").toString(), QString::fromUtf8("xxx")); QCOMPARE(object->property("fromListModel").toString(), QString::fromUtf8("xxx")); + QCOMPARE(object->property("qProperty").toString(), QString::fromUtf8("xxx")); QCoreApplication::removeTranslator(&translator); } |