Audacity  3.0.3
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 }

References sLocale.

◆ 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 137 of file Languages.cpp.

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

References BasicUI::Get(), name, TranslationExists(), Verbatim(), 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 }

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  int sysLang = wxLocale::GetSystemLanguage();
91 
92  const wxLanguageInfo *info;
93 
94 #ifdef __WXMAC__
95  // PRL: Bug 1227, system language on Mac may not be right because wxW3 is
96  // dependent on country code too in wxLocale::GetSystemLanguage().
97 
98  if (sysLang == wxLANGUAGE_UNKNOWN)
99  {
100  // wxW3 did a too-specific lookup of language and country, when
101  // there is nothing for that combination; try it by language alone.
102 
103  // The following lines are cribbed from that function.
104  wxCFRef<CFLocaleRef> userLocaleRef(CFLocaleCopyCurrent());
105  wxCFStringRef str(wxCFRetain((CFStringRef)CFLocaleGetValue(userLocaleRef, kCFLocaleLanguageCode)));
106  auto lang = str.AsString();
107 
108  // Now avoid wxLocale::GetLanguageInfo(), instead calling:
109  info = wxLocale::FindLanguageInfo(lang);
110  }
111  else
112 #endif
113  {
114  info = wxLocale::GetLanguageInfo(sysLang);
115  }
116 
117  if (info) {
118  wxString fullCode = info->CanonicalName;
119  if (fullCode.length() < 2)
120  return wxT("en");
121 
122  wxString code = fullCode.Left(2);
123  unsigned int i;
124 
125  for(i=0; i<langCodes.size(); i++) {
126  if (langCodes[i] == fullCode)
127  return fullCode;
128 
129  if (langCodes[i] == code)
130  return code;
131  }
132  }
133 
134  return wxT("en");
135 }

References GetLanguages().

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 
374  Internat::Init();
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 }

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

Referenced by GUIPrefs::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().

TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
TranslatableStrings
std::vector< TranslatableString > TranslatableStrings
Definition: TranslatableString.h:295
Languages::sLocale
static std::unique_ptr< wxLocale > sLocale
Definition: Languages.cpp:321
XO
#define XO(s)
Definition: Internat.h:31
Languages::sLocaleName
static wxString sLocaleName
Definition: Languages.cpp:322
BasicUI::Get
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:26
name
const TranslatableString name
Definition: Distortion.cpp:98
TranslationExists
static bool TranslationExists(const FilePaths &pathList, wxString code)
Definition: Languages.cpp:65
ReverseLangHash
std::unordered_map< TranslatableString, wxString > ReverseLangHash
Definition: Languages.cpp:53
Languages::GetLanguages
void GetLanguages(FilePaths pathList, wxArrayString &langCodes, TranslatableStrings &langNames)
Definition: Languages.cpp:137
Verbatim
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
Definition: TranslatableString.h:321
Languages::GetSystemLanguageCode
wxString GetSystemLanguageCode(const FilePaths &pathList)
Definition: Languages.cpp:83
LangHash
std::unordered_map< wxString, TranslatableString > LangHash
Definition: Languages.cpp:52
Internat::Init
static void Init()
Initialize internationalisation support. Call this once at program start.
Definition: Internat.cpp:78