21 #include "localization.h" 23 #include "configuration/doomseekerconfig.h" 24 #include "datapaths.h" 26 #include "plugins/engineplugin.h" 27 #include "plugins/pluginloader.h" 28 #include <QApplication> 32 #include <QLibraryInfo> 33 #include <QMessageBox> 35 #include <QStringList> 36 #include <QTranslator> 38 const QString DEFINITION_FILE_PATTERN =
"*.def";
39 const QString TRANSLATIONS_LOCATION_SUBDIR =
"translations";
40 const int NUM_VALID_VERSION_TOKENS = 2;
41 const int NUM_VALID_TOKENS = 3;
45 class Localization::LocalizationLoader
50 QList<LocalizationInfo> loadLocalizationsList(
const QStringList &definitionsFileSearchDirs);
53 QList<LocalizationInfo> localizations;
55 void loadLocalizationsListFile(
const QString &definitionsFilePath);
56 void loadLocalizationsListFile(QIODevice &io);
64 int obtainVersion(QIODevice &io);
80 Localization::Localization()
87 LocalizationInfo localization = LocalizationInfo::findBestMatch(localizations, localeName);
93 return currentLocalization_;
98 if (instance ==
nullptr)
103 bool Localization::isCurrentlyLoaded(
const QString &localeName)
const 105 return localeName == currentLocalization_.localeName ||
106 localeName == gConfig.doomseeker.localization;
109 QList<LocalizationInfo> Localization::loadLocalizationsList(
const QStringList &definitionsFileSearchDirs)
111 LocalizationLoader l;
112 this->localizations = l.loadLocalizationsList(definitionsFileSearchDirs);
113 return this->localizations;
116 bool Localization::loadTranslation(
const QString &localeName)
119 QLocale::system().name() :
122 this->currentLocalization_ = localization;
125 qDeleteAll(currentlyLoadedTranslations);
126 currentlyLoadedTranslations.clear();
131 TRANSLATIONS_LOCATION_SUBDIR);
133 installQtTranslations(localization.
localeName, searchPaths);
136 bool installed = installTranslation(localization.
localeName, searchPaths);
142 QTranslator *pluginTranslator = loadTranslationFile(
143 QString(
"%1_%2").arg(name, localization.
localeName),
145 if (pluginTranslator)
147 gLog << QString(
"Loaded translation for plugin %1").arg(name);
148 QCoreApplication::installTranslator(pluginTranslator);
149 currentlyLoadedTranslations.append(pluginTranslator);
155 void Localization::installQtTranslations(
const QString &localeName, QStringList searchPaths)
162 searchPaths << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
164 #if (QT_VERSION < QT_VERSION_CHECK(5, 3, 0)) 166 installTranslation(
"qt_" + localeName, searchPaths);
168 installTranslation(
"qtbase_" + localeName, searchPaths);
169 installTranslation(
"qtmultimedia_" + localeName, searchPaths);
173 bool Localization::installTranslation(
const QString &translationName,
const QStringList &searchPaths)
175 QTranslator *translator = loadTranslationFile(translationName, searchPaths);
176 if (translator !=
nullptr)
178 QCoreApplication::installTranslator(translator);
179 currentlyLoadedTranslations.append(translator);
184 gLog << QString(
"Translation '%1' not found.").arg(translationName);
189 QTranslator *Localization::loadTranslationFile(
const QString &translationName,
const QStringList &searchPaths)
191 auto pTranslator =
new QTranslator();
192 bool bLoaded =
false;
193 for (
const QString &dir : searchPaths)
195 if (pTranslator->load(translationName, dir))
197 gLog << QString(
"Found translation '%1' in dir '%2'.").arg(translationName, dir);
205 pTranslator =
nullptr;
210 Localization::LocalizationLoader::LocalizationLoader()
216 QList<LocalizationInfo> Localization::LocalizationLoader::loadLocalizationsList(
const QStringList &definitionsFileSearchDirs)
218 for (
const QString &dirPath : definitionsFileSearchDirs)
220 loadLocalizationsListFile(dirPath);
223 return localizations;
226 void Localization::LocalizationLoader::loadLocalizationsListFile(
const QString &definitionsFilePath)
228 QDir dir(definitionsFilePath);
229 QStringList defFiles = dir.entryList(QStringList(DEFINITION_FILE_PATTERN), QDir::Files);
230 for (
const QString &defFileName : defFiles)
234 gLog << QString(
"Reading localizations definitions file: %1").arg(defFileName);
235 QString filePath = dir.absoluteFilePath(defFileName);
236 QFile file(filePath);
237 if (file.open(QIODevice::ReadOnly))
239 loadLocalizationsListFile(file);
244 gLog << QString(
"Failed to open localizations definitions file: %1").arg(definitionsFilePath);
249 void Localization::LocalizationLoader::loadLocalizationsListFile(QIODevice &io)
251 int version = obtainVersion(io);
254 gLog << QString(
"Translation definition file doesn't contain valid protocol version information.");
258 QString line = QString::fromUtf8(io.readLine());
259 while (!line.isEmpty())
261 line = line.trimmed();
263 if (!line.isEmpty() && !line.startsWith(
"#"))
265 QStringList tokens = line.split(
";");
266 if (tokens.size() == NUM_VALID_TOKENS)
271 info.
niceName = tokens[2].trimmed();
272 if (!localizations.contains(info))
274 localizations.append(info);
279 gLog << QString(
"Invalid localization definition: %1").arg(line);
282 line = QString::fromUtf8(io.readLine());
286 int Localization::LocalizationLoader::obtainVersion(QIODevice &io)
288 QString line = io.readLine();
293 QStringList tokens = line.split(
"=");
294 if (tokens.size() == NUM_VALID_VERSION_TOKENS)
296 QString versionToken = tokens[1];
298 version = versionToken.toInt(&bOk);
308 void Localization::LocalizationLoader::sort()
310 std::sort(localizations.begin(), localizations.end(), localizationInfoLessThan);
QString localeName
Compliant with language_country standard. See QLocale::name()
LocalizationInfo coerceBestMatchingLocalization(const QString &localeName) const
QString niceName
Name that will be displayed to user.
QString countryCodeName
The same as code used for country flags in IP2C.
static const LocalizationInfo PROGRAM_NATIVE
QString nameCanonical() const
Either specified explicitly by plugin or derived from the actual plugin name.
static const LocalizationInfo SYSTEM_FOLLOW
static QStringList staticDataSearchDirs(const QString &subdir=QString())
Paths to directories where program should search for its static data.