aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quickcontrols/translation
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quickcontrols/translation')
-rw-r--r--tests/auto/quickcontrols/translation/CMakeLists.txt71
-rw-r--r--tests/auto/quickcontrols/translation/data/comboBox.qml18
-rw-r--r--tests/auto/quickcontrols/translation/data/dialogButtonBox.qml14
-rw-r--r--tests/auto/quickcontrols/translation/data/dialogButtonBoxWithCustomButtons.qml28
-rw-r--r--tests/auto/quickcontrols/translation/data/stackView.qml100
-rw-r--r--tests/auto/quickcontrols/translation/qml_jp.qmbin0 -> 135 bytes
-rw-r--r--tests/auto/quickcontrols/translation/qml_jp.ts28
-rw-r--r--tests/auto/quickcontrols/translation/qtbase_fr.qmbin0 -> 259 bytes
-rw-r--r--tests/auto/quickcontrols/translation/qtbase_fr.ts23
-rw-r--r--tests/auto/quickcontrols/translation/tst_translation.cpp165
10 files changed, 447 insertions, 0 deletions
diff --git a/tests/auto/quickcontrols/translation/CMakeLists.txt b/tests/auto/quickcontrols/translation/CMakeLists.txt
new file mode 100644
index 0000000000..c1c47e139d
--- /dev/null
+++ b/tests/auto/quickcontrols/translation/CMakeLists.txt
@@ -0,0 +1,71 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Generated from translation.pro.
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_translation LANGUAGES C CXX ASM)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+#####################################################################
+## tst_translation Test:
+#####################################################################
+
+# Collect test data
+file(GLOB_RECURSE test_data_glob
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ data/*)
+list(APPEND test_data ${test_data_glob})
+
+qt_internal_add_test(tst_translation
+ SOURCES
+ tst_translation.cpp
+ DEFINES
+ QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols\\\"
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::QmlPrivate
+ Qt::QuickControls2
+ Qt::QuickControls2Private
+ Qt::QuickControlsTestUtilsPrivate
+ Qt::QuickPrivate
+ Qt::QuickTemplates2Private
+ Qt::QuickTest
+ Qt::QuickTestUtilsPrivate
+ Qt::TestPrivate
+ TESTDATA ${test_data}
+)
+
+# Resources:
+set(qmake_immediate_resource_files
+ "qml_jp.qm"
+ "qtbase_fr.qm"
+)
+
+qt_internal_add_resource(tst_translation "qmake_immediate"
+ PREFIX
+ "/"
+ FILES
+ ${qmake_immediate_resource_files}
+)
+
+
+#### Keys ignored in scope 1:.:.:translation.pro:<TRUE>:
+# OTHER_FILES = "data/*.qml"
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_translation CONDITION ANDROID OR IOS
+ DEFINES
+ QT_QMLTEST_DATADIR=\\\":/data\\\"
+)
+
+qt_internal_extend_target(tst_translation CONDITION NOT ANDROID AND NOT IOS
+ DEFINES
+ QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\"
+)
diff --git a/tests/auto/quickcontrols/translation/data/comboBox.qml b/tests/auto/quickcontrols/translation/data/comboBox.qml
new file mode 100644
index 0000000000..e6a58787ae
--- /dev/null
+++ b/tests/auto/quickcontrols/translation/data/comboBox.qml
@@ -0,0 +1,18 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+
+ComboBox {
+ objectName: "comboBox"
+ textRole: "label"
+ model: ListModel {
+ ListElement {
+ label: qsTr("Hello")
+ }
+ ListElement {
+ label: qsTr("ListView")
+ }
+ }
+}
diff --git a/tests/auto/quickcontrols/translation/data/dialogButtonBox.qml b/tests/auto/quickcontrols/translation/data/dialogButtonBox.qml
new file mode 100644
index 0000000000..ababa65019
--- /dev/null
+++ b/tests/auto/quickcontrols/translation/data/dialogButtonBox.qml
@@ -0,0 +1,14 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+
+Item {
+ property Dialog dialog: Dialog {
+ width: 300
+ height: 300
+ visible: true
+ standardButtons: DialogButtonBox.Save | DialogButtonBox.Discard
+ }
+}
diff --git a/tests/auto/quickcontrols/translation/data/dialogButtonBoxWithCustomButtons.qml b/tests/auto/quickcontrols/translation/data/dialogButtonBoxWithCustomButtons.qml
new file mode 100644
index 0000000000..6e8dca8ad5
--- /dev/null
+++ b/tests/auto/quickcontrols/translation/data/dialogButtonBoxWithCustomButtons.qml
@@ -0,0 +1,28 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+
+Item {
+ property Dialog dialog: Dialog {
+ width: 300
+ height: 300
+ visible: true
+
+ footer: DialogButtonBox {
+ Button {
+ objectName: "okButton"
+ text: qsTr("OK")
+
+ DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
+ }
+ Button {
+ objectName: "cancelButton"
+ text: qsTr("Cancel")
+
+ DialogButtonBox.buttonRole: DialogButtonBox.RejectRole
+ }
+ }
+ }
+}
diff --git a/tests/auto/quickcontrols/translation/data/stackView.qml b/tests/auto/quickcontrols/translation/data/stackView.qml
new file mode 100644
index 0000000000..44d85c2ea1
--- /dev/null
+++ b/tests/auto/quickcontrols/translation/data/stackView.qml
@@ -0,0 +1,100 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Window
+
+Window {
+ id: window
+ width: 640
+ height: 480
+
+ property var engine
+
+ signal calledTranslate
+
+ property int pagesCreated: 0
+
+ Component {
+ id: translatePageComponent
+ Item {
+ id: root
+
+ Component.onCompleted: objectName = "translatePageRootItem" + pagesCreated++
+
+ StackView.onActivating: {
+ retranslateTimer.start()
+ }
+
+ Timer {
+ id: retranslateTimer
+ objectName: "retranslateTimer"
+ interval: 100
+ repeat: true
+
+ property int count: 0
+
+ onTriggered: {
+
+ // This triggers the crash without retranslate().
+ // retranslate() got cleverer in 6.2, sidestepping the issue.
+ replaceExit.animations[0].target = null;
+ replaceExit.animations[0].target = replaceExit.ViewTransition.item
+
+ console.log("timer within", root, "is about to call retranslate")
+ window.engine.retranslate()
+ window.calledTranslate()
+ count++
+ if(count >= 10) {
+ stop()
+ count = 0
+ }
+ }
+ }
+
+ Button {
+ objectName: "button"
+ text: qsTr("Push")
+ onClicked: root.StackView.view.replace(translatePageComponent)
+ }
+ }
+ }
+
+ StackView {
+ id: stack
+ objectName: "stackView"
+ anchors.fill: parent
+ initialItem: translatePageComponent
+
+ replaceEnter: Transition {
+ id: replaceEnter
+ objectName: "enterTransition"
+
+ PropertyAnimation {
+ objectName: replaceEnter.objectName + "PropertyAnimation"
+ target: replaceEnter.ViewTransition.item
+ property: "opacity"
+ from: 0
+ to: 1
+ duration: 10
+ }
+
+ }
+
+ replaceExit: Transition {
+ id: replaceExit
+ objectName: "exitTransition"
+
+ PropertyAnimation {
+ objectName: replaceExit.objectName + "PropertyAnimation"
+ target: replaceExit.ViewTransition.item
+ property: "opacity"
+ from: 1
+ to: 0
+ duration: 10
+ }
+ }
+ }
+}
+
diff --git a/tests/auto/quickcontrols/translation/qml_jp.qm b/tests/auto/quickcontrols/translation/qml_jp.qm
new file mode 100644
index 0000000000..a3712e9964
--- /dev/null
+++ b/tests/auto/quickcontrols/translation/qml_jp.qm
Binary files differ
diff --git a/tests/auto/quickcontrols/translation/qml_jp.ts b/tests/auto/quickcontrols/translation/qml_jp.ts
new file mode 100644
index 0000000000..303c142fd8
--- /dev/null
+++ b/tests/auto/quickcontrols/translation/qml_jp.ts
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ja_JP">
+<context>
+ <name>main</name>
+ <message>
+ <location filename="../main.qml" line="8"/>
+ <source>Hello World</source>
+ <translation>こんにちは世界</translation>
+ </message>
+ <message>
+ <location filename="../main.qml" line="12"/>
+ <source>Hello Text</source>
+ <translation>ハローテキスト</translation>
+ </message>
+ <message>
+ <location filename="../main.qml" line="35"/>
+ <source>Hello</source>
+ <translation>こんにちは</translation>
+ </message>
+ <message>
+ <location filename="../main.qml" line="38"/>
+ <source>ListView</source>
+ <translation>リストビュー</translation>
+ </message>
+</context>
+</TS>
+
diff --git a/tests/auto/quickcontrols/translation/qtbase_fr.qm b/tests/auto/quickcontrols/translation/qtbase_fr.qm
new file mode 100644
index 0000000000..176675a820
--- /dev/null
+++ b/tests/auto/quickcontrols/translation/qtbase_fr.qm
Binary files differ
diff --git a/tests/auto/quickcontrols/translation/qtbase_fr.ts b/tests/auto/quickcontrols/translation/qtbase_fr.ts
new file mode 100644
index 0000000000..7aff8bd760
--- /dev/null
+++ b/tests/auto/quickcontrols/translation/qtbase_fr.ts
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="fr_FR">
+<context>
+ <name>QPlatformTheme</name>
+ <message>
+ <source>Save</source>
+ <translation>Enregistrer</translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation>Ne pas tenir compte</translation>
+ </message>
+</context>
+<context>
+ <name>QGnomeTheme</name>
+ <message>
+ <source>&amp;Save</source>
+ <translation>&amp;Enregistrer</translation>
+ </message>
+</context>
+</TS>
+
diff --git a/tests/auto/quickcontrols/translation/tst_translation.cpp b/tests/auto/quickcontrols/translation/tst_translation.cpp
new file mode 100644
index 0000000000..f0798d0367
--- /dev/null
+++ b/tests/auto/quickcontrols/translation/tst_translation.cpp
@@ -0,0 +1,165 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QtTest/qsignalspy.h>
+#include <QtTest/qtest.h>
+#include <QtCore/qtranslator.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformtheme.h>
+#include <QtQuick/qquickview.h>
+#include <QtQuickTestUtils/private/qmlutils_p.h>
+#include <QtQuickTestUtils/private/visualtestutils_p.h>
+#include <QtQuickControlsTestUtils/private/controlstestutils_p.h>
+#include <QtQuickTemplates2/private/qquickabstractbutton_p.h>
+#include <QtQuickTemplates2/private/qquickcombobox_p.h>
+#include <QtQuickTemplates2/private/qquickdialog_p.h>
+#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h>
+#include <QtQuickTemplates2/private/qquicktextfield_p.h>
+#include <QtQuickControls2/qquickstyle.h>
+
+using namespace QQuickControlsTestUtils;
+using namespace QQuickVisualTestUtils;
+
+class tst_translation : public QQmlDataTest
+{
+ Q_OBJECT
+
+public:
+ tst_translation();
+
+private slots:
+ void dialogButtonBox();
+ void dialogButtonBoxWithCustomButtons();
+ void comboBox();
+ void stackView();
+};
+
+tst_translation::tst_translation()
+ : QQmlDataTest(QT_QMLTEST_DATADIR)
+{
+ QQuickStyle::setStyle("Basic");
+}
+
+void tst_translation::dialogButtonBox()
+{
+ QQuickView view(testFileUrl("dialogButtonBox.qml"));
+ if (view.status() != QQuickView::Ready)
+ QFAIL("Failed to load QML file");
+ view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ QQuickDialog *dialog = view.rootObject()->property("dialog").value<QQuickDialog*>();
+ QVERIFY(dialog);
+
+ QQuickDialogButtonBox *dialogButtonBox = qobject_cast<QQuickDialogButtonBox*>(dialog->footer());
+ QVERIFY(dialogButtonBox);
+
+ QQuickAbstractButton *saveButton = dialogButtonBox->standardButton(QPlatformDialogHelper::Save);
+ QVERIFY(saveButton);
+ QString defaultSaveText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Save);
+ defaultSaveText = QPlatformTheme::removeMnemonics(defaultSaveText);
+ QCOMPARE(saveButton->text(), defaultSaveText);
+
+ QQuickAbstractButton *discardButton = dialogButtonBox->standardButton(QPlatformDialogHelper::Discard);
+ QVERIFY(discardButton);
+ QString defaultDiscardText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Discard);
+ defaultDiscardText = QPlatformTheme::removeMnemonics(defaultDiscardText);
+ QCOMPARE(discardButton->text(), defaultDiscardText);
+
+ QTranslator translator;
+ QVERIFY(translator.load("qtbase_fr.qm", ":/"));
+ QVERIFY(qApp->installTranslator(&translator));
+ qApp->sendPostedEvents();
+ view.engine()->retranslate();
+
+ QString translatedSaveText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Save);
+ translatedSaveText = QPlatformTheme::removeMnemonics(translatedSaveText);
+ QCOMPARE(saveButton->text(), translatedSaveText);
+
+ QString translatedDiscardText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Discard);
+ translatedDiscardText = QPlatformTheme::removeMnemonics(translatedDiscardText);
+ QCOMPARE(discardButton->text(), translatedDiscardText);
+}
+
+// Test that custom buttons with explicitly specified text
+// do not have that text overwritten on language changes.
+void tst_translation::dialogButtonBoxWithCustomButtons()
+{
+ // This is just a way of simulating the translator going out of scope
+ // after the QML has been loaded.
+ QScopedPointer<QTranslator> translator(new QTranslator);
+ // Doesn't matter which language it is, as we won't be using it anyway.
+ QVERIFY(translator->load("qtbase_fr.qm", ":/"));
+ QVERIFY(qApp->installTranslator(translator.data()));
+
+ QQuickView view(testFileUrl("dialogButtonBoxWithCustomButtons.qml"));
+ if (view.status() != QQuickView::Ready)
+ QFAIL("Failed to load QML file");
+ view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ QQuickDialog *dialog = view.rootObject()->property("dialog").value<QQuickDialog*>();
+ QVERIFY(dialog);
+
+ QQuickDialogButtonBox *dialogButtonBox = qobject_cast<QQuickDialogButtonBox*>(dialog->footer());
+ QVERIFY(dialogButtonBox);
+
+ auto okButton = dialogButtonBox->findChild<QQuickAbstractButton*>("okButton");
+ QVERIFY(okButton);
+ QCOMPARE(okButton->text(), QLatin1String("OK"));
+
+ QQuickAbstractButton *cancelButton = dialogButtonBox->findChild<QQuickAbstractButton*>("cancelButton");
+ QVERIFY(cancelButton);
+ QCOMPARE(cancelButton->text(), QLatin1String("Cancel"));
+
+ // Delete the translator and hence cause a LanguageChange event,
+ // but _without_ calling QQmlEngine::retranslate(), which would
+ // restore the original bindings and hence not reproduce the issue.
+ translator.reset();
+ QCOMPARE(okButton->text(), QLatin1String("OK"));
+ QCOMPARE(cancelButton->text(), QLatin1String("Cancel"));
+}
+
+void tst_translation::comboBox()
+{
+ QQuickView view(testFileUrl("comboBox.qml"));
+
+ QQuickComboBox *comboBox = qobject_cast<QQuickComboBox*>(view.rootObject());
+ QVERIFY(comboBox);
+ QCOMPARE(comboBox->displayText(), QLatin1String("Hello"));
+
+ QQuickTextField *contentItem = qobject_cast<QQuickTextField*>(comboBox->contentItem());
+ QVERIFY(contentItem);
+ QCOMPARE(contentItem->text(), QLatin1String("Hello"));
+
+ QTranslator translator;
+ QVERIFY(translator.load("qml_jp.qm", ":/"));
+ QVERIFY(qApp->installTranslator(&translator));
+ view.engine()->retranslate();
+ QTRY_COMPARE(comboBox->displayText(), QString::fromUtf8("こんにちは"));
+ QCOMPARE(contentItem->text(), QString::fromUtf8("こんにちは"));
+}
+
+void tst_translation::stackView()
+{
+ QQuickControlsApplicationHelper helper(this, "stackView.qml");
+ QVERIFY2(helper.ready, helper.failureMessage());
+
+ QQuickWindow *window = helper.window;
+ QVERIFY(window->setProperty("engine", QVariant::fromValue(&helper.engine)));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QSignalSpy calledTranslateSpy(window, SIGNAL(calledTranslate()));
+ QVERIFY(calledTranslateSpy.isValid());
+
+ QQuickAbstractButton *button = window->findChild<QQuickAbstractButton*>("button");
+ QVERIFY(button);
+ // Shouldn't crash when calling retranslate.
+ QVERIFY(clickButton(button));
+ QTRY_COMPARE(calledTranslateSpy.size(), 1);
+}
+
+QTEST_MAIN(tst_translation)
+
+#include "tst_translation.moc"