X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2b5f62a0b2db198609b45dec622a018dae37008e..28b4db7f890258e83fa0a57ea85c72585e48b756:/src/common/intl.cpp diff --git a/src/common/intl.cpp b/src/common/intl.cpp index c6fa2cea1a..aef903c92b 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -6,7 +6,7 @@ // Created: 29/01/98 // RCS-ID: $Id$ // Copyright: (c) 1998 Vadim Zeitlin -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -31,7 +31,11 @@ #if wxUSE_INTL // standard headers + +#ifndef __WXWINCE__ #include +#endif + #include #include #ifdef HAVE_LANGINFO_H @@ -48,6 +52,12 @@ #include "wx/dynarray.h" #endif // WX_PRECOMP +#ifdef __WIN32__ + #include "wx/msw/private.h" +#elif defined(__UNIX_LIKE__) + #include "wx/fontmap.h" // for CharsetToEncoding() +#endif + #include "wx/file.h" #include "wx/tokenzr.h" #include "wx/module.h" @@ -55,12 +65,6 @@ #include "wx/encconv.h" #include "wx/hashmap.h" -#ifdef __WIN32__ - #include "wx/msw/private.h" -#elif defined(__UNIX_LIKE__) - #include "wx/fontmap.h" // for CharsetToEncoding() -#endif - #if defined(__WXMAC__) #include "wx/mac/private.h" // includes mac headers #endif @@ -141,13 +145,14 @@ static inline wxString ExtractNotLang(const wxString& langFull) #endif // __UNIX__ + // ---------------------------------------------------------------------------- // wxMsgCatalogFile corresponds to one disk-file message catalog. // // This is a "low-level" class and is used only by wxMsgCatalog // ---------------------------------------------------------------------------- -WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxString, wxMessagesHash) +WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxString, wxMessagesHash); class wxMsgCatalogFile { @@ -187,21 +192,39 @@ private: // all data is stored here, NULL if no data loaded size_t8 *m_pData; + // amount of memory pointed to by m_pData. + size_t32 m_nSize; + // data description size_t32 m_numStrings; // number of strings in this domain wxMsgTableEntry *m_pOrigTable, // pointer to original strings *m_pTransTable; // translated - const char *StringAtOfs(wxMsgTableEntry *pTable, size_t32 index) const - { return (const char *)(m_pData + Swap(pTable[index].ofsString)); } + // swap the 2 halves of 32 bit integer if needed + size_t32 Swap(size_t32 ui) const + { + return m_bSwapped ? (ui << 24) | ((ui & 0xff00) << 8) | + ((ui >> 8) & 0xff00) | (ui >> 24) + : ui; + } + + const char *StringAtOfs(wxMsgTableEntry *pTable, size_t32 n) const + { + const wxMsgTableEntry * const ent = pTable + n; + + // this check could fail for a corrupt message catalog + size_t32 ofsString = Swap(ent->ofsString); + if ( ofsString + Swap(ent->nLen) > m_nSize) + return NULL; + + return (const char *)(m_pData + ofsString); + } wxString GetCharset() const; - // utility functions - // big<->little endian - inline size_t32 Swap(size_t32 ui) const; + bool m_bSwapped; // wrong endianness? - bool m_bSwapped; // wrong endianness? + DECLARE_NO_COPY_CLASS(wxMsgCatalogFile) }; @@ -247,22 +270,15 @@ static wxArrayString s_searchPrefixes; // wxMsgCatalogFile class // ---------------------------------------------------------------------------- -// swap the 2 halves of 32 bit integer if needed -size_t32 wxMsgCatalogFile::Swap(size_t32 ui) const -{ - return m_bSwapped ? (ui << 24) | ((ui & 0xff00) << 8) | - ((ui >> 8) & 0xff00) | (ui >> 24) - : ui; -} - wxMsgCatalogFile::wxMsgCatalogFile() { - m_pData = NULL; + m_pData = NULL; + m_nSize = 0; } wxMsgCatalogFile::~wxMsgCatalogFile() { - wxDELETEA(m_pData); + wxDELETEA(m_pData); } // return all directories to search for given prefix @@ -296,9 +312,11 @@ static wxString GetFullSearchPath(const wxChar *lang) // LC_PATH is a standard env var containing the search path for the .mo // files +#ifndef __WXWINCE__ const wxChar *pszLcPath = wxGetenv(wxT("LC_PATH")); if ( pszLcPath != NULL ) searchPath << GetAllMsgCatalogSubdirs(pszLcPath, lang); +#endif #ifdef __UNIX__ // add some standard ones and the one in the tree where wxWin was installed: @@ -411,6 +429,7 @@ bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName0) Swap(pHeader->ofsOrigTable)); m_pTransTable = (wxMsgTableEntry *)(m_pData + Swap(pHeader->ofsTransTable)); + m_nSize = nSize; // everything is fine return TRUE; @@ -609,8 +628,28 @@ bool wxLocale::Init(const wxChar *szName, { // the argument to setlocale() szLocale = szShort; + + wxCHECK_MSG( szLocale, FALSE, _T("no locale to set in wxLocale::Init()") ); } - m_pszOldLocale = wxSetlocale(LC_ALL, szLocale); + +#ifdef __WXWINCE__ + // FIXME: I'm guessing here + wxChar localeName[256]; + int ret = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLANGUAGE, localeName, + 256); + if (ret != 0) + { + m_pszOldLocale = wxStrdup(localeName); + } + else + m_pszOldLocale = NULL; + + // TODO: how to find languageId + // SetLocaleInfo(languageId, SORT_DEFAULT, localeName); +#else + m_pszOldLocale = wxStrdup(wxSetlocale(LC_ALL, szLocale)); +#endif + if ( m_pszOldLocale == NULL ) wxLogError(_("locale '%s' can not be set."), szLocale); @@ -639,6 +678,23 @@ bool wxLocale::Init(const wxChar *szName, return bOk; } + +#if defined(__UNIX__) && wxUSE_UNICODE +static wxWCharBuffer wxSetlocaleTryUTF(int c, const wxChar *lc) +{ + wxMB2WXbuf l = wxSetlocale(c, lc); + if ( lc && lc[0] != 0 && !l ) + { + wxString buf(lc); + buf += wxT(".utf8"); + l = wxSetlocale(c, buf.c_str()); + } + return l; +} +#else +#define wxSetlocaleTryUTF(c, lc) wxSetlocale(c, lc) +#endif + bool wxLocale::Init(int language, int flags) { int lang = language; @@ -674,12 +730,12 @@ bool wxLocale::Init(int language, int flags) else locale = info->CanonicalName; - wxMB2WXbuf retloc = wxSetlocale(LC_ALL, locale); + wxMB2WXbuf retloc = wxSetlocaleTryUTF(LC_ALL, locale); if ( !retloc ) { // Some C libraries don't like xx_YY form and require xx only - retloc = wxSetlocale(LC_ALL, locale.Mid(0,2)); + retloc = wxSetlocaleTryUTF(LC_ALL, locale.Mid(0,2)); } if ( !retloc ) { @@ -692,14 +748,18 @@ bool wxLocale::Init(int language, int flags) locale = wxT("in") + locale.Mid(3); else if (mid == wxT("yi")) locale = wxT("ji") + locale.Mid(3); + else if (mid == wxT("nb")) + locale = wxT("no_NO"); + else if (mid == wxT("nn")) + locale = wxT("no_NY"); - retloc = wxSetlocale(LC_ALL, locale); + retloc = wxSetlocaleTryUTF(LC_ALL, locale); } if ( !retloc ) { // (This time, we changed locale in previous if-branch, so try again.) // Some C libraries don't like xx_YY form and require xx only - retloc = wxSetlocale(LC_ALL, locale.Mid(0,2)); + retloc = wxSetlocaleTryUTF(LC_ALL, locale.Mid(0,2)); } if ( !retloc ) { @@ -707,6 +767,17 @@ bool wxLocale::Init(int language, int flags) return FALSE; } #elif defined(__WIN32__) + + #if wxUSE_UNICODE && (defined(__VISUALC__) || defined(__MINGW32__)) + // NB: setlocale() from msvcrt.dll (used by VC++ and Mingw) + // can't set locale to language that can only be written using + // Unicode. Therefore wxSetlocale call failed, but we don't want + // to report it as an error -- so that at least message catalogs + // can be used. Watch for code marked with + // #ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS bellow. + #define SETLOCALE_FAILS_ON_UNICODE_LANGS + #endif + wxMB2WXbuf retloc = wxT("C"); if (language != wxLANGUAGE_DEFAULT) { @@ -717,42 +788,69 @@ bool wxLocale::Init(int language, int flags) } else { + int codepage = -1; wxUint32 lcid = MAKELCID(MAKELANGID(info->WinLang, info->WinSublang), SORT_DEFAULT); - if (SetThreadLocale(lcid)) + // FIXME +#ifndef __WXWINCE__ + SetThreadLocale(lcid); +#endif + // NB: we must translate LCID to CRT's setlocale string ourselves, + // because SetThreadLocale does not modify change the + // interpretation of setlocale(LC_ALL, "") call: + wxChar buffer[256]; + buffer[0] = wxT('\0'); + GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, buffer, 256); + locale << buffer; + if (GetLocaleInfo(lcid, LOCALE_SENGCOUNTRY, buffer, 256) > 0) + locale << wxT("_") << buffer; + if (GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE, buffer, 256) > 0) { - retloc = wxSetlocale(LC_ALL, wxEmptyString); + codepage = wxAtoi(buffer); + if (codepage != 0) + locale << wxT(".") << buffer; + } + if (locale.IsEmpty()) + { + wxLogLastError(wxT("SetThreadLocale")); + wxLogError(wxT("Cannot set locale to language %s."), name.c_str()); + return FALSE; } else { - // Windows9X doesn't support SetThreadLocale, so we must - // translate LCID to CRT's setlocale string ourselves - locale.Empty(); - if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) - { - wxChar buffer[256]; - buffer[0] = wxT('\0'); - GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, buffer, 256); - locale << buffer; - if (GetLocaleInfo(lcid, LOCALE_SENGCOUNTRY, buffer, 256) > 0) - locale << wxT("_") << buffer; - } - if (locale.IsEmpty()) - { - wxLogLastError(wxT("SetThreadLocale")); - wxLogError(wxT("Cannot set locale to language %s."), name.c_str()); - return FALSE; - } - else + // FIXME +#ifndef __WXWINCE__ + retloc = wxSetlocale(LC_ALL, locale); +#endif +#ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS + if (codepage == 0 && (const wxChar*)retloc == NULL) { - retloc = wxSetlocale(LC_ALL, locale); + retloc = wxT("C"); } +#endif } } } else { + // FIXME +#ifndef __WXWINCE__ retloc = wxSetlocale(LC_ALL, wxEmptyString); +#else + retloc = NULL; +#endif +#ifdef SETLOCALE_FAILS_ON_UNICODE_LANGS + if ((const wxChar*)retloc == NULL) + { + wxChar buffer[16]; + if (GetLocaleInfo(LOCALE_USER_DEFAULT, + LOCALE_IDEFAULTANSICODEPAGE, buffer, 16) > 0 && + wxStrcmp(buffer, wxT("0")) == 0) + { + retloc = wxT("C"); + } + } +#endif } if ( !retloc ) @@ -764,11 +862,21 @@ bool wxLocale::Init(int language, int flags) wxMB2WXbuf retloc = wxSetlocale(LC_ALL , wxEmptyString); #else return FALSE; + #define WX_NO_LOCALE_SUPPORT #endif - return Init(name, canonical, retloc, - (flags & wxLOCALE_LOAD_DEFAULT) != 0, - (flags & wxLOCALE_CONV_ENCODING) != 0); +#ifndef WX_NO_LOCALE_SUPPORT + wxChar *szLocale = retloc ? wxStrdup(retloc) : NULL; + bool ret = Init(name, canonical, retloc, + (flags & wxLOCALE_LOAD_DEFAULT) != 0, + (flags & wxLOCALE_CONV_ENCODING) != 0); + free(szLocale); + + if ( ret ) + m_language = lang; + + return ret; +#endif } @@ -854,10 +962,16 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix) wxString lang; if ( langOrig == wxT("iw")) lang = _T("he"); - else if ( langOrig == wxT("in") ) + else if (langOrig == wxT("in")) lang = wxT("id"); - else if ( langOrig == wxT("ji") ) + else if (langOrig == wxT("ji")) lang = wxT("yi"); + else if (langOrig == wxT("no_NO")) + lang = wxT("nb_NO"); + else if (langOrig == wxT("no_NY")) + lang = wxT("nn_NO"); + else if (langOrig == wxT("no")) + lang = wxT("nb_NO"); else lang = langOrig; @@ -913,279 +1027,279 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix) } } #elif defined(__WXMAC__) - const char* lc = NULL ; + const wxChar * lc = NULL ; long lang = GetScriptVariable( smSystemScript, smScriptLang) ; switch( GetScriptManagerVariable( smRegionCode ) ) { case verUS : - lc = "en_US" ; + lc = wxT("en_US") ; break ; case verFrance : - lc = "fr_FR" ; + lc = wxT("fr_FR") ; break ; case verBritain : - lc = "en_GB" ; + lc = wxT("en_GB") ; break ; case verGermany : - lc = "de_DE" ; + lc = wxT("de_DE") ; break ; case verItaly : - lc = "it_IT" ; + lc = wxT("it_IT") ; break ; case verNetherlands : - lc = "nl_NL" ; + lc = wxT("nl_NL") ; break ; case verFlemish : - lc = "nl_BE" ; + lc = wxT("nl_BE") ; break ; case verSweden : - lc = "sv_SE" ; + lc = wxT("sv_SE" ); break ; case verSpain : - lc = "es_ES" ; + lc = wxT("es_ES" ); break ; case verDenmark : - lc = "da_DK" ; + lc = wxT("da_DK") ; break ; case verPortugal : - lc = "pt_PT" ; + lc = wxT("pt_PT") ; break ; case verFrCanada: - lc = "fr_CA" ; + lc = wxT("fr_CA") ; break ; case verNorway: - lc = "no_NO" ; + lc = wxT("nb_NO") ; break ; case verIsrael: - lc = "iw_IL" ; + lc = wxT("iw_IL") ; break ; case verJapan: - lc = "ja_JP" ; + lc = wxT("ja_JP") ; break ; case verAustralia: - lc = "en_AU" ; + lc = wxT("en_AU") ; break ; case verArabic: - lc = "ar" ; + lc = wxT("ar") ; break ; case verFinland: - lc = "fi_FI" ; + lc = wxT("fi_FI") ; break ; case verFrSwiss: - lc = "fr_CH" ; + lc = wxT("fr_CH") ; break ; case verGrSwiss: - lc = "de_CH" ; + lc = wxT("de_CH") ; break ; case verGreece: - lc = "el_GR" ; + lc = wxT("el_GR") ; break ; case verIceland: - lc = "is_IS" ; + lc = wxT("is_IS") ; break ; case verMalta: - lc = "mt_MT" ; + lc = wxT("mt_MT") ; break ; case verCyprus: // _CY is not part of wx, so we have to translate according to the system language if ( lang == langGreek ) { - lc = "el_GR" ; + lc = wxT("el_GR") ; } else if ( lang == langTurkish ) { - lc = "tr_TR" ; + lc = wxT("tr_TR") ; } break ; case verTurkey: - lc = "tr_TR" ; + lc = wxT("tr_TR") ; break ; case verYugoCroatian: - lc = "hr_HR" ; + lc = wxT("hr_HR") ; break ; case verIndiaHindi: - lc = "hi_IN" ; + lc = wxT("hi_IN") ; break ; case verPakistanUrdu: - lc = "ur_PK" ; + lc = wxT("ur_PK") ; break ; case verTurkishModified: - lc = "tr_TR" ; + lc = wxT("tr_TR") ; break ; case verItalianSwiss: - lc = "it_CH" ; + lc = wxT("it_CH") ; break ; case verInternational: - lc = "en" ; + lc = wxT("en") ; break ; case verRomania: - lc = "ro_RO" ; + lc = wxT("ro_RO") ; break ; case verGreecePoly: - lc = "el_GR" ; + lc = wxT("el_GR") ; break ; case verLithuania: - lc = "lt_LT" ; + lc = wxT("lt_LT") ; break ; case verPoland: - lc = "pl_PL" ; + lc = wxT("pl_PL") ; break ; case verMagyar : case verHungary: - lc = "hu_HU" ; + lc = wxT("hu_HU") ; break ; case verEstonia: - lc = "et_EE" ; + lc = wxT("et_EE") ; break ; case verLatvia: - lc = "lv_LV" ; + lc = wxT("lv_LV") ; break ; case verSami: // not known break ; case verFaroeIsl: - lc = "fo_FO" ; + lc = wxT("fo_FO") ; break ; case verIran: - lc = "fa_IR" ; + lc = wxT("fa_IR") ; break ; case verRussia: - lc = "ru_RU" ; + lc = wxT("ru_RU") ; break ; case verIreland: - lc = "ga_IE" ; + lc = wxT("ga_IE") ; break ; case verKorea: - lc = "ko_KR" ; + lc = wxT("ko_KR") ; break ; case verChina: - lc = "zh_CN" ; + lc = wxT("zh_CN") ; break ; case verTaiwan: - lc = "zh_TW" ; + lc = wxT("zh_TW") ; break ; case verThailand: - lc = "th_TH" ; + lc = wxT("th_TH") ; break ; case verCzech: - lc = "cs_CZ" ; + lc = wxT("cs_CZ") ; break ; case verSlovak: - lc = "sk_SK" ; + lc = wxT("sk_SK") ; break ; case verBengali: - lc = "bn" ; + lc = wxT("bn") ; break ; case verByeloRussian: - lc = "be_BY" ; + lc = wxT("be_BY") ; break ; case verUkraine: - lc = "uk_UA" ; + lc = wxT("uk_UA") ; break ; case verGreeceAlt: - lc = "el_GR" ; + lc = wxT("el_GR") ; break ; case verSerbian: - lc = "sr_YU" ; + lc = wxT("sr_YU") ; break ; case verSlovenian: - lc = "sl_SI" ; + lc = wxT("sl_SI") ; break ; case verMacedonian: - lc = "mk_MK" ; + lc = wxT("mk_MK") ; break ; case verCroatia: - lc = "hr_HR" ; + lc = wxT("hr_HR") ; break ; case verBrazil: - lc = "pt_BR " ; + lc = wxT("pt_BR ") ; break ; case verBulgaria: - lc = "bg_BG" ; + lc = wxT("bg_BG") ; break ; case verCatalonia: - lc = "ca_ES" ; + lc = wxT("ca_ES") ; break ; case verScottishGaelic: - lc = "gd" ; + lc = wxT("gd") ; break ; case verManxGaelic: - lc = "gv" ; + lc = wxT("gv") ; break ; case verBreton: - lc = "br" ; + lc = wxT("br") ; break ; case verNunavut: - lc = "iu_CA" ; + lc = wxT("iu_CA") ; break ; case verWelsh: - lc = "cy" ; + lc = wxT("cy") ; break ; case verIrishGaelicScript: - lc = "ga_IE" ; + lc = wxT("ga_IE") ; break ; case verEngCanada: - lc = "en_CA" ; + lc = wxT("en_CA") ; break ; case verBhutan: - lc = "dz_BT" ; + lc = wxT("dz_BT") ; break ; case verArmenian: - lc = "hy_AM" ; + lc = wxT("hy_AM") ; break ; case verGeorgian: - lc = "ka_GE" ; + lc = wxT("ka_GE") ; break ; case verSpLatinAmerica: - lc = "es_AR" ; + lc = wxT("es_AR") ; break ; case verTonga: - lc = "to_TO" ; + lc = wxT("to_TO" ); break ; case verFrenchUniversal: - lc = "fr_FR" ; + lc = wxT("fr_FR") ; break ; case verAustria: - lc = "de_AT" ; + lc = wxT("de_AT") ; break ; case verGujarati: - lc = "gu_IN" ; + lc = wxT("gu_IN") ; break ; case verPunjabi: - lc = "pa" ; + lc = wxT("pa") ; break ; case verIndiaUrdu: - lc = "ur_IN" ; + lc = wxT("ur_IN") ; break ; case verVietnam: - lc = "vi_VN" ; + lc = wxT("vi_VN") ; break ; case verFrBelgium: - lc = "fr_BE" ; + lc = wxT("fr_BE") ; break ; case verUzbek: - lc = "uz_UZ" ; + lc = wxT("uz_UZ") ; break ; case verSingapore: - lc = "zh_SG" ; + lc = wxT("zh_SG") ; break ; case verNynorsk: - lc = "nn_NO" ; + lc = wxT("nn_NO") ; break ; case verAfrikaans: - lc = "af_ZA" ; + lc = wxT("af_ZA") ; break ; case verEsperanto: - lc = "eo" ; + lc = wxT("eo") ; break ; case verMarathi: - lc = "mr_IN" ; + lc = wxT("mr_IN") ; break ; case verTibetan: - lc = "bo" ; + lc = wxT("bo") ; break ; case verNepal: - lc = "ne_NP" ; + lc = wxT("ne_NP") ; break ; case verGreenland: - lc = "kl_GL" ; + lc = wxT("kl_GL") ; break ; default : break ; @@ -1384,7 +1498,7 @@ const wxLanguageInfo *wxLocale::GetLanguageInfo(int lang) { CreateLanguagesDB(); - size_t count = ms_languagesDB->GetCount(); + const size_t count = ms_languagesDB->GetCount(); for ( size_t i = 0; i < count; i++ ) { if ( ms_languagesDB->Item(i).Language == lang ) @@ -1396,9 +1510,60 @@ const wxLanguageInfo *wxLocale::GetLanguageInfo(int lang) return NULL; } +/* static */ +wxString wxLocale::GetLanguageName(int lang) +{ + const wxLanguageInfo *info = GetLanguageInfo(lang); + if ( !info ) + return wxEmptyString; + else + return info->Description; +} + +/* static */ +const wxLanguageInfo *wxLocale::FindLanguageInfo(const wxString& locale) +{ + CreateLanguagesDB(); + + const wxLanguageInfo *infoRet = NULL; + + const size_t count = ms_languagesDB->GetCount(); + for ( size_t i = 0; i < count; i++ ) + { + const wxLanguageInfo *info = &ms_languagesDB->Item(i); + + if ( wxStricmp(locale, info->CanonicalName) == 0 || + wxStricmp(locale, info->Description) == 0 ) + { + // exact match, stop searching + infoRet = info; + break; + } + + if ( wxStricmp(locale, info->CanonicalName.BeforeFirst(_T('_'))) == 0 ) + { + // a match -- but maybe we'll find an exact one later, so continue + // looking + // + // OTOH, maybe we had already found a language match and in this + // case don't overwrite it becauce the entry for the default + // country always appears first in ms_languagesDB + if ( !infoRet ) + infoRet = info; + } + } + + return infoRet; +} + wxString wxLocale::GetSysName() const { + // FIXME +#ifndef __WXWINCE__ return wxSetlocale(LC_ALL, NULL); +#else + return wxEmptyString; +#endif } // clean up @@ -1414,7 +1579,11 @@ wxLocale::~wxLocale() // restore old locale wxSetLocale(m_pOldLocale); + // FIXME +#ifndef __WXWINCE__ wxSetlocale(LC_ALL, m_pszOldLocale); +#endif + free((wxChar *)m_pszOldLocale); // const_cast } // get the translation of given string in current locale @@ -2168,7 +2337,7 @@ void wxLocale::InitLanguagesDB() LNG(wxLANGUAGE_CATALAN, "ca_ES", LANG_CATALAN , SUBLANG_DEFAULT , "Catalan") LNG(wxLANGUAGE_CHINESE, "zh_CN", LANG_CHINESE , SUBLANG_DEFAULT , "Chinese") LNG(wxLANGUAGE_CHINESE_SIMPLIFIED, "zh_CN", LANG_CHINESE , SUBLANG_CHINESE_SIMPLIFIED , "Chinese (Simplified)") - LNG(wxLANGUAGE_CHINESE_TRADITIONAL, "zh_CN", LANG_CHINESE , SUBLANG_CHINESE_TRADITIONAL , "Chinese (Traditional)") + LNG(wxLANGUAGE_CHINESE_TRADITIONAL, "zh_TW", LANG_CHINESE , SUBLANG_CHINESE_TRADITIONAL , "Chinese (Traditional)") LNG(wxLANGUAGE_CHINESE_HONGKONG, "zh_HK", LANG_CHINESE , SUBLANG_CHINESE_HONGKONG , "Chinese (Hongkong)") LNG(wxLANGUAGE_CHINESE_MACAU, "zh_MO", LANG_CHINESE , SUBLANG_CHINESE_MACAU , "Chinese (Macau)") LNG(wxLANGUAGE_CHINESE_SINGAPORE, "zh_SG", LANG_CHINESE , SUBLANG_CHINESE_SINGAPORE , "Chinese (Singapore)") @@ -2266,7 +2435,7 @@ void wxLocale::InitLanguagesDB() LNG(wxLANGUAGE_NAURU, "na" , 0 , 0 , "Nauru") LNG(wxLANGUAGE_NEPALI, "ne" , LANG_NEPALI , SUBLANG_DEFAULT , "Nepali") LNG(wxLANGUAGE_NEPALI_INDIA, "ne_IN", LANG_NEPALI , SUBLANG_NEPALI_INDIA , "Nepali (India)") - LNG(wxLANGUAGE_NORWEGIAN_BOKMAL, "no_NO", LANG_NORWEGIAN , SUBLANG_NORWEGIAN_BOKMAL , "Norwegian (Bokmal)") + LNG(wxLANGUAGE_NORWEGIAN_BOKMAL, "nb_NO", LANG_NORWEGIAN , SUBLANG_NORWEGIAN_BOKMAL , "Norwegian (Bokmal)") LNG(wxLANGUAGE_NORWEGIAN_NYNORSK, "nn_NO", LANG_NORWEGIAN , SUBLANG_NORWEGIAN_NYNORSK , "Norwegian (Nynorsk)") LNG(wxLANGUAGE_OCCITAN, "oc" , 0 , 0 , "Occitan") LNG(wxLANGUAGE_ORIYA, "or" , LANG_ORIYA , SUBLANG_DEFAULT , "Oriya")