Merge pull request #40 from QuasarApp/customtranslations
All checks were successful
buildbot/DocsGenerator Build finished.
buildbot/AndroidBuilder_v8Qt6 Build finished.
buildbot/LinuxCMakeBuilderQt6 Build finished.
buildbot/WindowsCMakeBuilder Build finished.
buildbot/IOSCMakeBuilder Build finished.

added tr method for custom translations
This commit is contained in:
Andrei Yankovich 2023-10-01 12:49:02 +03:00 committed by GitHub
commit 4d445ef7fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 132 additions and 27 deletions

View File

@ -13,6 +13,8 @@
#include <QLocale> #include <QLocale>
#include <QLibraryInfo> #include <QLibraryInfo>
#include <QRegularExpression> #include <QRegularExpression>
#include <QLocale>
#include <QMap>
#include "params.h" #include "params.h"
using namespace QuasarAppUtils; using namespace QuasarAppUtils;
@ -78,20 +80,8 @@ bool QuasarAppUtils::Locales::findQm(QString localePrefix,
return findQmPrivate(localePrefix, qmFiles); return findQmPrivate(localePrefix, qmFiles);
} }
bool Locales::setLocalePrivate(const QLocale &locale) { void QuasarAppUtils::Locales::installTranslations( QList<QTranslator *> &qmFiles)
removeOldTranslation(); {
const auto list = locale.uiLanguages();
QList<QTranslator *> qmFiles;
auto it = list.rbegin();
while (qmFiles.isEmpty() && it != list.rend() && !findQm(*it, qmFiles)) {
it++;
}
if (qmFiles.isEmpty())
return false;
for (const auto & translator: qAsConst(qmFiles)) { for (const auto & translator: qAsConst(qmFiles)) {
if (!QCoreApplication::installTranslator(translator)) { if (!QCoreApplication::installTranslator(translator)) {
@ -99,17 +89,59 @@ bool Locales::setLocalePrivate(const QLocale &locale) {
QuasarAppUtils::Warning); QuasarAppUtils::Warning);
delete translator; delete translator;
// we use a link of qmFiles so remove all invalid translations.
qmFiles.removeAll(translator);
continue; continue;
} }
}
}
_translations.push_back(translator); 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();
auto it = list.rbegin();
while (qmFiles.isEmpty() && it != list.rend() && !findQm(*it, qmFiles)) {
it++;
}
if (qmFiles.isEmpty())
return false;
} }
if (install)
installTranslations(qmFiles);
emit sigTranslationChanged(); emit sigTranslationChanged();
_currentLocate = locale; _currentLocate = locale;
return _translations.size(); return _translations[locale].size();
} }
const QLocale &Locales::currentLocate() { const QLocale &Locales::currentLocate() {
@ -117,9 +149,19 @@ const QLocale &Locales::currentLocate() {
return obj->currentLocatePrivate(); return obj->currentLocatePrivate();
} }
bool Locales::setLocale(const QLocale &locale) { QString Locales::tr(const char *source, const QLocale &locale) {
auto obj = instance(); 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) { 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); 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() { Locales *Locales::instance() {
static auto instance = new Locales(); static auto instance = new Locales();
return instance; return instance;
} }
void Locales::removeOldTranslation() { void Locales::removeOldTranslation(const QLocale &locale) {
for (const auto & tr :qAsConst(_translations)) { for (const auto & tr :qAsConst(_translations[locale])) {
QCoreApplication::removeTranslator(tr); QCoreApplication::removeTranslator(tr);
delete tr;
} }
_translations.clear();
} }
void Locales::addLocationPrivate(const QString &location) { void Locales::addLocationPrivate(const QString &location) {
@ -169,5 +245,5 @@ void Locales::addLocation(const QString &location) {
} }
Locales::~Locales() { Locales::~Locales() {
removeOldTranslation(); clearCache();
} }

View File

@ -46,7 +46,16 @@ public:
* @param locale This is new locale. * @param locale This is new locale.
* @return true if the all ltranstations files loaded successful. * @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. * @brief init This method initialize translation of applictaion.
@ -75,6 +84,15 @@ public:
*/ */
static const QLocale &currentLocate(); 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: signals:
/** /**
* @brief sigTranslationChanged Emited when set new locale for application. * @brief sigTranslationChanged Emited when set new locale for application.
@ -85,10 +103,18 @@ private:
Locales() = default; Locales() = default;
~Locales(); ~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(), bool initPrivate(const QLocale &locale = QLocale::system(),
const QSet<QString> &location = {}); 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); void addLocationPrivate(const QString& location);
const QLocale &currentLocatePrivate() const; const QLocale &currentLocatePrivate() const;
@ -97,10 +123,13 @@ private:
QList<QTranslator *> &result); QList<QTranslator *> &result);
bool findQmPrivate(const QString &prefix, bool findQmPrivate(const QString &prefix,
QList<QTranslator *> &qmFiles); QList<QTranslator *> &qmFiles);
void installTranslations(QList<QTranslator *> &qmFiles);
QString translatePrivate(const char *source, const QLocale& locale);
QLocale _currentLocate; QLocale _currentLocate;
QSet<QString> _locations; QSet<QString> _locations;
QList<QTranslator *> _translations; QHash<QLocale, QList<QTranslator *>> _translations;
}; };
} }