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/ip4range.cpp \
util/netutil.cpp \ util/netutil.cpp \
util/processinfo.cpp \ util/processinfo.cpp \
util/osutil.cpp util/osutil.cpp \
util/stringutil.cpp
HEADERS += \ HEADERS += \
activityLog/logbuffer.h \ activityLog/logbuffer.h \
@ -48,7 +49,8 @@ HEADERS += \
util/ip4range.h \ util/ip4range.h \
util/netutil.h \ util/netutil.h \
util/processinfo.h \ util/processinfo.h \
util/osutil.h util/osutil.h \
util/stringutil.h
QML_FILES += \ QML_FILES += \
qml/*.qml \ qml/*.qml \
@ -60,18 +62,25 @@ QML_FILES += \
OTHER_FILES += \ OTHER_FILES += \
$${QML_FILES} $${QML_FILES}
TRANSLATIONS += \
i18n/i18n_ru.ts
# QML files # QML files
RESOURCES += fort_qml.qrc RESOURCES += fort_qml.qrc
# Compiled translation files
RESOURCES += fort_i18n.qrc
# Images # Images
RESOURCES += fort_images.qrc 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 # Windows
LIBS += -lfwpuclnt -lkernel32 -lpsapi -luser32 -luuid -lws2_32 LIBS += -lfwpuclnt -lkernel32 -lpsapi -luser32 -luuid -lws2_32
RC_FILE = fort.rc 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); updateDriverConfFlags(m_firewallConf);
} }
void FortManager::setLanguage(int languageIndex) void FortManager::setLanguage(int language)
{ {
TranslationManager::instance()->switchLanguage( if (!TranslationManager::instance()->switchLanguage(language))
static_cast<TranslationManager::Language>(languageIndex)); return;
m_fortSettings->setLanguage(TranslationManager::instance()->langName()); m_fortSettings->setLanguage(TranslationManager::instance()->localeName());
updateTrayMenu(); updateTrayMenu();
} }

View File

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

View File

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

View File

@ -1,19 +1,24 @@
#include "translationmanager.h" #include "translationmanager.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QLocale> #include <QDir>
#include <QTranslator> #include <QTranslator>
#include "util/stringutil.h"
#define TRANSLATION_FILE_PREFIX "i18n_"
#define TRANSLATION_FILE_SUFFIX ".qm"
TranslationManager::TranslationManager(QObject *parent) : TranslationManager::TranslationManager(QObject *parent) :
QObject(parent), QObject(parent),
m_language(English), m_language(0)
m_i18nDir(":/i18n")
{ {
setupTranslation();
} }
TranslationManager::~TranslationManager() TranslationManager::~TranslationManager()
{ {
switchLanguage(English); uninstallAllTranslators();
} }
TranslationManager *TranslationManager::instance() TranslationManager *TranslationManager::instance()
@ -26,52 +31,110 @@ TranslationManager *TranslationManager::instance()
return g_instanceTranslationManager; 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); uninstallTranslator(m_language);
installTranslator(language);
m_language = language; m_language = language;
emit languageChanged(m_language); emit languageChanged(m_language);
installTranslator(m_language, m_locale);
refreshTranslations(); 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) { if (!translator) {
translator = loadTranslator(language); translator = loadTranslator(language, locale);
} }
if (translator) { if (translator) {
qApp->installTranslator(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 // Load .qm file
QTranslator *translator = new QTranslator(this); 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; return translator;
} }
@ -81,73 +144,7 @@ void TranslationManager::refreshTranslations()
emit dummyBoolChanged(); emit dummyBoolChanged();
} }
QString TranslationManager::langName() const QString TranslationManager::i18nDir()
{ {
return getLangName(m_language); return qApp->applicationDirPath() + "/i18n";
}
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();
}
} }

View File

@ -1,9 +1,10 @@
#ifndef TRANSLATIONMANAGER_H #ifndef TRANSLATIONMANAGER_H
#define TRANSLATIONMANAGER_H #define TRANSLATIONMANAGER_H
#include <QLocale>
#include <QObject> #include <QObject>
#include <QStringList> #include <QStringList>
#include <QHash> #include <QVector>
class QTranslator; class QTranslator;
@ -11,68 +12,54 @@ class TranslationManager : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool dummyBool READ dummyBool NOTIFY dummyBoolChanged) Q_PROPERTY(bool dummyBool READ dummyBool NOTIFY dummyBoolChanged)
Q_PROPERTY(Language language READ language WRITE switchLanguage NOTIFY languageChanged) Q_PROPERTY(int language READ language WRITE switchLanguage NOTIFY languageChanged)
Q_PROPERTY(QString langName READ langName WRITE setLangName NOTIFY languageChanged) Q_PROPERTY(QStringList naturalLabels READ naturalLabels CONSTANT)
protected: protected:
explicit TranslationManager(QObject *parent = 0); explicit TranslationManager(QObject *parent = 0);
virtual ~TranslationManager(); virtual ~TranslationManager();
public: public:
enum Language {
NoneLanguage = -1,
English = 0,
Russian,
Uzbek,
LanguageCount
};
Q_ENUM(Language)
static TranslationManager *instance(); static TranslationManager *instance();
bool dummyBool() const { return true; } 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; QStringList naturalLabels() const;
void setLangName(const QString &langName);
static TranslationManager::Language getLanguageByName(const QString &langName); int getLanguageByName(const QString &localeName) const;
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"); }
signals: signals:
void dummyBoolChanged(); void dummyBoolChanged();
void languageChanged(TranslationManager::Language language); void languageChanged(int language);
public slots: public slots:
void switchLanguage(TranslationManager::Language language = English); bool switchLanguage(int language = 0);
void switchLanguageByName(const QString &langName); bool switchLanguageByName(const QString &localeName);
void refreshTranslations(); void refreshTranslations();
private: private:
void installTranslator(Language language); void setupTranslation();
void uninstallTranslator(Language language);
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: 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 #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