Audacity 3.2.0
Functions | Variables
Languages Namespace Reference

Functions

wxString GetSystemLanguageCode (const FilePaths &pathList)
 
void GetLanguages (FilePaths pathList, wxArrayString &langCodes, TranslatableStrings &langNames)
 
wxString SetLang (const FilePaths &pathList, const wxString &lang)
 
wxString GetLocaleName ()
 
wxString GetLang ()
 
wxString GetLangShort ()
 

Variables

static std::unique_ptr< wxLocale > sLocale
 
static wxString sLocaleName
 

Function Documentation

◆ GetLang()

STRINGS_API wxString Languages::GetLang ( )
Returns
the last language code that was set

Definition at line 395 of file Languages.cpp.

396{
397 if (sLocale)
398 return sLocale->GetSysName();
399 else
400 return {};
401}
static std::unique_ptr< wxLocale > sLocale
Definition: Languages.cpp:321

References sLocale.

Referenced by audacity::cloud::audiocom::ServiceConfig::GetAcceptLanguageValue().

Here is the caller graph for this function:

◆ GetLangShort()

STRINGS_API wxString Languages::GetLangShort ( )
Returns
the last language code that was set (minus country code)

Definition at line 403 of file Languages.cpp.

404{
405 if (sLocale)
406 return sLocale->GetName();
407 else
408 return {};
409}

References sLocale.

◆ GetLanguages()

STRINGS_API void Languages::GetLanguages ( FilePaths  pathList,
wxArrayString &  langCodes,
TranslatableStrings langNames 
)
Parameters
pathListpaths to search for .mo files, grouped into subdirectories for the different languages
[out]langCodestwo-letter language abbreviations (like "fr") or language and country (like "pt_BR")
[out]langNamescorresponding autonyms of those languages (like "Português")

Definition at line 140 of file Languages.cpp.

142{
143 static const char *const utf8Names[] = {
144"af Afrikaans",
145"ar \330\247\331\204\330\271\330\261\330\250\331\212\330\251",
146"be \320\221\320\265\320\273\320\260\321\200\321\203\321\201\320\272\320\260\321\217",
147"bg \320\221\321\212\320\273\320\263\320\260\321\200\321\201\320\272\320\270",
148"bn \340\246\254\340\246\276\340\246\202\340\246\262\340\246\276",
149"bs Bosanski",
150"ca Catal\303\240",
151"ca_ES@valencia Valenci\303\240",
152"co Corsu",
153"cs \304\214e\305\241tina",
154"cy Cymraeg",
155"da Dansk",
156"de Deutsch",
157"el \316\225\316\273\316\273\316\267\316\275\316\271\316\272\316\254",
158"en English",
159"es Espa\303\261ol",
160"eu Euskara",
161"eu_ES Euskara (Espainiako)",
162"fa \331\201\330\247\330\261\330\263\333\214",
163"fi Suomi",
164"fr Fran\303\247ais",
165"ga Gaeilge",
166"gl Galego",
167"he \327\242\327\221\327\250\327\231\327\252",
168"hi \340\244\271\340\244\277\340\244\250\340\245\215\340\244\246\340\245\200",
169"hr Hrvatski",
170"hu Magyar",
171"hy \325\200\325\241\325\265\325\245\326\200\325\245\325\266",
172"id Bahasa Indonesia",
173"it Italiano",
174"ja \346\227\245\346\234\254\350\252\236",
175"ka \341\203\245\341\203\220\341\203\240\341\203\227\341\203\243\341\203\232\341\203\230",
176"km \341\236\201\341\237\201\341\236\230\341\236\232\341\236\227\341\236\266\341\236\237\341\236\266",
177"ko \355\225\234\352\265\255\354\226\264",
178"lt Lietuvi\305\263",
179"mk \320\234\320\260\320\272\320\265\320\264\320\276\320\275\321\201\320\272\320\270",
180"mr \340\244\256\340\244\260\340\244\276\340\244\240\340\245\200",
181"my \341\200\231\341\200\274\341\200\224\341\200\272\341\200\231\341\200\254\341\200\205\341\200\254",
182"nb Norsk",
183"nl Nederlands",
184"oc Occitan",
185"pl Polski",
186"pt Portugu\303\252s",
187"pt_BR Portugu\303\252s (Brasil)",
188"ro Rom\303\242n\304\203",
189"ru \320\240\321\203\321\201\321\201\320\272\320\270\320\271",
190"sk Sloven\304\215ina",
191"sl Sloven\305\241\304\215ina",
192"sr_RS \320\241\321\200\320\277\321\201\320\272\320\270",
193"sr_RS@latin Srpski",
194"sv Svenska",
195"ta \340\256\244\340\256\256\340\256\277\340\256\264\340\257\215",
196"tg \320\242\320\276\322\267\320\270\320\272\323\243",
197"tr T\303\274rk\303\247e",
198"uk \320\243\320\272\321\200\320\260\321\227\320\275\321\201\321\214\320\272\320\260",
199"vi Ti\341\272\277ng Vi\341\273\207t",
200"zh_CN \344\270\255\346\226\207\357\274\210\347\256\200\344\275\223\357\274\211",
201"zh_TW \344\270\255\346\226\207\357\274\210\347\271\201\351\253\224\357\274\211",
202 };
203
204 TranslatableStrings tempNames;
205 wxArrayString tempCodes;
206 ReverseLangHash reverseHash;
207 LangHash tempHash;
208
209 const LangHash localLanguageName = []{
210 LangHash localLanguageName;
211 for ( auto utf8Name : utf8Names )
212 {
213 auto str = wxString::FromUTF8(utf8Name);
214 auto code = str.BeforeFirst(' ');
215 auto name = str.AfterFirst(' ');
216 localLanguageName[code] = Verbatim( name );
217 }
218 return localLanguageName;
219 }();
220
221#if defined(__WXGTK__)
222 {
223 wxFileName pathNorm{ wxStandardPaths::Get().GetInstallPrefix() + L"/share/locale" };
224 pathNorm.Normalize();
225 const wxString newPath{ pathNorm.GetFullPath() };
226 if (pathList.end() ==
227 std::find(pathList.begin(), pathList.end(), newPath))
228 pathList.push_back(newPath);
229 }
230#endif
231
232 // For each language in our list we look for a corresponding entry in
233 // wxLocale.
234 for ( auto end = localLanguageName.end(), i = localLanguageName.begin();
235 i != end; ++i )
236 {
237 const wxLanguageInfo *info = wxLocale::FindLanguageInfo(i->first);
238
239 if (!info) {
240 wxASSERT(info != NULL);
241 continue;
242 }
243
244 wxString fullCode = info->CanonicalName;
245 wxString code = fullCode.Left(2);
246 auto name = Verbatim( info->Description );
247
248 // Logic: Languages codes are sometimes hierarchical, with a
249 // general language code and then a subheading. For example,
250 // zh_TW for Traditional Chinese and zh_CN for Simplified
251 // Chinese - but just zh for Chinese in general. First we look
252 // for the full code, like zh_TW. If that doesn't exist, we
253 // look for a code corresponding to the first two letters.
254 // Note that if the language for a fullCode exists but we only
255 // have a name for the short code, we will use the short code's
256 // name but associate it with the full code. This allows someone
257 // to drop in a NEW language and still get reasonable behavior.
258
259 if (fullCode.length() < 2)
260 continue;
261
262 auto found = localLanguageName.find( code );
263 if ( found != end ) {
264 name = found->second;
265 }
266 found = localLanguageName.find( fullCode );
267 if ( found != end ) {
268 name = found->second;
269 }
270
271 if (TranslationExists(pathList, fullCode)) {
272 code = fullCode;
273 }
274
275 if (!tempHash[code].empty())
276 continue;
277
278 if (TranslationExists(pathList, code) || code==wxT("en")) {
279 tempCodes.push_back(code);
280 tempNames.push_back(name);
281 tempHash[code] = name;
282
283/* wxLogDebug(wxT("code=%s name=%s fullCode=%s name=%s -> %s"),
284 code, localLanguageName[code],
285 fullCode, localLanguageName[fullCode],
286 name);*/
287 }
288 }
289
290 // JKC: Adding language for simplified audacity.
291 {
292 wxString code;
293 code = wxT("en-simple");
294 auto name = XO("Simplified");
295 if (TranslationExists(pathList, code) ) {
296 tempCodes.push_back(code);
297 tempNames.push_back(name);
298 tempHash[code] = name;
299 }
300 }
301
302
303 // Sort
304 unsigned int j;
305 for(j=0; j<tempNames.size(); j++){
306 reverseHash[tempNames[j]] = tempCodes[j];
307 }
308
309 std::sort(tempNames.begin(), tempNames.end(), TranslationLess);
310
311 // Add system language
312 langNames.push_back(XO("System"));
313 langCodes.push_back(wxT("System"));
314
315 for(j=0; j<tempNames.size(); j++) {
316 langNames.push_back(tempNames[j]);
317 langCodes.push_back(reverseHash[tempNames[j]]);
318 }
319}
wxT("CloseDown"))
#define str(a)
const TranslatableString name
Definition: Distortion.cpp:76
XO("Cut/Copy/Paste")
std::unordered_map< TranslatableString, wxString > ReverseLangHash
Definition: Languages.cpp:53
static bool TranslationExists(const FilePaths &pathList, wxString code)
Definition: Languages.cpp:65
std::unordered_map< wxString, TranslatableString > LangHash
Definition: Languages.cpp:52
bool TranslationLess(const TranslatableString &a, const TranslatableString &b)
A commonly needed sort comparator, which depends on the language setting.
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::vector< TranslatableString > TranslatableStrings
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:201
const char * end(const char *str) noexcept
Definition: StringUtils.h:106

References details::end(), BasicUI::Get(), name, str, TranslationExists(), TranslationLess(), Verbatim(), wxT(), and XO().

Referenced by GetSystemLanguageCode(), LangChoiceDialog::LangChoiceDialog(), and GUIPrefs::Populate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetLocaleName()

STRINGS_API wxString Languages::GetLocaleName ( )
Returns
a string as from setlocale()

Definition at line 390 of file Languages.cpp.

391{
392 return sLocaleName;
393}
static wxString sLocaleName
Definition: Languages.cpp:322

References sLocaleName.

Referenced by AudacityApp::InitPart2().

Here is the caller graph for this function:

◆ GetSystemLanguageCode()

STRINGS_API wxString Languages::GetSystemLanguageCode ( const FilePaths pathList)
Parameters
pathListpaths to search for .mo files, grouped into subdirectories for the different languages

Definition at line 83 of file Languages.cpp.

84{
85 wxArrayString langCodes;
86 TranslatableStrings langNames;
87
88 GetLanguages(pathList, langCodes, langNames);
89
90 const wxLanguageInfo *info;
91
92#ifdef __WXMAC__
93 // https://github.com/audacity/audacity/issues/2493
94 // It was observed, that macOS can have multiple `system default` languages,
95 // depending on the application rather than the user preferences.
96 // As a workaround, let's query the locale preferences for the application.
97 const wxCFStringRef appleLocale((CFStringRef)CFPreferencesCopyAppValue(CFSTR("AppleLocale"),
98 kCFPreferencesCurrentApplication));
99
100 const auto localeString = appleLocale.AsString();
101 // AppleLocale has `Apple` locale format, but let us try our luck
102 // and pass it FindLanguageInfo, so we can get the best possible match.
103 info = wxLocale::FindLanguageInfo(localeString);
104
105 if (info == nullptr)
106 {
107 // Full match has failed, lets match the language code only.
108 // wxLocale expects a two symbol code
109 wxString langCode = localeString.Left(2);
110 info = wxLocale::FindLanguageInfo(langCode);
111 }
112#else
113 {
114
115 const auto sysLang = wxLocale::GetSystemLanguage();
116 info = wxLocale::GetLanguageInfo(sysLang);
117 }
118#endif
119
120 if (info) {
121 wxString fullCode = info->CanonicalName;
122 if (fullCode.length() < 2)
123 return wxT("en");
124
125 wxString code = fullCode.Left(2);
126 unsigned int i;
127
128 for(i=0; i<langCodes.size(); i++) {
129 if (langCodes[i] == fullCode)
130 return fullCode;
131
132 if (langCodes[i] == code)
133 return code;
134 }
135 }
136
137 return wxT("en");
138}
void GetLanguages(FilePaths pathList, wxArrayString &langCodes, TranslatableStrings &langNames)
Definition: Languages.cpp:140

References GetLanguages(), and wxT().

Referenced by LangChoiceDialog::LangChoiceDialog(), LangChoiceDialog::OnOk(), anonymous_namespace{AudacityApp.cpp}::PopulatePreferences(), NyquistEffect::Process(), and SetLang().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetLang()

STRINGS_API wxString Languages::SetLang ( const FilePaths audacityPathList,
const wxString &  lang 
)
Parameters
audacityPathListpaths to search for .mo files, grouped into subdirectories for the different languages
langa language code; or if empty or "System", then default to system language.
Returns
the language code actually used which is not lang if lang cannot be found.

Definition at line 324 of file Languages.cpp.

325{
326 wxString result = lang;
327
328 sLocale.reset();
329
330#if defined(__WXMAC__)
331 // This should be reviewed again during the wx3 conversion.
332
333 // On OSX, if the LANG environment variable isn't set when
334 // using a language like Japanese, an assertion will trigger
335 // because conversion to Japanese from "?" doesn't return a
336 // valid length, so make OSX happy by defining/overriding
337 // the LANG environment variable with U.S. English for now.
338 wxSetEnv(wxT("LANG"), wxT("en_US.UTF-8"));
339#endif
340
341 const wxLanguageInfo *info = NULL;
342 if (!lang.empty() && lang != wxT("System")) {
343 // Try to find the given language
344 info = wxLocale::FindLanguageInfo(lang);
345 }
346 if (!info)
347 {
348 // Not given a language or can't find it; substitute the system language
349 result = Languages::GetSystemLanguageCode(pathList);
350 info = wxLocale::FindLanguageInfo(result);
351 if (!info)
352 // Return the substituted system language, but we can't complete setup
353 // Should we try to do something better?
354 return result;
355 }
356 sLocale = std::make_unique<wxLocale>(info->Language);
357
358 for( const auto &path : pathList )
359 sLocale->AddCatalogLookupPathPrefix( path );
360
361 // LL: Must add the wxWidgets catalog manually since the search
362 // paths were not set up when mLocale was created. The
363 // catalogs are search in LIFO order, so add wxstd first.
364 sLocale->AddCatalog(wxT("wxstd"));
365
366 // Must match TranslationExists() in Languages.cpp
367 sLocale->AddCatalog("audacity");
368
369 // Initialize internationalisation (number formats etc.)
370 //
371 // This must go _after_ creating the wxLocale instance because
372 // creating the wxLocale instance sets the application-wide locale.
373
375
376 using future1 = decltype(
377 // The file of unused strings is part of the source tree scanned by
378 // xgettext when compiling the catalog template audacity.pot.
379 // Including it here doesn't change that but does make the C++ compiler
380 // check for correct syntax, but also generate no object code for them.
381#include "FutureStrings.h"
382 0
383 );
384
385 sLocaleName = wxSetlocale(LC_ALL, NULL);
386
387 return result;
388}
static void Init()
Initialize internationalisation support. Call this once at program start.
Definition: Internat.cpp:53
wxString GetSystemLanguageCode(const FilePaths &pathList)
Definition: Languages.cpp:83

References GetSystemLanguageCode(), Internat::Init(), sLocale, sLocaleName, and wxT().

Referenced by GUISettings::SetLang().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ sLocale

std::unique_ptr<wxLocale> Languages::sLocale
static

Definition at line 321 of file Languages.cpp.

Referenced by GetLang(), GetLangShort(), and SetLang().

◆ sLocaleName

wxString Languages::sLocaleName
static

Definition at line 322 of file Languages.cpp.

Referenced by GetLocaleName(), and SetLang().