added tr method for custom translations

This commit is contained in:
Andrei Yankovich 2023-10-01 11:27:35 +02:00
parent 53a67709ff
commit 90a4284c56
2 changed files with 132 additions and 27 deletions

View File

@ -13,6 +13,8 @@
#include <QLocale>
#include <QLibraryInfo>
#include <QRegularExpression>
#include <QLocale>
#include <QMap>
#include "params.h"
using namespace QuasarAppUtils;
@ -78,11 +80,49 @@ bool QuasarAppUtils::Locales::findQm(QString localePrefix,
return findQmPrivate(localePrefix, qmFiles);
}
bool Locales::setLocalePrivate(const QLocale &locale) {
removeOldTranslation();
void QuasarAppUtils::Locales::installTranslations( QList<QTranslator *> &qmFiles)
{
for (const auto & translator: qAsConst(qmFiles)) {
if (!QCoreApplication::installTranslator(translator)) {
QuasarAppUtils::Params::log("Failed to install translation file : " + translator->filePath(),
QuasarAppUtils::Warning);
delete translator;
// we use a link of qmFiles so remove all invalid translations.
qmFiles.removeAll(translator);
continue;
}
}
}
QString Locales::translatePrivate(const char *source, const QLocale &locale) {
auto translations = _translations.value(locale);
for (const auto& tr : translations) {
auto result = tr->translate("QuasarAppUtils::Locales", source);
if (result.size()) {
return result;
}
}
return source;
}
bool Locales::setLocalePrivate(const QLocale &locale, bool force, bool install) {
if (force) {
clearCache(locale);
}
removeOldTranslation(_currentLocate);
// take a link to list of translations.
QList<QTranslator *> &qmFiles = _translations[locale];
if (qmFiles.isEmpty()) {
// fill list of translations
const auto list = locale.uiLanguages();
QList<QTranslator *> qmFiles;
auto it = list.rbegin();
while (qmFiles.isEmpty() && it != list.rend() && !findQm(*it, qmFiles)) {
@ -92,24 +132,16 @@ bool Locales::setLocalePrivate(const QLocale &locale) {
if (qmFiles.isEmpty())
return false;
for (const auto & translator: qAsConst(qmFiles)) {
if (!QCoreApplication::installTranslator(translator)) {
QuasarAppUtils::Params::log("Failed to install translation file : " + translator->filePath(),
QuasarAppUtils::Warning);
delete translator;
continue;
}
_translations.push_back(translator);
if (install)
installTranslations(qmFiles);
}
emit sigTranslationChanged();
_currentLocate = locale;
return _translations.size();
return _translations[locale].size();
}
const QLocale &Locales::currentLocate() {
@ -117,9 +149,19 @@ const QLocale &Locales::currentLocate() {
return obj->currentLocatePrivate();
}
bool Locales::setLocale(const QLocale &locale) {
QString Locales::tr(const char *source, const QLocale &locale) {
auto obj = instance();
return obj->setLocalePrivate(locale);
return obj->translatePrivate(source, locale);
}
bool Locales::setLocale(const QLocale &locale, bool force) {
auto obj = instance();
return obj->setLocalePrivate(locale, force);
}
bool Locales::init(const QList<QLocale> &locales, const QSet<QString> &location) {
auto obj = instance();
return obj->initPrivate(locales, location);
}
bool Locales::init(const QLocale &locale, const QSet<QString> & location) {
@ -142,17 +184,51 @@ bool Locales::initPrivate(const QLocale &locale, const QSet<QString> & locations
return setLocalePrivate(locale);
}
bool Locales::initPrivate(const QList<QLocale> &locales, const QSet<QString> &locations) {
#if QT_VERSION <= QT_VERSION_CHECK(6, 0, 0)
auto defaultTr = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
#else
auto defaultTr = QLibraryInfo::path(QLibraryInfo::TranslationsPath);
#endif
_locations = locations;
if (!_locations.contains(defaultTr)) {
_locations += defaultTr;
}
for (const auto& locale: locales) {
if (!setLocalePrivate(locale, false, false)) {
return false;
}
}
return true;
}
void Locales::clearCache(const QLocale &locale) {
for (const auto & tr :qAsConst(_translations[locale])) {
QCoreApplication::removeTranslator(tr);
delete tr;
}
_translations[locale].clear();
}
void Locales::clearCache() {
for (auto it = _translations.keyBegin(); it != _translations.keyEnd(); it = std::next(it)) {
clearCache(*it);
}
_translations.clear();
}
Locales *Locales::instance() {
static auto instance = new Locales();
return instance;
}
void Locales::removeOldTranslation() {
for (const auto & tr :qAsConst(_translations)) {
void Locales::removeOldTranslation(const QLocale &locale) {
for (const auto & tr :qAsConst(_translations[locale])) {
QCoreApplication::removeTranslator(tr);
delete tr;
}
_translations.clear();
}
void Locales::addLocationPrivate(const QString &location) {
@ -169,5 +245,5 @@ void Locales::addLocation(const QString &location) {
}
Locales::~Locales() {
removeOldTranslation();
clearCache();
}

View File

@ -46,7 +46,16 @@ public:
* @param locale This is new locale.
* @return true if the all ltranstations files loaded successful.
*/
static bool setLocale(const QLocale &locale);
static bool setLocale(const QLocale &locale, bool force = false);
/**
* @brief init This method initialize translations of applictaion.
* @param locales This is list of locales that you want to locad to application cache. See info about QLocale.
* @param location Path to folder with qm files. example (:/tr).
* @return return true if locale set for application.
*/
static bool init(const QList<QLocale> & locales,
const QSet<QString> & location = {});
/**
* @brief init This method initialize translation of applictaion.
@ -75,6 +84,15 @@ public:
*/
static const QLocale &currentLocate();
/**
* @brief tr This method will translate single string to choosed language.
* @param source This is source string of translations.
* @param locale This is choosed language.
* @return translated string value.
* @note use instant QOBject::tr, This method must be read by the lupdate utility
*/
static QString tr(const char *source, const QLocale& locale);
signals:
/**
* @brief sigTranslationChanged Emited when set new locale for application.
@ -85,10 +103,18 @@ private:
Locales() = default;
~Locales();
bool setLocalePrivate(const QLocale &locale = QLocale::system());
bool setLocalePrivate(const QLocale &locale = QLocale::system(), bool force = false, bool install = true);
bool initPrivate(const QLocale &locale = QLocale::system(),
const QSet<QString> &location = {});
void removeOldTranslation();
bool initPrivate(const QList<QLocale> &locales,
const QSet<QString> &location = {});
void clearCache(const QLocale& locale);
void clearCache();
void removeOldTranslation(const QLocale& locale);
void addLocationPrivate(const QString& location);
const QLocale &currentLocatePrivate() const;
@ -97,10 +123,13 @@ private:
QList<QTranslator *> &result);
bool findQmPrivate(const QString &prefix,
QList<QTranslator *> &qmFiles);
void installTranslations(QList<QTranslator *> &qmFiles);
QString translatePrivate(const char *source, const QLocale& locale);
QLocale _currentLocate;
QSet<QString> _locations;
QList<QTranslator *> _translations;
QHash<QLocale, QList<QTranslator *>> _translations;
};
}