21#include "qtlocalizer.h"
23#include <QtCore/QCoreApplication>
24#include <QtCore/QDateTime>
25#include <QtCore/QLibraryInfo>
26#include <QtCore/QTranslator>
27#include <QtCore/QVector>
29#include <QtCore/QLoggingCategory>
31Q_LOGGING_CATEGORY(CUTELEE_LOCALIZER,
"cutelee.localizer")
34 explicit Locale(
const QLocale &_locale) : locale(_locale) {}
38 qDeleteAll(systemTranslators);
39 qDeleteAll(themeTranslators);
51class QtLocalizerPrivate
55 auto localeStruct =
new Locale(locale);
56 m_availableLocales.insert(locale.
name(), localeStruct);
57 m_locales.push_back(localeStruct);
63 qDeleteAll(m_availableLocales);
68 Q_ASSERT(!m_locales.isEmpty());
69 if (m_locales.isEmpty()) {
70 qCWarning(CUTELEE_LOCALIZER) <<
"Invalid Locale";
73 return m_locales.last()->locale;
80 int count = -1)
const;
92static void replacePercentN(
QString *result,
int n)
103 fmt = QStringLiteral(
"%L1");
105 fmt = QStringLiteral(
"%1");
110 result->
replace(percentPos, len, fmt);
118 const QString &context,
int count)
const
122 if (m_locales.isEmpty()) {
124 replacePercentN(&result, count);
128 auto locale = m_locales.last();
129 Q_FOREACH (QTranslator *translator, locale->themeTranslators) {
135 = locale->externalSystemTranslators + locale->systemTranslators;
136 if (translators.isEmpty())
140 Q_FOREACH (QTranslator *translator, translators) {
148 replacePercentN(&result, count);
151 auto fallback = input;
152 replacePercentN(&fallback, count);
166 d->m_appTranslatorPath = path;
172 d->m_appTranslatorPrefix = prefix;
179 if (!d->m_availableLocales.contains(localeName)) {
180 const QLocale namedLocale(localeName);
181 d->m_availableLocales.insert(localeName,
new Locale(namedLocale));
183 d->m_availableLocales[localeName]->externalSystemTranslators.prepend(
191 return d->currentLocale().toString(date, formatType);
198 return d->currentLocale().toString(time, formatType);
205 return d->currentLocale().toString(dateTime, formatType);
211 return d->currentLocale().toString(number);
217 return d->currentLocale().toString(number,
'f', 2);
221 const QString ¤cyCode)
const
224 auto currencySymbol = QStringLiteral(
"$");
225 if (currencyCode == QStringLiteral(
"EUR")) {
226 currencySymbol =
QChar(0x20AC);
227 }
else if (currencyCode == QStringLiteral(
"GBP")) {
228 currencySymbol = QStringLiteral(
"£");
230 currencySymbol = currencyCode;
233 + d->currentLocale().toString(value,
'f', 2);
237 const QVariantList &arguments)
240 Q_FOREACH (
const QVariant &arg, arguments) {
241 if (arg.
userType() == qMetaTypeId<int>())
242 string =
string.
arg(arg.
value<
int>());
243 else if (arg.
userType() == qMetaTypeId<double>())
244 string =
string.
arg(arg.
value<
double>());
245 else if (arg.
userType() == qMetaTypeId<QDateTime>())
255 const QVariantList &arguments)
const
258 const auto translated = d->translate(
string, context);
259 return substituteArguments(translated, arguments);
263 const QVariantList &arguments)
const
266 const auto translated = d->translate(
string,
QString());
267 return substituteArguments(translated, arguments);
272 const QVariantList &_arguments)
const
276 auto arguments = _arguments;
277 const auto N = arguments.takeFirst().toInt();
278 const auto translated = d->translate(
string, context, N);
279 return substituteArguments(translated, arguments);
284 const QVariantList &_arguments)
const
288 auto arguments = _arguments;
289 const auto N = arguments.takeFirst().toInt();
290 const auto translated = d->translate(
string,
QString(), N);
291 return substituteArguments(translated, arguments);
297 return d->currentLocale().name();
304 if (!d->m_availableLocales.contains(localeName)) {
307 qtTranslator->
load(QStringLiteral(
"qt_") + localeName,
308#
if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
313 localeStruct->systemTranslators.
append(qtTranslator);
315 appTranslator->
load(d->m_appTranslatorPrefix + localeName,
316 d->m_appTranslatorPath);
317 localeStruct->systemTranslators.
append(appTranslator);
318 d->m_availableLocales.insert(localeName, localeStruct);
320 localeStruct = d->m_availableLocales[localeName];
322 Q_ASSERT(localeStruct);
323 d->m_locales.push_back(localeStruct);
329 Q_ASSERT(!d->m_locales.isEmpty());
330 d->m_locales.takeLast();
336 auto it = d->m_availableLocales.constBegin();
337 const auto end = d->m_availableLocales.constEnd();
338 for (; it != end; ++it) {
347 it.value()->themeTranslators.prepend(translator);
354 auto it = d->m_availableLocales.constBegin();
355 const auto end = d->m_availableLocales.constEnd();
356 for (; it != end; ++it) {
357 auto tranIt = (*it)->themeTranslators.begin();
358 while (tranIt != (*it)->themeTranslators.end()) {
359 if ((*tranIt)->objectName() == catalog) {
361 tranIt = (*it)->themeTranslators.erase(tranIt);
Provides internationalization based on QLocale and QTranslator.
QString localizePluralString(const QString &string, const QString &pluralForm, const QVariantList &arguments={}) const override
QString localizeDate(const QDate &date, QLocale::FormatType formatType=QLocale::ShortFormat) const override
void installTranslator(QTranslator *translator, const QString &localeName=QLocale::system().name())
QString localizeContextString(const QString &string, const QString &context, const QVariantList &arguments={}) const override
QString currentLocale() const override
void setAppTranslatorPath(const QString &path)
QString localizeNumber(int number) const override
QString localizeMonetaryValue(qreal value, const QString ¤cyCode={}) const override
void popLocale() override
void loadCatalog(const QString &path, const QString &catalog) override
QString localizeTime(const QTime &time, QLocale::FormatType formatType=QLocale::ShortFormat) const override
QString localizeDateTime(const QDateTime &dateTime, QLocale::FormatType formatType=QLocale::ShortFormat) const override
QtLocalizer(const QLocale &locale=QLocale::system())
QString localizePluralContextString(const QString &string, const QString &pluralForm, const QString &context, const QVariantList &arguments={}) const override
void pushLocale(const QString &localeName) override
QString localizeString(const QString &string, const QVariantList &arguments={}) const override
void setAppTranslatorPrefix(const QString &prefix)
void unloadCatalog(const QString &catalog) override
The Cutelee namespace holds all public Cutelee API.
const char * constData() const const
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
QString toString(Qt::DateFormat format) const const
QString location(LibraryLocation loc)
QString name() const const
void setObjectName(const QString &name)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
const QChar at(int position) const const
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString & replace(int position, int n, QChar after)
QByteArray toUtf8() const const
bool load(const QString &filename, const QString &directory, const QString &search_delimiters, const QString &suffix)
virtual QString translate(const char *context, const char *sourceText, const char *disambiguation, int n) const const
QDateTime toDateTime() const const
QString toString() const const
int userType() const const
void append(const T &value)