2020-06-01 06:07:41 -04:00
|
|
|
#include "L10nLoader.hpp"
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
#include <QApplication>
|
|
|
|
#include <QLocale>
|
|
|
|
#include <QTranslator>
|
|
|
|
#include <QRegularExpression>
|
|
|
|
#include <QDebug>
|
|
|
|
|
2020-09-18 16:37:08 -04:00
|
|
|
#include "qt_helpers.hpp"
|
|
|
|
#include "Logger.hpp"
|
|
|
|
|
2020-06-01 06:07:41 -04:00
|
|
|
#include "pimpl_impl.hpp"
|
|
|
|
|
|
|
|
class L10nLoader::impl final
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit impl(QApplication * app)
|
|
|
|
: app_ {app}
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool load_translator (QString const& filename
|
|
|
|
, QString const& directory = QString {}
|
|
|
|
, QString const& search_delimiters = QString {}
|
|
|
|
, QString const& suffix = QString {})
|
|
|
|
{
|
|
|
|
std::unique_ptr<QTranslator> translator {new QTranslator};
|
|
|
|
if (translator->load (filename, directory, search_delimiters, suffix))
|
|
|
|
{
|
|
|
|
install (std::move (translator));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool load_translator (QLocale const& locale, QString const& filename
|
|
|
|
, QString const& prefix = QString {}
|
|
|
|
, QString const& directory = QString {}
|
|
|
|
, QString const& suffix = QString {})
|
|
|
|
{
|
|
|
|
std::unique_ptr<QTranslator> translator {new QTranslator};
|
|
|
|
if (translator->load (locale, filename, prefix, directory, suffix))
|
|
|
|
{
|
|
|
|
install (std::move (translator));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void install (std::unique_ptr<QTranslator> translator)
|
|
|
|
{
|
|
|
|
app_->installTranslator (translator.get ());
|
|
|
|
translators_.push_back (std::move (translator));
|
|
|
|
}
|
|
|
|
|
|
|
|
QApplication * app_;
|
|
|
|
std::vector<std::unique_ptr<QTranslator>> translators_;
|
|
|
|
};
|
|
|
|
|
|
|
|
L10nLoader::L10nLoader (QApplication * app, QLocale const& locale, QString const& language_override)
|
|
|
|
: m_ {app}
|
|
|
|
{
|
2020-09-18 16:37:08 -04:00
|
|
|
LOG_INFO (QString {"locale: language: %1 script: %2 country: %3 ui-languages: %4"}
|
2020-06-01 06:07:41 -04:00
|
|
|
.arg (QLocale::languageToString (locale.language ()))
|
|
|
|
.arg (QLocale::scriptToString (locale.script ()))
|
|
|
|
.arg (QLocale::countryToString (locale.country ()))
|
2020-09-27 11:52:19 -04:00
|
|
|
.arg (locale.uiLanguages ().join (", ")));
|
2020-06-01 06:07:41 -04:00
|
|
|
|
|
|
|
// we don't load translators if the language override is 'en',
|
|
|
|
// 'en_US', or 'en-US'. In these cases we assume the user is trying
|
|
|
|
// to disable translations loaded because of their locale. We cannot
|
|
|
|
// load any locale based translations in this case.
|
|
|
|
auto skip_locale = language_override.contains (QRegularExpression {"^(?:en|en[-_]US)$"});
|
|
|
|
|
|
|
|
//
|
|
|
|
// Enable base i18n
|
|
|
|
//
|
|
|
|
QString translations_dir {":/Translations"};
|
|
|
|
if (!skip_locale)
|
|
|
|
{
|
2020-09-26 09:15:44 -04:00
|
|
|
LOG_TRACE ("Looking for locale based Qt translations in resources filesystem");
|
2020-06-01 06:07:41 -04:00
|
|
|
if (m_->load_translator (locale, "qt", "_", translations_dir))
|
|
|
|
{
|
2020-09-18 16:37:08 -04:00
|
|
|
LOG_INFO ("Loaded Qt translations for current locale from resources");
|
2020-06-01 06:07:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Default translations for releases use translations stored in
|
|
|
|
// the resources file system under the Translations
|
|
|
|
// directory. These are built by the CMake build system from .ts
|
|
|
|
// files in the translations source directory. New languages are
|
|
|
|
// added by enabling the UPDATE_TRANSLATIONS CMake option and
|
|
|
|
// building with the new language added to the LANGUAGES CMake
|
|
|
|
// list variable. UPDATE_TRANSLATIONS will preserve existing
|
|
|
|
// translations but should only be set when adding new
|
|
|
|
// languages. The resulting .ts files should be checked info
|
|
|
|
// source control for translators to access and update.
|
|
|
|
|
|
|
|
// try and load the base translation
|
2020-09-26 09:15:44 -04:00
|
|
|
LOG_TRACE ("Looking for WSJT-X translations based on UI languages in the resources filesystem");
|
2020-06-01 06:07:41 -04:00
|
|
|
for (QString locale_name : locale.uiLanguages ())
|
|
|
|
{
|
|
|
|
auto language = locale_name.left (2);
|
|
|
|
if (locale.uiLanguages ().front ().left (2) == language)
|
|
|
|
{
|
2020-09-27 11:52:19 -04:00
|
|
|
LOG_TRACE (QString {"Trying %1"}.arg (language));
|
2020-06-01 06:07:41 -04:00
|
|
|
if (m_->load_translator ("wsjtx_" + language, translations_dir))
|
|
|
|
{
|
2020-09-18 16:37:08 -04:00
|
|
|
LOG_INFO (QString {"Loaded WSJT-X base translation file from %1 based on language %2"}
|
2020-06-01 06:07:41 -04:00
|
|
|
.arg (translations_dir)
|
2020-09-27 11:52:19 -04:00
|
|
|
.arg (language));
|
2020-06-01 06:07:41 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// now try and load the most specific translations (may be a
|
|
|
|
// duplicate but we shouldn't care)
|
2020-09-26 09:15:44 -04:00
|
|
|
LOG_TRACE ("Looking for WSJT-X translations based on locale in the resources filesystem");
|
2020-06-01 06:07:41 -04:00
|
|
|
if (m_->load_translator (locale, "wsjtx", "_", translations_dir))
|
|
|
|
{
|
2020-09-18 16:37:08 -04:00
|
|
|
LOG_INFO ("Loaded WSJT-X translations for current locale from resources");
|
2020-06-01 06:07:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load any matching translation from the current directory
|
|
|
|
// using the command line option language override. This allows
|
|
|
|
// translators to easily test their translations by releasing
|
|
|
|
// (lrelease) a .qm file into the current directory with a
|
|
|
|
// suitable name (e.g. wsjtx_en_GB.qm), then running wsjtx to
|
|
|
|
// view the results.
|
|
|
|
if (language_override.size ())
|
|
|
|
{
|
|
|
|
auto language = language_override;
|
|
|
|
language.replace ('-', '_');
|
|
|
|
// try and load the base translation
|
|
|
|
auto base_language = language.left (2);
|
2020-09-26 09:15:44 -04:00
|
|
|
LOG_TRACE ("Looking for WSJT-X translations based on command line region override in the resources filesystem");
|
2020-06-01 06:07:41 -04:00
|
|
|
if (m_->load_translator ("wsjtx_" + base_language, translations_dir))
|
|
|
|
{
|
2020-09-18 16:37:08 -04:00
|
|
|
LOG_INFO (QString {"Loaded base translation file from %1 based on language %2"}
|
2020-06-01 06:07:41 -04:00
|
|
|
.arg (translations_dir)
|
2020-09-27 11:52:19 -04:00
|
|
|
.arg (base_language));
|
2020-06-01 06:07:41 -04:00
|
|
|
}
|
|
|
|
// now load the requested translations (may be a duplicate
|
|
|
|
// but we shouldn't care)
|
2020-09-26 09:15:44 -04:00
|
|
|
LOG_TRACE ("Looking for WSJT-X translations based on command line override country in the resources filesystem");
|
2020-06-01 06:07:41 -04:00
|
|
|
if (m_->load_translator ("wsjtx_" + language, translations_dir))
|
|
|
|
{
|
2020-09-18 16:37:08 -04:00
|
|
|
LOG_INFO (QString {"Loaded translation file from %1 based on language %2"}
|
2020-06-01 06:07:41 -04:00
|
|
|
.arg (translations_dir)
|
2020-09-27 11:52:19 -04:00
|
|
|
.arg (language));
|
2020-06-01 06:07:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load any matching translation from the current directory using
|
|
|
|
// the current locale. This allows translators to easily test their
|
|
|
|
// translations by releasing (lrelease) a .qm file into the current
|
|
|
|
// directory with a suitable name (e.g. wsjtx_en_GB.qm), then
|
|
|
|
// running wsjtx to view the results. The system locale setting will
|
|
|
|
// be used to select the translation file which can be overridden by
|
|
|
|
// the LANG environment variable on non-Windows system.
|
|
|
|
|
|
|
|
// try and load the base translation
|
2020-09-26 09:15:44 -04:00
|
|
|
LOG_TRACE ("Looking for WSJT-X translations based on command line override country in the current directory");
|
2020-06-01 06:07:41 -04:00
|
|
|
for (QString locale_name : locale.uiLanguages ())
|
|
|
|
{
|
|
|
|
auto language = locale_name.left (2);
|
|
|
|
if (locale.uiLanguages ().front ().left (2) == language)
|
|
|
|
{
|
2020-09-27 11:52:19 -04:00
|
|
|
LOG_TRACE (QString {"Trying %1"}.arg (language));
|
2020-06-01 06:07:41 -04:00
|
|
|
if (m_->load_translator ("wsjtx_" + language))
|
|
|
|
{
|
2020-09-27 11:52:19 -04:00
|
|
|
LOG_INFO (QString {"Loaded base translation file from $cwd based on language %1"}.arg (language));
|
2020-06-01 06:07:41 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!skip_locale)
|
|
|
|
{
|
|
|
|
// now try and load the most specific translations (may be a
|
|
|
|
// duplicate but we shouldn't care)
|
2020-09-26 09:15:44 -04:00
|
|
|
LOG_TRACE ("Looking for WSJT-X translations based on locale in the resources filesystem");
|
2020-06-01 06:07:41 -04:00
|
|
|
if (m_->load_translator (locale, "wsjtx", "_"))
|
|
|
|
{
|
2020-09-18 16:37:08 -04:00
|
|
|
LOG_INFO ("loaded translations for current locale from a file");
|
2020-06-01 06:07:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load any matching translation from the current directory using
|
|
|
|
// the command line option language override. This allows
|
|
|
|
// translators to easily test their translations on Windows by
|
|
|
|
// releasing (lrelease) a .qm file into the current directory with a
|
|
|
|
// suitable name (e.g. wsjtx_en_GB.qm), then running wsjtx to view
|
|
|
|
// the results.
|
|
|
|
if (language_override.size ())
|
|
|
|
{
|
|
|
|
auto language = language_override;
|
|
|
|
language.replace ('-', '_');
|
|
|
|
// try and load the base translation
|
|
|
|
auto base_language = language.left (2);
|
2020-09-26 09:15:44 -04:00
|
|
|
LOG_TRACE ("Looking for WSJT-X translations based on command line override country in the current directory");
|
2020-06-01 06:07:41 -04:00
|
|
|
if (m_->load_translator ("wsjtx_" + base_language))
|
|
|
|
{
|
2020-09-27 11:52:19 -04:00
|
|
|
LOG_INFO (QString {"Loaded base translation file from $cwd based on language %1"}.arg (base_language));
|
2020-06-01 06:07:41 -04:00
|
|
|
}
|
|
|
|
// now load the requested translations (may be a duplicate
|
|
|
|
// but we shouldn't care)
|
2020-09-26 09:15:44 -04:00
|
|
|
LOG_TRACE ("Looking for WSJT-X translations based on command line region in the current directory");
|
2020-06-01 06:07:41 -04:00
|
|
|
if (m_->load_translator ("wsjtx_" + language))
|
|
|
|
{
|
2020-09-27 11:52:19 -04:00
|
|
|
LOG_INFO (QString {"loaded translation file from $cwd based on language %1"}.arg (language));
|
2020-06-01 06:07:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
L10nLoader::~L10nLoader ()
|
|
|
|
{
|
|
|
|
}
|