TranslationManager, Russian translation example

This commit is contained in:
Ilya Kitaev 2016-07-19 23:31:09 +03:00
parent de7bd2eb97
commit a9339838ac
13 changed files with 192 additions and 39 deletions

63
TranslationManager.cpp Normal file
View file

@ -0,0 +1,63 @@
#include "TranslationManager.h"
#include <QApplication>
#include <QTranslator>
#include <QDir>
#include <QDebug>
#include <QFileInfo>
TranslationManager * TranslationManager::m_instance = nullptr;
TranslationManager::TranslationManager(QObject *parent) : QObject(parent)
{
m_translator = new QTranslator(this);
}
bool TranslationManager::setLanguage(const QString &language)
{
qDebug() << __FUNCTION__ << " " << language;
// if language is "en", remove translator
if (language.toLower() == "en") {
qApp->removeTranslator(m_translator);
emit languageChanged();
return true;
}
// we expecting to have translation files in "i18n" directory
QString dir = qApp->applicationDirPath() + QDir::separator() + "i18n";
QString filename = "monero-core_" + language;
qDebug("%s: loading translation file '%s' from '%s",
__FUNCTION__, qPrintable(filename), qPrintable(dir));
if (m_translator->load(filename, dir)) {
qDebug("%s: translation for language '%s' loaded successfully",
__FUNCTION__, qPrintable(language));
// TODO: apply locale?
qApp->installTranslator(m_translator);
emit languageChanged();
return true;
} else {
qCritical("%s: error loading translation for language '%s'",
__FUNCTION__, qPrintable(language));
return false;
}
}
TranslationManager *TranslationManager::instance()
{
if (!m_instance) {
m_instance = new TranslationManager();
}
return m_instance;
}
QString TranslationManager::emptyString()
{
return "";
}

29
TranslationManager.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef TRANSLATIONMANAGER_H
#define TRANSLATIONMANAGER_H
#include <QObject>
class QTranslator;
class TranslationManager : public QObject
{
Q_OBJECT
Q_PROPERTY(QString emptyString READ emptyString NOTIFY languageChanged)
public:
Q_INVOKABLE bool setLanguage(const QString &language);
static TranslationManager *instance();
QString emptyString();
signals:
void languageChanged();
private:
explicit TranslationManager(QObject *parent = 0);
private:
static TranslationManager * m_instance;
QTranslator * m_translator;
};
#endif // TRANSLATIONMANAGER_H

View file

@ -2,7 +2,7 @@
BITMONERO_URL=https://github.com/mbg033/bitmonero.git BITMONERO_URL=https://github.com/mbg033/bitmonero.git
BITMONERO_BRANCH=devel BITMONERO_BRANCH=master
# thanks to SO: http://stackoverflow.com/a/20283965/4118915 # thanks to SO: http://stackoverflow.com/a/20283965/4118915
CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu) CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu)
pushd $(pwd) pushd $(pwd)

View file

@ -1,14 +1,25 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<languages> <languages>
<language display_name="US English" locale="en_US" wallet_name="English" flag="/lang/flags/usa.png" qs="none"/>
<language display_name="UK English" locale="en_GB" wallet_name="English" flag="/lang/flags/uk.png" qs="none"/> <!--
<language display_name="Russia" locale="ru_RU" wallet_name="English" flag="/lang/flags/russia.png" qs="none"/> List of available languages for your wallet's seed:
<language display_name="RPA" locale="TODO" wallet_name="English" flag="/lang/flags/rpa.png" qs="none"/> 0 : English
<language display_name="Palestine" locale="TODO" wallet_name="English" flag="/lang/flags/palestine.png" qs="none"/> 1 : Spanish
<language display_name="India" locale="hi_IN" wallet_name="English" flag="/lang/flags/india.png" qs="none"/> 2 : German
<language display_name="Italy" locale="it_IT" wallet_name="English" flag="/lang/flags/italy.png" qs="none"/> 3 : Italian
<language display_name="German" locale="de_DE" wallet_name="English" flag="/lang/flags/german.png" qs="none"/> 4 : Portuguese
<language display_name="China" locale="zh_CN" wallet_name="English" flag="/lang/flags/china.png" qs="none"/> 5 : Russian
<language display_name="Brazil" locale="pt_BR" wallet_name="English" flag="/lang/flags/brazil.png" qs="none"/> 6 : Japanese
<language display_name="Bangladesh" locale="TODO" wallet_name="English" flag="/lang/flags/bangladesh.png" qs="none"/> -->
<language display_name="US English" locale="en_US" wallet_language="English" flag="/lang/flags/usa.png" qs="none"/>
<language display_name="UK English" locale="en_GB" wallet_language="English" flag="/lang/flags/uk.png" qs="none"/>
<language display_name="Russia" locale="ru_RU" wallet_language="Russian" flag="/lang/flags/russia.png" qs="none"/>
<language display_name="RPA" locale="en_SA" wallet_language="English" flag="/lang/flags/rpa.png" qs="none"/>
<language display_name="Palestine" locale="ar_PS" wallet_language="English" flag="/lang/flags/palestine.png" qs="none"/>
<language display_name="India" locale="hi_IN" wallet_language="English" flag="/lang/flags/india.png" qs="none"/>
<language display_name="Italy" locale="it_IT" wallet_language="Italian" flag="/lang/flags/italy.png" qs="none"/>
<language display_name="German" locale="de_DE" wallet_language="German" flag="/lang/flags/german.png" qs="none"/>
<language display_name="China" locale="zh_CN" wallet_language="English" flag="/lang/flags/china.png" qs="none"/>
<language display_name="Brazil" locale="pt_BR" wallet_language="Portuguese" flag="/lang/flags/brazil.png" qs="none"/>
<language display_name="Bangladesh" locale="en_US" wallet_language="English" flag="/lang/flags/bangladesh.png" qs="none"/>
</languages> </languages>

View file

@ -37,6 +37,7 @@
#include "WalletManager.h" #include "WalletManager.h"
#include "Wallet.h" #include "Wallet.h"
#include "PendingTransaction.h" #include "PendingTransaction.h"
#include "TranslationManager.h"
@ -53,10 +54,18 @@ int main(int argc, char *argv[])
app.installEventFilter(eventFilter); app.installEventFilter(eventFilter);
qmlRegisterType<clipboardAdapter>("moneroComponents", 1, 0, "Clipboard"); qmlRegisterType<clipboardAdapter>("moneroComponents", 1, 0, "Clipboard");
qmlRegisterUncreatableType<Wallet>("Bitmonero.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly"); qmlRegisterUncreatableType<Wallet>("Bitmonero.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly");
qmlRegisterUncreatableType<PendingTransaction>("Bitmonero.PendingTransaction", 1, 0, "PendingTransaction", qmlRegisterUncreatableType<PendingTransaction>("Bitmonero.PendingTransaction", 1, 0, "PendingTransaction",
"PendingTransaction can't be instantiated directly"); "PendingTransaction can't be instantiated directly");
qmlRegisterUncreatableType<WalletManager>("Bitmonero.WalletManager", 1, 0, "WalletManager",
"WalletManager can't be instantiated directly");
qmlRegisterUncreatableType<TranslationManager>("moneroComponents", 1, 0, "TranslationManager",
"TranslationManager can't be instantiated directly");
qRegisterMetaType<PendingTransaction::Priority>(); qRegisterMetaType<PendingTransaction::Priority>();
@ -69,6 +78,8 @@ int main(int argc, char *argv[])
engine.rootContext()->setContextProperty("walletManager", WalletManager::instance()); engine.rootContext()->setContextProperty("walletManager", WalletManager::instance());
engine.rootContext()->setContextProperty("translationManager", TranslationManager::instance());
// export to QML monero accounts root directory // export to QML monero accounts root directory
// wizard is talking about where // wizard is talking about where
// to save the wallet file (.keys, .bin), they have to be user-accessible for // to save the wallet file (.keys, .bin), they have to be user-accessible for

View file

@ -19,7 +19,8 @@ HEADERS += \
src/libwalletqt/PendingTransaction.h \ src/libwalletqt/PendingTransaction.h \
src/libwalletqt/TransactionHistory.h \ src/libwalletqt/TransactionHistory.h \
src/libwalletqt/TransactionInfo.h \ src/libwalletqt/TransactionInfo.h \
oshelper.h oshelper.h \
TranslationManager.h
SOURCES += main.cpp \ SOURCES += main.cpp \
@ -31,7 +32,8 @@ SOURCES += main.cpp \
src/libwalletqt/PendingTransaction.cpp \ src/libwalletqt/PendingTransaction.cpp \
src/libwalletqt/TransactionHistory.cpp \ src/libwalletqt/TransactionHistory.cpp \
src/libwalletqt/TransactionInfo.cpp \ src/libwalletqt/TransactionInfo.cpp \
oshelper.cpp oshelper.cpp \
TranslationManager.cpp
lupdate_only { lupdate_only {
SOURCES = *.qml \ SOURCES = *.qml \
@ -101,11 +103,11 @@ macx {
# translations files; # translations files;
TRANSLATIONS = $$PWD/translations/monero-core_en.ts \ # English (could be untranslated) TRANSLATIONS = $$PWD/translations/monero-core_en.ts \ # English (could be untranslated)
$$PWD/translations/monero-core_de.ts \ # Deutsch $$PWD/translations/monero-core_de.ts \ # Deutsch
$$PWD/translations/monero-core_zh.ts \ # Chineese $$PWD/translations/monero-core_zh.ts \ # Chineese
$$PWD/translations/monero-core_ru.ts \ # Russian $$PWD/translations/monero-core_ru.ts \ # Russian
$$PWD/translations/monero-core_it.ts \ # Italian $$PWD/translations/monero-core_it.ts \ # Italian
$$PWD/translations/monero-core_pl.ts \ # Polish $$PWD/translations/monero-core_pl.ts \ # Polish
@ -117,7 +119,7 @@ trans_update.depends = $$_PRO_FILE_
trans_release.commands = lrelease $$_PRO_FILE_ trans_release.commands = lrelease $$_PRO_FILE_
trans_release.depends = trans_update $$TRANSLATIONS trans_release.depends = trans_update $$TRANSLATIONS
translate.commands = $(COPY) $$PWD/*.qm ${DESTDIR} translate.commands = $(MKDIR) ${DESTDIR}/i18n && $(COPY) $$PWD/translations/*.qm ${DESTDIR}/i18n
translate.depends = trans_release translate.depends = trans_release
QMAKE_EXTRA_TARGETS += trans_update trans_release translate QMAKE_EXTRA_TARGETS += trans_update trans_release translate

View file

@ -666,12 +666,13 @@
<context> <context>
<name>WizardWelcome</name> <name>WizardWelcome</name>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="65"/> <location filename="../wizard/WizardWelcome.qml" line="49"/>
<location filename="../wizard/WizardWelcome.qml" line="73"/>
<source>Welcome</source> <source>Welcome</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="76"/> <location filename="../wizard/WizardWelcome.qml" line="86"/>
<source>Please choose a language and regional format.</source> <source>Please choose a language and regional format.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

View file

@ -666,12 +666,13 @@
<context> <context>
<name>WizardWelcome</name> <name>WizardWelcome</name>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="65"/> <location filename="../wizard/WizardWelcome.qml" line="49"/>
<location filename="../wizard/WizardWelcome.qml" line="73"/>
<source>Welcome</source> <source>Welcome</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="76"/> <location filename="../wizard/WizardWelcome.qml" line="86"/>
<source>Please choose a language and regional format.</source> <source>Please choose a language and regional format.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

View file

@ -666,12 +666,13 @@
<context> <context>
<name>WizardWelcome</name> <name>WizardWelcome</name>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="65"/> <location filename="../wizard/WizardWelcome.qml" line="49"/>
<location filename="../wizard/WizardWelcome.qml" line="73"/>
<source>Welcome</source> <source>Welcome</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="76"/> <location filename="../wizard/WizardWelcome.qml" line="86"/>
<source>Please choose a language and regional format.</source> <source>Please choose a language and regional format.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

View file

@ -666,12 +666,13 @@
<context> <context>
<name>WizardWelcome</name> <name>WizardWelcome</name>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="65"/> <location filename="../wizard/WizardWelcome.qml" line="49"/>
<location filename="../wizard/WizardWelcome.qml" line="73"/>
<source>Welcome</source> <source>Welcome</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="76"/> <location filename="../wizard/WizardWelcome.qml" line="86"/>
<source>Please choose a language and regional format.</source> <source>Please choose a language and regional format.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

View file

@ -6,7 +6,7 @@
<message> <message>
<location filename="../pages/AddressBook.qml" line="47"/> <location filename="../pages/AddressBook.qml" line="47"/>
<source>Add new entry</source> <source>Add new entry</source>
<translation type="unfinished"></translation> <translation>Новая запись</translation>
</message> </message>
<message> <message>
<location filename="../pages/AddressBook.qml" line="56"/> <location filename="../pages/AddressBook.qml" line="56"/>
@ -666,14 +666,15 @@
<context> <context>
<name>WizardWelcome</name> <name>WizardWelcome</name>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="65"/> <location filename="../wizard/WizardWelcome.qml" line="49"/>
<location filename="../wizard/WizardWelcome.qml" line="73"/>
<source>Welcome</source> <source>Welcome</source>
<translation type="unfinished"></translation> <translation>Добро пожаловать</translation>
</message> </message>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="76"/> <location filename="../wizard/WizardWelcome.qml" line="86"/>
<source>Please choose a language and regional format.</source> <source>Please choose a language and regional format.</source>
<translation type="unfinished"></translation> <translation>Пожалуйста выберите язык и региональный формат.</translation>
</message> </message>
</context> </context>
<context> <context>

View file

@ -666,12 +666,13 @@
<context> <context>
<name>WizardWelcome</name> <name>WizardWelcome</name>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="65"/> <location filename="../wizard/WizardWelcome.qml" line="49"/>
<location filename="../wizard/WizardWelcome.qml" line="73"/>
<source>Welcome</source> <source>Welcome</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../wizard/WizardWelcome.qml" line="76"/> <location filename="../wizard/WizardWelcome.qml" line="86"/>
<source>Please choose a language and regional format.</source> <source>Please choose a language and regional format.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

View file

@ -39,11 +39,25 @@ Item {
function onPageClosed(settingsObject) { function onPageClosed(settingsObject) {
var lang = languagesModel.get(gridView.currentIndex); var lang = languagesModel.get(gridView.currentIndex);
settingsObject['language'] = lang.display_name; settingsObject['language'] = lang.display_name;
settingsObject['wallet_language'] = lang.wallet_name; settingsObject['wallet_language'] = lang.wallet_language;
settingsObject['locale'] = lang.locale; settingsObject['locale'] = lang.locale;
return true return true
} }
// function retranslateUi() {
// welcomeText.text = qsTr("Welcome")
// }
// Connections {
// target: translationManager
// onEmptyStringChanged: {
// console.log("languageChanged")
// retranslateUi()
// }
// }
Column { Column {
id: headerColumn id: headerColumn
anchors.left: parent.left anchors.left: parent.left
@ -55,6 +69,7 @@ Item {
spacing: 24 spacing: 24
Text { Text {
id: welcomeText
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
font.family: "Arial" font.family: "Arial"
@ -62,10 +77,14 @@ Item {
//renderType: Text.NativeRendering //renderType: Text.NativeRendering
color: "#3F3F3F" color: "#3F3F3F"
wrapMode: Text.Wrap wrapMode: Text.Wrap
text: qsTr("Welcome") // hack to implement dynamic translation
// https://wiki.qt.io/How_to_do_dynamic_translation_in_QML
text: qsTr("Welcome") +
translationManager.emptyString
} }
Text { Text {
id: selectLanguageText
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
font.family: "Arial" font.family: "Arial"
@ -74,6 +93,7 @@ Item {
color: "#4A4646" color: "#4A4646"
wrapMode: Text.Wrap wrapMode: Text.Wrap
text: qsTr("Please choose a language and regional format.") text: qsTr("Please choose a language and regional format.")
+ translationManager.emptyString
} }
} }
@ -84,11 +104,13 @@ Item {
XmlRole { name: "display_name"; query: "@display_name/string()" } XmlRole { name: "display_name"; query: "@display_name/string()" }
XmlRole { name: "locale"; query: "@locale/string()" } XmlRole { name: "locale"; query: "@locale/string()" }
XmlRole { name: "wallet_name"; query: "@wallet_name/string()" } XmlRole { name: "wallet_language"; query: "@wallet_language/string()" }
XmlRole { name: "flag"; query: "@flag/string()" } XmlRole { name: "flag"; query: "@flag/string()" }
// TODO: XmlListModel is read only, we should store current language somewhere else // TODO: XmlListModel is read only, we should store current language somewhere else
// and set current language accordingly // and set current language accordingly
XmlRole { name: "isCurrent"; query: "@enabled/string()" } XmlRole { name: "isCurrent"; query: "@enabled/string()" }
} }
GridView { GridView {
@ -111,6 +133,8 @@ Item {
height: gridView.cellHeight height: gridView.cellHeight
Rectangle { Rectangle {
id: flagRect id: flagRect
width: 60; height: 60 width: 60; height: 60
@ -139,8 +163,15 @@ Item {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
gridView.currentIndex = index gridView.currentIndex = index
var data = languagesModel.get(gridView.currentIndex);
if (data !== null || data !== undefined) {
var locale = data.locale
translationManager.setLanguage(locale.split("_")[0]);
}
} }
} }
} } // delegate
} }
} }