QtCanpool 3.3.0
载入中...
搜索中...
未找到
qxtranslator.cpp
浏览该文件的文档.
1
6#include "qxtranslator.h"
7
8#include <QtCore/QCoreApplication>
9#include <QtCore/QDir>
10#include <QtCore/QLibraryInfo>
11#include <QtCore/QTranslator>
12
14
21static QString qtTranslationsPath()
22{
23#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
24 return QLibraryInfo::path(QLibraryInfo::TranslationsPath);
25#else
26 return QLibraryInfo::location(QLibraryInfo::TranslationsPath);
27#endif
28}
29
36static QString languageFromFileName(const QString &fileName)
37{
38 if (!fileName.endsWith(QLatin1String(".qm"), Qt::CaseInsensitive)) {
39 return QString();
40 }
41
42 const QString stem = fileName.left(fileName.length() - 3);
43 const int separator = stem.indexOf(QLatin1Char('_'));
44 if (separator <= 0 || separator == stem.length() - 1) {
45 return QString();
46 }
47
48 return stem.mid(separator + 1);
49}
50
51class QxTranslatorPrivate
52{
53public:
55 void clear()
56 {
57 for (QTranslator *translator : m_installed) {
58 QCoreApplication::removeTranslator(translator);
59 delete translator;
60 }
61
62 m_installed.clear();
63 m_loadedFiles.clear();
64 }
65public:
66 QString m_path;
67 QString m_language;
68 QList<QTranslator *> m_installed;
69 QStringList m_loadedFiles;
70};
71
72QxTranslator::QxTranslator(QObject *parent)
73 : QObject(parent)
74 , d_ptr(new QxTranslatorPrivate())
75{
76}
77
79{
80 Q_D(QxTranslator);
81 d->clear();
83}
84
86{
87 Q_D(const QxTranslator);
88 return d->m_path;
89}
90
91void QxTranslator::setTranslationPath(const QString &path)
92{
93 Q_D(QxTranslator);
94 d->m_path = path;
95}
96
98{
99 Q_D(const QxTranslator);
100 if (d->m_path.isEmpty()) {
101 return QStringList();
102 }
103
104 const QDir dir(d->m_path);
105 if (!dir.exists()) {
106 return QStringList();
107 }
108
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);
113 if (!language.isEmpty() && !languages.contains(language)) {
114 languages.append(language);
115 }
116 }
117
118 languages.sort();
119 return languages;
120}
121
123{
124 Q_D(const QxTranslator);
125 return d->m_language;
126}
127
128bool QxTranslator::setLanguage(const QString &language)
129{
130 Q_D(QxTranslator);
131 if (language.isEmpty()) {
132 return false;
133 }
134
135 if (!QCoreApplication::instance()) {
136 qWarning("QxTranslator: no QCoreApplication instance to install '%s' into", qPrintable(language));
137 return false;
138 }
139
140 QList<QTranslator *> translators;
141 QStringList files;
142
143 // Everything the application deployed, whatever prefix it happens to use.
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);
153 files.append(file);
154 } else {
155 qWarning("QxTranslator: '%s' is not a usable translation", qPrintable(file));
156 delete translator;
157 }
158 }
159 }
160
161 // Nothing loaded means this language is not installed here. The swap below
162 // is the only thing that touches state, so returning now leaves the
163 // application exactly as it was.
164 if (translators.isEmpty()) {
165 return false;
166 }
167
168 // Qt's own strings, on top. This is the one optional part, and it is not
169 // searched again when the application's directory happens to be the one Qt
170 // keeps them in - the scan above already picked them up.
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")));
180 } else {
181 delete translator;
182 }
183 }
184 }
185
186 // The swap happens only once the replacement is complete, so a language
187 // that cannot be installed leaves the application translated as it was
188 // rather than untranslated.
189 d->clear();
190 for (QTranslator *translator : translators) {
191 QCoreApplication::installTranslator(translator);
192 d->m_installed.append(translator);
193 }
194
195 d->m_loadedFiles = files;
196 d->m_language = language;
197
199 return true;
200}
201
202QStringList QxTranslator::loadedFiles() const
203{
204 Q_D(const QxTranslator);
205 return d->m_loadedFiles;
206}
207
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
QFile file
Definition qxlogger.cpp:25
const char * fileName
Definition qxtheme.cpp:26
const char * name
Definition qxtheme.cpp:25