X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/58ad1bab8cea288c067e20181b8f9a13f327f913..0aaa804e7019b8187e2d35dffba133b43af79533:/src/common/intl.cpp diff --git a/src/common/intl.cpp b/src/common/intl.cpp index 9dfb288cd0..d47dbea5b1 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -79,6 +79,8 @@ #include "wx/encconv.h" #include "wx/hashmap.h" #include "wx/ptr_scpd.h" +#include "wx/app.h" +#include "wx/apptrait.h" #if defined(__WXMAC__) #include "wx/mac/private.h" // includes mac headers @@ -100,14 +102,13 @@ typedef wxUint32 size_t32; const size_t32 MSGCATALOG_MAGIC = 0x950412de; const size_t32 MSGCATALOG_MAGIC_SW = 0xde120495; -// extension of ".mo" files -#define MSGCATALOG_EXTENSION _T(".mo") - // the constants describing the format of lang_LANG locale string static const size_t LEN_LANG = 2; static const size_t LEN_SUBLANG = 2; static const size_t LEN_FULL = LEN_LANG + 1 + LEN_SUBLANG; // 1 for '_' +#define TRACE_I18N _T("i18n") + // ---------------------------------------------------------------------------- // global functions // ---------------------------------------------------------------------------- @@ -499,7 +500,6 @@ public: ~wxPluralFormsCalculator() {} void init(wxPluralFormsToken::Number nplurals, wxPluralFormsNode* plural); - wxString getString() const; private: wxPluralFormsToken::Number m_nplurals; @@ -1078,13 +1078,24 @@ static wxString GetFullSearchPath(const wxChar *lang) bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName, wxPluralFormsCalculatorPtr& rPluralFormsCalculator) { - /* - We need to handle locales like de_AT.iso-8859-1 - For this we first chop off the .CHARSET specifier and ignore it. - FIXME: UNICODE SUPPORT: must use CHARSET specifier! - */ + wxString searchPath; + +#if wxUSE_FONTMAP + // first look for the catalog for this language and the current locale: + // notice that we don't use the system name for the locale as this would + // force us to install catalogs in different locations depending on the + // system but always use the canonical name + wxFontEncoding encSys = wxLocale::GetSystemEncoding(); + if ( encSys != wxFONTENCODING_SYSTEM ) + { + wxString fullname(szDirPrefix); + fullname << _T('.') << wxFontMapperBase::GetEncodingName(encSys); + searchPath << GetFullSearchPath(fullname) << wxPATH_SEP; + } +#endif // wxUSE_FONTMAP + - wxString searchPath = GetFullSearchPath(szDirPrefix); + searchPath += GetFullSearchPath(szDirPrefix); const wxChar *sublocale = wxStrchr(szDirPrefix, wxT('_')); if ( sublocale ) { @@ -1104,17 +1115,21 @@ bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName, NoTransErr noTransErr; wxLogVerbose(_("looking for catalog '%s' in path '%s'."), szName, searchPath.c_str()); + wxLogTrace(TRACE_I18N, _T("Looking for \"%s.mo\" in \"%s\""), + szName, searchPath.c_str()); wxFileName fn(szName); - fn.SetExt(MSGCATALOG_EXTENSION); + fn.SetExt(_T("mo")); wxString strFullName; if ( !wxFindFileInPath(&strFullName, searchPath, fn.GetFullPath()) ) { wxLogVerbose(_("catalog file for domain '%s' not found."), szName); + wxLogTrace(TRACE_I18N, _T("Catalog \"%s.mo\" not found"), szName); return false; } // open file wxLogVerbose(_("using catalog '%s' from '%s'."), szName, strFullName.c_str()); + wxLogTrace(TRACE_I18N, _T("Using catalog \"%s\"."), strFullName.c_str()); wxFile fileMsg(strFullName); if ( !fileMsg.IsOpened() ) @@ -1202,8 +1217,7 @@ bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName, } else { - wxLogVerbose(_("Cannot parse Plural-Forms:'%s'"), - pfs.c_str()); + wxLogVerbose(_("Cannot parse Plural-Forms:'%s'"), pfs.c_str()); } } } @@ -1221,16 +1235,42 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, const wxString& msgIdCharset, bool convertEncoding) const { -#if wxUSE_WCHAR_T - wxCSConv *csConv = NULL; - if ( !m_charset.empty() ) - csConv = new wxCSConv(m_charset); +#if wxUSE_FONTMAP + // determine if we need any conversion at all + if ( convertEncoding ) + { + wxFontEncoding encCat = wxFontMapperBase::GetEncodingFromName(m_charset); + if ( encCat == wxLocale::GetSystemEncoding() ) + { + // no need to convert + convertEncoding = false; + } + } +#endif // wxUSE_FONTMAP - wxMBConv& inputConv = csConv ? *((wxMBConv*)csConv) : *wxConvCurrent; +#if wxUSE_WCHAR_T + // conversion to use to convert catalog strings to the GUI encoding + wxMBConv *inputConv, + *csConv = NULL; // another ptr just to be able to delete it later + if ( convertEncoding ) + { + if ( m_charset.empty() ) + inputConv = wxConvCurrent; + else + inputConv = + csConv = new wxCSConv(m_charset); + } + else // no conversion needed + { + inputConv = NULL; + } - wxCSConv *sourceConv = NULL; - if ( !msgIdCharset.empty() && (m_charset != msgIdCharset) ) - sourceConv = new wxCSConv(msgIdCharset); + // conversion to apply to msgid strings before looking them up: we only + // need it if the msgids are neither in 7 bit ASCII nor in the same + // encoding as the catalog + wxCSConv *sourceConv = msgIdCharset.empty() || (msgIdCharset == m_charset) + ? NULL + : new wxCSConv(msgIdCharset); #elif wxUSE_FONTMAP wxASSERT_MSG( msgIdCharset == NULL, @@ -1273,12 +1313,12 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, { const char *data = StringAtOfs(m_pOrigTable, i); #if wxUSE_UNICODE - wxString msgid(data, inputConv); -#else + wxString msgid(data, *inputConv); +#else // ASCII wxString msgid; #if wxUSE_WCHAR_T - if ( convertEncoding && sourceConv ) - msgid = wxString(inputConv.cMB2WC(data), *sourceConv); + if ( inputConv && sourceConv ) + msgid = wxString(inputConv->cMB2WC(data), *sourceConv); else #endif msgid = data; @@ -1293,10 +1333,10 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, wxString msgstr; #if wxUSE_WCHAR_T #if wxUSE_UNICODE - msgstr = wxString(data + offset, inputConv); + msgstr = wxString(data + offset, *inputConv); #else - if ( convertEncoding ) - msgstr = wxString(inputConv.cMB2WC(data + offset), wxConvLocal); + if ( inputConv ) + msgstr = wxString(inputConv->cMB2WC(data + offset), wxConvLocal); else msgstr = wxString(data + offset); #endif @@ -1474,8 +1514,19 @@ bool wxLocale::Init(const wxChar *szName, m_pMsgCat = NULL; bool bOk = true; if ( bLoadDefault ) + { bOk = AddCatalog(wxT("wxstd")); + // there may be a catalog with toolkit specific overrides, it is not + // an error if this does not exist + if ( bOk && wxTheApp ) + { + wxAppTraits *traits = wxTheApp->GetTraits(); + if (traits) + AddCatalog(traits->GetToolkitInfo().name.BeforeFirst(wxT('/')).MakeLower()); + } + } + return bOk; } @@ -1549,6 +1600,18 @@ bool wxLocale::Init(int language, int flags) wxMB2WXbuf retloc = wxSetlocaleTryUTF(LC_ALL, locale); +#ifdef __AIX__ + // at least in AIX 5.2 libc is buggy and the string returned from setlocale(LC_ALL) + // can't be passed back to it because it returns 6 strings (one for each locale + // category), i.e. for C locale we get back "C C C C C C" + // + // this contradicts IBM own docs but this is not of much help, so just work around + // it in the crudest possible manner + wxChar *p = wxStrchr((wxChar *)retloc, _T(' ')); + if ( p ) + *p = _T('\0'); +#endif // __AIX__ + if ( !retloc ) { // Some C libraries don't like xx_YY form and require xx only @@ -1795,7 +1858,7 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix) (langFull.Len() == LEN_FULL && langFull[LEN_LANG] == wxT('_')) ) { // 0. Make sure the lang is according to latest ISO 639 - // (this is neccessary because glibc uses iw and in instead + // (this is necessary because glibc uses iw and in instead // of he and id respectively). // the language itself (second part is the dialect/sublang) @@ -2216,35 +2279,9 @@ wxString wxLocale::GetSystemEncodingName() if ( alang ) { - // 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 recent glibc call it ANSI_X3.4-1968... - // - // HP-UX uses HP-Roman8 cset which is not the same as ASCII (see RFC - // 1345 for its definition) but must be recognized as otherwise HP - // users get a warning about it on each program startup, so handle it - // here -- but it would be obviously better to add real supprot to it, - // of course! - if ( strcmp(alang, "646") == 0 - || strcmp(alang, "ANSI_X3.4-1968") == 0 -#ifdef __HPUX__ - || strcmp(alang, "roman8") == 0 -#endif // __HPUX__ - ) - { - encname = _T("US-ASCII"); - } - else - { - encname = wxString::FromAscii( alang ); - } + encname = wxString::FromAscii( alang ); } - else + else // nl_langinfo() failed #endif // HAVE_LANGINFO_H { // if we can't get at the character set directly, try to see if it's in @@ -2281,12 +2318,17 @@ wxFontEncoding wxLocale::GetSystemEncoding() #if defined(__WIN32__) && !defined(__WXMICROWIN__) UINT codepage = ::GetACP(); - // wxWidgets only knows about CP1250-1257, 932, 936, 949, 950 + // wxWidgets only knows about CP1250-1257, 874, 932, 936, 949, 950 if ( codepage >= 1250 && codepage <= 1257 ) { return (wxFontEncoding)(wxFONTENCODING_CP1250 + codepage - 1250); } + if ( codepage == 874 ) + { + return wxFONTENCODING_CP874; + } + if ( codepage == 932 ) { return wxFONTENCODING_CP932; @@ -2315,16 +2357,15 @@ wxFontEncoding wxLocale::GetSystemEncoding() #endif return wxMacGetFontEncFromSystemEnc( encoding ) ; #elif defined(__UNIX_LIKE__) && wxUSE_FONTMAP - wxString encname = GetSystemEncodingName(); + const wxString encname = GetSystemEncodingName(); if ( !encname.empty() ) { - wxFontEncoding enc = (wxFontMapperBase::Get())-> - CharsetToEncoding(encname, false /* not interactive */); + wxFontEncoding enc = wxFontMapperBase::GetEncodingFromName(encname); // 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 !wxUSE_UNICODE && defined(__WXGTK__) if ( enc == wxFONTENCODING_UTF8 ) { // the most similar supported encoding... @@ -2332,13 +2373,11 @@ wxFontEncoding wxLocale::GetSystemEncoding() } #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 - // - // we, OTOH, definitely shouldn't return it as it doesn't make sense at - // all (which encoding is it?) - if ( enc != wxFONTENCODING_DEFAULT ) + // GetEncodingFromName() returns wxFONTENCODING_DEFAULT for C locale + // (a.k.a. US-ASCII) which is arguably a bug but keep it like this for + // backwards compatibility and just take care to not return + // wxFONTENCODING_DEFAULT from here as this surely doesn't make sense + if ( enc != wxFONTENCODING_MAX && enc != wxFONTENCODING_DEFAULT ) { return enc; } @@ -2499,20 +2538,12 @@ const wxChar *wxLocale::GetString(const wxChar *szOrigString, { NoTransErr noTransErr; - if ( szDomain != NULL ) - { - wxLogTrace(_T("i18n"), - _T("string '%s'[%lu] not found in domain '%s' for locale '%s'."), - szOrigString, (unsigned long)n, - szDomain, m_strLocale.c_str()); - - } - else - { - wxLogTrace(_T("i18n"), - _T("string '%s'[%lu] not found in locale '%s'."), - szOrigString, (unsigned long)n, m_strLocale.c_str()); - } + wxLogTrace(TRACE_I18N, + _T("string \"%s\"[%ld] not found in %slocale '%s'."), + szOrigString, (long)n, + szDomain ? wxString::Format(_T("domain '%s' "), szDomain).c_str() + : _T(""), + m_strLocale.c_str()); } #endif // __WXDEBUG__