Improve translation stuff.

This commit is contained in:
Nodir Temirkhodjaev 2017-09-09 09:24:04 +05:00
parent 7167149565
commit 5247b9e134
9 changed files with 165 additions and 148 deletions

View File

@ -26,7 +26,8 @@ SOURCES += \
util/ip4range.cpp \
util/netutil.cpp \
util/processinfo.cpp \
util/osutil.cpp
util/osutil.cpp \
util/stringutil.cpp
HEADERS += \
activityLog/logbuffer.h \
@ -48,7 +49,8 @@ HEADERS += \
util/ip4range.h \
util/netutil.h \
util/processinfo.h \
util/osutil.h
util/osutil.h \
util/stringutil.h
QML_FILES += \
qml/*.qml \
@ -60,18 +62,25 @@ QML_FILES += \
OTHER_FILES += \
$${QML_FILES}
TRANSLATIONS += \
i18n/i18n_ru.ts
# QML files
RESOURCES += fort_qml.qrc
# Compiled translation files
RESOURCES += fort_i18n.qrc
# Images
RESOURCES += fort_images.qrc
# Shadow Build: Copy i18n/ to build path
!equals(PWD, $${OUT_PWD}) {
CONFIG(debug, debug|release) {
OUTDIR = debug
} else {
OUTDIR = release
}
i18n.files = i18n/*.qm
i18n.path = $${OUT_PWD}/$${OUTDIR}/i18n
COPIES += i18n
}
# Windows
LIBS += -lfwpuclnt -lkernel32 -lpsapi -luser32 -luuid -lws2_32
RC_FILE = fort.rc

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>i18n/i18n_ru.qm</file>
</qresource>
</RCC>

View File

@ -241,12 +241,12 @@ void FortManager::setAppLogBlocked(bool enable)
updateDriverConfFlags(m_firewallConf);
}
void FortManager::setLanguage(int languageIndex)
void FortManager::setLanguage(int language)
{
TranslationManager::instance()->switchLanguage(
static_cast<TranslationManager::Language>(languageIndex));
if (!TranslationManager::instance()->switchLanguage(language))
return;
m_fortSettings->setLanguage(TranslationManager::instance()->langName());
m_fortSettings->setLanguage(TranslationManager::instance()->localeName());
updateTrayMenu();
}

View File

@ -49,7 +49,7 @@ public slots:
void setAppLogBlocked(bool enable);
void setLanguage(int languageIndex);
void setLanguage(int language);
private slots:
void saveTrayFlags();

View File

@ -40,7 +40,7 @@ BasePage {
width: Math.max(implicitWidth, 180)
flat: true
currentIndex: translationManager.language
model: translationManager.getNaturalLabels()
model: translationManager.naturalLabels
onActivated: fortManager.setLanguage(index)
}
}

View File

@ -1,19 +1,24 @@
#include "translationmanager.h"
#include <QCoreApplication>
#include <QLocale>
#include <QDir>
#include <QTranslator>
#include "util/stringutil.h"
#define TRANSLATION_FILE_PREFIX "i18n_"
#define TRANSLATION_FILE_SUFFIX ".qm"
TranslationManager::TranslationManager(QObject *parent) :
QObject(parent),
m_language(English),
m_i18nDir(":/i18n")
m_language(0)
{
setupTranslation();
}
TranslationManager::~TranslationManager()
{
switchLanguage(English);
uninstallAllTranslators();
}
TranslationManager *TranslationManager::instance()
@ -26,52 +31,110 @@ TranslationManager *TranslationManager::instance()
return g_instanceTranslationManager;
}
void TranslationManager::switchLanguage(TranslationManager::Language language)
void TranslationManager::setupTranslation()
{
QLocale::setDefault(getLocale(language));
// Collect locales from i18n files
const int prefixLen = QLatin1String(TRANSLATION_FILE_PREFIX).size();
m_locales.append(QLocale(QLocale::English, QLocale::UnitedStates));
foreach (const QFileInfo &fileInfo, QDir(i18nDir())
.entryInfoList(QStringList() << ("*" TRANSLATION_FILE_SUFFIX))) {
const QString localeName = fileInfo.completeBaseName().mid(prefixLen);
const QLocale locale(localeName);
m_locales.append(locale);
}
// Translators will be loaded later when needed
m_translators.resize(m_locales.size());
m_translators.fill(nullptr);
}
QStringList TranslationManager::naturalLabels() const
{
QStringList list;
list.reserve(m_locales.size());
foreach (const QLocale &locale, m_locales) {
list.append(StringUtil::capitalize(
locale.nativeLanguageName()));
}
return list;
}
int TranslationManager::getLanguageByName(const QString &localeName) const
{
int index = 0;
foreach (const QLocale &locale, m_locales) {
if (localeName == locale.name()) {
return index;
}
++index;
}
return 0;
}
bool TranslationManager::switchLanguage(int language)
{
if (language < 0 || language >= m_locales.size())
return false;
m_locale = m_locales.at(language);
QLocale::setDefault(m_locale);
uninstallTranslator(m_language);
installTranslator(language);
m_language = language;
emit languageChanged(m_language);
installTranslator(m_language, m_locale);
refreshTranslations();
return true;
}
void TranslationManager::switchLanguageByName(const QString &langName)
bool TranslationManager::switchLanguageByName(const QString &localeName)
{
return switchLanguage(getLanguageByName(langName));
return switchLanguage(getLanguageByName(localeName));
}
void TranslationManager::installTranslator(Language language)
void TranslationManager::uninstallAllTranslators()
{
QTranslator *translator = m_translators.value(language);
const int translatorsCount = m_translators.size();
for (int i = 0; i < translatorsCount; ++i) {
uninstallTranslator(i);
}
}
void TranslationManager::uninstallTranslator(int language)
{
QTranslator *translator = m_translators.at(language);
if (translator) {
qApp->removeTranslator(translator);
}
}
void TranslationManager::installTranslator(int language, const QLocale &locale)
{
QTranslator *translator = m_translators.at(language);
if (!translator) {
translator = loadTranslator(language);
translator = loadTranslator(language, locale);
}
if (translator) {
qApp->installTranslator(translator);
}
}
void TranslationManager::uninstallTranslator(Language language)
QTranslator *TranslationManager::loadTranslator(int language, const QLocale &locale)
{
QTranslator *translator = m_translators.value(language);
if (translator) {
qApp->removeTranslator(translator);
}
}
QTranslator *TranslationManager::loadTranslator(Language language)
{
const QString langName = getLangName(language);
// Load .qm file
QTranslator *translator = new QTranslator(this);
translator->load(QLatin1String("i18n_") + langName, m_i18nDir);
translator->load(TRANSLATION_FILE_PREFIX + locale.name(), i18nDir());
m_translators.insert(language, translator);
m_translators.replace(language, translator);
return translator;
}
@ -81,73 +144,7 @@ void TranslationManager::refreshTranslations()
emit dummyBoolChanged();
}
QString TranslationManager::langName() const
QString TranslationManager::i18nDir()
{
return getLangName(m_language);
}
void TranslationManager::setLangName(const QString &langName)
{
const int i = getLangNames().indexOf(langName);
if (i >= 0 && i < LanguageCount)
switchLanguage(static_cast<Language>(i));
}
TranslationManager::Language TranslationManager::getLanguageByName(const QString &langName)
{
return static_cast<Language>(getLangNames().indexOf(langName));
}
QString TranslationManager::getLangName(TranslationManager::Language language) const
{
return getLangNames().at(language != NoneLanguage
? language : m_language);
}
QString TranslationManager::getLabel(TranslationManager::Language language) const
{
return getLabels().at(language != NoneLanguage
? language : m_language);
}
QString TranslationManager::getNaturalLabel(TranslationManager::Language language) const
{
return getNaturalLabels().at(language != NoneLanguage
? language : m_language);
}
QStringList TranslationManager::getLangNames()
{
static QStringList g_langNames = QStringList()
<< "en" << "ru" << "uz";
return g_langNames;
}
QStringList TranslationManager::getLabels()
{
static QStringList g_labels = QStringList()
<< "American" << "Russian" << "Uzbek";
return g_labels;
}
QStringList TranslationManager::getNaturalLabels()
{
static QStringList g_naturalLabels = QStringList()
<< "English language" << "Русский язык" << "Ўзбек тили";
return g_naturalLabels;
}
QLocale TranslationManager::getLocale(Language language)
{
switch (language) {
case English:
return QLocale(QLocale::English, QLocale::UnitedStates);
case Russian:
return QLocale(QLocale::Russian);
case Uzbek:
return QLocale(QLocale::Uzbek);
default:
Q_UNREACHABLE();
return QLocale();
}
return qApp->applicationDirPath() + "/i18n";
}

View File

@ -1,9 +1,10 @@
#ifndef TRANSLATIONMANAGER_H
#define TRANSLATIONMANAGER_H
#include <QLocale>
#include <QObject>
#include <QStringList>
#include <QHash>
#include <QVector>
class QTranslator;
@ -11,68 +12,54 @@ class TranslationManager : public QObject
{
Q_OBJECT
Q_PROPERTY(bool dummyBool READ dummyBool NOTIFY dummyBoolChanged)
Q_PROPERTY(Language language READ language WRITE switchLanguage NOTIFY languageChanged)
Q_PROPERTY(QString langName READ langName WRITE setLangName NOTIFY languageChanged)
Q_PROPERTY(int language READ language WRITE switchLanguage NOTIFY languageChanged)
Q_PROPERTY(QStringList naturalLabels READ naturalLabels CONSTANT)
protected:
explicit TranslationManager(QObject *parent = 0);
virtual ~TranslationManager();
public:
enum Language {
NoneLanguage = -1,
English = 0,
Russian,
Uzbek,
LanguageCount
};
Q_ENUM(Language)
static TranslationManager *instance();
bool dummyBool() const { return true; }
TranslationManager::Language language() const { return m_language; }
int language() const { return m_language; }
QString localeName() const { return m_locale.name(); }
QString langName() const;
void setLangName(const QString &langName);
QStringList naturalLabels() const;
static TranslationManager::Language getLanguageByName(const QString &langName);
Q_INVOKABLE QString getLangName(TranslationManager::Language language = NoneLanguage) const;
Q_INVOKABLE QString getLabel(TranslationManager::Language language = NoneLanguage) const;
Q_INVOKABLE QString getNaturalLabel(TranslationManager::Language language = NoneLanguage) const;
Q_INVOKABLE static QStringList getLangNames();
Q_INVOKABLE static QStringList getLabels();
Q_INVOKABLE static QStringList getNaturalLabels();
static QString defaultLangName() { return QLatin1String("en"); }
int getLanguageByName(const QString &localeName) const;
signals:
void dummyBoolChanged();
void languageChanged(TranslationManager::Language language);
void languageChanged(int language);
public slots:
void switchLanguage(TranslationManager::Language language = English);
void switchLanguageByName(const QString &langName);
bool switchLanguage(int language = 0);
bool switchLanguageByName(const QString &localeName);
void refreshTranslations();
private:
void installTranslator(Language language);
void uninstallTranslator(Language language);
void setupTranslation();
QTranslator *loadTranslator(Language language);
void uninstallAllTranslators();
void uninstallTranslator(int language);
static QLocale getLocale(Language language);
void installTranslator(int language, const QLocale &locale);
QTranslator *loadTranslator(int language, const QLocale &locale);
static QString i18nDir();
private:
Language m_language;
int m_language;
QString m_i18nDir;
QLocale m_locale;
QHash<Language, QTranslator *> m_translators;
QList<QLocale> m_locales;
QVector<QTranslator *> m_translators;
};
#endif // TRANSLATIONMANAGER_H

View File

@ -0,0 +1,13 @@
#include "stringutil.h"
StringUtil::StringUtil(QObject *parent) :
QObject(parent)
{
}
QString StringUtil::capitalize(const QString &text)
{
const QChar firstChar = text.at(0);
return firstChar.toUpper() + text.mid(1);
}

16
src/ui/util/stringutil.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef STRINGUTIL_H
#define STRINGUTIL_H
#include <QObject>
class StringUtil : public QObject
{
Q_OBJECT
public:
explicit StringUtil(QObject *parent = nullptr);
static QString capitalize(const QString &text);
};
#endif // STRINGUTIL_H