8#include <QtCore/QCoreApplication>
10#include <QtCore/QLibraryInfo>
11#include <QtCore/QTranslator>
21static QString qtTranslationsPath()
23#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
24 return QLibraryInfo::path(QLibraryInfo::TranslationsPath);
26 return QLibraryInfo::location(QLibraryInfo::TranslationsPath);
36static QString languageFromFileName(
const QString &
fileName)
38 if (!
fileName.endsWith(QLatin1String(
".qm"), Qt::CaseInsensitive)) {
43 const int separator = stem.indexOf(QLatin1Char(
'_'));
44 if (separator <= 0 || separator == stem.length() - 1) {
48 return stem.mid(separator + 1);
51class QxTranslatorPrivate
57 for (QTranslator *translator : m_installed) {
58 QCoreApplication::removeTranslator(translator);
63 m_loadedFiles.clear();
68 QList<QTranslator *> m_installed;
69 QStringList m_loadedFiles;
72QxTranslator::QxTranslator(QObject *parent)
74 , d_ptr(new QxTranslatorPrivate())
100 if (d->m_path.isEmpty()) {
101 return QStringList();
104 const QDir dir(d->m_path);
106 return QStringList();
109 QStringList languages;
110 const QStringList entries = dir.entryList(QStringList{QStringLiteral(
"*.qm")}, QDir::Files);
111 for (
const QString &entry : entries) {
112 const QString
language = languageFromFileName(entry);
125 return d->m_language;
135 if (!QCoreApplication::instance()) {
136 qWarning(
"QxTranslator: no QCoreApplication instance to install '%s' into", qPrintable(
language));
140 QList<QTranslator *> translators;
144 const QDir dir(d->m_path);
145 if (!d->m_path.isEmpty() && dir.exists()) {
146 const QStringList entries =
147 dir.entryList(QStringList{QStringLiteral(
"*_%1.qm").arg(
language)}, QDir::Files, QDir::Name);
148 for (
const QString &entry : entries) {
149 const QString
file = dir.absoluteFilePath(entry);
150 QTranslator *translator =
new QTranslator();
151 if (translator->load(
file)) {
152 translators.append(translator);
155 qWarning(
"QxTranslator: '%s' is not a usable translation", qPrintable(
file));
164 if (translators.isEmpty()) {
171 const QString qtPath = qtTranslationsPath();
172 if (!qtPath.isEmpty() && qtPath != d->m_path) {
173 const QStringList qtPrefixes{QStringLiteral(
"qtbase"), QStringLiteral(
"qt")};
174 for (
const QString &prefix : qtPrefixes) {
175 const QString
name = prefix + QLatin1Char(
'_') +
language;
176 QTranslator *translator =
new QTranslator();
177 if (translator->load(
name, qtPath)) {
178 translators.append(translator);
179 files.append(QDir(qtPath).absoluteFilePath(
name + QStringLiteral(
".qm")));
190 for (QTranslator *translator : translators) {
191 QCoreApplication::installTranslator(translator);
192 d->m_installed.append(translator);
195 d->m_loadedFiles = files;
205 return d->m_loadedFiles;
Loads, installs and switches the translations of an application at run time.
QStringList availableLanguages() const
The languages present in translationPath(), read from the file names: "app_zh_CN.qm" contributes "zh_...
void languageChanged(const QString &language)
Emitted once language is installed, so a slot may call translate() immediately.
QString language() const
The language currently applied, or empty while none is.
QStringList loadedFiles() const
The files installed by the last successful setLanguage() call.
bool setLanguage(const QString &language)
Installs the translations for language and returns true.
void setTranslationPath(const QString &path)
Points the loader at path.
QString translationPath() const
Directory scanned for "<prefix>_<language>.qm"; empty by default.
#define QX_FINI_PRIVATE()
#define QX_CORE_BEGIN_NAMESPACE
#define QX_CORE_END_NAMESPACE