Add basic translation support 23/13023/4
authorTasuku Suzuki <tasuku.suzuki@qt.io>
Wed, 27 Dec 2017 11:34:03 +0000 (20:34 +0900)
committerRomain Forlot <romain.forlot@iot.bzh>
Fri, 29 Dec 2017 16:26:33 +0000 (17:26 +0100)
Added French and Japanese translations

Change-Id: I58eca5ffaad2367a4dd26b6472bdbcd45c957061
Signed-off-by: Tasuku Suzuki <tasuku.suzuki@qt.io>
Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
app/HVAC.qml
app/HeatDegree.qml
app/app.pro
app/main.cpp
app/translations.pri [new file with mode: 0644]
app/translations/hvac_fr_FR.ts [new file with mode: 0644]
app/translations/hvac_ja_JP.ts [new file with mode: 0644]
app/translator.cpp [new file with mode: 0644]
app/translator.h [new file with mode: 0644]

index b3be443..c375f2f 100644 (file)
@@ -18,11 +18,17 @@ import QtQuick 2.6
 import QtQuick.Layouts 1.1
 import QtQuick.Controls 2.0
 import AGL.Demo.Controls 1.0
+import Translator 1.0
 import 'api' as API
 
 ApplicationWindow {
     id: root
 
+    Translator {
+        id: translator
+//        language: 'ja_JP'
+    }
+
     API.Binding {
         id: binding
         url: bindingAddress
@@ -57,7 +63,7 @@ ApplicationWindow {
                     anchors.left: fanSpeedSlider.left
                     anchors.top: fanSpeedSlider.bottom
                     font.pixelSize: 32
-                    text: 'FAN SPEED'
+                    text: translator.translate(qsTr('FAN SPEED'), translator.language)
                 }
             }
         }
@@ -89,7 +95,7 @@ ApplicationWindow {
                     Label {
                         anchors.centerIn: parent
                         color: parent.checked ? '#00ADDC' : '#848286'
-                        text: 'A/C'
+                        text: translator.translate(qsTr('A/C'), translator.language)
                         font.pixelSize: parent.height / 3
                     }
                     onCheckedChanged: {
@@ -102,7 +108,7 @@ ApplicationWindow {
                     Label {
                         anchors.centerIn: parent
                         color: parent.checked ? '#00ADDC' : '#848286'
-                        text: 'AUTO'
+                        text: translator.translate(qsTr('AUTO'), translator.language)
                         font.pixelSize: parent.height / 3
                     }
                     onCheckedChanged: {
index aa5770a..a9bc83c 100644 (file)
@@ -28,11 +28,11 @@ ListView {
     property int degree: currentIndex > -1 ? model.get(currentIndex).value : -1
     model: ListModel {
         Component.onCompleted: {
-            append({value: 15, modelData: 'LO'})
+            append({value: 15, modelData: translator.translate(qsTr('LO'), translator.language)})
             for (var d = 16; d < 30; d++) {
-                append({value: d, modelData: d.toFixed(0) + '\u00b0'})
+                append({value: d, modelData: translator.translate(qsTr('%1\u00b0'), translator.language).arg(d.toFixed(0))})
             }
-            append({value: 30, modelData: 'HI'})
+            append({value: 30, modelData: translator.translate(qsTr('HI'), translator.language)})
         }
     }
     delegate: Label {
@@ -41,7 +41,7 @@ ListView {
         horizontalAlignment: Label.AlignHCenter
         verticalAlignment: Label.AlignVCenter
         text: model.modelData
-        font.pixelSize: height * 0.8
+        font.pixelSize: height * 0.7
         color: (ListView.view.enabled && ListView.isCurrentItem) ? '#00ADDC' : 'white'
     }
 
index da4e8a4..edd08aa 100644 (file)
@@ -1,10 +1,17 @@
 TARGET = hvac
 QT = quick qml
 
-SOURCES = main.cpp
+HEADERS += \
+    translator.h
+
+SOURCES = main.cpp \
+    translator.cpp
 
 RESOURCES += \
     hvac.qrc \
     images/images.qrc
 
 include(app.pri)
+
+LANGUAGES = ja_JP fr_FR
+include(translations.pri)
index b793ef3..211f52b 100644 (file)
@@ -22,6 +22,8 @@
 #include <QtQml/QQmlContext>
 #include <QtQuick/QQuickWindow>
 
+#include "translator.h"
+
 #ifdef HAVE_LIBHOMESCREEN
 #include <libhomescreen.hpp>
 #endif
@@ -46,13 +48,17 @@ int main(int argc, char *argv[])
     parser.process(app);
     QStringList positionalArguments = parser.positionalArguments();
 
+    qmlRegisterType<Translator>("Translator", 1, 0, "Translator");
+
     QQmlApplicationEngine engine;
     QQmlContext *context = engine.rootContext();
     QUrl bindingAddress;
 
+    int port;
+    QString secret;
     if (positionalArguments.length() == 2) {
-        int port = positionalArguments.takeFirst().toInt();
-        QString secret = positionalArguments.takeFirst();
+        port = positionalArguments.takeFirst().toInt();
+        secret = positionalArguments.takeFirst();
         bindingAddress.setScheme(QStringLiteral("ws"));
         bindingAddress.setHost(QStringLiteral("localhost"));
         bindingAddress.setPort(port);
diff --git a/app/translations.pri b/app/translations.pri
new file mode 100644 (file)
index 0000000..81bd94b
--- /dev/null
@@ -0,0 +1,16 @@
+defineReplace(prependAll) {
+    for(a,$$1):result += $$2$${a}$$3
+    return($$result)
+}
+
+qtPrepareTool(QMAKE_LRELEASE, lrelease)
+TRANSLATIONS = $$prependAll(LANGUAGES, $$PWD/translations/$${TARGET}_,.ts)
+
+qm.depends = $${TRANSLATIONS}
+qm.input = TRANSLATIONS
+qm.output = $$OUT_PWD/../package/root/translations/${QMAKE_FILE_BASE}.qm
+qm.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT}
+qm.name = LRELEASE ${QMAKE_FILE_IN}
+qm.CONFIG += no_link
+QMAKE_EXTRA_COMPILERS += qm
+PRE_TARGETDEPS += compiler_qm_make_all
diff --git a/app/translations/hvac_fr_FR.ts b/app/translations/hvac_fr_FR.ts
new file mode 100644 (file)
index 0000000..241a6f9
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="fr_FR">
+<context>
+    <name>HVAC</name>
+    <message>
+        <location filename="../HVAC.qml" line="66"/>
+        <source>FAN SPEED</source>
+        <translation>Vitesse de ventilation</translation>
+    </message>
+    <message>
+        <location filename="../HVAC.qml" line="98"/>
+        <source>A/C</source>
+        <translation></translation>
+    </message>
+    <message>
+        <location filename="../HVAC.qml" line="111"/>
+        <source>AUTO</source>
+        <translation></translation>
+    </message>
+</context>
+<context>
+    <name>HeatDegree</name>
+    <message>
+        <location filename="../HeatDegree.qml" line="31"/>
+        <source>LO</source>
+        <translation>BAS</translation>
+    </message>
+    <message>
+        <location filename="../HeatDegree.qml" line="33"/>
+        <source>%1°</source>
+        <translation></translation>
+    </message>
+    <message>
+        <location filename="../HeatDegree.qml" line="35"/>
+        <source>HI</source>
+        <translation>HAU</translation>
+    </message>
+</context>
+<context>
+    <name>main</name>
+    <message>
+        <location filename="../main.cpp" line="44"/>
+        <source>port for binding</source>
+        <translation>Port du binding</translation>
+    </message>
+    <message>
+        <location filename="../main.cpp" line="45"/>
+        <source>secret for binding</source>
+        <translation>Token de sécurité du binding</translation>
+    </message>
+</context>
+</TS>
diff --git a/app/translations/hvac_ja_JP.ts b/app/translations/hvac_ja_JP.ts
new file mode 100644 (file)
index 0000000..a3a78a8
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ja_JP">
+<context>
+    <name>HVAC</name>
+    <message>
+        <location filename="../HVAC.qml" line="66"/>
+        <source>FAN SPEED</source>
+        <translation>ファンの回転数</translation>
+    </message>
+    <message>
+        <location filename="../HVAC.qml" line="98"/>
+        <source>A/C</source>
+        <translation></translation>
+    </message>
+    <message>
+        <location filename="../HVAC.qml" line="111"/>
+        <source>AUTO</source>
+        <translation></translation>
+    </message>
+</context>
+<context>
+    <name>HeatDegree</name>
+    <message>
+        <location filename="../HeatDegree.qml" line="31"/>
+        <source>LO</source>
+        <translation>寒</translation>
+    </message>
+    <message>
+        <location filename="../HeatDegree.qml" line="33"/>
+        <source>%1°</source>
+        <translation></translation>
+    </message>
+    <message>
+        <location filename="../HeatDegree.qml" line="35"/>
+        <source>HI</source>
+        <translation>暖</translation>
+    </message>
+</context>
+<context>
+    <name>main</name>
+    <message>
+        <location filename="../main.cpp" line="44"/>
+        <source>port for binding</source>
+        <translation>binding 用のポート</translation>
+    </message>
+    <message>
+        <location filename="../main.cpp" line="45"/>
+        <source>secret for binding</source>
+        <translation>binding 用の secret</translation>
+    </message>
+</context>
+</TS>
diff --git a/app/translator.cpp b/app/translator.cpp
new file mode 100644 (file)
index 0000000..9b67f13
--- /dev/null
@@ -0,0 +1,52 @@
+#include "translator.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QLocale>
+#include <QtCore/QTranslator>
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+
+Translator::Translator(QObject *parent)
+    : QObject(parent)
+    , m_language(QStringLiteral("C"))
+    , m_translator(nullptr)
+{
+}
+
+QString Translator::translate(const QString &string, const QString &language) const
+{
+    Q_UNUSED(language)
+    return string;
+}
+
+QString Translator::language() const
+{
+    return m_language;
+}
+
+void Translator::setLanguage(const QString &language)
+{
+    if (m_language == language) return;
+    m_language = language;
+    setTranslator(language);
+    emit languageChanged(language);
+}
+
+void Translator::setTranslator(const QString &language)
+{
+    if (m_translator) {
+        QCoreApplication::removeTranslator(m_translator);
+    } else {
+        m_translator = new QTranslator(this);
+    }
+    QLocale locale(language);
+    QString fileName = QCoreApplication::instance()->applicationName().toLower();
+    qDebug() << "####" << QDir::currentPath() << QCoreApplication::applicationDirPath();
+    if (m_translator->load(locale, fileName, QStringLiteral("_"), QStringLiteral("%1/../translations").arg(QCoreApplication::applicationDirPath()))) {
+        QCoreApplication::installTranslator(m_translator);
+    } else {
+        delete m_translator;
+        m_translator = nullptr;
+    }
+}
+
diff --git a/app/translator.h b/app/translator.h
new file mode 100644 (file)
index 0000000..82c5872
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef TRANSLATOR_H
+#define TRANSLATOR_H
+
+#include <QtCore/QObject>
+
+class  QTranslator;
+
+class Translator : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QString language READ language WRITE setLanguage NOTIFY languageChanged)
+public:
+    explicit Translator(QObject *parent = nullptr);
+
+    QString language() const;
+
+    Q_INVOKABLE QString translate(const QString &string, const QString &language) const;
+public slots:
+    void setLanguage(const QString &language);
+
+signals:
+    void languageChanged(const QString &language);
+
+private slots:
+    void setTranslator(const QString &language);
+
+private:
+    QString m_language;
+    QTranslator *m_translator;
+};
+
+#endif // TRANSLATOR_H