diff --git a/docs/changes.txt b/docs/changes.txt index 7d3e0eeb60..16cb9613f5 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -108,9 +108,13 @@ Changes in behaviour which may result in build errors 3.1.3: (released 2019-??-??) ---------------------------- -All: +INCOMPATIBLE CHANGES SINCE 3.1.2: + +- New wxTranslations::GetAcceptableTranslations() method was problematic and + was removed, fixing various regressions in wxTranslations::AddCatalog() that + were introduced by it. Thanks to Tomasz Słodkowicz and Dummy for reporting + this and providing fixes for it. -- Fix regression in wxTranslations::AddCatalog() in 3.1.2 (Tomasz Słodkowicz). All (GUI): diff --git a/include/wx/translation.h b/include/wx/translation.h index 9b931a088a..3d5d5b0b83 100644 --- a/include/wx/translation.h +++ b/include/wx/translation.h @@ -145,12 +145,6 @@ public: wxString GetBestTranslation(const wxString& domain, const wxString& msgIdLanguage = "en"); - // find best and all other suitable translation languages for given domain - wxArrayString GetAcceptableTranslations(const wxString& domain, - wxLanguage msgIdLanguage); - wxArrayString GetAcceptableTranslations(const wxString& domain, - const wxString& msgIdLanguage = "en"); - // add standard wxWidgets catalog ("wxstd") bool AddStdCatalog(); diff --git a/interface/wx/translation.h b/interface/wx/translation.h index 23ca5128c7..eed6355d0b 100644 --- a/interface/wx/translation.h +++ b/interface/wx/translation.h @@ -137,34 +137,6 @@ public: const wxString& msgIdLanguage = "en"); /** - Returns the languages of all translations that can be used for the @a - domain. - - This is a more general version of GetBestTranslation(), which returns - the whole list of preferred UI languages for which a translation for - the @a domain was found instead of just the first, i.e. the most - preferred, element of this list. - - @param domain - The catalog domain to look for. - - @param msgIdLanguage - Specifies the language of "msgid" strings in source code (i.e. - arguments to GetString(), wxGetTranslation() and the _() macro). - - @return An array of language codes if any suitable matches were found, - empty array otherwise. - - @since 3.1.2 - */ - wxArrayString GetAcceptableTranslations(const wxString& domain, - wxLanguage msgIdLanguage); - - /// @overload - wxArrayString GetAcceptableTranslations(const wxString& domain, - const wxString& msgIdLanguage = "en"); - - /** Add standard wxWidgets catalogs ("wxstd" and possible port-specific catalogs). @@ -175,10 +147,9 @@ public: bool AddStdCatalog(); /** - Add a catalog for the preferred UI language. In case of multiple - preferences, add catalog for each language, if available. + Add a catalog for use with the current locale. - By default, the catalog is searched for in standard places (see + By default, it is searched for in standard places (see wxFileTranslationsLoader), but you may also prepend additional directories to the search path with wxFileTranslationsLoader::AddCatalogLookupPathPrefix(). @@ -202,9 +173,8 @@ public: code are used instead. @return - @true if catalog in the most preferred language was successfully loaded, - @false otherwise (which might mean that the catalog is not found or that - it isn't in the correct format). + @true if catalog was successfully loaded, @false otherwise (which might + mean that the catalog is not found or that it isn't in the correct format). */ bool AddCatalog(const wxString& domain, wxLanguage msgIdLanguage = wxLANGUAGE_ENGLISH_US); @@ -230,9 +200,8 @@ public: in case they use 8-bit characters (e.g. German or French strings). @return - @true if catalog in the most preferred language was successfully loaded, - @false otherwise (which might mean that the catalog is not found or that - it isn't in the correct format). + @true if catalog was successfully loaded, @false otherwise (which might + mean that the catalog is not found or that it isn't in the correct format). */ bool AddCatalog(const wxString& domain, wxLanguage msgIdLanguage, diff --git a/src/common/translation.cpp b/src/common/translation.cpp index 08c4bfd7ad..bf92ed2942 100644 --- a/src/common/translation.cpp +++ b/src/common/translation.cpp @@ -127,7 +127,7 @@ wxString GetPreferredUILanguageFallback(const wxArrayString& WXUNUSED(available) #ifdef __WINDOWS__ -wxString GetPreferredUILanguage(const wxArrayString& available, wxArrayString& allPreferred) +wxString GetPreferredUILanguage(const wxArrayString& available) { typedef BOOL (WINAPI *GetUserPreferredUILanguages_t)(DWORD, PULONG, PWSTR, PULONG); static GetUserPreferredUILanguages_t s_pfnGetUserPreferredUILanguages = NULL; @@ -172,20 +172,18 @@ wxString GetPreferredUILanguage(const wxArrayString& available, wxArrayString& a wxString lang(*j); lang.Replace("-", "_"); if ( available.Index(lang, /*bCase=*/false) != wxNOT_FOUND ) - allPreferred.Add(lang); + return lang; size_t pos = lang.find('_'); if ( pos != wxString::npos ) { lang = lang.substr(0, pos); if ( available.Index(lang, /*bCase=*/false) != wxNOT_FOUND ) - allPreferred.Add(lang); + return lang; } } } } } - if ( !allPreferred.empty() ) - return allPreferred[0]; return GetPreferredUILanguageFallback(available); } @@ -209,7 +207,7 @@ void LogTraceArray(const char *prefix, CFArrayRef arr) #endif // wxUSE_LOG_TRACE -wxString GetPreferredUILanguage(const wxArrayString& available, wxArrayString &allPreferred) +wxString GetPreferredUILanguage(const wxArrayString& available) { wxStringToStringHashMap availableNormalized; wxCFRef availableArr( @@ -233,19 +231,17 @@ wxString GetPreferredUILanguage(const wxArrayString& available, wxArrayString &a LogTraceArray(" - system preferred languages", prefArr); unsigned prefArrLength = CFArrayGetCount(prefArr); - for ( size_t x = 0; x < prefArrLength; ++x ) + if ( prefArrLength > 0 ) { // Lookup the name in 'available' by index -- we need to get the // original value corresponding to the normalized one chosen. - wxString lang(wxCFStringRef::AsString((CFStringRef)CFArrayGetValueAtIndex(prefArr, x))); + wxString lang(wxCFStringRef::AsString((CFStringRef)CFArrayGetValueAtIndex(prefArr, 0))); wxStringToStringHashMap::const_iterator i = availableNormalized.find(lang); if ( i == availableNormalized.end() ) - allPreferred.push_back(lang); + return lang; else - allPreferred.push_back(i->second); + return i->second; } - if ( allPreferred.empty() == false ) - return allPreferred[0]; return GetPreferredUILanguageFallback(available); } @@ -259,7 +255,7 @@ wxString GetPreferredUILanguage(const wxArrayString& available, wxArrayString &a // The LANGUAGE variable may contain a colon separated list of language // codes in the order of preference. // http://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html -wxString GetPreferredUILanguage(const wxArrayString& available, wxArrayString &allPreferred) +wxString GetPreferredUILanguage(const wxArrayString& available) { wxString languageFromEnv; wxArrayString preferred; @@ -287,17 +283,15 @@ wxString GetPreferredUILanguage(const wxArrayString& available, wxArrayString &a { wxString lang(*j); if ( available.Index(lang) != wxNOT_FOUND ) - allPreferred.Add(lang); + return lang; size_t pos = lang.find('_'); if ( pos != wxString::npos ) { lang = lang.substr(0, pos); if ( available.Index(lang) != wxNOT_FOUND ) - allPreferred.Add(lang); + return lang; } } - if ( allPreferred.empty() == false ) - return allPreferred[0]; return GetPreferredUILanguageFallback(available); } @@ -1555,9 +1549,9 @@ bool wxTranslations::AddCatalog(const wxString& domain, wxLanguage msgIdLanguage) { const wxString msgIdLang = wxLocale::GetLanguageCanonicalName(msgIdLanguage); - const wxArrayString domain_langs = GetAcceptableTranslations(domain, msgIdLanguage); + const wxString domain_lang = GetBestTranslation(domain, msgIdLang); - if ( domain_langs.empty() ) + if ( domain_lang.empty() ) { wxLogTrace(TRACE_I18N, wxS("no suitable translation for domain '%s' found"), @@ -1565,30 +1559,11 @@ bool wxTranslations::AddCatalog(const wxString& domain, return false; } - bool success = false; - for ( wxArrayString::const_iterator lang = domain_langs.begin(); - lang != domain_langs.end(); - ++lang ) - { - wxLogTrace(TRACE_I18N, - wxS("adding '%s' translation for domain '%s' (msgid language '%s')"), - *lang, domain, msgIdLang); + wxLogTrace(TRACE_I18N, + wxS("adding '%s' translation for domain '%s' (msgid language '%s')"), + domain_lang, domain, msgIdLang); - // We determine success by the success of loading/failing to load - // the most preferred (i.e. the first one) language's catalog: - if ( lang == domain_langs.begin() ) - success = LoadCatalog(domain, *lang, msgIdLang); - else - LoadCatalog(domain, *lang, msgIdLang); - - // No use loading languages that are less preferred than the - // msgid language, as by definition it contains all the strings - // in the msgid language. - if ( msgIdLang == *lang ) - break; - } - - return success; + return LoadCatalog(domain, domain_lang, msgIdLang); } @@ -1675,37 +1650,20 @@ wxString wxTranslations::GetBestTranslation(const wxString& domain, wxString wxTranslations::GetBestTranslation(const wxString& domain, const wxString& msgIdLanguage) { - const wxArrayString allGoodOnes = GetAcceptableTranslations(domain, msgIdLanguage); - wxString best(allGoodOnes.empty() ? wxString() : allGoodOnes[0]); - wxLogTrace(TRACE_I18N, " => using language '%s'", best); - return best; -} + // explicitly set language should always be respected + if ( !m_lang.empty() ) + return m_lang; -wxArrayString wxTranslations::GetAcceptableTranslations(const wxString& domain, - wxLanguage msgIdLanguage) -{ - const wxString lang = wxLocale::GetLanguageCanonicalName(msgIdLanguage); - return GetAcceptableTranslations(domain, lang); -} - -wxArrayString wxTranslations::GetAcceptableTranslations(const wxString& domain, - const wxString& msgIdLanguage) -{ wxArrayString available(GetAvailableTranslations(domain)); // it's OK to have duplicates, so just add msgid language available.push_back(msgIdLanguage); available.push_back(msgIdLanguage.BeforeFirst('_')); - wxLogTrace(TRACE_I18N, "choosing best languages for domain '%s'", domain); + wxLogTrace(TRACE_I18N, "choosing best language for domain '%s'", domain); LogTraceArray(" - available translations", available); - wxArrayString allPreferred; - GetPreferredUILanguage(available, allPreferred); - - // explicitly set language should always be preferred the most - if ( !m_lang.empty() ) - allPreferred.insert(allPreferred.begin(), m_lang); - - return allPreferred; + const wxString lang = GetPreferredUILanguage(available); + wxLogTrace(TRACE_I18N, " => using language '%s'", lang); + return lang; }