X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ec37df5776f89de888cdef2ac1445896d283590a..9d59f1fc2ee07ad28b55a6b8bae8d451705e2215:/src/common/intl.cpp diff --git a/src/common/intl.cpp b/src/common/intl.cpp index d3cf3e156a..5852174e3a 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: intl.cpp +// Name: src/common/intl.cpp // Purpose: Internationalization and localisation for wxWindows // Author: Vadim Zeitlin // Modified by: @@ -31,26 +31,35 @@ #if wxUSE_INTL // standard headers -#include -#include +#include +#include +#include +#ifdef HAVE_LANGINFO_H + #include +#endif // wxWindows -#include "wx/defs.h" -#include "wx/string.h" -#include "wx/tokenzr.h" -#include "wx/intl.h" +#ifndef WX_PRECOMP + #include "wx/string.h" + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/debug.h" + #include "wx/utils.h" + #include "wx/dynarray.h" +#endif // WX_PRECOMP + #include "wx/file.h" -#include "wx/log.h" -#include "wx/debug.h" -#include "wx/utils.h" -#include "wx/dynarray.h" +#include "wx/tokenzr.h" +#include "wx/module.h" +#include "wx/fontmap.h" +#include "wx/encconv.h" + #ifdef __WIN32__ -#include "wx/msw/private.h" + #include "wx/msw/private.h" +#elif defined(__UNIX_LIKE__) + #include "wx/fontmap.h" // for CharsetToEncoding() #endif - -#include - // ---------------------------------------------------------------------------- // simple types // ---------------------------------------------------------------------------- @@ -85,9 +94,7 @@ typedef unsigned char size_t8; { // Asserting a sizeof directly causes some compilers to // issue a "using constant in a conditional expression" warning - size_t intsize = sizeof(int); - - wxASSERT_MSG( intsize == 4, + wxASSERT_MSG( wxAssertIsEqual(sizeof(int), 4), "size_t32 is incorrectly defined!" ); } } intsizechecker; @@ -499,29 +506,15 @@ const char *wxMsgCatalog::GetString(const char *szOrig) const return NULL; } - -#if wxUSE_GUI -#include "wx/fontmap.h" -#include "wx/encconv.h" -#endif - void wxMsgCatalog::ConvertEncoding() { -#if wxUSE_GUI - wxFontEncoding enc; - // first, find encoding header: const char *hdr = StringAtOfs(m_pOrigTable, 0); if ( hdr == NULL || hdr[0] != 0 ) { - // not supported by this catalog, does not have non-fuzzy header + // not supported by this catalog, does not have correct header return; } - /* - we support catalogs with header (msgid "") that is _not_ marked as "#, - fuzzy" (otherwise the string would not be included into compiled - catalog) - */ wxString header(StringAtOfs(m_pTransTable, 0)); wxString charset; int pos = header.Find(wxT("Content-Type: text/plain; charset=")); @@ -531,23 +524,28 @@ void wxMsgCatalog::ConvertEncoding() while (header[n] != wxT('\n')) charset << header[n++]; - enc = wxTheFontMapper->CharsetToEncoding(charset, FALSE); +#if wxUSE_FONTMAP + wxFontEncoding enc = wxTheFontMapper->CharsetToEncoding(charset, FALSE); if ( enc == wxFONTENCODING_SYSTEM ) return; // unknown encoding - wxFontEncodingArray a = wxEncodingConverter::GetPlatformEquivalents(enc); - if (a[0] == enc) - return; // no conversion needed, locale uses native encoding - - if (a.GetCount() == 0) - return; // we don't know common equiv. under this platform + wxFontEncoding targetEnc = wxLocale::GetSystemEncoding(); + if (targetEnc == wxFONTENCODING_SYSTEM) + { + wxFontEncodingArray a = wxEncodingConverter::GetPlatformEquivalents(enc); + if (a[0] == enc) + return; // no conversion needed, locale uses native encoding + if (a.GetCount() == 0) + return; // we don't know common equiv. under this platform + targetEnc = a[0]; + } wxEncodingConverter converter; + converter.Init(enc, targetEnc); - converter.Init(enc, a[0]); for (size_t i = 0; i < m_numStrings; i++) converter.Convert((char*)StringAtOfs(m_pTransTable, i)); -#endif // wxUSE_GUI +#endif // wxUSE_FONTMAP } @@ -559,11 +557,28 @@ void wxMsgCatalog::ConvertEncoding() WX_DECLARE_EXPORTED_OBJARRAY(wxLanguageInfo, wxLanguageInfoArray); WX_DEFINE_OBJARRAY(wxLanguageInfoArray); +wxLanguageInfoArray *wxLocale::ms_languagesDB = NULL; + +/*static*/ void wxLocale::CreateLanguagesDB() +{ + if (ms_languagesDB == NULL) + { + ms_languagesDB = new wxLanguageInfoArray; + InitLanguagesDB(); + } +} + +/*static*/ void wxLocale::DestroyLanguagesDB() +{ + delete ms_languagesDB; + ms_languagesDB = NULL; +} + + wxLocale::wxLocale() { m_pszOldLocale = NULL; m_pMsgCat = NULL; - m_languagesDB = NULL; m_language = wxLANGUAGE_UNKNOWN; } @@ -614,11 +629,7 @@ bool wxLocale::Init(int language, int flags) wxLanguageInfo *info = NULL; int lang = language; - if (m_languagesDB == NULL) - { - m_languagesDB = new wxLanguageInfoArray; - InitLanguagesDB(); - } + CreateLanguagesDB(); if (lang == wxLANGUAGE_DEFAULT) { @@ -634,11 +645,11 @@ bool wxLocale::Init(int language, int flags) if (lang != wxLANGUAGE_DEFAULT) { - for (size_t i = 0; i < m_languagesDB->GetCount(); i++) + for (size_t i = 0; i < ms_languagesDB->GetCount(); i++) { - if (m_languagesDB->Item(i).Language == lang) + if (ms_languagesDB->Item(i).Language == lang) { - info = &m_languagesDB->Item(i); + info = &ms_languagesDB->Item(i); break; } } @@ -654,7 +665,7 @@ bool wxLocale::Init(int language, int flags) wxString name = info->Description; wxString canonical = info->CanonicalName; wxString locale; - wxChar *retloc; + const wxChar *retloc; // Set the locale: #ifdef __UNIX__ @@ -759,14 +770,13 @@ void wxLocale::AddCatalogLookupPathPrefix(const wxString& prefix) //else: already have it } -int wxLocale::GetSystemLanguage() const +/*static*/ int wxLocale::GetSystemLanguage() { - wxCHECK_MSG( m_languagesDB != NULL, wxLANGUAGE_UNKNOWN, - _T("Languages DB not initialized, call wxLocale::Init!") ); + CreateLanguagesDB(); // init i to avoid compiler warning size_t i = 0, - count = m_languagesDB->GetCount(); + count = ms_languagesDB->GetCount(); #if defined(__UNIX__) // first get the string identifying the language from the environment @@ -775,14 +785,14 @@ int wxLocale::GetSystemLanguage() const !wxGetEnv(wxT("LC_MESSAGES"), &langFull) && !wxGetEnv(wxT("LANG"), &langFull)) { - // no language specified - return wxLANGUAGE_UNKNOWN; + // no language specified, threat it as English + return wxLANGUAGE_ENGLISH; } if ( langFull == _T("C") ) { // default C locale - return wxLANGUAGE_DEFAULT; + return wxLANGUAGE_ENGLISH; } // the language string has the following form @@ -835,7 +845,7 @@ int wxLocale::GetSystemLanguage() const // 1. Try to find the language either as is: for ( i = 0; i < count; i++ ) { - if ( m_languagesDB->Item(i).CanonicalName == langFull ) + if ( ms_languagesDB->Item(i).CanonicalName == langFull ) { break; } @@ -846,7 +856,7 @@ int wxLocale::GetSystemLanguage() const { for ( i = 0; i < count; i++ ) { - if ( m_languagesDB->Item(i).CanonicalName == lang ) + if ( ms_languagesDB->Item(i).CanonicalName == lang ) { break; } @@ -858,7 +868,7 @@ int wxLocale::GetSystemLanguage() const { for ( i = 0; i < count; i++ ) { - if ( ExtractLang(m_languagesDB->Item(i).CanonicalName) + if ( ExtractLang(ms_languagesDB->Item(i).CanonicalName) == langFull ) { break; @@ -871,7 +881,7 @@ int wxLocale::GetSystemLanguage() const // try to find the name in verbose description for ( i = 0; i < count; i++ ) { - if (m_languagesDB->Item(i).Description.CmpNoCase(langFull) == 0) + if (ms_languagesDB->Item(i).Description.CmpNoCase(langFull) == 0) { break; } @@ -886,8 +896,8 @@ int wxLocale::GetSystemLanguage() const for ( i = 0; i < count; i++ ) { - if (m_languagesDB->Item(i).WinLang == lang && - m_languagesDB->Item(i).WinSublang == sublang) + if (ms_languagesDB->Item(i).WinLang == lang && + ms_languagesDB->Item(i).WinSublang == sublang) { break; } @@ -899,17 +909,102 @@ int wxLocale::GetSystemLanguage() const if ( i < count ) { // we did find a matching entry, use it - return m_languagesDB->Item(i).Language; + return ms_languagesDB->Item(i).Language; } // no info about this language in the database return wxLANGUAGE_UNKNOWN; } -void wxLocale::AddLanguage(const wxLanguageInfo& info) +// ---------------------------------------------------------------------------- +// encoding stuff +// ---------------------------------------------------------------------------- + +// this is a bit strange as under Windows we get the encoding name using its +// numeric value and under Unix we do it the other way round, but this just +// reflects the way different systems provide he encoding info + +/* static */ +wxString wxLocale::GetSystemEncodingName() +{ + wxString encname; + +#ifdef __WIN32__ + // FIXME: what is the error return value for GetACP()? + UINT codepage = ::GetACP(); + encname.Printf(_T("windows-%u"), codepage); +#elif defined(__UNIX_LIKE__) + +#if defined(HAVE_LANGINFO_H) && defined(CODESET) + // GNU libc provides current character set this way (this conforms + // to Unix98) + char *oldLocale = strdup(setlocale(LC_CTYPE, NULL)); + setlocale(LC_CTYPE, ""); + char *alang = nl_langinfo(CODESET); + setlocale(LC_CTYPE, oldLocale); + free(oldLocale); + if (alang) + { + encname = wxConvLibc.cMB2WX(alang); + } + else +#endif // HAVE_LANGINFO_H + { + // 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; + if (!dot) + { + lang = wxGetenv(wxT("LC_CTYPE")); + if ( lang ) + dot = wxStrchr(lang, wxT('.')); + } + if (!dot) + { + lang = wxGetenv(wxT("LANG")); + if ( lang ) + dot = wxStrchr(lang, wxT('.')); + } + + if ( dot ) + { + encname = dot+1; + } + } +#endif // Win32/Unix + + return encname; +} + +/* static */ +wxFontEncoding wxLocale::GetSystemEncoding() { - wxASSERT_MSG(m_languagesDB != NULL, "Languages DB not initialized, call wxLocale::Init!"); - m_languagesDB->Add(info); +#ifdef __WIN32__ + UINT codepage = ::GetACP(); + + // wxWindows only knows about CP1250-1257 + if ( codepage >= 1250 && codepage <= 1257 ) + { + return (wxFontEncoding)(wxFONTENCODING_CP1250 + codepage - 1250); + } +#elif defined(__UNIX_LIKE__) && wxUSE_FONTMAP + wxString encname = GetSystemEncodingName(); + if ( !encname.empty() ) + { + return wxTheFontMapper-> + CharsetToEncoding(encname, FALSE /* not interactive */); + } +#endif // Win32/Unix + + return wxFONTENCODING_SYSTEM; +} + +/*static*/ void wxLocale::AddLanguage(const wxLanguageInfo& info) +{ + CreateLanguagesDB(); + ms_languagesDB->Add(info); } wxString wxLocale::GetSysName() const @@ -928,8 +1023,6 @@ wxLocale::~wxLocale() delete pTmpCat; } - delete m_languagesDB; - // restore old locale wxSetLocale(m_pOldLocale); wxSetlocale(LC_ALL, m_pszOldLocale); @@ -1057,15 +1150,37 @@ wxLocale *wxSetLocale(wxLocale *pLocale) return pOld; } + + +// ---------------------------------------------------------------------------- +// wxLocale module (for lazy destruction of languagesDB) +// ---------------------------------------------------------------------------- + +class wxLocaleModule: public wxModule +{ + DECLARE_DYNAMIC_CLASS(wxLocaleModule) + public: + wxLocaleModule() {} + bool OnInit() { return TRUE; } + void OnExit() { wxLocale::DestroyLanguagesDB(); } +}; + +IMPLEMENT_DYNAMIC_CLASS(wxLocaleModule, wxModule) + + + // ---------------------------------------------------------------------------- // default languages table & initialization // ---------------------------------------------------------------------------- + +// --- --- --- generated code begins here --- --- --- + // This table is generated by misc/languages/genlang.py // When making changes, please put them into misc/languages/langtabl.txt -#ifndef __WIN32__ +#if !defined(__WIN32__) || defined(__WXMICROWIN__) #define SETWINLANG(info,lang,sublang) @@ -1567,7 +1682,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") @@ -1795,10 +1910,11 @@ 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 +// --- --- --- generated code ends here --- --- --- #endif // wxUSE_INTL