X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/baf736e1f34666a81706bbef3b0c80ed59869859..a148cfb64451d6553cf66d1075b654e54e908210:/src/common/intl.cpp diff --git a/src/common/intl.cpp b/src/common/intl.cpp index ad3ce22570..e2a7299f7a 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -147,7 +147,7 @@ static inline wxString ExtractNotLang(const wxString& langFull) // This is a "low-level" class and is used only by wxMsgCatalog // ---------------------------------------------------------------------------- -WX_DECLARE_STRING_HASH_MAP(wxString, wxMessagesHash) +WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxString, wxMessagesHash); class wxMsgCatalogFile { @@ -194,7 +194,7 @@ private: const char *StringAtOfs(wxMsgTableEntry *pTable, size_t32 index) const { return (const char *)(m_pData + Swap(pTable[index].ofsString)); } - + wxString GetCharset() const; // utility functions @@ -202,6 +202,8 @@ private: inline size_t32 Swap(size_t32 ui) const; bool m_bSwapped; // wrong endianness? + + DECLARE_NO_COPY_CLASS(wxMsgCatalogFile) }; @@ -300,6 +302,15 @@ static wxString GetFullSearchPath(const wxChar *lang) if ( pszLcPath != NULL ) searchPath << GetAllMsgCatalogSubdirs(pszLcPath, lang); +#ifdef __UNIX__ + // add some standard ones and the one in the tree where wxWin was installed: + searchPath + << GetAllMsgCatalogSubdirs(wxString(wxGetInstallPrefix()) + wxT("/share/locale"), lang) + << GetAllMsgCatalogSubdirs(wxT("/usr/share/locale"), lang) + << GetAllMsgCatalogSubdirs(wxT("/usr/lib/locale"), lang) + << GetAllMsgCatalogSubdirs(wxT("/usr/local/share/locale"), lang); +#endif // __UNIX__ + // then take the current directory // FIXME it should be the directory of the executable #ifdef __WXMAC__ @@ -307,15 +318,11 @@ static wxString GetFullSearchPath(const wxChar *lang) wxGetWorkingDirectory( cwd , sizeof( cwd ) ) ; searchPath << GetAllMsgCatalogSubdirs(cwd, lang); // generic search paths could be somewhere in the system folder preferences -#else +#else // !Mac searchPath << GetAllMsgCatalogSubdirs(wxT("."), lang); - // and finally add some standard ones - searchPath - << GetAllMsgCatalogSubdirs(wxT("/usr/share/locale"), lang) - << GetAllMsgCatalogSubdirs(wxT("/usr/lib/locale"), lang) - << GetAllMsgCatalogSubdirs(wxT("/usr/local/share/locale"), lang); -#endif +#endif // platform + return searchPath; } @@ -420,7 +427,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons if ( !!charset ) csConv = new wxCSConv(charset); - wxMBConv& inputConv = csConv ? *csConv : *wxConvCurrent; + wxMBConv& inputConv = csConv ? *((wxMBConv*)csConv) : *wxConvCurrent; for (size_t i = 0; i < m_numStrings; i++) { @@ -430,7 +437,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons hash[key] = wxString(StringAtOfs(m_pTransTable, i), inputConv); #else if ( convertEncoding ) - hash[key] = + hash[key] = wxString(inputConv.cMB2WC(StringAtOfs(m_pTransTable, i)), wxConvLocal); else @@ -444,7 +451,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons if ( convertEncoding ) { wxFontEncoding targetEnc = wxFONTENCODING_SYSTEM; - wxFontEncoding enc = wxTheFontMapper->CharsetToEncoding(charset, FALSE); + wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(charset, FALSE); if ( enc == wxFONTENCODING_SYSTEM ) { convertEncoding = FALSE; // unknown encoding @@ -457,7 +464,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons wxFontEncodingArray a = wxEncodingConverter::GetPlatformEquivalents(enc); if (a[0] == enc) // no conversion needed, locale uses native encoding - convertEncoding = FALSE; + convertEncoding = FALSE; if (a.GetCount() == 0) // we don't know common equiv. under this platform convertEncoding = FALSE; @@ -473,7 +480,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, bool convertEncoding) cons for (size_t i = 0; i < m_numStrings; i++) { wxString key(StringAtOfs(m_pOrigTable, i)); - hash[key] = + hash[key] = converter.Convert(wxString(StringAtOfs(m_pTransTable, i))); } } @@ -495,31 +502,31 @@ wxString wxMsgCatalogFile::GetCharset() const { // first, find encoding header: const char *hdr = StringAtOfs(m_pOrigTable, 0); - if ( hdr == NULL || hdr[0] != 0 ) + if ( hdr == NULL || hdr[0] != 0 ) { // not supported by this catalog, does not have correct header return wxEmptyString; } - wxString header(StringAtOfs(m_pTransTable, 0)); + wxString header = wxString::FromAscii( StringAtOfs(m_pTransTable, 0)); wxString charset; int pos = header.Find(wxT("Content-Type: text/plain; charset=")); if ( pos == wxNOT_FOUND ) { // incorrectly filled Content-Type header - return wxEmptyString; + return wxEmptyString; } size_t n = pos + 34; /*strlen("Content-Type: text/plain; charset=")*/ while ( header[n] != wxT('\n') ) charset << header[n++]; - + if ( charset == wxT("CHARSET") ) { // "CHARSET" is not valid charset, but lazy translator return wxEmptyString; } - + return charset; } @@ -527,20 +534,20 @@ wxString wxMsgCatalogFile::GetCharset() const // wxMsgCatalog class // ---------------------------------------------------------------------------- -bool wxMsgCatalog::Load(const wxChar *szDirPrefix, const wxChar *szName, +bool wxMsgCatalog::Load(const wxChar *szDirPrefix, const wxChar *szName, bool bConvertEncoding) { wxMsgCatalogFile file; - + m_name = szName; - + if ( file.Load(szDirPrefix, szName) ) { file.FillHash(m_messages, bConvertEncoding); return TRUE; } - else - return FALSE; + + return FALSE; } const wxChar *wxMsgCatalog::GetString(const wxChar *sz) const @@ -604,6 +611,8 @@ 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); if ( m_pszOldLocale == NULL ) @@ -636,11 +645,7 @@ bool wxLocale::Init(const wxChar *szName, bool wxLocale::Init(int language, int flags) { - wxLanguageInfo *info = NULL; int lang = language; - - CreateLanguagesDB(); - if (lang == wxLANGUAGE_DEFAULT) { // auto detect the language @@ -653,17 +658,7 @@ bool wxLocale::Init(int language, int flags) return FALSE; } - if (lang != wxLANGUAGE_DEFAULT) - { - for (size_t i = 0; i < ms_languagesDB->GetCount(); i++) - { - if (ms_languagesDB->Item(i).Language == lang) - { - info = &ms_languagesDB->Item(i); - break; - } - } - } + const wxLanguageInfo *info = GetLanguageInfo(lang); // Unknown language: if (info == NULL) @@ -675,57 +670,63 @@ bool wxLocale::Init(int language, int flags) wxString name = info->Description; wxString canonical = info->CanonicalName; wxString locale; - const wxChar *retloc; // Set the locale: -#ifdef __UNIX__ +#if defined(__UNIX__) && !defined(__WXMAC__) if (language == wxLANGUAGE_DEFAULT) locale = wxEmptyString; else locale = info->CanonicalName; - retloc = wxSetlocale(LC_ALL, locale); + wxMB2WXbuf retloc = wxSetlocale(LC_ALL, locale); - if (retloc == NULL) + if ( !retloc ) { // Some C libraries don't like xx_YY form and require xx only retloc = wxSetlocale(LC_ALL, locale.Mid(0,2)); } - if (retloc == NULL) + if ( !retloc ) { // Some C libraries (namely glibc) still use old ISO 639, // so will translate the abbrev for them wxString mid = locale.Mid(0,2); - if (mid == wxT("he")) locale = wxT("iw") + locale.Mid(3); - else if (mid == wxT("id")) locale = wxT("in") + locale.Mid(3); - else if (mid == wxT("yi")) locale = wxT("ji") + locale.Mid(3); + if (mid == wxT("he")) + locale = wxT("iw") + locale.Mid(3); + else if (mid == wxT("id")) + locale = wxT("in") + locale.Mid(3); + else if (mid == wxT("yi")) + locale = wxT("ji") + locale.Mid(3); + retloc = wxSetlocale(LC_ALL, locale); } - if (retloc == NULL) + 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)); } - if (retloc == NULL) + if ( !retloc ) { wxLogError(wxT("Cannot set locale to '%s'."), locale.c_str()); return FALSE; } #elif defined(__WIN32__) + wxMB2WXbuf retloc = wxT("C"); if (language != wxLANGUAGE_DEFAULT) { if (info->WinLang == 0) { wxLogWarning(wxT("Locale '%s' not supported by OS."), name.c_str()); - retloc = wxT("C"); + // retloc already set to "C" } else { wxUint32 lcid = MAKELCID(MAKELANGID(info->WinLang, info->WinSublang), SORT_DEFAULT); if (SetThreadLocale(lcid)) + { retloc = wxSetlocale(LC_ALL, wxEmptyString); + } else { // Windows9X doesn't support SetThreadLocale, so we must @@ -747,27 +748,38 @@ bool wxLocale::Init(int language, int flags) return FALSE; } else + { retloc = wxSetlocale(LC_ALL, locale); + } } } } else + { retloc = wxSetlocale(LC_ALL, wxEmptyString); + } - if (retloc == NULL) + if ( !retloc ) { wxLogError(wxT("Cannot set locale to language %s."), name.c_str()); return FALSE; } -#elif defined(__WXMAC__) - retloc = wxSetlocale(LC_ALL , wxEmptyString); +#elif defined(__WXMAC__) || defined(__WXPM__) + wxMB2WXbuf retloc = wxSetlocale(LC_ALL , wxEmptyString); #else return FALSE; + #define WX_NO_LOCALE_SUPPORT #endif - return Init(name, canonical, wxString(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); + if (szLocale) + free(szLocale); + return ret; +#endif } @@ -789,7 +801,7 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix) size_t i = 0, count = ms_languagesDB->GetCount(); -#if defined(__UNIX__) +#if defined(__UNIX__) && !defined(__WXMAC__) // first get the string identifying the language from the environment wxString langFull; if (!wxGetEnv(wxT("LC_ALL"), &langFull) && @@ -912,7 +924,7 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix) } } #elif defined(__WXMAC__) - char* lc = NULL ; + const char* lc = NULL ; long lang = GetScriptVariable( smSystemScript, smScriptLang) ; switch( GetScriptManagerVariable( smRegionCode ) ) { case verUS : @@ -1196,7 +1208,7 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix) break; } } - + #elif defined(__WIN32__) LCID lcid = GetUserDefaultLCID(); if ( lcid != 0 ) @@ -1253,20 +1265,25 @@ wxString wxLocale::GetSystemEncodingName() char *alang = nl_langinfo(CODESET); setlocale(LC_CTYPE, oldLocale); free(oldLocale); - if (alang) + + if ( alang ) { -#ifdef __SOLARIS__ + // 7 bit ASCII encoding has several alternative names which we should + // recognize to avoid warnings about unrecognized encoding on each + // program startup + // nl_langinfo() under Solaris returns 646 by default which stands for - // ISO-646, i.e. 7 bit ASCII and we should recognize it to avoid - // warnings about unrecognized encoding on each program startup - if ( strcmp(alang, "646") == 0 ) + // ISO-646, i.e. 7 bit ASCII + // + // and recent glibc call it ANSI_X3.4-1968... + if ( strcmp(alang, "646") == 0 || + strcmp(alang, "ANSI_X3.4-1968") == 0 ) { encname = _T("US-ASCII"); } else -#endif // __SOLARIS__ { - encname = wxConvLibc.cMB2WX(alang); + encname = wxString::FromAscii( alang ); } } else @@ -1275,24 +1292,24 @@ wxString wxLocale::GetSystemEncodingName() // if we can't get at the character set directly, try to see if it's in // the environment variables (in most cases this won't work, but I was // out of ideas) - wxChar *lang = wxGetenv(wxT("LC_ALL")); - wxChar *dot = lang ? wxStrchr(lang, wxT('.')) : (wxChar *)NULL; + char *lang = getenv( "LC_ALL"); + char *dot = lang ? strchr(lang, '.') : (char *)NULL; if (!dot) { - lang = wxGetenv(wxT("LC_CTYPE")); + lang = getenv( "LC_CTYPE" ); if ( lang ) - dot = wxStrchr(lang, wxT('.')); + dot = strchr(lang, '.' ); } if (!dot) { - lang = wxGetenv(wxT("LANG")); + lang = getenv( "LANG"); if ( lang ) - dot = wxStrchr(lang, wxT('.')); + dot = strchr(lang, '.'); } if ( dot ) { - encname = dot+1; + encname = wxString::FromAscii( dot+1 ); } } #endif // Win32/Unix @@ -1335,9 +1352,20 @@ wxFontEncoding wxLocale::GetSystemEncoding() wxString encname = GetSystemEncodingName(); if ( !encname.empty() ) { - wxFontEncoding enc = wxTheFontMapper-> + wxFontEncoding enc = wxFontMapper::Get()-> CharsetToEncoding(encname, FALSE /* not interactive */); + // on some modern Linux systems (RedHat 8) the default system locale + // is UTF8 -- but it isn't supported by wxGTK in ANSI build at all so + // don't even try to use it in this case +#if !wxUSE_UNICODE + if ( enc == wxFONTENCODING_UTF8 ) + { + // the most similar supported encoding... + enc = wxFONTENCODING_ISO8859_1; + } +#endif // !wxUSE_UNICODE + // this should probably be considered as a bug in CharsetToEncoding(): // it shouldn't return wxFONTENCODING_DEFAULT at all - but it does it // for US-ASCII charset @@ -1355,12 +1383,30 @@ wxFontEncoding wxLocale::GetSystemEncoding() return wxFONTENCODING_SYSTEM; } -/*static*/ void wxLocale::AddLanguage(const wxLanguageInfo& info) +/* static */ +void wxLocale::AddLanguage(const wxLanguageInfo& info) { CreateLanguagesDB(); ms_languagesDB->Add(info); } +/* static */ +const wxLanguageInfo *wxLocale::GetLanguageInfo(int lang) +{ + CreateLanguagesDB(); + + size_t count = ms_languagesDB->GetCount(); + for ( size_t i = 0; i < count; i++ ) + { + if ( ms_languagesDB->Item(i).Language == lang ) + { + return &ms_languagesDB->Item(i); + } + } + + return NULL; +} + wxString wxLocale::GetSysName() const { return wxSetlocale(LC_ALL, NULL); @@ -1392,7 +1438,7 @@ const wxChar *wxLocale::GetString(const wxChar *szOrigString, const wxChar *pszTrans = NULL; wxMsgCatalog *pMsgCat; - if ( szDomain != NULL ) + if ( szDomain != NULL ) { pMsgCat = FindCatalog(szDomain); @@ -1400,10 +1446,10 @@ const wxChar *wxLocale::GetString(const wxChar *szOrigString, if ( pMsgCat != NULL ) pszTrans = pMsgCat->GetString(szOrigString); } - else + else { // search in all domains - for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext ) + for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext ) { pszTrans = pMsgCat->GetString(szOrigString); if ( pszTrans != NULL ) // take the first found @@ -1411,21 +1457,23 @@ const wxChar *wxLocale::GetString(const wxChar *szOrigString, } } - if ( pszTrans == NULL ) + if ( pszTrans == NULL ) { #ifdef __WXDEBUG__ - if ( !NoTransErr::Suppress() ) + if ( !NoTransErr::Suppress() ) { NoTransErr noTransErr; if ( szDomain != NULL ) { - wxLogDebug(_T("string '%s' not found in domain '%s' for locale '%s'."), - szOrigString, szDomain, m_strLocale.c_str()); + wxLogTrace(_T("i18n"), + _T("string '%s' not found in domain '%s' for locale '%s'."), + szOrigString, szDomain, m_strLocale.c_str()); } else { - wxLogDebug(_T("string '%s' not found in locale '%s'."), + wxLogTrace(_T("i18n"), + _T("string '%s' not found in locale '%s'."), szOrigString, m_strLocale.c_str()); } } @@ -1442,7 +1490,7 @@ wxMsgCatalog *wxLocale::FindCatalog(const wxChar *szDomain) const { // linear search in the linked list wxMsgCatalog *pMsgCat; - for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext ) + for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext ) { if ( wxStricmp(pMsgCat->GetName(), szDomain) == 0 ) return pMsgCat; @@ -2079,7 +2127,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxLocaleModule, wxModule) #define LNG(wxlang, canonical, winlang, winsublang, desc) \ info.Language = wxlang; \ info.CanonicalName = wxT(canonical); \ - info.Description = desc; \ + info.Description = wxT(desc); \ SETWINLANG(info, winlang, winsublang) \ AddLanguage(info); @@ -2088,7 +2136,7 @@ void wxLocale::InitLanguagesDB() wxLanguageInfo info; wxStringTokenizer tkn; - LNG(wxLANGUAGE_ABKHAZIAN, "ab" , 0 , 0 , "Abkhazian") + LNG(wxLANGUAGE_ABKHAZIAN, "ab" , 0 , 0 , "Abkhazian") LNG(wxLANGUAGE_AFAR, "aa" , 0 , 0 , "Afar") LNG(wxLANGUAGE_AFRIKAANS, "af_ZA", LANG_AFRIKAANS , SUBLANG_DEFAULT , "Afrikaans") LNG(wxLANGUAGE_ALBANIAN, "sq_AL", LANG_ALBANIAN , SUBLANG_DEFAULT , "Albanian") @@ -2135,7 +2183,7 @@ void wxLocale::InitLanguagesDB() 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)") - LNG(wxLANGUAGE_CHINESE_TAIWAN, "zh_TW", 0 , 0 , "Chinese (Taiwan)") + LNG(wxLANGUAGE_CHINESE_TAIWAN, "zh_TW", LANG_CHINESE , SUBLANG_CHINESE_TRADITIONAL , "Chinese (Taiwan)") LNG(wxLANGUAGE_CORSICAN, "co" , 0 , 0 , "Corsican") LNG(wxLANGUAGE_CROATIAN, "hr_HR", LANG_CROATIAN , SUBLANG_DEFAULT , "Croatian") LNG(wxLANGUAGE_CZECH, "cs_CZ", LANG_CZECH , SUBLANG_DEFAULT , "Czech") @@ -2316,7 +2364,7 @@ void wxLocale::InitLanguagesDB() LNG(wxLANGUAGE_YORUBA, "yo" , 0 , 0 , "Yoruba") LNG(wxLANGUAGE_ZHUANG, "za" , 0 , 0 , "Zhuang") LNG(wxLANGUAGE_ZULU, "zu" , 0 , 0 , "Zulu") - + }; #undef LNG