/********************************************************************** Audacity: A Digital Audio Editor Languages.cpp Dominic Mazzoni *******************************************************************//*! \file Languages.cpp \brief Determine installed languages. Figure out what translations are installed and return a list of language codes (like "es", "fr", or "pt-br") and corresponding language names (like "Español", "Français", and "Português"). We use our own list of translations of language names (i.e. "Français" instead of "French") but we fallback on the language name in wxWidgets if we don't have it listed. This code is designed to work well with all of the current languages, but adapt to any language that wxWidgets supports. Other languages will only be supported if they're added to the database using wxLocale::AddLanguage. But for the most part, this means that somebody could add a new translation and have it work immediately. *//*******************************************************************/ #include "Audacity.h" #include #include #include #include "Languages.h" #include "AudacityApp.h" #include WX_DECLARE_STRING_HASH_MAP(wxString, LangHash); bool TranslationExists(wxArrayString &audacityPathList, wxString code) { wxArrayString results; wxGetApp().FindFilesInPathList(wxString::Format(wxT("%s/audacity.mo"), code.c_str()), audacityPathList, results); wxGetApp().FindFilesInPathList(wxString::Format(wxT("%s/LC_MESSAGES/audacity.mo"), code.c_str()), audacityPathList, results); return (results.GetCount() > 0); } wxString GetSystemLanguageCode() { wxArrayString langCodes; wxArrayString langNames; GetLanguages(langCodes, langNames); int sysLang = wxLocale::GetSystemLanguage(); const wxLanguageInfo *info = wxLocale::GetLanguageInfo(sysLang); if (info) { wxString fullCode = info->CanonicalName; if (fullCode.Length() < 2) return wxT("en"); wxString code = fullCode.Left(2); unsigned int i; for(i=0; iCanonicalName; wxString code = fullCode.Left(2); wxString name = info->Description; // Logic: Languages codes are sometimes hierarchical, with a // general language code and then a subheading. For example, // zh_TW for Traditional Chinese and zh_CN for Simplified // Chinese - but just zh for Chinese in general. First we look // for the full code, like zh_TW. If that doesn't exist, we // look for a code corresponding to the first two letters. // Note that if the language for a fullCode exists but we only // have a name for the short code, we will use the short code's // name but associate it with the full code. This allows someone // to drop in a new language and still get reasonable behavior. if (fullCode.Length() < 2) continue; if (localLanguageName[code] != wxT("")) { name = localLanguageName[code]; } if (localLanguageName[fullCode] != wxT("")) { name = localLanguageName[fullCode]; } if (TranslationExists(audacityPathList, fullCode)) { code = fullCode; } if (tempHash[code] != wxT("")) continue; if (TranslationExists(audacityPathList, code) || code==wxT("en")) { tempCodes.Add(code); tempNames.Add(name); tempHash[code] = name; /* for debugging */ wxLogDebug(wxT("code=%s name=%s fullCode=%s name=%s -> %s\n"), code.c_str(), localLanguageName[code].c_str(), fullCode.c_str(), localLanguageName[fullCode].c_str(), name.c_str()); } } // JKC: Adding language for simplified audacity. { wxString code; wxString name; code = wxT("en-simple"); name = wxT("Simplified"); if (TranslationExists(audacityPathList, code) ) { tempCodes.Add(code); tempNames.Add(name); tempHash[code] = name; /* for debugging printf(wxT("code=%s name=%s fullCode=%s name=%s -> %s\n"), code.c_str(), localLanguageName[code].c_str(), fullCode.c_str(), localLanguageName[fullCode].c_str(), name.c_str()); */ } } // Sort unsigned int j; for(j=0; j