aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2020-03-24 11:21:25 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2020-04-02 22:23:04 +0200
commite40098c5303e7af4b12c64093b120405c63fdf8d (patch)
tree9636894ed820567731f9b4dd41870392ce052a70
parent63bf6ac4c483cc64b48c410c6e1afb404f2bcbd1 (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.h3
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp10
-rw-r--r--src/qml/qml/qqmlpropertybinding.cpp24
-rw-r--r--src/qml/qml/qqmlpropertybinding_p.h12
-rw-r--r--tests/auto/qml/qqmltranslation/.prev_CMakeLists.txt1
-rw-r--r--tests/auto/qml/qqmltranslation/CMakeLists.txt1
-rw-r--r--tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml3
-rw-r--r--tests/auto/qml/qqmltranslation/data/translationChange.qml1
-rw-r--r--tests/auto/qml/qqmltranslation/qqmltranslation.pro2
-rw-r--r--tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp15
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);
}