X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b40a6748eb6c815cb046127b642f225f8d2030cf..e9531db94d220b8471165de39c50f1a8fc4032df:/src/common/intl.cpp diff --git a/src/common/intl.cpp b/src/common/intl.cpp index 2350c1a41e..2014d6dd84 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -18,10 +18,6 @@ // headers // ---------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "intl.h" -#endif - #if defined(__BORLAND__) && !defined(__WXDEBUG__) // There's a bug in Borland's compiler that breaks wxLocale with -O2, // so make sure that flag is not used for this file: @@ -72,12 +68,16 @@ #endif #include "wx/file.h" +#include "wx/filename.h" #include "wx/tokenzr.h" #include "wx/module.h" #include "wx/fontmap.h" #include "wx/encconv.h" #include "wx/hashmap.h" #include "wx/ptr_scpd.h" +#include "wx/app.h" +#include "wx/apptrait.h" +#include "wx/stdpaths.h" #if defined(__WXMAC__) #include "wx/mac/private.h" // includes mac headers @@ -99,14 +99,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 // ---------------------------------------------------------------------------- @@ -498,14 +497,13 @@ public: ~wxPluralFormsCalculator() {} void init(wxPluralFormsToken::Number nplurals, wxPluralFormsNode* plural); - wxString getString() const; private: wxPluralFormsToken::Number m_nplurals; wxPluralFormsNodePtr m_plural; }; -wxDEFINE_SCOPED_PTR_TYPE(wxPluralFormsCalculator); +wxDEFINE_SCOPED_PTR_TYPE(wxPluralFormsCalculator) void wxPluralFormsCalculator::init(wxPluralFormsToken::Number nplurals, wxPluralFormsNode* plural) @@ -987,7 +985,7 @@ private: // ---------------------------------------------------------------------------- // the list of the directories to search for message catalog files -static wxArrayString s_searchPrefixes; +static wxArrayString gs_searchPrefixes; // ============================================================================ // implementation @@ -1008,18 +1006,20 @@ wxMsgCatalogFile::~wxMsgCatalogFile() wxDELETEA(m_pData); } -// return all directories to search for given prefix -static wxString GetAllMsgCatalogSubdirs(const wxChar *prefix, - const wxChar *lang) +// return the directory to search for message catalogs under the given prefix +static +wxString GetMsgCatalogSubdir(const wxChar *prefix, const wxChar *lang) { wxString searchPath; + searchPath << prefix << wxFILE_SEP_PATH << lang; - // search first in prefix/fr/LC_MESSAGES, then in prefix/fr and finally in - // prefix (assuming the language is 'fr') - searchPath << prefix << wxFILE_SEP_PATH << lang << wxFILE_SEP_PATH - << wxT("LC_MESSAGES") << wxPATH_SEP - << prefix << wxFILE_SEP_PATH << lang << wxPATH_SEP - << prefix << wxPATH_SEP; + // under Unix, the message catalogs are supposed to go into LC_MESSAGES + // subdirectory so look there too +#ifdef __UNIX__ + const wxString searchPathOrig(searchPath); + searchPath << wxFILE_SEP_PATH << wxT("LC_MESSAGES") + << wxPATH_SEP << searchPathOrig; +#endif // __UNIX__ return searchPath; } @@ -1027,75 +1027,96 @@ static wxString GetAllMsgCatalogSubdirs(const wxChar *prefix, // construct the search path for the given language static wxString GetFullSearchPath(const wxChar *lang) { - wxString searchPath; - // first take the entries explicitly added by the program - size_t count = s_searchPrefixes.Count(); - for ( size_t n = 0; n < count; n++ ) + wxArrayString paths; + paths.reserve(gs_searchPrefixes.size() + 1); + size_t n, + count = gs_searchPrefixes.size(); + for ( n = 0; n < count; n++ ) { - searchPath << GetAllMsgCatalogSubdirs(s_searchPrefixes[n], lang) - << wxPATH_SEP; + paths.Add(GetMsgCatalogSubdir(gs_searchPrefixes[n], lang)); } + +#if wxUSE_STDPATHS + // then look in the standard location + const wxString stdp = wxStandardPaths::Get(). + GetLocalizedResourcesDir(lang, wxStandardPaths::ResourceCat_Messages); + + if ( paths.Index(stdp) == wxNOT_FOUND ) + paths.Add(stdp); +#endif // wxUSE_STDPATHS + + // last look in default locations +#ifdef __UNIX__ // 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 + if ( pszLcPath ) + { + const wxString lcp = GetMsgCatalogSubdir(pszLcPath, lang); + if ( paths.Index(lcp) == wxNOT_FOUND ) + paths.Add(lcp); + } -#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); + // also add the one from where wxWin was installed: + wxString wxp = wxGetInstallPrefix(); + if ( !wxp.empty() ) + { + wxp = GetMsgCatalogSubdir(wxp + _T("/share/locale"), lang); + if ( paths.Index(wxp) == wxNOT_FOUND ) + paths.Add(wxp); + } #endif // __UNIX__ - // then take the current directory - // FIXME it should be the directory of the executable -#ifdef __WXMAC__ - wxChar cwd[512] ; - wxGetWorkingDirectory( cwd , sizeof( cwd ) ) ; - searchPath << GetAllMsgCatalogSubdirs(cwd, lang); - // generic search paths could be somewhere in the system folder preferences -#else // !Mac - searchPath << GetAllMsgCatalogSubdirs(wxT("."), lang); -#endif // platform + // finally construct the full search path + wxString searchPath; + searchPath.reserve(500); + count = paths.size(); + for ( n = 0; n < count; n++ ) + { + searchPath += paths[n]; + if ( n != count - 1 ) + searchPath += wxPATH_SEP; + } return searchPath; } // open disk file and read in it's contents -bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName0, +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 szName = szName0; - if(szName.Find(wxT('.')) != wxNOT_FOUND) // contains a dot - szName = szName.Left(szName.Find(wxT('.'))); + wxString searchPath; - wxString searchPath = GetFullSearchPath(szDirPrefix); +#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 + + + searchPath += GetFullSearchPath(szDirPrefix); const wxChar *sublocale = wxStrchr(szDirPrefix, wxT('_')); if ( sublocale ) { // also add just base locale name: for things like "fr_BE" (belgium // french) we should use "fr" if no belgium specific message catalogs // exist - searchPath << GetFullSearchPath(wxString(szDirPrefix). - Left((size_t)(sublocale - szDirPrefix))) - << wxPATH_SEP; + searchPath << wxPATH_SEP + << GetFullSearchPath(wxString(szDirPrefix). + Left((size_t)(sublocale - szDirPrefix))); } - wxString strFile = szName; - strFile += MSGCATALOG_EXTENSION; - // don't give translation errors here because the wxstd catalog might // not yet be loaded (and it's normal) // @@ -1103,36 +1124,44 @@ bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName0, NoTransErr noTransErr; wxLogVerbose(_("looking for catalog '%s' in path '%s'."), - szName.c_str(), searchPath.c_str()); + szName, searchPath.c_str()); + wxLogTrace(TRACE_I18N, _T("Looking for \"%s.mo\" in \"%s\""), + szName, searchPath.c_str()); + wxFileName fn(szName); + fn.SetExt(_T("mo")); wxString strFullName; - if ( !wxFindFileInPath(&strFullName, searchPath, strFile) ) { - wxLogVerbose(_("catalog file for domain '%s' not found."), szName.c_str()); + 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.c_str(), strFullName.c_str()); + 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() ) return false; // get the file size (assume it is less than 4Gb...) - wxFileSize_t nSize = fileMsg.Length(); - if ( nSize == wxInvalidOffset ) + wxFileOffset lenFile = fileMsg.Length(); + if ( lenFile == wxInvalidOffset ) return false; + size_t nSize = wx_truncate_cast(size_t, lenFile); + wxASSERT_MSG( nSize == lenFile + size_t(0), _T("message catalog bigger than 4GB?") ); + // read the whole file in memory m_pData = new size_t8[nSize]; - if ( fileMsg.Read(m_pData, nSize) != nSize ) { + if ( fileMsg.Read(m_pData, nSize) != lenFile ) { wxDELETEA(m_pData); return false; } // examine header - bool bValid = nSize > sizeof(wxMsgCatalogHeader); + bool bValid = nSize + (size_t)0 > sizeof(wxMsgCatalogHeader); wxMsgCatalogHeader *pHeader = (wxMsgCatalogHeader *)m_pData; if ( bValid ) { @@ -1157,7 +1186,7 @@ bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName0, Swap(pHeader->ofsOrigTable)); m_pTransTable = (wxMsgTableEntry *)(m_pData + Swap(pHeader->ofsTransTable)); - m_nSize = nSize; + m_nSize = (size_t32)nSize; // now parse catalog's header and try to extract catalog charset and // plural forms formula from it: @@ -1201,8 +1230,7 @@ bool wxMsgCatalogFile::Load(const wxChar *szDirPrefix, const wxChar *szName0, } else { - wxLogVerbose(_("Cannot parse Plural-Forms:'%s'"), - pfs.c_str()); + wxLogVerbose(_("Cannot parse Plural-Forms:'%s'"), pfs.c_str()); } } } @@ -1220,16 +1248,51 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, const wxString& msgIdCharset, bool convertEncoding) const { -#if wxUSE_WCHAR_T - wxCSConv *csConv = NULL; - if ( !m_charset.IsEmpty() ) - 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 need to convert the encoding + { + // we still need the conversion for Unicode build +#if wxUSE_UNICODE + inputConv = wxConvCurrent; +#else // !wxUSE_UNICODE + inputConv = NULL; +#endif // wxUSE_UNICODE/!wxUSE_UNICODE + } - 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, @@ -1239,7 +1302,7 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, if ( convertEncoding ) { wxFontEncoding targetEnc = wxFONTENCODING_SYSTEM; - wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(m_charset, false); + wxFontEncoding enc = wxFontMapperBase::Get()->CharsetToEncoding(m_charset, false); if ( enc == wxFONTENCODING_SYSTEM ) { convertEncoding = false; // unknown encoding @@ -1268,18 +1331,18 @@ void wxMsgCatalogFile::FillHash(wxMessagesHash& hash, #endif // wxUSE_WCHAR_T/!wxUSE_WCHAR_T (void)convertEncoding; // get rid of warnings about unused parameter - for (size_t i = 0; i < m_numStrings; i++) + for (size_t32 i = 0; i < m_numStrings; i++) { 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); - else -#endif + #if wxUSE_WCHAR_T + if ( inputConv && sourceConv ) + msgid = wxString(inputConv->cMB2WC(data), *sourceConv); + else + #endif msgid = data; #endif // wxUSE_UNICODE @@ -1292,10 +1355,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 @@ -1375,7 +1438,7 @@ const wxChar *wxMsgCatalog::GetString(const wxChar *sz, size_t n) const #include "wx/arrimpl.cpp" WX_DECLARE_EXPORTED_OBJARRAY(wxLanguageInfo, wxLanguageInfoArray); -WX_DEFINE_OBJARRAY(wxLanguageInfoArray); +WX_DEFINE_OBJARRAY(wxLanguageInfoArray) wxLanguageInfoArray *wxLocale::ms_languagesDB = NULL; @@ -1398,6 +1461,9 @@ wxLanguageInfoArray *wxLocale::ms_languagesDB = NULL; void wxLocale::DoCommonInit() { m_pszOldLocale = NULL; + + m_pOldLocale = wxSetLocale(this); + m_pMsgCat = NULL; m_language = wxLANGUAGE_UNKNOWN; m_initialized = false; @@ -1455,7 +1521,7 @@ bool wxLocale::Init(const wxChar *szName, // the short name will be used to look for catalog files as well, // so we need something here - if ( m_strShort.IsEmpty() ) { + if ( m_strShort.empty() ) { // FIXME I don't know how these 2 letter abbreviations are formed, // this wild guess is surely wrong if ( szLocale && szLocale[0] ) @@ -1466,15 +1532,23 @@ bool wxLocale::Init(const wxChar *szName, } } - // save the old locale to be able to restore it later - m_pOldLocale = wxSetLocale(this); - // load the default catalog with wxWidgets standard messages 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; } @@ -1540,48 +1614,83 @@ bool wxLocale::Init(int language, int flags) wxString locale; // Set the locale: -#if defined(__UNIX__) && !defined(__WXMAC__) - if (language == wxLANGUAGE_DEFAULT) - locale = wxEmptyString; - else +#if defined(__OS2__) + wxMB2WXbuf retloc = wxSetlocale(LC_ALL , wxEmptyString); +#elif defined(__UNIX__) && !defined(__WXMAC__) + if (language != wxLANGUAGE_DEFAULT) locale = info->CanonicalName; wxMB2WXbuf retloc = wxSetlocaleTryUTF(LC_ALL, locale); + const wxString langOnly = locale.Left(2); if ( !retloc ) { // Some C libraries don't like xx_YY form and require xx only - retloc = wxSetlocaleTryUTF(LC_ALL, locale.Mid(0,2)); + retloc = wxSetlocaleTryUTF(LC_ALL, langOnly); } + +#if wxUSE_FONTMAP + // some systems (e.g. FreeBSD and HP-UX) don't have xx_YY aliases but + // require the full xx_YY.encoding form, so try using UTF-8 because this is + // the only thing we can do generically + // + // TODO: add encodings applicable to each language to the lang DB and try + // them all in turn here 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); - else if (mid == wxT("nb")) - locale = wxT("no_NO"); - else if (mid == wxT("nn")) - locale = wxT("no_NY"); - - retloc = wxSetlocaleTryUTF(LC_ALL, locale); + const wxChar **names = + wxFontMapperBase::GetAllEncodingNames(wxFONTENCODING_UTF8); + while ( *names ) + { + retloc = wxSetlocale(LC_ALL, locale + _T('.') + *names++); + if ( retloc ) + break; + } } +#endif // wxUSE_FONTMAP + 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 = wxSetlocaleTryUTF(LC_ALL, locale.Mid(0,2)); + // Some C libraries (namely glibc) still use old ISO 639, + // so will translate the abbrev for them + wxString localeAlt; + if ( langOnly == wxT("he") ) + localeAlt = wxT("iw") + locale.Mid(3); + else if ( langOnly == wxT("id") ) + localeAlt = wxT("in") + locale.Mid(3); + else if ( langOnly == wxT("yi") ) + localeAlt = wxT("ji") + locale.Mid(3); + else if ( langOnly == wxT("nb") ) + localeAlt = wxT("no_NO"); + else if ( langOnly == wxT("nn") ) + localeAlt = wxT("no_NY"); + + if ( !localeAlt.empty() ) + { + retloc = wxSetlocaleTryUTF(LC_ALL, localeAlt); + if ( !retloc ) + retloc = wxSetlocaleTryUTF(LC_ALL, locale.Left(2)); + } } + if ( !retloc ) { wxLogError(wxT("Cannot set locale to '%s'."), locale.c_str()); return false; } + +#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__ + #elif defined(__WIN32__) #if wxUSE_UNICODE && (defined(__VISUALC__) || defined(__MINGW32__)) @@ -1633,7 +1742,7 @@ bool wxLocale::Init(int language, int flags) if (codepage != 0) locale << wxT(".") << buffer; } - if (locale.IsEmpty()) + if (locale.empty()) { wxLogLastError(wxT("SetThreadLocale")); wxLogError(wxT("Cannot set locale to language %s."), name.c_str()); @@ -1681,16 +1790,33 @@ bool wxLocale::Init(int language, int flags) wxLogError(wxT("Cannot set locale to language %s."), name.c_str()); return false; } -#elif defined(__WXMAC__) || defined(__WXPM__) - wxMB2WXbuf retloc = wxSetlocale(LC_ALL , wxEmptyString); +#elif defined(__WXMAC__) + if (lang == wxLANGUAGE_DEFAULT) + locale = wxEmptyString; + else + locale = info->CanonicalName; + + wxMB2WXbuf retloc = wxSetlocale(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)); + } + if ( !retloc ) + { + wxLogError(wxT("Cannot set locale to '%s'."), locale.c_str()); + return false; + } #else + wxUnusedVar(flags); return false; #define WX_NO_LOCALE_SUPPORT #endif #ifndef WX_NO_LOCALE_SUPPORT wxChar *szLocale = retloc ? wxStrdup(retloc) : NULL; - bool ret = Init(name, canonical, retloc, + bool ret = Init(name, canonical, szLocale, (flags & wxLOCALE_LOAD_DEFAULT) != 0, (flags & wxLOCALE_CONV_ENCODING) != 0); free(szLocale); @@ -1699,16 +1825,16 @@ bool wxLocale::Init(int language, int flags) m_language = lang; return ret; -#endif +#endif // !WX_NO_LOCALE_SUPPORT } void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix) { - if ( s_searchPrefixes.Index(prefix) == wxNOT_FOUND ) + if ( gs_searchPrefixes.Index(prefix) == wxNOT_FOUND ) { - s_searchPrefixes.Add(prefix); + gs_searchPrefixes.Add(prefix); } //else: already have it } @@ -1776,7 +1902,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) @@ -2181,6 +2307,9 @@ wxString wxLocale::GetSystemEncodingName() // FIXME: what is the error return value for GetACP()? UINT codepage = ::GetACP(); encname.Printf(_T("windows-%u"), codepage); +#elif defined(__WXMAC__) + // default is just empty string, this resolves to the default system + // encoding later #elif defined(__UNIX_LIKE__) #if defined(HAVE_LANGINFO_H) && defined(CODESET) @@ -2194,35 +2323,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 @@ -2259,12 +2362,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; @@ -2293,16 +2401,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 = wxFontMapper::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__) || defined(__WXMOTIF__)) if ( enc == wxFONTENCODING_UTF8 ) { // the most similar supported encoding... @@ -2310,13 +2417,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; } @@ -2423,8 +2528,9 @@ wxLocale::~wxLocale() delete pTmpCat; } - // restore old locale + // restore old locale pointer wxSetLocale(m_pOldLocale); + // FIXME #ifndef __WXWINCE__ wxSetlocale(LC_ALL, m_pszOldLocale); @@ -2476,20 +2582,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__ @@ -2519,14 +2617,14 @@ wxString wxLocale::GetHeaderValue( const wxChar* szHeader, if ( pMsgCat == NULL ) return wxEmptyString; - pszTrans = pMsgCat->GetString(wxT(""), (size_t)-1); + pszTrans = pMsgCat->GetString(wxEmptyString, (size_t)-1); } else { // search in all domains for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext ) { - pszTrans = pMsgCat->GetString(wxT(""), (size_t)-1); + pszTrans = pMsgCat->GetString(wxEmptyString, (size_t)-1); if ( pszTrans != NULL ) // take the first found break; } @@ -3486,10 +3584,9 @@ void wxLocale::InitLanguagesDB() LNG(wxLANGUAGE_ZHUANG, "za" , 0 , 0 , "Zhuang") LNG(wxLANGUAGE_ZULU, "zu" , 0 , 0 , "Zulu") -}; +} #undef LNG // --- --- --- generated code ends here --- --- --- #endif // wxUSE_INTL -