| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  | #include "L10nLoader.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							|  |  |  | #include <memory>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QApplication>
 | 
					
						
							|  |  |  | #include <QLocale>
 | 
					
						
							|  |  |  | #include <QTranslator>
 | 
					
						
							|  |  |  | #include <QRegularExpression>
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-18 21:37:08 +01:00
										 |  |  | #include "qt_helpers.hpp"
 | 
					
						
							|  |  |  | #include "Logger.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01: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 21:37:08 +01:00
										 |  |  |   LOG_INFO (QString {"locale: language: %1 script: %2 country: %3 ui-languages: %4"} | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |      .arg (QLocale::languageToString (locale.language ())) | 
					
						
							|  |  |  |      .arg (QLocale::scriptToString (locale.script ())) | 
					
						
							|  |  |  |      .arg (QLocale::countryToString (locale.country ())) | 
					
						
							| 
									
										
										
										
											2020-09-27 16:52:19 +01:00
										 |  |  |      .arg (locale.uiLanguages ().join (", "))); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01: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 14:15:44 +01:00
										 |  |  |       LOG_TRACE ("Looking for locale based Qt translations in resources filesystem"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |       if (m_->load_translator (locale, "qt", "_", translations_dir)) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-09-18 21:37:08 +01:00
										 |  |  |           LOG_INFO ("Loaded Qt translations for current locale from resources"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01: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 14:15:44 +01:00
										 |  |  |       LOG_TRACE ("Looking for WSJT-X translations based on UI languages in the resources filesystem"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |       for (QString locale_name : locale.uiLanguages ()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           auto language = locale_name.left (2); | 
					
						
							|  |  |  |           if (locale.uiLanguages ().front ().left (2) == language) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2020-09-27 16:52:19 +01:00
										 |  |  |               LOG_TRACE (QString {"Trying %1"}.arg (language)); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |               if (m_->load_translator ("wsjtx_" + language, translations_dir)) | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2020-09-18 21:37:08 +01:00
										 |  |  |                   LOG_INFO (QString {"Loaded WSJT-X base translation file from %1 based on language %2"} | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |                      .arg (translations_dir) | 
					
						
							| 
									
										
										
										
											2020-09-27 16:52:19 +01:00
										 |  |  |                      .arg (language)); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |                   break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       // now try and load the most specific translations (may be a
 | 
					
						
							|  |  |  |       // duplicate but we shouldn't care)
 | 
					
						
							| 
									
										
										
										
											2020-09-26 14:15:44 +01:00
										 |  |  |       LOG_TRACE ("Looking for WSJT-X translations based on locale in the resources filesystem"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |       if (m_->load_translator (locale, "wsjtx", "_", translations_dir)) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-09-18 21:37:08 +01:00
										 |  |  |           LOG_INFO ("Loaded WSJT-X translations for current locale from resources"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01: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 14:15:44 +01:00
										 |  |  |       LOG_TRACE ("Looking for WSJT-X translations based on command line region override in the resources filesystem"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |       if (m_->load_translator ("wsjtx_" + base_language, translations_dir)) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-09-18 21:37:08 +01:00
										 |  |  |           LOG_INFO (QString {"Loaded base translation file from %1 based on language %2"} | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |              .arg (translations_dir) | 
					
						
							| 
									
										
										
										
											2020-09-27 16:52:19 +01:00
										 |  |  |              .arg (base_language)); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |       // now load the requested translations (may be a duplicate
 | 
					
						
							|  |  |  |       // but we shouldn't care)
 | 
					
						
							| 
									
										
										
										
											2020-09-26 14:15:44 +01:00
										 |  |  |       LOG_TRACE ("Looking for WSJT-X translations based on command line override country in the resources filesystem"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |       if (m_->load_translator ("wsjtx_" + language, translations_dir)) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-09-18 21:37:08 +01:00
										 |  |  |           LOG_INFO (QString {"Loaded translation file from %1 based on language %2"} | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |               .arg (translations_dir) | 
					
						
							| 
									
										
										
										
											2020-09-27 16:52:19 +01:00
										 |  |  |              .arg (language)); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01: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 14:15:44 +01:00
										 |  |  |   LOG_TRACE ("Looking for WSJT-X translations based on command line override country in the current directory"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |   for (QString locale_name : locale.uiLanguages ()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       auto language = locale_name.left (2); | 
					
						
							|  |  |  |       if (locale.uiLanguages ().front ().left (2) == language) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-09-27 16:52:19 +01:00
										 |  |  |           LOG_TRACE (QString {"Trying %1"}.arg (language)); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |           if (m_->load_translator ("wsjtx_" + language)) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2020-09-27 16:52:19 +01:00
										 |  |  |               LOG_INFO (QString {"Loaded base translation file from $cwd based on language %1"}.arg (language)); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01: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 14:15:44 +01:00
										 |  |  |       LOG_TRACE ("Looking for WSJT-X translations based on locale in the resources filesystem"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |       if (m_->load_translator (locale, "wsjtx", "_")) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-09-18 21:37:08 +01:00
										 |  |  |           LOG_INFO ("loaded translations for current locale from a file"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01: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 14:15:44 +01:00
										 |  |  |       LOG_TRACE ("Looking for WSJT-X translations based on command line override country in the current directory"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |       if (m_->load_translator ("wsjtx_" + base_language)) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-09-27 16:52:19 +01:00
										 |  |  |           LOG_INFO (QString {"Loaded base translation file from $cwd based on language %1"}.arg (base_language)); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |       // now load the requested translations (may be a duplicate
 | 
					
						
							|  |  |  |       // but we shouldn't care)
 | 
					
						
							| 
									
										
										
										
											2020-09-26 14:15:44 +01:00
										 |  |  |       LOG_TRACE ("Looking for WSJT-X translations based on command line region in the current directory"); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |       if (m_->load_translator ("wsjtx_" + language)) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-09-27 16:52:19 +01:00
										 |  |  |           LOG_INFO (QString {"loaded translation file from $cwd based on language %1"}.arg (language)); | 
					
						
							| 
									
										
										
										
											2020-06-01 11:07:41 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | L10nLoader::~L10nLoader () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } |